[SCM] ffmpeg/master: Imported Upstream version 0.8~beta1
siretart at users.alioth.debian.org
siretart at users.alioth.debian.org
Fri Dec 30 22:46:25 UTC 2011
The following commit has been merged in the master branch:
commit 5146e3178dca4d2f152ab421167d9b30a3da24d3
Author: Reinhard Tartler <siretart at tauware.de>
Date: Fri Dec 30 23:42:13 2011 +0100
Imported Upstream version 0.8~beta1
diff --git a/.gitignore b/.gitignore
index 8887980..2118a51 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,9 +12,10 @@ doc/*.html
doc/*.pod
doxy
ffmpeg
-ffplay
-ffprobe
-ffserver
+avconv
+avplay
+avprobe
+avserver
libavcodec/*_tablegen
libavcodec/*_tables.c
libavcodec/*_tables.h
@@ -30,7 +31,6 @@ tests/audiogen
tests/base64
tests/data
tests/rotozoom
-tests/seek_test
tests/tiny_psnr
tests/videogen
tests/vsynth1
@@ -42,5 +42,4 @@ tools/pktdumper
tools/probetest
tools/qt-faststart
tools/trasher
-tools/trasher*.d
version.h
diff --git a/Changelog b/Changelog
index e8fcf82..19ba73a 100644
--- a/Changelog
+++ b/Changelog
@@ -1,71 +1,118 @@
Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest.
-version 0.7.3:
-
-- check buffer and input values in various parts of the code:
- vmd (CVE-2011-4364), qdm2 (CVE-2011-4351), imgutils (several codecs),
- vp6 (CVE-2011-4353), svq1 (CVE-2011-4579), vp3 (CVE-2011-4352), wma, 4xm
-- backport avcodec_open2() as a replacement for avcodec_open()
-- backport avformat_find_stream_info()
-
-
-version 0.7.2:
-
-- check buffer and input values in various parts of the code:
- H.264, VC-1, APE, FLV, Indeo 2, XAN, Ogg, MXF, wavpack, ffv1, MOV,
- cavs (OCERT-2011-002, CVE-2011-3362), Smacker, cpu detection, lavf,
- Matroska (CVE-2011-3504), RV10, RV30/RV40
-- memory leaks: vf_scale, eval
-
-- ARM: workaround for bug in GNU assembler
-- AVOptions: fix av_set_string3() doxy to match reality. (Bug #28)
-- Reintroduce AVInputStream.nb_streams to avoid crashes
-- aac: Only output configure if audio was found
-- aac: Remove some suspicious illegal memcpy()s from LTP
-- aacps: skip some memcpy() if src and dst would be equal
-- adts: fix PCE copying
-- alsa: fallback to buffer_size/4 for period_size
-- alsa: limit buffer_size to 32768 frames
-- cljr, indeo2: init_get_bits size in bits instead of bytes
-- configure: add missing CFLAGS to fix building on the HURD
-- dca: set AVCodecContext frame_size for DTS audio
-- fate: allow testing with libavfilter disabled
-- gxf: fix 25 fps DV material in GXF being misdetected as 50 fps
-- h264: correct implicit weight table computation for long ref pics
-- h264: correct the check for invalid long term frame index in MMCO decode
-- h264: fix PCM intra-coded blocks in monochrome case
-- jpegdec: actually search for and parse RSTn
-- lavc: fix type for thread_type option
-- lavf: fix context pointer in av_open_input_stream when avformat_open_input fails
-- lavf: do not set codec_tag for rawvideo
-- libx264: do not set pic quality if no frame is output
-- movenc: create an alternate group for each media type
-- mpegts: fix Continuity Counter error detection
-- mxfenc: fix ignored drop flag in binary timecode representation
-- fix crashes in 32-bit PIC builds (cf e.g. http://bugs.debian.org/639948)
-- ppc64: fix cast related random failures
-- riff: Add mpgv MPEG-2 fourcc
-- swscale: don't use planar output functions to write to NV12/21
-- vc1: properly zero coded_block[] edges on new slice entry
-- vp3/theora: flush after seek
-
-- various bug other fixes
-
-
-version 0.7.1:
-
-- added various additional FOURCC codec identifiers
-- H.264 4:4:4 fixes
-- build system and compilation fixes
-- Doxygen and general documentation corrections and improvements
-- fixed segfault in ffprobe
-- behavioral fix in av_open_input_stream()
-- Licensing clarification for LGPL'ed vf_gradfun
-- bugfixes while seeking in multithreaded decoding
-- support newer versions of OpenCV
-- ffmpeg: fix operation with --disable-avfilter
-- fixed integer underflow in matroska decoder
+
+version 0.8_beta1:
+
+- BWF muxer
+- Flash Screen Video 2 decoder
+- ffplay/ffprobe/ffserver renamed to avplay/avprobe/avserver
+- ffmpeg deprecated, added avconv, which is almost the same for now, except
+for a few incompatible changes in the options, which will hopefully make them
+easier to use. The changes are:
+ * The options placement is now strictly enforced! While in theory the
+ options for ffmpeg should be given in [input options] -i INPUT [output
+ options] OUTPUT order, in practice it was possible to give output options
+ before the -i and it mostly worked. Except when it didn't - the behavior was
+ a bit inconsistent. In avconv, it is not possible to mix input and output
+ options. All non-global options are reset after an input or output filename.
+ * All per-file options are now truly per-file - they apply only to the next
+ input or output file and specifying different values for different files
+ will now work properly (notably -ss and -t options).
+ * All per-stream options are now truly per-stream - it is possible to
+ specify which stream(s) should a given option apply to. See the Stream
+ specifiers section in the avconv manual for details.
+ * In ffmpeg some options (like -newvideo/-newaudio/...) are irregular in the
+ sense that they're specified after the output filename instead of before,
+ like all other options. In avconv this irregularity is removed, all options
+ apply to the next input or output file.
+ * -newvideo/-newaudio/-newsubtitle options were removed. Not only were they
+ irregular and highly confusing, they were also redundant. In avconv the -map
+ option will create new streams in the output file and map input streams to
+ them. E.g. avconv -i INPUT -map 0 OUTPUT will create an output stream for
+ each stream in the first input file.
+ * The -map option now has slightly different and more powerful syntax:
+ + Colons (':') are used to separate file index/stream type/stream index
+ instead of dots. Comma (',') is used to separate the sync stream instead
+ of colon.. This is done for consistency with other options.
+ + It's possible to specify stream type. E.g. -map 0:a:2 creates an
+ output stream from the third input audio stream.
+ + Omitting the stream index now maps all the streams of the given type,
+ not just the first. E.g. -map 0:s creates output streams for all the
+ subtitle streams in the first input file.
+ + Since -map can now match multiple streams, negative mappings were
+ introduced. Negative mappings disable some streams from an already
+ defined map. E.g. '-map 0 -map -0:a:1' means 'create output streams for
+ all the stream in the first input file, except for the second audio
+ stream'.
+ * There is a new option -c (or -codec) for choosing the decoder/encoder to
+ use, which allows to precisely specify target stream(s) consistently with
+ other options. E.g. -c:v lib264 sets the codec for all video streams, -c:a:0
+ libvorbis sets the codec for the first audio stream and -c copy copies all
+ the streams without reencoding. Old -vcodec/-acodec/-scodec options are now
+ aliases to -c:v/a/s
+ * It is now possible to precisely specify which stream should an AVOption
+ apply to. E.g. -b:v:0 2M sets the bitrate for the first video stream, while
+ -b:a 128k sets the bitrate for all audio streams. Note that the old -ab 128k
+ syntax is deprecated and will stop working soon.
+ * -map_chapters now takes only an input file index and applies to the next
+ output file. This is consistent with how all the other options work.
+ * -map_metadata now takes only an input metadata specifier and applies to
+ the next output file. Output metadata specifier is now part of the option
+ name, similarly to the AVOptions/map/codec feature above.
+ * -metadata can now be used to set metadata on streams and chapters, e.g.
+ -metadata:s:1 language=eng sets the language of the first stream to 'eng'.
+ This made -vlang/-alang/-slang options redundant, so they were removed.
+ * -qscale option now uses stream specifiers and applies to all streams, not
+ just video. I.e. plain -qscale number would now apply to all streams. To get
+ the old behavior, use -qscale:v. Also there is now a shortcut -q for -qscale
+ and -aq is now an alias for -q:a.
+ * -vbsf/-absf/-sbsf options were removed and replaced by a -bsf option which
+ uses stream specifiers. Use -bsf:v/a/s instead of the old options.
+ * -itsscale option now uses stream specifiers, so its argument is only the
+ scale parameter.
+ * -intra option was removed, use -g 0 for the same effect.
+ * -psnr option was removed, use -flags +psnr for the same effect.
+ * -vf option is now an alias to the new -filter option, which uses stream specifiers.
+ * -vframes/-aframes/-dframes options are now aliases to the new -frames option.
+ * -vtag/-atag/-stag options are now aliases to the new -tag option.
+- XMV demuxer
+- Windows Media Image decoder
+- LATM muxer/demuxer
+- showinfo filter
+- split filter
+- libcdio-paranoia input device for audio CD grabbing
+- select filter
+- Apple ProRes decoder
+- CELT in Ogg demuxing
+- VC-1 interlaced decoding
+- lut, lutrgb, and lutyuv filters
+- boxblur filter
+- Ut Video decoder
+- Speex encoding via libspeex
+- 4:2:2 H.264 decoding support
+- 4:2:2 and 4:4:4 H.264 encoding with libx264
+- Pulseaudio input device
+- replacement Indeo 3 decoder
+- TLS/SSL and HTTPS protocol support
+- AVOptions API rewritten and documented
+- most of CODEC_FLAG2_*, some CODEC_FLAG_* and many codec-specific fields in
+ AVCodecContext deprecated. Codec private options should be used instead.
+- Properly working defaults in libx264 wrapper, support for native presets.
+- Encrypted OMA files support
+- Discworld II BMV decoding support
+- VBLE Decoder
+- OS X Video Decoder Acceleration (VDA) support
+- CRI ADX audio format demuxer
+- Playstation Portable PMP format demuxer
+- PCM format support in OMA demuxer
+- CLJR encoder
+- Dxtory capture format decoder
+- v410 QuickTime uncompressed 4:4:4 10-bit encoder and decoder
+- OpenMG Audio muxer
+- Simple segmenting muxer
+- Indeo 4 decoder
+- SMJPEG demuxer
version 0.7:
diff --git a/Doxyfile b/Doxyfile
index 485b93d..f28fb70 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -31,7 +31,13 @@ PROJECT_NAME = Libav
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 0.7.1
+PROJECT_NUMBER =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will
+# copy the logo to the output directory.
+PROJECT_LOGO =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
@@ -760,7 +766,7 @@ ALPHABETICAL_INDEX = YES
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
-COLS_IN_ALPHA_INDEX = 5
+COLS_IN_ALPHA_INDEX = 2
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
@@ -794,13 +800,13 @@ HTML_FILE_EXTENSION = .html
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
-HTML_HEADER =
+HTML_HEADER = doc/doxy/header.html
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
-HTML_FOOTER =
+HTML_FOOTER = doc/doxy/footer.html
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to
@@ -809,7 +815,7 @@ HTML_FOOTER =
# the style sheet file to the HTML output directory, so don't put your own
# stylesheet in the HTML output directory as well, or it will be erased!
-HTML_STYLESHEET =
+HTML_STYLESHEET = doc/doxy/doxy_stylesheet.css
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
# Doxygen will adjust the colors in the stylesheet and background images
@@ -819,7 +825,7 @@ HTML_STYLESHEET =
# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
# The allowed range is 0 to 359.
-HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_HUE = 120
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
# the colors in the HTML output. For a value of 0 the output will use
@@ -1382,7 +1388,8 @@ PREDEFINED = "__attribute__(x)=" \
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
-EXPAND_AS_DEFINED = declare_idct
+EXPAND_AS_DEFINED = declare_idct \
+ READ_PAR_DATA \
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all function-like macros that are alone
diff --git a/Makefile b/Makefile
index d29872f..19b8df4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,34 +1,74 @@
include config.mak
-SRC_DIR = $(SRC_PATH_BARE)
+vpath %.c $(SRC_PATH)
+vpath %.h $(SRC_PATH)
+vpath %.S $(SRC_PATH)
+vpath %.asm $(SRC_PATH)
+vpath %.v $(SRC_PATH)
+vpath %.texi $(SRC_PATH)
+
+ifndef V
+Q = @
+ECHO = printf "$(1)\t%s\n" $(2)
+BRIEF = CC AS YASM AR LD HOSTCC
+SILENT = DEPCC YASMDEP RM RANLIB
+MSG = $@
+M = @$(call ECHO,$(TAG),$@);
+$(foreach VAR,$(BRIEF), \
+ $(eval override $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR))))
+$(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))
+$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_PATH)/%=%)); $(INSTALL))
+endif
+
+ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale
+
+IFLAGS := -I. -I$(SRC_PATH)
+CPPFLAGS := $(IFLAGS) $(CPPFLAGS)
+CFLAGS += $(ECFLAGS)
+CCFLAGS = $(CFLAGS)
+YASMFLAGS += $(IFLAGS) -I$(SRC_PATH)/libavutil/x86/ -Pconfig.asm
+HOSTCFLAGS += $(IFLAGS)
+LDFLAGS := $(ALLFFLIBS:%=-Llib%) $(LDFLAGS)
+
+define COMPILE
+ $($(1)DEP)
+ $($(1)) $(CPPFLAGS) $($(1)FLAGS) $($(1)_DEPFLAGS) -c $($(1)_O) $<
+endef
+
+COMPILE_C = $(call COMPILE,CC)
+COMPILE_S = $(call COMPILE,AS)
+
+%.o: %.c
+ $(COMPILE_C)
-vpath %.c $(SRC_DIR)
-vpath %.h $(SRC_DIR)
-vpath %.S $(SRC_DIR)
-vpath %.asm $(SRC_DIR)
-vpath %.v $(SRC_DIR)
-vpath %.texi $(SRC_PATH_BARE)
+%.o: %.S
+ $(COMPILE_S)
+
+%.ho: %.h
+ $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused -c -o $@ -x c $<
+
+%.ver: %.v
+ $(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@
+
+%.c %.h: TAG = GEN
PROGS-$(CONFIG_FFMPEG) += ffmpeg
-PROGS-$(CONFIG_FFPLAY) += ffplay
-PROGS-$(CONFIG_FFPROBE) += ffprobe
-PROGS-$(CONFIG_FFSERVER) += ffserver
+PROGS-$(CONFIG_AVCONV) += avconv
+PROGS-$(CONFIG_AVPLAY) += avplay
+PROGS-$(CONFIG_AVPROBE) += avprobe
+PROGS-$(CONFIG_AVSERVER) += avserver
PROGS := $(PROGS-yes:%=%$(EXESUF))
OBJS = $(PROGS-yes:%=%.o) cmdutils.o
-MANPAGES = $(PROGS-yes:%=doc/%.1)
-PODPAGES = $(PROGS-yes:%=doc/%.pod)
-HTMLPAGES = $(PROGS-yes:%=doc/%.html)
-TOOLS = $(addprefix tools/, $(addsuffix $(EXESUF), cws2fws graph2dot lavfi-showfiltfmts pktdumper probetest qt-faststart trasher))
TESTTOOLS = audiogen videogen rotozoom tiny_psnr base64
HOSTPROGS := $(TESTTOOLS:%=tests/%)
+TOOLS = qt-faststart trasher
+TOOLS-$(CONFIG_ZLIB) += cws2fws
-BASENAMES = ffmpeg ffplay ffprobe ffserver
+BASENAMES = ffmpeg avconv avplay avprobe avserver
ALLPROGS = $(BASENAMES:%=%$(EXESUF))
ALLMANPAGES = $(BASENAMES:%=%.1)
-ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale
-
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
FFLIBS-$(CONFIG_AVFILTER) += avfilter
FFLIBS-$(CONFIG_AVFORMAT) += avformat
@@ -38,29 +78,31 @@ FFLIBS-$(CONFIG_SWSCALE) += swscale
FFLIBS := avutil
-DATA_FILES := $(wildcard $(SRC_DIR)/ffpresets/*.ffpreset)
+DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.avpreset)
SKIPHEADERS = cmdutils_common_opts.h
-include common.mak
+include $(SRC_PATH)/common.mak
-FF_LDFLAGS := $(FFLDFLAGS)
FF_EXTRALIBS := $(FFEXTRALIBS)
FF_DEP_LIBS := $(DEP_LIBS)
-all-$(CONFIG_DOC): documentation
+all: $(PROGS)
+
+$(TOOLS): %$(EXESUF): %.o
+ $(LD) $(LDFLAGS) -o $@ $< $(ELIBS)
-all: $(FF_DEP_LIBS) $(PROGS)
+tools/cws2fws$(EXESUF): ELIBS = -lz
config.h: .config
-.config: $(wildcard $(FFLIBS:%=$(SRC_DIR)/lib%/all*.c))
+.config: $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c))
@-tput bold 2>/dev/null
@-printf '\nWARNING: $(?F) newer than config.h, rerun configure\n\n'
@-tput sgr0 2>/dev/null
SUBDIR_VARS := OBJS FFLIBS CLEANFILES DIRS TESTPROGS EXAMPLES SKIPHEADERS \
ALTIVEC-OBJS MMX-OBJS NEON-OBJS X86-OBJS YASM-OBJS-FFT YASM-OBJS \
- HOSTPROGS BUILT_HEADERS TESTOBJS ARCH_HEADERS ARMV6-OBJS
+ HOSTPROGS BUILT_HEADERS TESTOBJS ARCH_HEADERS ARMV6-OBJS TOOLS
define RESET
$(1) :=
@@ -70,31 +112,25 @@ endef
define DOSUBDIR
$(foreach V,$(SUBDIR_VARS),$(eval $(call RESET,$(V))))
SUBDIR := $(1)/
-include $(1)/Makefile
+include $(SRC_PATH)/$(1)/Makefile
+include $(SRC_PATH)/library.mak
endef
$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))
-ffplay.o: CFLAGS += $(SDL_CFLAGS)
-ffplay$(EXESUF): FF_EXTRALIBS += $(SDL_LIBS)
-ffserver$(EXESUF): FF_LDFLAGS += $(FFSERVERLDFLAGS)
+avplay.o: CFLAGS += $(SDL_CFLAGS)
+avplay$(EXESUF): FF_EXTRALIBS += $(SDL_LIBS)
+avserver$(EXESUF): LDFLAGS += $(AVSERVERLDFLAGS)
$(PROGS): %$(EXESUF): %.o cmdutils.o $(FF_DEP_LIBS)
- $(LD) $(FF_LDFLAGS) -o $@ $< cmdutils.o $(FF_EXTRALIBS)
-
-alltools: $(TOOLS)
+ $(LD) $(LDFLAGS) -o $@ $< cmdutils.o $(FF_EXTRALIBS)
-tools/%$(EXESUF): tools/%.o
- $(LD) $(FF_LDFLAGS) -o $@ $< $(FF_EXTRALIBS)
-
-tools/%.o: tools/%.c
- $(CC) $(CPPFLAGS) $(CFLAGS) -c $(CC_O) $<
+OBJDIRS += tools
-include $(wildcard tools/*.d)
--include $(wildcard tests/*.d)
-VERSION_SH = $(SRC_PATH_BARE)/version.sh
-GIT_LOG = $(SRC_PATH_BARE)/.git/logs/HEAD
+VERSION_SH = $(SRC_PATH)/version.sh
+GIT_LOG = $(SRC_PATH)/.git/logs/HEAD
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak
.version: M=@
@@ -106,28 +142,6 @@ version.h .version:
# force version.sh to run whenever version might have changed
-include .version
-DOCS = $(addprefix doc/, developer.html faq.html general.html libavfilter.html) $(HTMLPAGES) $(MANPAGES) $(PODPAGES)
-
-documentation: $(DOCS)
-
--include $(wildcard $(DOCS:%=%.d))
-
-TEXIDEP = awk '/^@include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d)
-
-doc/%.html: TAG = HTML
-doc/%.html: doc/%.texi $(SRC_PATH_BARE)/doc/t2h.init
- $(Q)$(TEXIDEP)
- $(M)texi2html -monolithic --init-file $(SRC_PATH_BARE)/doc/t2h.init --output $@ $<
-
-doc/%.pod: TAG = POD
-doc/%.pod: doc/%.texi
- $(Q)$(TEXIDEP)
- $(M)doc/texi2pod.pl $< $@
-
-doc/%.1: TAG = MAN
-doc/%.1: doc/%.pod
- $(M)pod2man --section=1 --center=" " --release=" " $< > $@
-
ifdef PROGS
install: install-progs install-data
endif
@@ -137,7 +151,6 @@ install: install-libs install-headers
install-libs: install-libs-yes
install-progs-yes:
-install-progs-$(CONFIG_DOC): install-man
install-progs-$(CONFIG_SHARED): install-libs
install-progs: install-progs-yes $(PROGS)
@@ -148,11 +161,7 @@ install-data: $(DATA_FILES)
$(Q)mkdir -p "$(DATADIR)"
$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"
-install-man: $(MANPAGES)
- $(Q)mkdir -p "$(MANDIR)/man1"
- $(INSTALL) -m 644 $(MANPAGES) "$(MANDIR)/man1"
-
-uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data uninstall-man
+uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
uninstall-progs:
$(RM) $(addprefix "$(BINDIR)/", $(ALLPROGS))
@@ -160,19 +169,9 @@ uninstall-progs:
uninstall-data:
$(RM) -r "$(DATADIR)"
-uninstall-man:
- $(RM) $(addprefix "$(MANDIR)/man1/",$(ALLMANPAGES))
-
-testclean:
- $(RM) -r tests/vsynth1 tests/vsynth2 tests/data
- $(RM) $(addprefix tests/,$(CLEANSUFFIXES))
- $(RM) tests/seek_test$(EXESUF) tests/seek_test.o
- $(RM) $(TESTTOOLS:%=tests/%$(HOSTEXESUF))
-
-clean:: testclean
+clean::
$(RM) $(ALLPROGS)
$(RM) $(CLEANSUFFIXES)
- $(RM) doc/*.html doc/*.pod doc/*.1 doc/*.d doc/*~
$(RM) $(TOOLS)
$(RM) $(CLEANSUFFIXES:%=tools/%)
@@ -183,122 +182,19 @@ distclean::
config:
$(SRC_PATH)/configure $(value LIBAV_CONFIGURATION)
-# regression tests
-
-check: test checkheaders
-
-fulltest test: codectest lavftest lavfitest seektest
-
-FFSERVER_REFFILE = $(SRC_PATH)/tests/ffserver.regression.ref
-
-codectest: fate-codec
-lavftest: fate-lavf
-lavfitest: fate-lavfi
-seektest: fate-seek
-
-AREF = fate-acodec-aref
-VREF = fate-vsynth1-vref fate-vsynth2-vref
-REFS = $(AREF) $(VREF)
-
-$(VREF): ffmpeg$(EXESUF) tests/vsynth1/00.pgm tests/vsynth2/00.pgm
-$(AREF): ffmpeg$(EXESUF) tests/data/asynth1.sw
-
-ffservertest: ffserver$(EXESUF) tests/vsynth1/00.pgm tests/data/asynth1.sw
- @echo
- @echo "Unfortunately ffserver is broken and therefore its regression"
- @echo "test fails randomly. Treat the results accordingly."
- @echo
- $(SRC_PATH)/tests/ffserver-regression.sh $(FFSERVER_REFFILE) $(SRC_PATH)/tests/ffserver.conf
-
-tests/vsynth1/00.pgm: tests/videogen$(HOSTEXESUF)
- @mkdir -p tests/vsynth1
- $(M)./$< 'tests/vsynth1/'
-
-tests/vsynth2/00.pgm: tests/rotozoom$(HOSTEXESUF)
- @mkdir -p tests/vsynth2
- $(M)./$< 'tests/vsynth2/' $(SRC_PATH)/tests/lena.pnm
-
-tests/data/asynth1.sw: tests/audiogen$(HOSTEXESUF)
- @mkdir -p tests/data
- $(M)./$< $@
-
-tests/data/asynth1.sw tests/vsynth%/00.pgm: TAG = GEN
-
-tests/seek_test$(EXESUF): tests/seek_test.o $(FF_DEP_LIBS)
- $(LD) $(FF_LDFLAGS) -o $@ $< $(FF_EXTRALIBS)
-
-tools/lavfi-showfiltfmts$(EXESUF): tools/lavfi-showfiltfmts.o $(FF_DEP_LIBS)
- $(LD) $(FF_LDFLAGS) -o $@ $< $(FF_EXTRALIBS)
-
-include $(SRC_PATH_BARE)/tests/fate.mak
-include $(SRC_PATH_BARE)/tests/fate2.mak
-
-include $(SRC_PATH_BARE)/tests/fate/aac.mak
-include $(SRC_PATH_BARE)/tests/fate/als.mak
-include $(SRC_PATH_BARE)/tests/fate/fft.mak
-include $(SRC_PATH_BARE)/tests/fate/h264.mak
-include $(SRC_PATH_BARE)/tests/fate/mp3.mak
-include $(SRC_PATH_BARE)/tests/fate/vorbis.mak
-include $(SRC_PATH_BARE)/tests/fate/vp8.mak
-
-FATE_ACODEC = $(ACODEC_TESTS:%=fate-acodec-%)
-FATE_VSYNTH1 = $(VCODEC_TESTS:%=fate-vsynth1-%)
-FATE_VSYNTH2 = $(VCODEC_TESTS:%=fate-vsynth2-%)
-FATE_VCODEC = $(FATE_VSYNTH1) $(FATE_VSYNTH2)
-FATE_LAVF = $(LAVF_TESTS:%=fate-lavf-%)
-FATE_LAVFI = $(LAVFI_TESTS:%=fate-lavfi-%)
-FATE_SEEK = $(SEEK_TESTS:seek_%=fate-seek-%)
-
-FATE = $(FATE_ACODEC) \
- $(FATE_VCODEC) \
- $(FATE_LAVF) \
- $(FATE_SEEK) \
-
-FATE-$(CONFIG_AVFILTER) += $(FATE_LAVFI)
-
-FATE += $(FATE-yes)
-
-$(filter-out %-aref,$(FATE_ACODEC)): $(AREF)
-$(filter-out %-vref,$(FATE_VCODEC)): $(VREF)
-$(FATE_LAVF): $(REFS)
-$(FATE_LAVFI): $(REFS) tools/lavfi-showfiltfmts$(EXESUF)
-$(FATE_SEEK): fate-codec fate-lavf tests/seek_test$(EXESUF)
-
-$(FATE_ACODEC): CMD = codectest acodec
-$(FATE_VSYNTH1): CMD = codectest vsynth1
-$(FATE_VSYNTH2): CMD = codectest vsynth2
-$(FATE_LAVF): CMD = lavftest
-$(FATE_LAVFI): CMD = lavfitest
-$(FATE_SEEK): CMD = seektest
-
-fate-codec: fate-acodec fate-vcodec
-fate-acodec: $(FATE_ACODEC)
-fate-vcodec: $(FATE_VCODEC)
-fate-lavf: $(FATE_LAVF)
-fate-lavfi: $(FATE_LAVFI)
-fate-seek: $(FATE_SEEK)
-
-ifdef SAMPLES
-FATE += $(FATE_TESTS) $(FATE_TESTS-yes)
-fate-rsync:
- rsync -vaLW rsync://fate-suite.libav.org/fate-suite/ $(SAMPLES)
-else
-fate-rsync:
- @echo "use 'make fate-rsync SAMPLES=/path/to/samples' to sync the fate suite"
-$(FATE_TESTS):
- @echo "SAMPLES not specified, cannot run FATE"
-endif
-
-FATE_UTILS = base64 tiny_psnr
+include $(SRC_PATH)/doc/Makefile
+include $(SRC_PATH)/tests/Makefile
-fate: $(FATE)
+$(sort $(OBJDIRS)):
+ $(Q)mkdir -p $@
-$(FATE): ffmpeg$(EXESUF) $(FATE_UTILS:%=tests/%$(HOSTEXESUF))
- @echo "TEST $(@:fate-%=%)"
- $(Q)$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)' '$(CMP)' '$(REF)' '$(FUZZ)' '$(THREADS)' '$(THREAD_TYPE)'
+# Dummy rule to stop make trying to rebuild removed or renamed headers
+%.h:
+ @:
-fate-list:
- @printf '%s\n' $(sort $(FATE))
+# Disable suffix rules. Most of the builtin rules are suffix rules,
+# so this saves some time on slow systems.
+.SUFFIXES:
-.PHONY: all alltools *clean check config documentation examples install*
-.PHONY: *test testprogs uninstall*
+.PHONY: all all-yes alltools *clean config examples install*
+.PHONY: testprogs uninstall*
diff --git a/RELEASE b/RELEASE
index f38fc53..8e0f8bc 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-0.7.3
+0.8_beta1
diff --git a/VERSION b/VERSION
deleted file mode 100644
index f38fc53..0000000
--- a/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-0.7.3
diff --git a/avconv.c b/avconv.c
new file mode 100644
index 0000000..f3e6e28
--- /dev/null
+++ b/avconv.c
@@ -0,0 +1,4477 @@
+/*
+ * avconv main
+ * Copyright (c) 2000-2011 The libav developers.
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <signal.h>
+#include <limits.h>
+#include <unistd.h>
+#include "libavformat/avformat.h"
+#include "libavdevice/avdevice.h"
+#include "libswscale/swscale.h"
+#include "libavutil/opt.h"
+#include "libavcodec/audioconvert.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/samplefmt.h"
+#include "libavutil/colorspace.h"
+#include "libavutil/fifo.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/avstring.h"
+#include "libavutil/libm.h"
+#include "libavutil/imgutils.h"
+#include "libavformat/os_support.h"
+
+#if CONFIG_AVFILTER
+# include "libavfilter/avfilter.h"
+# include "libavfilter/avfiltergraph.h"
+# include "libavfilter/buffersrc.h"
+# include "libavfilter/vsrc_buffer.h"
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#elif HAVE_GETPROCESSTIMES
+#include <windows.h>
+#endif
+#if HAVE_GETPROCESSMEMORYINFO
+#include <windows.h>
+#include <psapi.h>
+#endif
+
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include <time.h>
+
+#include "cmdutils.h"
+
+#include "libavutil/avassert.h"
+
+const char program_name[] = "avconv";
+const int program_birth_year = 2000;
+
+/* select an input stream for an output stream */
+typedef struct StreamMap {
+ int disabled; /** 1 is this mapping is disabled by a negative map */
+ int file_index;
+ int stream_index;
+ int sync_file_index;
+ int sync_stream_index;
+} StreamMap;
+
+/**
+ * select an input file for an output file
+ */
+typedef struct MetadataMap {
+ int file; ///< file index
+ char type; ///< type of metadata to copy -- (g)lobal, (s)tream, (c)hapter or (p)rogram
+ int index; ///< stream/chapter/program number
+} MetadataMap;
+
+static const OptionDef options[];
+
+static int video_discard = 0;
+static int same_quant = 0;
+static int do_deinterlace = 0;
+static int intra_dc_precision = 8;
+static int qp_hist = 0;
+
+static int file_overwrite = 0;
+static int do_benchmark = 0;
+static int do_hex_dump = 0;
+static int do_pkt_dump = 0;
+static int do_pass = 0;
+static char *pass_logfilename_prefix = NULL;
+static int video_sync_method = -1;
+static int audio_sync_method = 0;
+static float audio_drift_threshold = 0.1;
+static int copy_ts = 0;
+static int copy_tb = 1;
+static int opt_shortest = 0;
+static char *vstats_filename;
+static FILE *vstats_file;
+
+static int audio_volume = 256;
+
+static int exit_on_error = 0;
+static int using_stdin = 0;
+static int64_t video_size = 0;
+static int64_t audio_size = 0;
+static int64_t extra_size = 0;
+static int nb_frames_dup = 0;
+static int nb_frames_drop = 0;
+static int input_sync;
+
+static float dts_delta_threshold = 10;
+
+static int print_stats = 1;
+
+static uint8_t *audio_buf;
+static uint8_t *audio_out;
+static unsigned int allocated_audio_out_size, allocated_audio_buf_size;
+
+#define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass"
+
+typedef struct FrameBuffer {
+ uint8_t *base[4];
+ uint8_t *data[4];
+ int linesize[4];
+
+ int h, w;
+ enum PixelFormat pix_fmt;
+
+ int refcount;
+ struct InputStream *ist;
+ struct FrameBuffer *next;
+} FrameBuffer;
+
+typedef struct InputStream {
+ int file_index;
+ AVStream *st;
+ int discard; /* true if stream data should be discarded */
+ int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
+ AVCodec *dec;
+ AVFrame *decoded_frame;
+ AVFrame *filtered_frame;
+
+ int64_t start; /* time when read started */
+ int64_t next_pts; /* synthetic pts for cases where pkt.pts
+ is not defined */
+ int64_t pts; /* current pts */
+ PtsCorrectionContext pts_ctx;
+ double ts_scale;
+ int is_start; /* is 1 at the start and after a discontinuity */
+ int showed_multi_packet_warning;
+ AVDictionary *opts;
+
+ /* a pool of free buffers for decoded data */
+ FrameBuffer *buffer_pool;
+} InputStream;
+
+typedef struct InputFile {
+ AVFormatContext *ctx;
+ int eof_reached; /* true if eof reached */
+ int ist_index; /* index of first stream in ist_table */
+ int buffer_size; /* current total buffer size */
+ int64_t ts_offset;
+ int nb_streams; /* number of stream that avconv is aware of; may be different
+ from ctx.nb_streams if new streams appear during av_read_frame() */
+ int rate_emu;
+} InputFile;
+
+typedef struct OutputStream {
+ int file_index; /* file index */
+ int index; /* stream index in the output file */
+ int source_index; /* InputStream index */
+ AVStream *st; /* stream in the output file */
+ int encoding_needed; /* true if encoding needed for this stream */
+ int frame_number;
+ /* input pts and corresponding output pts
+ for A/V sync */
+ // double sync_ipts; /* dts from the AVPacket of the demuxer in second units */
+ struct InputStream *sync_ist; /* input stream to sync against */
+ int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number
+ AVBitStreamFilterContext *bitstream_filters;
+ AVCodec *enc;
+ int64_t max_frames;
+
+ /* video only */
+ int video_resample;
+ AVFrame pict_tmp; /* temporary image for resampling */
+ struct SwsContext *img_resample_ctx; /* for image resampling */
+ int resample_height;
+ int resample_width;
+ int resample_pix_fmt;
+ AVRational frame_rate;
+ int force_fps;
+ int top_field_first;
+
+ float frame_aspect_ratio;
+
+ /* forced key frames */
+ int64_t *forced_kf_pts;
+ int forced_kf_count;
+ int forced_kf_index;
+
+ /* audio only */
+ int audio_resample;
+ ReSampleContext *resample; /* for audio resampling */
+ int resample_sample_fmt;
+ int resample_channels;
+ int resample_sample_rate;
+ int reformat_pair;
+ AVAudioConvert *reformat_ctx;
+ AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */
+ FILE *logfile;
+
+#if CONFIG_AVFILTER
+ AVFilterContext *output_video_filter;
+ AVFilterContext *input_video_filter;
+ AVFilterBufferRef *picref;
+ char *avfilter;
+ AVFilterGraph *graph;
+#endif
+
+ int64_t sws_flags;
+ AVDictionary *opts;
+ int is_past_recording_time;
+ int stream_copy;
+ const char *attachment_filename;
+ int copy_initial_nonkeyframes;
+} OutputStream;
+
+
+typedef struct OutputFile {
+ AVFormatContext *ctx;
+ AVDictionary *opts;
+ int ost_index; /* index of the first stream in output_streams */
+ int64_t recording_time; /* desired length of the resulting file in microseconds */
+ int64_t start_time; /* start time in microseconds */
+ uint64_t limit_filesize;
+} OutputFile;
+
+static InputStream *input_streams = NULL;
+static int nb_input_streams = 0;
+static InputFile *input_files = NULL;
+static int nb_input_files = 0;
+
+static OutputStream *output_streams = NULL;
+static int nb_output_streams = 0;
+static OutputFile *output_files = NULL;
+static int nb_output_files = 0;
+
+typedef struct OptionsContext {
+ /* input/output options */
+ int64_t start_time;
+ const char *format;
+
+ SpecifierOpt *codec_names;
+ int nb_codec_names;
+ SpecifierOpt *audio_channels;
+ int nb_audio_channels;
+ SpecifierOpt *audio_sample_rate;
+ int nb_audio_sample_rate;
+ SpecifierOpt *frame_rates;
+ int nb_frame_rates;
+ SpecifierOpt *frame_sizes;
+ int nb_frame_sizes;
+ SpecifierOpt *frame_pix_fmts;
+ int nb_frame_pix_fmts;
+
+ /* input options */
+ int64_t input_ts_offset;
+ int rate_emu;
+
+ SpecifierOpt *ts_scale;
+ int nb_ts_scale;
+ SpecifierOpt *dump_attachment;
+ int nb_dump_attachment;
+
+ /* output options */
+ StreamMap *stream_maps;
+ int nb_stream_maps;
+ /* first item specifies output metadata, second is input */
+ MetadataMap (*meta_data_maps)[2];
+ int nb_meta_data_maps;
+ int metadata_global_manual;
+ int metadata_streams_manual;
+ int metadata_chapters_manual;
+ const char **attachments;
+ int nb_attachments;
+
+ int chapters_input_file;
+
+ int64_t recording_time;
+ uint64_t limit_filesize;
+ float mux_preload;
+ float mux_max_delay;
+
+ int video_disable;
+ int audio_disable;
+ int subtitle_disable;
+ int data_disable;
+
+ /* indexed by output file stream index */
+ int *streamid_map;
+ int nb_streamid_map;
+
+ SpecifierOpt *metadata;
+ int nb_metadata;
+ SpecifierOpt *max_frames;
+ int nb_max_frames;
+ SpecifierOpt *bitstream_filters;
+ int nb_bitstream_filters;
+ SpecifierOpt *codec_tags;
+ int nb_codec_tags;
+ SpecifierOpt *sample_fmts;
+ int nb_sample_fmts;
+ SpecifierOpt *qscale;
+ int nb_qscale;
+ SpecifierOpt *forced_key_frames;
+ int nb_forced_key_frames;
+ SpecifierOpt *force_fps;
+ int nb_force_fps;
+ SpecifierOpt *frame_aspect_ratios;
+ int nb_frame_aspect_ratios;
+ SpecifierOpt *rc_overrides;
+ int nb_rc_overrides;
+ SpecifierOpt *intra_matrices;
+ int nb_intra_matrices;
+ SpecifierOpt *inter_matrices;
+ int nb_inter_matrices;
+ SpecifierOpt *top_field_first;
+ int nb_top_field_first;
+ SpecifierOpt *metadata_map;
+ int nb_metadata_map;
+ SpecifierOpt *presets;
+ int nb_presets;
+ SpecifierOpt *copy_initial_nonkeyframes;
+ int nb_copy_initial_nonkeyframes;
+#if CONFIG_AVFILTER
+ SpecifierOpt *filters;
+ int nb_filters;
+#endif
+} OptionsContext;
+
+#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
+{\
+ int i, ret;\
+ for (i = 0; i < o->nb_ ## name; i++) {\
+ char *spec = o->name[i].specifier;\
+ if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
+ outvar = o->name[i].u.type;\
+ else if (ret < 0)\
+ exit_program(1);\
+ }\
+}
+
+static void reset_options(OptionsContext *o)
+{
+ const OptionDef *po = options;
+
+ /* all OPT_SPEC and OPT_STRING can be freed in generic way */
+ while (po->name) {
+ void *dst = (uint8_t*)o + po->u.off;
+
+ if (po->flags & OPT_SPEC) {
+ SpecifierOpt **so = dst;
+ int i, *count = (int*)(so + 1);
+ for (i = 0; i < *count; i++) {
+ av_freep(&(*so)[i].specifier);
+ if (po->flags & OPT_STRING)
+ av_freep(&(*so)[i].u.str);
+ }
+ av_freep(so);
+ *count = 0;
+ } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
+ av_freep(dst);
+ po++;
+ }
+
+ av_freep(&o->stream_maps);
+ av_freep(&o->meta_data_maps);
+ av_freep(&o->streamid_map);
+
+ memset(o, 0, sizeof(*o));
+
+ o->mux_max_delay = 0.7;
+ o->recording_time = INT64_MAX;
+ o->limit_filesize = UINT64_MAX;
+ o->chapters_input_file = INT_MAX;
+
+ uninit_opts();
+ init_opts();
+}
+
+static int alloc_buffer(InputStream *ist, FrameBuffer **pbuf)
+{
+ AVCodecContext *s = ist->st->codec;
+ FrameBuffer *buf = av_mallocz(sizeof(*buf));
+ int ret;
+ const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1;
+ int h_chroma_shift, v_chroma_shift;
+ int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1
+ int w = s->width, h = s->height;
+
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
+ w += 2*edge;
+ h += 2*edge;
+ }
+
+ avcodec_align_dimensions(s, &w, &h);
+ if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,
+ s->pix_fmt, 32)) < 0) {
+ av_freep(&buf);
+ return ret;
+ }
+ /* XXX this shouldn't be needed, but some tests break without this line
+ * those decoders are buggy and need to be fixed.
+ * the following tests fail:
+ * bethsoft-vid, cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
+ */
+ memset(buf->base[0], 128, ret);
+
+ avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
+ for (int i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
+ const int h_shift = i==0 ? 0 : h_chroma_shift;
+ const int v_shift = i==0 ? 0 : v_chroma_shift;
+ if (s->flags & CODEC_FLAG_EMU_EDGE)
+ buf->data[i] = buf->base[i];
+ else
+ buf->data[i] = buf->base[i] +
+ FFALIGN((buf->linesize[i]*edge >> v_shift) +
+ (pixel_size*edge >> h_shift), 32);
+ }
+ buf->w = s->width;
+ buf->h = s->height;
+ buf->pix_fmt = s->pix_fmt;
+ buf->ist = ist;
+
+ *pbuf = buf;
+ return 0;
+}
+
+static void free_buffer_pool(InputStream *ist)
+{
+ FrameBuffer *buf = ist->buffer_pool;
+ while (buf) {
+ ist->buffer_pool = buf->next;
+ av_freep(&buf->base[0]);
+ av_free(buf);
+ buf = ist->buffer_pool;
+ }
+}
+
+static void unref_buffer(InputStream *ist, FrameBuffer *buf)
+{
+ av_assert0(buf->refcount);
+ buf->refcount--;
+ if (!buf->refcount) {
+ buf->next = ist->buffer_pool;
+ ist->buffer_pool = buf;
+ }
+}
+
+static int codec_get_buffer(AVCodecContext *s, AVFrame *frame)
+{
+ InputStream *ist = s->opaque;
+ FrameBuffer *buf;
+ int ret, i;
+
+ if (!ist->buffer_pool && (ret = alloc_buffer(ist, &ist->buffer_pool)) < 0)
+ return ret;
+
+ buf = ist->buffer_pool;
+ ist->buffer_pool = buf->next;
+ buf->next = NULL;
+ if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) {
+ av_freep(&buf->base[0]);
+ av_free(buf);
+ if ((ret = alloc_buffer(ist, &buf)) < 0)
+ return ret;
+ }
+ buf->refcount++;
+
+ frame->opaque = buf;
+ frame->type = FF_BUFFER_TYPE_USER;
+ frame->extended_data = frame->data;
+ frame->pkt_pts = s->pkt ? s->pkt->pts : AV_NOPTS_VALUE;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
+ frame->base[i] = buf->base[i]; // XXX h264.c uses base though it shouldn't
+ frame->data[i] = buf->data[i];
+ frame->linesize[i] = buf->linesize[i];
+ }
+
+ return 0;
+}
+
+static void codec_release_buffer(AVCodecContext *s, AVFrame *frame)
+{
+ InputStream *ist = s->opaque;
+ FrameBuffer *buf = frame->opaque;
+ int i;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
+ frame->data[i] = NULL;
+
+ unref_buffer(ist, buf);
+}
+
+static void filter_release_buffer(AVFilterBuffer *fb)
+{
+ FrameBuffer *buf = fb->priv;
+ av_free(fb);
+ unref_buffer(buf->ist, buf);
+}
+
+#if CONFIG_AVFILTER
+
+static int configure_video_filters(InputStream *ist, OutputStream *ost)
+{
+ AVFilterContext *last_filter, *filter;
+ /** filter graph containing all filters including input & output */
+ AVCodecContext *codec = ost->st->codec;
+ AVCodecContext *icodec = ist->st->codec;
+ FFSinkContext ffsink_ctx = { .pix_fmt = codec->pix_fmt };
+ AVRational sample_aspect_ratio;
+ char args[255];
+ int ret;
+
+ ost->graph = avfilter_graph_alloc();
+
+ if (ist->st->sample_aspect_ratio.num) {
+ sample_aspect_ratio = ist->st->sample_aspect_ratio;
+ } else
+ sample_aspect_ratio = ist->st->codec->sample_aspect_ratio;
+
+ snprintf(args, 255, "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width,
+ ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE,
+ sample_aspect_ratio.num, sample_aspect_ratio.den);
+
+ ret = avfilter_graph_create_filter(&ost->input_video_filter, avfilter_get_by_name("buffer"),
+ "src", args, NULL, ost->graph);
+ if (ret < 0)
+ return ret;
+ ret = avfilter_graph_create_filter(&ost->output_video_filter, &ffsink,
+ "out", NULL, &ffsink_ctx, ost->graph);
+ if (ret < 0)
+ return ret;
+ last_filter = ost->input_video_filter;
+
+ if (codec->width != icodec->width || codec->height != icodec->height) {
+ snprintf(args, 255, "%d:%d:flags=0x%X",
+ codec->width,
+ codec->height,
+ (unsigned)ost->sws_flags);
+ if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
+ NULL, args, NULL, ost->graph)) < 0)
+ return ret;
+ if ((ret = avfilter_link(last_filter, 0, filter, 0)) < 0)
+ return ret;
+ last_filter = filter;
+ }
+
+ snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
+ ost->graph->scale_sws_opts = av_strdup(args);
+
+ if (ost->avfilter) {
+ AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
+ AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut));
+
+ outputs->name = av_strdup("in");
+ outputs->filter_ctx = last_filter;
+ outputs->pad_idx = 0;
+ outputs->next = NULL;
+
+ inputs->name = av_strdup("out");
+ inputs->filter_ctx = ost->output_video_filter;
+ inputs->pad_idx = 0;
+ inputs->next = NULL;
+
+ if ((ret = avfilter_graph_parse(ost->graph, ost->avfilter, inputs, outputs, NULL)) < 0)
+ return ret;
+ av_freep(&ost->avfilter);
+ } else {
+ if ((ret = avfilter_link(last_filter, 0, ost->output_video_filter, 0)) < 0)
+ return ret;
+ }
+
+ if ((ret = avfilter_graph_config(ost->graph, NULL)) < 0)
+ return ret;
+
+ codec->width = ost->output_video_filter->inputs[0]->w;
+ codec->height = ost->output_video_filter->inputs[0]->h;
+ codec->sample_aspect_ratio = ost->st->sample_aspect_ratio =
+ ost->frame_aspect_ratio ? // overridden by the -aspect cli option
+ av_d2q(ost->frame_aspect_ratio * codec->height/codec->width, 255) :
+ ost->output_video_filter->inputs[0]->sample_aspect_ratio;
+
+ return 0;
+}
+#endif /* CONFIG_AVFILTER */
+
+static void term_exit(void)
+{
+ av_log(NULL, AV_LOG_QUIET, "");
+}
+
+static volatile int received_sigterm = 0;
+static volatile int received_nb_signals = 0;
+
+static void
+sigterm_handler(int sig)
+{
+ received_sigterm = sig;
+ received_nb_signals++;
+ term_exit();
+}
+
+static void term_init(void)
+{
+ signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */
+ signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */
+#ifdef SIGXCPU
+ signal(SIGXCPU, sigterm_handler);
+#endif
+}
+
+static int decode_interrupt_cb(void *ctx)
+{
+ return received_nb_signals > 1;
+}
+
+static const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
+
+void exit_program(int ret)
+{
+ int i;
+
+ /* close files */
+ for (i = 0; i < nb_output_files; i++) {
+ AVFormatContext *s = output_files[i].ctx;
+ if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
+ avio_close(s->pb);
+ avformat_free_context(s);
+ av_dict_free(&output_files[i].opts);
+ }
+ for (i = 0; i < nb_input_files; i++) {
+ avformat_close_input(&input_files[i].ctx);
+ }
+ for (i = 0; i < nb_input_streams; i++) {
+ av_freep(&input_streams[i].decoded_frame);
+ av_freep(&input_streams[i].filtered_frame);
+ av_dict_free(&input_streams[i].opts);
+ free_buffer_pool(&input_streams[i]);
+ }
+
+ if (vstats_file)
+ fclose(vstats_file);
+ av_free(vstats_filename);
+
+ av_freep(&input_streams);
+ av_freep(&input_files);
+ av_freep(&output_streams);
+ av_freep(&output_files);
+
+ uninit_opts();
+ av_free(audio_buf);
+ av_free(audio_out);
+ allocated_audio_buf_size = allocated_audio_out_size = 0;
+
+#if CONFIG_AVFILTER
+ avfilter_uninit();
+#endif
+ avformat_network_deinit();
+
+ if (received_sigterm) {
+ av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",
+ (int) received_sigterm);
+ exit (255);
+ }
+
+ exit(ret);
+}
+
+static void assert_avoptions(AVDictionary *m)
+{
+ AVDictionaryEntry *t;
+ if ((t = av_dict_get(m, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+ av_log(NULL, AV_LOG_FATAL, "Option %s not found.\n", t->key);
+ exit_program(1);
+ }
+}
+
+static void assert_codec_experimental(AVCodecContext *c, int encoder)
+{
+ const char *codec_string = encoder ? "encoder" : "decoder";
+ AVCodec *codec;
+ if (c->codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
+ c->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+ av_log(NULL, AV_LOG_FATAL, "%s '%s' is experimental and might produce bad "
+ "results.\nAdd '-strict experimental' if you want to use it.\n",
+ codec_string, c->codec->name);
+ codec = encoder ? avcodec_find_encoder(c->codec->id) : avcodec_find_decoder(c->codec->id);
+ if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
+ av_log(NULL, AV_LOG_FATAL, "Or use the non experimental %s '%s'.\n",
+ codec_string, codec->name);
+ exit_program(1);
+ }
+}
+
+static void choose_sample_fmt(AVStream *st, AVCodec *codec)
+{
+ if (codec && codec->sample_fmts) {
+ const enum AVSampleFormat *p = codec->sample_fmts;
+ for (; *p != -1; p++) {
+ if (*p == st->codec->sample_fmt)
+ break;
+ }
+ if (*p == -1) {
+ av_log(NULL, AV_LOG_WARNING,
+ "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
+ av_get_sample_fmt_name(st->codec->sample_fmt),
+ codec->name,
+ av_get_sample_fmt_name(codec->sample_fmts[0]));
+ st->codec->sample_fmt = codec->sample_fmts[0];
+ }
+ }
+}
+
+/**
+ * Update the requested input sample format based on the output sample format.
+ * This is currently only used to request float output from decoders which
+ * support multiple sample formats, one of which is AV_SAMPLE_FMT_FLT.
+ * Ideally this will be removed in the future when decoders do not do format
+ * conversion and only output in their native format.
+ */
+static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec,
+ AVCodecContext *enc)
+{
+ /* if sample formats match or a decoder sample format has already been
+ requested, just return */
+ if (enc->sample_fmt == dec->sample_fmt ||
+ dec->request_sample_fmt > AV_SAMPLE_FMT_NONE)
+ return;
+
+ /* if decoder supports more than one output format */
+ if (dec_codec && dec_codec->sample_fmts &&
+ dec_codec->sample_fmts[0] != AV_SAMPLE_FMT_NONE &&
+ dec_codec->sample_fmts[1] != AV_SAMPLE_FMT_NONE) {
+ const enum AVSampleFormat *p;
+ int min_dec = -1, min_inc = -1;
+
+ /* find a matching sample format in the encoder */
+ for (p = dec_codec->sample_fmts; *p != AV_SAMPLE_FMT_NONE; p++) {
+ if (*p == enc->sample_fmt) {
+ dec->request_sample_fmt = *p;
+ return;
+ } else if (*p > enc->sample_fmt) {
+ min_inc = FFMIN(min_inc, *p - enc->sample_fmt);
+ } else
+ min_dec = FFMIN(min_dec, enc->sample_fmt - *p);
+ }
+
+ /* if none match, provide the one that matches quality closest */
+ dec->request_sample_fmt = min_inc > 0 ? enc->sample_fmt + min_inc :
+ enc->sample_fmt - min_dec;
+ }
+}
+
+static void choose_sample_rate(AVStream *st, AVCodec *codec)
+{
+ if (codec && codec->supported_samplerates) {
+ const int *p = codec->supported_samplerates;
+ int best = 0;
+ int best_dist = INT_MAX;
+ for (; *p; p++) {
+ int dist = abs(st->codec->sample_rate - *p);
+ if (dist < best_dist) {
+ best_dist = dist;
+ best = *p;
+ }
+ }
+ if (best_dist) {
+ av_log(st->codec, AV_LOG_WARNING, "Requested sampling rate unsupported using closest supported (%d)\n", best);
+ }
+ st->codec->sample_rate = best;
+ }
+}
+
+static void choose_pixel_fmt(AVStream *st, AVCodec *codec)
+{
+ if (codec && codec->pix_fmts) {
+ const enum PixelFormat *p = codec->pix_fmts;
+ if (st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
+ if (st->codec->codec_id == CODEC_ID_MJPEG) {
+ p = (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE };
+ } else if (st->codec->codec_id == CODEC_ID_LJPEG) {
+ p = (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ444P, PIX_FMT_YUV420P,
+ PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_BGRA, PIX_FMT_NONE };
+ }
+ }
+ for (; *p != PIX_FMT_NONE; p++) {
+ if (*p == st->codec->pix_fmt)
+ break;
+ }
+ if (*p == PIX_FMT_NONE) {
+ if (st->codec->pix_fmt != PIX_FMT_NONE)
+ av_log(NULL, AV_LOG_WARNING,
+ "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
+ av_pix_fmt_descriptors[st->codec->pix_fmt].name,
+ codec->name,
+ av_pix_fmt_descriptors[codec->pix_fmts[0]].name);
+ st->codec->pix_fmt = codec->pix_fmts[0];
+ }
+ }
+}
+
+static double
+get_sync_ipts(const OutputStream *ost)
+{
+ const InputStream *ist = ost->sync_ist;
+ OutputFile *of = &output_files[ost->file_index];
+ return (double)(ist->pts - of->start_time) / AV_TIME_BASE;
+}
+
+static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx, AVBitStreamFilterContext *bsfc)
+{
+ int ret;
+
+ while (bsfc) {
+ AVPacket new_pkt = *pkt;
+ int a = av_bitstream_filter_filter(bsfc, avctx, NULL,
+ &new_pkt.data, &new_pkt.size,
+ pkt->data, pkt->size,
+ pkt->flags & AV_PKT_FLAG_KEY);
+ if (a > 0) {
+ av_free_packet(pkt);
+ new_pkt.destruct = av_destruct_packet;
+ } else if (a < 0) {
+ av_log(NULL, AV_LOG_ERROR, "%s failed for stream %d, codec %s",
+ bsfc->filter->name, pkt->stream_index,
+ avctx->codec ? avctx->codec->name : "copy");
+ print_error("", a);
+ if (exit_on_error)
+ exit_program(1);
+ }
+ *pkt = new_pkt;
+
+ bsfc = bsfc->next;
+ }
+
+ ret = av_interleaved_write_frame(s, pkt);
+ if (ret < 0) {
+ print_error("av_interleaved_write_frame()", ret);
+ exit_program(1);
+ }
+}
+
+static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_t size)
+{
+ int fill_char = 0x00;
+ if (sample_fmt == AV_SAMPLE_FMT_U8)
+ fill_char = 0x80;
+ memset(buf, fill_char, size);
+}
+
+static void do_audio_out(AVFormatContext *s, OutputStream *ost,
+ InputStream *ist, AVFrame *decoded_frame)
+{
+ uint8_t *buftmp;
+ int64_t audio_out_size, audio_buf_size;
+
+ int size_out, frame_bytes, ret, resample_changed;
+ AVCodecContext *enc = ost->st->codec;
+ AVCodecContext *dec = ist->st->codec;
+ int osize = av_get_bytes_per_sample(enc->sample_fmt);
+ int isize = av_get_bytes_per_sample(dec->sample_fmt);
+ const int coded_bps = av_get_bits_per_sample(enc->codec->id);
+ uint8_t *buf = decoded_frame->data[0];
+ int size = decoded_frame->nb_samples * dec->channels * isize;
+ int64_t allocated_for_size = size;
+
+need_realloc:
+ audio_buf_size = (allocated_for_size + isize * dec->channels - 1) / (isize * dec->channels);
+ audio_buf_size = (audio_buf_size * enc->sample_rate + dec->sample_rate) / dec->sample_rate;
+ audio_buf_size = audio_buf_size * 2 + 10000; // safety factors for the deprecated resampling API
+ audio_buf_size = FFMAX(audio_buf_size, enc->frame_size);
+ audio_buf_size *= osize * enc->channels;
+
+ audio_out_size = FFMAX(audio_buf_size, enc->frame_size * osize * enc->channels);
+ if (coded_bps > 8 * osize)
+ audio_out_size = audio_out_size * coded_bps / (8*osize);
+ audio_out_size += FF_MIN_BUFFER_SIZE;
+
+ if (audio_out_size > INT_MAX || audio_buf_size > INT_MAX) {
+ av_log(NULL, AV_LOG_FATAL, "Buffer sizes too large\n");
+ exit_program(1);
+ }
+
+ av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size);
+ av_fast_malloc(&audio_out, &allocated_audio_out_size, audio_out_size);
+ if (!audio_buf || !audio_out) {
+ av_log(NULL, AV_LOG_FATAL, "Out of memory in do_audio_out\n");
+ exit_program(1);
+ }
+
+ if (enc->channels != dec->channels || enc->sample_rate != dec->sample_rate)
+ ost->audio_resample = 1;
+
+ resample_changed = ost->resample_sample_fmt != dec->sample_fmt ||
+ ost->resample_channels != dec->channels ||
+ ost->resample_sample_rate != dec->sample_rate;
+
+ if ((ost->audio_resample && !ost->resample) || resample_changed) {
+ if (resample_changed) {
+ av_log(NULL, AV_LOG_INFO, "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n",
+ ist->file_index, ist->st->index,
+ ost->resample_sample_rate, av_get_sample_fmt_name(ost->resample_sample_fmt), ost->resample_channels,
+ dec->sample_rate, av_get_sample_fmt_name(dec->sample_fmt), dec->channels);
+ ost->resample_sample_fmt = dec->sample_fmt;
+ ost->resample_channels = dec->channels;
+ ost->resample_sample_rate = dec->sample_rate;
+ if (ost->resample)
+ audio_resample_close(ost->resample);
+ }
+ /* if audio_sync_method is >1 the resampler is needed for audio drift compensation */
+ if (audio_sync_method <= 1 &&
+ ost->resample_sample_fmt == enc->sample_fmt &&
+ ost->resample_channels == enc->channels &&
+ ost->resample_sample_rate == enc->sample_rate) {
+ ost->resample = NULL;
+ ost->audio_resample = 0;
+ } else if (ost->audio_resample) {
+ if (dec->sample_fmt != AV_SAMPLE_FMT_S16)
+ av_log(NULL, AV_LOG_WARNING, "Using s16 intermediate sample format for resampling\n");
+ ost->resample = av_audio_resample_init(enc->channels, dec->channels,
+ enc->sample_rate, dec->sample_rate,
+ enc->sample_fmt, dec->sample_fmt,
+ 16, 10, 0, 0.8);
+ if (!ost->resample) {
+ av_log(NULL, AV_LOG_FATAL, "Can not resample %d channels @ %d Hz to %d channels @ %d Hz\n",
+ dec->channels, dec->sample_rate,
+ enc->channels, enc->sample_rate);
+ exit_program(1);
+ }
+ }
+ }
+
+#define MAKE_SFMT_PAIR(a,b) ((a)+AV_SAMPLE_FMT_NB*(b))
+ if (!ost->audio_resample && dec->sample_fmt != enc->sample_fmt &&
+ MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt) != ost->reformat_pair) {
+ if (ost->reformat_ctx)
+ av_audio_convert_free(ost->reformat_ctx);
+ ost->reformat_ctx = av_audio_convert_alloc(enc->sample_fmt, 1,
+ dec->sample_fmt, 1, NULL, 0);
+ if (!ost->reformat_ctx) {
+ av_log(NULL, AV_LOG_FATAL, "Cannot convert %s sample format to %s sample format\n",
+ av_get_sample_fmt_name(dec->sample_fmt),
+ av_get_sample_fmt_name(enc->sample_fmt));
+ exit_program(1);
+ }
+ ost->reformat_pair = MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt);
+ }
+
+ if (audio_sync_method) {
+ double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts -
+ av_fifo_size(ost->fifo) / (enc->channels * osize);
+ int idelta = delta * dec->sample_rate / enc->sample_rate;
+ int byte_delta = idelta * isize * dec->channels;
+
+ // FIXME resample delay
+ if (fabs(delta) > 50) {
+ if (ist->is_start || fabs(delta) > audio_drift_threshold*enc->sample_rate) {
+ if (byte_delta < 0) {
+ byte_delta = FFMAX(byte_delta, -size);
+ size += byte_delta;
+ buf -= byte_delta;
+ av_log(NULL, AV_LOG_VERBOSE, "discarding %d audio samples\n",
+ -byte_delta / (isize * dec->channels));
+ if (!size)
+ return;
+ ist->is_start = 0;
+ } else {
+ static uint8_t *input_tmp = NULL;
+ input_tmp = av_realloc(input_tmp, byte_delta + size);
+
+ if (byte_delta > allocated_for_size - size) {
+ allocated_for_size = byte_delta + (int64_t)size;
+ goto need_realloc;
+ }
+ ist->is_start = 0;
+
+ generate_silence(input_tmp, dec->sample_fmt, byte_delta);
+ memcpy(input_tmp + byte_delta, buf, size);
+ buf = input_tmp;
+ size += byte_delta;
+ av_log(NULL, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", idelta);
+ }
+ } else if (audio_sync_method > 1) {
+ int comp = av_clip(delta, -audio_sync_method, audio_sync_method);
+ av_assert0(ost->audio_resample);
+ av_log(NULL, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n",
+ delta, comp, enc->sample_rate);
+// fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2));
+ av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);
+ }
+ }
+ } else
+ ost->sync_opts = lrintf(get_sync_ipts(ost) * enc->sample_rate) -
+ av_fifo_size(ost->fifo) / (enc->channels * osize); // FIXME wrong
+
+ if (ost->audio_resample) {
+ buftmp = audio_buf;
+ size_out = audio_resample(ost->resample,
+ (short *)buftmp, (short *)buf,
+ size / (dec->channels * isize));
+ size_out = size_out * enc->channels * osize;
+ } else {
+ buftmp = buf;
+ size_out = size;
+ }
+
+ if (!ost->audio_resample && dec->sample_fmt != enc->sample_fmt) {
+ const void *ibuf[6] = { buftmp };
+ void *obuf[6] = { audio_buf };
+ int istride[6] = { isize };
+ int ostride[6] = { osize };
+ int len = size_out / istride[0];
+ if (av_audio_convert(ost->reformat_ctx, obuf, ostride, ibuf, istride, len) < 0) {
+ printf("av_audio_convert() failed\n");
+ if (exit_on_error)
+ exit_program(1);
+ return;
+ }
+ buftmp = audio_buf;
+ size_out = len * osize;
+ }
+
+ /* now encode as many frames as possible */
+ if (enc->frame_size > 1) {
+ /* output resampled raw samples */
+ if (av_fifo_realloc2(ost->fifo, av_fifo_size(ost->fifo) + size_out) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "av_fifo_realloc2() failed\n");
+ exit_program(1);
+ }
+ av_fifo_generic_write(ost->fifo, buftmp, size_out, NULL);
+
+ frame_bytes = enc->frame_size * osize * enc->channels;
+
+ while (av_fifo_size(ost->fifo) >= frame_bytes) {
+ AVPacket pkt;
+ av_init_packet(&pkt);
+
+ av_fifo_generic_read(ost->fifo, audio_buf, frame_bytes, NULL);
+
+ // FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
+
+ ret = avcodec_encode_audio(enc, audio_out, audio_out_size,
+ (short *)audio_buf);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n");
+ exit_program(1);
+ }
+ audio_size += ret;
+ pkt.stream_index = ost->index;
+ pkt.data = audio_out;
+ pkt.size = ret;
+ if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
+ pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ write_frame(s, &pkt, enc, ost->bitstream_filters);
+
+ ost->sync_opts += enc->frame_size;
+ }
+ } else {
+ AVPacket pkt;
+ av_init_packet(&pkt);
+
+ ost->sync_opts += size_out / (osize * enc->channels);
+
+ /* output a pcm frame */
+ /* determine the size of the coded buffer */
+ size_out /= osize;
+ if (coded_bps)
+ size_out = size_out * coded_bps / 8;
+
+ if (size_out > audio_out_size) {
+ av_log(NULL, AV_LOG_FATAL, "Internal error, buffer size too small\n");
+ exit_program(1);
+ }
+
+ // FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
+ ret = avcodec_encode_audio(enc, audio_out, size_out,
+ (short *)buftmp);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n");
+ exit_program(1);
+ }
+ audio_size += ret;
+ pkt.stream_index = ost->index;
+ pkt.data = audio_out;
+ pkt.size = ret;
+ if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
+ pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ write_frame(s, &pkt, enc, ost->bitstream_filters);
+ }
+}
+
+static void pre_process_video_frame(InputStream *ist, AVPicture *picture, void **bufp)
+{
+ AVCodecContext *dec;
+ AVPicture *picture2;
+ AVPicture picture_tmp;
+ uint8_t *buf = 0;
+
+ dec = ist->st->codec;
+
+ /* deinterlace : must be done before any resize */
+ if (do_deinterlace) {
+ int size;
+
+ /* create temporary picture */
+ size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height);
+ buf = av_malloc(size);
+ if (!buf)
+ return;
+
+ picture2 = &picture_tmp;
+ avpicture_fill(picture2, buf, dec->pix_fmt, dec->width, dec->height);
+
+ if (avpicture_deinterlace(picture2, picture,
+ dec->pix_fmt, dec->width, dec->height) < 0) {
+ /* if error, do not deinterlace */
+ av_log(NULL, AV_LOG_WARNING, "Deinterlacing failed\n");
+ av_free(buf);
+ buf = NULL;
+ picture2 = picture;
+ }
+ } else {
+ picture2 = picture;
+ }
+
+ if (picture != picture2)
+ *picture = *picture2;
+ *bufp = buf;
+}
+
+static void do_subtitle_out(AVFormatContext *s,
+ OutputStream *ost,
+ InputStream *ist,
+ AVSubtitle *sub,
+ int64_t pts)
+{
+ static uint8_t *subtitle_out = NULL;
+ int subtitle_out_max_size = 1024 * 1024;
+ int subtitle_out_size, nb, i;
+ AVCodecContext *enc;
+ AVPacket pkt;
+
+ if (pts == AV_NOPTS_VALUE) {
+ av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
+ if (exit_on_error)
+ exit_program(1);
+ return;
+ }
+
+ enc = ost->st->codec;
+
+ if (!subtitle_out) {
+ subtitle_out = av_malloc(subtitle_out_max_size);
+ }
+
+ /* Note: DVB subtitle need one packet to draw them and one other
+ packet to clear them */
+ /* XXX: signal it in the codec context ? */
+ if (enc->codec_id == CODEC_ID_DVB_SUBTITLE)
+ nb = 2;
+ else
+ nb = 1;
+
+ for (i = 0; i < nb; i++) {
+ sub->pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q);
+ // start_display_time is required to be 0
+ sub->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q);
+ sub->end_display_time -= sub->start_display_time;
+ sub->start_display_time = 0;
+ subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out,
+ subtitle_out_max_size, sub);
+ if (subtitle_out_size < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Subtitle encoding failed\n");
+ exit_program(1);
+ }
+
+ av_init_packet(&pkt);
+ pkt.stream_index = ost->index;
+ pkt.data = subtitle_out;
+ pkt.size = subtitle_out_size;
+ pkt.pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base);
+ if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) {
+ /* XXX: the pts correction is handled here. Maybe handling
+ it in the codec would be better */
+ if (i == 0)
+ pkt.pts += 90 * sub->start_display_time;
+ else
+ pkt.pts += 90 * sub->end_display_time;
+ }
+ write_frame(s, &pkt, ost->st->codec, ost->bitstream_filters);
+ }
+}
+
+static int bit_buffer_size = 1024 * 256;
+static uint8_t *bit_buffer = NULL;
+
+static void do_video_resample(OutputStream *ost,
+ InputStream *ist,
+ AVFrame *in_picture,
+ AVFrame **out_picture)
+{
+ int resample_changed = 0;
+ AVCodecContext *dec = ist->st->codec;
+ *out_picture = in_picture;
+
+ resample_changed = ost->resample_width != dec->width ||
+ ost->resample_height != dec->height ||
+ ost->resample_pix_fmt != dec->pix_fmt;
+
+ if (resample_changed) {
+ av_log(NULL, AV_LOG_INFO,
+ "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
+ ist->file_index, ist->st->index,
+ ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt),
+ dec->width , dec->height , av_get_pix_fmt_name(dec->pix_fmt));
+ if (!ost->video_resample)
+ ost->video_resample = 1;
+ }
+
+#if !CONFIG_AVFILTER
+ if (ost->video_resample) {
+ *out_picture = &ost->pict_tmp;
+ if (resample_changed) {
+ /* initialize a new scaler context */
+ sws_freeContext(ost->img_resample_ctx);
+ ost->img_resample_ctx = sws_getContext(
+ ist->st->codec->width,
+ ist->st->codec->height,
+ ist->st->codec->pix_fmt,
+ ost->st->codec->width,
+ ost->st->codec->height,
+ ost->st->codec->pix_fmt,
+ ost->sws_flags, NULL, NULL, NULL);
+ if (ost->img_resample_ctx == NULL) {
+ av_log(NULL, AV_LOG_FATAL, "Cannot get resampling context\n");
+ exit_program(1);
+ }
+ }
+ sws_scale(ost->img_resample_ctx, in_picture->data, in_picture->linesize,
+ 0, ost->resample_height, (*out_picture)->data, (*out_picture)->linesize);
+ }
+#else
+ if (resample_changed) {
+ avfilter_graph_free(&ost->graph);
+ if (configure_video_filters(ist, ost)) {
+ av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
+ exit_program(1);
+ }
+ }
+#endif
+ if (resample_changed) {
+ ost->resample_width = dec->width;
+ ost->resample_height = dec->height;
+ ost->resample_pix_fmt = dec->pix_fmt;
+ }
+}
+
+
+static void do_video_out(AVFormatContext *s,
+ OutputStream *ost,
+ InputStream *ist,
+ AVFrame *in_picture,
+ int *frame_size, float quality)
+{
+ int nb_frames, i, ret, format_video_sync;
+ AVFrame *final_picture;
+ AVCodecContext *enc;
+ double sync_ipts;
+
+ enc = ost->st->codec;
+
+ sync_ipts = get_sync_ipts(ost) / av_q2d(enc->time_base);
+
+ /* by default, we output a single frame */
+ nb_frames = 1;
+
+ *frame_size = 0;
+
+ format_video_sync = video_sync_method;
+ if (format_video_sync < 0)
+ format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? 0 :
+ (s->oformat->flags & AVFMT_VARIABLE_FPS) ? 2 : 1;
+
+ if (format_video_sync) {
+ double vdelta = sync_ipts - ost->sync_opts;
+ // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
+ if (vdelta < -1.1)
+ nb_frames = 0;
+ else if (format_video_sync == 2) {
+ if (vdelta <= -0.6) {
+ nb_frames = 0;
+ } else if (vdelta > 0.6)
+ ost->sync_opts = lrintf(sync_ipts);
+ } else if (vdelta > 1.1)
+ nb_frames = lrintf(vdelta);
+//fprintf(stderr, "vdelta:%f, ost->sync_opts:%"PRId64", ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, get_sync_ipts(ost), nb_frames);
+ if (nb_frames == 0) {
+ ++nb_frames_drop;
+ av_log(NULL, AV_LOG_VERBOSE, "*** drop!\n");
+ } else if (nb_frames > 1) {
+ nb_frames_dup += nb_frames - 1;
+ av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1);
+ }
+ } else
+ ost->sync_opts = lrintf(sync_ipts);
+
+ nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);
+ if (nb_frames <= 0)
+ return;
+
+ do_video_resample(ost, ist, in_picture, &final_picture);
+
+ /* duplicates frame if needed */
+ for (i = 0; i < nb_frames; i++) {
+ AVPacket pkt;
+ av_init_packet(&pkt);
+ pkt.stream_index = ost->index;
+
+ if (s->oformat->flags & AVFMT_RAWPICTURE &&
+ enc->codec->id == CODEC_ID_RAWVIDEO) {
+ /* raw pictures are written as AVPicture structure to
+ avoid any copies. We support temporarily the older
+ method. */
+ enc->coded_frame->interlaced_frame = in_picture->interlaced_frame;
+ enc->coded_frame->top_field_first = in_picture->top_field_first;
+ pkt.data = (uint8_t *)final_picture;
+ pkt.size = sizeof(AVPicture);
+ pkt.pts = av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base);
+ pkt.flags |= AV_PKT_FLAG_KEY;
+
+ write_frame(s, &pkt, ost->st->codec, ost->bitstream_filters);
+ } else {
+ AVFrame big_picture;
+
+ big_picture = *final_picture;
+ /* better than nothing: use input picture interlaced
+ settings */
+ big_picture.interlaced_frame = in_picture->interlaced_frame;
+ if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)) {
+ if (ost->top_field_first == -1)
+ big_picture.top_field_first = in_picture->top_field_first;
+ else
+ big_picture.top_field_first = !!ost->top_field_first;
+ }
+
+ /* handles same_quant here. This is not correct because it may
+ not be a global option */
+ big_picture.quality = quality;
+ if (!enc->me_threshold)
+ big_picture.pict_type = 0;
+// big_picture.pts = AV_NOPTS_VALUE;
+ big_picture.pts = ost->sync_opts;
+// big_picture.pts= av_rescale(ost->sync_opts, AV_TIME_BASE*(int64_t)enc->time_base.num, enc->time_base.den);
+// av_log(NULL, AV_LOG_DEBUG, "%"PRId64" -> encoder\n", ost->sync_opts);
+ if (ost->forced_kf_index < ost->forced_kf_count &&
+ big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
+ big_picture.pict_type = AV_PICTURE_TYPE_I;
+ ost->forced_kf_index++;
+ }
+ ret = avcodec_encode_video(enc,
+ bit_buffer, bit_buffer_size,
+ &big_picture);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
+ exit_program(1);
+ }
+
+ if (ret > 0) {
+ pkt.data = bit_buffer;
+ pkt.size = ret;
+ if (enc->coded_frame->pts != AV_NOPTS_VALUE)
+ pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
+/*av_log(NULL, AV_LOG_DEBUG, "encoder -> %"PRId64"/%"PRId64"\n",
+ pkt.pts != AV_NOPTS_VALUE ? av_rescale(pkt.pts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1,
+ pkt.dts != AV_NOPTS_VALUE ? av_rescale(pkt.dts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1);*/
+
+ if (enc->coded_frame->key_frame)
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ write_frame(s, &pkt, ost->st->codec, ost->bitstream_filters);
+ *frame_size = ret;
+ video_size += ret;
+ // fprintf(stderr,"\nFrame: %3d size: %5d type: %d",
+ // enc->frame_number-1, ret, enc->pict_type);
+ /* if two pass, output log */
+ if (ost->logfile && enc->stats_out) {
+ fprintf(ost->logfile, "%s", enc->stats_out);
+ }
+ }
+ }
+ ost->sync_opts++;
+ ost->frame_number++;
+ }
+}
+
+static double psnr(double d)
+{
+ return -10.0 * log(d) / log(10.0);
+}
+
+static void do_video_stats(AVFormatContext *os, OutputStream *ost,
+ int frame_size)
+{
+ AVCodecContext *enc;
+ int frame_number;
+ double ti1, bitrate, avg_bitrate;
+
+ /* this is executed just the first time do_video_stats is called */
+ if (!vstats_file) {
+ vstats_file = fopen(vstats_filename, "w");
+ if (!vstats_file) {
+ perror("fopen");
+ exit_program(1);
+ }
+ }
+
+ enc = ost->st->codec;
+ if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+ frame_number = ost->frame_number;
+ fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality / (float)FF_QP2LAMBDA);
+ if (enc->flags&CODEC_FLAG_PSNR)
+ fprintf(vstats_file, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0] / (enc->width * enc->height * 255.0 * 255.0)));
+
+ fprintf(vstats_file,"f_size= %6d ", frame_size);
+ /* compute pts value */
+ ti1 = ost->sync_opts * av_q2d(enc->time_base);
+ if (ti1 < 0.01)
+ ti1 = 0.01;
+
+ bitrate = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0;
+ avg_bitrate = (double)(video_size * 8) / ti1 / 1000.0;
+ fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
+ (double)video_size / 1024, ti1, bitrate, avg_bitrate);
+ fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(enc->coded_frame->pict_type));
+ }
+}
+
+static void print_report(OutputFile *output_files,
+ OutputStream *ost_table, int nb_ostreams,
+ int is_last_report, int64_t timer_start)
+{
+ char buf[1024];
+ OutputStream *ost;
+ AVFormatContext *oc;
+ int64_t total_size;
+ AVCodecContext *enc;
+ int frame_number, vid, i;
+ double bitrate, ti1, pts;
+ static int64_t last_time = -1;
+ static int qp_histogram[52];
+
+ if (!print_stats && !is_last_report)
+ return;
+
+ if (!is_last_report) {
+ int64_t cur_time;
+ /* display the report every 0.5 seconds */
+ cur_time = av_gettime();
+ if (last_time == -1) {
+ last_time = cur_time;
+ return;
+ }
+ if ((cur_time - last_time) < 500000)
+ return;
+ last_time = cur_time;
+ }
+
+
+ oc = output_files[0].ctx;
+
+ total_size = avio_size(oc->pb);
+ if (total_size < 0) // FIXME improve avio_size() so it works with non seekable output too
+ total_size = avio_tell(oc->pb);
+
+ buf[0] = '\0';
+ ti1 = 1e10;
+ vid = 0;
+ for (i = 0; i < nb_ostreams; i++) {
+ float q = -1;
+ ost = &ost_table[i];
+ enc = ost->st->codec;
+ if (!ost->stream_copy && enc->coded_frame)
+ q = enc->coded_frame->quality / (float)FF_QP2LAMBDA;
+ if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
+ }
+ if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+ float t = (av_gettime() - timer_start) / 1000000.0;
+
+ frame_number = ost->frame_number;
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3d q=%3.1f ",
+ frame_number, (t > 1) ? (int)(frame_number / t + 0.5) : 0, q);
+ if (is_last_report)
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");
+ if (qp_hist) {
+ int j;
+ int qp = lrintf(q);
+ if (qp >= 0 && qp < FF_ARRAY_ELEMS(qp_histogram))
+ qp_histogram[qp]++;
+ for (j = 0; j < 32; j++)
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log(qp_histogram[j] + 1) / log(2)));
+ }
+ if (enc->flags&CODEC_FLAG_PSNR) {
+ int j;
+ double error, error_sum = 0;
+ double scale, scale_sum = 0;
+ char type[3] = { 'Y','U','V' };
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR=");
+ for (j = 0; j < 3; j++) {
+ if (is_last_report) {
+ error = enc->error[j];
+ scale = enc->width * enc->height * 255.0 * 255.0 * frame_number;
+ } else {
+ error = enc->coded_frame->error[j];
+ scale = enc->width * enc->height * 255.0 * 255.0;
+ }
+ if (j)
+ scale /= 4;
+ error_sum += error;
+ scale_sum += scale;
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], psnr(error / scale));
+ }
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum / scale_sum));
+ }
+ vid = 1;
+ }
+ /* compute min output value */
+ pts = (double)ost->st->pts.val * av_q2d(ost->st->time_base);
+ if ((pts < ti1) && (pts > 0))
+ ti1 = pts;
+ }
+ if (ti1 < 0.01)
+ ti1 = 0.01;
+
+ bitrate = (double)(total_size * 8) / ti1 / 1000.0;
+
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ "size=%8.0fkB time=%0.2f bitrate=%6.1fkbits/s",
+ (double)total_size / 1024, ti1, bitrate);
+
+ if (nb_frames_dup || nb_frames_drop)
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",
+ nb_frames_dup, nb_frames_drop);
+
+ av_log(NULL, AV_LOG_INFO, "%s \r", buf);
+
+ fflush(stderr);
+
+ if (is_last_report) {
+ int64_t raw= audio_size + video_size + extra_size;
+ av_log(NULL, AV_LOG_INFO, "\n");
+ av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB global headers:%1.0fkB muxing overhead %f%%\n",
+ video_size / 1024.0,
+ audio_size / 1024.0,
+ extra_size / 1024.0,
+ 100.0 * (total_size - raw) / raw
+ );
+ }
+}
+
+static void flush_encoders(OutputStream *ost_table, int nb_ostreams)
+{
+ int i, ret;
+
+ for (i = 0; i < nb_ostreams; i++) {
+ OutputStream *ost = &ost_table[i];
+ AVCodecContext *enc = ost->st->codec;
+ AVFormatContext *os = output_files[ost->file_index].ctx;
+
+ if (!ost->encoding_needed)
+ continue;
+
+ if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1)
+ continue;
+ if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE) && enc->codec->id == CODEC_ID_RAWVIDEO)
+ continue;
+
+ for (;;) {
+ AVPacket pkt;
+ int fifo_bytes;
+ av_init_packet(&pkt);
+ pkt.stream_index = ost->index;
+
+ switch (ost->st->codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ fifo_bytes = av_fifo_size(ost->fifo);
+ ret = 0;
+ /* encode any samples remaining in fifo */
+ if (fifo_bytes > 0) {
+ int osize = av_get_bytes_per_sample(enc->sample_fmt);
+ int fs_tmp = enc->frame_size;
+
+ av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL);
+ if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
+ enc->frame_size = fifo_bytes / (osize * enc->channels);
+ } else { /* pad */
+ int frame_bytes = enc->frame_size*osize*enc->channels;
+ if (allocated_audio_buf_size < frame_bytes)
+ exit_program(1);
+ generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes);
+ }
+
+ ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf);
+ pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den,
+ ost->st->time_base.num, enc->sample_rate);
+ enc->frame_size = fs_tmp;
+ }
+ if (ret <= 0) {
+ ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL);
+ }
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n");
+ exit_program(1);
+ }
+ audio_size += ret;
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
+ exit_program(1);
+ }
+ video_size += ret;
+ if (enc->coded_frame && enc->coded_frame->key_frame)
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ if (ost->logfile && enc->stats_out) {
+ fprintf(ost->logfile, "%s", enc->stats_out);
+ }
+ break;
+ default:
+ ret = -1;
+ }
+
+ if (ret <= 0)
+ break;
+ pkt.data = bit_buffer;
+ pkt.size = ret;
+ if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
+ pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
+ write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters);
+ }
+ }
+}
+
+/*
+ * Check whether a packet from ist should be written into ost at this time
+ */
+static int check_output_constraints(InputStream *ist, OutputStream *ost)
+{
+ OutputFile *of = &output_files[ost->file_index];
+ int ist_index = ist - input_streams;
+
+ if (ost->source_index != ist_index)
+ return 0;
+
+ if (of->start_time && ist->pts < of->start_time)
+ return 0;
+
+ if (of->recording_time != INT64_MAX &&
+ av_compare_ts(ist->pts, AV_TIME_BASE_Q, of->recording_time + of->start_time,
+ (AVRational){ 1, 1000000 }) >= 0) {
+ ost->is_past_recording_time = 1;
+ return 0;
+ }
+
+ return 1;
+}
+
+static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *pkt)
+{
+ OutputFile *of = &output_files[ost->file_index];
+ int64_t ost_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
+ AVPacket opkt;
+
+ av_init_packet(&opkt);
+
+ if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) &&
+ !ost->copy_initial_nonkeyframes)
+ return;
+
+ /* force the input stream PTS */
+ if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+ audio_size += pkt->size;
+ else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ video_size += pkt->size;
+ ost->sync_opts++;
+ }
+
+ opkt.stream_index = ost->index;
+ if (pkt->pts != AV_NOPTS_VALUE)
+ opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time;
+ else
+ opkt.pts = AV_NOPTS_VALUE;
+
+ 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.dts -= ost_tb_start_time;
+
+ opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
+ opkt.flags = pkt->flags;
+
+ // FIXME remove the following 2 lines they shall be replaced by the bitstream filters
+ if ( ost->st->codec->codec_id != CODEC_ID_H264
+ && ost->st->codec->codec_id != CODEC_ID_MPEG1VIDEO
+ && ost->st->codec->codec_id != CODEC_ID_MPEG2VIDEO
+ ) {
+ if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY))
+ opkt.destruct = av_destruct_packet;
+ } else {
+ opkt.data = pkt->data;
+ opkt.size = pkt->size;
+ }
+
+ write_frame(of->ctx, &opkt, ost->st->codec, ost->bitstream_filters);
+ ost->st->codec->frame_number++;
+ ost->frame_number++;
+ av_free_packet(&opkt);
+}
+
+static void rate_emu_sleep(InputStream *ist)
+{
+ if (input_files[ist->file_index].rate_emu) {
+ int64_t pts = av_rescale(ist->pts, 1000000, AV_TIME_BASE);
+ int64_t now = av_gettime() - ist->start;
+ if (pts > now)
+ usleep(pts - now);
+ }
+}
+
+static int transcode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
+{
+ AVFrame *decoded_frame;
+ AVCodecContext *avctx = ist->st->codec;
+ int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt);
+ int i, ret;
+
+ if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
+ return AVERROR(ENOMEM);
+ else
+ avcodec_get_frame_defaults(ist->decoded_frame);
+ decoded_frame = ist->decoded_frame;
+
+ ret = avcodec_decode_audio4(avctx, decoded_frame, got_output, pkt);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (!*got_output) {
+ /* no audio frame */
+ return ret;
+ }
+
+ /* if the decoder provides a pts, use it instead of the last packet pts.
+ the decoder could be delaying output by a packet or more. */
+ if (decoded_frame->pts != AV_NOPTS_VALUE)
+ ist->next_pts = decoded_frame->pts;
+
+ /* increment next_pts to use for the case where the input stream does not
+ have timestamps or there are multiple frames in the packet */
+ ist->next_pts += ((int64_t)AV_TIME_BASE * decoded_frame->nb_samples) /
+ avctx->sample_rate;
+
+ // preprocess audio (volume)
+ if (audio_volume != 256) {
+ int decoded_data_size = decoded_frame->nb_samples * avctx->channels * bps;
+ void *samples = decoded_frame->data[0];
+ switch (avctx->sample_fmt) {
+ case AV_SAMPLE_FMT_U8:
+ {
+ uint8_t *volp = samples;
+ for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
+ int v = (((*volp - 128) * audio_volume + 128) >> 8) + 128;
+ *volp++ = av_clip_uint8(v);
+ }
+ break;
+ }
+ case AV_SAMPLE_FMT_S16:
+ {
+ int16_t *volp = samples;
+ for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
+ int v = ((*volp) * audio_volume + 128) >> 8;
+ *volp++ = av_clip_int16(v);
+ }
+ break;
+ }
+ case AV_SAMPLE_FMT_S32:
+ {
+ int32_t *volp = samples;
+ for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
+ int64_t v = (((int64_t)*volp * audio_volume + 128) >> 8);
+ *volp++ = av_clipl_int32(v);
+ }
+ break;
+ }
+ case AV_SAMPLE_FMT_FLT:
+ {
+ float *volp = samples;
+ float scale = audio_volume / 256.f;
+ for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
+ *volp++ *= scale;
+ }
+ break;
+ }
+ case AV_SAMPLE_FMT_DBL:
+ {
+ double *volp = samples;
+ double scale = audio_volume / 256.;
+ for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
+ *volp++ *= scale;
+ }
+ break;
+ }
+ default:
+ av_log(NULL, AV_LOG_FATAL,
+ "Audio volume adjustment on sample format %s is not supported.\n",
+ av_get_sample_fmt_name(ist->st->codec->sample_fmt));
+ exit_program(1);
+ }
+ }
+
+ rate_emu_sleep(ist);
+
+ for (i = 0; i < nb_output_streams; i++) {
+ OutputStream *ost = &output_streams[i];
+
+ if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
+ continue;
+ do_audio_out(output_files[ost->file_index].ctx, ost, ist, decoded_frame);
+ }
+
+ return ret;
+}
+
+static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_t *pkt_pts)
+{
+ AVFrame *decoded_frame, *filtered_frame = NULL;
+ void *buffer_to_free = NULL;
+ int i, ret = 0;
+ float quality;
+#if CONFIG_AVFILTER
+ int frame_available = 1;
+#endif
+
+ if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
+ return AVERROR(ENOMEM);
+ else
+ avcodec_get_frame_defaults(ist->decoded_frame);
+ decoded_frame = ist->decoded_frame;
+ pkt->pts = *pkt_pts;
+ pkt->dts = ist->pts;
+ *pkt_pts = AV_NOPTS_VALUE;
+
+ ret = avcodec_decode_video2(ist->st->codec,
+ decoded_frame, got_output, pkt);
+ if (ret < 0)
+ return ret;
+
+ quality = same_quant ? decoded_frame->quality : 0;
+ if (!*got_output) {
+ /* no picture yet */
+ return ret;
+ }
+ ist->next_pts = ist->pts = guess_correct_pts(&ist->pts_ctx, decoded_frame->pkt_pts,
+ decoded_frame->pkt_dts);
+ if (pkt->duration)
+ ist->next_pts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
+ else if (ist->st->codec->time_base.num != 0) {
+ int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 :
+ ist->st->codec->ticks_per_frame;
+ ist->next_pts += ((int64_t)AV_TIME_BASE *
+ ist->st->codec->time_base.num * ticks) /
+ ist->st->codec->time_base.den;
+ }
+ pkt->size = 0;
+ pre_process_video_frame(ist, (AVPicture *)decoded_frame, &buffer_to_free);
+
+ rate_emu_sleep(ist);
+
+ for (i = 0; i < nb_output_streams; i++) {
+ OutputStream *ost = &output_streams[i];
+ int frame_size;
+
+ if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
+ continue;
+
+#if CONFIG_AVFILTER
+ if (ist->st->sample_aspect_ratio.num)
+ decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio;
+ if (ist->st->codec->codec->capabilities & CODEC_CAP_DR1) {
+ FrameBuffer *buf = decoded_frame->opaque;
+ AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays(
+ decoded_frame->data, decoded_frame->linesize,
+ AV_PERM_READ | AV_PERM_PRESERVE,
+ ist->st->codec->width, ist->st->codec->height,
+ ist->st->codec->pix_fmt);
+
+ avfilter_copy_frame_props(fb, decoded_frame);
+ fb->pts = ist->pts;
+ fb->buf->priv = buf;
+ fb->buf->free = filter_release_buffer;
+
+ buf->refcount++;
+ av_buffersrc_buffer(ost->input_video_filter, fb);
+ } else
+ av_vsrc_buffer_add_frame(ost->input_video_filter, decoded_frame,
+ ist->pts, decoded_frame->sample_aspect_ratio);
+
+ if (!ist->filtered_frame && !(ist->filtered_frame = avcodec_alloc_frame())) {
+ av_free(buffer_to_free);
+ return AVERROR(ENOMEM);
+ } else
+ avcodec_get_frame_defaults(ist->filtered_frame);
+ filtered_frame = ist->filtered_frame;
+
+ frame_available = avfilter_poll_frame(ost->output_video_filter->inputs[0]);
+ while (frame_available) {
+ AVRational ist_pts_tb;
+ if (ost->output_video_filter)
+ get_filtered_video_frame(ost->output_video_filter, filtered_frame, &ost->picref, &ist_pts_tb);
+ if (ost->picref)
+ ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
+ if (ost->picref->video && !ost->frame_aspect_ratio)
+ ost->st->codec->sample_aspect_ratio = ost->picref->video->pixel_aspect;
+#else
+ filtered_frame = decoded_frame;
+#endif
+
+ do_video_out(output_files[ost->file_index].ctx, ost, ist, filtered_frame, &frame_size,
+ same_quant ? quality : ost->st->codec->global_quality);
+ if (vstats_filename && frame_size)
+ do_video_stats(output_files[ost->file_index].ctx, ost, frame_size);
+#if CONFIG_AVFILTER
+ frame_available = ost->output_video_filter && avfilter_poll_frame(ost->output_video_filter->inputs[0]);
+ if (ost->picref)
+ avfilter_unref_buffer(ost->picref);
+ }
+#endif
+ }
+
+ av_free(buffer_to_free);
+ return ret;
+}
+
+static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
+{
+ AVSubtitle subtitle;
+ int i, ret = avcodec_decode_subtitle2(ist->st->codec,
+ &subtitle, got_output, pkt);
+ if (ret < 0)
+ return ret;
+ if (!*got_output)
+ return ret;
+
+ rate_emu_sleep(ist);
+
+ for (i = 0; i < nb_output_streams; i++) {
+ OutputStream *ost = &output_streams[i];
+
+ if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
+ continue;
+
+ do_subtitle_out(output_files[ost->file_index].ctx, ost, ist, &subtitle, pkt->pts);
+ }
+
+ avsubtitle_free(&subtitle);
+ return ret;
+}
+
+/* pkt = NULL means EOF (needed to flush decoder buffers) */
+static int output_packet(InputStream *ist,
+ OutputStream *ost_table, int nb_ostreams,
+ const AVPacket *pkt)
+{
+ int i;
+ int got_output;
+ int64_t pkt_pts = AV_NOPTS_VALUE;
+ AVPacket avpkt;
+
+ if (ist->next_pts == AV_NOPTS_VALUE)
+ ist->next_pts = ist->pts;
+
+ if (pkt == NULL) {
+ /* EOF handling */
+ av_init_packet(&avpkt);
+ avpkt.data = NULL;
+ avpkt.size = 0;
+ goto handle_eof;
+ } else {
+ avpkt = *pkt;
+ }
+
+ if (pkt->dts != AV_NOPTS_VALUE)
+ ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q);
+
+ // while we have more to decode or while the decoder did output something on EOF
+ while (ist->decoding_needed && (avpkt.size > 0 || (!pkt && got_output))) {
+ int ret = 0;
+ handle_eof:
+
+ ist->pts = ist->next_pts;
+
+ if (avpkt.size && avpkt.size != pkt->size) {
+ av_log(NULL, ist->showed_multi_packet_warning ? AV_LOG_VERBOSE : AV_LOG_WARNING,
+ "Multiple frames in a packet from stream %d\n", pkt->stream_index);
+ ist->showed_multi_packet_warning = 1;
+ }
+
+ switch (ist->st->codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ ret = transcode_audio (ist, &avpkt, &got_output);
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ ret = transcode_video (ist, &avpkt, &got_output, &pkt_pts);
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ ret = transcode_subtitles(ist, &avpkt, &got_output);
+ break;
+ default:
+ return -1;
+ }
+
+ if (ret < 0)
+ return ret;
+ // touch data and size only if not EOF
+ if (pkt) {
+ avpkt.data += ret;
+ avpkt.size -= ret;
+ }
+ if (!got_output) {
+ continue;
+ }
+ }
+
+ /* handle stream copy */
+ if (!ist->decoding_needed) {
+ rate_emu_sleep(ist);
+ ist->pts = ist->next_pts;
+ switch (ist->st->codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /
+ ist->st->codec->sample_rate;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ if (ist->st->codec->time_base.num != 0) {
+ int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->st->codec->ticks_per_frame;
+ ist->next_pts += ((int64_t)AV_TIME_BASE *
+ ist->st->codec->time_base.num * ticks) /
+ ist->st->codec->time_base.den;
+ }
+ break;
+ }
+ }
+ for (i = 0; pkt && i < nb_ostreams; i++) {
+ OutputStream *ost = &ost_table[i];
+
+ if (!check_output_constraints(ist, ost) || ost->encoding_needed)
+ continue;
+
+ do_streamcopy(ist, ost, pkt);
+ }
+
+ return 0;
+}
+
+static void print_sdp(OutputFile *output_files, int n)
+{
+ char sdp[2048];
+ int i;
+ AVFormatContext **avc = av_malloc(sizeof(*avc) * n);
+
+ if (!avc)
+ exit_program(1);
+ for (i = 0; i < n; i++)
+ avc[i] = output_files[i].ctx;
+
+ av_sdp_create(avc, n, sdp, sizeof(sdp));
+ printf("SDP:\n%s\n", sdp);
+ fflush(stdout);
+ av_freep(&avc);
+}
+
+static int init_input_stream(int ist_index, OutputStream *output_streams, int nb_output_streams,
+ char *error, int error_len)
+{
+ int i;
+ InputStream *ist = &input_streams[ist_index];
+ if (ist->decoding_needed) {
+ AVCodec *codec = ist->dec;
+ if (!codec) {
+ snprintf(error, error_len, "Decoder (codec id %d) not found for input stream #%d:%d",
+ ist->st->codec->codec_id, ist->file_index, ist->st->index);
+ return AVERROR(EINVAL);
+ }
+
+ /* update requested sample format for the decoder based on the
+ corresponding encoder sample format */
+ for (i = 0; i < nb_output_streams; i++) {
+ OutputStream *ost = &output_streams[i];
+ if (ost->source_index == ist_index) {
+ update_sample_fmt(ist->st->codec, codec, ost->st->codec);
+ break;
+ }
+ }
+
+ if (codec->type == AVMEDIA_TYPE_VIDEO && codec->capabilities & CODEC_CAP_DR1) {
+ ist->st->codec->get_buffer = codec_get_buffer;
+ ist->st->codec->release_buffer = codec_release_buffer;
+ ist->st->codec->opaque = ist;
+ }
+
+ if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) {
+ snprintf(error, error_len, "Error while opening decoder for input stream #%d:%d",
+ ist->file_index, ist->st->index);
+ return AVERROR(EINVAL);
+ }
+ assert_codec_experimental(ist->st->codec, 0);
+ assert_avoptions(ist->opts);
+ }
+
+ ist->pts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0;
+ ist->next_pts = AV_NOPTS_VALUE;
+ init_pts_correction(&ist->pts_ctx);
+ ist->is_start = 1;
+
+ return 0;
+}
+
+static int transcode_init(OutputFile *output_files,
+ int nb_output_files,
+ InputFile *input_files,
+ int nb_input_files)
+{
+ int ret = 0, i, j, k;
+ AVFormatContext *oc;
+ AVCodecContext *codec, *icodec;
+ OutputStream *ost;
+ InputStream *ist;
+ char error[1024];
+ int want_sdp = 1;
+
+ /* init framerate emulation */
+ for (i = 0; i < nb_input_files; i++) {
+ InputFile *ifile = &input_files[i];
+ if (ifile->rate_emu)
+ for (j = 0; j < ifile->nb_streams; j++)
+ input_streams[j + ifile->ist_index].start = av_gettime();
+ }
+
+ /* output stream init */
+ for (i = 0; i < nb_output_files; i++) {
+ oc = output_files[i].ctx;
+ if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
+ av_dump_format(oc, i, oc->filename, 1);
+ av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", i);
+ return AVERROR(EINVAL);
+ }
+ }
+
+ /* for each output stream, we compute the right encoding parameters */
+ for (i = 0; i < nb_output_streams; i++) {
+ ost = &output_streams[i];
+ oc = output_files[ost->file_index].ctx;
+ ist = &input_streams[ost->source_index];
+
+ if (ost->attachment_filename)
+ continue;
+
+ codec = ost->st->codec;
+ icodec = ist->st->codec;
+
+ ost->st->disposition = ist->st->disposition;
+ codec->bits_per_raw_sample = icodec->bits_per_raw_sample;
+ codec->chroma_sample_location = icodec->chroma_sample_location;
+
+ if (ost->stream_copy) {
+ uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
+
+ if (extra_size > INT_MAX) {
+ return AVERROR(EINVAL);
+ }
+
+ /* if stream_copy is selected, no need to decode or encode */
+ codec->codec_id = icodec->codec_id;
+ codec->codec_type = icodec->codec_type;
+
+ if (!codec->codec_tag) {
+ if (!oc->oformat->codec_tag ||
+ av_codec_get_id (oc->oformat->codec_tag, icodec->codec_tag) == codec->codec_id ||
+ av_codec_get_tag(oc->oformat->codec_tag, icodec->codec_id) <= 0)
+ codec->codec_tag = icodec->codec_tag;
+ }
+
+ codec->bit_rate = icodec->bit_rate;
+ codec->rc_max_rate = icodec->rc_max_rate;
+ codec->rc_buffer_size = icodec->rc_buffer_size;
+ codec->field_order = icodec->field_order;
+ codec->extradata = av_mallocz(extra_size);
+ if (!codec->extradata) {
+ return AVERROR(ENOMEM);
+ }
+ memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);
+ codec->extradata_size = icodec->extradata_size;
+ if (!copy_tb) {
+ codec->time_base = icodec->time_base;
+ codec->time_base.num *= icodec->ticks_per_frame;
+ av_reduce(&codec->time_base.num, &codec->time_base.den,
+ codec->time_base.num, codec->time_base.den, INT_MAX);
+ } else
+ codec->time_base = ist->st->time_base;
+
+ switch (codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ if (audio_volume != 256) {
+ av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n");
+ exit_program(1);
+ }
+ codec->channel_layout = icodec->channel_layout;
+ codec->sample_rate = icodec->sample_rate;
+ codec->channels = icodec->channels;
+ codec->frame_size = icodec->frame_size;
+ codec->audio_service_type = icodec->audio_service_type;
+ codec->block_align = icodec->block_align;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ codec->pix_fmt = icodec->pix_fmt;
+ codec->width = icodec->width;
+ codec->height = icodec->height;
+ codec->has_b_frames = icodec->has_b_frames;
+ if (!codec->sample_aspect_ratio.num) {
+ codec->sample_aspect_ratio =
+ ost->st->sample_aspect_ratio =
+ ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio :
+ ist->st->codec->sample_aspect_ratio.num ?
+ ist->st->codec->sample_aspect_ratio : (AVRational){0, 1};
+ }
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ codec->width = icodec->width;
+ codec->height = icodec->height;
+ break;
+ case AVMEDIA_TYPE_DATA:
+ case AVMEDIA_TYPE_ATTACHMENT:
+ break;
+ default:
+ abort();
+ }
+ } else {
+ if (!ost->enc)
+ ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
+
+ ist->decoding_needed = 1;
+ ost->encoding_needed = 1;
+
+ switch (codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ ost->fifo = av_fifo_alloc(1024);
+ if (!ost->fifo) {
+ return AVERROR(ENOMEM);
+ }
+ ost->reformat_pair = MAKE_SFMT_PAIR(AV_SAMPLE_FMT_NONE,AV_SAMPLE_FMT_NONE);
+
+ if (!codec->sample_rate)
+ codec->sample_rate = icodec->sample_rate;
+ choose_sample_rate(ost->st, ost->enc);
+ codec->time_base = (AVRational){ 1, codec->sample_rate };
+
+ if (codec->sample_fmt == AV_SAMPLE_FMT_NONE)
+ codec->sample_fmt = icodec->sample_fmt;
+ choose_sample_fmt(ost->st, ost->enc);
+
+ if (!codec->channels)
+ codec->channels = icodec->channels;
+ codec->channel_layout = icodec->channel_layout;
+ if (av_get_channel_layout_nb_channels(codec->channel_layout) != codec->channels)
+ codec->channel_layout = 0;
+
+ ost->audio_resample = codec-> sample_rate != icodec->sample_rate || audio_sync_method > 1;
+ icodec->request_channels = codec-> channels;
+ ost->resample_sample_fmt = icodec->sample_fmt;
+ ost->resample_sample_rate = icodec->sample_rate;
+ ost->resample_channels = icodec->channels;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ if (codec->pix_fmt == PIX_FMT_NONE)
+ codec->pix_fmt = icodec->pix_fmt;
+ choose_pixel_fmt(ost->st, ost->enc);
+
+ if (ost->st->codec->pix_fmt == PIX_FMT_NONE) {
+ av_log(NULL, AV_LOG_FATAL, "Video pixel format is unknown, stream cannot be encoded\n");
+ exit_program(1);
+ }
+
+ if (!codec->width || !codec->height) {
+ codec->width = icodec->width;
+ codec->height = icodec->height;
+ }
+
+ ost->video_resample = codec->width != icodec->width ||
+ codec->height != icodec->height ||
+ codec->pix_fmt != icodec->pix_fmt;
+ if (ost->video_resample) {
+#if !CONFIG_AVFILTER
+ avcodec_get_frame_defaults(&ost->pict_tmp);
+ if (avpicture_alloc((AVPicture*)&ost->pict_tmp, codec->pix_fmt,
+ codec->width, codec->height)) {
+ av_log(NULL, AV_LOG_FATAL, "Cannot allocate temp picture, check pix fmt\n");
+ exit_program(1);
+ }
+ ost->img_resample_ctx = sws_getContext(
+ icodec->width,
+ icodec->height,
+ icodec->pix_fmt,
+ codec->width,
+ codec->height,
+ codec->pix_fmt,
+ ost->sws_flags, NULL, NULL, NULL);
+ if (ost->img_resample_ctx == NULL) {
+ av_log(NULL, AV_LOG_FATAL, "Cannot get resampling context\n");
+ exit_program(1);
+ }
+#endif
+ codec->bits_per_raw_sample = 0;
+ }
+
+ ost->resample_height = icodec->height;
+ ost->resample_width = icodec->width;
+ ost->resample_pix_fmt = icodec->pix_fmt;
+
+ if (!ost->frame_rate.num)
+ ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational) { 25, 1 };
+ if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) {
+ int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
+ ost->frame_rate = ost->enc->supported_framerates[idx];
+ }
+ codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num};
+
+#if CONFIG_AVFILTER
+ if (configure_video_filters(ist, ost)) {
+ av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n");
+ exit(1);
+ }
+#endif
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ break;
+ default:
+ abort();
+ break;
+ }
+ /* two pass mode */
+ if ((codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
+ char logfilename[1024];
+ FILE *f;
+
+ snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
+ pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX,
+ i);
+ if (codec->flags & CODEC_FLAG_PASS1) {
+ f = fopen(logfilename, "wb");
+ if (!f) {
+ av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
+ logfilename, strerror(errno));
+ exit_program(1);
+ }
+ ost->logfile = f;
+ } else {
+ char *logbuffer;
+ size_t logbuffer_size;
+ if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
+ logfilename);
+ exit_program(1);
+ }
+ codec->stats_in = logbuffer;
+ }
+ }
+ }
+ if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ int size = codec->width * codec->height;
+ bit_buffer_size = FFMAX(bit_buffer_size, 6 * size + 200);
+ }
+ }
+
+ if (!bit_buffer)
+ bit_buffer = av_malloc(bit_buffer_size);
+ if (!bit_buffer) {
+ av_log(NULL, AV_LOG_ERROR, "Cannot allocate %d bytes output buffer\n",
+ bit_buffer_size);
+ return AVERROR(ENOMEM);
+ }
+
+ /* open each encoder */
+ for (i = 0; i < nb_output_streams; i++) {
+ ost = &output_streams[i];
+ if (ost->encoding_needed) {
+ AVCodec *codec = ost->enc;
+ AVCodecContext *dec = input_streams[ost->source_index].st->codec;
+ if (!codec) {
+ snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d:%d",
+ ost->st->codec->codec_id, ost->file_index, ost->index);
+ ret = AVERROR(EINVAL);
+ goto dump_format;
+ }
+ if (dec->subtitle_header) {
+ ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size);
+ if (!ost->st->codec->subtitle_header) {
+ ret = AVERROR(ENOMEM);
+ goto dump_format;
+ }
+ memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
+ ost->st->codec->subtitle_header_size = dec->subtitle_header_size;
+ }
+ if (avcodec_open2(ost->st->codec, codec, &ost->opts) < 0) {
+ snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height",
+ ost->file_index, ost->index);
+ ret = AVERROR(EINVAL);
+ goto dump_format;
+ }
+ assert_codec_experimental(ost->st->codec, 1);
+ assert_avoptions(ost->opts);
+ if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000)
+ av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
+ "It takes bits/s as argument, not kbits/s\n");
+ extra_size += ost->st->codec->extradata_size;
+
+ if (ost->st->codec->me_threshold)
+ input_streams[ost->source_index].st->codec->debug |= FF_DEBUG_MV;
+ }
+ }
+
+ /* init input streams */
+ for (i = 0; i < nb_input_streams; i++)
+ if ((ret = init_input_stream(i, output_streams, nb_output_streams, error, sizeof(error))) < 0)
+ goto dump_format;
+
+ /* discard unused programs */
+ for (i = 0; i < nb_input_files; i++) {
+ InputFile *ifile = &input_files[i];
+ for (j = 0; j < ifile->ctx->nb_programs; j++) {
+ AVProgram *p = ifile->ctx->programs[j];
+ int discard = AVDISCARD_ALL;
+
+ for (k = 0; k < p->nb_stream_indexes; k++)
+ if (!input_streams[ifile->ist_index + p->stream_index[k]].discard) {
+ discard = AVDISCARD_DEFAULT;
+ break;
+ }
+ p->discard = discard;
+ }
+ }
+
+ /* open files and write file headers */
+ for (i = 0; i < nb_output_files; i++) {
+ oc = output_files[i].ctx;
+ oc->interrupt_callback = int_cb;
+ if (avformat_write_header(oc, &output_files[i].opts) < 0) {
+ snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);
+ ret = AVERROR(EINVAL);
+ goto dump_format;
+ }
+ assert_avoptions(output_files[i].opts);
+ if (strcmp(oc->oformat->name, "rtp")) {
+ want_sdp = 0;
+ }
+ }
+
+ dump_format:
+ /* dump the file output parameters - cannot be done before in case
+ of stream copy */
+ for (i = 0; i < nb_output_files; i++) {
+ av_dump_format(output_files[i].ctx, i, output_files[i].ctx->filename, 1);
+ }
+
+ /* dump the stream mapping */
+ av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
+ for (i = 0; i < nb_output_streams; i++) {
+ ost = &output_streams[i];
+
+ if (ost->attachment_filename) {
+ /* an attached file */
+ av_log(NULL, AV_LOG_INFO, " File %s -> Stream #%d:%d\n",
+ ost->attachment_filename, ost->file_index, ost->index);
+ continue;
+ }
+ av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
+ input_streams[ost->source_index].file_index,
+ input_streams[ost->source_index].st->index,
+ ost->file_index,
+ ost->index);
+ if (ost->sync_ist != &input_streams[ost->source_index])
+ av_log(NULL, AV_LOG_INFO, " [sync #%d:%d]",
+ ost->sync_ist->file_index,
+ ost->sync_ist->st->index);
+ if (ost->stream_copy)
+ av_log(NULL, AV_LOG_INFO, " (copy)");
+ else
+ av_log(NULL, AV_LOG_INFO, " (%s -> %s)", input_streams[ost->source_index].dec ?
+ input_streams[ost->source_index].dec->name : "?",
+ ost->enc ? ost->enc->name : "?");
+ av_log(NULL, AV_LOG_INFO, "\n");
+ }
+
+ if (ret) {
+ av_log(NULL, AV_LOG_ERROR, "%s\n", error);
+ return ret;
+ }
+
+ if (want_sdp) {
+ print_sdp(output_files, nb_output_files);
+ }
+
+ return 0;
+}
+
+/*
+ * The following code is the main loop of the file converter
+ */
+static int transcode(OutputFile *output_files,
+ int nb_output_files,
+ InputFile *input_files,
+ int nb_input_files)
+{
+ int ret, i;
+ AVFormatContext *is, *os;
+ OutputStream *ost;
+ InputStream *ist;
+ uint8_t *no_packet;
+ int no_packet_count = 0;
+ int64_t timer_start;
+
+ if (!(no_packet = av_mallocz(nb_input_files)))
+ exit_program(1);
+
+ ret = transcode_init(output_files, nb_output_files, input_files, nb_input_files);
+ if (ret < 0)
+ goto fail;
+
+ av_log(NULL, AV_LOG_INFO, "Press ctrl-c to stop encoding\n");
+ term_init();
+
+ timer_start = av_gettime();
+
+ for (; received_sigterm == 0;) {
+ int file_index, ist_index;
+ AVPacket pkt;
+ int64_t ipts_min;
+ double opts_min;
+
+ ipts_min = INT64_MAX;
+ opts_min = 1e100;
+
+ /* select the stream that we must read now by looking at the
+ smallest output pts */
+ file_index = -1;
+ for (i = 0; i < nb_output_streams; i++) {
+ OutputFile *of;
+ int64_t ipts;
+ double opts;
+ ost = &output_streams[i];
+ of = &output_files[ost->file_index];
+ os = output_files[ost->file_index].ctx;
+ ist = &input_streams[ost->source_index];
+ if (ost->is_past_recording_time || no_packet[ist->file_index] ||
+ (os->pb && avio_tell(os->pb) >= of->limit_filesize))
+ continue;
+ opts = ost->st->pts.val * av_q2d(ost->st->time_base);
+ ipts = ist->pts;
+ if (!input_files[ist->file_index].eof_reached) {
+ if (ipts < ipts_min) {
+ ipts_min = ipts;
+ if (input_sync)
+ file_index = ist->file_index;
+ }
+ if (opts < opts_min) {
+ opts_min = opts;
+ if (!input_sync) file_index = ist->file_index;
+ }
+ }
+ if (ost->frame_number >= ost->max_frames) {
+ int j;
+ for (j = 0; j < of->ctx->nb_streams; j++)
+ output_streams[of->ost_index + j].is_past_recording_time = 1;
+ continue;
+ }
+ }
+ /* if none, if is finished */
+ if (file_index < 0) {
+ if (no_packet_count) {
+ no_packet_count = 0;
+ memset(no_packet, 0, nb_input_files);
+ usleep(10000);
+ continue;
+ }
+ break;
+ }
+
+ /* read a frame from it and output it in the fifo */
+ is = input_files[file_index].ctx;
+ ret = av_read_frame(is, &pkt);
+ if (ret == AVERROR(EAGAIN)) {
+ no_packet[file_index] = 1;
+ no_packet_count++;
+ continue;
+ }
+ if (ret < 0) {
+ input_files[file_index].eof_reached = 1;
+ if (opt_shortest)
+ break;
+ else
+ continue;
+ }
+
+ no_packet_count = 0;
+ memset(no_packet, 0, nb_input_files);
+
+ if (do_pkt_dump) {
+ av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump,
+ is->streams[pkt.stream_index]);
+ }
+ /* the following test is needed in case new streams appear
+ dynamically in stream : we ignore them */
+ if (pkt.stream_index >= input_files[file_index].nb_streams)
+ goto discard_packet;
+ ist_index = input_files[file_index].ist_index + pkt.stream_index;
+ ist = &input_streams[ist_index];
+ if (ist->discard)
+ goto discard_packet;
+
+ if (pkt.dts != AV_NOPTS_VALUE)
+ pkt.dts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
+ if (pkt.pts != AV_NOPTS_VALUE)
+ pkt.pts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
+
+ if (pkt.pts != AV_NOPTS_VALUE)
+ pkt.pts *= ist->ts_scale;
+ if (pkt.dts != AV_NOPTS_VALUE)
+ pkt.dts *= ist->ts_scale;
+
+ //fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n",
+ // ist->next_pts,
+ // pkt.dts, input_files[ist->file_index].ts_offset,
+ // ist->st->codec->codec_type);
+ if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE
+ && (is->iformat->flags & AVFMT_TS_DISCONT)) {
+ int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
+ int64_t delta = pkt_dts - ist->next_pts;
+ if ((FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE || pkt_dts + 1 < ist->pts) && !copy_ts) {
+ input_files[ist->file_index].ts_offset -= delta;
+ av_log(NULL, AV_LOG_DEBUG,
+ "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
+ delta, input_files[ist->file_index].ts_offset);
+ pkt.dts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
+ if (pkt.pts != AV_NOPTS_VALUE)
+ pkt.pts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
+ }
+ }
+
+ // fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->st->index, pkt.size);
+ if (output_packet(ist, output_streams, nb_output_streams, &pkt) < 0) {
+
+ av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",
+ ist->file_index, ist->st->index);
+ if (exit_on_error)
+ exit_program(1);
+ av_free_packet(&pkt);
+ continue;
+ }
+
+ discard_packet:
+ av_free_packet(&pkt);
+
+ /* dump report by using the output first video and audio streams */
+ print_report(output_files, output_streams, nb_output_streams, 0, timer_start);
+ }
+
+ /* at the end of stream, we must flush the decoder buffers */
+ for (i = 0; i < nb_input_streams; i++) {
+ ist = &input_streams[i];
+ if (ist->decoding_needed) {
+ output_packet(ist, output_streams, nb_output_streams, NULL);
+ }
+ }
+ flush_encoders(output_streams, nb_output_streams);
+
+ term_exit();
+
+ /* write the trailer if needed and close file */
+ for (i = 0; i < nb_output_files; i++) {
+ os = output_files[i].ctx;
+ av_write_trailer(os);
+ }
+
+ /* dump report by using the first video and audio streams */
+ print_report(output_files, output_streams, nb_output_streams, 1, timer_start);
+
+ /* close each encoder */
+ for (i = 0; i < nb_output_streams; i++) {
+ ost = &output_streams[i];
+ if (ost->encoding_needed) {
+ av_freep(&ost->st->codec->stats_in);
+ avcodec_close(ost->st->codec);
+ }
+#if CONFIG_AVFILTER
+ avfilter_graph_free(&ost->graph);
+#endif
+ }
+
+ /* close each decoder */
+ for (i = 0; i < nb_input_streams; i++) {
+ ist = &input_streams[i];
+ if (ist->decoding_needed) {
+ avcodec_close(ist->st->codec);
+ }
+ }
+
+ /* finished ! */
+ ret = 0;
+
+ fail:
+ av_freep(&bit_buffer);
+ av_freep(&no_packet);
+
+ if (output_streams) {
+ for (i = 0; i < nb_output_streams; i++) {
+ ost = &output_streams[i];
+ if (ost) {
+ if (ost->stream_copy)
+ av_freep(&ost->st->codec->extradata);
+ if (ost->logfile) {
+ fclose(ost->logfile);
+ ost->logfile = NULL;
+ }
+ av_fifo_free(ost->fifo); /* works even if fifo is not
+ initialized but set to zero */
+ av_freep(&ost->st->codec->subtitle_header);
+ av_free(ost->pict_tmp.data[0]);
+ av_free(ost->forced_kf_pts);
+ if (ost->video_resample)
+ sws_freeContext(ost->img_resample_ctx);
+ if (ost->resample)
+ audio_resample_close(ost->resample);
+ if (ost->reformat_ctx)
+ av_audio_convert_free(ost->reformat_ctx);
+ av_dict_free(&ost->opts);
+ }
+ }
+ }
+ return ret;
+}
+
+static double parse_frame_aspect_ratio(const char *arg)
+{
+ int x = 0, y = 0;
+ double ar = 0;
+ const char *p;
+ char *end;
+
+ p = strchr(arg, ':');
+ if (p) {
+ x = strtol(arg, &end, 10);
+ if (end == p)
+ y = strtol(end + 1, &end, 10);
+ if (x > 0 && y > 0)
+ ar = (double)x / (double)y;
+ } else
+ ar = strtod(arg, NULL);
+
+ if (!ar) {
+ av_log(NULL, AV_LOG_FATAL, "Incorrect aspect ratio specification.\n");
+ exit_program(1);
+ }
+ return ar;
+}
+
+static int opt_audio_codec(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "codec:a", arg, options);
+}
+
+static int opt_video_codec(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "codec:v", arg, options);
+}
+
+static int opt_subtitle_codec(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "codec:s", arg, options);
+}
+
+static int opt_data_codec(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "codec:d", arg, options);
+}
+
+static int opt_map(OptionsContext *o, const char *opt, const char *arg)
+{
+ StreamMap *m = NULL;
+ int i, negative = 0, file_idx;
+ int sync_file_idx = -1, sync_stream_idx;
+ char *p, *sync;
+ char *map;
+
+ if (*arg == '-') {
+ negative = 1;
+ arg++;
+ }
+ map = av_strdup(arg);
+
+ /* parse sync stream first, just pick first matching stream */
+ if (sync = strchr(map, ',')) {
+ *sync = 0;
+ sync_file_idx = strtol(sync + 1, &sync, 0);
+ if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
+ exit_program(1);
+ }
+ if (*sync)
+ sync++;
+ for (i = 0; i < input_files[sync_file_idx].nb_streams; i++)
+ if (check_stream_specifier(input_files[sync_file_idx].ctx,
+ input_files[sync_file_idx].ctx->streams[i], sync) == 1) {
+ sync_stream_idx = i;
+ break;
+ }
+ if (i == input_files[sync_file_idx].nb_streams) {
+ av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
+ "match any streams.\n", arg);
+ exit_program(1);
+ }
+ }
+
+
+ file_idx = strtol(map, &p, 0);
+ if (file_idx >= nb_input_files || file_idx < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
+ exit_program(1);
+ }
+ if (negative)
+ /* disable some already defined maps */
+ for (i = 0; i < o->nb_stream_maps; i++) {
+ m = &o->stream_maps[i];
+ if (file_idx == m->file_index &&
+ check_stream_specifier(input_files[m->file_index].ctx,
+ input_files[m->file_index].ctx->streams[m->stream_index],
+ *p == ':' ? p + 1 : p) > 0)
+ m->disabled = 1;
+ }
+ else
+ for (i = 0; i < input_files[file_idx].nb_streams; i++) {
+ if (check_stream_specifier(input_files[file_idx].ctx, input_files[file_idx].ctx->streams[i],
+ *p == ':' ? p + 1 : p) <= 0)
+ continue;
+ o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps),
+ &o->nb_stream_maps, o->nb_stream_maps + 1);
+ m = &o->stream_maps[o->nb_stream_maps - 1];
+
+ m->file_index = file_idx;
+ m->stream_index = i;
+
+ if (sync_file_idx >= 0) {
+ m->sync_file_index = sync_file_idx;
+ m->sync_stream_index = sync_stream_idx;
+ } else {
+ m->sync_file_index = file_idx;
+ m->sync_stream_index = i;
+ }
+ }
+
+ if (!m) {
+ av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
+ exit_program(1);
+ }
+
+ av_freep(&map);
+ return 0;
+}
+
+static int opt_attach(OptionsContext *o, const char *opt, const char *arg)
+{
+ o->attachments = grow_array(o->attachments, sizeof(*o->attachments),
+ &o->nb_attachments, o->nb_attachments + 1);
+ o->attachments[o->nb_attachments - 1] = arg;
+ return 0;
+}
+
+/**
+ * Parse a metadata specifier in arg.
+ * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
+ * @param index for type c/p, chapter/program index is written here
+ * @param stream_spec for type s, the stream specifier is written here
+ */
+static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
+{
+ if (*arg) {
+ *type = *arg;
+ switch (*arg) {
+ case 'g':
+ break;
+ case 's':
+ if (*(++arg) && *arg != ':') {
+ av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
+ exit_program(1);
+ }
+ *stream_spec = *arg == ':' ? arg + 1 : "";
+ break;
+ case 'c':
+ case 'p':
+ if (*(++arg) == ':')
+ *index = strtol(++arg, NULL, 0);
+ break;
+ default:
+ av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
+ exit_program(1);
+ }
+ } else
+ *type = 'g';
+}
+
+static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
+{
+ AVDictionary **meta_in = NULL;
+ AVDictionary **meta_out;
+ int i, ret = 0;
+ char type_in, type_out;
+ const char *istream_spec = NULL, *ostream_spec = NULL;
+ int idx_in = 0, idx_out = 0;
+
+ parse_meta_type(inspec, &type_in, &idx_in, &istream_spec);
+ parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
+
+ if (type_in == 'g' || type_out == 'g')
+ o->metadata_global_manual = 1;
+ if (type_in == 's' || type_out == 's')
+ o->metadata_streams_manual = 1;
+ if (type_in == 'c' || type_out == 'c')
+ o->metadata_chapters_manual = 1;
+
+#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
+ if ((index) < 0 || (index) >= (nb_elems)) {\
+ av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
+ (desc), (index));\
+ exit_program(1);\
+ }
+
+#define SET_DICT(type, meta, context, index)\
+ switch (type) {\
+ case 'g':\
+ meta = &context->metadata;\
+ break;\
+ case 'c':\
+ METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
+ meta = &context->chapters[index]->metadata;\
+ break;\
+ case 'p':\
+ METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
+ meta = &context->programs[index]->metadata;\
+ break;\
+ }\
+
+ SET_DICT(type_in, meta_in, ic, idx_in);
+ SET_DICT(type_out, meta_out, oc, idx_out);
+
+ /* for input streams choose first matching stream */
+ if (type_in == 's') {
+ for (i = 0; i < ic->nb_streams; i++) {
+ if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
+ meta_in = &ic->streams[i]->metadata;
+ break;
+ } else if (ret < 0)
+ exit_program(1);
+ }
+ if (!meta_in) {
+ av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
+ exit_program(1);
+ }
+ }
+
+ if (type_out == 's') {
+ for (i = 0; i < oc->nb_streams; i++) {
+ if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
+ meta_out = &oc->streams[i]->metadata;
+ av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
+ } else if (ret < 0)
+ exit_program(1);
+ }
+ } else
+ av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
+
+ return 0;
+}
+
+static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
+{
+ const char *codec_string = encoder ? "encoder" : "decoder";
+ AVCodec *codec;
+
+ codec = encoder ?
+ avcodec_find_encoder_by_name(name) :
+ avcodec_find_decoder_by_name(name);
+ if (!codec) {
+ av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
+ exit_program(1);
+ }
+ if (codec->type != type) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
+ exit_program(1);
+ }
+ return codec;
+}
+
+static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
+{
+ char *codec_name = NULL;
+
+ MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
+ if (codec_name) {
+ AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
+ st->codec->codec_id = codec->id;
+ return codec;
+ } else
+ return avcodec_find_decoder(st->codec->codec_id);
+}
+
+/**
+ * Add all the streams from the given input file to the global
+ * list of input streams.
+ */
+static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
+{
+ int i, rfps, rfps_base;
+
+ for (i = 0; i < ic->nb_streams; i++) {
+ AVStream *st = ic->streams[i];
+ AVCodecContext *dec = st->codec;
+ InputStream *ist;
+
+ input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1);
+ ist = &input_streams[nb_input_streams - 1];
+ ist->st = st;
+ ist->file_index = nb_input_files;
+ ist->discard = 1;
+ ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st);
+
+ ist->ts_scale = 1.0;
+ MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
+
+ ist->dec = choose_decoder(o, ic, st);
+
+ switch (dec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ if (o->audio_disable)
+ st->discard = AVDISCARD_ALL;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ rfps = ic->streams[i]->r_frame_rate.num;
+ rfps_base = ic->streams[i]->r_frame_rate.den;
+ if (dec->lowres) {
+ dec->flags |= CODEC_FLAG_EMU_EDGE;
+ dec->height >>= dec->lowres;
+ dec->width >>= dec->lowres;
+ }
+
+ if (dec->time_base.den != rfps * dec->ticks_per_frame || dec->time_base.num != rfps_base) {
+
+ av_log(NULL, AV_LOG_INFO,"\nSeems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d)\n",
+ i, (float)dec->time_base.den / dec->time_base.num, dec->time_base.den, dec->time_base.num,
+ (float)rfps / rfps_base, rfps, rfps_base);
+ }
+
+ if (o->video_disable)
+ st->discard = AVDISCARD_ALL;
+ else if (video_discard)
+ st->discard = video_discard;
+ break;
+ case AVMEDIA_TYPE_DATA:
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ if (o->subtitle_disable)
+ st->discard = AVDISCARD_ALL;
+ break;
+ case AVMEDIA_TYPE_ATTACHMENT:
+ case AVMEDIA_TYPE_UNKNOWN:
+ break;
+ default:
+ abort();
+ }
+ }
+}
+
+static void assert_file_overwrite(const char *filename)
+{
+ if (!file_overwrite &&
+ (strchr(filename, ':') == NULL || filename[1] == ':' ||
+ av_strstart(filename, "file:", NULL))) {
+ if (avio_check(filename, 0) == 0) {
+ if (!using_stdin) {
+ fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
+ fflush(stderr);
+ if (!read_yesno()) {
+ fprintf(stderr, "Not overwriting - exiting\n");
+ exit_program(1);
+ }
+ }
+ else {
+ fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
+ exit_program(1);
+ }
+ }
+ }
+}
+
+static void dump_attachment(AVStream *st, const char *filename)
+{
+ int ret;
+ AVIOContext *out = NULL;
+ AVDictionaryEntry *e;
+
+ if (!st->codec->extradata_size) {
+ av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
+ nb_input_files - 1, st->index);
+ return;
+ }
+ if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
+ filename = e->value;
+ if (!*filename) {
+ av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
+ "in stream #%d:%d.\n", nb_input_files - 1, st->index);
+ exit_program(1);
+ }
+
+ assert_file_overwrite(filename);
+
+ if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
+ filename);
+ exit_program(1);
+ }
+
+ avio_write(out, st->codec->extradata, st->codec->extradata_size);
+ avio_flush(out);
+ avio_close(out);
+}
+
+static int opt_input_file(OptionsContext *o, const char *opt, const char *filename)
+{
+ AVFormatContext *ic;
+ AVInputFormat *file_iformat = NULL;
+ int err, i, ret;
+ int64_t timestamp;
+ uint8_t buf[128];
+ AVDictionary **opts;
+ int orig_nb_streams; // number of streams before avformat_find_stream_info
+
+ if (o->format) {
+ if (!(file_iformat = av_find_input_format(o->format))) {
+ av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
+ exit_program(1);
+ }
+ }
+
+ if (!strcmp(filename, "-"))
+ filename = "pipe:";
+
+ using_stdin |= !strncmp(filename, "pipe:", 5) ||
+ !strcmp(filename, "/dev/stdin");
+
+ /* get default parameters from command line */
+ ic = avformat_alloc_context();
+ if (!ic) {
+ print_error(filename, AVERROR(ENOMEM));
+ exit_program(1);
+ }
+ if (o->nb_audio_sample_rate) {
+ snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
+ av_dict_set(&format_opts, "sample_rate", buf, 0);
+ }
+ if (o->nb_audio_channels) {
+ snprintf(buf, sizeof(buf), "%d", o->audio_channels[o->nb_audio_channels - 1].u.i);
+ av_dict_set(&format_opts, "channels", buf, 0);
+ }
+ if (o->nb_frame_rates) {
+ av_dict_set(&format_opts, "framerate", o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
+ }
+ if (o->nb_frame_sizes) {
+ av_dict_set(&format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
+ }
+ if (o->nb_frame_pix_fmts)
+ av_dict_set(&format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
+
+ ic->flags |= AVFMT_FLAG_NONBLOCK;
+ ic->interrupt_callback = int_cb;
+
+ /* open the input file with generic libav function */
+ err = avformat_open_input(&ic, filename, file_iformat, &format_opts);
+ if (err < 0) {
+ print_error(filename, err);
+ exit_program(1);
+ }
+ assert_avoptions(format_opts);
+
+ /* apply forced codec ids */
+ for (i = 0; i < ic->nb_streams; i++)
+ choose_decoder(o, ic, ic->streams[i]);
+
+ /* Set AVCodecContext options for avformat_find_stream_info */
+ opts = setup_find_stream_info_opts(ic, codec_opts);
+ orig_nb_streams = ic->nb_streams;
+
+ /* If not enough info to get the stream parameters, we decode the
+ first frames to get it. (used in mpeg case for example) */
+ ret = avformat_find_stream_info(ic, opts);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
+ avformat_close_input(&ic);
+ exit_program(1);
+ }
+
+ timestamp = o->start_time;
+ /* add the stream start time */
+ if (ic->start_time != AV_NOPTS_VALUE)
+ timestamp += ic->start_time;
+
+ /* if seeking requested, we execute it */
+ if (o->start_time != 0) {
+ ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
+ filename, (double)timestamp / AV_TIME_BASE);
+ }
+ }
+
+ /* update the current parameters so that they match the one of the input stream */
+ add_input_streams(o, ic);
+
+ /* dump the file content */
+ av_dump_format(ic, nb_input_files, filename, 0);
+
+ input_files = grow_array(input_files, sizeof(*input_files), &nb_input_files, nb_input_files + 1);
+ input_files[nb_input_files - 1].ctx = ic;
+ input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams;
+ input_files[nb_input_files - 1].ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp);
+ input_files[nb_input_files - 1].nb_streams = ic->nb_streams;
+ input_files[nb_input_files - 1].rate_emu = o->rate_emu;
+
+ for (i = 0; i < o->nb_dump_attachment; i++) {
+ int j;
+
+ for (j = 0; j < ic->nb_streams; j++) {
+ AVStream *st = ic->streams[j];
+
+ if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
+ dump_attachment(st, o->dump_attachment[i].u.str);
+ }
+ }
+
+ for (i = 0; i < orig_nb_streams; i++)
+ av_dict_free(&opts[i]);
+ av_freep(&opts);
+
+ reset_options(o);
+ return 0;
+}
+
+static void parse_forced_key_frames(char *kf, OutputStream *ost,
+ AVCodecContext *avctx)
+{
+ char *p;
+ int n = 1, i;
+ int64_t t;
+
+ for (p = kf; *p; p++)
+ if (*p == ',')
+ n++;
+ ost->forced_kf_count = n;
+ ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n);
+ if (!ost->forced_kf_pts) {
+ av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
+ exit_program(1);
+ }
+ for (i = 0; i < n; i++) {
+ p = i ? strchr(p, ',') + 1 : kf;
+ t = parse_time_or_die("force_key_frames", p, 1);
+ ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
+ }
+}
+
+static uint8_t *get_line(AVIOContext *s)
+{
+ AVIOContext *line;
+ uint8_t *buf;
+ char c;
+
+ if (avio_open_dyn_buf(&line) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
+ exit_program(1);
+ }
+
+ while ((c = avio_r8(s)) && c != '\n')
+ avio_w8(line, c);
+ avio_w8(line, 0);
+ avio_close_dyn_buf(line, &buf);
+
+ return buf;
+}
+
+static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
+{
+ int i, ret = 1;
+ char filename[1000];
+ const char *base[3] = { getenv("AVCONV_DATADIR"),
+ getenv("HOME"),
+ AVCONV_DATADIR,
+ };
+
+ for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
+ if (!base[i])
+ continue;
+ if (codec_name) {
+ snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
+ i != 1 ? "" : "/.avconv", codec_name, preset_name);
+ ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
+ }
+ if (ret) {
+ snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
+ i != 1 ? "" : "/.avconv", preset_name);
+ ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
+ }
+ }
+ return ret;
+}
+
+static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
+{
+ char *codec_name = NULL;
+
+ MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
+ if (!codec_name) {
+ ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
+ NULL, ost->st->codec->codec_type);
+ ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
+ } else if (!strcmp(codec_name, "copy"))
+ ost->stream_copy = 1;
+ else {
+ ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
+ ost->st->codec->codec_id = ost->enc->id;
+ }
+}
+
+static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
+{
+ OutputStream *ost;
+ AVStream *st = avformat_new_stream(oc, NULL);
+ int idx = oc->nb_streams - 1, ret = 0;
+ char *bsf = NULL, *next, *codec_tag = NULL;
+ AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
+ double qscale = -1;
+ char *buf = NULL, *arg = NULL, *preset = NULL;
+ AVIOContext *s = NULL;
+
+ if (!st) {
+ av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
+ exit_program(1);
+ }
+
+ if (oc->nb_streams - 1 < o->nb_streamid_map)
+ st->id = o->streamid_map[oc->nb_streams - 1];
+
+ output_streams = grow_array(output_streams, sizeof(*output_streams), &nb_output_streams,
+ nb_output_streams + 1);
+ ost = &output_streams[nb_output_streams - 1];
+ ost->file_index = nb_output_files;
+ ost->index = idx;
+ ost->st = st;
+ st->codec->codec_type = type;
+ choose_encoder(o, oc, ost);
+ if (ost->enc) {
+ ost->opts = filter_codec_opts(codec_opts, ost->enc->id, oc, st);
+ }
+
+ avcodec_get_context_defaults3(st->codec, ost->enc);
+ st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
+
+ MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
+ if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
+ do {
+ buf = get_line(s);
+ if (!buf[0] || buf[0] == '#') {
+ av_free(buf);
+ continue;
+ }
+ if (!(arg = strchr(buf, '='))) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
+ exit_program(1);
+ }
+ *arg++ = 0;
+ av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
+ av_free(buf);
+ } while (!s->eof_reached);
+ avio_close(s);
+ }
+ if (ret) {
+ av_log(NULL, AV_LOG_FATAL,
+ "Preset %s specified for stream %d:%d, but could not be opened.\n",
+ preset, ost->file_index, ost->index);
+ exit_program(1);
+ }
+
+ ost->max_frames = INT64_MAX;
+ MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
+
+ MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
+ while (bsf) {
+ if (next = strchr(bsf, ','))
+ *next++ = 0;
+ if (!(bsfc = av_bitstream_filter_init(bsf))) {
+ av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
+ exit_program(1);
+ }
+ if (bsfc_prev)
+ bsfc_prev->next = bsfc;
+ else
+ ost->bitstream_filters = bsfc;
+
+ bsfc_prev = bsfc;
+ bsf = next;
+ }
+
+ MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
+ if (codec_tag) {
+ uint32_t tag = strtol(codec_tag, &next, 0);
+ if (*next)
+ tag = AV_RL32(codec_tag);
+ st->codec->codec_tag = tag;
+ }
+
+ MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
+ if (qscale >= 0 || same_quant) {
+ st->codec->flags |= CODEC_FLAG_QSCALE;
+ st->codec->global_quality = FF_QP2LAMBDA * qscale;
+ }
+
+ if (oc->oformat->flags & AVFMT_GLOBALHEADER)
+ st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+ av_opt_get_int(sws_opts, "sws_flags", 0, &ost->sws_flags);
+ return ost;
+}
+
+static void parse_matrix_coeffs(uint16_t *dest, const char *str)
+{
+ int i;
+ const char *p = str;
+ for (i = 0;; i++) {
+ dest[i] = atoi(p);
+ if (i == 63)
+ break;
+ p = strchr(p, ',');
+ if (!p) {
+ av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
+ exit_program(1);
+ }
+ p++;
+ }
+}
+
+static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
+{
+ AVStream *st;
+ OutputStream *ost;
+ AVCodecContext *video_enc;
+
+ ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
+ st = ost->st;
+ video_enc = st->codec;
+
+ if (!ost->stream_copy) {
+ const char *p = NULL;
+ char *forced_key_frames = NULL, *frame_rate = NULL, *frame_size = NULL;
+ char *frame_aspect_ratio = NULL, *frame_pix_fmt = NULL;
+ char *intra_matrix = NULL, *inter_matrix = NULL, *filters = NULL;
+ int i;
+
+ MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
+ if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
+ exit_program(1);
+ }
+
+ MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
+ if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
+ exit_program(1);
+ }
+
+ MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
+ if (frame_aspect_ratio)
+ ost->frame_aspect_ratio = parse_frame_aspect_ratio(frame_aspect_ratio);
+
+ MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
+ if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == PIX_FMT_NONE) {
+ av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
+ exit_program(1);
+ }
+ st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
+
+ MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
+ if (intra_matrix) {
+ if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
+ av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
+ exit_program(1);
+ }
+ parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
+ }
+ MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
+ if (inter_matrix) {
+ if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
+ av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
+ exit_program(1);
+ }
+ parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
+ }
+
+ MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
+ for (i = 0; p; i++) {
+ int start, end, q;
+ int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
+ if (e != 3) {
+ av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
+ exit_program(1);
+ }
+ video_enc->rc_override =
+ av_realloc(video_enc->rc_override,
+ sizeof(RcOverride) * (i + 1));
+ video_enc->rc_override[i].start_frame = start;
+ video_enc->rc_override[i].end_frame = end;
+ if (q > 0) {
+ video_enc->rc_override[i].qscale = q;
+ video_enc->rc_override[i].quality_factor = 1.0;
+ }
+ else {
+ video_enc->rc_override[i].qscale = 0;
+ video_enc->rc_override[i].quality_factor = -q/100.0;
+ }
+ p = strchr(p, '/');
+ if (p) p++;
+ }
+ video_enc->rc_override_count = i;
+ if (!video_enc->rc_initial_buffer_occupancy)
+ video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size * 3 / 4;
+ video_enc->intra_dc_precision = intra_dc_precision - 8;
+
+ /* two pass mode */
+ if (do_pass) {
+ if (do_pass == 1) {
+ video_enc->flags |= CODEC_FLAG_PASS1;
+ } else {
+ video_enc->flags |= CODEC_FLAG_PASS2;
+ }
+ }
+
+ MATCH_PER_STREAM_OPT(forced_key_frames, str, forced_key_frames, oc, st);
+ if (forced_key_frames)
+ parse_forced_key_frames(forced_key_frames, ost, video_enc);
+
+ MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
+
+ ost->top_field_first = -1;
+ MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
+
+ MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
+
+#if CONFIG_AVFILTER
+ MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
+ if (filters)
+ ost->avfilter = av_strdup(filters);
+#endif
+ }
+
+ return ost;
+}
+
+static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
+{
+ AVStream *st;
+ OutputStream *ost;
+ AVCodecContext *audio_enc;
+
+ ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO);
+ st = ost->st;
+
+ audio_enc = st->codec;
+ audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
+
+ if (!ost->stream_copy) {
+ char *sample_fmt = NULL;
+
+ MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
+
+ MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
+ if (sample_fmt &&
+ (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
+ exit_program(1);
+ }
+
+ MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
+ }
+
+ return ost;
+}
+
+static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
+{
+ OutputStream *ost;
+
+ ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA);
+ if (!ost->stream_copy) {
+ av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
+ exit_program(1);
+ }
+
+ return ost;
+}
+
+static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc)
+{
+ OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT);
+ ost->stream_copy = 1;
+ return ost;
+}
+
+static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc)
+{
+ AVStream *st;
+ OutputStream *ost;
+ AVCodecContext *subtitle_enc;
+
+ ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE);
+ st = ost->st;
+ subtitle_enc = st->codec;
+
+ subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
+
+ return ost;
+}
+
+/* arg format is "output-stream-index:streamid-value". */
+static int opt_streamid(OptionsContext *o, const char *opt, const char *arg)
+{
+ int idx;
+ char *p;
+ char idx_str[16];
+
+ av_strlcpy(idx_str, arg, sizeof(idx_str));
+ p = strchr(idx_str, ':');
+ if (!p) {
+ av_log(NULL, AV_LOG_FATAL,
+ "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
+ arg, opt);
+ exit_program(1);
+ }
+ *p++ = '\0';
+ idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
+ o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
+ o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
+ return 0;
+}
+
+static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
+{
+ AVFormatContext *is = ifile->ctx;
+ AVFormatContext *os = ofile->ctx;
+ int i;
+
+ for (i = 0; i < is->nb_chapters; i++) {
+ AVChapter *in_ch = is->chapters[i], *out_ch;
+ int64_t ts_off = av_rescale_q(ofile->start_time - ifile->ts_offset,
+ AV_TIME_BASE_Q, in_ch->time_base);
+ int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
+ av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
+
+
+ if (in_ch->end < ts_off)
+ continue;
+ if (rt != INT64_MAX && in_ch->start > rt + ts_off)
+ break;
+
+ out_ch = av_mallocz(sizeof(AVChapter));
+ if (!out_ch)
+ return AVERROR(ENOMEM);
+
+ out_ch->id = in_ch->id;
+ out_ch->time_base = in_ch->time_base;
+ out_ch->start = FFMAX(0, in_ch->start - ts_off);
+ out_ch->end = FFMIN(rt, in_ch->end - ts_off);
+
+ if (copy_metadata)
+ av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
+
+ os->nb_chapters++;
+ os->chapters = av_realloc(os->chapters, sizeof(AVChapter) * os->nb_chapters);
+ if (!os->chapters)
+ return AVERROR(ENOMEM);
+ os->chapters[os->nb_chapters - 1] = out_ch;
+ }
+ return 0;
+}
+
+static void opt_output_file(void *optctx, const char *filename)
+{
+ OptionsContext *o = optctx;
+ AVFormatContext *oc;
+ int i, err;
+ AVOutputFormat *file_oformat;
+ OutputStream *ost;
+ InputStream *ist;
+
+ if (!strcmp(filename, "-"))
+ filename = "pipe:";
+
+ oc = avformat_alloc_context();
+ if (!oc) {
+ print_error(filename, AVERROR(ENOMEM));
+ exit_program(1);
+ }
+
+ if (o->format) {
+ file_oformat = av_guess_format(o->format, NULL, NULL);
+ if (!file_oformat) {
+ av_log(NULL, AV_LOG_FATAL, "Requested output format '%s' is not a suitable output format\n", o->format);
+ exit_program(1);
+ }
+ } else {
+ file_oformat = av_guess_format(NULL, filename, NULL);
+ if (!file_oformat) {
+ av_log(NULL, AV_LOG_FATAL, "Unable to find a suitable output format for '%s'\n",
+ filename);
+ exit_program(1);
+ }
+ }
+
+ oc->oformat = file_oformat;
+ oc->interrupt_callback = int_cb;
+ av_strlcpy(oc->filename, filename, sizeof(oc->filename));
+
+ if (!o->nb_stream_maps) {
+ /* pick the "best" stream of each type */
+#define NEW_STREAM(type, index)\
+ if (index >= 0) {\
+ ost = new_ ## type ## _stream(o, oc);\
+ ost->source_index = index;\
+ ost->sync_ist = &input_streams[index];\
+ input_streams[index].discard = 0;\
+ }
+
+ /* video: highest resolution */
+ if (!o->video_disable && oc->oformat->video_codec != CODEC_ID_NONE) {
+ int area = 0, idx = -1;
+ for (i = 0; i < nb_input_streams; i++) {
+ ist = &input_streams[i];
+ if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+ ist->st->codec->width * ist->st->codec->height > area) {
+ area = ist->st->codec->width * ist->st->codec->height;
+ idx = i;
+ }
+ }
+ NEW_STREAM(video, idx);
+ }
+
+ /* audio: most channels */
+ if (!o->audio_disable && oc->oformat->audio_codec != CODEC_ID_NONE) {
+ int channels = 0, idx = -1;
+ for (i = 0; i < nb_input_streams; i++) {
+ ist = &input_streams[i];
+ if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+ ist->st->codec->channels > channels) {
+ channels = ist->st->codec->channels;
+ idx = i;
+ }
+ }
+ NEW_STREAM(audio, idx);
+ }
+
+ /* subtitles: pick first */
+ if (!o->subtitle_disable && oc->oformat->subtitle_codec != CODEC_ID_NONE) {
+ for (i = 0; i < nb_input_streams; i++)
+ if (input_streams[i].st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+ NEW_STREAM(subtitle, i);
+ break;
+ }
+ }
+ /* do something with data? */
+ } else {
+ for (i = 0; i < o->nb_stream_maps; i++) {
+ StreamMap *map = &o->stream_maps[i];
+
+ if (map->disabled)
+ continue;
+
+ ist = &input_streams[input_files[map->file_index].ist_index + map->stream_index];
+ switch (ist->st->codec->codec_type) {
+ case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
+ case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
+ case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break;
+ case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break;
+ case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break;
+ default:
+ av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
+ map->file_index, map->stream_index);
+ exit_program(1);
+ }
+
+ ost->source_index = input_files[map->file_index].ist_index + map->stream_index;
+ ost->sync_ist = &input_streams[input_files[map->sync_file_index].ist_index +
+ map->sync_stream_index];
+ ist->discard = 0;
+ }
+ }
+
+ /* handle attached files */
+ for (i = 0; i < o->nb_attachments; i++) {
+ AVIOContext *pb;
+ uint8_t *attachment;
+ const char *p;
+ int64_t len;
+
+ if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
+ o->attachments[i]);
+ exit_program(1);
+ }
+ if ((len = avio_size(pb)) <= 0) {
+ av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
+ o->attachments[i]);
+ exit_program(1);
+ }
+ if (!(attachment = av_malloc(len))) {
+ av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
+ o->attachments[i]);
+ exit_program(1);
+ }
+ avio_read(pb, attachment, len);
+
+ ost = new_attachment_stream(o, oc);
+ ost->stream_copy = 0;
+ ost->source_index = -1;
+ ost->attachment_filename = o->attachments[i];
+ ost->st->codec->extradata = attachment;
+ ost->st->codec->extradata_size = len;
+
+ p = strrchr(o->attachments[i], '/');
+ av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
+ avio_close(pb);
+ }
+
+ output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1);
+ output_files[nb_output_files - 1].ctx = oc;
+ output_files[nb_output_files - 1].ost_index = nb_output_streams - oc->nb_streams;
+ output_files[nb_output_files - 1].recording_time = o->recording_time;
+ output_files[nb_output_files - 1].start_time = o->start_time;
+ output_files[nb_output_files - 1].limit_filesize = o->limit_filesize;
+ av_dict_copy(&output_files[nb_output_files - 1].opts, format_opts, 0);
+
+ /* check filename in case of an image number is expected */
+ if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
+ if (!av_filename_number_test(oc->filename)) {
+ print_error(oc->filename, AVERROR(EINVAL));
+ exit_program(1);
+ }
+ }
+
+ if (!(oc->oformat->flags & AVFMT_NOFILE)) {
+ /* test if it already exists to avoid losing precious files */
+ assert_file_overwrite(filename);
+
+ /* open the file */
+ if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
+ &oc->interrupt_callback,
+ &output_files[nb_output_files - 1].opts)) < 0) {
+ print_error(filename, err);
+ exit_program(1);
+ }
+ }
+
+ if (o->mux_preload) {
+ uint8_t buf[64];
+ snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
+ av_dict_set(&output_files[nb_output_files - 1].opts, "preload", buf, 0);
+ }
+ oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
+ oc->flags |= AVFMT_FLAG_NONBLOCK;
+
+ /* copy metadata */
+ for (i = 0; i < o->nb_metadata_map; i++) {
+ char *p;
+ int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
+
+ if (in_file_index < 0)
+ continue;
+ if (in_file_index >= nb_input_files) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
+ exit_program(1);
+ }
+ copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc, input_files[in_file_index].ctx, o);
+ }
+
+ /* copy chapters */
+ if (o->chapters_input_file >= nb_input_files) {
+ if (o->chapters_input_file == INT_MAX) {
+ /* copy chapters from the first input file that has them*/
+ o->chapters_input_file = -1;
+ for (i = 0; i < nb_input_files; i++)
+ if (input_files[i].ctx->nb_chapters) {
+ o->chapters_input_file = i;
+ break;
+ }
+ } else {
+ av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
+ o->chapters_input_file);
+ exit_program(1);
+ }
+ }
+ if (o->chapters_input_file >= 0)
+ copy_chapters(&input_files[o->chapters_input_file], &output_files[nb_output_files - 1],
+ !o->metadata_chapters_manual);
+
+ /* copy global metadata by default */
+ if (!o->metadata_global_manual && nb_input_files)
+ av_dict_copy(&oc->metadata, input_files[0].ctx->metadata,
+ AV_DICT_DONT_OVERWRITE);
+ if (!o->metadata_streams_manual)
+ for (i = output_files[nb_output_files - 1].ost_index; i < nb_output_streams; i++) {
+ InputStream *ist;
+ if (output_streams[i].source_index < 0) /* this is true e.g. for attached files */
+ continue;
+ ist = &input_streams[output_streams[i].source_index];
+ av_dict_copy(&output_streams[i].st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
+ }
+
+ /* process manually set metadata */
+ for (i = 0; i < o->nb_metadata; i++) {
+ AVDictionary **m;
+ char type, *val;
+ const char *stream_spec;
+ int index = 0, j, ret;
+
+ val = strchr(o->metadata[i].u.str, '=');
+ if (!val) {
+ av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
+ o->metadata[i].u.str);
+ exit_program(1);
+ }
+ *val++ = 0;
+
+ parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
+ if (type == 's') {
+ for (j = 0; j < oc->nb_streams; j++) {
+ if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
+ av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
+ } else if (ret < 0)
+ exit_program(1);
+ }
+ printf("ret %d, stream_spec %s\n", ret, stream_spec);
+ }
+ else {
+ switch (type) {
+ case 'g':
+ m = &oc->metadata;
+ break;
+ case 'c':
+ if (index < 0 || index >= oc->nb_chapters) {
+ av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
+ exit_program(1);
+ }
+ m = &oc->chapters[index]->metadata;
+ break;
+ default:
+ av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
+ exit_program(1);
+ }
+ av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
+ }
+ }
+
+ reset_options(o);
+}
+
+/* same option as mencoder */
+static int opt_pass(const char *opt, const char *arg)
+{
+ do_pass = parse_number_or_die(opt, arg, OPT_INT, 1, 2);
+ return 0;
+}
+
+static int64_t getutime(void)
+{
+#if HAVE_GETRUSAGE
+ struct rusage rusage;
+
+ getrusage(RUSAGE_SELF, &rusage);
+ return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
+#elif HAVE_GETPROCESSTIMES
+ HANDLE proc;
+ FILETIME c, e, k, u;
+ proc = GetCurrentProcess();
+ GetProcessTimes(proc, &c, &e, &k, &u);
+ return ((int64_t) u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
+#else
+ return av_gettime();
+#endif
+}
+
+static int64_t getmaxrss(void)
+{
+#if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
+ struct rusage rusage;
+ getrusage(RUSAGE_SELF, &rusage);
+ return (int64_t)rusage.ru_maxrss * 1024;
+#elif HAVE_GETPROCESSMEMORYINFO
+ HANDLE proc;
+ PROCESS_MEMORY_COUNTERS memcounters;
+ proc = GetCurrentProcess();
+ memcounters.cb = sizeof(memcounters);
+ GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
+ return memcounters.PeakPagefileUsage;
+#else
+ return 0;
+#endif
+}
+
+static int opt_audio_qscale(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "q:a", arg, options);
+}
+
+static void show_usage(void)
+{
+ printf("Hyper fast Audio and Video encoder\n");
+ printf("usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
+ printf("\n");
+}
+
+static void show_help(void)
+{
+ int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
+ av_log_set_callback(log_callback_help);
+ show_usage();
+ show_help_options(options, "Main options:\n",
+ OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | OPT_GRAB, 0);
+ show_help_options(options, "\nAdvanced options:\n",
+ OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | OPT_GRAB,
+ OPT_EXPERT);
+ show_help_options(options, "\nVideo options:\n",
+ OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
+ OPT_VIDEO);
+ show_help_options(options, "\nAdvanced Video options:\n",
+ OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
+ OPT_VIDEO | OPT_EXPERT);
+ show_help_options(options, "\nAudio options:\n",
+ OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
+ OPT_AUDIO);
+ show_help_options(options, "\nAdvanced Audio options:\n",
+ OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
+ OPT_AUDIO | OPT_EXPERT);
+ show_help_options(options, "\nSubtitle options:\n",
+ OPT_SUBTITLE | OPT_GRAB,
+ OPT_SUBTITLE);
+ show_help_options(options, "\nAudio/Video grab options:\n",
+ OPT_GRAB,
+ OPT_GRAB);
+ printf("\n");
+ show_help_children(avcodec_get_class(), flags);
+ show_help_children(avformat_get_class(), flags);
+ show_help_children(sws_get_class(), flags);
+}
+
+static int opt_target(OptionsContext *o, const char *opt, const char *arg)
+{
+ enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
+ static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
+
+ if (!strncmp(arg, "pal-", 4)) {
+ norm = PAL;
+ arg += 4;
+ } else if (!strncmp(arg, "ntsc-", 5)) {
+ norm = NTSC;
+ arg += 5;
+ } else if (!strncmp(arg, "film-", 5)) {
+ norm = FILM;
+ arg += 5;
+ } else {
+ /* Try to determine PAL/NTSC by peeking in the input files */
+ if (nb_input_files) {
+ int i, j, fr;
+ for (j = 0; j < nb_input_files; j++) {
+ for (i = 0; i < input_files[j].nb_streams; i++) {
+ AVCodecContext *c = input_files[j].ctx->streams[i]->codec;
+ if (c->codec_type != AVMEDIA_TYPE_VIDEO)
+ continue;
+ fr = c->time_base.den * 1000 / c->time_base.num;
+ if (fr == 25000) {
+ norm = PAL;
+ break;
+ } else if ((fr == 29970) || (fr == 23976)) {
+ norm = NTSC;
+ break;
+ }
+ }
+ if (norm != UNKNOWN)
+ break;
+ }
+ }
+ if (norm != UNKNOWN)
+ av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
+ }
+
+ if (norm == UNKNOWN) {
+ av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
+ av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
+ av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
+ exit_program(1);
+ }
+
+ if (!strcmp(arg, "vcd")) {
+ opt_video_codec(o, "c:v", "mpeg1video");
+ opt_audio_codec(o, "c:a", "mp2");
+ parse_option(o, "f", "vcd", options);
+
+ parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
+ parse_option(o, "r", frame_rates[norm], options);
+ opt_default("g", norm == PAL ? "15" : "18");
+
+ opt_default("b", "1150000");
+ opt_default("maxrate", "1150000");
+ opt_default("minrate", "1150000");
+ opt_default("bufsize", "327680"); // 40*1024*8;
+
+ opt_default("b:a", "224000");
+ parse_option(o, "ar", "44100", options);
+ parse_option(o, "ac", "2", options);
+
+ opt_default("packetsize", "2324");
+ opt_default("muxrate", "1411200"); // 2352 * 75 * 8;
+
+ /* We have to offset the PTS, so that it is consistent with the SCR.
+ SCR starts at 36000, but the first two packs contain only padding
+ and the first pack from the other stream, respectively, may also have
+ been written before.
+ So the real data starts at SCR 36000+3*1200. */
+ o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
+ } else if (!strcmp(arg, "svcd")) {
+
+ opt_video_codec(o, "c:v", "mpeg2video");
+ opt_audio_codec(o, "c:a", "mp2");
+ parse_option(o, "f", "svcd", options);
+
+ parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
+ parse_option(o, "r", frame_rates[norm], options);
+ opt_default("g", norm == PAL ? "15" : "18");
+
+ opt_default("b", "2040000");
+ opt_default("maxrate", "2516000");
+ opt_default("minrate", "0"); // 1145000;
+ opt_default("bufsize", "1835008"); // 224*1024*8;
+ opt_default("flags", "+scan_offset");
+
+
+ opt_default("b:a", "224000");
+ parse_option(o, "ar", "44100", options);
+
+ opt_default("packetsize", "2324");
+
+ } else if (!strcmp(arg, "dvd")) {
+
+ opt_video_codec(o, "c:v", "mpeg2video");
+ opt_audio_codec(o, "c:a", "ac3");
+ parse_option(o, "f", "dvd", options);
+
+ parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
+ parse_option(o, "r", frame_rates[norm], options);
+ opt_default("g", norm == PAL ? "15" : "18");
+
+ opt_default("b", "6000000");
+ opt_default("maxrate", "9000000");
+ opt_default("minrate", "0"); // 1500000;
+ opt_default("bufsize", "1835008"); // 224*1024*8;
+
+ opt_default("packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
+ opt_default("muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
+
+ opt_default("b:a", "448000");
+ parse_option(o, "ar", "48000", options);
+
+ } else if (!strncmp(arg, "dv", 2)) {
+
+ parse_option(o, "f", "dv", options);
+
+ parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
+ parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
+ norm == PAL ? "yuv420p" : "yuv411p", options);
+ parse_option(o, "r", frame_rates[norm], options);
+
+ parse_option(o, "ar", "48000", options);
+ parse_option(o, "ac", "2", options);
+
+ } else {
+ av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
+ return AVERROR(EINVAL);
+ }
+ return 0;
+}
+
+static int opt_vstats_file(const char *opt, const char *arg)
+{
+ av_free (vstats_filename);
+ vstats_filename = av_strdup (arg);
+ return 0;
+}
+
+static int opt_vstats(const char *opt, const char *arg)
+{
+ char filename[40];
+ time_t today2 = time(NULL);
+ struct tm *today = localtime(&today2);
+
+ snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
+ today->tm_sec);
+ return opt_vstats_file(opt, filename);
+}
+
+static int opt_video_frames(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "frames:v", arg, options);
+}
+
+static int opt_audio_frames(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "frames:a", arg, options);
+}
+
+static int opt_data_frames(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "frames:d", arg, options);
+}
+
+static int opt_video_tag(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "tag:v", arg, options);
+}
+
+static int opt_audio_tag(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "tag:a", arg, options);
+}
+
+static int opt_subtitle_tag(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "tag:s", arg, options);
+}
+
+static int opt_video_filters(OptionsContext *o, const char *opt, const char *arg)
+{
+ return parse_option(o, "filter:v", arg, options);
+}
+
+#define OFFSET(x) offsetof(OptionsContext, x)
+static const OptionDef options[] = {
+ /* main options */
+#include "cmdutils_common_opts.h"
+ { "f", HAS_ARG | OPT_STRING | OPT_OFFSET, {.off = OFFSET(format)}, "force format", "fmt" },
+ { "i", HAS_ARG | OPT_FUNC2, {(void*)opt_input_file}, "input file name", "filename" },
+ { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
+ { "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" },
+ { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" },
+ { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, "preset name", "preset" },
+ { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
+ { "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(metadata_map)}, "set metadata information of outfile from infile",
+ "outfile[,metadata]:infile[,metadata]" },
+ { "map_chapters", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(chapters_input_file)}, "set chapters mapping", "input_file_index" },
+ { "t", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(recording_time)}, "record or transcode \"duration\" seconds of audio/video", "duration" },
+ { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET, {.off = OFFSET(limit_filesize)}, "set the limit file size in bytes", "limit_size" }, //
+ { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(start_time)}, "set the start time offset", "time_off" },
+ { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(input_ts_offset)}, "set the input ts offset", "time_off" },
+ { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(ts_scale)}, "set the input ts scale", "scale" },
+ { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(metadata)}, "add metadata", "string=string" },
+ { "dframes", HAS_ARG | OPT_FUNC2, {(void*)opt_data_frames}, "set the number of data frames to record", "number" },
+ { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
+ "add timings for benchmarking" },
+ { "timelimit", HAS_ARG, {(void*)opt_timelimit}, "set max runtime in seconds", "limit" },
+ { "dump", OPT_BOOL | OPT_EXPERT, {(void*)&do_pkt_dump},
+ "dump each input packet" },
+ { "hex", OPT_BOOL | OPT_EXPERT, {(void*)&do_hex_dump},
+ "when dumping packets, also dump the payload" },
+ { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(rate_emu)}, "read input at native frame rate", "" },
+ { "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
+ { "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
+ { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
+ { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" },
+ { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" },
+ { "copytb", OPT_BOOL | OPT_EXPERT, {(void*)©_tb}, "copy input stream time base when stream copying" },
+ { "shortest", OPT_BOOL | OPT_EXPERT, {(void*)&opt_shortest}, "finish encoding within shortest input" }, //
+ { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "threshold" },
+ { "xerror", OPT_BOOL, {(void*)&exit_on_error}, "exit on error", "error" },
+ { "copyinkf", OPT_BOOL | OPT_EXPERT | OPT_SPEC, {.off = OFFSET(copy_initial_nonkeyframes)}, "copy initial non-keyframes" },
+ { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC, {.off = OFFSET(max_frames)}, "set the number of frames to record", "number" },
+ { "tag", OPT_STRING | HAS_ARG | OPT_SPEC, {.off = OFFSET(codec_tags)}, "force codec tag/fourcc", "fourcc/tag" },
+ { "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(qscale)}, "use fixed quality scale (VBR)", "q" },
+ { "qscale", HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(qscale)}, "use fixed quality scale (VBR)", "q" },
+#if CONFIG_AVFILTER
+ { "filter", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(filters)}, "set stream filterchain", "filter_list" },
+#endif
+ { "stats", OPT_BOOL, {&print_stats}, "print progress report during encoding", },
+ { "attach", HAS_ARG | OPT_FUNC2, {(void*)opt_attach}, "add an attachment to the output file", "filename" },
+ { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(dump_attachment)}, "extract an attachment into a file", "filename" },
+
+ /* video options */
+ { "vframes", HAS_ARG | OPT_VIDEO | OPT_FUNC2, {(void*)opt_video_frames}, "set the number of video frames to record", "number" },
+ { "r", HAS_ARG | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_rates)}, "set frame rate (Hz value, fraction or abbreviation)", "rate" },
+ { "s", HAS_ARG | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_sizes)}, "set frame size (WxH or abbreviation)", "size" },
+ { "aspect", HAS_ARG | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_aspect_ratios)}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
+ { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_pix_fmts)}, "set pixel format", "format" },
+ { "vn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET, {.off = OFFSET(video_disable)}, "disable video" },
+ { "vdt", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&video_discard}, "discard threshold", "n" },
+ { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(rc_overrides)}, "rate control override for specific intervals", "override" },
+ { "vcodec", HAS_ARG | OPT_VIDEO | OPT_FUNC2, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" },
+ { "same_quant", OPT_BOOL | OPT_VIDEO, {(void*)&same_quant},
+ "use same quantizer as source (implies VBR)" },
+ { "pass", HAS_ARG | OPT_VIDEO, {(void*)opt_pass}, "select the pass number (1 or 2)", "n" },
+ { "passlogfile", HAS_ARG | OPT_STRING | OPT_VIDEO, {(void*)&pass_logfilename_prefix}, "select two pass log file name prefix", "prefix" },
+ { "deinterlace", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_deinterlace},
+ "deinterlace pictures" },
+ { "vstats", OPT_EXPERT | OPT_VIDEO, {(void*)&opt_vstats}, "dump video coding statistics to file" },
+ { "vstats_file", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_vstats_file}, "dump video coding statistics to file", "file" },
+#if CONFIG_AVFILTER
+ { "vf", HAS_ARG | OPT_VIDEO | OPT_FUNC2, {(void*)opt_video_filters}, "video filters", "filter list" },
+#endif
+ { "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(intra_matrices)}, "specify intra matrix coeffs", "matrix" },
+ { "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(inter_matrices)}, "specify inter matrix coeffs", "matrix" },
+ { "top", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_INT| OPT_SPEC, {.off = OFFSET(top_field_first)}, "top=1/bottom=0/auto=-1 field first", "" },
+ { "dc", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_dc_precision}, "intra_dc_precision", "precision" },
+ { "vtag", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_FUNC2, {(void*)opt_video_tag}, "force video tag/fourcc", "fourcc/tag" },
+ { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" },
+ { "force_fps", OPT_BOOL | OPT_EXPERT | OPT_VIDEO | OPT_SPEC, {.off = OFFSET(force_fps)}, "force the selected framerate, disable the best supported framerate selection" },
+ { "streamid", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_streamid}, "set the value of an outfile streamid", "streamIndex:value" },
+ { "force_key_frames", OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_SPEC, {.off = OFFSET(forced_key_frames)}, "force key frames at specified timestamps", "timestamps" },
+
+ /* audio options */
+ { "aframes", HAS_ARG | OPT_AUDIO | OPT_FUNC2, {(void*)opt_audio_frames}, "set the number of audio frames to record", "number" },
+ { "aq", HAS_ARG | OPT_AUDIO | OPT_FUNC2, {(void*)opt_audio_qscale}, "set audio quality (codec-specific)", "quality", },
+ { "ar", HAS_ARG | OPT_AUDIO | OPT_INT | OPT_SPEC, {.off = OFFSET(audio_sample_rate)}, "set audio sampling rate (in Hz)", "rate" },
+ { "ac", HAS_ARG | OPT_AUDIO | OPT_INT | OPT_SPEC, {.off = OFFSET(audio_channels)}, "set number of audio channels", "channels" },
+ { "an", OPT_BOOL | OPT_AUDIO | OPT_OFFSET, {.off = OFFSET(audio_disable)}, "disable audio" },
+ { "acodec", HAS_ARG | OPT_AUDIO | OPT_FUNC2, {(void*)opt_audio_codec}, "force audio codec ('copy' to copy stream)", "codec" },
+ { "atag", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_FUNC2, {(void*)opt_audio_tag}, "force audio tag/fourcc", "fourcc/tag" },
+ { "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, //
+ { "sample_fmt", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_SPEC | OPT_STRING, {.off = OFFSET(sample_fmts)}, "set sample format", "format" },
+
+ /* subtitle options */
+ { "sn", OPT_BOOL | OPT_SUBTITLE | OPT_OFFSET, {.off = OFFSET(subtitle_disable)}, "disable subtitle" },
+ { "scodec", HAS_ARG | OPT_SUBTITLE | OPT_FUNC2, {(void*)opt_subtitle_codec}, "force subtitle codec ('copy' to copy stream)", "codec" },
+ { "stag", HAS_ARG | OPT_EXPERT | OPT_SUBTITLE | OPT_FUNC2, {(void*)opt_subtitle_tag}, "force subtitle tag/fourcc", "fourcc/tag" },
+
+ /* grab options */
+ { "isync", OPT_BOOL | OPT_EXPERT | OPT_GRAB, {(void*)&input_sync}, "sync read on input", "" },
+
+ /* muxer options */
+ { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(mux_max_delay)}, "set the maximum demux-decode delay", "seconds" },
+ { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(mux_preload)}, "set the initial demux-decode delay", "seconds" },
+
+ { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(bitstream_filters)}, "A comma-separated list of bitstream filters", "bitstream_filters" },
+
+ /* data codec support */
+ { "dcodec", HAS_ARG | OPT_DATA | OPT_FUNC2, {(void*)opt_data_codec}, "force data codec ('copy' to copy stream)", "codec" },
+
+ { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
+ { NULL, },
+};
+
+int main(int argc, char **argv)
+{
+ OptionsContext o = { 0 };
+ int64_t ti;
+
+ reset_options(&o);
+
+ av_log_set_flags(AV_LOG_SKIP_REPEATED);
+ parse_loglevel(argc, argv, options);
+
+ avcodec_register_all();
+#if CONFIG_AVDEVICE
+ avdevice_register_all();
+#endif
+#if CONFIG_AVFILTER
+ avfilter_register_all();
+#endif
+ av_register_all();
+ avformat_network_init();
+
+ show_banner();
+
+ /* parse options */
+ parse_options(&o, argc, argv, options, opt_output_file);
+
+ if (nb_output_files <= 0 && nb_input_files == 0) {
+ show_usage();
+ av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
+ exit_program(1);
+ }
+
+ /* file converter / grab */
+ if (nb_output_files <= 0) {
+ fprintf(stderr, "At least one output file must be specified\n");
+ exit_program(1);
+ }
+
+ if (nb_input_files == 0) {
+ av_log(NULL, AV_LOG_FATAL, "At least one input file must be specified\n");
+ exit_program(1);
+ }
+
+ ti = getutime();
+ if (transcode(output_files, nb_output_files, input_files, nb_input_files) < 0)
+ exit_program(1);
+ ti = getutime() - ti;
+ if (do_benchmark) {
+ int maxrss = getmaxrss() / 1024;
+ printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss);
+ }
+
+ exit_program(0);
+ return 0;
+}
diff --git a/avplay.c b/avplay.c
new file mode 100644
index 0000000..c217010
--- /dev/null
+++ b/avplay.c
@@ -0,0 +1,3123 @@
+/*
+ * avplay : Simple Media Player based on the Libav libraries
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <inttypes.h>
+#include <math.h>
+#include <limits.h>
+#include "libavutil/avstring.h"
+#include "libavutil/colorspace.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/dict.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/samplefmt.h"
+#include "libavformat/avformat.h"
+#include "libavdevice/avdevice.h"
+#include "libswscale/swscale.h"
+#include "libavcodec/audioconvert.h"
+#include "libavutil/opt.h"
+#include "libavcodec/avfft.h"
+
+#if CONFIG_AVFILTER
+# include "libavfilter/avfilter.h"
+# include "libavfilter/avfiltergraph.h"
+#endif
+
+#include "cmdutils.h"
+
+#include <SDL.h>
+#include <SDL_thread.h>
+
+#ifdef __MINGW32__
+#undef main /* We don't want SDL to override our main() */
+#endif
+
+#include <unistd.h>
+#include <assert.h>
+
+const char program_name[] = "avplay";
+const int program_birth_year = 2003;
+
+#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
+#define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
+#define MIN_FRAMES 5
+
+/* SDL audio buffer size, in samples. Should be small to have precise
+ A/V sync as SDL does not have hardware buffer fullness info. */
+#define SDL_AUDIO_BUFFER_SIZE 1024
+
+/* no AV sync correction is done if below the AV sync threshold */
+#define AV_SYNC_THRESHOLD 0.01
+/* no AV correction is done if too big error */
+#define AV_NOSYNC_THRESHOLD 10.0
+
+#define FRAME_SKIP_FACTOR 0.05
+
+/* maximum audio speed change to get correct sync */
+#define SAMPLE_CORRECTION_PERCENT_MAX 10
+
+/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
+#define AUDIO_DIFF_AVG_NB 20
+
+/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
+#define SAMPLE_ARRAY_SIZE (2*65536)
+
+static int sws_flags = SWS_BICUBIC;
+
+typedef struct PacketQueue {
+ AVPacketList *first_pkt, *last_pkt;
+ int nb_packets;
+ int size;
+ int abort_request;
+ SDL_mutex *mutex;
+ SDL_cond *cond;
+} PacketQueue;
+
+#define VIDEO_PICTURE_QUEUE_SIZE 2
+#define SUBPICTURE_QUEUE_SIZE 4
+
+typedef struct VideoPicture {
+ double pts; ///<presentation time stamp for this picture
+ double target_clock; ///<av_gettime() time at which this should be displayed ideally
+ int64_t pos; ///<byte position in file
+ SDL_Overlay *bmp;
+ int width, height; /* source height & width */
+ int allocated;
+ int reallocate;
+ enum PixelFormat pix_fmt;
+
+#if CONFIG_AVFILTER
+ AVFilterBufferRef *picref;
+#endif
+} VideoPicture;
+
+typedef struct SubPicture {
+ double pts; /* presentation time stamp for this picture */
+ AVSubtitle sub;
+} SubPicture;
+
+enum {
+ AV_SYNC_AUDIO_MASTER, /* default choice */
+ AV_SYNC_VIDEO_MASTER,
+ AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
+};
+
+typedef struct VideoState {
+ SDL_Thread *parse_tid;
+ SDL_Thread *video_tid;
+ SDL_Thread *refresh_tid;
+ AVInputFormat *iformat;
+ int no_background;
+ int abort_request;
+ int paused;
+ int last_paused;
+ int seek_req;
+ int seek_flags;
+ int64_t seek_pos;
+ int64_t seek_rel;
+ int read_pause_return;
+ AVFormatContext *ic;
+ int dtg_active_format;
+
+ int audio_stream;
+
+ int av_sync_type;
+ double external_clock; /* external clock base */
+ int64_t external_clock_time;
+
+ double audio_clock;
+ double audio_diff_cum; /* used for AV difference average computation */
+ double audio_diff_avg_coef;
+ double audio_diff_threshold;
+ int audio_diff_avg_count;
+ AVStream *audio_st;
+ PacketQueue audioq;
+ int audio_hw_buf_size;
+ uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE];
+ uint8_t *audio_buf;
+ uint8_t *audio_buf1;
+ unsigned int audio_buf_size; /* in bytes */
+ int audio_buf_index; /* in bytes */
+ AVPacket audio_pkt_temp;
+ AVPacket audio_pkt;
+ enum AVSampleFormat audio_src_fmt;
+ AVAudioConvert *reformat_ctx;
+ AVFrame *frame;
+
+ int show_audio; /* if true, display audio samples */
+ int16_t sample_array[SAMPLE_ARRAY_SIZE];
+ int sample_array_index;
+ int last_i_start;
+ RDFTContext *rdft;
+ int rdft_bits;
+ FFTSample *rdft_data;
+ int xpos;
+
+ SDL_Thread *subtitle_tid;
+ int subtitle_stream;
+ int subtitle_stream_changed;
+ AVStream *subtitle_st;
+ PacketQueue subtitleq;
+ SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
+ int subpq_size, subpq_rindex, subpq_windex;
+ SDL_mutex *subpq_mutex;
+ SDL_cond *subpq_cond;
+
+ double frame_timer;
+ double frame_last_pts;
+ double frame_last_delay;
+ double video_clock; ///<pts of last decoded frame / predicted pts of next decoded frame
+ int video_stream;
+ AVStream *video_st;
+ PacketQueue videoq;
+ double video_current_pts; ///<current displayed pts (different from video_clock if frame fifos are used)
+ double video_current_pts_drift; ///<video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
+ int64_t video_current_pos; ///<current displayed file pos
+ VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
+ int pictq_size, pictq_rindex, pictq_windex;
+ SDL_mutex *pictq_mutex;
+ SDL_cond *pictq_cond;
+#if !CONFIG_AVFILTER
+ struct SwsContext *img_convert_ctx;
+#endif
+
+ // QETimer *video_timer;
+ char filename[1024];
+ int width, height, xleft, ytop;
+
+ PtsCorrectionContext pts_ctx;
+
+#if CONFIG_AVFILTER
+ AVFilterContext *out_video_filter; ///<the last filter in the video chain
+#endif
+
+ float skip_frames;
+ float skip_frames_index;
+ int refresh;
+} VideoState;
+
+static void show_help(void);
+
+/* options specified by the user */
+static AVInputFormat *file_iformat;
+static const char *input_filename;
+static const char *window_title;
+static int fs_screen_width;
+static int fs_screen_height;
+static int screen_width = 0;
+static int screen_height = 0;
+static int audio_disable;
+static int video_disable;
+static int wanted_stream[AVMEDIA_TYPE_NB]={
+ [AVMEDIA_TYPE_AUDIO]=-1,
+ [AVMEDIA_TYPE_VIDEO]=-1,
+ [AVMEDIA_TYPE_SUBTITLE]=-1,
+};
+static int seek_by_bytes=-1;
+static int display_disable;
+static int show_status = 1;
+static int av_sync_type = AV_SYNC_AUDIO_MASTER;
+static int64_t start_time = AV_NOPTS_VALUE;
+static int64_t duration = AV_NOPTS_VALUE;
+static int debug = 0;
+static int debug_mv = 0;
+static int step = 0;
+static int thread_count = 1;
+static int workaround_bugs = 1;
+static int fast = 0;
+static int genpts = 0;
+static int lowres = 0;
+static int idct = FF_IDCT_AUTO;
+static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
+static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
+static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
+static int error_recognition = FF_ER_CAREFUL;
+static int error_concealment = 3;
+static int decoder_reorder_pts= -1;
+static int autoexit;
+static int exit_on_keydown;
+static int exit_on_mousedown;
+static int loop=1;
+static int framedrop=1;
+
+static int rdftspeed=20;
+#if CONFIG_AVFILTER
+static char *vfilters = NULL;
+#endif
+
+/* current context */
+static int is_full_screen;
+static VideoState *cur_stream;
+static int64_t audio_callback_time;
+
+static AVPacket flush_pkt;
+
+#define FF_ALLOC_EVENT (SDL_USEREVENT)
+#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
+#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
+
+static SDL_Surface *screen;
+
+void exit_program(int ret)
+{
+ exit(ret);
+}
+
+static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
+
+/* packet queue handling */
+static void packet_queue_init(PacketQueue *q)
+{
+ memset(q, 0, sizeof(PacketQueue));
+ q->mutex = SDL_CreateMutex();
+ q->cond = SDL_CreateCond();
+ packet_queue_put(q, &flush_pkt);
+}
+
+static void packet_queue_flush(PacketQueue *q)
+{
+ AVPacketList *pkt, *pkt1;
+
+ SDL_LockMutex(q->mutex);
+ for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
+ pkt1 = pkt->next;
+ av_free_packet(&pkt->pkt);
+ av_freep(&pkt);
+ }
+ q->last_pkt = NULL;
+ q->first_pkt = NULL;
+ q->nb_packets = 0;
+ q->size = 0;
+ SDL_UnlockMutex(q->mutex);
+}
+
+static void packet_queue_end(PacketQueue *q)
+{
+ packet_queue_flush(q);
+ SDL_DestroyMutex(q->mutex);
+ SDL_DestroyCond(q->cond);
+}
+
+static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
+{
+ AVPacketList *pkt1;
+
+ /* duplicate the packet */
+ if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
+ return -1;
+
+ pkt1 = av_malloc(sizeof(AVPacketList));
+ if (!pkt1)
+ return -1;
+ pkt1->pkt = *pkt;
+ pkt1->next = NULL;
+
+
+ SDL_LockMutex(q->mutex);
+
+ if (!q->last_pkt)
+
+ q->first_pkt = pkt1;
+ else
+ q->last_pkt->next = pkt1;
+ q->last_pkt = pkt1;
+ q->nb_packets++;
+ q->size += pkt1->pkt.size + sizeof(*pkt1);
+ /* XXX: should duplicate packet data in DV case */
+ SDL_CondSignal(q->cond);
+
+ SDL_UnlockMutex(q->mutex);
+ return 0;
+}
+
+static void packet_queue_abort(PacketQueue *q)
+{
+ SDL_LockMutex(q->mutex);
+
+ q->abort_request = 1;
+
+ SDL_CondSignal(q->cond);
+
+ SDL_UnlockMutex(q->mutex);
+}
+
+/* return < 0 if aborted, 0 if no packet and > 0 if packet. */
+static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
+{
+ AVPacketList *pkt1;
+ int ret;
+
+ SDL_LockMutex(q->mutex);
+
+ for(;;) {
+ if (q->abort_request) {
+ ret = -1;
+ break;
+ }
+
+ pkt1 = q->first_pkt;
+ if (pkt1) {
+ q->first_pkt = pkt1->next;
+ if (!q->first_pkt)
+ q->last_pkt = NULL;
+ q->nb_packets--;
+ q->size -= pkt1->pkt.size + sizeof(*pkt1);
+ *pkt = pkt1->pkt;
+ av_free(pkt1);
+ ret = 1;
+ break;
+ } else if (!block) {
+ ret = 0;
+ break;
+ } else {
+ SDL_CondWait(q->cond, q->mutex);
+ }
+ }
+ SDL_UnlockMutex(q->mutex);
+ return ret;
+}
+
+static inline void fill_rectangle(SDL_Surface *screen,
+ int x, int y, int w, int h, int color)
+{
+ SDL_Rect rect;
+ rect.x = x;
+ rect.y = y;
+ rect.w = w;
+ rect.h = h;
+ SDL_FillRect(screen, &rect, color);
+}
+
+#define ALPHA_BLEND(a, oldp, newp, s)\
+((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
+
+#define RGBA_IN(r, g, b, a, s)\
+{\
+ unsigned int v = ((const uint32_t *)(s))[0];\
+ a = (v >> 24) & 0xff;\
+ r = (v >> 16) & 0xff;\
+ g = (v >> 8) & 0xff;\
+ b = v & 0xff;\
+}
+
+#define YUVA_IN(y, u, v, a, s, pal)\
+{\
+ unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
+ a = (val >> 24) & 0xff;\
+ y = (val >> 16) & 0xff;\
+ u = (val >> 8) & 0xff;\
+ v = val & 0xff;\
+}
+
+#define YUVA_OUT(d, y, u, v, a)\
+{\
+ ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
+}
+
+
+#define BPP 1
+
+static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
+{
+ int wrap, wrap3, width2, skip2;
+ int y, u, v, a, u1, v1, a1, w, h;
+ uint8_t *lum, *cb, *cr;
+ const uint8_t *p;
+ const uint32_t *pal;
+ int dstx, dsty, dstw, dsth;
+
+ dstw = av_clip(rect->w, 0, imgw);
+ dsth = av_clip(rect->h, 0, imgh);
+ dstx = av_clip(rect->x, 0, imgw - dstw);
+ dsty = av_clip(rect->y, 0, imgh - dsth);
+ lum = dst->data[0] + dsty * dst->linesize[0];
+ cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
+ cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
+
+ width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
+ skip2 = dstx >> 1;
+ wrap = dst->linesize[0];
+ wrap3 = rect->pict.linesize[0];
+ p = rect->pict.data[0];
+ pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
+
+ if (dsty & 1) {
+ lum += dstx;
+ cb += skip2;
+ cr += skip2;
+
+ if (dstx & 1) {
+ YUVA_IN(y, u, v, a, p, pal);
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
+ cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
+ cb++;
+ cr++;
+ lum++;
+ p += BPP;
+ }
+ for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
+ YUVA_IN(y, u, v, a, p, pal);
+ u1 = u;
+ v1 = v;
+ a1 = a;
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+
+ YUVA_IN(y, u, v, a, p + BPP, pal);
+ u1 += u;
+ v1 += v;
+ a1 += a;
+ lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
+ cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
+ cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
+ cb++;
+ cr++;
+ p += 2 * BPP;
+ lum += 2;
+ }
+ if (w) {
+ YUVA_IN(y, u, v, a, p, pal);
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
+ cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
+ p++;
+ lum++;
+ }
+ p += wrap3 - dstw * BPP;
+ lum += wrap - dstw - dstx;
+ cb += dst->linesize[1] - width2 - skip2;
+ cr += dst->linesize[2] - width2 - skip2;
+ }
+ for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
+ lum += dstx;
+ cb += skip2;
+ cr += skip2;
+
+ if (dstx & 1) {
+ YUVA_IN(y, u, v, a, p, pal);
+ u1 = u;
+ v1 = v;
+ a1 = a;
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ p += wrap3;
+ lum += wrap;
+ YUVA_IN(y, u, v, a, p, pal);
+ u1 += u;
+ v1 += v;
+ a1 += a;
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
+ cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
+ cb++;
+ cr++;
+ p += -wrap3 + BPP;
+ lum += -wrap + 1;
+ }
+ for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
+ YUVA_IN(y, u, v, a, p, pal);
+ u1 = u;
+ v1 = v;
+ a1 = a;
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+
+ YUVA_IN(y, u, v, a, p + BPP, pal);
+ u1 += u;
+ v1 += v;
+ a1 += a;
+ lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
+ p += wrap3;
+ lum += wrap;
+
+ YUVA_IN(y, u, v, a, p, pal);
+ u1 += u;
+ v1 += v;
+ a1 += a;
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+
+ YUVA_IN(y, u, v, a, p + BPP, pal);
+ u1 += u;
+ v1 += v;
+ a1 += a;
+ lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
+
+ cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
+ cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
+
+ cb++;
+ cr++;
+ p += -wrap3 + 2 * BPP;
+ lum += -wrap + 2;
+ }
+ if (w) {
+ YUVA_IN(y, u, v, a, p, pal);
+ u1 = u;
+ v1 = v;
+ a1 = a;
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ p += wrap3;
+ lum += wrap;
+ YUVA_IN(y, u, v, a, p, pal);
+ u1 += u;
+ v1 += v;
+ a1 += a;
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
+ cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
+ cb++;
+ cr++;
+ p += -wrap3 + BPP;
+ lum += -wrap + 1;
+ }
+ p += wrap3 + (wrap3 - dstw * BPP);
+ lum += wrap + (wrap - dstw - dstx);
+ cb += dst->linesize[1] - width2 - skip2;
+ cr += dst->linesize[2] - width2 - skip2;
+ }
+ /* handle odd height */
+ if (h) {
+ lum += dstx;
+ cb += skip2;
+ cr += skip2;
+
+ if (dstx & 1) {
+ YUVA_IN(y, u, v, a, p, pal);
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
+ cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
+ cb++;
+ cr++;
+ lum++;
+ p += BPP;
+ }
+ for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
+ YUVA_IN(y, u, v, a, p, pal);
+ u1 = u;
+ v1 = v;
+ a1 = a;
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+
+ YUVA_IN(y, u, v, a, p + BPP, pal);
+ u1 += u;
+ v1 += v;
+ a1 += a;
+ lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
+ cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
+ cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
+ cb++;
+ cr++;
+ p += 2 * BPP;
+ lum += 2;
+ }
+ if (w) {
+ YUVA_IN(y, u, v, a, p, pal);
+ lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
+ cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
+ }
+ }
+}
+
+static void free_subpicture(SubPicture *sp)
+{
+ avsubtitle_free(&sp->sub);
+}
+
+static void video_image_display(VideoState *is)
+{
+ VideoPicture *vp;
+ SubPicture *sp;
+ AVPicture pict;
+ float aspect_ratio;
+ int width, height, x, y;
+ SDL_Rect rect;
+ int i;
+
+ vp = &is->pictq[is->pictq_rindex];
+ if (vp->bmp) {
+#if CONFIG_AVFILTER
+ if (vp->picref->video->pixel_aspect.num == 0)
+ aspect_ratio = 0;
+ else
+ aspect_ratio = av_q2d(vp->picref->video->pixel_aspect);
+#else
+
+ /* XXX: use variable in the frame */
+ if (is->video_st->sample_aspect_ratio.num)
+ aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
+ else if (is->video_st->codec->sample_aspect_ratio.num)
+ aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
+ else
+ aspect_ratio = 0;
+#endif
+ if (aspect_ratio <= 0.0)
+ aspect_ratio = 1.0;
+ aspect_ratio *= (float)vp->width / (float)vp->height;
+
+ if (is->subtitle_st)
+ {
+ if (is->subpq_size > 0)
+ {
+ sp = &is->subpq[is->subpq_rindex];
+
+ if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
+ {
+ SDL_LockYUVOverlay (vp->bmp);
+
+ pict.data[0] = vp->bmp->pixels[0];
+ pict.data[1] = vp->bmp->pixels[2];
+ pict.data[2] = vp->bmp->pixels[1];
+
+ pict.linesize[0] = vp->bmp->pitches[0];
+ pict.linesize[1] = vp->bmp->pitches[2];
+ pict.linesize[2] = vp->bmp->pitches[1];
+
+ for (i = 0; i < sp->sub.num_rects; i++)
+ blend_subrect(&pict, sp->sub.rects[i],
+ vp->bmp->w, vp->bmp->h);
+
+ SDL_UnlockYUVOverlay (vp->bmp);
+ }
+ }
+ }
+
+
+ /* XXX: we suppose the screen has a 1.0 pixel ratio */
+ height = is->height;
+ width = ((int)rint(height * aspect_ratio)) & ~1;
+ if (width > is->width) {
+ width = is->width;
+ height = ((int)rint(width / aspect_ratio)) & ~1;
+ }
+ x = (is->width - width) / 2;
+ y = (is->height - height) / 2;
+ is->no_background = 0;
+ rect.x = is->xleft + x;
+ rect.y = is->ytop + y;
+ rect.w = width;
+ rect.h = height;
+ SDL_DisplayYUVOverlay(vp->bmp, &rect);
+ }
+}
+
+/* get the current audio output buffer size, in samples. With SDL, we
+ cannot have a precise information */
+static int audio_write_get_buf_size(VideoState *is)
+{
+ return is->audio_buf_size - is->audio_buf_index;
+}
+
+static inline int compute_mod(int a, int b)
+{
+ a = a % b;
+ if (a >= 0)
+ return a;
+ else
+ return a + b;
+}
+
+static void video_audio_display(VideoState *s)
+{
+ int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
+ int ch, channels, h, h2, bgcolor, fgcolor;
+ int16_t time_diff;
+ int rdft_bits, nb_freq;
+
+ for(rdft_bits=1; (1<<rdft_bits)<2*s->height; rdft_bits++)
+ ;
+ nb_freq= 1<<(rdft_bits-1);
+
+ /* compute display index : center on currently output samples */
+ channels = s->audio_st->codec->channels;
+ nb_display_channels = channels;
+ if (!s->paused) {
+ int data_used= s->show_audio==1 ? s->width : (2*nb_freq);
+ n = 2 * channels;
+ delay = audio_write_get_buf_size(s);
+ delay /= n;
+
+ /* to be more precise, we take into account the time spent since
+ the last buffer computation */
+ if (audio_callback_time) {
+ time_diff = av_gettime() - audio_callback_time;
+ delay -= (time_diff * s->audio_st->codec->sample_rate) / 1000000;
+ }
+
+ delay += 2*data_used;
+ if (delay < data_used)
+ delay = data_used;
+
+ i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
+ if(s->show_audio==1){
+ h= INT_MIN;
+ for(i=0; i<1000; i+=channels){
+ int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
+ int a= s->sample_array[idx];
+ int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
+ int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
+ int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
+ int score= a-d;
+ if(h<score && (b^c)<0){
+ h= score;
+ i_start= idx;
+ }
+ }
+ }
+
+ s->last_i_start = i_start;
+ } else {
+ i_start = s->last_i_start;
+ }
+
+ bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
+ if(s->show_audio==1){
+ fill_rectangle(screen,
+ s->xleft, s->ytop, s->width, s->height,
+ bgcolor);
+
+ fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
+
+ /* total height for one channel */
+ h = s->height / nb_display_channels;
+ /* graph height / 2 */
+ h2 = (h * 9) / 20;
+ for(ch = 0;ch < nb_display_channels; ch++) {
+ i = i_start + ch;
+ y1 = s->ytop + ch * h + (h / 2); /* position of center line */
+ for(x = 0; x < s->width; x++) {
+ y = (s->sample_array[i] * h2) >> 15;
+ if (y < 0) {
+ y = -y;
+ ys = y1 - y;
+ } else {
+ ys = y1;
+ }
+ fill_rectangle(screen,
+ s->xleft + x, ys, 1, y,
+ fgcolor);
+ i += channels;
+ if (i >= SAMPLE_ARRAY_SIZE)
+ i -= SAMPLE_ARRAY_SIZE;
+ }
+ }
+
+ fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
+
+ for(ch = 1;ch < nb_display_channels; ch++) {
+ y = s->ytop + ch * h;
+ fill_rectangle(screen,
+ s->xleft, y, s->width, 1,
+ fgcolor);
+ }
+ SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
+ }else{
+ nb_display_channels= FFMIN(nb_display_channels, 2);
+ if(rdft_bits != s->rdft_bits){
+ av_rdft_end(s->rdft);
+ av_free(s->rdft_data);
+ s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
+ s->rdft_bits= rdft_bits;
+ s->rdft_data= av_malloc(4*nb_freq*sizeof(*s->rdft_data));
+ }
+ {
+ FFTSample *data[2];
+ for(ch = 0;ch < nb_display_channels; ch++) {
+ data[ch] = s->rdft_data + 2*nb_freq*ch;
+ i = i_start + ch;
+ for(x = 0; x < 2*nb_freq; x++) {
+ double w= (x-nb_freq)*(1.0/nb_freq);
+ data[ch][x]= s->sample_array[i]*(1.0-w*w);
+ i += channels;
+ if (i >= SAMPLE_ARRAY_SIZE)
+ i -= SAMPLE_ARRAY_SIZE;
+ }
+ av_rdft_calc(s->rdft, data[ch]);
+ }
+ //least efficient way to do this, we should of course directly access it but its more than fast enough
+ for(y=0; y<s->height; y++){
+ double w= 1/sqrt(nb_freq);
+ int a= sqrt(w*sqrt(data[0][2*y+0]*data[0][2*y+0] + data[0][2*y+1]*data[0][2*y+1]));
+ int b= (nb_display_channels == 2 ) ? sqrt(w*sqrt(data[1][2*y+0]*data[1][2*y+0]
+ + data[1][2*y+1]*data[1][2*y+1])) : a;
+ a= FFMIN(a,255);
+ b= FFMIN(b,255);
+ fgcolor = SDL_MapRGB(screen->format, a, b, (a+b)/2);
+
+ fill_rectangle(screen,
+ s->xpos, s->height-y, 1, 1,
+ fgcolor);
+ }
+ }
+ SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
+ s->xpos++;
+ if(s->xpos >= s->width)
+ s->xpos= s->xleft;
+ }
+}
+
+static int video_open(VideoState *is){
+ int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
+ int w,h;
+
+ if(is_full_screen) flags |= SDL_FULLSCREEN;
+ else flags |= SDL_RESIZABLE;
+
+ if (is_full_screen && fs_screen_width) {
+ w = fs_screen_width;
+ h = fs_screen_height;
+ } else if(!is_full_screen && screen_width){
+ w = screen_width;
+ h = screen_height;
+#if CONFIG_AVFILTER
+ }else if (is->out_video_filter && is->out_video_filter->inputs[0]){
+ w = is->out_video_filter->inputs[0]->w;
+ h = is->out_video_filter->inputs[0]->h;
+#else
+ }else if (is->video_st && is->video_st->codec->width){
+ w = is->video_st->codec->width;
+ h = is->video_st->codec->height;
+#endif
+ } else {
+ w = 640;
+ h = 480;
+ }
+ if(screen && is->width == screen->w && screen->w == w
+ && is->height== screen->h && screen->h == h)
+ return 0;
+
+#if defined(__APPLE__) && !SDL_VERSION_ATLEAST(1, 2, 14)
+ /* setting bits_per_pixel = 0 or 32 causes blank video on OS X and older SDL */
+ screen = SDL_SetVideoMode(w, h, 24, flags);
+#else
+ screen = SDL_SetVideoMode(w, h, 0, flags);
+#endif
+ if (!screen) {
+ fprintf(stderr, "SDL: could not set video mode - exiting\n");
+ return -1;
+ }
+ if (!window_title)
+ window_title = input_filename;
+ SDL_WM_SetCaption(window_title, window_title);
+
+ is->width = screen->w;
+ is->height = screen->h;
+
+ return 0;
+}
+
+/* display the current picture, if any */
+static void video_display(VideoState *is)
+{
+ if(!screen)
+ video_open(cur_stream);
+ if (is->audio_st && is->show_audio)
+ video_audio_display(is);
+ else if (is->video_st)
+ video_image_display(is);
+}
+
+static int refresh_thread(void *opaque)
+{
+ VideoState *is= opaque;
+ while(!is->abort_request){
+ SDL_Event event;
+ event.type = FF_REFRESH_EVENT;
+ event.user.data1 = opaque;
+ if(!is->refresh){
+ is->refresh=1;
+ SDL_PushEvent(&event);
+ }
+ usleep(is->audio_st && is->show_audio ? rdftspeed*1000 : 5000); //FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
+ }
+ return 0;
+}
+
+/* get the current audio clock value */
+static double get_audio_clock(VideoState *is)
+{
+ double pts;
+ int hw_buf_size, bytes_per_sec;
+ pts = is->audio_clock;
+ hw_buf_size = audio_write_get_buf_size(is);
+ bytes_per_sec = 0;
+ if (is->audio_st) {
+ bytes_per_sec = is->audio_st->codec->sample_rate *
+ 2 * is->audio_st->codec->channels;
+ }
+ if (bytes_per_sec)
+ pts -= (double)hw_buf_size / bytes_per_sec;
+ return pts;
+}
+
+/* get the current video clock value */
+static double get_video_clock(VideoState *is)
+{
+ if (is->paused) {
+ return is->video_current_pts;
+ } else {
+ return is->video_current_pts_drift + av_gettime() / 1000000.0;
+ }
+}
+
+/* get the current external clock value */
+static double get_external_clock(VideoState *is)
+{
+ int64_t ti;
+ ti = av_gettime();
+ return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
+}
+
+/* get the current master clock value */
+static double get_master_clock(VideoState *is)
+{
+ double val;
+
+ if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
+ if (is->video_st)
+ val = get_video_clock(is);
+ else
+ val = get_audio_clock(is);
+ } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
+ if (is->audio_st)
+ val = get_audio_clock(is);
+ else
+ val = get_video_clock(is);
+ } else {
+ val = get_external_clock(is);
+ }
+ return val;
+}
+
+/* seek in the stream */
+static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
+{
+ if (!is->seek_req) {
+ is->seek_pos = pos;
+ is->seek_rel = rel;
+ is->seek_flags &= ~AVSEEK_FLAG_BYTE;
+ if (seek_by_bytes)
+ is->seek_flags |= AVSEEK_FLAG_BYTE;
+ is->seek_req = 1;
+ }
+}
+
+/* pause or resume the video */
+static void stream_pause(VideoState *is)
+{
+ if (is->paused) {
+ is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
+ if(is->read_pause_return != AVERROR(ENOSYS)){
+ is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
+ }
+ is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
+ }
+ is->paused = !is->paused;
+}
+
+static double compute_target_time(double frame_current_pts, VideoState *is)
+{
+ double delay, sync_threshold, diff;
+
+ /* compute nominal delay */
+ delay = frame_current_pts - is->frame_last_pts;
+ if (delay <= 0 || delay >= 10.0) {
+ /* if incorrect delay, use previous one */
+ delay = is->frame_last_delay;
+ } else {
+ is->frame_last_delay = delay;
+ }
+ is->frame_last_pts = frame_current_pts;
+
+ /* update delay to follow master synchronisation source */
+ if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
+ is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
+ /* if video is slave, we try to correct big delays by
+ duplicating or deleting a frame */
+ diff = get_video_clock(is) - get_master_clock(is);
+
+ /* skip or repeat frame. We take into account the
+ delay to compute the threshold. I still don't know
+ if it is the best guess */
+ sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
+ if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
+ if (diff <= -sync_threshold)
+ delay = 0;
+ else if (diff >= sync_threshold)
+ delay = 2 * delay;
+ }
+ }
+ is->frame_timer += delay;
+
+ av_dlog(NULL, "video: delay=%0.3f pts=%0.3f A-V=%f\n",
+ delay, frame_current_pts, -diff);
+
+ return is->frame_timer;
+}
+
+/* called to display each frame */
+static void video_refresh_timer(void *opaque)
+{
+ VideoState *is = opaque;
+ VideoPicture *vp;
+
+ SubPicture *sp, *sp2;
+
+ if (is->video_st) {
+retry:
+ if (is->pictq_size == 0) {
+ //nothing to do, no picture to display in the que
+ } else {
+ double time= av_gettime()/1000000.0;
+ double next_target;
+ /* dequeue the picture */
+ vp = &is->pictq[is->pictq_rindex];
+
+ if(time < vp->target_clock)
+ return;
+ /* update current video pts */
+ is->video_current_pts = vp->pts;
+ is->video_current_pts_drift = is->video_current_pts - time;
+ is->video_current_pos = vp->pos;
+ if(is->pictq_size > 1){
+ VideoPicture *nextvp= &is->pictq[(is->pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE];
+ assert(nextvp->target_clock >= vp->target_clock);
+ next_target= nextvp->target_clock;
+ }else{
+ next_target= vp->target_clock + is->video_clock - vp->pts; //FIXME pass durations cleanly
+ }
+ if(framedrop && time > next_target){
+ is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR;
+ if(is->pictq_size > 1 || time > next_target + 0.5){
+ /* update queue size and signal for next picture */
+ if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
+ is->pictq_rindex = 0;
+
+ SDL_LockMutex(is->pictq_mutex);
+ is->pictq_size--;
+ SDL_CondSignal(is->pictq_cond);
+ SDL_UnlockMutex(is->pictq_mutex);
+ goto retry;
+ }
+ }
+
+ if(is->subtitle_st) {
+ if (is->subtitle_stream_changed) {
+ SDL_LockMutex(is->subpq_mutex);
+
+ while (is->subpq_size) {
+ free_subpicture(&is->subpq[is->subpq_rindex]);
+
+ /* update queue size and signal for next picture */
+ if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
+ is->subpq_rindex = 0;
+
+ is->subpq_size--;
+ }
+ is->subtitle_stream_changed = 0;
+
+ SDL_CondSignal(is->subpq_cond);
+ SDL_UnlockMutex(is->subpq_mutex);
+ } else {
+ if (is->subpq_size > 0) {
+ sp = &is->subpq[is->subpq_rindex];
+
+ if (is->subpq_size > 1)
+ sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
+ else
+ sp2 = NULL;
+
+ if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
+ || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
+ {
+ free_subpicture(sp);
+
+ /* update queue size and signal for next picture */
+ if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
+ is->subpq_rindex = 0;
+
+ SDL_LockMutex(is->subpq_mutex);
+ is->subpq_size--;
+ SDL_CondSignal(is->subpq_cond);
+ SDL_UnlockMutex(is->subpq_mutex);
+ }
+ }
+ }
+ }
+
+ /* display picture */
+ if (!display_disable)
+ video_display(is);
+
+ /* update queue size and signal for next picture */
+ if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
+ is->pictq_rindex = 0;
+
+ SDL_LockMutex(is->pictq_mutex);
+ is->pictq_size--;
+ SDL_CondSignal(is->pictq_cond);
+ SDL_UnlockMutex(is->pictq_mutex);
+ }
+ } else if (is->audio_st) {
+ /* draw the next audio frame */
+
+ /* if only audio stream, then display the audio bars (better
+ than nothing, just to test the implementation */
+
+ /* display picture */
+ if (!display_disable)
+ video_display(is);
+ }
+ if (show_status) {
+ static int64_t last_time;
+ int64_t cur_time;
+ int aqsize, vqsize, sqsize;
+ double av_diff;
+
+ cur_time = av_gettime();
+ if (!last_time || (cur_time - last_time) >= 30000) {
+ aqsize = 0;
+ vqsize = 0;
+ sqsize = 0;
+ if (is->audio_st)
+ aqsize = is->audioq.size;
+ if (is->video_st)
+ vqsize = is->videoq.size;
+ if (is->subtitle_st)
+ sqsize = is->subtitleq.size;
+ av_diff = 0;
+ if (is->audio_st && is->video_st)
+ av_diff = get_audio_clock(is) - get_video_clock(is);
+ printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
+ get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->pts_ctx.num_faulty_dts, is->pts_ctx.num_faulty_pts);
+ fflush(stdout);
+ last_time = cur_time;
+ }
+ }
+}
+
+static void stream_close(VideoState *is)
+{
+ VideoPicture *vp;
+ int i;
+ /* XXX: use a special url_shutdown call to abort parse cleanly */
+ is->abort_request = 1;
+ SDL_WaitThread(is->parse_tid, NULL);
+ SDL_WaitThread(is->refresh_tid, NULL);
+
+ /* free all pictures */
+ for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
+ vp = &is->pictq[i];
+#if CONFIG_AVFILTER
+ if (vp->picref) {
+ avfilter_unref_buffer(vp->picref);
+ vp->picref = NULL;
+ }
+#endif
+ if (vp->bmp) {
+ SDL_FreeYUVOverlay(vp->bmp);
+ vp->bmp = NULL;
+ }
+ }
+ SDL_DestroyMutex(is->pictq_mutex);
+ SDL_DestroyCond(is->pictq_cond);
+ SDL_DestroyMutex(is->subpq_mutex);
+ SDL_DestroyCond(is->subpq_cond);
+#if !CONFIG_AVFILTER
+ if (is->img_convert_ctx)
+ sws_freeContext(is->img_convert_ctx);
+#endif
+ av_free(is);
+}
+
+static void do_exit(void)
+{
+ if (cur_stream) {
+ stream_close(cur_stream);
+ cur_stream = NULL;
+ }
+ uninit_opts();
+#if CONFIG_AVFILTER
+ avfilter_uninit();
+#endif
+ avformat_network_deinit();
+ if (show_status)
+ printf("\n");
+ SDL_Quit();
+ av_log(NULL, AV_LOG_QUIET, "");
+ exit(0);
+}
+
+/* allocate a picture (needs to do that in main thread to avoid
+ potential locking problems */
+static void alloc_picture(void *opaque)
+{
+ VideoState *is = opaque;
+ VideoPicture *vp;
+
+ vp = &is->pictq[is->pictq_windex];
+
+ if (vp->bmp)
+ SDL_FreeYUVOverlay(vp->bmp);
+
+#if CONFIG_AVFILTER
+ if (vp->picref)
+ avfilter_unref_buffer(vp->picref);
+ vp->picref = NULL;
+
+ vp->width = is->out_video_filter->inputs[0]->w;
+ vp->height = is->out_video_filter->inputs[0]->h;
+ vp->pix_fmt = is->out_video_filter->inputs[0]->format;
+#else
+ vp->width = is->video_st->codec->width;
+ vp->height = is->video_st->codec->height;
+ vp->pix_fmt = is->video_st->codec->pix_fmt;
+#endif
+
+ vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
+ SDL_YV12_OVERLAY,
+ screen);
+ if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
+ /* SDL allocates a buffer smaller than requested if the video
+ * overlay hardware is unable to support the requested size. */
+ fprintf(stderr, "Error: the video system does not support an image\n"
+ "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
+ "to reduce the image size.\n", vp->width, vp->height );
+ do_exit();
+ }
+
+ SDL_LockMutex(is->pictq_mutex);
+ vp->allocated = 1;
+ SDL_CondSignal(is->pictq_cond);
+ SDL_UnlockMutex(is->pictq_mutex);
+}
+
+/**
+ *
+ * @param pts the dts of the pkt / pts of the frame and guessed if not known
+ */
+static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos)
+{
+ VideoPicture *vp;
+#if CONFIG_AVFILTER
+ AVPicture pict_src;
+#else
+ int dst_pix_fmt = PIX_FMT_YUV420P;
+#endif
+ /* wait until we have space to put a new picture */
+ SDL_LockMutex(is->pictq_mutex);
+
+ if(is->pictq_size>=VIDEO_PICTURE_QUEUE_SIZE && !is->refresh)
+ is->skip_frames= FFMAX(1.0 - FRAME_SKIP_FACTOR, is->skip_frames * (1.0-FRAME_SKIP_FACTOR));
+
+ while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
+ !is->videoq.abort_request) {
+ SDL_CondWait(is->pictq_cond, is->pictq_mutex);
+ }
+ SDL_UnlockMutex(is->pictq_mutex);
+
+ if (is->videoq.abort_request)
+ return -1;
+
+ vp = &is->pictq[is->pictq_windex];
+
+ /* alloc or resize hardware picture buffer */
+ if (!vp->bmp || vp->reallocate ||
+#if CONFIG_AVFILTER
+ vp->width != is->out_video_filter->inputs[0]->w ||
+ vp->height != is->out_video_filter->inputs[0]->h) {
+#else
+ vp->width != is->video_st->codec->width ||
+ vp->height != is->video_st->codec->height) {
+#endif
+ SDL_Event event;
+
+ vp->allocated = 0;
+ vp->reallocate = 0;
+
+ /* the allocation must be done in the main thread to avoid
+ locking problems */
+ event.type = FF_ALLOC_EVENT;
+ event.user.data1 = is;
+ SDL_PushEvent(&event);
+
+ /* wait until the picture is allocated */
+ SDL_LockMutex(is->pictq_mutex);
+ while (!vp->allocated && !is->videoq.abort_request) {
+ SDL_CondWait(is->pictq_cond, is->pictq_mutex);
+ }
+ SDL_UnlockMutex(is->pictq_mutex);
+
+ if (is->videoq.abort_request)
+ return -1;
+ }
+
+ /* if the frame is not skipped, then display it */
+ if (vp->bmp) {
+ AVPicture pict;
+#if CONFIG_AVFILTER
+ if(vp->picref)
+ avfilter_unref_buffer(vp->picref);
+ vp->picref = src_frame->opaque;
+#endif
+
+ /* get a pointer on the bitmap */
+ SDL_LockYUVOverlay (vp->bmp);
+
+ memset(&pict,0,sizeof(AVPicture));
+ pict.data[0] = vp->bmp->pixels[0];
+ pict.data[1] = vp->bmp->pixels[2];
+ pict.data[2] = vp->bmp->pixels[1];
+
+ pict.linesize[0] = vp->bmp->pitches[0];
+ pict.linesize[1] = vp->bmp->pitches[2];
+ pict.linesize[2] = vp->bmp->pitches[1];
+
+#if CONFIG_AVFILTER
+ pict_src.data[0] = src_frame->data[0];
+ pict_src.data[1] = src_frame->data[1];
+ pict_src.data[2] = src_frame->data[2];
+
+ pict_src.linesize[0] = src_frame->linesize[0];
+ pict_src.linesize[1] = src_frame->linesize[1];
+ pict_src.linesize[2] = src_frame->linesize[2];
+
+ //FIXME use direct rendering
+ av_picture_copy(&pict, &pict_src,
+ vp->pix_fmt, vp->width, vp->height);
+#else
+ sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
+ is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
+ vp->width, vp->height, vp->pix_fmt, vp->width, vp->height,
+ dst_pix_fmt, sws_flags, NULL, NULL, NULL);
+ if (is->img_convert_ctx == NULL) {
+ fprintf(stderr, "Cannot initialize the conversion context\n");
+ exit(1);
+ }
+ sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
+ 0, vp->height, pict.data, pict.linesize);
+#endif
+ /* update the bitmap content */
+ SDL_UnlockYUVOverlay(vp->bmp);
+
+ vp->pts = pts;
+ vp->pos = pos;
+
+ /* now we can update the picture count */
+ if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
+ is->pictq_windex = 0;
+ SDL_LockMutex(is->pictq_mutex);
+ vp->target_clock= compute_target_time(vp->pts, is);
+
+ is->pictq_size++;
+ SDL_UnlockMutex(is->pictq_mutex);
+ }
+ return 0;
+}
+
+/**
+ * compute the exact PTS for the picture if it is omitted in the stream
+ * @param pts1 the dts of the pkt / pts of the frame
+ */
+static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
+{
+ double frame_delay, pts;
+
+ pts = pts1;
+
+ if (pts != 0) {
+ /* update video clock with pts, if present */
+ is->video_clock = pts;
+ } else {
+ pts = is->video_clock;
+ }
+ /* update video clock for next frame */
+ frame_delay = av_q2d(is->video_st->codec->time_base);
+ /* for MPEG2, the frame can be repeated, so we update the
+ clock accordingly */
+ frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
+ is->video_clock += frame_delay;
+
+ return queue_picture(is, src_frame, pts, pos);
+}
+
+static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
+{
+ int got_picture, i;
+
+ if (packet_queue_get(&is->videoq, pkt, 1) < 0)
+ return -1;
+
+ if (pkt->data == flush_pkt.data) {
+ avcodec_flush_buffers(is->video_st->codec);
+
+ SDL_LockMutex(is->pictq_mutex);
+ //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
+ for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
+ is->pictq[i].target_clock= 0;
+ }
+ while (is->pictq_size && !is->videoq.abort_request) {
+ SDL_CondWait(is->pictq_cond, is->pictq_mutex);
+ }
+ is->video_current_pos = -1;
+ SDL_UnlockMutex(is->pictq_mutex);
+
+ init_pts_correction(&is->pts_ctx);
+ is->frame_last_pts = AV_NOPTS_VALUE;
+ is->frame_last_delay = 0;
+ is->frame_timer = (double)av_gettime() / 1000000.0;
+ is->skip_frames = 1;
+ is->skip_frames_index = 0;
+ return 0;
+ }
+
+ avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt);
+
+ if (got_picture) {
+ if (decoder_reorder_pts == -1) {
+ *pts = guess_correct_pts(&is->pts_ctx, frame->pkt_pts, frame->pkt_dts);
+ } else if (decoder_reorder_pts) {
+ *pts = frame->pkt_pts;
+ } else {
+ *pts = frame->pkt_dts;
+ }
+
+ if (*pts == AV_NOPTS_VALUE) {
+ *pts = 0;
+ }
+
+ is->skip_frames_index += 1;
+ if(is->skip_frames_index >= is->skip_frames){
+ is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);
+ return 1;
+ }
+
+ }
+ return 0;
+}
+
+#if CONFIG_AVFILTER
+typedef struct {
+ VideoState *is;
+ AVFrame *frame;
+ int use_dr1;
+} FilterPriv;
+
+static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
+{
+ AVFilterContext *ctx = codec->opaque;
+ AVFilterBufferRef *ref;
+ int perms = AV_PERM_WRITE;
+ int i, w, h, stride[4];
+ unsigned edge;
+ int pixel_size;
+
+ if (codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES)
+ perms |= AV_PERM_NEG_LINESIZES;
+
+ if(pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
+ if(pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
+ if(pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
+ if(pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2;
+ }
+ if(pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE;
+
+ w = codec->width;
+ h = codec->height;
+ avcodec_align_dimensions2(codec, &w, &h, stride);
+ edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width();
+ w += edge << 1;
+ h += edge << 1;
+
+ if(!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h)))
+ return -1;
+
+ pixel_size = av_pix_fmt_descriptors[ref->format].comp[0].step_minus1+1;
+ ref->video->w = codec->width;
+ ref->video->h = codec->height;
+ for(i = 0; i < 4; i ++) {
+ unsigned hshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_w : 0;
+ unsigned vshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_h : 0;
+
+ if (ref->data[i]) {
+ ref->data[i] += ((edge * pixel_size) >> hshift) + ((edge * ref->linesize[i]) >> vshift);
+ }
+ pic->data[i] = ref->data[i];
+ pic->linesize[i] = ref->linesize[i];
+ }
+ pic->opaque = ref;
+ pic->type = FF_BUFFER_TYPE_USER;
+ pic->reordered_opaque = codec->reordered_opaque;
+ if(codec->pkt) pic->pkt_pts = codec->pkt->pts;
+ else pic->pkt_pts = AV_NOPTS_VALUE;
+ return 0;
+}
+
+static void input_release_buffer(AVCodecContext *codec, AVFrame *pic)
+{
+ memset(pic->data, 0, sizeof(pic->data));
+ avfilter_unref_buffer(pic->opaque);
+}
+
+static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic)
+{
+ AVFilterBufferRef *ref = pic->opaque;
+
+ if (pic->data[0] == NULL) {
+ pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
+ return codec->get_buffer(codec, pic);
+ }
+
+ if ((codec->width != ref->video->w) || (codec->height != ref->video->h) ||
+ (codec->pix_fmt != ref->format)) {
+ av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n");
+ return -1;
+ }
+
+ pic->reordered_opaque = codec->reordered_opaque;
+ if(codec->pkt) pic->pkt_pts = codec->pkt->pts;
+ else pic->pkt_pts = AV_NOPTS_VALUE;
+ return 0;
+}
+
+static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ FilterPriv *priv = ctx->priv;
+ AVCodecContext *codec;
+ if(!opaque) return -1;
+
+ priv->is = opaque;
+ codec = priv->is->video_st->codec;
+ codec->opaque = ctx;
+ if(codec->codec->capabilities & CODEC_CAP_DR1) {
+ priv->use_dr1 = 1;
+ codec->get_buffer = input_get_buffer;
+ codec->release_buffer = input_release_buffer;
+ codec->reget_buffer = input_reget_buffer;
+ codec->thread_safe_callbacks = 1;
+ }
+
+ priv->frame = avcodec_alloc_frame();
+
+ return 0;
+}
+
+static void input_uninit(AVFilterContext *ctx)
+{
+ FilterPriv *priv = ctx->priv;
+ av_free(priv->frame);
+}
+
+static int input_request_frame(AVFilterLink *link)
+{
+ FilterPriv *priv = link->src->priv;
+ AVFilterBufferRef *picref;
+ int64_t pts = 0;
+ AVPacket pkt;
+ int ret;
+
+ while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
+ av_free_packet(&pkt);
+ if (ret < 0)
+ return -1;
+
+ if(priv->use_dr1) {
+ picref = avfilter_ref_buffer(priv->frame->opaque, ~0);
+ } else {
+ picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
+ av_image_copy(picref->data, picref->linesize,
+ priv->frame->data, priv->frame->linesize,
+ picref->format, link->w, link->h);
+ }
+ av_free_packet(&pkt);
+
+ avfilter_copy_frame_props(picref, priv->frame);
+ picref->pts = pts;
+
+ avfilter_start_frame(link, picref);
+ avfilter_draw_slice(link, 0, link->h, 1);
+ avfilter_end_frame(link);
+
+ return 0;
+}
+
+static int input_query_formats(AVFilterContext *ctx)
+{
+ FilterPriv *priv = ctx->priv;
+ enum PixelFormat pix_fmts[] = {
+ priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
+ };
+
+ avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ return 0;
+}
+
+static int input_config_props(AVFilterLink *link)
+{
+ FilterPriv *priv = link->src->priv;
+ AVCodecContext *c = priv->is->video_st->codec;
+
+ link->w = c->width;
+ link->h = c->height;
+ link->time_base = priv->is->video_st->time_base;
+
+ return 0;
+}
+
+static AVFilter input_filter =
+{
+ .name = "avplay_input",
+
+ .priv_size = sizeof(FilterPriv),
+
+ .init = input_init,
+ .uninit = input_uninit,
+
+ .query_formats = input_query_formats,
+
+ .inputs = (AVFilterPad[]) {{ .name = NULL }},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .request_frame = input_request_frame,
+ .config_props = input_config_props, },
+ { .name = NULL }},
+};
+
+static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
+{
+ char sws_flags_str[128];
+ int ret;
+ FFSinkContext ffsink_ctx = { .pix_fmt = PIX_FMT_YUV420P };
+ AVFilterContext *filt_src = NULL, *filt_out = NULL;
+ snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
+ graph->scale_sws_opts = av_strdup(sws_flags_str);
+
+ if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
+ NULL, is, graph)) < 0)
+ return ret;
+ if ((ret = avfilter_graph_create_filter(&filt_out, &ffsink, "out",
+ NULL, &ffsink_ctx, graph)) < 0)
+ return ret;
+
+ if(vfilters) {
+ AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
+ AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut));
+
+ outputs->name = av_strdup("in");
+ outputs->filter_ctx = filt_src;
+ outputs->pad_idx = 0;
+ outputs->next = NULL;
+
+ inputs->name = av_strdup("out");
+ inputs->filter_ctx = filt_out;
+ inputs->pad_idx = 0;
+ inputs->next = NULL;
+
+ if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0)
+ return ret;
+ av_freep(&vfilters);
+ } else {
+ if ((ret = avfilter_link(filt_src, 0, filt_out, 0)) < 0)
+ return ret;
+ }
+
+ if ((ret = avfilter_graph_config(graph, NULL)) < 0)
+ return ret;
+
+ is->out_video_filter = filt_out;
+
+ return ret;
+}
+
+#endif /* CONFIG_AVFILTER */
+
+static int video_thread(void *arg)
+{
+ VideoState *is = arg;
+ AVFrame *frame= avcodec_alloc_frame();
+ int64_t pts_int;
+ double pts;
+ int ret;
+
+#if CONFIG_AVFILTER
+ AVFilterGraph *graph = avfilter_graph_alloc();
+ AVFilterContext *filt_out = NULL;
+ int64_t pos;
+ int last_w = is->video_st->codec->width;
+ int last_h = is->video_st->codec->height;
+
+ if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
+ goto the_end;
+ filt_out = is->out_video_filter;
+#endif
+
+ for(;;) {
+#if !CONFIG_AVFILTER
+ AVPacket pkt;
+#else
+ AVFilterBufferRef *picref;
+ AVRational tb;
+#endif
+ while (is->paused && !is->videoq.abort_request)
+ SDL_Delay(10);
+#if CONFIG_AVFILTER
+ if ( last_w != is->video_st->codec->width
+ || last_h != is->video_st->codec->height) {
+ av_dlog(NULL, "Changing size %dx%d -> %dx%d\n", last_w, last_h,
+ is->video_st->codec->width, is->video_st->codec->height);
+ avfilter_graph_free(&graph);
+ graph = avfilter_graph_alloc();
+ if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
+ goto the_end;
+ filt_out = is->out_video_filter;
+ last_w = is->video_st->codec->width;
+ last_h = is->video_st->codec->height;
+ }
+ ret = get_filtered_video_frame(filt_out, frame, &picref, &tb);
+ if (picref) {
+ pts_int = picref->pts;
+ pos = picref->pos;
+ frame->opaque = picref;
+ }
+
+ if (av_cmp_q(tb, is->video_st->time_base)) {
+ av_unused int64_t pts1 = pts_int;
+ pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
+ av_dlog(NULL, "video_thread(): "
+ "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
+ tb.num, tb.den, pts1,
+ is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
+ }
+#else
+ ret = get_video_frame(is, frame, &pts_int, &pkt);
+#endif
+
+ if (ret < 0) goto the_end;
+
+ if (!ret)
+ continue;
+
+ pts = pts_int*av_q2d(is->video_st->time_base);
+
+#if CONFIG_AVFILTER
+ ret = output_picture2(is, frame, pts, pos);
+#else
+ ret = output_picture2(is, frame, pts, pkt.pos);
+ av_free_packet(&pkt);
+#endif
+ if (ret < 0)
+ goto the_end;
+
+ if (step)
+ if (cur_stream)
+ stream_pause(cur_stream);
+ }
+ the_end:
+#if CONFIG_AVFILTER
+ avfilter_graph_free(&graph);
+#endif
+ av_free(frame);
+ return 0;
+}
+
+static int subtitle_thread(void *arg)
+{
+ VideoState *is = arg;
+ SubPicture *sp;
+ AVPacket pkt1, *pkt = &pkt1;
+ int got_subtitle;
+ double pts;
+ int i, j;
+ int r, g, b, y, u, v, a;
+
+ for(;;) {
+ while (is->paused && !is->subtitleq.abort_request) {
+ SDL_Delay(10);
+ }
+ if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
+ break;
+
+ if(pkt->data == flush_pkt.data){
+ avcodec_flush_buffers(is->subtitle_st->codec);
+ continue;
+ }
+ SDL_LockMutex(is->subpq_mutex);
+ while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
+ !is->subtitleq.abort_request) {
+ SDL_CondWait(is->subpq_cond, is->subpq_mutex);
+ }
+ SDL_UnlockMutex(is->subpq_mutex);
+
+ if (is->subtitleq.abort_request)
+ return 0;
+
+ sp = &is->subpq[is->subpq_windex];
+
+ /* NOTE: ipts is the PTS of the _first_ picture beginning in
+ this packet, if any */
+ pts = 0;
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
+
+ avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
+ &got_subtitle, pkt);
+
+ if (got_subtitle && sp->sub.format == 0) {
+ sp->pts = pts;
+
+ for (i = 0; i < sp->sub.num_rects; i++)
+ {
+ for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
+ {
+ RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
+ y = RGB_TO_Y_CCIR(r, g, b);
+ u = RGB_TO_U_CCIR(r, g, b, 0);
+ v = RGB_TO_V_CCIR(r, g, b, 0);
+ YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
+ }
+ }
+
+ /* now we can update the picture count */
+ if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
+ is->subpq_windex = 0;
+ SDL_LockMutex(is->subpq_mutex);
+ is->subpq_size++;
+ SDL_UnlockMutex(is->subpq_mutex);
+ }
+ av_free_packet(pkt);
+ }
+ return 0;
+}
+
+/* copy samples for viewing in editor window */
+static void update_sample_display(VideoState *is, short *samples, int samples_size)
+{
+ int size, len;
+
+ size = samples_size / sizeof(short);
+ while (size > 0) {
+ len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
+ if (len > size)
+ len = size;
+ memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
+ samples += len;
+ is->sample_array_index += len;
+ if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
+ is->sample_array_index = 0;
+ size -= len;
+ }
+}
+
+/* return the new audio buffer size (samples can be added or deleted
+ to get better sync if video or external master clock) */
+static int synchronize_audio(VideoState *is, short *samples,
+ int samples_size1, double pts)
+{
+ int n, samples_size;
+ double ref_clock;
+
+ n = 2 * is->audio_st->codec->channels;
+ samples_size = samples_size1;
+
+ /* if not master, then we try to remove or add samples to correct the clock */
+ if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
+ is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
+ double diff, avg_diff;
+ int wanted_size, min_size, max_size, nb_samples;
+
+ ref_clock = get_master_clock(is);
+ diff = get_audio_clock(is) - ref_clock;
+
+ if (diff < AV_NOSYNC_THRESHOLD) {
+ is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
+ if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
+ /* not enough measures to have a correct estimate */
+ is->audio_diff_avg_count++;
+ } else {
+ /* estimate the A-V difference */
+ avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
+
+ if (fabs(avg_diff) >= is->audio_diff_threshold) {
+ wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
+ nb_samples = samples_size / n;
+
+ min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
+ max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
+ if (wanted_size < min_size)
+ wanted_size = min_size;
+ else if (wanted_size > max_size)
+ wanted_size = max_size;
+
+ /* add or remove samples to correction the synchro */
+ if (wanted_size < samples_size) {
+ /* remove samples */
+ samples_size = wanted_size;
+ } else if (wanted_size > samples_size) {
+ uint8_t *samples_end, *q;
+ int nb;
+
+ /* add samples */
+ nb = (samples_size - wanted_size);
+ samples_end = (uint8_t *)samples + samples_size - n;
+ q = samples_end + n;
+ while (nb > 0) {
+ memcpy(q, samples_end, n);
+ q += n;
+ nb -= n;
+ }
+ samples_size = wanted_size;
+ }
+ }
+ av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
+ diff, avg_diff, samples_size - samples_size1,
+ is->audio_clock, is->video_clock, is->audio_diff_threshold);
+ }
+ } else {
+ /* too big difference : may be initial PTS errors, so
+ reset A-V filter */
+ is->audio_diff_avg_count = 0;
+ is->audio_diff_cum = 0;
+ }
+ }
+
+ return samples_size;
+}
+
+/* decode one audio frame and returns its uncompressed size */
+static int audio_decode_frame(VideoState *is, double *pts_ptr)
+{
+ AVPacket *pkt_temp = &is->audio_pkt_temp;
+ AVPacket *pkt = &is->audio_pkt;
+ AVCodecContext *dec= is->audio_st->codec;
+ int n, len1, data_size, got_frame;
+ double pts;
+ int new_packet = 0;
+ int flush_complete = 0;
+
+ for(;;) {
+ /* NOTE: the audio packet can contain several frames */
+ while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
+ if (!is->frame) {
+ if (!(is->frame = avcodec_alloc_frame()))
+ return AVERROR(ENOMEM);
+ } else
+ avcodec_get_frame_defaults(is->frame);
+
+ if (flush_complete)
+ break;
+ new_packet = 0;
+ len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
+ if (len1 < 0) {
+ /* if error, we skip the frame */
+ pkt_temp->size = 0;
+ break;
+ }
+
+ pkt_temp->data += len1;
+ pkt_temp->size -= len1;
+
+ if (!got_frame) {
+ /* stop sending empty packets if the decoder is finished */
+ if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
+ flush_complete = 1;
+ continue;
+ }
+ data_size = av_samples_get_buffer_size(NULL, dec->channels,
+ is->frame->nb_samples,
+ dec->sample_fmt, 1);
+
+ if (dec->sample_fmt != is->audio_src_fmt) {
+ if (is->reformat_ctx)
+ av_audio_convert_free(is->reformat_ctx);
+ is->reformat_ctx= av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,
+ dec->sample_fmt, 1, NULL, 0);
+ if (!is->reformat_ctx) {
+ fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
+ av_get_sample_fmt_name(dec->sample_fmt),
+ av_get_sample_fmt_name(AV_SAMPLE_FMT_S16));
+ break;
+ }
+ is->audio_src_fmt= dec->sample_fmt;
+ }
+
+ if (is->reformat_ctx) {
+ const void *ibuf[6]= { is->frame->data[0] };
+ void *obuf[6];
+ int istride[6]= {av_get_bytes_per_sample(dec->sample_fmt)};
+ int ostride[6]= {2};
+ int len= data_size/istride[0];
+ obuf[0] = av_realloc(is->audio_buf1, FFALIGN(len * ostride[0], 32));
+ if (!obuf[0]) {
+ return AVERROR(ENOMEM);
+ }
+ is->audio_buf1 = obuf[0];
+ if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
+ printf("av_audio_convert() failed\n");
+ break;
+ }
+ is->audio_buf = is->audio_buf1;
+ /* FIXME: existing code assume that data_size equals framesize*channels*2
+ remove this legacy cruft */
+ data_size= len*2;
+ }else{
+ is->audio_buf = is->frame->data[0];
+ }
+
+ /* if no pts, then compute it */
+ pts = is->audio_clock;
+ *pts_ptr = pts;
+ n = 2 * dec->channels;
+ is->audio_clock += (double)data_size /
+ (double)(n * dec->sample_rate);
+#ifdef DEBUG
+ {
+ static double last_clock;
+ printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
+ is->audio_clock - last_clock,
+ is->audio_clock, pts);
+ last_clock = is->audio_clock;
+ }
+#endif
+ return data_size;
+ }
+
+ /* free the current packet */
+ if (pkt->data)
+ av_free_packet(pkt);
+ memset(pkt_temp, 0, sizeof(*pkt_temp));
+
+ if (is->paused || is->audioq.abort_request) {
+ return -1;
+ }
+
+ /* read next packet */
+ if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
+ return -1;
+
+ if (pkt->data == flush_pkt.data)
+ avcodec_flush_buffers(dec);
+
+ *pkt_temp = *pkt;
+
+ /* if update the audio clock with the pts */
+ if (pkt->pts != AV_NOPTS_VALUE) {
+ is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
+ }
+ }
+}
+
+/* prepare a new audio buffer */
+static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
+{
+ VideoState *is = opaque;
+ int audio_size, len1;
+ double pts;
+
+ audio_callback_time = av_gettime();
+
+ while (len > 0) {
+ if (is->audio_buf_index >= is->audio_buf_size) {
+ audio_size = audio_decode_frame(is, &pts);
+ if (audio_size < 0) {
+ /* if error, just output silence */
+ is->audio_buf = is->silence_buf;
+ is->audio_buf_size = sizeof(is->silence_buf);
+ } else {
+ if (is->show_audio)
+ update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
+ audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
+ pts);
+ is->audio_buf_size = audio_size;
+ }
+ is->audio_buf_index = 0;
+ }
+ len1 = is->audio_buf_size - is->audio_buf_index;
+ if (len1 > len)
+ len1 = len;
+ memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
+ len -= len1;
+ stream += len1;
+ is->audio_buf_index += len1;
+ }
+}
+
+/* open a given stream. Return 0 if OK */
+static int stream_component_open(VideoState *is, int stream_index)
+{
+ AVFormatContext *ic = is->ic;
+ AVCodecContext *avctx;
+ AVCodec *codec;
+ SDL_AudioSpec wanted_spec, spec;
+ AVDictionary *opts;
+ AVDictionaryEntry *t = NULL;
+
+ if (stream_index < 0 || stream_index >= ic->nb_streams)
+ return -1;
+ avctx = ic->streams[stream_index]->codec;
+
+ opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index]);
+
+ codec = avcodec_find_decoder(avctx->codec_id);
+ avctx->debug_mv = debug_mv;
+ avctx->debug = debug;
+ avctx->workaround_bugs = workaround_bugs;
+ avctx->lowres = lowres;
+ if(lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
+ avctx->idct_algo= idct;
+ if(fast) avctx->flags2 |= CODEC_FLAG2_FAST;
+ avctx->skip_frame= skip_frame;
+ avctx->skip_idct= skip_idct;
+ avctx->skip_loop_filter= skip_loop_filter;
+ avctx->error_recognition= error_recognition;
+ avctx->error_concealment= error_concealment;
+ avctx->thread_count= thread_count;
+
+ if (!codec ||
+ avcodec_open2(avctx, codec, &opts) < 0)
+ return -1;
+ if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+ av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
+ return AVERROR_OPTION_NOT_FOUND;
+ }
+
+ /* prepare audio output */
+ if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
+ wanted_spec.freq = avctx->sample_rate;
+ wanted_spec.format = AUDIO_S16SYS;
+ wanted_spec.channels = avctx->channels;
+ wanted_spec.silence = 0;
+ wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
+ wanted_spec.callback = sdl_audio_callback;
+ wanted_spec.userdata = is;
+ if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
+ fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
+ return -1;
+ }
+ is->audio_hw_buf_size = spec.size;
+ is->audio_src_fmt= AV_SAMPLE_FMT_S16;
+ }
+
+ ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
+ switch(avctx->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ is->audio_stream = stream_index;
+ is->audio_st = ic->streams[stream_index];
+ is->audio_buf_size = 0;
+ is->audio_buf_index = 0;
+
+ /* init averaging filter */
+ is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
+ is->audio_diff_avg_count = 0;
+ /* since we do not have a precise anough audio fifo fullness,
+ we correct audio sync only if larger than this threshold */
+ is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / avctx->sample_rate;
+
+ memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
+ packet_queue_init(&is->audioq);
+ SDL_PauseAudio(0);
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ is->video_stream = stream_index;
+ is->video_st = ic->streams[stream_index];
+
+ packet_queue_init(&is->videoq);
+ is->video_tid = SDL_CreateThread(video_thread, is);
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ is->subtitle_stream = stream_index;
+ is->subtitle_st = ic->streams[stream_index];
+ packet_queue_init(&is->subtitleq);
+
+ is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static void stream_component_close(VideoState *is, int stream_index)
+{
+ AVFormatContext *ic = is->ic;
+ AVCodecContext *avctx;
+
+ if (stream_index < 0 || stream_index >= ic->nb_streams)
+ return;
+ avctx = ic->streams[stream_index]->codec;
+
+ switch(avctx->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ packet_queue_abort(&is->audioq);
+
+ SDL_CloseAudio();
+
+ packet_queue_end(&is->audioq);
+ av_free_packet(&is->audio_pkt);
+ if (is->reformat_ctx)
+ av_audio_convert_free(is->reformat_ctx);
+ is->reformat_ctx = NULL;
+ av_freep(&is->audio_buf1);
+ is->audio_buf = NULL;
+ av_freep(&is->frame);
+
+ if (is->rdft) {
+ av_rdft_end(is->rdft);
+ av_freep(&is->rdft_data);
+ is->rdft = NULL;
+ is->rdft_bits = 0;
+ }
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ packet_queue_abort(&is->videoq);
+
+ /* note: we also signal this mutex to make sure we deblock the
+ video thread in all cases */
+ SDL_LockMutex(is->pictq_mutex);
+ SDL_CondSignal(is->pictq_cond);
+ SDL_UnlockMutex(is->pictq_mutex);
+
+ SDL_WaitThread(is->video_tid, NULL);
+
+ packet_queue_end(&is->videoq);
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ packet_queue_abort(&is->subtitleq);
+
+ /* note: we also signal this mutex to make sure we deblock the
+ video thread in all cases */
+ SDL_LockMutex(is->subpq_mutex);
+ is->subtitle_stream_changed = 1;
+
+ SDL_CondSignal(is->subpq_cond);
+ SDL_UnlockMutex(is->subpq_mutex);
+
+ SDL_WaitThread(is->subtitle_tid, NULL);
+
+ packet_queue_end(&is->subtitleq);
+ break;
+ default:
+ break;
+ }
+
+ ic->streams[stream_index]->discard = AVDISCARD_ALL;
+ avcodec_close(avctx);
+ switch(avctx->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ is->audio_st = NULL;
+ is->audio_stream = -1;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ is->video_st = NULL;
+ is->video_stream = -1;
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ is->subtitle_st = NULL;
+ is->subtitle_stream = -1;
+ break;
+ default:
+ break;
+ }
+}
+
+/* since we have only one decoding thread, we can use a global
+ variable instead of a thread local variable */
+static VideoState *global_video_state;
+
+static int decode_interrupt_cb(void *ctx)
+{
+ return (global_video_state && global_video_state->abort_request);
+}
+
+/* this thread gets the stream from the disk or the network */
+static int decode_thread(void *arg)
+{
+ VideoState *is = arg;
+ AVFormatContext *ic = NULL;
+ int err, i, ret;
+ int st_index[AVMEDIA_TYPE_NB];
+ AVPacket pkt1, *pkt = &pkt1;
+ int eof=0;
+ int pkt_in_play_range = 0;
+ AVDictionaryEntry *t;
+ AVDictionary **opts;
+ int orig_nb_streams;
+
+ memset(st_index, -1, sizeof(st_index));
+ is->video_stream = -1;
+ is->audio_stream = -1;
+ is->subtitle_stream = -1;
+
+ global_video_state = is;
+
+ ic = avformat_alloc_context();
+ ic->interrupt_callback.callback = decode_interrupt_cb;
+ err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
+ if (err < 0) {
+ print_error(is->filename, err);
+ ret = -1;
+ goto fail;
+ }
+ if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+ av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
+ ret = AVERROR_OPTION_NOT_FOUND;
+ goto fail;
+ }
+ is->ic = ic;
+
+ if(genpts)
+ ic->flags |= AVFMT_FLAG_GENPTS;
+
+ opts = setup_find_stream_info_opts(ic, codec_opts);
+ orig_nb_streams = ic->nb_streams;
+
+ err = avformat_find_stream_info(ic, opts);
+ if (err < 0) {
+ fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
+ ret = -1;
+ goto fail;
+ }
+ for (i = 0; i < orig_nb_streams; i++)
+ av_dict_free(&opts[i]);
+ av_freep(&opts);
+
+ if(ic->pb)
+ ic->pb->eof_reached= 0; //FIXME hack, avplay maybe should not use url_feof() to test for the end
+
+ if(seek_by_bytes<0)
+ seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT);
+
+ /* if seeking requested, we execute it */
+ if (start_time != AV_NOPTS_VALUE) {
+ int64_t timestamp;
+
+ timestamp = start_time;
+ /* add the stream start time */
+ if (ic->start_time != AV_NOPTS_VALUE)
+ timestamp += ic->start_time;
+ ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
+ if (ret < 0) {
+ fprintf(stderr, "%s: could not seek to position %0.3f\n",
+ is->filename, (double)timestamp / AV_TIME_BASE);
+ }
+ }
+
+ for (i = 0; i < ic->nb_streams; i++)
+ ic->streams[i]->discard = AVDISCARD_ALL;
+ if (!video_disable)
+ st_index[AVMEDIA_TYPE_VIDEO] =
+ av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
+ wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
+ if (!audio_disable)
+ st_index[AVMEDIA_TYPE_AUDIO] =
+ av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
+ wanted_stream[AVMEDIA_TYPE_AUDIO],
+ st_index[AVMEDIA_TYPE_VIDEO],
+ NULL, 0);
+ if (!video_disable)
+ st_index[AVMEDIA_TYPE_SUBTITLE] =
+ av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
+ wanted_stream[AVMEDIA_TYPE_SUBTITLE],
+ (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
+ st_index[AVMEDIA_TYPE_AUDIO] :
+ st_index[AVMEDIA_TYPE_VIDEO]),
+ NULL, 0);
+ if (show_status) {
+ av_dump_format(ic, 0, is->filename, 0);
+ }
+
+ /* open the streams */
+ if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
+ stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
+ }
+
+ ret=-1;
+ if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
+ ret= stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
+ }
+ is->refresh_tid = SDL_CreateThread(refresh_thread, is);
+ if(ret<0) {
+ if (!display_disable)
+ is->show_audio = 2;
+ }
+
+ if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
+ stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
+ }
+
+ if (is->video_stream < 0 && is->audio_stream < 0) {
+ fprintf(stderr, "%s: could not open codecs\n", is->filename);
+ ret = -1;
+ goto fail;
+ }
+
+ for(;;) {
+ if (is->abort_request)
+ break;
+ if (is->paused != is->last_paused) {
+ is->last_paused = is->paused;
+ if (is->paused)
+ is->read_pause_return= av_read_pause(ic);
+ else
+ av_read_play(ic);
+ }
+#if CONFIG_RTSP_DEMUXER
+ if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
+ /* wait 10 ms to avoid trying to get another packet */
+ /* XXX: horrible */
+ SDL_Delay(10);
+ continue;
+ }
+#endif
+ if (is->seek_req) {
+ int64_t seek_target= is->seek_pos;
+ int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
+ int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
+//FIXME the +-2 is due to rounding being not done in the correct direction in generation
+// of the seek_pos/seek_rel variables
+
+ ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
+ if (ret < 0) {
+ fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
+ }else{
+ if (is->audio_stream >= 0) {
+ packet_queue_flush(&is->audioq);
+ packet_queue_put(&is->audioq, &flush_pkt);
+ }
+ if (is->subtitle_stream >= 0) {
+ packet_queue_flush(&is->subtitleq);
+ packet_queue_put(&is->subtitleq, &flush_pkt);
+ }
+ if (is->video_stream >= 0) {
+ packet_queue_flush(&is->videoq);
+ packet_queue_put(&is->videoq, &flush_pkt);
+ }
+ }
+ is->seek_req = 0;
+ eof= 0;
+ }
+
+ /* if the queue are full, no need to read more */
+ if ( is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
+ || ( (is->audioq .size > MIN_AUDIOQ_SIZE || is->audio_stream<0)
+ && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream<0)
+ && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
+ /* wait 10 ms */
+ SDL_Delay(10);
+ continue;
+ }
+ if(eof) {
+ if(is->video_stream >= 0){
+ av_init_packet(pkt);
+ pkt->data=NULL;
+ pkt->size=0;
+ pkt->stream_index= is->video_stream;
+ packet_queue_put(&is->videoq, pkt);
+ }
+ if (is->audio_stream >= 0 &&
+ is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
+ av_init_packet(pkt);
+ pkt->data = NULL;
+ pkt->size = 0;
+ pkt->stream_index = is->audio_stream;
+ packet_queue_put(&is->audioq, pkt);
+ }
+ SDL_Delay(10);
+ if(is->audioq.size + is->videoq.size + is->subtitleq.size ==0){
+ if(loop!=1 && (!loop || --loop)){
+ stream_seek(cur_stream, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
+ }else if(autoexit){
+ ret=AVERROR_EOF;
+ goto fail;
+ }
+ }
+ continue;
+ }
+ ret = av_read_frame(ic, pkt);
+ if (ret < 0) {
+ if (ret == AVERROR_EOF || (ic->pb && ic->pb->eof_reached))
+ eof=1;
+ if (ic->pb && ic->pb->error)
+ break;
+ SDL_Delay(100); /* wait for user event */
+ continue;
+ }
+ /* check if packet is in play range specified by user, then queue, otherwise discard */
+ pkt_in_play_range = duration == AV_NOPTS_VALUE ||
+ (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
+ av_q2d(ic->streams[pkt->stream_index]->time_base) -
+ (double)(start_time != AV_NOPTS_VALUE ? start_time : 0)/1000000
+ <= ((double)duration/1000000);
+ if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
+ packet_queue_put(&is->audioq, pkt);
+ } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
+ packet_queue_put(&is->videoq, pkt);
+ } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
+ packet_queue_put(&is->subtitleq, pkt);
+ } else {
+ av_free_packet(pkt);
+ }
+ }
+ /* wait until the end */
+ while (!is->abort_request) {
+ SDL_Delay(100);
+ }
+
+ ret = 0;
+ fail:
+ /* disable interrupting */
+ global_video_state = NULL;
+
+ /* close each stream */
+ if (is->audio_stream >= 0)
+ stream_component_close(is, is->audio_stream);
+ if (is->video_stream >= 0)
+ stream_component_close(is, is->video_stream);
+ if (is->subtitle_stream >= 0)
+ stream_component_close(is, is->subtitle_stream);
+ if (is->ic) {
+ avformat_close_input(&is->ic);
+ }
+ avio_set_interrupt_cb(NULL);
+
+ if (ret != 0) {
+ SDL_Event event;
+
+ event.type = FF_QUIT_EVENT;
+ event.user.data1 = is;
+ SDL_PushEvent(&event);
+ }
+ return 0;
+}
+
+static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
+{
+ VideoState *is;
+
+ is = av_mallocz(sizeof(VideoState));
+ if (!is)
+ return NULL;
+ av_strlcpy(is->filename, filename, sizeof(is->filename));
+ is->iformat = iformat;
+ is->ytop = 0;
+ is->xleft = 0;
+
+ /* start video display */
+ is->pictq_mutex = SDL_CreateMutex();
+ is->pictq_cond = SDL_CreateCond();
+
+ is->subpq_mutex = SDL_CreateMutex();
+ is->subpq_cond = SDL_CreateCond();
+
+ is->av_sync_type = av_sync_type;
+ is->parse_tid = SDL_CreateThread(decode_thread, is);
+ if (!is->parse_tid) {
+ av_free(is);
+ return NULL;
+ }
+ return is;
+}
+
+static void stream_cycle_channel(VideoState *is, int codec_type)
+{
+ AVFormatContext *ic = is->ic;
+ int start_index, stream_index;
+ AVStream *st;
+
+ if (codec_type == AVMEDIA_TYPE_VIDEO)
+ start_index = is->video_stream;
+ else if (codec_type == AVMEDIA_TYPE_AUDIO)
+ start_index = is->audio_stream;
+ else
+ start_index = is->subtitle_stream;
+ if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
+ return;
+ stream_index = start_index;
+ for(;;) {
+ if (++stream_index >= is->ic->nb_streams)
+ {
+ if (codec_type == AVMEDIA_TYPE_SUBTITLE)
+ {
+ stream_index = -1;
+ goto the_end;
+ } else
+ stream_index = 0;
+ }
+ if (stream_index == start_index)
+ return;
+ st = ic->streams[stream_index];
+ if (st->codec->codec_type == codec_type) {
+ /* check that parameters are OK */
+ switch(codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ if (st->codec->sample_rate != 0 &&
+ st->codec->channels != 0)
+ goto the_end;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ case AVMEDIA_TYPE_SUBTITLE:
+ goto the_end;
+ default:
+ break;
+ }
+ }
+ }
+ the_end:
+ stream_component_close(is, start_index);
+ stream_component_open(is, stream_index);
+}
+
+
+static void toggle_full_screen(void)
+{
+ is_full_screen = !is_full_screen;
+#if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
+ /* OSX needs to empty the picture_queue */
+ for (int i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
+ cur_stream->pictq[i].reallocate = 1;
+ }
+#endif
+ video_open(cur_stream);
+}
+
+static void toggle_pause(void)
+{
+ if (cur_stream)
+ stream_pause(cur_stream);
+ step = 0;
+}
+
+static void step_to_next_frame(void)
+{
+ if (cur_stream) {
+ /* if the stream is paused unpause it, then step */
+ if (cur_stream->paused)
+ stream_pause(cur_stream);
+ }
+ step = 1;
+}
+
+static void toggle_audio_display(void)
+{
+ if (cur_stream) {
+ int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
+ cur_stream->show_audio = (cur_stream->show_audio + 1) % 3;
+ fill_rectangle(screen,
+ cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height,
+ bgcolor);
+ SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height);
+ }
+}
+
+/* handle an event sent by the GUI */
+static void event_loop(void)
+{
+ SDL_Event event;
+ double incr, pos, frac;
+
+ for(;;) {
+ double x;
+ SDL_WaitEvent(&event);
+ switch(event.type) {
+ case SDL_KEYDOWN:
+ if (exit_on_keydown) {
+ do_exit();
+ break;
+ }
+ switch(event.key.keysym.sym) {
+ case SDLK_ESCAPE:
+ case SDLK_q:
+ do_exit();
+ break;
+ case SDLK_f:
+ toggle_full_screen();
+ break;
+ case SDLK_p:
+ case SDLK_SPACE:
+ toggle_pause();
+ break;
+ case SDLK_s: //S: Step to next frame
+ step_to_next_frame();
+ break;
+ case SDLK_a:
+ if (cur_stream)
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
+ break;
+ case SDLK_v:
+ if (cur_stream)
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
+ break;
+ case SDLK_t:
+ if (cur_stream)
+ stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
+ break;
+ case SDLK_w:
+ toggle_audio_display();
+ break;
+ case SDLK_LEFT:
+ incr = -10.0;
+ goto do_seek;
+ case SDLK_RIGHT:
+ incr = 10.0;
+ goto do_seek;
+ case SDLK_UP:
+ incr = 60.0;
+ goto do_seek;
+ case SDLK_DOWN:
+ incr = -60.0;
+ do_seek:
+ if (cur_stream) {
+ if (seek_by_bytes) {
+ if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){
+ pos= cur_stream->video_current_pos;
+ }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
+ pos= cur_stream->audio_pkt.pos;
+ }else
+ pos = avio_tell(cur_stream->ic->pb);
+ if (cur_stream->ic->bit_rate)
+ incr *= cur_stream->ic->bit_rate / 8.0;
+ else
+ incr *= 180000.0;
+ pos += incr;
+ stream_seek(cur_stream, pos, incr, 1);
+ } else {
+ pos = get_master_clock(cur_stream);
+ pos += incr;
+ stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ if (exit_on_mousedown) {
+ do_exit();
+ break;
+ }
+ case SDL_MOUSEMOTION:
+ if(event.type ==SDL_MOUSEBUTTONDOWN){
+ x= event.button.x;
+ }else{
+ if(event.motion.state != SDL_PRESSED)
+ break;
+ x= event.motion.x;
+ }
+ if (cur_stream) {
+ if(seek_by_bytes || cur_stream->ic->duration<=0){
+ uint64_t size= avio_size(cur_stream->ic->pb);
+ stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
+ }else{
+ int64_t ts;
+ int ns, hh, mm, ss;
+ int tns, thh, tmm, tss;
+ tns = cur_stream->ic->duration/1000000LL;
+ thh = tns/3600;
+ tmm = (tns%3600)/60;
+ tss = (tns%60);
+ frac = x/cur_stream->width;
+ ns = frac*tns;
+ hh = ns/3600;
+ mm = (ns%3600)/60;
+ ss = (ns%60);
+ fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
+ hh, mm, ss, thh, tmm, tss);
+ ts = frac*cur_stream->ic->duration;
+ if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
+ ts += cur_stream->ic->start_time;
+ stream_seek(cur_stream, ts, 0, 0);
+ }
+ }
+ break;
+ case SDL_VIDEORESIZE:
+ if (cur_stream) {
+ screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
+ SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
+ screen_width = cur_stream->width = event.resize.w;
+ screen_height= cur_stream->height= event.resize.h;
+ }
+ break;
+ case SDL_QUIT:
+ case FF_QUIT_EVENT:
+ do_exit();
+ break;
+ case FF_ALLOC_EVENT:
+ video_open(event.user.data1);
+ alloc_picture(event.user.data1);
+ break;
+ case FF_REFRESH_EVENT:
+ video_refresh_timer(event.user.data1);
+ cur_stream->refresh=0;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static int opt_frame_size(const char *opt, const char *arg)
+{
+ av_log(NULL, AV_LOG_ERROR,
+ "Option '%s' has been removed, use private format options instead\n", opt);
+ return AVERROR(EINVAL);
+}
+
+static int opt_width(const char *opt, const char *arg)
+{
+ screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
+ return 0;
+}
+
+static int opt_height(const char *opt, const char *arg)
+{
+ screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
+ return 0;
+}
+
+static int opt_format(const char *opt, const char *arg)
+{
+ file_iformat = av_find_input_format(arg);
+ if (!file_iformat) {
+ fprintf(stderr, "Unknown input format: %s\n", arg);
+ return AVERROR(EINVAL);
+ }
+ return 0;
+}
+
+static int opt_frame_pix_fmt(const char *opt, const char *arg)
+{
+ av_log(NULL, AV_LOG_ERROR,
+ "Option '%s' has been removed, use private format options instead\n", opt);
+ return AVERROR(EINVAL);
+}
+
+static int opt_sync(const char *opt, const char *arg)
+{
+ if (!strcmp(arg, "audio"))
+ av_sync_type = AV_SYNC_AUDIO_MASTER;
+ else if (!strcmp(arg, "video"))
+ av_sync_type = AV_SYNC_VIDEO_MASTER;
+ else if (!strcmp(arg, "ext"))
+ av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
+ else {
+ fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
+ exit(1);
+ }
+ return 0;
+}
+
+static int opt_seek(const char *opt, const char *arg)
+{
+ start_time = parse_time_or_die(opt, arg, 1);
+ return 0;
+}
+
+static int opt_duration(const char *opt, const char *arg)
+{
+ duration = parse_time_or_die(opt, arg, 1);
+ return 0;
+}
+
+static int opt_debug(const char *opt, const char *arg)
+{
+ av_log_set_level(99);
+ debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
+ return 0;
+}
+
+static int opt_vismv(const char *opt, const char *arg)
+{
+ debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
+ return 0;
+}
+
+static int opt_thread_count(const char *opt, const char *arg)
+{
+ thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
+#if !HAVE_THREADS
+ fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
+#endif
+ return 0;
+}
+
+static const OptionDef options[] = {
+#include "cmdutils_common_opts.h"
+ { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
+ { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
+ { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
+ { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
+ { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
+ { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
+ { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_AUDIO]}, "select desired audio stream", "stream_number" },
+ { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_VIDEO]}, "select desired video stream", "stream_number" },
+ { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_SUBTITLE]}, "select desired subtitle stream", "stream_number" },
+ { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
+ { "t", HAS_ARG, {(void*)&opt_duration}, "play \"duration\" seconds of audio/video", "duration" },
+ { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto", "val" },
+ { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
+ { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
+ { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
+ { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
+ { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
+ { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
+ { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
+ { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
+ { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
+ { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
+ { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
+ { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
+ { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
+ { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
+ { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" },
+ { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)", "threshold" },
+ { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" },
+ { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
+ { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
+ { "autoexit", OPT_BOOL | OPT_EXPERT, {(void*)&autoexit}, "exit at the end", "" },
+ { "exitonkeydown", OPT_BOOL | OPT_EXPERT, {(void*)&exit_on_keydown}, "exit on key down", "" },
+ { "exitonmousedown", OPT_BOOL | OPT_EXPERT, {(void*)&exit_on_mousedown}, "exit on mouse down", "" },
+ { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&loop}, "set number of times the playback shall be looped", "loop count" },
+ { "framedrop", OPT_BOOL | OPT_EXPERT, {(void*)&framedrop}, "drop frames when cpu is too slow", "" },
+ { "window_title", OPT_STRING | HAS_ARG, {(void*)&window_title}, "set window title", "window title" },
+#if CONFIG_AVFILTER
+ { "vf", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
+#endif
+ { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, {(void*)&rdftspeed}, "rdft speed", "msecs" },
+ { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
+ { "i", 0, {NULL}, "avconv compatibility dummy option", ""},
+ { NULL, },
+};
+
+static void show_usage(void)
+{
+ printf("Simple media player\n");
+ printf("usage: %s [options] input_file\n", program_name);
+ printf("\n");
+}
+
+static void show_help(void)
+{
+ av_log_set_callback(log_callback_help);
+ show_usage();
+ show_help_options(options, "Main options:\n",
+ OPT_EXPERT, 0);
+ show_help_options(options, "\nAdvanced options:\n",
+ OPT_EXPERT, OPT_EXPERT);
+ printf("\n");
+ show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
+ show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
+#if !CONFIG_AVFILTER
+ show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
+#endif
+ printf("\nWhile playing:\n"
+ "q, ESC quit\n"
+ "f toggle full screen\n"
+ "p, SPC pause\n"
+ "a cycle audio channel\n"
+ "v cycle video channel\n"
+ "t cycle subtitle channel\n"
+ "w show audio waves\n"
+ "s activate frame-step mode\n"
+ "left/right seek backward/forward 10 seconds\n"
+ "down/up seek backward/forward 1 minute\n"
+ "mouse click seek to percentage in file corresponding to fraction of width\n"
+ );
+}
+
+static void opt_input_file(void *optctx, const char *filename)
+{
+ if (input_filename) {
+ fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
+ filename, input_filename);
+ exit(1);
+ }
+ if (!strcmp(filename, "-"))
+ filename = "pipe:";
+ input_filename = filename;
+}
+
+/* Called from the main */
+int main(int argc, char **argv)
+{
+ int flags;
+
+ av_log_set_flags(AV_LOG_SKIP_REPEATED);
+ parse_loglevel(argc, argv, options);
+
+ /* register all codecs, demux and protocols */
+ avcodec_register_all();
+#if CONFIG_AVDEVICE
+ avdevice_register_all();
+#endif
+#if CONFIG_AVFILTER
+ avfilter_register_all();
+#endif
+ av_register_all();
+ avformat_network_init();
+
+ init_opts();
+
+ show_banner();
+
+ parse_options(NULL, argc, argv, options, opt_input_file);
+
+ if (!input_filename) {
+ show_usage();
+ fprintf(stderr, "An input file must be specified\n");
+ fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
+ exit(1);
+ }
+
+ if (display_disable) {
+ video_disable = 1;
+ }
+ flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
+#if !defined(__MINGW32__) && !defined(__APPLE__)
+ flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
+#endif
+ if (SDL_Init (flags)) {
+ fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
+ exit(1);
+ }
+
+ if (!display_disable) {
+#if HAVE_SDL_VIDEO_SIZE
+ const SDL_VideoInfo *vi = SDL_GetVideoInfo();
+ fs_screen_width = vi->current_w;
+ fs_screen_height = vi->current_h;
+#endif
+ }
+
+ SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
+ SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
+ SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
+
+ av_init_packet(&flush_pkt);
+ flush_pkt.data= "FLUSH";
+
+ cur_stream = stream_open(input_filename, file_iformat);
+
+ event_loop();
+
+ /* never returns */
+
+ return 0;
+}
diff --git a/avprobe.c b/avprobe.c
new file mode 100644
index 0000000..de9657b
--- /dev/null
+++ b/avprobe.c
@@ -0,0 +1,423 @@
+/*
+ * avprobe : Simple Media Prober based on the Libav libraries
+ * Copyright (c) 2007-2010 Stefano Sabatini
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "libavformat/avformat.h"
+#include "libavcodec/avcodec.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/dict.h"
+#include "libavdevice/avdevice.h"
+#include "cmdutils.h"
+
+const char program_name[] = "avprobe";
+const int program_birth_year = 2007;
+
+static int do_show_format = 0;
+static int do_show_packets = 0;
+static int do_show_streams = 0;
+
+static int show_value_unit = 0;
+static int use_value_prefix = 0;
+static int use_byte_value_binary_prefix = 0;
+static int use_value_sexagesimal_format = 0;
+
+/* globals */
+static const OptionDef options[];
+
+/* AVprobe context */
+static const char *input_filename;
+static AVInputFormat *iformat = NULL;
+
+static const char *binary_unit_prefixes [] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" };
+static const char *decimal_unit_prefixes[] = { "", "K" , "M" , "G" , "T" , "P" };
+
+static const char *unit_second_str = "s" ;
+static const char *unit_hertz_str = "Hz" ;
+static const char *unit_byte_str = "byte" ;
+static const char *unit_bit_per_second_str = "bit/s";
+
+void exit_program(int ret)
+{
+ exit(ret);
+}
+
+static char *value_string(char *buf, int buf_size, double val, const char *unit)
+{
+ if (unit == unit_second_str && use_value_sexagesimal_format) {
+ double secs;
+ int hours, mins;
+ secs = val;
+ mins = (int)secs / 60;
+ secs = secs - mins * 60;
+ hours = mins / 60;
+ mins %= 60;
+ snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs);
+ } else if (use_value_prefix) {
+ const char *prefix_string;
+ int index;
+
+ if (unit == unit_byte_str && use_byte_value_binary_prefix) {
+ index = (int) (log(val)/log(2)) / 10;
+ index = av_clip(index, 0, FF_ARRAY_ELEMS(binary_unit_prefixes) -1);
+ val /= pow(2, index*10);
+ prefix_string = binary_unit_prefixes[index];
+ } else {
+ index = (int) (log10(val)) / 3;
+ index = av_clip(index, 0, FF_ARRAY_ELEMS(decimal_unit_prefixes) -1);
+ val /= pow(10, index*3);
+ prefix_string = decimal_unit_prefixes[index];
+ }
+
+ snprintf(buf, buf_size, "%.3f %s%s", val, prefix_string, show_value_unit ? unit : "");
+ } else {
+ snprintf(buf, buf_size, "%f %s", val, show_value_unit ? unit : "");
+ }
+
+ return buf;
+}
+
+static char *time_value_string(char *buf, int buf_size, int64_t val, const AVRational *time_base)
+{
+ if (val == AV_NOPTS_VALUE) {
+ snprintf(buf, buf_size, "N/A");
+ } else {
+ value_string(buf, buf_size, val * av_q2d(*time_base), unit_second_str);
+ }
+
+ return buf;
+}
+
+static char *ts_value_string (char *buf, int buf_size, int64_t ts)
+{
+ if (ts == AV_NOPTS_VALUE) {
+ snprintf(buf, buf_size, "N/A");
+ } else {
+ snprintf(buf, buf_size, "%"PRId64, ts);
+ }
+
+ return buf;
+}
+
+static const char *media_type_string(enum AVMediaType media_type)
+{
+ switch (media_type) {
+ case AVMEDIA_TYPE_VIDEO: return "video";
+ case AVMEDIA_TYPE_AUDIO: return "audio";
+ case AVMEDIA_TYPE_DATA: return "data";
+ case AVMEDIA_TYPE_SUBTITLE: return "subtitle";
+ case AVMEDIA_TYPE_ATTACHMENT: return "attachment";
+ default: return "unknown";
+ }
+}
+
+static void show_packet(AVFormatContext *fmt_ctx, AVPacket *pkt)
+{
+ char val_str[128];
+ AVStream *st = fmt_ctx->streams[pkt->stream_index];
+
+ printf("[PACKET]\n");
+ printf("codec_type=%s\n" , media_type_string(st->codec->codec_type));
+ printf("stream_index=%d\n" , pkt->stream_index);
+ printf("pts=%s\n" , ts_value_string (val_str, sizeof(val_str), pkt->pts));
+ printf("pts_time=%s\n" , time_value_string(val_str, sizeof(val_str), pkt->pts, &st->time_base));
+ printf("dts=%s\n" , ts_value_string (val_str, sizeof(val_str), pkt->dts));
+ printf("dts_time=%s\n" , time_value_string(val_str, sizeof(val_str), pkt->dts, &st->time_base));
+ printf("duration=%s\n" , ts_value_string (val_str, sizeof(val_str), pkt->duration));
+ printf("duration_time=%s\n", time_value_string(val_str, sizeof(val_str), pkt->duration, &st->time_base));
+ printf("size=%s\n" , value_string (val_str, sizeof(val_str), pkt->size, unit_byte_str));
+ printf("pos=%"PRId64"\n" , pkt->pos);
+ printf("flags=%c\n" , pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_');
+ printf("[/PACKET]\n");
+}
+
+static void show_packets(AVFormatContext *fmt_ctx)
+{
+ AVPacket pkt;
+
+ av_init_packet(&pkt);
+
+ while (!av_read_frame(fmt_ctx, &pkt))
+ show_packet(fmt_ctx, &pkt);
+}
+
+static void show_stream(AVFormatContext *fmt_ctx, int stream_idx)
+{
+ AVStream *stream = fmt_ctx->streams[stream_idx];
+ AVCodecContext *dec_ctx;
+ AVCodec *dec;
+ char val_str[128];
+ AVDictionaryEntry *tag = NULL;
+ AVRational display_aspect_ratio;
+
+ printf("[STREAM]\n");
+
+ printf("index=%d\n", stream->index);
+
+ if ((dec_ctx = stream->codec)) {
+ if ((dec = dec_ctx->codec)) {
+ printf("codec_name=%s\n", dec->name);
+ printf("codec_long_name=%s\n", dec->long_name);
+ } else {
+ printf("codec_name=unknown\n");
+ }
+
+ printf("codec_type=%s\n", media_type_string(dec_ctx->codec_type));
+ printf("codec_time_base=%d/%d\n", dec_ctx->time_base.num, dec_ctx->time_base.den);
+
+ /* print AVI/FourCC tag */
+ av_get_codec_tag_string(val_str, sizeof(val_str), dec_ctx->codec_tag);
+ printf("codec_tag_string=%s\n", val_str);
+ printf("codec_tag=0x%04x\n", dec_ctx->codec_tag);
+
+ switch (dec_ctx->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ printf("width=%d\n", dec_ctx->width);
+ printf("height=%d\n", dec_ctx->height);
+ printf("has_b_frames=%d\n", dec_ctx->has_b_frames);
+ if (dec_ctx->sample_aspect_ratio.num) {
+ printf("sample_aspect_ratio=%d:%d\n", dec_ctx->sample_aspect_ratio.num,
+ dec_ctx->sample_aspect_ratio.den);
+ av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
+ dec_ctx->width * dec_ctx->sample_aspect_ratio.num,
+ dec_ctx->height * dec_ctx->sample_aspect_ratio.den,
+ 1024*1024);
+ printf("display_aspect_ratio=%d:%d\n", display_aspect_ratio.num,
+ display_aspect_ratio.den);
+ }
+ printf("pix_fmt=%s\n", dec_ctx->pix_fmt != PIX_FMT_NONE ?
+ av_pix_fmt_descriptors[dec_ctx->pix_fmt].name : "unknown");
+ printf("level=%d\n", dec_ctx->level);
+ break;
+
+ case AVMEDIA_TYPE_AUDIO:
+ printf("sample_rate=%s\n", value_string(val_str, sizeof(val_str),
+ dec_ctx->sample_rate,
+ unit_hertz_str));
+ printf("channels=%d\n", dec_ctx->channels);
+ printf("bits_per_sample=%d\n", av_get_bits_per_sample(dec_ctx->codec_id));
+ break;
+ }
+ } else {
+ printf("codec_type=unknown\n");
+ }
+
+ if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS)
+ printf("id=0x%x\n", stream->id);
+ printf("r_frame_rate=%d/%d\n", stream->r_frame_rate.num, stream->r_frame_rate.den);
+ printf("avg_frame_rate=%d/%d\n", stream->avg_frame_rate.num, stream->avg_frame_rate.den);
+ printf("time_base=%d/%d\n", stream->time_base.num, stream->time_base.den);
+ printf("start_time=%s\n", time_value_string(val_str, sizeof(val_str), stream->start_time,
+ &stream->time_base));
+ printf("duration=%s\n", time_value_string(val_str, sizeof(val_str), stream->duration,
+ &stream->time_base));
+ if (stream->nb_frames)
+ printf("nb_frames=%"PRId64"\n", stream->nb_frames);
+
+ while ((tag = av_dict_get(stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
+ printf("TAG:%s=%s\n", tag->key, tag->value);
+
+ printf("[/STREAM]\n");
+}
+
+static void show_format(AVFormatContext *fmt_ctx)
+{
+ AVDictionaryEntry *tag = NULL;
+ char val_str[128];
+
+ printf("[FORMAT]\n");
+
+ printf("filename=%s\n", fmt_ctx->filename);
+ printf("nb_streams=%d\n", fmt_ctx->nb_streams);
+ printf("format_name=%s\n", fmt_ctx->iformat->name);
+ printf("format_long_name=%s\n", fmt_ctx->iformat->long_name);
+ printf("start_time=%s\n", time_value_string(val_str, sizeof(val_str), fmt_ctx->start_time,
+ &AV_TIME_BASE_Q));
+ printf("duration=%s\n", time_value_string(val_str, sizeof(val_str), fmt_ctx->duration,
+ &AV_TIME_BASE_Q));
+ printf("size=%s\n", value_string(val_str, sizeof(val_str), fmt_ctx->file_size,
+ unit_byte_str));
+ printf("bit_rate=%s\n", value_string(val_str, sizeof(val_str), fmt_ctx->bit_rate,
+ unit_bit_per_second_str));
+
+ while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
+ printf("TAG:%s=%s\n", tag->key, tag->value);
+
+ printf("[/FORMAT]\n");
+}
+
+static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
+{
+ int err, i;
+ AVFormatContext *fmt_ctx = NULL;
+ AVDictionaryEntry *t;
+
+ if ((err = avformat_open_input(&fmt_ctx, filename, iformat, &format_opts)) < 0) {
+ print_error(filename, err);
+ return err;
+ }
+ if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+ av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
+ return AVERROR_OPTION_NOT_FOUND;
+ }
+
+
+ /* fill the streams in the format context */
+ if ((err = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
+ print_error(filename, err);
+ return err;
+ }
+
+ av_dump_format(fmt_ctx, 0, filename, 0);
+
+ /* bind a decoder to each input stream */
+ for (i = 0; i < fmt_ctx->nb_streams; i++) {
+ AVStream *stream = fmt_ctx->streams[i];
+ AVCodec *codec;
+
+ if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
+ fprintf(stderr, "Unsupported codec with id %d for input stream %d\n",
+ stream->codec->codec_id, stream->index);
+ } else if (avcodec_open2(stream->codec, codec, NULL) < 0) {
+ fprintf(stderr, "Error while opening codec for input stream %d\n",
+ stream->index);
+ }
+ }
+
+ *fmt_ctx_ptr = fmt_ctx;
+ return 0;
+}
+
+static int probe_file(const char *filename)
+{
+ AVFormatContext *fmt_ctx;
+ int ret, i;
+
+ if ((ret = open_input_file(&fmt_ctx, filename)))
+ return ret;
+
+ if (do_show_packets)
+ show_packets(fmt_ctx);
+
+ if (do_show_streams)
+ for (i = 0; i < fmt_ctx->nb_streams; i++)
+ show_stream(fmt_ctx, i);
+
+ if (do_show_format)
+ show_format(fmt_ctx);
+
+ avformat_close_input(&fmt_ctx);
+ return 0;
+}
+
+static void show_usage(void)
+{
+ printf("Simple multimedia streams analyzer\n");
+ printf("usage: %s [OPTIONS] [INPUT_FILE]\n", program_name);
+ printf("\n");
+}
+
+static int opt_format(const char *opt, const char *arg)
+{
+ iformat = av_find_input_format(arg);
+ if (!iformat) {
+ fprintf(stderr, "Unknown input format: %s\n", arg);
+ return AVERROR(EINVAL);
+ }
+ return 0;
+}
+
+static void opt_input_file(void *optctx, const char *arg)
+{
+ if (input_filename) {
+ fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
+ arg, input_filename);
+ exit(1);
+ }
+ if (!strcmp(arg, "-"))
+ arg = "pipe:";
+ input_filename = arg;
+}
+
+static void show_help(void)
+{
+ av_log_set_callback(log_callback_help);
+ show_usage();
+ show_help_options(options, "Main options:\n", 0, 0);
+ printf("\n");
+ show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
+}
+
+static void opt_pretty(void)
+{
+ show_value_unit = 1;
+ use_value_prefix = 1;
+ use_byte_value_binary_prefix = 1;
+ use_value_sexagesimal_format = 1;
+}
+
+static const OptionDef options[] = {
+#include "cmdutils_common_opts.h"
+ { "f", HAS_ARG, {(void*)opt_format}, "force format", "format" },
+ { "unit", OPT_BOOL, {(void*)&show_value_unit}, "show unit of the displayed values" },
+ { "prefix", OPT_BOOL, {(void*)&use_value_prefix}, "use SI prefixes for the displayed values" },
+ { "byte_binary_prefix", OPT_BOOL, {(void*)&use_byte_value_binary_prefix},
+ "use binary prefixes for byte units" },
+ { "sexagesimal", OPT_BOOL, {(void*)&use_value_sexagesimal_format},
+ "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
+ { "pretty", 0, {(void*)&opt_pretty},
+ "prettify the format of displayed values, make it more human readable" },
+ { "show_format", OPT_BOOL, {(void*)&do_show_format} , "show format/container info" },
+ { "show_packets", OPT_BOOL, {(void*)&do_show_packets}, "show packets info" },
+ { "show_streams", OPT_BOOL, {(void*)&do_show_streams}, "show streams info" },
+ { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
+ { NULL, },
+};
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ parse_loglevel(argc, argv, options);
+ av_register_all();
+ avformat_network_init();
+ init_opts();
+#if CONFIG_AVDEVICE
+ avdevice_register_all();
+#endif
+
+ show_banner();
+ parse_options(NULL, argc, argv, options, opt_input_file);
+
+ if (!input_filename) {
+ show_usage();
+ fprintf(stderr, "You have to specify one input file.\n");
+ fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'.\n", program_name);
+ exit(1);
+ }
+
+ ret = probe_file(input_filename);
+
+ avformat_network_deinit();
+
+ return ret;
+}
diff --git a/avserver.c b/avserver.c
new file mode 100644
index 0000000..9016d1f
--- /dev/null
+++ b/avserver.c
@@ -0,0 +1,4748 @@
+/*
+ * Multiple format streaming server
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#if !HAVE_CLOSESOCKET
+#define closesocket close
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include "libavformat/avformat.h"
+#include "libavformat/ffm.h"
+#include "libavformat/network.h"
+#include "libavformat/os_support.h"
+#include "libavformat/rtpdec.h"
+#include "libavformat/rtsp.h"
+// XXX for ffio_open_dyn_packet_buffer, to be removed
+#include "libavformat/avio_internal.h"
+#include "libavutil/avstring.h"
+#include "libavutil/lfg.h"
+#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/random_seed.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/opt.h"
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#if HAVE_POLL_H
+#include <poll.h>
+#endif
+#include <errno.h>
+#include <sys/time.h>
+#include <time.h>
+#include <sys/wait.h>
+#include <signal.h>
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include "cmdutils.h"
+
+const char program_name[] = "avserver";
+const int program_birth_year = 2000;
+
+static const OptionDef options[];
+
+enum HTTPState {
+ HTTPSTATE_WAIT_REQUEST,
+ HTTPSTATE_SEND_HEADER,
+ HTTPSTATE_SEND_DATA_HEADER,
+ HTTPSTATE_SEND_DATA, /* sending TCP or UDP data */
+ HTTPSTATE_SEND_DATA_TRAILER,
+ HTTPSTATE_RECEIVE_DATA,
+ HTTPSTATE_WAIT_FEED, /* wait for data from the feed */
+ HTTPSTATE_READY,
+
+ RTSPSTATE_WAIT_REQUEST,
+ RTSPSTATE_SEND_REPLY,
+ RTSPSTATE_SEND_PACKET,
+};
+
+static const char *http_state[] = {
+ "HTTP_WAIT_REQUEST",
+ "HTTP_SEND_HEADER",
+
+ "SEND_DATA_HEADER",
+ "SEND_DATA",
+ "SEND_DATA_TRAILER",
+ "RECEIVE_DATA",
+ "WAIT_FEED",
+ "READY",
+
+ "RTSP_WAIT_REQUEST",
+ "RTSP_SEND_REPLY",
+ "RTSP_SEND_PACKET",
+};
+
+#define MAX_STREAMS 20
+
+#define IOBUFFER_INIT_SIZE 8192
+
+/* timeouts are in ms */
+#define HTTP_REQUEST_TIMEOUT (15 * 1000)
+#define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000)
+
+#define SYNC_TIMEOUT (10 * 1000)
+
+typedef struct RTSPActionServerSetup {
+ uint32_t ipaddr;
+ char transport_option[512];
+} RTSPActionServerSetup;
+
+typedef struct {
+ int64_t count1, count2;
+ int64_t time1, time2;
+} DataRateData;
+
+/* context associated with one connection */
+typedef struct HTTPContext {
+ enum HTTPState state;
+ int fd; /* socket file descriptor */
+ struct sockaddr_in from_addr; /* origin */
+ struct pollfd *poll_entry; /* used when polling */
+ int64_t timeout;
+ uint8_t *buffer_ptr, *buffer_end;
+ int http_error;
+ int post;
+ int chunked_encoding;
+ int chunk_size; /* 0 if it needs to be read */
+ struct HTTPContext *next;
+ int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
+ int64_t data_count;
+ /* feed input */
+ int feed_fd;
+ /* input format handling */
+ AVFormatContext *fmt_in;
+ int64_t start_time; /* In milliseconds - this wraps fairly often */
+ int64_t first_pts; /* initial pts value */
+ int64_t cur_pts; /* current pts value from the stream in us */
+ int64_t cur_frame_duration; /* duration of the current frame in us */
+ int cur_frame_bytes; /* output frame size, needed to compute
+ the time at which we send each
+ packet */
+ int pts_stream_index; /* stream we choose as clock reference */
+ int64_t cur_clock; /* current clock reference value in us */
+ /* output format handling */
+ struct FFStream *stream;
+ /* -1 is invalid stream */
+ int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
+ int switch_feed_streams[MAX_STREAMS]; /* index of streams in the feed */
+ int switch_pending;
+ AVFormatContext fmt_ctx; /* instance of FFStream for one user */
+ int last_packet_sent; /* true if last data packet was sent */
+ int suppress_log;
+ DataRateData datarate;
+ int wmp_client_id;
+ char protocol[16];
+ char method[16];
+ char url[128];
+ int buffer_size;
+ uint8_t *buffer;
+ int is_packetized; /* if true, the stream is packetized */
+ int packet_stream_index; /* current stream for output in state machine */
+
+ /* RTSP state specific */
+ uint8_t *pb_buffer; /* XXX: use that in all the code */
+ AVIOContext *pb;
+ int seq; /* RTSP sequence number */
+
+ /* RTP state specific */
+ enum RTSPLowerTransport rtp_protocol;
+ char session_id[32]; /* session id */
+ AVFormatContext *rtp_ctx[MAX_STREAMS];
+
+ /* RTP/UDP specific */
+ URLContext *rtp_handles[MAX_STREAMS];
+
+ /* RTP/TCP specific */
+ struct HTTPContext *rtsp_c;
+ uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
+} HTTPContext;
+
+/* each generated stream is described here */
+enum StreamType {
+ STREAM_TYPE_LIVE,
+ STREAM_TYPE_STATUS,
+ STREAM_TYPE_REDIRECT,
+};
+
+enum IPAddressAction {
+ IP_ALLOW = 1,
+ IP_DENY,
+};
+
+typedef struct IPAddressACL {
+ struct IPAddressACL *next;
+ enum IPAddressAction action;
+ /* These are in host order */
+ struct in_addr first;
+ struct in_addr last;
+} IPAddressACL;
+
+/* description of each stream of the avserver.conf file */
+typedef struct FFStream {
+ enum StreamType stream_type;
+ char filename[1024]; /* stream filename */
+ struct FFStream *feed; /* feed we are using (can be null if
+ coming from file) */
+ AVDictionary *in_opts; /* input parameters */
+ AVInputFormat *ifmt; /* if non NULL, force input format */
+ AVOutputFormat *fmt;
+ IPAddressACL *acl;
+ char dynamic_acl[1024];
+ int nb_streams;
+ int prebuffer; /* Number of millseconds early to start */
+ int64_t max_time; /* Number of milliseconds to run */
+ int send_on_key;
+ AVStream *streams[MAX_STREAMS];
+ int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
+ char feed_filename[1024]; /* file name of the feed storage, or
+ input file name for a stream */
+ char author[512];
+ char title[512];
+ char copyright[512];
+ char comment[512];
+ pid_t pid; /* of avconv process */
+ time_t pid_start; /* of avconv process */
+ char **child_argv;
+ struct FFStream *next;
+ unsigned bandwidth; /* bandwidth, in kbits/s */
+ /* RTSP options */
+ char *rtsp_option;
+ /* multicast specific */
+ int is_multicast;
+ struct in_addr multicast_ip;
+ int multicast_port; /* first port used for multicast */
+ int multicast_ttl;
+ int loop; /* if true, send the stream in loops (only meaningful if file) */
+
+ /* feed specific */
+ int feed_opened; /* true if someone is writing to the feed */
+ int is_feed; /* true if it is a feed */
+ int readonly; /* True if writing is prohibited to the file */
+ int truncate; /* True if feeder connection truncate the feed file */
+ int conns_served;
+ int64_t bytes_served;
+ int64_t feed_max_size; /* maximum storage size, zero means unlimited */
+ int64_t feed_write_index; /* current write position in feed (it wraps around) */
+ int64_t feed_size; /* current size of feed */
+ struct FFStream *next_feed;
+} FFStream;
+
+typedef struct FeedData {
+ long long data_count;
+ float avg_frame_size; /* frame size averaged over last frames with exponential mean */
+} FeedData;
+
+static struct sockaddr_in my_http_addr;
+static struct sockaddr_in my_rtsp_addr;
+
+static char logfilename[1024];
+static HTTPContext *first_http_ctx;
+static FFStream *first_feed; /* contains only feeds */
+static FFStream *first_stream; /* contains all streams, including feeds */
+
+static void new_connection(int server_fd, int is_rtsp);
+static void close_connection(HTTPContext *c);
+
+/* HTTP handling */
+static int handle_connection(HTTPContext *c);
+static int http_parse_request(HTTPContext *c);
+static int http_send_data(HTTPContext *c);
+static void compute_status(HTTPContext *c);
+static int open_input_stream(HTTPContext *c, const char *info);
+static int http_start_receive_data(HTTPContext *c);
+static int http_receive_data(HTTPContext *c);
+
+/* RTSP handling */
+static int rtsp_parse_request(HTTPContext *c);
+static void rtsp_cmd_describe(HTTPContext *c, const char *url);
+static void rtsp_cmd_options(HTTPContext *c, const char *url);
+static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPMessageHeader *h);
+static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h);
+static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h);
+static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h);
+
+/* SDP handling */
+static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
+ struct in_addr my_ip);
+
+/* RTP handling */
+static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
+ FFStream *stream, const char *session_id,
+ enum RTSPLowerTransport rtp_protocol);
+static int rtp_new_av_stream(HTTPContext *c,
+ int stream_index, struct sockaddr_in *dest_addr,
+ HTTPContext *rtsp_c);
+
+static const char *my_program_name;
+static const char *my_program_dir;
+
+static const char *config_filename = "/etc/avserver.conf";
+
+static int avserver_debug;
+static int avserver_daemon;
+static int no_launch;
+static int need_to_start_children;
+
+/* maximum number of simultaneous HTTP connections */
+static unsigned int nb_max_http_connections = 2000;
+static unsigned int nb_max_connections = 5;
+static unsigned int nb_connections;
+
+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
+
+static AVLFG random_state;
+
+static FILE *logfile = NULL;
+
+void exit_program(int ret)
+{
+ exit(ret);
+}
+
+/* FIXME: make avserver work with IPv6 */
+/* resolve host with also IP address parsing */
+static int resolve_host(struct in_addr *sin_addr, const char *hostname)
+{
+
+ if (!ff_inet_aton(hostname, sin_addr)) {
+#if HAVE_GETADDRINFO
+ struct addrinfo *ai, *cur;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ if (getaddrinfo(hostname, NULL, &hints, &ai))
+ return -1;
+ /* getaddrinfo returns a linked list of addrinfo structs.
+ * Even if we set ai_family = AF_INET above, make sure
+ * that the returned one actually is of the correct type. */
+ for (cur = ai; cur; cur = cur->ai_next) {
+ if (cur->ai_family == AF_INET) {
+ *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr;
+ freeaddrinfo(ai);
+ return 0;
+ }
+ }
+ freeaddrinfo(ai);
+ return -1;
+#else
+ struct hostent *hp;
+ hp = gethostbyname(hostname);
+ if (!hp)
+ return -1;
+ memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
+#endif
+ }
+ return 0;
+}
+
+static char *ctime1(char *buf2)
+{
+ time_t ti;
+ char *p;
+
+ ti = time(NULL);
+ p = ctime(&ti);
+ strcpy(buf2, p);
+ p = buf2 + strlen(p) - 1;
+ if (*p == '\n')
+ *p = '\0';
+ return buf2;
+}
+
+static void http_vlog(const char *fmt, va_list vargs)
+{
+ 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);
+ }
+}
+
+#ifdef __GNUC__
+__attribute__ ((format (printf, 1, 2)))
+#endif
+static void 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_get_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\" %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);
+}
+
+static void update_datarate(DataRateData *drd, int64_t count)
+{
+ if (!drd->time1 && !drd->count1) {
+ drd->time1 = drd->time2 = cur_time;
+ drd->count1 = drd->count2 = count;
+ } else if (cur_time - drd->time2 > 5000) {
+ drd->time1 = drd->time2;
+ drd->count1 = drd->count2;
+ drd->time2 = cur_time;
+ drd->count2 = count;
+ }
+}
+
+/* In bytes per second */
+static int compute_datarate(DataRateData *drd, int64_t count)
+{
+ if (cur_time == drd->time1)
+ return 0;
+
+ return ((count - drd->count1) * 1000) / (cur_time - drd->time1);
+}
+
+
+static void start_children(FFStream *feed)
+{
+ if (no_launch)
+ return;
+
+ for (; feed; feed = feed->next) {
+ if (feed->child_argv && !feed->pid) {
+ feed->pid_start = time(0);
+
+ feed->pid = fork();
+
+ if (feed->pid < 0) {
+ http_log("Unable to create children\n");
+ exit(1);
+ }
+ if (!feed->pid) {
+ /* In child */
+ char pathname[1024];
+ char *slash;
+ int i;
+
+ av_strlcpy(pathname, my_program_name, sizeof(pathname));
+
+ slash = strrchr(pathname, '/');
+ if (!slash)
+ slash = pathname;
+ else
+ slash++;
+ strcpy(slash, "avconv");
+
+ http_log("Launch command line: ");
+ 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 (!avserver_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);
+
+ signal(SIGPIPE, SIG_DFL);
+
+ execvp(pathname, feed->child_argv);
+
+ _exit(1);
+ }
+ }
+ }
+}
+
+/* open a listening socket */
+static int socket_open_listen(struct sockaddr_in *my_addr)
+{
+ int server_fd, tmp;
+
+ server_fd = socket(AF_INET,SOCK_STREAM,0);
+ if (server_fd < 0) {
+ perror ("socket");
+ return -1;
+ }
+
+ tmp = 1;
+ setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
+
+ my_addr->sin_family = AF_INET;
+ if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) {
+ char bindmsg[32];
+ snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port));
+ perror (bindmsg);
+ closesocket(server_fd);
+ return -1;
+ }
+
+ if (listen (server_fd, 5) < 0) {
+ perror ("listen");
+ closesocket(server_fd);
+ return -1;
+ }
+ ff_socket_nonblock(server_fd, 1);
+
+ return server_fd;
+}
+
+/* start all multicast streams */
+static void start_multicast(void)
+{
+ FFStream *stream;
+ char session_id[32];
+ HTTPContext *rtp_c;
+ struct sockaddr_in dest_addr;
+ int default_port, stream_index;
+
+ default_port = 6000;
+ for(stream = first_stream; stream != NULL; stream = stream->next) {
+ if (stream->is_multicast) {
+ /* open the RTP connection */
+ snprintf(session_id, sizeof(session_id), "%08x%08x",
+ av_lfg_get(&random_state), av_lfg_get(&random_state));
+
+ /* choose a port if none given */
+ if (stream->multicast_port == 0) {
+ stream->multicast_port = default_port;
+ default_port += 100;
+ }
+
+ dest_addr.sin_family = AF_INET;
+ dest_addr.sin_addr = stream->multicast_ip;
+ dest_addr.sin_port = htons(stream->multicast_port);
+
+ rtp_c = rtp_new_connection(&dest_addr, stream, session_id,
+ RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
+ if (!rtp_c)
+ continue;
+
+ if (open_input_stream(rtp_c, "") < 0) {
+ http_log("Could not open input stream for stream '%s'\n",
+ stream->filename);
+ continue;
+ }
+
+ /* open each RTP stream */
+ for(stream_index = 0; stream_index < stream->nb_streams;
+ stream_index++) {
+ dest_addr.sin_port = htons(stream->multicast_port +
+ 2 * stream_index);
+ if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, NULL) < 0) {
+ http_log("Could not open output stream '%s/streamid=%d'\n",
+ stream->filename, stream_index);
+ exit(1);
+ }
+ }
+
+ /* change state to send data */
+ rtp_c->state = HTTPSTATE_SEND_DATA;
+ }
+ }
+}
+
+/* main loop of the http server */
+static int http_server(void)
+{
+ int server_fd = 0, rtsp_server_fd = 0;
+ int ret, delay, delay1;
+ struct pollfd *poll_table, *poll_entry;
+ HTTPContext *c, *c_next;
+
+ if(!(poll_table = av_mallocz((nb_max_http_connections + 2)*sizeof(*poll_table)))) {
+ http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections);
+ 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;
+ }
+
+ if (!rtsp_server_fd && !server_fd) {
+ http_log("HTTP and RTSP disabled.\n");
+ return -1;
+ }
+
+ http_log("AVserver started.\n");
+
+ start_children(first_feed);
+
+ start_multicast();
+
+ for(;;) {
+ poll_entry = poll_table;
+ 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;
+ delay = 1000;
+ while (c != NULL) {
+ int fd;
+ fd = c->fd;
+ switch(c->state) {
+ case HTTPSTATE_SEND_HEADER:
+ case RTSPSTATE_SEND_REPLY:
+ case RTSPSTATE_SEND_PACKET:
+ c->poll_entry = poll_entry;
+ poll_entry->fd = fd;
+ poll_entry->events = POLLOUT;
+ poll_entry++;
+ break;
+ case HTTPSTATE_SEND_DATA_HEADER:
+ case HTTPSTATE_SEND_DATA:
+ case HTTPSTATE_SEND_DATA_TRAILER:
+ if (!c->is_packetized) {
+ /* for TCP, we output as much as we can (may need to put a limit) */
+ c->poll_entry = poll_entry;
+ poll_entry->fd = fd;
+ poll_entry->events = POLLOUT;
+ poll_entry++;
+ } else {
+ /* when avserver is doing the timing, we work by
+ looking at which packet need to be sent every
+ 10 ms */
+ delay1 = 10; /* one tick wait XXX: 10 ms assumed */
+ if (delay1 < delay)
+ delay = delay1;
+ }
+ break;
+ case HTTPSTATE_WAIT_REQUEST:
+ case HTTPSTATE_RECEIVE_DATA:
+ case HTTPSTATE_WAIT_FEED:
+ case RTSPSTATE_WAIT_REQUEST:
+ /* need to catch errors */
+ c->poll_entry = poll_entry;
+ poll_entry->fd = fd;
+ poll_entry->events = POLLIN;/* Maybe this will work */
+ poll_entry++;
+ break;
+ default:
+ c->poll_entry = NULL;
+ break;
+ }
+ c = c->next;
+ }
+
+ /* wait for an event on one connection. We poll at least every
+ second to handle timeouts */
+ do {
+ ret = poll(poll_table, poll_entry - poll_table, delay);
+ if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR))
+ return -1;
+ } while (ret < 0);
+
+ cur_time = av_gettime() / 1000;
+
+ if (need_to_start_children) {
+ need_to_start_children = 0;
+ start_children(first_feed);
+ }
+
+ /* now handle the events */
+ for(c = first_http_ctx; c != NULL; c = c_next) {
+ c_next = c->next;
+ if (handle_connection(c) < 0) {
+ /* close and free the connection */
+ log_connection(c);
+ close_connection(c);
+ }
+ }
+
+ poll_entry = poll_table;
+ 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);
+ }
+ }
+}
+
+/* start waiting for a new HTTP/RTSP request */
+static void start_wait_request(HTTPContext *c, int is_rtsp)
+{
+ c->buffer_ptr = c->buffer;
+ c->buffer_end = c->buffer + c->buffer_size - 1; /* leave room for '\0' */
+
+ if (is_rtsp) {
+ c->timeout = cur_time + RTSP_REQUEST_TIMEOUT;
+ c->state = RTSPSTATE_WAIT_REQUEST;
+ } else {
+ c->timeout = cur_time + HTTP_REQUEST_TIMEOUT;
+ c->state = HTTPSTATE_WAIT_REQUEST;
+ }
+}
+
+static void http_send_too_busy_reply(int fd)
+{
+ char buffer[300];
+ int len = snprintf(buffer, sizeof(buffer),
+ "HTTP/1.0 503 Server too busy\r\n"
+ "Content-type: text/html\r\n"
+ "\r\n"
+ "<html><head><title>Too busy</title></head><body>\r\n"
+ "<p>The server is too busy to serve your request at this time.</p>\r\n"
+ "<p>The number of current connections is %d, and this exceeds the limit of %d.</p>\r\n"
+ "</body></html>\r\n",
+ nb_connections, nb_max_connections);
+ send(fd, buffer, len, 0);
+}
+
+
+static void new_connection(int server_fd, int is_rtsp)
+{
+ struct sockaddr_in from_addr;
+ int fd, len;
+ HTTPContext *c = NULL;
+
+ len = sizeof(from_addr);
+ fd = accept(server_fd, (struct sockaddr *)&from_addr,
+ &len);
+ if (fd < 0) {
+ http_log("error during accept %s\n", strerror(errno));
+ return;
+ }
+ ff_socket_nonblock(fd, 1);
+
+ if (nb_connections >= nb_max_connections) {
+ http_send_too_busy_reply(fd);
+ goto fail;
+ }
+
+ /* add a new connection */
+ c = av_mallocz(sizeof(HTTPContext));
+ if (!c)
+ goto fail;
+
+ c->fd = fd;
+ c->poll_entry = NULL;
+ c->from_addr = from_addr;
+ c->buffer_size = IOBUFFER_INIT_SIZE;
+ c->buffer = av_malloc(c->buffer_size);
+ if (!c->buffer)
+ goto fail;
+
+ c->next = first_http_ctx;
+ first_http_ctx = c;
+ nb_connections++;
+
+ start_wait_request(c, is_rtsp);
+
+ return;
+
+ fail:
+ if (c) {
+ av_free(c->buffer);
+ av_free(c);
+ }
+ closesocket(fd);
+}
+
+static void close_connection(HTTPContext *c)
+{
+ HTTPContext **cp, *c1;
+ int i, nb_streams;
+ AVFormatContext *ctx;
+ URLContext *h;
+ AVStream *st;
+
+ /* remove connection from list */
+ cp = &first_http_ctx;
+ while ((*cp) != NULL) {
+ c1 = *cp;
+ if (c1 == c)
+ *cp = c->next;
+ else
+ cp = &c1->next;
+ }
+
+ /* remove references, if any (XXX: do it faster) */
+ for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
+ if (c1->rtsp_c == c)
+ c1->rtsp_c = NULL;
+ }
+
+ /* remove connection associated resources */
+ if (c->fd >= 0)
+ closesocket(c->fd);
+ if (c->fmt_in) {
+ /* close each frame parser */
+ for(i=0;i<c->fmt_in->nb_streams;i++) {
+ st = c->fmt_in->streams[i];
+ if (st->codec->codec)
+ avcodec_close(st->codec);
+ }
+ avformat_close_input(&c->fmt_in);
+ }
+
+ /* free RTP output streams if any */
+ nb_streams = 0;
+ if (c->stream)
+ nb_streams = c->stream->nb_streams;
+
+ for(i=0;i<nb_streams;i++) {
+ ctx = c->rtp_ctx[i];
+ if (ctx) {
+ av_write_trailer(ctx);
+ av_dict_free(&ctx->metadata);
+ av_free(ctx->streams[0]);
+ av_free(ctx);
+ }
+ h = c->rtp_handles[i];
+ if (h)
+ url_close(h);
+ }
+
+ ctx = &c->fmt_ctx;
+
+ if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
+ if (ctx->oformat) {
+ /* prepare header */
+ if (avio_open_dyn_buf(&ctx->pb) >= 0) {
+ av_write_trailer(ctx);
+ av_freep(&c->pb_buffer);
+ avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
+ }
+ }
+ }
+
+ for(i=0; i<ctx->nb_streams; i++)
+ av_free(ctx->streams[i]);
+
+ if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
+ current_bandwidth -= c->stream->bandwidth;
+
+ /* signal that there is no feed if we are the feeder socket */
+ if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
+ c->stream->feed_opened = 0;
+ close(c->feed_fd);
+ }
+
+ av_freep(&c->pb_buffer);
+ av_freep(&c->packet_buffer);
+ av_free(c->buffer);
+ av_free(c);
+ nb_connections--;
+}
+
+static int handle_connection(HTTPContext *c)
+{
+ int len, ret;
+
+ switch(c->state) {
+ case HTTPSTATE_WAIT_REQUEST:
+ case RTSPSTATE_WAIT_REQUEST:
+ /* timeout ? */
+ if ((c->timeout - cur_time) < 0)
+ return -1;
+ if (c->poll_entry->revents & (POLLERR | POLLHUP))
+ return -1;
+
+ /* no need to read if no events */
+ if (!(c->poll_entry->revents & POLLIN))
+ return 0;
+ /* read the data */
+ read_loop:
+ len = recv(c->fd, c->buffer_ptr, 1, 0);
+ if (len < 0) {
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR))
+ return -1;
+ } else if (len == 0) {
+ return -1;
+ } else {
+ /* search for end of request. */
+ uint8_t *ptr;
+ c->buffer_ptr += len;
+ ptr = c->buffer_ptr;
+ if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
+ (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
+ /* request found : parse it and reply */
+ if (c->state == HTTPSTATE_WAIT_REQUEST) {
+ ret = http_parse_request(c);
+ } else {
+ ret = rtsp_parse_request(c);
+ }
+ if (ret < 0)
+ return -1;
+ } else if (ptr >= c->buffer_end) {
+ /* request too long: cannot do anything */
+ return -1;
+ } else goto read_loop;
+ }
+ break;
+
+ case HTTPSTATE_SEND_HEADER:
+ if (c->poll_entry->revents & (POLLERR | POLLHUP))
+ return -1;
+
+ /* no need to write if no events */
+ if (!(c->poll_entry->revents & POLLOUT))
+ return 0;
+ len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
+ if (len < 0) {
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR)) {
+ /* error : close connection */
+ av_freep(&c->pb_buffer);
+ return -1;
+ }
+ } else {
+ c->buffer_ptr += len;
+ if (c->stream)
+ c->stream->bytes_served += len;
+ c->data_count += len;
+ if (c->buffer_ptr >= c->buffer_end) {
+ av_freep(&c->pb_buffer);
+ /* if error, exit */
+ if (c->http_error)
+ return -1;
+ /* all the buffer was sent : synchronize to the incoming stream */
+ c->state = HTTPSTATE_SEND_DATA_HEADER;
+ c->buffer_ptr = c->buffer_end = c->buffer;
+ }
+ }
+ break;
+
+ case HTTPSTATE_SEND_DATA:
+ case HTTPSTATE_SEND_DATA_HEADER:
+ case HTTPSTATE_SEND_DATA_TRAILER:
+ /* for packetized output, we consider we can always write (the
+ input streams sets the speed). It may be better to verify
+ that we do not rely too much on the kernel queues */
+ if (!c->is_packetized) {
+ if (c->poll_entry->revents & (POLLERR | POLLHUP))
+ return -1;
+
+ /* no need to read if no events */
+ if (!(c->poll_entry->revents & POLLOUT))
+ return 0;
+ }
+ if (http_send_data(c) < 0)
+ return -1;
+ /* close connection if trailer sent */
+ if (c->state == HTTPSTATE_SEND_DATA_TRAILER)
+ return -1;
+ break;
+ case HTTPSTATE_RECEIVE_DATA:
+ /* no need to read if no events */
+ if (c->poll_entry->revents & (POLLERR | POLLHUP))
+ return -1;
+ if (!(c->poll_entry->revents & POLLIN))
+ return 0;
+ if (http_receive_data(c) < 0)
+ return -1;
+ break;
+ case HTTPSTATE_WAIT_FEED:
+ /* no need to read if no events */
+ if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP))
+ return -1;
+
+ /* nothing to do, we'll be waken up by incoming feed packets */
+ break;
+
+ case RTSPSTATE_SEND_REPLY:
+ if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
+ av_freep(&c->pb_buffer);
+ return -1;
+ }
+ /* no need to write if no events */
+ if (!(c->poll_entry->revents & POLLOUT))
+ return 0;
+ len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
+ if (len < 0) {
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR)) {
+ /* error : close connection */
+ av_freep(&c->pb_buffer);
+ return -1;
+ }
+ } else {
+ c->buffer_ptr += len;
+ c->data_count += len;
+ if (c->buffer_ptr >= c->buffer_end) {
+ /* all the buffer was sent : wait for a new request */
+ av_freep(&c->pb_buffer);
+ start_wait_request(c, 1);
+ }
+ }
+ break;
+ case RTSPSTATE_SEND_PACKET:
+ if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
+ av_freep(&c->packet_buffer);
+ return -1;
+ }
+ /* no need to write if no events */
+ if (!(c->poll_entry->revents & POLLOUT))
+ return 0;
+ len = send(c->fd, c->packet_buffer_ptr,
+ c->packet_buffer_end - c->packet_buffer_ptr, 0);
+ if (len < 0) {
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR)) {
+ /* error : close connection */
+ av_freep(&c->packet_buffer);
+ return -1;
+ }
+ } else {
+ c->packet_buffer_ptr += len;
+ if (c->packet_buffer_ptr >= c->packet_buffer_end) {
+ /* all the buffer was sent : wait for a new request */
+ av_freep(&c->packet_buffer);
+ c->state = RTSPSTATE_WAIT_REQUEST;
+ }
+ }
+ break;
+ case HTTPSTATE_READY:
+ /* nothing to do */
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static int extract_rates(char *rates, int ratelen, const char *request)
+{
+ const char *p;
+
+ for (p = request; *p && *p != '\r' && *p != '\n'; ) {
+ if (av_strncasecmp(p, "Pragma:", 7) == 0) {
+ const char *q = p + 7;
+
+ while (*q && *q != '\n' && isspace(*q))
+ q++;
+
+ if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) {
+ int stream_no;
+ int rate_no;
+
+ q += 20;
+
+ memset(rates, 0xff, ratelen);
+
+ while (1) {
+ while (*q && *q != '\n' && *q != ':')
+ q++;
+
+ if (sscanf(q, ":%d:%d", &stream_no, &rate_no) != 2)
+ break;
+
+ stream_no--;
+ if (stream_no < ratelen && stream_no >= 0)
+ rates[stream_no] = rate_no;
+
+ while (*q && *q != '\n' && !isspace(*q))
+ q++;
+ }
+
+ return 1;
+ }
+ }
+ p = strchr(p, '\n');
+ if (!p)
+ break;
+
+ p++;
+ }
+
+ return 0;
+}
+
+static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_rate)
+{
+ int i;
+ int best_bitrate = 100000000;
+ int best = -1;
+
+ for (i = 0; i < feed->nb_streams; i++) {
+ AVCodecContext *feed_codec = feed->streams[i]->codec;
+
+ if (feed_codec->codec_id != codec->codec_id ||
+ feed_codec->sample_rate != codec->sample_rate ||
+ feed_codec->width != codec->width ||
+ feed_codec->height != codec->height)
+ continue;
+
+ /* Potential stream */
+
+ /* We want the fastest stream less than bit_rate, or the slowest
+ * faster than bit_rate
+ */
+
+ if (feed_codec->bit_rate <= bit_rate) {
+ if (best_bitrate > bit_rate || feed_codec->bit_rate > best_bitrate) {
+ best_bitrate = feed_codec->bit_rate;
+ best = i;
+ }
+ } else {
+ if (feed_codec->bit_rate < best_bitrate) {
+ best_bitrate = feed_codec->bit_rate;
+ best = i;
+ }
+ }
+ }
+
+ return best;
+}
+
+static int modify_current_stream(HTTPContext *c, char *rates)
+{
+ int i;
+ FFStream *req = c->stream;
+ int action_required = 0;
+
+ /* Not much we can do for a feed */
+ if (!req->feed)
+ return 0;
+
+ for (i = 0; i < req->nb_streams; i++) {
+ AVCodecContext *codec = req->streams[i]->codec;
+
+ switch(rates[i]) {
+ case 0:
+ c->switch_feed_streams[i] = req->feed_streams[i];
+ break;
+ case 1:
+ c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 2);
+ break;
+ case 2:
+ /* Wants off or slow */
+ c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 4);
+#ifdef WANTS_OFF
+ /* This doesn't work well when it turns off the only stream! */
+ c->switch_feed_streams[i] = -2;
+ c->feed_streams[i] = -2;
+#endif
+ break;
+ }
+
+ if (c->switch_feed_streams[i] >= 0 && c->switch_feed_streams[i] != c->feed_streams[i])
+ action_required = 1;
+ }
+
+ return action_required;
+}
+
+/* XXX: factorize in utils.c ? */
+/* XXX: take care with different space meaning */
+static void skip_spaces(const char **pp)
+{
+ const char *p;
+ p = *pp;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ *pp = p;
+}
+
+static void get_word(char *buf, int buf_size, const char **pp)
+{
+ const char *p;
+ char *q;
+
+ p = *pp;
+ skip_spaces(&p);
+ q = buf;
+ while (!isspace(*p) && *p != '\0') {
+ if ((q - buf) < buf_size - 1)
+ *q++ = *p;
+ p++;
+ }
+ if (buf_size > 0)
+ *q = '\0';
+ *pp = p;
+}
+
+static void get_arg(char *buf, int buf_size, const char **pp)
+{
+ const char *p;
+ char *q;
+ int quote;
+
+ p = *pp;
+ while (isspace(*p)) p++;
+ q = buf;
+ quote = 0;
+ if (*p == '\"' || *p == '\'')
+ quote = *p++;
+ for(;;) {
+ if (quote) {
+ if (*p == quote)
+ break;
+ } else {
+ if (isspace(*p))
+ break;
+ }
+ if (*p == '\0')
+ break;
+ if ((q - buf) < buf_size - 1)
+ *q++ = *p;
+ p++;
+ }
+ *q = '\0';
+ if (quote && *p == quote)
+ p++;
+ *pp = p;
+}
+
+static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl,
+ const char *p, const char *filename, int line_num)
+{
+ char arg[1024];
+ IPAddressACL acl;
+ int errors = 0;
+
+ get_arg(arg, sizeof(arg), &p);
+ if (av_strcasecmp(arg, "allow") == 0)
+ acl.action = IP_ALLOW;
+ else if (av_strcasecmp(arg, "deny") == 0)
+ acl.action = IP_DENY;
+ else {
+ fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
+ filename, line_num, arg);
+ errors++;
+ }
+
+ get_arg(arg, sizeof(arg), &p);
+
+ if (resolve_host(&acl.first, arg) != 0) {
+ fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
+ filename, line_num, arg);
+ errors++;
+ } else
+ acl.last = acl.first;
+
+ get_arg(arg, sizeof(arg), &p);
+
+ if (arg[0]) {
+ if (resolve_host(&acl.last, arg) != 0) {
+ fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
+ filename, line_num, arg);
+ errors++;
+ }
+ }
+
+ if (!errors) {
+ IPAddressACL *nacl = av_mallocz(sizeof(*nacl));
+ IPAddressACL **naclp = 0;
+
+ acl.next = 0;
+ *nacl = acl;
+
+ if (stream)
+ naclp = &stream->acl;
+ else if (feed)
+ naclp = &feed->acl;
+ else if (ext_acl)
+ naclp = &ext_acl;
+ else {
+ fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
+ filename, line_num);
+ errors++;
+ }
+
+ if (naclp) {
+ while (*naclp)
+ naclp = &(*naclp)->next;
+
+ *naclp = nacl;
+ }
+ }
+}
+
+
+static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
+{
+ FILE* f;
+ char line[1024];
+ char cmd[1024];
+ IPAddressACL *acl = NULL;
+ int line_num = 0;
+ const char *p;
+
+ f = fopen(stream->dynamic_acl, "r");
+ if (!f) {
+ perror(stream->dynamic_acl);
+ return NULL;
+ }
+
+ acl = av_mallocz(sizeof(IPAddressACL));
+
+ /* Build ACL */
+ for(;;) {
+ if (fgets(line, sizeof(line), f) == NULL)
+ break;
+ line_num++;
+ p = line;
+ while (isspace(*p))
+ p++;
+ if (*p == '\0' || *p == '#')
+ continue;
+ get_arg(cmd, sizeof(cmd), &p);
+
+ if (!av_strcasecmp(cmd, "ACL"))
+ parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
+ }
+ fclose(f);
+ return acl;
+}
+
+
+static void free_acl_list(IPAddressACL *in_acl)
+{
+ IPAddressACL *pacl,*pacl2;
+
+ pacl = in_acl;
+ while(pacl) {
+ pacl2 = pacl;
+ pacl = pacl->next;
+ av_freep(pacl2);
+ }
+}
+
+static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c)
+{
+ enum IPAddressAction last_action = IP_DENY;
+ IPAddressACL *acl;
+ struct in_addr *src = &c->from_addr.sin_addr;
+ unsigned long src_addr = src->s_addr;
+
+ for (acl = in_acl; acl; acl = acl->next) {
+ if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr)
+ return (acl->action == IP_ALLOW) ? 1 : 0;
+ last_action = acl->action;
+ }
+
+ /* Nothing matched, so return not the last action */
+ return (last_action == IP_DENY) ? 1 : 0;
+}
+
+static int validate_acl(FFStream *stream, HTTPContext *c)
+{
+ int ret = 0;
+ IPAddressACL *acl;
+
+
+ /* if stream->acl is null validate_acl_list will return 1 */
+ ret = validate_acl_list(stream->acl, c);
+
+ if (stream->dynamic_acl[0]) {
+ acl = parse_dynamic_acl(stream, c);
+
+ ret = validate_acl_list(acl, c);
+
+ free_acl_list(acl);
+ }
+
+ return ret;
+}
+
+/* compute the real filename of a file by matching it without its
+ extensions to all the stream filenames */
+static void compute_real_filename(char *filename, int max_size)
+{
+ char file1[1024];
+ char file2[1024];
+ char *p;
+ FFStream *stream;
+
+ /* compute filename by matching without the file extensions */
+ av_strlcpy(file1, filename, sizeof(file1));
+ p = strrchr(file1, '.');
+ if (p)
+ *p = '\0';
+ for(stream = first_stream; stream != NULL; stream = stream->next) {
+ av_strlcpy(file2, stream->filename, sizeof(file2));
+ p = strrchr(file2, '.');
+ if (p)
+ *p = '\0';
+ if (!strcmp(file1, file2)) {
+ av_strlcpy(filename, stream->filename, max_size);
+ break;
+ }
+ }
+}
+
+enum RedirType {
+ REDIR_NONE,
+ REDIR_ASX,
+ REDIR_RAM,
+ REDIR_ASF,
+ REDIR_RTSP,
+ REDIR_SDP,
+};
+
+/* parse http request and prepare header */
+static int http_parse_request(HTTPContext *c)
+{
+ char *p;
+ enum RedirType redir_type;
+ char cmd[32];
+ char info[1024], filename[1024];
+ char url[1024], *q;
+ char protocol[32];
+ char msg[1024];
+ const char *mime_type;
+ FFStream *stream;
+ int i;
+ char ratebuf[32];
+ char *useragent = 0;
+
+ p = c->buffer;
+ get_word(cmd, sizeof(cmd), (const char **)&p);
+ av_strlcpy(c->method, cmd, sizeof(c->method));
+
+ if (!strcmp(cmd, "GET"))
+ c->post = 0;
+ else if (!strcmp(cmd, "POST"))
+ c->post = 1;
+ else
+ return -1;
+
+ get_word(url, sizeof(url), (const char **)&p);
+ av_strlcpy(c->url, url, sizeof(c->url));
+
+ get_word(protocol, sizeof(protocol), (const char **)&p);
+ if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1"))
+ return -1;
+
+ av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
+
+ if (avserver_debug)
+ http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url);
+
+ /* find the filename and the optional info string in the request */
+ p = strchr(url, '?');
+ if (p) {
+ av_strlcpy(info, p, sizeof(info));
+ *p = '\0';
+ } else
+ info[0] = '\0';
+
+ av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
+
+ for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
+ if (av_strncasecmp(p, "User-Agent:", 11) == 0) {
+ useragent = p + 11;
+ if (*useragent && *useragent != '\n' && isspace(*useragent))
+ useragent++;
+ break;
+ }
+ p = strchr(p, '\n');
+ if (!p)
+ break;
+
+ p++;
+ }
+
+ redir_type = REDIR_NONE;
+ if (av_match_ext(filename, "asx")) {
+ redir_type = REDIR_ASX;
+ filename[strlen(filename)-1] = 'f';
+ } else if (av_match_ext(filename, "asf") &&
+ (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) {
+ /* if this isn't WMP or lookalike, return the redirector file */
+ redir_type = REDIR_ASF;
+ } else if (av_match_ext(filename, "rpm,ram")) {
+ redir_type = REDIR_RAM;
+ strcpy(filename + strlen(filename)-2, "m");
+ } else if (av_match_ext(filename, "rtsp")) {
+ redir_type = REDIR_RTSP;
+ compute_real_filename(filename, sizeof(filename) - 1);
+ } else if (av_match_ext(filename, "sdp")) {
+ redir_type = REDIR_SDP;
+ compute_real_filename(filename, sizeof(filename) - 1);
+ }
+
+ // "redirect" / request to index.html
+ if (!strlen(filename))
+ av_strlcpy(filename, "index.html", sizeof(filename) - 1);
+
+ stream = first_stream;
+ while (stream != NULL) {
+ if (!strcmp(stream->filename, filename) && validate_acl(stream, c))
+ break;
+ stream = stream->next;
+ }
+ if (stream == NULL) {
+ snprintf(msg, sizeof(msg), "File '%s' not found", url);
+ http_log("File '%s' not found\n", url);
+ goto send_error;
+ }
+
+ c->stream = stream;
+ memcpy(c->feed_streams, stream->feed_streams, sizeof(c->feed_streams));
+ memset(c->switch_feed_streams, -1, sizeof(c->switch_feed_streams));
+
+ if (stream->stream_type == STREAM_TYPE_REDIRECT) {
+ c->http_error = 301;
+ q = c->buffer;
+ q += snprintf(q, c->buffer_size,
+ "HTTP/1.0 301 Moved\r\n"
+ "Location: %s\r\n"
+ "Content-type: text/html\r\n"
+ "\r\n"
+ "<html><head><title>Moved</title></head><body>\r\n"
+ "You should be <a href=\"%s\">redirected</a>.\r\n"
+ "</body></html>\r\n", stream->feed_filename, stream->feed_filename);
+ /* prepare output buffer */
+ c->buffer_ptr = c->buffer;
+ c->buffer_end = q;
+ c->state = HTTPSTATE_SEND_HEADER;
+ return 0;
+ }
+
+ /* If this is WMP, get the rate information */
+ if (extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
+ if (modify_current_stream(c, ratebuf)) {
+ for (i = 0; i < FF_ARRAY_ELEMS(c->feed_streams); i++) {
+ if (c->switch_feed_streams[i] >= 0)
+ c->switch_feed_streams[i] = -1;
+ }
+ }
+ }
+
+ if (c->post == 0 && stream->stream_type == STREAM_TYPE_LIVE)
+ current_bandwidth += stream->bandwidth;
+
+ /* 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;
+ }
+
+ if (c->post == 0 && max_bandwidth < current_bandwidth) {
+ c->http_error = 503;
+ q = c->buffer;
+ q += snprintf(q, c->buffer_size,
+ "HTTP/1.0 503 Server too busy\r\n"
+ "Content-type: text/html\r\n"
+ "\r\n"
+ "<html><head><title>Too busy</title></head><body>\r\n"
+ "<p>The server is too busy to serve your request at this time.</p>\r\n"
+ "<p>The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, "
+ "and this exceeds the limit of %"PRIu64"kbit/sec.</p>\r\n"
+ "</body></html>\r\n", current_bandwidth, max_bandwidth);
+ /* prepare output buffer */
+ c->buffer_ptr = c->buffer;
+ c->buffer_end = q;
+ c->state = HTTPSTATE_SEND_HEADER;
+ return 0;
+ }
+
+ if (redir_type != REDIR_NONE) {
+ char *hostinfo = 0;
+
+ for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
+ if (av_strncasecmp(p, "Host:", 5) == 0) {
+ hostinfo = p + 5;
+ break;
+ }
+ p = strchr(p, '\n');
+ if (!p)
+ break;
+
+ p++;
+ }
+
+ if (hostinfo) {
+ char *eoh;
+ char hostbuf[260];
+
+ while (isspace(*hostinfo))
+ hostinfo++;
+
+ eoh = strchr(hostinfo, '\n');
+ if (eoh) {
+ if (eoh[-1] == '\r')
+ eoh--;
+
+ if (eoh - hostinfo < sizeof(hostbuf) - 1) {
+ memcpy(hostbuf, hostinfo, eoh - hostinfo);
+ hostbuf[eoh - hostinfo] = 0;
+
+ c->http_error = 200;
+ q = c->buffer;
+ switch(redir_type) {
+ case REDIR_ASX:
+ q += snprintf(q, c->buffer_size,
+ "HTTP/1.0 200 ASX Follows\r\n"
+ "Content-type: video/x-ms-asf\r\n"
+ "\r\n"
+ "<ASX Version=\"3\">\r\n"
+ //"<!-- Autogenerated by avserver -->\r\n"
+ "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n"
+ "</ASX>\r\n", hostbuf, filename, info);
+ break;
+ case REDIR_RAM:
+ q += snprintf(q, c->buffer_size,
+ "HTTP/1.0 200 RAM Follows\r\n"
+ "Content-type: audio/x-pn-realaudio\r\n"
+ "\r\n"
+ "# Autogenerated by avserver\r\n"
+ "http://%s/%s%s\r\n", hostbuf, filename, info);
+ break;
+ case REDIR_ASF:
+ q += snprintf(q, c->buffer_size,
+ "HTTP/1.0 200 ASF Redirect follows\r\n"
+ "Content-type: video/x-ms-asf\r\n"
+ "\r\n"
+ "[Reference]\r\n"
+ "Ref1=http://%s/%s%s\r\n", hostbuf, filename, info);
+ break;
+ case REDIR_RTSP:
+ {
+ char hostname[256], *p;
+ /* extract only hostname */
+ av_strlcpy(hostname, hostbuf, sizeof(hostname));
+ p = strrchr(hostname, ':');
+ if (p)
+ *p = '\0';
+ q += snprintf(q, c->buffer_size,
+ "HTTP/1.0 200 RTSP Redirect follows\r\n"
+ /* XXX: incorrect mime type ? */
+ "Content-type: application/x-rtsp\r\n"
+ "\r\n"
+ "rtsp://%s:%d/%s\r\n", hostname, ntohs(my_rtsp_addr.sin_port), filename);
+ }
+ break;
+ case REDIR_SDP:
+ {
+ uint8_t *sdp_data;
+ int sdp_data_size, len;
+ struct sockaddr_in my_addr;
+
+ q += snprintf(q, c->buffer_size,
+ "HTTP/1.0 200 OK\r\n"
+ "Content-type: application/sdp\r\n"
+ "\r\n");
+
+ len = sizeof(my_addr);
+ getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
+
+ /* XXX: should use a dynamic buffer */
+ sdp_data_size = prepare_sdp_description(stream,
+ &sdp_data,
+ my_addr.sin_addr);
+ if (sdp_data_size > 0) {
+ memcpy(q, sdp_data, sdp_data_size);
+ q += sdp_data_size;
+ *q = '\0';
+ av_free(sdp_data);
+ }
+ }
+ break;
+ default:
+ abort();
+ break;
+ }
+
+ /* prepare output buffer */
+ c->buffer_ptr = c->buffer;
+ c->buffer_end = q;
+ c->state = HTTPSTATE_SEND_HEADER;
+ return 0;
+ }
+ }
+ }
+
+ snprintf(msg, sizeof(msg), "ASX/RAM file not handled");
+ goto send_error;
+ }
+
+ stream->conns_served++;
+
+ /* XXX: add there authenticate and IP match */
+
+ if (c->post) {
+ /* if post, it means a feed is being sent */
+ if (!stream->is_feed) {
+ /* However it might be a status report from WMP! Let us log the
+ * data as it might come in handy one day. */
+ char *logline = 0;
+ int client_id = 0;
+
+ for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
+ if (av_strncasecmp(p, "Pragma: log-line=", 17) == 0) {
+ logline = p;
+ break;
+ }
+ if (av_strncasecmp(p, "Pragma: client-id=", 18) == 0)
+ client_id = strtol(p + 18, 0, 10);
+ p = strchr(p, '\n');
+ if (!p)
+ break;
+
+ p++;
+ }
+
+ if (logline) {
+ char *eol = strchr(logline, '\n');
+
+ logline += 17;
+
+ if (eol) {
+ if (eol[-1] == '\r')
+ eol--;
+ http_log("%.*s\n", (int) (eol - logline), logline);
+ c->suppress_log = 1;
+ }
+ }
+
+#ifdef DEBUG
+ http_log("\nGot request:\n%s\n", c->buffer);
+#endif
+
+ if (client_id && extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
+ HTTPContext *wmpc;
+
+ /* Now we have to find the client_id */
+ for (wmpc = first_http_ctx; wmpc; wmpc = wmpc->next) {
+ if (wmpc->wmp_client_id == client_id)
+ break;
+ }
+
+ if (wmpc && modify_current_stream(wmpc, ratebuf))
+ wmpc->switch_pending = 1;
+ }
+
+ snprintf(msg, sizeof(msg), "POST command not handled");
+ c->stream = 0;
+ goto send_error;
+ }
+ if (http_start_receive_data(c) < 0) {
+ snprintf(msg, sizeof(msg), "could not open feed");
+ goto send_error;
+ }
+ c->http_error = 0;
+ c->state = HTTPSTATE_RECEIVE_DATA;
+ return 0;
+ }
+
+#ifdef DEBUG
+ if (strcmp(stream->filename + strlen(stream->filename) - 4, ".asf") == 0)
+ http_log("\nGot request:\n%s\n", c->buffer);
+#endif
+
+ if (c->stream->stream_type == STREAM_TYPE_STATUS)
+ goto send_status;
+
+ /* open input stream */
+ if (open_input_stream(c, info) < 0) {
+ snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url);
+ goto send_error;
+ }
+
+ /* prepare http header */
+ q = c->buffer;
+ q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n");
+ mime_type = c->stream->fmt->mime_type;
+ if (!mime_type)
+ mime_type = "application/x-octet-stream";
+ q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Pragma: no-cache\r\n");
+
+ /* for asf, we need extra headers */
+ if (!strcmp(c->stream->fmt->name,"asf_stream")) {
+ /* Need to allocate a client id */
+
+ c->wmp_client_id = av_lfg_get(&random_state);
+
+ q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id);
+ }
+ q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-Type: %s\r\n", mime_type);
+ q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
+
+ /* prepare output buffer */
+ c->http_error = 0;
+ c->buffer_ptr = c->buffer;
+ c->buffer_end = q;
+ c->state = HTTPSTATE_SEND_HEADER;
+ return 0;
+ send_error:
+ c->http_error = 404;
+ q = c->buffer;
+ q += snprintf(q, c->buffer_size,
+ "HTTP/1.0 404 Not Found\r\n"
+ "Content-type: text/html\r\n"
+ "\r\n"
+ "<html>\n"
+ "<head><title>404 Not Found</title></head>\n"
+ "<body>%s</body>\n"
+ "</html>\n", msg);
+ /* prepare output buffer */
+ c->buffer_ptr = c->buffer;
+ c->buffer_end = q;
+ c->state = HTTPSTATE_SEND_HEADER;
+ return 0;
+ send_status:
+ compute_status(c);
+ c->http_error = 200; /* horrible : we use this value to avoid
+ going to the send data state */
+ c->state = HTTPSTATE_SEND_HEADER;
+ return 0;
+}
+
+static void fmt_bytecount(AVIOContext *pb, int64_t count)
+{
+ static const char *suffix = " kMGTP";
+ const char *s;
+
+ for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++);
+
+ avio_printf(pb, "%"PRId64"%c", count, *s);
+}
+
+static void compute_status(HTTPContext *c)
+{
+ HTTPContext *c1;
+ FFStream *stream;
+ char *p;
+ time_t ti;
+ int i, len;
+ AVIOContext *pb;
+
+ if (avio_open_dyn_buf(&pb) < 0) {
+ /* XXX: return an error ? */
+ c->buffer_ptr = c->buffer;
+ c->buffer_end = c->buffer;
+ return;
+ }
+
+ avio_printf(pb, "HTTP/1.0 200 OK\r\n");
+ avio_printf(pb, "Content-type: %s\r\n", "text/html");
+ avio_printf(pb, "Pragma: no-cache\r\n");
+ avio_printf(pb, "\r\n");
+
+ avio_printf(pb, "<html><head><title>%s Status</title>\n", program_name);
+ if (c->stream->feed_filename[0])
+ avio_printf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);
+ avio_printf(pb, "</head>\n<body>");
+ avio_printf(pb, "<h1>%s Status</h1>\n", program_name);
+ /* format status */
+ avio_printf(pb, "<h2>Available Streams</h2>\n");
+ avio_printf(pb, "<table cellspacing=0 cellpadding=4>\n");
+ avio_printf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<th valign=top>Format<th>Bit rate<br>kbits/s<th align=left>Video<br>kbits/s<th><br>Codec<th align=left>Audio<br>kbits/s<th><br>Codec<th align=left valign=top>Feed\n");
+ stream = first_stream;
+ while (stream != NULL) {
+ char sfilename[1024];
+ char *eosf;
+
+ if (stream->feed != stream) {
+ av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10);
+ eosf = sfilename + strlen(sfilename);
+ if (eosf - sfilename >= 4) {
+ if (strcmp(eosf - 4, ".asf") == 0)
+ strcpy(eosf - 4, ".asx");
+ else if (strcmp(eosf - 3, ".rm") == 0)
+ strcpy(eosf - 3, ".ram");
+ else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
+ /* generate a sample RTSP director if
+ unicast. Generate an SDP redirector if
+ multicast */
+ eosf = strrchr(sfilename, '.');
+ if (!eosf)
+ eosf = sfilename + strlen(sfilename);
+ if (stream->is_multicast)
+ strcpy(eosf, ".sdp");
+ else
+ strcpy(eosf, ".rtsp");
+ }
+ }
+
+ avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
+ sfilename, stream->filename);
+ avio_printf(pb, "<td align=right> %d <td align=right> ",
+ stream->conns_served);
+ fmt_bytecount(pb, stream->bytes_served);
+ switch(stream->stream_type) {
+ case STREAM_TYPE_LIVE: {
+ int audio_bit_rate = 0;
+ int video_bit_rate = 0;
+ const char *audio_codec_name = "";
+ const char *video_codec_name = "";
+ const char *audio_codec_name_extra = "";
+ const char *video_codec_name_extra = "";
+
+ for(i=0;i<stream->nb_streams;i++) {
+ AVStream *st = stream->streams[i];
+ AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
+ switch(st->codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ audio_bit_rate += st->codec->bit_rate;
+ if (codec) {
+ if (*audio_codec_name)
+ audio_codec_name_extra = "...";
+ audio_codec_name = codec->name;
+ }
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ video_bit_rate += st->codec->bit_rate;
+ if (codec) {
+ if (*video_codec_name)
+ video_codec_name_extra = "...";
+ video_codec_name = codec->name;
+ }
+ break;
+ case AVMEDIA_TYPE_DATA:
+ video_bit_rate += st->codec->bit_rate;
+ break;
+ default:
+ abort();
+ }
+ }
+ avio_printf(pb, "<td align=center> %s <td align=right> %d <td align=right> %d <td> %s %s <td align=right> %d <td> %s %s",
+ stream->fmt->name,
+ stream->bandwidth,
+ video_bit_rate / 1000, video_codec_name, video_codec_name_extra,
+ audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra);
+ if (stream->feed)
+ avio_printf(pb, "<td>%s", stream->feed->filename);
+ else
+ avio_printf(pb, "<td>%s", stream->feed_filename);
+ avio_printf(pb, "\n");
+ }
+ break;
+ default:
+ avio_printf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n");
+ break;
+ }
+ }
+ stream = stream->next;
+ }
+ avio_printf(pb, "</table>\n");
+
+ stream = first_stream;
+ while (stream != NULL) {
+ if (stream->feed == stream) {
+ avio_printf(pb, "<h2>Feed %s</h2>", stream->filename);
+ if (stream->pid) {
+ avio_printf(pb, "Running as pid %d.\n", stream->pid);
+
+#if defined(linux) && !defined(CONFIG_NOCUTILS)
+ {
+ FILE *pid_stat;
+ char ps_cmd[64];
+
+ /* This is somewhat linux specific I guess */
+ snprintf(ps_cmd, sizeof(ps_cmd),
+ "ps -o \"%%cpu,cputime\" --no-headers %d",
+ stream->pid);
+
+ pid_stat = popen(ps_cmd, "r");
+ if (pid_stat) {
+ char cpuperc[10];
+ char cpuused[64];
+
+ if (fscanf(pid_stat, "%10s %64s", cpuperc,
+ cpuused) == 2) {
+ avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",
+ cpuperc, cpuused);
+ }
+ fclose(pid_stat);
+ }
+ }
+#endif
+
+ avio_printf(pb, "<p>");
+ }
+ avio_printf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>type<th>kbits/s<th align=left>codec<th align=left>Parameters\n");
+
+ for (i = 0; i < stream->nb_streams; i++) {
+ AVStream *st = stream->streams[i];
+ AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
+ const char *type = "unknown";
+ char parameters[64];
+
+ parameters[0] = 0;
+
+ switch(st->codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ type = "audio";
+ snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate);
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ type = "video";
+ snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height,
+ st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num);
+ break;
+ default:
+ abort();
+ }
+ avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\n",
+ i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters);
+ }
+ avio_printf(pb, "</table>\n");
+
+ }
+ stream = stream->next;
+ }
+
+ /* connection status */
+ avio_printf(pb, "<h2>Connection Status</h2>\n");
+
+ avio_printf(pb, "Number of connections: %d / %d<br>\n",
+ nb_connections, nb_max_connections);
+
+ avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
+ current_bandwidth, max_bandwidth);
+
+ avio_printf(pb, "<table>\n");
+ avio_printf(pb, "<tr><th>#<th>File<th>IP<th>Proto<th>State<th>Target bits/sec<th>Actual bits/sec<th>Bytes transferred\n");
+ c1 = first_http_ctx;
+ i = 0;
+ while (c1 != NULL) {
+ int bitrate;
+ int j;
+
+ bitrate = 0;
+ if (c1->stream) {
+ for (j = 0; j < c1->stream->nb_streams; j++) {
+ if (!c1->stream->feed)
+ bitrate += c1->stream->streams[j]->codec->bit_rate;
+ else if (c1->feed_streams[j] >= 0)
+ bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate;
+ }
+ }
+
+ i++;
+ p = inet_ntoa(c1->from_addr.sin_addr);
+ avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td align=right>",
+ i,
+ c1->stream ? c1->stream->filename : "",
+ c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "",
+ p,
+ c1->protocol,
+ http_state[c1->state]);
+ fmt_bytecount(pb, bitrate);
+ avio_printf(pb, "<td align=right>");
+ fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);
+ avio_printf(pb, "<td align=right>");
+ fmt_bytecount(pb, c1->data_count);
+ avio_printf(pb, "\n");
+ c1 = c1->next;
+ }
+ avio_printf(pb, "</table>\n");
+
+ /* date */
+ ti = time(NULL);
+ p = ctime(&ti);
+ avio_printf(pb, "<hr size=1 noshade>Generated at %s", p);
+ avio_printf(pb, "</body>\n</html>\n");
+
+ len = avio_close_dyn_buf(pb, &c->pb_buffer);
+ c->buffer_ptr = c->pb_buffer;
+ c->buffer_end = c->pb_buffer + len;
+}
+
+/* check if the parser needs to be opened for stream i */
+static void open_parser(AVFormatContext *s, int i)
+{
+ AVStream *st = s->streams[i];
+ AVCodec *codec;
+
+ if (!st->codec->codec) {
+ codec = avcodec_find_decoder(st->codec->codec_id);
+ if (codec && (codec->capabilities & CODEC_CAP_PARSE_ONLY)) {
+ st->codec->parse_only = 1;
+ if (avcodec_open2(st->codec, codec, NULL) < 0)
+ st->codec->parse_only = 0;
+ }
+ }
+}
+
+static int open_input_stream(HTTPContext *c, const char *info)
+{
+ char buf[128];
+ char input_filename[1024];
+ AVFormatContext *s = NULL;
+ int i, ret;
+ int64_t stream_pos;
+
+ /* find file name */
+ if (c->stream->feed) {
+ strcpy(input_filename, c->stream->feed->feed_filename);
+ /* compute position (absolute time) */
+ if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
+ if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0)
+ return ret;
+ } else if (av_find_info_tag(buf, sizeof(buf), "buffer", info)) {
+ int prebuffer = strtol(buf, 0, 10);
+ stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
+ } else
+ stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000;
+ } else {
+ strcpy(input_filename, c->stream->feed_filename);
+ /* compute position (relative time) */
+ if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
+ if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0)
+ return ret;
+ } else
+ stream_pos = 0;
+ }
+ if (input_filename[0] == '\0')
+ return -1;
+
+ /* open stream */
+ if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) {
+ http_log("could not open %s: %d\n", input_filename, ret);
+ return -1;
+ }
+ s->flags |= AVFMT_FLAG_GENPTS;
+ c->fmt_in = s;
+ if (strcmp(s->iformat->name, "ffm") && avformat_find_stream_info(c->fmt_in, NULL) < 0) {
+ http_log("Could not find stream info '%s'\n", input_filename);
+ avformat_close_input(&s);
+ return -1;
+ }
+
+ /* open each parser */
+ for(i=0;i<s->nb_streams;i++)
+ open_parser(s, i);
+
+ /* choose stream as clock source (we favorize video stream if
+ present) for packet sending */
+ c->pts_stream_index = 0;
+ for(i=0;i<c->stream->nb_streams;i++) {
+ if (c->pts_stream_index == 0 &&
+ c->stream->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ c->pts_stream_index = i;
+ }
+ }
+
+ if (c->fmt_in->iformat->read_seek)
+ av_seek_frame(c->fmt_in, -1, stream_pos, 0);
+ /* set the start time (needed for maxtime and RTP packet timing) */
+ c->start_time = cur_time;
+ c->first_pts = AV_NOPTS_VALUE;
+ return 0;
+}
+
+/* return the server clock (in us) */
+static int64_t get_server_clock(HTTPContext *c)
+{
+ /* compute current pts value from system time */
+ return (cur_time - c->start_time) * 1000;
+}
+
+/* return the estimated time at which the current packet must be sent
+ (in us) */
+static int64_t get_packet_send_clock(HTTPContext *c)
+{
+ int bytes_left, bytes_sent, frame_bytes;
+
+ frame_bytes = c->cur_frame_bytes;
+ if (frame_bytes <= 0)
+ return c->cur_pts;
+ else {
+ bytes_left = c->buffer_end - c->buffer_ptr;
+ bytes_sent = frame_bytes - bytes_left;
+ return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
+ }
+}
+
+
+static int http_prepare_data(HTTPContext *c)
+{
+ int i, len, ret;
+ AVFormatContext *ctx;
+
+ av_freep(&c->pb_buffer);
+ switch(c->state) {
+ case HTTPSTATE_SEND_DATA_HEADER:
+ memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx));
+ av_dict_set(&c->fmt_ctx.metadata, "author" , c->stream->author , 0);
+ av_dict_set(&c->fmt_ctx.metadata, "comment" , c->stream->comment , 0);
+ av_dict_set(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0);
+ av_dict_set(&c->fmt_ctx.metadata, "title" , c->stream->title , 0);
+
+ c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams);
+
+ for(i=0;i<c->stream->nb_streams;i++) {
+ AVStream *src;
+ c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
+ /* if file or feed, then just take streams from FFStream struct */
+ if (!c->stream->feed ||
+ c->stream->feed == c->stream)
+ src = c->stream->streams[i];
+ else
+ src = c->stream->feed->streams[c->stream->feed_streams[i]];
+
+ *(c->fmt_ctx.streams[i]) = *src;
+ c->fmt_ctx.streams[i]->priv_data = 0;
+ c->fmt_ctx.streams[i]->codec->frame_number = 0; /* XXX: should be done in
+ 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 */
+ if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
+ /* XXX: potential leak */
+ return -1;
+ }
+ c->fmt_ctx.pb->seekable = 0;
+
+ /*
+ * HACK to avoid mpeg ps muxer to spit many underflow errors
+ * Default value from Libav
+ * 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);
+
+ if (avformat_write_header(&c->fmt_ctx, NULL) < 0) {
+ http_log("Error writing output header\n");
+ return -1;
+ }
+ av_dict_free(&c->fmt_ctx.metadata);
+
+ len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
+ c->buffer_ptr = c->pb_buffer;
+ c->buffer_end = c->pb_buffer + len;
+
+ c->state = HTTPSTATE_SEND_DATA;
+ c->last_packet_sent = 0;
+ break;
+ case HTTPSTATE_SEND_DATA:
+ /* find a new packet */
+ /* read a packet from the input stream */
+ if (c->stream->feed)
+ ffm_set_write_index(c->fmt_in,
+ c->stream->feed->feed_write_index,
+ c->stream->feed->feed_size);
+
+ if (c->stream->max_time &&
+ c->stream->max_time + c->start_time - cur_time < 0)
+ /* We have timed out */
+ c->state = HTTPSTATE_SEND_DATA_TRAILER;
+ else {
+ AVPacket pkt;
+ redo:
+ ret = av_read_frame(c->fmt_in, &pkt);
+ if (ret < 0) {
+ if (c->stream->feed) {
+ /* if coming from feed, it means we reached the end of the
+ ffm file, so must wait for more data */
+ c->state = HTTPSTATE_WAIT_FEED;
+ return 1; /* state changed */
+ } else if (ret == AVERROR(EAGAIN)) {
+ /* input not ready, come back later */
+ return 0;
+ } else {
+ if (c->stream->loop) {
+ avformat_close_input(&c->fmt_in);
+ if (open_input_stream(c, "") < 0)
+ goto no_loop;
+ goto redo;
+ } else {
+ no_loop:
+ /* must send trailer now because eof or error */
+ c->state = HTTPSTATE_SEND_DATA_TRAILER;
+ }
+ }
+ } else {
+ int source_index = pkt.stream_index;
+ /* update first pts if needed */
+ if (c->first_pts == AV_NOPTS_VALUE) {
+ c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
+ c->start_time = cur_time;
+ }
+ /* send it to the appropriate stream */
+ if (c->stream->feed) {
+ /* if coming from a feed, select the right stream */
+ if (c->switch_pending) {
+ c->switch_pending = 0;
+ for(i=0;i<c->stream->nb_streams;i++) {
+ if (c->switch_feed_streams[i] == pkt.stream_index)
+ if (pkt.flags & AV_PKT_FLAG_KEY)
+ c->switch_feed_streams[i] = -1;
+ if (c->switch_feed_streams[i] >= 0)
+ c->switch_pending = 1;
+ }
+ }
+ for(i=0;i<c->stream->nb_streams;i++) {
+ if (c->stream->feed_streams[i] == pkt.stream_index) {
+ AVStream *st = c->fmt_in->streams[source_index];
+ pkt.stream_index = i;
+ if (pkt.flags & AV_PKT_FLAG_KEY &&
+ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
+ c->stream->nb_streams == 1))
+ c->got_key_frame = 1;
+ if (!c->stream->send_on_key || c->got_key_frame)
+ goto send_it;
+ }
+ }
+ } 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) {
+ /* compute send time and duration */
+ c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
+ c->cur_pts -= c->first_pts;
+ c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
+ /* find RTP context */
+ c->packet_stream_index = pkt.stream_index;
+ ctx = c->rtp_ctx[c->packet_stream_index];
+ if(!ctx) {
+ av_free_packet(&pkt);
+ break;
+ }
+ codec = ctx->streams[0]->codec;
+ /* only one stream per RTP connection */
+ pkt.stream_index = 0;
+ } else {
+ ctx = &c->fmt_ctx;
+ /* Fudge here */
+ codec = ctx->streams[pkt.stream_index]->codec;
+ }
+
+ if (c->is_packetized) {
+ int max_packet_size;
+ if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
+ max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
+ else
+ max_packet_size = url_get_max_packet_size(c->rtp_handles[c->packet_stream_index]);
+ ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size);
+ } else {
+ ret = avio_open_dyn_buf(&ctx->pb);
+ }
+ if (ret < 0) {
+ /* XXX: potential leak */
+ return -1;
+ }
+ ost = ctx->streams[pkt.stream_index];
+
+ ctx->pb->seekable = 0;
+ if (pkt.dts != AV_NOPTS_VALUE)
+ 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, 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;
+ }
+
+ len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
+ c->cur_frame_bytes = len;
+ c->buffer_ptr = c->pb_buffer;
+ c->buffer_end = c->pb_buffer + len;
+
+ codec->frame_number++;
+ if (len == 0) {
+ av_free_packet(&pkt);
+ goto redo;
+ }
+ }
+ av_free_packet(&pkt);
+ }
+ }
+ break;
+ default:
+ case HTTPSTATE_SEND_DATA_TRAILER:
+ /* last packet test ? */
+ if (c->last_packet_sent || c->is_packetized)
+ return -1;
+ ctx = &c->fmt_ctx;
+ /* prepare header */
+ if (avio_open_dyn_buf(&ctx->pb) < 0) {
+ /* XXX: potential leak */
+ return -1;
+ }
+ c->fmt_ctx.pb->seekable = 0;
+ av_write_trailer(ctx);
+ len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
+ c->buffer_ptr = c->pb_buffer;
+ c->buffer_end = c->pb_buffer + len;
+
+ c->last_packet_sent = 1;
+ break;
+ }
+ return 0;
+}
+
+/* should convert the format at the same time */
+/* send data starting at c->buffer_ptr to the output connection
+ (either UDP or TCP connection) */
+static int http_send_data(HTTPContext *c)
+{
+ int len, ret;
+
+ for(;;) {
+ if (c->buffer_ptr >= c->buffer_end) {
+ ret = http_prepare_data(c);
+ if (ret < 0)
+ return -1;
+ else if (ret != 0)
+ /* state change requested */
+ break;
+ } else {
+ if (c->is_packetized) {
+ /* RTP data output */
+ len = c->buffer_end - c->buffer_ptr;
+ if (len < 4) {
+ /* fail safe - should never happen */
+ fail1:
+ c->buffer_ptr = c->buffer_end;
+ return 0;
+ }
+ len = (c->buffer_ptr[0] << 24) |
+ (c->buffer_ptr[1] << 16) |
+ (c->buffer_ptr[2] << 8) |
+ (c->buffer_ptr[3]);
+ if (len > (c->buffer_end - c->buffer_ptr))
+ goto fail1;
+ if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {
+ /* nothing to send yet: we can wait */
+ return 0;
+ }
+
+ c->data_count += len;
+ update_datarate(&c->datarate, c->data_count);
+ if (c->stream)
+ c->stream->bytes_served += len;
+
+ if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
+ /* RTP packets are sent inside the RTSP TCP connection */
+ AVIOContext *pb;
+ int interleaved_index, size;
+ uint8_t header[4];
+ HTTPContext *rtsp_c;
+
+ rtsp_c = c->rtsp_c;
+ /* if no RTSP connection left, error */
+ if (!rtsp_c)
+ return -1;
+ /* if already sending something, then wait. */
+ if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)
+ break;
+ if (avio_open_dyn_buf(&pb) < 0)
+ goto fail1;
+ interleaved_index = c->packet_stream_index * 2;
+ /* RTCP packets are sent at odd indexes */
+ if (c->buffer_ptr[1] == 200)
+ interleaved_index++;
+ /* write RTSP TCP header */
+ header[0] = '$';
+ header[1] = interleaved_index;
+ header[2] = len >> 8;
+ header[3] = len;
+ avio_write(pb, header, 4);
+ /* write RTP packet data */
+ c->buffer_ptr += 4;
+ avio_write(pb, c->buffer_ptr, len);
+ size = avio_close_dyn_buf(pb, &c->packet_buffer);
+ /* prepare asynchronous TCP sending */
+ rtsp_c->packet_buffer_ptr = c->packet_buffer;
+ rtsp_c->packet_buffer_end = c->packet_buffer + size;
+ c->buffer_ptr += len;
+
+ /* send everything we can NOW */
+ len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,
+ rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);
+ if (len > 0)
+ rtsp_c->packet_buffer_ptr += len;
+ if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
+ /* if we could not send all the data, we will
+ send it later, so a new state is needed to
+ "lock" the RTSP TCP connection */
+ rtsp_c->state = RTSPSTATE_SEND_PACKET;
+ break;
+ } else
+ /* all data has been sent */
+ av_freep(&c->packet_buffer);
+ } else {
+ /* send RTP packet directly in UDP */
+ c->buffer_ptr += 4;
+ url_write(c->rtp_handles[c->packet_stream_index],
+ c->buffer_ptr, len);
+ c->buffer_ptr += len;
+ /* here we continue as we can send several packets per 10 ms slot */
+ }
+ } else {
+ /* TCP data output */
+ len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
+ if (len < 0) {
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR))
+ /* error : close connection */
+ return -1;
+ else
+ return 0;
+ } else
+ c->buffer_ptr += len;
+
+ c->data_count += len;
+ update_datarate(&c->datarate, c->data_count);
+ if (c->stream)
+ c->stream->bytes_served += len;
+ break;
+ }
+ }
+ } /* for(;;) */
+ return 0;
+}
+
+static int http_start_receive_data(HTTPContext *c)
+{
+ int fd;
+
+ if (c->stream->feed_opened)
+ return -1;
+
+ /* Don't permit writing to this one */
+ if (c->stream->readonly)
+ return -1;
+
+ /* open feed */
+ fd = open(c->stream->feed_filename, O_RDWR);
+ if (fd < 0) {
+ http_log("Error opening feeder file: %s\n", strerror(errno));
+ return -1;
+ }
+ c->feed_fd = fd;
+
+ if (c->stream->truncate) {
+ /* truncate feed file */
+ ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
+ ftruncate(c->feed_fd, FFM_PACKET_SIZE);
+ http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
+ } else {
+ if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) {
+ http_log("Error reading write index from feed file: %s\n", strerror(errno));
+ return -1;
+ }
+ }
+
+ c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
+ c->stream->feed_size = lseek(fd, 0, SEEK_END);
+ lseek(fd, 0, SEEK_SET);
+
+ /* init buffer input */
+ c->buffer_ptr = c->buffer;
+ c->buffer_end = c->buffer + FFM_PACKET_SIZE;
+ c->stream->feed_opened = 1;
+ c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
+ return 0;
+}
+
+static int http_receive_data(HTTPContext *c)
+{
+ HTTPContext *c1;
+ int len, loop_run = 0;
+
+ while (c->chunked_encoding && !c->chunk_size &&
+ c->buffer_end > c->buffer_ptr) {
+ /* read chunk header, if present */
+ len = recv(c->fd, c->buffer_ptr, 1, 0);
+
+ if (len < 0) {
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR))
+ /* error : close connection */
+ goto fail;
+ return 0;
+ } else if (len == 0) {
+ /* end of connection : close it */
+ goto fail;
+ } else if (c->buffer_ptr - c->buffer >= 2 &&
+ !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
+ c->chunk_size = strtol(c->buffer, 0, 16);
+ if (c->chunk_size == 0) // end of stream
+ goto fail;
+ c->buffer_ptr = c->buffer;
+ break;
+ } else if (++loop_run > 10) {
+ /* no chunk header, abort */
+ goto fail;
+ } else {
+ c->buffer_ptr++;
+ }
+ }
+
+ if (c->buffer_end > c->buffer_ptr) {
+ len = recv(c->fd, c->buffer_ptr,
+ FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
+ if (len < 0) {
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR))
+ /* error : close connection */
+ goto fail;
+ } else if (len == 0)
+ /* end of connection : close it */
+ goto fail;
+ else {
+ c->chunk_size -= len;
+ c->buffer_ptr += len;
+ c->data_count += len;
+ update_datarate(&c->datarate, c->data_count);
+ }
+ }
+
+ if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
+ if (c->buffer[0] != 'f' ||
+ c->buffer[1] != 'm') {
+ http_log("Feed stream has become desynchronized -- disconnecting\n");
+ goto fail;
+ }
+ }
+
+ if (c->buffer_ptr >= c->buffer_end) {
+ FFStream *feed = c->stream;
+ /* a packet has been received : write it in the store, except
+ if header */
+ if (c->data_count > FFM_PACKET_SIZE) {
+
+ // printf("writing pos=0x%"PRIx64" size=0x%"PRIx64"\n", feed->feed_write_index, feed->feed_size);
+ /* XXX: use llseek or url_seek */
+ lseek(c->feed_fd, feed->feed_write_index, SEEK_SET);
+ if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) {
+ http_log("Error writing to feed file: %s\n", strerror(errno));
+ goto fail;
+ }
+
+ feed->feed_write_index += FFM_PACKET_SIZE;
+ /* update file size */
+ if (feed->feed_write_index > c->stream->feed_size)
+ feed->feed_size = feed->feed_write_index;
+
+ /* handle wrap around if max file size reached */
+ if (c->stream->feed_max_size && feed->feed_write_index >= c->stream->feed_max_size)
+ feed->feed_write_index = FFM_PACKET_SIZE;
+
+ /* write index */
+ if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) {
+ http_log("Error writing index to feed file: %s\n", strerror(errno));
+ goto fail;
+ }
+
+ /* wake up any waiting connections */
+ for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
+ if (c1->state == HTTPSTATE_WAIT_FEED &&
+ c1->stream->feed == c->stream->feed)
+ c1->state = HTTPSTATE_SEND_DATA;
+ }
+ } else {
+ /* We have a header in our hands that contains useful data */
+ AVFormatContext *s = avformat_alloc_context();
+ AVIOContext *pb;
+ AVInputFormat *fmt_in;
+ int i;
+
+ if (!s)
+ goto fail;
+
+ /* use feed output format name to find corresponding input format */
+ fmt_in = av_find_input_format(feed->fmt->name);
+ if (!fmt_in)
+ goto fail;
+
+ pb = avio_alloc_context(c->buffer, c->buffer_end - c->buffer,
+ 0, NULL, NULL, NULL, NULL);
+ pb->seekable = 0;
+
+ s->pb = pb;
+ if (avformat_open_input(&s, 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) {
+ avformat_close_input(&s);
+ av_free(pb);
+ http_log("Feed '%s' stream number does not match registered feed\n",
+ c->stream->feed_filename);
+ goto fail;
+ }
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *fst = feed->streams[i];
+ AVStream *st = s->streams[i];
+ avcodec_copy_context(fst->codec, st->codec);
+ }
+
+ avformat_close_input(&s);
+ av_free(pb);
+ }
+ c->buffer_ptr = c->buffer;
+ }
+
+ return 0;
+ fail:
+ c->stream->feed_opened = 0;
+ close(c->feed_fd);
+ /* wake up any waiting connections to stop waiting for feed */
+ for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
+ if (c1->state == HTTPSTATE_WAIT_FEED &&
+ c1->stream->feed == c->stream->feed)
+ c1->state = HTTPSTATE_SEND_DATA_TRAILER;
+ }
+ return -1;
+}
+
+/********************************************************************/
+/* RTSP handling */
+
+static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
+{
+ const char *str;
+ time_t ti;
+ struct tm *tm;
+ char buf2[32];
+
+ switch(error_number) {
+ case RTSP_STATUS_OK:
+ str = "OK";
+ break;
+ case RTSP_STATUS_METHOD:
+ str = "Method Not Allowed";
+ break;
+ case RTSP_STATUS_BANDWIDTH:
+ str = "Not Enough Bandwidth";
+ break;
+ case RTSP_STATUS_SESSION:
+ str = "Session Not Found";
+ break;
+ case RTSP_STATUS_STATE:
+ str = "Method Not Valid in This State";
+ break;
+ case RTSP_STATUS_AGGREGATE:
+ str = "Aggregate operation not allowed";
+ break;
+ case RTSP_STATUS_ONLY_AGGREGATE:
+ str = "Only aggregate operation allowed";
+ break;
+ case RTSP_STATUS_TRANSPORT:
+ str = "Unsupported transport";
+ break;
+ case RTSP_STATUS_INTERNAL:
+ str = "Internal Server Error";
+ break;
+ case RTSP_STATUS_SERVICE:
+ str = "Service Unavailable";
+ break;
+ case RTSP_STATUS_VERSION:
+ str = "RTSP Version not supported";
+ break;
+ default:
+ str = "Unknown Error";
+ break;
+ }
+
+ avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
+ avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
+
+ /* output GMT time */
+ ti = time(NULL);
+ tm = gmtime(&ti);
+ strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
+ avio_printf(c->pb, "Date: %s GMT\r\n", buf2);
+}
+
+static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
+{
+ rtsp_reply_header(c, error_number);
+ avio_printf(c->pb, "\r\n");
+}
+
+static int rtsp_parse_request(HTTPContext *c)
+{
+ const char *p, *p1, *p2;
+ char cmd[32];
+ char url[1024];
+ char protocol[32];
+ char line[1024];
+ int len;
+ RTSPMessageHeader header1, *header = &header1;
+
+ c->buffer_ptr[0] = '\0';
+ p = c->buffer;
+
+ get_word(cmd, sizeof(cmd), &p);
+ get_word(url, sizeof(url), &p);
+ get_word(protocol, sizeof(protocol), &p);
+
+ av_strlcpy(c->method, cmd, sizeof(c->method));
+ av_strlcpy(c->url, url, sizeof(c->url));
+ av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
+
+ if (avio_open_dyn_buf(&c->pb) < 0) {
+ /* XXX: cannot do more */
+ c->pb = NULL; /* safety */
+ return -1;
+ }
+
+ /* check version name */
+ if (strcmp(protocol, "RTSP/1.0") != 0) {
+ rtsp_reply_error(c, RTSP_STATUS_VERSION);
+ goto the_end;
+ }
+
+ /* parse each header line */
+ memset(header, 0, sizeof(*header));
+ /* skip to next line */
+ while (*p != '\n' && *p != '\0')
+ p++;
+ if (*p == '\n')
+ p++;
+ while (*p != '\0') {
+ p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
+ if (!p1)
+ break;
+ p2 = p1;
+ if (p2 > p && p2[-1] == '\r')
+ p2--;
+ /* skip empty line */
+ if (p2 == p)
+ break;
+ len = p2 - p;
+ if (len > sizeof(line) - 1)
+ len = sizeof(line) - 1;
+ memcpy(line, p, len);
+ line[len] = '\0';
+ ff_rtsp_parse_line(header, line, NULL, NULL);
+ p = p1 + 1;
+ }
+
+ /* handle sequence number */
+ c->seq = header->seq;
+
+ if (!strcmp(cmd, "DESCRIBE"))
+ rtsp_cmd_describe(c, url);
+ else if (!strcmp(cmd, "OPTIONS"))
+ rtsp_cmd_options(c, url);
+ else if (!strcmp(cmd, "SETUP"))
+ rtsp_cmd_setup(c, url, header);
+ else if (!strcmp(cmd, "PLAY"))
+ rtsp_cmd_play(c, url, header);
+ else if (!strcmp(cmd, "PAUSE"))
+ rtsp_cmd_pause(c, url, header);
+ else if (!strcmp(cmd, "TEARDOWN"))
+ rtsp_cmd_teardown(c, url, header);
+ else
+ rtsp_reply_error(c, RTSP_STATUS_METHOD);
+
+ the_end:
+ len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
+ c->pb = NULL; /* safety */
+ if (len < 0) {
+ /* XXX: cannot do more */
+ return -1;
+ }
+ c->buffer_ptr = c->pb_buffer;
+ c->buffer_end = c->pb_buffer + len;
+ c->state = RTSPSTATE_SEND_REPLY;
+ return 0;
+}
+
+static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
+ struct in_addr my_ip)
+{
+ AVFormatContext *avc;
+ AVStream *avs = NULL;
+ int i;
+
+ avc = avformat_alloc_context();
+ if (avc == NULL) {
+ return -1;
+ }
+ av_dict_set(&avc->metadata, "title",
+ stream->title[0] ? stream->title : "No Title", 0);
+ avc->nb_streams = stream->nb_streams;
+ if (stream->is_multicast) {
+ snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
+ inet_ntoa(stream->multicast_ip),
+ stream->multicast_port, stream->multicast_ttl);
+ } else {
+ snprintf(avc->filename, 1024, "rtp://0.0.0.0");
+ }
+
+ if (avc->nb_streams >= INT_MAX/sizeof(*avc->streams) ||
+ !(avc->streams = av_malloc(avc->nb_streams * sizeof(*avc->streams))))
+ goto sdp_done;
+ if (avc->nb_streams >= INT_MAX/sizeof(*avs) ||
+ !(avs = av_malloc(avc->nb_streams * sizeof(*avs))))
+ goto sdp_done;
+
+ for(i = 0; i < stream->nb_streams; i++) {
+ avc->streams[i] = &avs[i];
+ avc->streams[i]->codec = stream->streams[i]->codec;
+ }
+ *pbuffer = av_mallocz(2048);
+ av_sdp_create(&avc, 1, *pbuffer, 2048);
+
+ sdp_done:
+ av_free(avc->streams);
+ av_dict_free(&avc->metadata);
+ av_free(avc);
+ av_free(avs);
+
+ return strlen(*pbuffer);
+}
+
+static void rtsp_cmd_options(HTTPContext *c, const char *url)
+{
+// rtsp_reply_header(c, RTSP_STATUS_OK);
+ avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
+ avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
+ avio_printf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
+ avio_printf(c->pb, "\r\n");
+}
+
+static void rtsp_cmd_describe(HTTPContext *c, const char *url)
+{
+ FFStream *stream;
+ char path1[1024];
+ const char *path;
+ uint8_t *content;
+ int content_length, len;
+ struct sockaddr_in my_addr;
+
+ /* find which url is asked */
+ av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
+ path = path1;
+ if (*path == '/')
+ path++;
+
+ for(stream = first_stream; stream != NULL; stream = stream->next) {
+ if (!stream->is_feed &&
+ stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
+ !strcmp(path, stream->filename)) {
+ goto found;
+ }
+ }
+ /* no stream found */
+ rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
+ return;
+
+ found:
+ /* prepare the media description in sdp format */
+
+ /* get the host IP */
+ len = sizeof(my_addr);
+ getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
+ content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr);
+ if (content_length < 0) {
+ rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
+ return;
+ }
+ rtsp_reply_header(c, RTSP_STATUS_OK);
+ avio_printf(c->pb, "Content-Base: %s/\r\n", url);
+ avio_printf(c->pb, "Content-Type: application/sdp\r\n");
+ avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
+ avio_printf(c->pb, "\r\n");
+ avio_write(c->pb, content, content_length);
+ av_free(content);
+}
+
+static HTTPContext *find_rtp_session(const char *session_id)
+{
+ HTTPContext *c;
+
+ if (session_id[0] == '\0')
+ return NULL;
+
+ for(c = first_http_ctx; c != NULL; c = c->next) {
+ if (!strcmp(c->session_id, session_id))
+ return c;
+ }
+ return NULL;
+}
+
+static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport)
+{
+ RTSPTransportField *th;
+ int i;
+
+ for(i=0;i<h->nb_transports;i++) {
+ th = &h->transports[i];
+ if (th->lower_transport == lower_transport)
+ return th;
+ }
+ return NULL;
+}
+
+static void rtsp_cmd_setup(HTTPContext *c, const char *url,
+ RTSPMessageHeader *h)
+{
+ FFStream *stream;
+ int stream_index, rtp_port, rtcp_port;
+ char buf[1024];
+ char path1[1024];
+ const char *path;
+ HTTPContext *rtp_c;
+ RTSPTransportField *th;
+ struct sockaddr_in dest_addr;
+ RTSPActionServerSetup setup;
+
+ /* find which url is asked */
+ av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
+ path = path1;
+ if (*path == '/')
+ path++;
+
+ /* now check each stream */
+ for(stream = first_stream; stream != NULL; stream = stream->next) {
+ if (!stream->is_feed &&
+ stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
+ /* accept aggregate filenames only if single stream */
+ if (!strcmp(path, stream->filename)) {
+ if (stream->nb_streams != 1) {
+ rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);
+ return;
+ }
+ stream_index = 0;
+ goto found;
+ }
+
+ for(stream_index = 0; stream_index < stream->nb_streams;
+ stream_index++) {
+ snprintf(buf, sizeof(buf), "%s/streamid=%d",
+ stream->filename, stream_index);
+ if (!strcmp(path, buf))
+ goto found;
+ }
+ }
+ }
+ /* no stream found */
+ rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
+ return;
+ found:
+
+ /* generate session id if needed */
+ if (h->session_id[0] == '\0')
+ snprintf(h->session_id, sizeof(h->session_id), "%08x%08x",
+ av_lfg_get(&random_state), av_lfg_get(&random_state));
+
+ /* find rtp session, and create it if none found */
+ rtp_c = find_rtp_session(h->session_id);
+ if (!rtp_c) {
+ /* always prefer UDP */
+ th = find_transport(h, RTSP_LOWER_TRANSPORT_UDP);
+ if (!th) {
+ th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP);
+ if (!th) {
+ rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
+ return;
+ }
+ }
+
+ rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,
+ th->lower_transport);
+ if (!rtp_c) {
+ rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);
+ return;
+ }
+
+ /* open input stream */
+ if (open_input_stream(rtp_c, "") < 0) {
+ rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
+ return;
+ }
+ }
+
+ /* test if stream is OK (test needed because several SETUP needs
+ to be done for a given file) */
+ if (rtp_c->stream != stream) {
+ rtsp_reply_error(c, RTSP_STATUS_SERVICE);
+ return;
+ }
+
+ /* test if stream is already set up */
+ if (rtp_c->rtp_ctx[stream_index]) {
+ rtsp_reply_error(c, RTSP_STATUS_STATE);
+ return;
+ }
+
+ /* check transport */
+ th = find_transport(h, rtp_c->rtp_protocol);
+ if (!th || (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
+ th->client_port_min <= 0)) {
+ rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
+ return;
+ }
+
+ /* setup default options */
+ setup.transport_option[0] = '\0';
+ dest_addr = rtp_c->from_addr;
+ dest_addr.sin_port = htons(th->client_port_min);
+
+ /* setup stream */
+ if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
+ rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
+ return;
+ }
+
+ /* now everything is OK, so we can send the connection parameters */
+ rtsp_reply_header(c, RTSP_STATUS_OK);
+ /* session ID */
+ avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+
+ switch(rtp_c->rtp_protocol) {
+ case RTSP_LOWER_TRANSPORT_UDP:
+ rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
+ rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
+ avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
+ "client_port=%d-%d;server_port=%d-%d",
+ th->client_port_min, th->client_port_max,
+ rtp_port, rtcp_port);
+ break;
+ case RTSP_LOWER_TRANSPORT_TCP:
+ avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
+ stream_index * 2, stream_index * 2 + 1);
+ break;
+ default:
+ break;
+ }
+ if (setup.transport_option[0] != '\0')
+ avio_printf(c->pb, ";%s", setup.transport_option);
+ avio_printf(c->pb, "\r\n");
+
+
+ avio_printf(c->pb, "\r\n");
+}
+
+
+/* find an rtp connection by using the session ID. Check consistency
+ with filename */
+static HTTPContext *find_rtp_session_with_url(const char *url,
+ const char *session_id)
+{
+ HTTPContext *rtp_c;
+ char path1[1024];
+ const char *path;
+ char buf[1024];
+ int s, len;
+
+ rtp_c = find_rtp_session(session_id);
+ if (!rtp_c)
+ return NULL;
+
+ /* find which url is asked */
+ av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
+ path = path1;
+ if (*path == '/')
+ path++;
+ if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
+ for(s=0; s<rtp_c->stream->nb_streams; ++s) {
+ snprintf(buf, sizeof(buf), "%s/streamid=%d",
+ rtp_c->stream->filename, s);
+ if(!strncmp(path, buf, sizeof(buf))) {
+ // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
+ return rtp_c;
+ }
+ }
+ len = strlen(path);
+ if (len > 0 && path[len - 1] == '/' &&
+ !strncmp(path, rtp_c->stream->filename, len - 1))
+ return rtp_c;
+ return NULL;
+}
+
+static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
+{
+ HTTPContext *rtp_c;
+
+ rtp_c = find_rtp_session_with_url(url, h->session_id);
+ if (!rtp_c) {
+ rtsp_reply_error(c, RTSP_STATUS_SESSION);
+ return;
+ }
+
+ if (rtp_c->state != HTTPSTATE_SEND_DATA &&
+ rtp_c->state != HTTPSTATE_WAIT_FEED &&
+ rtp_c->state != HTTPSTATE_READY) {
+ rtsp_reply_error(c, RTSP_STATUS_STATE);
+ return;
+ }
+
+ rtp_c->state = HTTPSTATE_SEND_DATA;
+
+ /* now everything is OK, so we can send the connection parameters */
+ rtsp_reply_header(c, RTSP_STATUS_OK);
+ /* session ID */
+ avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+ avio_printf(c->pb, "\r\n");
+}
+
+static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h)
+{
+ HTTPContext *rtp_c;
+
+ rtp_c = find_rtp_session_with_url(url, h->session_id);
+ if (!rtp_c) {
+ rtsp_reply_error(c, RTSP_STATUS_SESSION);
+ return;
+ }
+
+ if (rtp_c->state != HTTPSTATE_SEND_DATA &&
+ rtp_c->state != HTTPSTATE_WAIT_FEED) {
+ rtsp_reply_error(c, RTSP_STATUS_STATE);
+ return;
+ }
+
+ rtp_c->state = HTTPSTATE_READY;
+ rtp_c->first_pts = AV_NOPTS_VALUE;
+ /* now everything is OK, so we can send the connection parameters */
+ rtsp_reply_header(c, RTSP_STATUS_OK);
+ /* session ID */
+ avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+ avio_printf(c->pb, "\r\n");
+}
+
+static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h)
+{
+ HTTPContext *rtp_c;
+
+ rtp_c = find_rtp_session_with_url(url, h->session_id);
+ if (!rtp_c) {
+ rtsp_reply_error(c, RTSP_STATUS_SESSION);
+ return;
+ }
+
+ /* now everything is OK, so we can send the connection parameters */
+ rtsp_reply_header(c, RTSP_STATUS_OK);
+ /* session ID */
+ avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+ avio_printf(c->pb, "\r\n");
+
+ /* abort the session */
+ close_connection(rtp_c);
+}
+
+
+/********************************************************************/
+/* RTP handling */
+
+static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
+ FFStream *stream, const char *session_id,
+ enum RTSPLowerTransport rtp_protocol)
+{
+ HTTPContext *c = NULL;
+ const char *proto_str;
+
+ /* XXX: should output a warning page when coming
+ close to the connection limit */
+ if (nb_connections >= nb_max_connections)
+ goto fail;
+
+ /* add a new connection */
+ c = av_mallocz(sizeof(HTTPContext));
+ if (!c)
+ goto fail;
+
+ c->fd = -1;
+ c->poll_entry = NULL;
+ c->from_addr = *from_addr;
+ c->buffer_size = IOBUFFER_INIT_SIZE;
+ c->buffer = av_malloc(c->buffer_size);
+ if (!c->buffer)
+ goto fail;
+ nb_connections++;
+ c->stream = stream;
+ av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
+ c->state = HTTPSTATE_READY;
+ c->is_packetized = 1;
+ c->rtp_protocol = rtp_protocol;
+
+ /* protocol is shown in statistics */
+ switch(c->rtp_protocol) {
+ case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
+ proto_str = "MCAST";
+ break;
+ case RTSP_LOWER_TRANSPORT_UDP:
+ proto_str = "UDP";
+ break;
+ case RTSP_LOWER_TRANSPORT_TCP:
+ proto_str = "TCP";
+ break;
+ default:
+ proto_str = "???";
+ break;
+ }
+ av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
+ av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
+
+ current_bandwidth += stream->bandwidth;
+
+ c->next = first_http_ctx;
+ first_http_ctx = c;
+ return c;
+
+ fail:
+ if (c) {
+ av_free(c->buffer);
+ av_free(c);
+ }
+ return NULL;
+}
+
+/* add a new RTP stream in an RTP connection (used in RTSP SETUP
+ command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
+ used. */
+static int rtp_new_av_stream(HTTPContext *c,
+ int stream_index, struct sockaddr_in *dest_addr,
+ HTTPContext *rtsp_c)
+{
+ AVFormatContext *ctx;
+ AVStream *st;
+ char *ipaddr;
+ URLContext *h = NULL;
+ uint8_t *dummy_buf;
+ int max_packet_size;
+
+ /* now we can open the relevant output stream */
+ ctx = avformat_alloc_context();
+ if (!ctx)
+ return -1;
+ ctx->oformat = av_guess_format("rtp", NULL, NULL);
+
+ st = av_mallocz(sizeof(AVStream));
+ if (!st)
+ goto fail;
+ ctx->nb_streams = 1;
+ ctx->streams = av_mallocz(sizeof(AVStream *) * ctx->nb_streams);
+ if (!ctx->streams)
+ goto fail;
+ ctx->streams[0] = st;
+
+ if (!c->stream->feed ||
+ c->stream->feed == c->stream)
+ memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
+ else
+ memcpy(st,
+ c->stream->feed->streams[c->stream->feed_streams[stream_index]],
+ sizeof(AVStream));
+ st->priv_data = NULL;
+
+ /* build destination RTP address */
+ ipaddr = inet_ntoa(dest_addr->sin_addr);
+
+ switch(c->rtp_protocol) {
+ case RTSP_LOWER_TRANSPORT_UDP:
+ case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
+ /* RTP/UDP case */
+
+ /* XXX: also pass as parameter to function ? */
+ if (c->stream->is_multicast) {
+ int ttl;
+ ttl = c->stream->multicast_ttl;
+ if (!ttl)
+ ttl = 16;
+ snprintf(ctx->filename, sizeof(ctx->filename),
+ "rtp://%s:%d?multicast=1&ttl=%d",
+ ipaddr, ntohs(dest_addr->sin_port), ttl);
+ } else {
+ snprintf(ctx->filename, sizeof(ctx->filename),
+ "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
+ }
+
+ if (url_open(&h, ctx->filename, AVIO_FLAG_WRITE) < 0)
+ goto fail;
+ c->rtp_handles[stream_index] = h;
+ max_packet_size = url_get_max_packet_size(h);
+ break;
+ case RTSP_LOWER_TRANSPORT_TCP:
+ /* RTP/TCP case */
+ c->rtsp_c = rtsp_c;
+ max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
+ break;
+ default:
+ goto fail;
+ }
+
+ http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",
+ ipaddr, ntohs(dest_addr->sin_port),
+ c->stream->filename, stream_index, c->protocol);
+
+ /* normally, no packets should be output here, but the packet size may be checked */
+ if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
+ /* XXX: close stream */
+ goto fail;
+ }
+ if (avformat_write_header(ctx, NULL) < 0) {
+ fail:
+ if (h)
+ url_close(h);
+ av_free(ctx);
+ return -1;
+ }
+ avio_close_dyn_buf(ctx->pb, &dummy_buf);
+ av_free(dummy_buf);
+
+ c->rtp_ctx[stream_index] = ctx;
+ return 0;
+}
+
+/********************************************************************/
+/* avserver initialization */
+
+static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
+{
+ AVStream *fst;
+
+ fst = av_mallocz(sizeof(AVStream));
+ if (!fst)
+ return NULL;
+ if (copy) {
+ fst->codec = avcodec_alloc_context3(NULL);
+ memcpy(fst->codec, codec, sizeof(AVCodecContext));
+ if (codec->extradata_size) {
+ fst->codec->extradata = av_malloc(codec->extradata_size);
+ memcpy(fst->codec->extradata, codec->extradata,
+ codec->extradata_size);
+ }
+ } else {
+ /* live streams must use the actual feed's codec since it may be
+ * updated later to carry extradata needed by the streams.
+ */
+ fst->codec = codec;
+ }
+ fst->priv_data = av_mallocz(sizeof(FeedData));
+ fst->index = stream->nb_streams;
+ av_set_pts_info(fst, 33, 1, 90000);
+ fst->sample_aspect_ratio = codec->sample_aspect_ratio;
+ stream->streams[stream->nb_streams++] = fst;
+ return fst;
+}
+
+/* return the stream number in the feed */
+static int add_av_stream(FFStream *feed, AVStream *st)
+{
+ AVStream *fst;
+ AVCodecContext *av, *av1;
+ int i;
+
+ av = st->codec;
+ for(i=0;i<feed->nb_streams;i++) {
+ st = feed->streams[i];
+ av1 = st->codec;
+ if (av1->codec_id == av->codec_id &&
+ av1->codec_type == av->codec_type &&
+ av1->bit_rate == av->bit_rate) {
+
+ switch(av->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ if (av1->channels == av->channels &&
+ av1->sample_rate == av->sample_rate)
+ return i;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ if (av1->width == av->width &&
+ av1->height == av->height &&
+ av1->time_base.den == av->time_base.den &&
+ av1->time_base.num == av->time_base.num &&
+ av1->gop_size == av->gop_size)
+ return i;
+ break;
+ default:
+ abort();
+ }
+ }
+ }
+
+ fst = add_av_stream1(feed, av, 0);
+ if (!fst)
+ return -1;
+ return feed->nb_streams - 1;
+}
+
+static void remove_stream(FFStream *stream)
+{
+ FFStream **ps;
+ ps = &first_stream;
+ while (*ps != NULL) {
+ if (*ps == stream)
+ *ps = (*ps)->next;
+ else
+ ps = &(*ps)->next;
+ }
+}
+
+/* specific mpeg4 handling : we extract the raw parameters */
+static void extract_mpeg4_header(AVFormatContext *infile)
+{
+ int mpeg4_count, i, size;
+ AVPacket pkt;
+ AVStream *st;
+ const uint8_t *p;
+
+ mpeg4_count = 0;
+ for(i=0;i<infile->nb_streams;i++) {
+ st = infile->streams[i];
+ if (st->codec->codec_id == CODEC_ID_MPEG4 &&
+ st->codec->extradata_size == 0) {
+ mpeg4_count++;
+ }
+ }
+ if (!mpeg4_count)
+ return;
+
+ printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
+ while (mpeg4_count > 0) {
+ if (av_read_packet(infile, &pkt) < 0)
+ break;
+ st = infile->streams[pkt.stream_index];
+ if (st->codec->codec_id == CODEC_ID_MPEG4 &&
+ st->codec->extradata_size == 0) {
+ av_freep(&st->codec->extradata);
+ /* fill extradata with the header */
+ /* XXX: we make hard suppositions here ! */
+ p = pkt.data;
+ while (p < pkt.data + pkt.size - 4) {
+ /* stop when vop header is found */
+ if (p[0] == 0x00 && p[1] == 0x00 &&
+ p[2] == 0x01 && p[3] == 0xb6) {
+ size = p - pkt.data;
+ // av_hex_dump_log(infile, AV_LOG_DEBUG, pkt.data, size);
+ st->codec->extradata = av_malloc(size);
+ st->codec->extradata_size = size;
+ memcpy(st->codec->extradata, pkt.data, size);
+ break;
+ }
+ p++;
+ }
+ mpeg4_count--;
+ }
+ av_free_packet(&pkt);
+ }
+}
+
+/* compute the needed AVStream for each file */
+static void build_file_streams(void)
+{
+ FFStream *stream, *stream_next;
+ int i, ret;
+
+ /* gather all streams */
+ for(stream = first_stream; stream != NULL; stream = stream_next) {
+ AVFormatContext *infile = NULL;
+ stream_next = stream->next;
+ if (stream->stream_type == STREAM_TYPE_LIVE &&
+ !stream->feed) {
+ /* the stream comes from a file */
+ /* try to open the file */
+ /* open stream */
+ if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
+ /* specific case : if transport stream output to RTP,
+ we use a raw transport stream reader */
+ av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
+ }
+
+ http_log("Opening file '%s'\n", stream->feed_filename);
+ if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {
+ http_log("Could not open '%s': %d\n", stream->feed_filename, ret);
+ /* remove stream (no need to spend more time on it) */
+ fail:
+ remove_stream(stream);
+ } else {
+ /* find all the AVStreams inside and reference them in
+ 'stream' */
+ if (avformat_find_stream_info(infile, NULL) < 0) {
+ http_log("Could not find codec parameters from '%s'\n",
+ stream->feed_filename);
+ avformat_close_input(&infile);
+ goto fail;
+ }
+ extract_mpeg4_header(infile);
+
+ for(i=0;i<infile->nb_streams;i++)
+ add_av_stream1(stream, infile->streams[i]->codec, 1);
+
+ avformat_close_input(&infile);
+ }
+ }
+ }
+}
+
+/* compute the needed AVStream for each feed */
+static void build_feed_streams(void)
+{
+ FFStream *stream, *feed;
+ int i;
+
+ /* gather all streams */
+ for(stream = first_stream; stream != NULL; stream = stream->next) {
+ feed = stream->feed;
+ if (feed) {
+ if (stream->is_feed) {
+ for(i=0;i<stream->nb_streams;i++)
+ stream->feed_streams[i] = i;
+ } else {
+ /* we handle a stream coming from a feed */
+ for(i=0;i<stream->nb_streams;i++)
+ stream->feed_streams[i] = add_av_stream(feed, stream->streams[i]);
+ }
+ }
+ }
+
+ /* create feed files if needed */
+ for(feed = first_feed; feed != NULL; feed = feed->next_feed) {
+ int fd;
+
+ if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) {
+ /* See if it matches */
+ AVFormatContext *s = NULL;
+ int matches = 0;
+
+ if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) {
+ /* Now see if it matches */
+ if (s->nb_streams == feed->nb_streams) {
+ matches = 1;
+ for(i=0;i<s->nb_streams;i++) {
+ AVStream *sf, *ss;
+ sf = feed->streams[i];
+ ss = s->streams[i];
+
+ if (sf->index != ss->index ||
+ sf->id != ss->id) {
+ http_log("Index & Id do not match for stream %d (%s)\n",
+ i, feed->feed_filename);
+ matches = 0;
+ } else {
+ AVCodecContext *ccf, *ccs;
+
+ ccf = sf->codec;
+ ccs = ss->codec;
+#define CHECK_CODEC(x) (ccf->x != ccs->x)
+
+ if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
+ http_log("Codecs do not match for stream %d\n", i);
+ matches = 0;
+ } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
+ http_log("Codec bitrates do not match for stream %d\n", i);
+ matches = 0;
+ } else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (CHECK_CODEC(time_base.den) ||
+ CHECK_CODEC(time_base.num) ||
+ CHECK_CODEC(width) ||
+ CHECK_CODEC(height)) {
+ http_log("Codec width, height and framerate do not match for stream %d\n", i);
+ matches = 0;
+ }
+ } else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) {
+ if (CHECK_CODEC(sample_rate) ||
+ CHECK_CODEC(channels) ||
+ CHECK_CODEC(frame_size)) {
+ http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i);
+ matches = 0;
+ }
+ } else {
+ http_log("Unknown codec type\n");
+ matches = 0;
+ }
+ }
+ if (!matches)
+ break;
+ }
+ } else
+ http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n",
+ feed->feed_filename, s->nb_streams, feed->nb_streams);
+
+ avformat_close_input(&s);
+ } else
+ http_log("Deleting feed file '%s' as it appears to be corrupt\n",
+ feed->feed_filename);
+
+ if (!matches) {
+ if (feed->readonly) {
+ http_log("Unable to delete feed file '%s' as it is marked readonly\n",
+ feed->feed_filename);
+ exit(1);
+ }
+ unlink(feed->feed_filename);
+ }
+ }
+ if (avio_check(feed->feed_filename, AVIO_FLAG_WRITE) <= 0) {
+ AVFormatContext s1 = {0}, *s = &s1;
+
+ if (feed->readonly) {
+ 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 (avio_open(&s->pb, feed->feed_filename, AVIO_FLAG_WRITE) < 0) {
+ http_log("Could not open output feed file '%s'\n",
+ feed->feed_filename);
+ exit(1);
+ }
+ s->oformat = feed->fmt;
+ s->nb_streams = feed->nb_streams;
+ s->streams = feed->streams;
+ if (avformat_write_header(s, NULL) < 0) {
+ http_log("Container doesn't supports the required parameters\n");
+ exit(1);
+ }
+ /* XXX: need better api */
+ av_freep(&s->priv_data);
+ avio_close(s->pb);
+ }
+ /* get feed size and write index */
+ fd = open(feed->feed_filename, O_RDONLY);
+ if (fd < 0) {
+ http_log("Could not open output feed file '%s'\n",
+ feed->feed_filename);
+ exit(1);
+ }
+
+ feed->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
+ feed->feed_size = lseek(fd, 0, SEEK_END);
+ /* ensure that we do not wrap before the end of file */
+ if (feed->feed_max_size && feed->feed_max_size < feed->feed_size)
+ feed->feed_max_size = feed->feed_size;
+
+ close(fd);
+ }
+}
+
+/* compute the bandwidth used by each stream */
+static void compute_bandwidth(void)
+{
+ unsigned bandwidth;
+ int i;
+ FFStream *stream;
+
+ for(stream = first_stream; stream != NULL; stream = stream->next) {
+ bandwidth = 0;
+ for(i=0;i<stream->nb_streams;i++) {
+ AVStream *st = stream->streams[i];
+ switch(st->codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ case AVMEDIA_TYPE_VIDEO:
+ bandwidth += st->codec->bit_rate;
+ break;
+ default:
+ break;
+ }
+ }
+ stream->bandwidth = (bandwidth + 999) / 1000;
+ }
+}
+
+/* add a codec and set the default parameters */
+static void add_codec(FFStream *stream, AVCodecContext *av)
+{
+ AVStream *st;
+
+ /* compute default parameters */
+ switch(av->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ if (av->bit_rate == 0)
+ av->bit_rate = 64000;
+ if (av->sample_rate == 0)
+ av->sample_rate = 22050;
+ if (av->channels == 0)
+ av->channels = 1;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ if (av->bit_rate == 0)
+ av->bit_rate = 64000;
+ if (av->time_base.num == 0){
+ av->time_base.den = 5;
+ av->time_base.num = 1;
+ }
+ if (av->width == 0 || av->height == 0) {
+ av->width = 160;
+ av->height = 128;
+ }
+ /* Bitrate tolerance is less for streaming */
+ if (av->bit_rate_tolerance == 0)
+ av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
+ (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
+ if (av->qmin == 0)
+ av->qmin = 3;
+ if (av->qmax == 0)
+ av->qmax = 31;
+ if (av->max_qdiff == 0)
+ av->max_qdiff = 3;
+ av->qcompress = 0.5;
+ av->qblur = 0.5;
+
+ if (!av->nsse_weight)
+ av->nsse_weight = 8;
+
+ av->frame_skip_cmp = FF_CMP_DCTMAX;
+ if (!av->me_method)
+ av->me_method = ME_EPZS;
+ av->rc_buffer_aggressivity = 1.0;
+
+ if (!av->rc_eq)
+ av->rc_eq = "tex^qComp";
+ if (!av->i_quant_factor)
+ av->i_quant_factor = -0.8;
+ if (!av->b_quant_factor)
+ av->b_quant_factor = 1.25;
+ if (!av->b_quant_offset)
+ av->b_quant_offset = 1.25;
+ if (!av->rc_max_rate)
+ av->rc_max_rate = av->bit_rate * 2;
+
+ if (av->rc_max_rate && !av->rc_buffer_size) {
+ av->rc_buffer_size = av->rc_max_rate;
+ }
+
+
+ break;
+ default:
+ abort();
+ }
+
+ st = av_mallocz(sizeof(AVStream));
+ if (!st)
+ return;
+ st->codec = avcodec_alloc_context3(NULL);
+ stream->streams[stream->nb_streams++] = st;
+ memcpy(st->codec, av, sizeof(AVCodecContext));
+}
+
+static enum CodecID opt_audio_codec(const char *arg)
+{
+ AVCodec *p= avcodec_find_encoder_by_name(arg);
+
+ if (p == NULL || p->type != AVMEDIA_TYPE_AUDIO)
+ return CODEC_ID_NONE;
+
+ return p->id;
+}
+
+static enum CodecID opt_video_codec(const char *arg)
+{
+ AVCodec *p= avcodec_find_encoder_by_name(arg);
+
+ if (p == NULL || p->type != AVMEDIA_TYPE_VIDEO)
+ return CODEC_ID_NONE;
+
+ return p->id;
+}
+
+/* simplistic plugin support */
+
+#if HAVE_DLOPEN
+static void load_module(const char *filename)
+{
+ void *dll;
+ void (*init_func)(void);
+ dll = dlopen(filename, RTLD_NOW);
+ if (!dll) {
+ fprintf(stderr, "Could not load module '%s' - %s\n",
+ filename, dlerror());
+ return;
+ }
+
+ init_func = dlsym(dll, "avserver_module_init");
+ if (!init_func) {
+ fprintf(stderr,
+ "%s: init function 'avserver_module_init()' not found\n",
+ filename);
+ dlclose(dll);
+ }
+
+ init_func();
+}
+#endif
+
+static int avserver_opt_default(const char *opt, const char *arg,
+ AVCodecContext *avctx, int type)
+{
+ int ret = 0;
+ const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0);
+ if(o)
+ ret = av_opt_set(avctx, opt, arg, 0);
+ return ret;
+}
+
+static int avserver_opt_preset(const char *arg,
+ AVCodecContext *avctx, int type,
+ enum CodecID *audio_id, enum CodecID *video_id)
+{
+ FILE *f=NULL;
+ char filename[1000], tmp[1000], tmp2[1000], line[1000];
+ int ret = 0;
+ AVCodec *codec = avcodec_find_encoder(avctx->codec_id);
+
+ if (!(f = get_preset_file(filename, sizeof(filename), arg, 0,
+ codec ? codec->name : NULL))) {
+ fprintf(stderr, "File for preset '%s' not found\n", arg);
+ return 1;
+ }
+
+ while(!feof(f)){
+ int e= fscanf(f, "%999[^\n]\n", line) - 1;
+ if(line[0] == '#' && !e)
+ continue;
+ e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
+ if(e){
+ fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line);
+ ret = 1;
+ break;
+ }
+ if(!strcmp(tmp, "acodec")){
+ *audio_id = opt_audio_codec(tmp2);
+ }else if(!strcmp(tmp, "vcodec")){
+ *video_id = opt_video_codec(tmp2);
+ }else if(!strcmp(tmp, "scodec")){
+ /* opt_subtitle_codec(tmp2); */
+ }else if(avserver_opt_default(tmp, tmp2, avctx, type) < 0){
+ fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2);
+ ret = 1;
+ break;
+ }
+ }
+
+ fclose(f);
+
+ return ret;
+}
+
+static AVOutputFormat *avserver_guess_format(const char *short_name, const char *filename,
+ const char *mime_type)
+{
+ AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
+
+ if (fmt) {
+ AVOutputFormat *stream_fmt;
+ char stream_format_name[64];
+
+ snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
+ stream_fmt = av_guess_format(stream_format_name, NULL, NULL);
+
+ if (stream_fmt)
+ fmt = stream_fmt;
+ }
+
+ return fmt;
+}
+
+static void report_config_error(const char *filename, int line_num, int *errors, const char *fmt, ...)
+{
+ va_list vl;
+ va_start(vl, fmt);
+ fprintf(stderr, "%s:%d: ", filename, line_num);
+ vfprintf(stderr, fmt, vl);
+ va_end(vl);
+
+ (*errors)++;
+}
+
+static int parse_ffconfig(const char *filename)
+{
+ FILE *f;
+ char line[1024];
+ char cmd[64];
+ char arg[1024];
+ const char *p;
+ int val, errors, line_num;
+ FFStream **last_stream, *stream, *redirect;
+ FFStream **last_feed, *feed, *s;
+ AVCodecContext audio_enc, video_enc;
+ enum CodecID audio_id, video_id;
+
+ f = fopen(filename, "r");
+ if (!f) {
+ perror(filename);
+ return -1;
+ }
+
+ errors = 0;
+ line_num = 0;
+ first_stream = NULL;
+ last_stream = &first_stream;
+ first_feed = NULL;
+ last_feed = &first_feed;
+ stream = NULL;
+ feed = NULL;
+ redirect = NULL;
+ audio_id = CODEC_ID_NONE;
+ video_id = CODEC_ID_NONE;
+
+#define ERROR(...) report_config_error(filename, line_num, &errors, __VA_ARGS__)
+ for(;;) {
+ if (fgets(line, sizeof(line), f) == NULL)
+ break;
+ line_num++;
+ p = line;
+ while (isspace(*p))
+ p++;
+ if (*p == '\0' || *p == '#')
+ continue;
+
+ get_arg(cmd, sizeof(cmd), &p);
+
+ if (!av_strcasecmp(cmd, "Port")) {
+ get_arg(arg, sizeof(arg), &p);
+ val = atoi(arg);
+ if (val < 1 || val > 65536) {
+ ERROR("Invalid_port: %s\n", arg);
+ }
+ my_http_addr.sin_port = htons(val);
+ } else if (!av_strcasecmp(cmd, "BindAddress")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
+ ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
+ }
+ } else if (!av_strcasecmp(cmd, "NoDaemon")) {
+ avserver_daemon = 0;
+ } else if (!av_strcasecmp(cmd, "RTSPPort")) {
+ get_arg(arg, sizeof(arg), &p);
+ val = atoi(arg);
+ if (val < 1 || val > 65536) {
+ ERROR("%s:%d: Invalid port: %s\n", arg);
+ }
+ my_rtsp_addr.sin_port = htons(atoi(arg));
+ } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
+ ERROR("Invalid host/IP address: %s\n", arg);
+ }
+ } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) {
+ get_arg(arg, sizeof(arg), &p);
+ val = atoi(arg);
+ if (val < 1 || val > 65536) {
+ ERROR("Invalid MaxHTTPConnections: %s\n", arg);
+ }
+ nb_max_http_connections = val;
+ } else if (!av_strcasecmp(cmd, "MaxClients")) {
+ get_arg(arg, sizeof(arg), &p);
+ val = atoi(arg);
+ if (val < 1 || val > nb_max_http_connections) {
+ ERROR("Invalid MaxClients: %s\n", arg);
+ } else {
+ nb_max_connections = val;
+ }
+ } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
+ int64_t llval;
+ get_arg(arg, sizeof(arg), &p);
+ llval = atoll(arg);
+ if (llval < 10 || llval > 10000000) {
+ ERROR("Invalid MaxBandwidth: %s\n", arg);
+ } else
+ max_bandwidth = llval;
+ } else if (!av_strcasecmp(cmd, "CustomLog")) {
+ if (!avserver_debug)
+ get_arg(logfilename, sizeof(logfilename), &p);
+ } else if (!av_strcasecmp(cmd, "<Feed")) {
+ /*********************************************/
+ /* Feed related options */
+ char *q;
+ if (stream || feed) {
+ ERROR("Already in a tag\n");
+ } else {
+ feed = av_mallocz(sizeof(FFStream));
+ get_arg(feed->filename, sizeof(feed->filename), &p);
+ q = strrchr(feed->filename, '>');
+ if (*q)
+ *q = '\0';
+
+ for (s = first_feed; s; s = s->next) {
+ if (!strcmp(feed->filename, s->filename)) {
+ ERROR("Feed '%s' already registered\n", s->filename);
+ }
+ }
+
+ feed->fmt = av_guess_format("ffm", NULL, NULL);
+ /* defaut feed file */
+ snprintf(feed->feed_filename, sizeof(feed->feed_filename),
+ "/tmp/%s.ffm", feed->filename);
+ feed->feed_max_size = 5 * 1024 * 1024;
+ feed->is_feed = 1;
+ feed->feed = feed; /* self feeding :-) */
+
+ /* add in stream list */
+ *last_stream = feed;
+ last_stream = &feed->next;
+ /* add in feed list */
+ *last_feed = feed;
+ last_feed = &feed->next_feed;
+ }
+ } else if (!av_strcasecmp(cmd, "Launch")) {
+ if (feed) {
+ int i;
+
+ feed->child_argv = av_mallocz(64 * sizeof(char *));
+
+ for (i = 0; i < 62; i++) {
+ get_arg(arg, sizeof(arg), &p);
+ if (!arg[0])
+ break;
+
+ feed->child_argv[i] = av_strdup(arg);
+ }
+
+ feed->child_argv[i] = av_malloc(30 + strlen(feed->filename));
+
+ snprintf(feed->child_argv[i], 30+strlen(feed->filename),
+ "http://%s:%d/%s",
+ (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);
+ }
+ } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) {
+ if (feed) {
+ get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
+ feed->readonly = 1;
+ } else if (stream) {
+ get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
+ }
+ } else if (!av_strcasecmp(cmd, "File")) {
+ if (feed) {
+ get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
+ } else if (stream)
+ get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
+ } else if (!av_strcasecmp(cmd, "Truncate")) {
+ if (feed) {
+ get_arg(arg, sizeof(arg), &p);
+ feed->truncate = strtod(arg, NULL);
+ }
+ } else if (!av_strcasecmp(cmd, "FileMaxSize")) {
+ if (feed) {
+ char *p1;
+ double fsize;
+
+ get_arg(arg, sizeof(arg), &p);
+ p1 = arg;
+ fsize = strtod(p1, &p1);
+ switch(toupper(*p1)) {
+ case 'K':
+ fsize *= 1024;
+ break;
+ case 'M':
+ fsize *= 1024 * 1024;
+ break;
+ case 'G':
+ fsize *= 1024 * 1024 * 1024;
+ break;
+ }
+ feed->feed_max_size = (int64_t)fsize;
+ if (feed->feed_max_size < FFM_PACKET_SIZE*4) {
+ ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4);
+ }
+ }
+ } else if (!av_strcasecmp(cmd, "</Feed>")) {
+ if (!feed) {
+ ERROR("No corresponding <Feed> for </Feed>\n");
+ }
+ feed = NULL;
+ } else if (!av_strcasecmp(cmd, "<Stream")) {
+ /*********************************************/
+ /* Stream related options */
+ char *q;
+ if (stream || feed) {
+ ERROR("Already in a tag\n");
+ } else {
+ FFStream *s;
+ stream = av_mallocz(sizeof(FFStream));
+ get_arg(stream->filename, sizeof(stream->filename), &p);
+ q = strrchr(stream->filename, '>');
+ if (*q)
+ *q = '\0';
+
+ for (s = first_stream; s; s = s->next) {
+ if (!strcmp(stream->filename, s->filename)) {
+ ERROR("Stream '%s' already registered\n", s->filename);
+ }
+ }
+
+ stream->fmt = avserver_guess_format(NULL, stream->filename, NULL);
+ avcodec_get_context_defaults3(&video_enc, NULL);
+ avcodec_get_context_defaults3(&audio_enc, NULL);
+ audio_id = CODEC_ID_NONE;
+ video_id = CODEC_ID_NONE;
+ if (stream->fmt) {
+ audio_id = stream->fmt->audio_codec;
+ video_id = stream->fmt->video_codec;
+ }
+
+ *last_stream = stream;
+ last_stream = &stream->next;
+ }
+ } else if (!av_strcasecmp(cmd, "Feed")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ FFStream *sfeed;
+
+ sfeed = first_feed;
+ while (sfeed != NULL) {
+ if (!strcmp(sfeed->filename, arg))
+ break;
+ sfeed = sfeed->next_feed;
+ }
+ if (!sfeed)
+ ERROR("feed '%s' not defined\n", arg);
+ else
+ stream->feed = sfeed;
+ }
+ } else if (!av_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 = avserver_guess_format(arg, NULL, NULL);
+ if (!stream->fmt) {
+ ERROR("Unknown Format: %s\n", arg);
+ }
+ }
+ if (stream->fmt) {
+ audio_id = stream->fmt->audio_codec;
+ video_id = stream->fmt->video_codec;
+ }
+ }
+ } else if (!av_strcasecmp(cmd, "InputFormat")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ stream->ifmt = av_find_input_format(arg);
+ if (!stream->ifmt) {
+ ERROR("Unknown input format: %s\n", arg);
+ }
+ }
+ } else if (!av_strcasecmp(cmd, "FaviconURL")) {
+ if (stream && stream->stream_type == STREAM_TYPE_STATUS) {
+ get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
+ } else {
+ ERROR("FaviconURL only permitted for status streams\n");
+ }
+ } else if (!av_strcasecmp(cmd, "Author")) {
+ if (stream)
+ get_arg(stream->author, sizeof(stream->author), &p);
+ } else if (!av_strcasecmp(cmd, "Comment")) {
+ if (stream)
+ get_arg(stream->comment, sizeof(stream->comment), &p);
+ } else if (!av_strcasecmp(cmd, "Copyright")) {
+ if (stream)
+ get_arg(stream->copyright, sizeof(stream->copyright), &p);
+ } else if (!av_strcasecmp(cmd, "Title")) {
+ if (stream)
+ get_arg(stream->title, sizeof(stream->title), &p);
+ } else if (!av_strcasecmp(cmd, "Preroll")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ stream->prebuffer = atof(arg) * 1000;
+ } else if (!av_strcasecmp(cmd, "StartSendOnKey")) {
+ if (stream)
+ stream->send_on_key = 1;
+ } else if (!av_strcasecmp(cmd, "AudioCodec")) {
+ get_arg(arg, sizeof(arg), &p);
+ audio_id = opt_audio_codec(arg);
+ if (audio_id == CODEC_ID_NONE) {
+ ERROR("Unknown AudioCodec: %s\n", arg);
+ }
+ } else if (!av_strcasecmp(cmd, "VideoCodec")) {
+ get_arg(arg, sizeof(arg), &p);
+ video_id = opt_video_codec(arg);
+ if (video_id == CODEC_ID_NONE) {
+ ERROR("Unknown VideoCodec: %s\n", arg);
+ }
+ } else if (!av_strcasecmp(cmd, "MaxTime")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ stream->max_time = atof(arg) * 1000;
+ } else if (!av_strcasecmp(cmd, "AudioBitRate")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ audio_enc.bit_rate = lrintf(atof(arg) * 1000);
+ } else if (!av_strcasecmp(cmd, "AudioChannels")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ audio_enc.channels = atoi(arg);
+ } else if (!av_strcasecmp(cmd, "AudioSampleRate")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ audio_enc.sample_rate = atoi(arg);
+ } else if (!av_strcasecmp(cmd, "AudioQuality")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+// audio_enc.quality = atof(arg) * 1000;
+ }
+ } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
+ if (stream) {
+ int minrate, maxrate;
+
+ get_arg(arg, sizeof(arg), &p);
+
+ if (sscanf(arg, "%d-%d", &minrate, &maxrate) == 2) {
+ video_enc.rc_min_rate = minrate * 1000;
+ video_enc.rc_max_rate = maxrate * 1000;
+ } else {
+ ERROR("Incorrect format for VideoBitRateRange -- should be <min>-<max>: %s\n", arg);
+ }
+ }
+ } else if (!av_strcasecmp(cmd, "Debug")) {
+ if (stream) {
+ get_arg(arg, sizeof(arg), &p);
+ video_enc.debug = strtol(arg,0,0);
+ }
+ } else if (!av_strcasecmp(cmd, "Strict")) {
+ if (stream) {
+ get_arg(arg, sizeof(arg), &p);
+ video_enc.strict_std_compliance = atoi(arg);
+ }
+ } else if (!av_strcasecmp(cmd, "VideoBufferSize")) {
+ if (stream) {
+ get_arg(arg, sizeof(arg), &p);
+ video_enc.rc_buffer_size = atoi(arg) * 8*1024;
+ }
+ } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
+ if (stream) {
+ get_arg(arg, sizeof(arg), &p);
+ video_enc.bit_rate_tolerance = atoi(arg) * 1000;
+ }
+ } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ video_enc.bit_rate = atoi(arg) * 1000;
+ }
+ } else if (!av_strcasecmp(cmd, "VideoSize")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ av_parse_video_size(&video_enc.width, &video_enc.height, arg);
+ if ((video_enc.width % 16) != 0 ||
+ (video_enc.height % 16) != 0) {
+ ERROR("Image size must be a multiple of 16\n");
+ }
+ }
+ } else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ AVRational frame_rate;
+ if (av_parse_video_rate(&frame_rate, arg) < 0) {
+ ERROR("Incorrect frame rate: %s\n", arg);
+ } else {
+ video_enc.time_base.num = frame_rate.den;
+ video_enc.time_base.den = frame_rate.num;
+ }
+ }
+ } else if (!av_strcasecmp(cmd, "VideoGopSize")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ video_enc.gop_size = atoi(arg);
+ } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) {
+ if (stream)
+ video_enc.gop_size = 1;
+ } else if (!av_strcasecmp(cmd, "VideoHighQuality")) {
+ if (stream)
+ video_enc.mb_decision = FF_MB_DECISION_BITS;
+ } else if (!av_strcasecmp(cmd, "Video4MotionVector")) {
+ if (stream) {
+ video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove
+ video_enc.flags |= CODEC_FLAG_4MV;
+ }
+ } else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
+ !av_strcasecmp(cmd, "AVOptionAudio")) {
+ char arg2[1024];
+ AVCodecContext *avctx;
+ int type;
+ get_arg(arg, sizeof(arg), &p);
+ get_arg(arg2, sizeof(arg2), &p);
+ if (!av_strcasecmp(cmd, "AVOptionVideo")) {
+ avctx = &video_enc;
+ type = AV_OPT_FLAG_VIDEO_PARAM;
+ } else {
+ avctx = &audio_enc;
+ type = AV_OPT_FLAG_AUDIO_PARAM;
+ }
+ if (avserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
+ ERROR("AVOption error: %s %s\n", arg, arg2);
+ }
+ } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
+ !av_strcasecmp(cmd, "AVPresetAudio")) {
+ AVCodecContext *avctx;
+ int type;
+ get_arg(arg, sizeof(arg), &p);
+ if (!av_strcasecmp(cmd, "AVPresetVideo")) {
+ avctx = &video_enc;
+ video_enc.codec_id = video_id;
+ type = AV_OPT_FLAG_VIDEO_PARAM;
+ } else {
+ avctx = &audio_enc;
+ audio_enc.codec_id = audio_id;
+ type = AV_OPT_FLAG_AUDIO_PARAM;
+ }
+ if (avserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
+ ERROR("AVPreset error: %s\n", arg);
+ }
+ } else if (!av_strcasecmp(cmd, "VideoTag")) {
+ get_arg(arg, sizeof(arg), &p);
+ if ((strlen(arg) == 4) && stream)
+ video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]);
+ } else if (!av_strcasecmp(cmd, "BitExact")) {
+ if (stream)
+ video_enc.flags |= CODEC_FLAG_BITEXACT;
+ } else if (!av_strcasecmp(cmd, "DctFastint")) {
+ if (stream)
+ video_enc.dct_algo = FF_DCT_FASTINT;
+ } else if (!av_strcasecmp(cmd, "IdctSimple")) {
+ if (stream)
+ video_enc.idct_algo = FF_IDCT_SIMPLE;
+ } else if (!av_strcasecmp(cmd, "Qscale")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ video_enc.flags |= CODEC_FLAG_QSCALE;
+ video_enc.global_quality = FF_QP2LAMBDA * atoi(arg);
+ }
+ } else if (!av_strcasecmp(cmd, "VideoQDiff")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ video_enc.max_qdiff = atoi(arg);
+ if (video_enc.max_qdiff < 1 || video_enc.max_qdiff > 31) {
+ ERROR("VideoQDiff out of range\n");
+ }
+ }
+ } else if (!av_strcasecmp(cmd, "VideoQMax")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ video_enc.qmax = atoi(arg);
+ if (video_enc.qmax < 1 || video_enc.qmax > 31) {
+ ERROR("VideoQMax out of range\n");
+ }
+ }
+ } else if (!av_strcasecmp(cmd, "VideoQMin")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ video_enc.qmin = atoi(arg);
+ if (video_enc.qmin < 1 || video_enc.qmin > 31) {
+ ERROR("VideoQMin out of range\n");
+ }
+ }
+ } else if (!av_strcasecmp(cmd, "LumaElim")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ video_enc.luma_elim_threshold = atoi(arg);
+ } else if (!av_strcasecmp(cmd, "ChromaElim")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ video_enc.chroma_elim_threshold = atoi(arg);
+ } else if (!av_strcasecmp(cmd, "LumiMask")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ video_enc.lumi_masking = atof(arg);
+ } else if (!av_strcasecmp(cmd, "DarkMask")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ video_enc.dark_masking = atof(arg);
+ } else if (!av_strcasecmp(cmd, "NoVideo")) {
+ video_id = CODEC_ID_NONE;
+ } else if (!av_strcasecmp(cmd, "NoAudio")) {
+ audio_id = CODEC_ID_NONE;
+ } else if (!av_strcasecmp(cmd, "ACL")) {
+ parse_acl_row(stream, feed, NULL, p, filename, line_num);
+ } else if (!av_strcasecmp(cmd, "DynamicACL")) {
+ if (stream) {
+ get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p);
+ }
+ } else if (!av_strcasecmp(cmd, "RTSPOption")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ av_freep(&stream->rtsp_option);
+ stream->rtsp_option = av_strdup(arg);
+ }
+ } else if (!av_strcasecmp(cmd, "MulticastAddress")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream) {
+ if (resolve_host(&stream->multicast_ip, arg) != 0) {
+ ERROR("Invalid host/IP address: %s\n", arg);
+ }
+ stream->is_multicast = 1;
+ stream->loop = 1; /* default is looping */
+ }
+ } else if (!av_strcasecmp(cmd, "MulticastPort")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ stream->multicast_port = atoi(arg);
+ } else if (!av_strcasecmp(cmd, "MulticastTTL")) {
+ get_arg(arg, sizeof(arg), &p);
+ if (stream)
+ stream->multicast_ttl = atoi(arg);
+ } else if (!av_strcasecmp(cmd, "NoLoop")) {
+ if (stream)
+ stream->loop = 0;
+ } else if (!av_strcasecmp(cmd, "</Stream>")) {
+ if (!stream) {
+ ERROR("No corresponding <Stream> for </Stream>\n");
+ } else {
+ if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) {
+ if (audio_id != CODEC_ID_NONE) {
+ audio_enc.codec_type = AVMEDIA_TYPE_AUDIO;
+ audio_enc.codec_id = audio_id;
+ add_codec(stream, &audio_enc);
+ }
+ if (video_id != CODEC_ID_NONE) {
+ video_enc.codec_type = AVMEDIA_TYPE_VIDEO;
+ video_enc.codec_id = video_id;
+ add_codec(stream, &video_enc);
+ }
+ }
+ stream = NULL;
+ }
+ } else if (!av_strcasecmp(cmd, "<Redirect")) {
+ /*********************************************/
+ char *q;
+ if (stream || feed || redirect) {
+ ERROR("Already in a tag\n");
+ } else {
+ redirect = av_mallocz(sizeof(FFStream));
+ *last_stream = redirect;
+ last_stream = &redirect->next;
+
+ get_arg(redirect->filename, sizeof(redirect->filename), &p);
+ q = strrchr(redirect->filename, '>');
+ if (*q)
+ *q = '\0';
+ redirect->stream_type = STREAM_TYPE_REDIRECT;
+ }
+ } else if (!av_strcasecmp(cmd, "URL")) {
+ if (redirect)
+ get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p);
+ } else if (!av_strcasecmp(cmd, "</Redirect>")) {
+ if (!redirect) {
+ ERROR("No corresponding <Redirect> for </Redirect>\n");
+ } else {
+ if (!redirect->feed_filename[0]) {
+ ERROR("No URL found for <Redirect>\n");
+ }
+ redirect = NULL;
+ }
+ } else if (!av_strcasecmp(cmd, "LoadModule")) {
+ get_arg(arg, sizeof(arg), &p);
+#if HAVE_DLOPEN
+ load_module(arg);
+#else
+ ERROR("Module support not compiled into this version: '%s'\n", arg);
+#endif
+ } else {
+ ERROR("Incorrect keyword: '%s'\n", cmd);
+ }
+ }
+#undef ERROR
+
+ fclose(f);
+ if (errors)
+ return -1;
+ else
+ return 0;
+}
+
+static void handle_child_exit(int sig)
+{
+ pid_t pid;
+ int status;
+
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
+ FFStream *feed;
+
+ for (feed = first_feed; feed; feed = feed->next) {
+ if (feed->pid == pid) {
+ int uptime = time(0) - feed->pid_start;
+
+ feed->pid = 0;
+ fprintf(stderr, "%s: Pid %d exited with status %d after %d seconds\n", feed->filename, pid, status, uptime);
+
+ if (uptime < 30)
+ /* Turn off any more restarts */
+ feed->child_argv = 0;
+ }
+ }
+ }
+
+ need_to_start_children = 1;
+}
+
+static void opt_debug(void)
+{
+ avserver_debug = 1;
+ avserver_daemon = 0;
+ logfilename[0] = '-';
+}
+
+static void show_help(void)
+{
+ printf("usage: avserver [options]\n"
+ "Hyper fast multi format Audio/Video streaming server\n");
+ printf("\n");
+ show_help_options(options, "Main options:\n", 0, 0);
+}
+
+static const OptionDef options[] = {
+#include "cmdutils_common_opts.h"
+ { "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" },
+ { "d", 0, {(void*)opt_debug}, "enable debug mode" },
+ { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/avserver.conf", "configfile" },
+ { NULL },
+};
+
+int main(int argc, char **argv)
+{
+ struct sigaction sigact;
+
+ parse_loglevel(argc, argv, options);
+ av_register_all();
+ avformat_network_init();
+
+ show_banner();
+
+ my_program_name = argv[0];
+ my_program_dir = getcwd(0, 0);
+ avserver_daemon = 1;
+
+ parse_options(NULL, argc, argv, options, NULL);
+
+ unsetenv("http_proxy"); /* Kill the http_proxy */
+
+ av_lfg_init(&random_state, av_get_random_seed());
+
+ memset(&sigact, 0, sizeof(sigact));
+ sigact.sa_handler = handle_child_exit;
+ sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART;
+ sigaction(SIGCHLD, &sigact, 0);
+
+ if (parse_ffconfig(config_filename) < 0) {
+ fprintf(stderr, "Incorrect config file - exiting.\n");
+ 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();
+
+ compute_bandwidth();
+
+ /* put the process in background and detach it from its TTY */
+ if (avserver_daemon) {
+ int pid;
+
+ pid = fork();
+ if (pid < 0) {
+ perror("fork");
+ exit(1);
+ } else if (pid > 0) {
+ /* parent : exit */
+ exit(0);
+ } else {
+ /* child */
+ setsid();
+ close(0);
+ open("/dev/null", O_RDWR);
+ if (strcmp(logfilename, "-") != 0) {
+ close(1);
+ dup(0);
+ }
+ close(2);
+ dup(0);
+ }
+ }
+
+ /* signal init */
+ signal(SIGPIPE, SIG_IGN);
+
+ if (avserver_daemon)
+ chdir("/");
+
+ if (http_server() < 0) {
+ http_log("Could not start server\n");
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/cmdutils.c b/cmdutils.c
index 943a77c..c5c2c1c 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -35,6 +35,7 @@
#include "libswscale/swscale.h"
#include "libpostproc/postprocess.h"
#include "libavutil/avstring.h"
+#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/eval.h"
@@ -49,22 +50,13 @@
#include <sys/resource.h>
#endif
-const char **opt_names;
-const char **opt_values;
-static int opt_name_count;
-AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
-AVFormatContext *avformat_opts;
struct SwsContext *sws_opts;
-AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts;
+AVDictionary *format_opts, *codec_opts;
static const int this_year = 2011;
void init_opts(void)
{
- int i;
- for (i = 0; i < AVMEDIA_TYPE_NB; i++)
- avcodec_opts[i] = avcodec_alloc_context2(i);
- avformat_opts = avformat_alloc_context();
#if CONFIG_SWSCALE
sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
#endif
@@ -72,30 +64,12 @@ void init_opts(void)
void uninit_opts(void)
{
- int i;
- for (i = 0; i < AVMEDIA_TYPE_NB; i++)
- av_freep(&avcodec_opts[i]);
- av_freep(&avformat_opts->key);
- av_freep(&avformat_opts);
#if CONFIG_SWSCALE
sws_freeContext(sws_opts);
sws_opts = NULL;
#endif
- for (i = 0; i < opt_name_count; i++) {
- //opt_values are only stored for codec-specific options in which case
- //both the name and value are dup'd
- if (opt_values[i]) {
- av_freep(&opt_names[i]);
- av_freep(&opt_values[i]);
- }
- }
- av_freep(&opt_names);
- av_freep(&opt_values);
- opt_name_count = 0;
av_dict_free(&format_opts);
- av_dict_free(&video_opts);
- av_dict_free(&audio_opts);
- av_dict_free(&sub_opts);
+ av_dict_free(&codec_opts);
}
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
@@ -118,17 +92,18 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do
error= "Expected int for %s but found %s\n";
else
return d;
- fprintf(stderr, error, context, numstr, min, max);
- exit(1);
+ av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
+ exit_program(1);
+ return 0;
}
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
{
int64_t us;
if (av_parse_time(&us, timestr, is_duration) < 0) {
- fprintf(stderr, "Invalid %s specification for %s: %s\n",
- is_duration ? "duration" : "date", context, timestr);
- exit(1);
+ av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
+ is_duration ? "duration" : "date", context, timestr);
+ exit_program(1);
}
return us;
}
@@ -156,9 +131,22 @@ void show_help_options(const OptionDef *options, const char *msg, int mask, int
}
}
+void show_help_children(const AVClass *class, int flags)
+{
+ const AVClass *child = NULL;
+ av_opt_show2(&class, NULL, flags, 0);
+ printf("\n");
+
+ while (child = av_opt_child_class_next(class, child))
+ show_help_children(child, flags);
+}
+
static const OptionDef* find_option(const OptionDef *po, const char *name){
+ const char *p = strchr(name, ':');
+ int len = p ? p - name : strlen(name);
+
while (po->name != NULL) {
- if (!strcmp(name, po->name))
+ if (!strncmp(name, po->name, len) && strlen(po->name) == len)
break;
po++;
}
@@ -226,12 +214,81 @@ static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
}
#endif /* WIN32 && !__MINGW32CE__ */
-void parse_options(int argc, char **argv, const OptionDef *options,
- void (* parse_arg_function)(const char*))
+int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options)
{
- const char *opt, *arg;
- int optindex, handleoptions=1;
const OptionDef *po;
+ int bool_val = 1;
+ int *dstcount;
+ void *dst;
+
+ po = find_option(options, opt);
+ if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
+ /* handle 'no' bool option */
+ po = find_option(options, opt + 2);
+ if (!(po->name && (po->flags & OPT_BOOL)))
+ goto unknown_opt;
+ bool_val = 0;
+ }
+ if (!po->name)
+ po = find_option(options, "default");
+ if (!po->name) {
+unknown_opt:
+ av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
+ return AVERROR(EINVAL);
+ }
+ if (po->flags & HAS_ARG && !arg) {
+ av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
+ return AVERROR(EINVAL);
+ }
+
+ /* new-style options contain an offset into optctx, old-style address of
+ * a global var*/
+ dst = po->flags & (OPT_OFFSET|OPT_SPEC) ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr;
+
+ if (po->flags & OPT_SPEC) {
+ SpecifierOpt **so = dst;
+ char *p = strchr(opt, ':');
+
+ dstcount = (int*)(so + 1);
+ *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1);
+ (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : "");
+ dst = &(*so)[*dstcount - 1].u;
+ }
+
+ if (po->flags & OPT_STRING) {
+ char *str;
+ str = av_strdup(arg);
+ *(char**)dst = str;
+ } else if (po->flags & OPT_BOOL) {
+ *(int*)dst = bool_val;
+ } else if (po->flags & OPT_INT) {
+ *(int*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
+ } else if (po->flags & OPT_INT64) {
+ *(int64_t*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
+ } else if (po->flags & OPT_TIME) {
+ *(int64_t*)dst = parse_time_or_die(opt, arg, 1);
+ } else if (po->flags & OPT_FLOAT) {
+ *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
+ } else if (po->flags & OPT_DOUBLE) {
+ *(double*)dst = parse_number_or_die(opt, arg, OPT_DOUBLE, -INFINITY, INFINITY);
+ } else if (po->u.func_arg) {
+ int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg) :
+ po->u.func_arg(opt, arg);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Failed to set value '%s' for option '%s'\n", arg, opt);
+ return ret;
+ }
+ }
+ if (po->flags & OPT_EXIT)
+ exit_program(0);
+ return !!(po->flags & HAS_ARG);
+}
+
+void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
+ void (* parse_arg_function)(void *, const char*))
+{
+ const char *opt;
+ int optindex, handleoptions = 1, ret;
/* perform system-dependent conversions for arguments list */
prepare_app_arguments(&argc, &argv);
@@ -242,159 +299,92 @@ void parse_options(int argc, char **argv, const OptionDef *options,
opt = argv[optindex++];
if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
- int bool_val = 1;
if (opt[1] == '-' && opt[2] == '\0') {
handleoptions = 0;
continue;
}
opt++;
- po= find_option(options, opt);
- if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
- /* handle 'no' bool option */
- po = find_option(options, opt + 2);
- if (!(po->name && (po->flags & OPT_BOOL)))
- goto unknown_opt;
- bool_val = 0;
- }
- if (!po->name)
- po= find_option(options, "default");
- if (!po->name) {
-unknown_opt:
- fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
- exit(1);
- }
- arg = NULL;
- if (po->flags & HAS_ARG) {
- arg = argv[optindex++];
- if (!arg) {
- fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
- exit(1);
- }
- }
- if (po->flags & OPT_STRING) {
- char *str;
- str = av_strdup(arg);
- *po->u.str_arg = str;
- } else if (po->flags & OPT_BOOL) {
- *po->u.int_arg = bool_val;
- } else if (po->flags & OPT_INT) {
- *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
- } else if (po->flags & OPT_INT64) {
- *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
- } else if (po->flags & OPT_FLOAT) {
- *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
- } else if (po->u.func_arg) {
- if (po->u.func_arg(opt, arg) < 0) {
- fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
- exit(1);
- }
- }
- if(po->flags & OPT_EXIT)
- exit(0);
+
+ if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
+ exit_program(1);
+ optindex += ret;
} else {
if (parse_arg_function)
- parse_arg_function(opt);
+ parse_arg_function(optctx, opt);
}
}
}
-#define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
-#define SET_PREFIXED_OPTS(ch, flag, output) \
- if (opt[0] == ch && avcodec_opts[0] && (o = av_opt_find(avcodec_opts[0], opt+1, NULL, flag, 0)))\
- av_dict_set(&output, opt+1, arg, FLAGS);
-static int opt_default2(const char *opt, const char *arg)
+/*
+ * Return index of option opt in argv or 0 if not found.
+ */
+static int locate_option(int argc, char **argv, const OptionDef *options, const char *optname)
+{
+ const OptionDef *po;
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ const char *cur_opt = argv[i];
+
+ if (*cur_opt++ != '-')
+ continue;
+
+ po = find_option(options, cur_opt);
+ if (!po->name && cur_opt[0] == 'n' && cur_opt[1] == 'o')
+ po = find_option(options, cur_opt + 2);
+
+ if ((!po->name && !strcmp(cur_opt, optname)) ||
+ (po->name && !strcmp(optname, po->name)))
+ return i;
+
+ if (!po || po->flags & HAS_ARG)
+ i++;
+ }
+ return 0;
+}
+
+void parse_loglevel(int argc, char **argv, const OptionDef *options)
+{
+ int idx = locate_option(argc, argv, options, "loglevel");
+ if (!idx)
+ idx = locate_option(argc, argv, options, "v");
+ if (idx && argv[idx + 1])
+ opt_loglevel("loglevel", argv[idx + 1]);
+}
+
+#define FLAGS (o->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
+int opt_default(const char *opt, const char *arg)
{
const AVOption *o;
- if ((o = av_opt_find(avcodec_opts[0], opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
- if (o->flags & AV_OPT_FLAG_VIDEO_PARAM)
- av_dict_set(&video_opts, opt, arg, FLAGS);
- if (o->flags & AV_OPT_FLAG_AUDIO_PARAM)
- av_dict_set(&audio_opts, opt, arg, FLAGS);
- if (o->flags & AV_OPT_FLAG_SUBTITLE_PARAM)
- av_dict_set(&sub_opts, opt, arg, FLAGS);
- } else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN)))
+ char opt_stripped[128];
+ const char *p;
+ const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc = sws_get_class();
+
+ if (!(p = strchr(opt, ':')))
+ p = opt + strlen(opt);
+ av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
+
+ if ((o = av_opt_find(&cc, opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN|AV_OPT_SEARCH_FAKE_OBJ)) ||
+ ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
+ (o = av_opt_find(&cc, opt+1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
+ av_dict_set(&codec_opts, opt, arg, FLAGS);
+ else if ((o = av_opt_find(&fc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
av_dict_set(&format_opts, opt, arg, FLAGS);
- else if ((o = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
+ else if ((o = av_opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
// XXX we only support sws_flags, not arbitrary sws options
- int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
+ int ret = av_opt_set(sws_opts, opt, arg, 0);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
return ret;
}
}
- if (!o) {
- SET_PREFIXED_OPTS('v', AV_OPT_FLAG_VIDEO_PARAM, video_opts)
- SET_PREFIXED_OPTS('a', AV_OPT_FLAG_AUDIO_PARAM, audio_opts)
- SET_PREFIXED_OPTS('s', AV_OPT_FLAG_SUBTITLE_PARAM, sub_opts)
- }
-
if (o)
return 0;
- fprintf(stderr, "Unrecognized option '%s'\n", opt);
+ av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
return AVERROR_OPTION_NOT_FOUND;
}
-int opt_default(const char *opt, const char *arg){
- int type;
- int ret= 0;
- const AVOption *o= NULL;
- int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
-
- for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){
- const AVOption *o2 = av_opt_find(avcodec_opts[0], opt, NULL, opt_types[type], 0);
- if(o2)
- ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
- }
- if(!o && avformat_opts)
- ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
- if(!o && sws_opts)
- ret = av_set_string3(sws_opts, opt, arg, 1, &o);
- if(!o){
- if (opt[0] == 'a' && avcodec_opts[AVMEDIA_TYPE_AUDIO])
- ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o);
- else if(opt[0] == 'v' && avcodec_opts[AVMEDIA_TYPE_VIDEO])
- ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
- else if(opt[0] == 's' && avcodec_opts[AVMEDIA_TYPE_SUBTITLE])
- ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
- }
- if (o && ret < 0) {
- fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
- exit(1);
- }
- if (!o) {
- AVCodec *p = NULL;
- AVOutputFormat *oformat = NULL;
- while ((p=av_codec_next(p))){
- const AVClass *c = p->priv_class;
- if(c && av_opt_find(&c, opt, NULL, 0, 0))
- break;
- }
- if (!p) {
- while ((oformat = av_oformat_next(oformat))) {
- const AVClass *c = oformat->priv_class;
- if (c && av_opt_find(&c, opt, NULL, 0, 0))
- break;
- }
- }
- }
-
- if ((ret = opt_default2(opt, arg)) < 0)
- return ret;
-
-// av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));
-
- //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this
- opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
- opt_values[opt_name_count]= o ? NULL : av_strdup(arg);
- opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
- opt_names[opt_name_count++]= o ? o->name : av_strdup(opt);
-
- if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug))
- av_log_set_level(AV_LOG_DEBUG);
- return 0;
-}
-
int opt_loglevel(const char *opt, const char *arg)
{
const struct { const char *name; int level; } log_levels[] = {
@@ -420,11 +410,11 @@ int opt_loglevel(const char *opt, const char *arg)
level = strtol(arg, &tail, 10);
if (*tail) {
- fprintf(stderr, "Invalid loglevel \"%s\". "
- "Possible levels are numbers or:\n", arg);
+ av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
+ "Possible levels are numbers or:\n", arg);
for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
- fprintf(stderr, "\"%s\"\n", log_levels[i].name);
- exit(1);
+ av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
+ exit_program(1);
}
av_log_set_level(level);
return 0;
@@ -438,43 +428,11 @@ int opt_timelimit(const char *opt, const char *arg)
if (setrlimit(RLIMIT_CPU, &rl))
perror("setrlimit");
#else
- fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
+ av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
#endif
return 0;
}
-void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec)
-{
- int i;
- void *priv_ctx=NULL;
- if(!strcmp("AVCodecContext", (*(AVClass**)ctx)->class_name)){
- AVCodecContext *avctx= ctx;
- if(codec && codec->priv_class && avctx->priv_data){
- priv_ctx= avctx->priv_data;
- }
- } else if (!strcmp("AVFormatContext", (*(AVClass**)ctx)->class_name)) {
- AVFormatContext *avctx = ctx;
- if (avctx->oformat && avctx->oformat->priv_class) {
- priv_ctx = avctx->priv_data;
- }
- }
-
- for(i=0; i<opt_name_count; i++){
- char buf[256];
- const AVOption *opt;
- 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_string3(ctx, opt_names[i], str, 1, NULL);
- /* We need to use a differnt system to pass options to the private context because
- it is not known which codec and thus context kind that will be when parsing options
- we thus use opt_values directly instead of opts_ctx */
- if(!str && priv_ctx && av_get_string(priv_ctx, opt_names[i], &opt, buf, sizeof(buf))){
- av_set_string3(priv_ctx, opt_names[i], opt_values[i], 1, NULL);
- }
- }
-}
-
void print_error(const char *filename, int err)
{
char errbuf[128];
@@ -482,7 +440,7 @@ void print_error(const char *filename, int err)
if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
errbuf_ptr = strerror(AVUNERROR(err));
- fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
+ av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
}
static int warned_cfg = 0;
@@ -491,58 +449,59 @@ static int warned_cfg = 0;
#define SHOW_VERSION 2
#define SHOW_CONFIG 4
-#define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags) \
+#define PRINT_LIB_INFO(libname, LIBNAME, flags, level) \
if (CONFIG_##LIBNAME) { \
const char *indent = flags & INDENT? " " : ""; \
if (flags & SHOW_VERSION) { \
unsigned int version = libname##_version(); \
- fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
- indent, #libname, \
- LIB##LIBNAME##_VERSION_MAJOR, \
- LIB##LIBNAME##_VERSION_MINOR, \
- LIB##LIBNAME##_VERSION_MICRO, \
- version >> 16, version >> 8 & 0xff, version & 0xff); \
+ av_log(NULL, level, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n",\
+ indent, #libname, \
+ LIB##LIBNAME##_VERSION_MAJOR, \
+ LIB##LIBNAME##_VERSION_MINOR, \
+ LIB##LIBNAME##_VERSION_MICRO, \
+ version >> 16, version >> 8 & 0xff, version & 0xff); \
} \
if (flags & SHOW_CONFIG) { \
const char *cfg = libname##_configuration(); \
if (strcmp(LIBAV_CONFIGURATION, cfg)) { \
if (!warned_cfg) { \
- fprintf(outstream, \
+ av_log(NULL, level, \
"%sWARNING: library configuration mismatch\n", \
indent); \
warned_cfg = 1; \
} \
- fprintf(stderr, "%s%-11s configuration: %s\n", \
+ av_log(NULL, level, "%s%-11s configuration: %s\n", \
indent, #libname, cfg); \
} \
} \
} \
-static void print_all_libs_info(FILE* outstream, int flags)
+static void print_all_libs_info(int flags, int level)
{
- PRINT_LIB_INFO(outstream, avutil, AVUTIL, flags);
- PRINT_LIB_INFO(outstream, avcodec, AVCODEC, flags);
- PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
- PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
- PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
- PRINT_LIB_INFO(outstream, swscale, SWSCALE, flags);
- PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
+ PRINT_LIB_INFO(avutil, AVUTIL, flags, level);
+ PRINT_LIB_INFO(avcodec, AVCODEC, flags, level);
+ PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
+ PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
+ PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
+ PRINT_LIB_INFO(swscale, SWSCALE, flags, level);
+ PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
}
void show_banner(void)
{
- fprintf(stderr, "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
- program_name, program_birth_year, this_year);
- fprintf(stderr, " built on %s %s with %s %s\n",
- __DATE__, __TIME__, CC_TYPE, CC_VERSION);
- fprintf(stderr, " configuration: " LIBAV_CONFIGURATION "\n");
- print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
- print_all_libs_info(stderr, INDENT|SHOW_VERSION);
+ av_log(NULL, AV_LOG_INFO, "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
+ program_name, program_birth_year, this_year);
+ av_log(NULL, AV_LOG_INFO, " built on %s %s with %s %s\n",
+ __DATE__, __TIME__, CC_TYPE, CC_VERSION);
+ av_log(NULL, AV_LOG_VERBOSE, " configuration: " LIBAV_CONFIGURATION "\n");
+ print_all_libs_info(INDENT|SHOW_CONFIG, AV_LOG_VERBOSE);
+ print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_VERBOSE);
}
void show_version(void) {
+ av_log_set_callback(log_callback_help);
printf("%s " LIBAV_VERSION "\n", program_name);
- print_all_libs_info(stdout, SHOW_VERSION);
+ print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
}
void show_license(void)
@@ -807,6 +766,15 @@ void show_pix_fmts(void)
}
}
+int show_sample_fmts(const char *opt, const char *arg)
+{
+ int i;
+ char fmt_str[128];
+ for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
+ printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
+ return 0;
+}
+
int read_yesno(void)
{
int c = getchar();
@@ -818,12 +786,13 @@ int read_yesno(void)
return yesno;
}
-int read_file(const char *filename, char **bufptr, size_t *size)
+int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
{
+ int ret;
FILE *f = fopen(filename, "rb");
if (!f) {
- fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
+ av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename, strerror(errno));
return AVERROR(errno);
}
fseek(f, 0, SEEK_END);
@@ -831,15 +800,26 @@ int read_file(const char *filename, char **bufptr, size_t *size)
fseek(f, 0, SEEK_SET);
*bufptr = av_malloc(*size + 1);
if (!*bufptr) {
- fprintf(stderr, "Could not allocate file buffer\n");
+ av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
fclose(f);
return AVERROR(ENOMEM);
}
- fread(*bufptr, 1, *size, f);
- (*bufptr)[*size++] = '\0';
+ ret = fread(*bufptr, 1, *size, f);
+ if (ret < *size) {
+ av_free(*bufptr);
+ if (ferror(f)) {
+ av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
+ filename, strerror(errno));
+ ret = AVERROR(errno);
+ } else
+ ret = AVERROR_EOF;
+ } else {
+ ret = 0;
+ (*bufptr)[*size++] = '\0';
+ }
fclose(f);
- return 0;
+ return ret;
}
void init_pts_correction(PtsCorrectionContext *ctx)
@@ -874,9 +854,9 @@ FILE *get_preset_file(char *filename, size_t filename_size,
{
FILE *f = NULL;
int i;
- const char *base[3]= { getenv("FFMPEG_DATADIR"),
+ const char *base[3]= { getenv("AVCONV_DATADIR"),
getenv("HOME"),
- FFMPEG_DATADIR,
+ AVCONV_DATADIR,
};
if (is_path) {
@@ -886,11 +866,11 @@ FILE *get_preset_file(char *filename, size_t filename_size,
for (i = 0; i < 3 && !f; i++) {
if (!base[i])
continue;
- snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", preset_name);
+ snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", preset_name);
f = fopen(filename, "r");
if (!f && codec_name) {
snprintf(filename, filename_size,
- "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", codec_name, preset_name);
+ "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", codec_name, preset_name);
f = fopen(filename, "r");
}
}
@@ -899,6 +879,115 @@ FILE *get_preset_file(char *filename, size_t filename_size,
return f;
}
+int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
+{
+ if (*spec <= '9' && *spec >= '0') /* opt:index */
+ return strtol(spec, NULL, 0) == st->index;
+ else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' || *spec == 't') { /* opt:[vasdt] */
+ enum AVMediaType type;
+
+ switch (*spec++) {
+ case 'v': type = AVMEDIA_TYPE_VIDEO; break;
+ case 'a': type = AVMEDIA_TYPE_AUDIO; break;
+ case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
+ case 'd': type = AVMEDIA_TYPE_DATA; break;
+ case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
+ }
+ if (type != st->codec->codec_type)
+ return 0;
+ if (*spec++ == ':') { /* possibly followed by :index */
+ int i, index = strtol(spec, NULL, 0);
+ for (i = 0; i < s->nb_streams; i++)
+ if (s->streams[i]->codec->codec_type == type && index-- == 0)
+ return i == st->index;
+ return 0;
+ }
+ return 1;
+ } else if (*spec == 'p' && *(spec + 1) == ':') {
+ int prog_id, i, j;
+ char *endptr;
+ spec += 2;
+ prog_id = strtol(spec, &endptr, 0);
+ for (i = 0; i < s->nb_programs; i++) {
+ if (s->programs[i]->id != prog_id)
+ continue;
+
+ if (*endptr++ == ':') {
+ int stream_idx = strtol(endptr, NULL, 0);
+ return (stream_idx >= 0 && stream_idx < s->programs[i]->nb_stream_indexes &&
+ st->index == s->programs[i]->stream_index[stream_idx]);
+ }
+
+ for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
+ if (st->index == s->programs[i]->stream_index[j])
+ return 1;
+ }
+ return 0;
+ } else if (!*spec) /* empty specifier, matches everything */
+ return 1;
+
+ av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
+ return AVERROR(EINVAL);
+}
+
+AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st)
+{
+ AVDictionary *ret = NULL;
+ AVDictionaryEntry *t = NULL;
+ AVCodec *codec = s->oformat ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id);
+ int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
+ char prefix = 0;
+ const AVClass *cc = avcodec_get_class();
+
+ if (!codec)
+ return NULL;
+
+ switch (codec->type) {
+ case AVMEDIA_TYPE_VIDEO: prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM; break;
+ case AVMEDIA_TYPE_AUDIO: prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM; break;
+ case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
+ }
+
+ while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
+ char *p = strchr(t->key, ':');
+
+ /* check stream specification in opt name */
+ if (p)
+ switch (check_stream_specifier(s, st, p + 1)) {
+ case 1: *p = 0; break;
+ case 0: continue;
+ default: return NULL;
+ }
+
+ if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
+ (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ)))
+ av_dict_set(&ret, t->key, t->value, 0);
+ else if (t->key[0] == prefix && av_opt_find(&cc, t->key+1, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ))
+ av_dict_set(&ret, t->key+1, t->value, 0);
+
+ if (p)
+ *p = ':';
+ }
+ return ret;
+}
+
+AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
+{
+ int i;
+ AVDictionary **opts;
+
+ if (!s->nb_streams)
+ return NULL;
+ opts = av_mallocz(s->nb_streams * sizeof(*opts));
+ if (!opts) {
+ av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
+ return NULL;
+ }
+ for (i = 0; i < s->nb_streams; i++)
+ opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, s, s->streams[i]);
+ return opts;
+}
+
#if CONFIG_AVFILTER
static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
@@ -958,8 +1047,28 @@ int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
frame->top_field_first = picref->video->top_field_first;
frame->key_frame = picref->video->key_frame;
frame->pict_type = picref->video->pict_type;
+ frame->sample_aspect_ratio = picref->video->pixel_aspect;
return 1;
}
#endif /* CONFIG_AVFILTER */
+
+void *grow_array(void *array, int elem_size, int *size, int new_size)
+{
+ if (new_size >= INT_MAX / elem_size) {
+ av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
+ exit_program(1);
+ }
+ if (*size < new_size) {
+ uint8_t *tmp = av_realloc(array, new_size*elem_size);
+ if (!tmp) {
+ av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
+ exit_program(1);
+ }
+ memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
+ *size = new_size;
+ return tmp;
+ }
+ return array;
+}
diff --git a/cmdutils.h b/cmdutils.h
index 02fcea4..db75d53 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -39,11 +39,10 @@ extern const char program_name[];
*/
extern const int program_birth_year;
-extern const char **opt_names;
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
extern AVFormatContext *avformat_opts;
extern struct SwsContext *sws_opts;
-extern AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts;
+extern AVDictionary *format_opts, *codec_opts;
/**
* Initialize the cmdutils option system, in particular
@@ -84,7 +83,7 @@ int opt_timelimit(const char *opt, const char *arg);
* parsed or the corresponding value is invalid.
*
* @param context the context of the value to be set (e.g. the
- * corresponding commandline option name)
+ * corresponding command line option name)
* @param numstr the string to be parsed
* @param type the type (OPT_INT64 or OPT_FLOAT) as which the
* string should be parsed
@@ -99,7 +98,7 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do
* the string cannot be correctly parsed.
*
* @param context the context of the value to be set (e.g. the
- * corresponding commandline option name)
+ * corresponding command line option name)
* @param timestr the string to be parsed
* @param is_duration a flag which tells how to interpret timestr, if
* not zero timestr is interpreted as a duration, otherwise as a
@@ -109,6 +108,17 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do
*/
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration);
+typedef struct SpecifierOpt {
+ char *specifier; /**< stream/chapter/program/... specifier */
+ union {
+ uint8_t *str;
+ int i;
+ int64_t i64;
+ float f;
+ double dbl;
+ } u;
+} SpecifierOpt;
+
typedef struct {
const char *name;
int flags;
@@ -125,12 +135,18 @@ typedef struct {
#define OPT_INT64 0x0400
#define OPT_EXIT 0x0800
#define OPT_DATA 0x1000
+#define OPT_FUNC2 0x2000
+#define OPT_OFFSET 0x4000 /* option is specified as an offset in a passed optctx */
+#define OPT_SPEC 0x8000 /* option is to be stored in an array of SpecifierOpt.
+ Implies OPT_OFFSET. Next element after the offset is
+ an int containing element count in the array. */
+#define OPT_TIME 0x10000
+#define OPT_DOUBLE 0x20000
union {
- int *int_arg;
- char **str_arg;
- float *float_arg;
+ void *dst_ptr;
int (*func_arg)(const char *, const char *);
- int64_t *int64_arg;
+ int (*func2_arg)(void *, const char *, const char *);
+ size_t off;
} u;
const char *help;
const char *argname;
@@ -139,17 +155,71 @@ typedef struct {
void show_help_options(const OptionDef *options, const char *msg, int mask, int value);
/**
+ * Show help for all options with given flags in class and all its
+ * children.
+ */
+void show_help_children(const AVClass *class, int flags);
+
+/**
* Parse the command line arguments.
+ *
+ * @param optctx an opaque options context
* @param options Array with the definitions required to interpret every
* option of the form: -option_name [argument]
* @param parse_arg_function Name of the function called to process every
* argument without a leading option name flag. NULL if such arguments do
* not have to be processed.
*/
-void parse_options(int argc, char **argv, const OptionDef *options,
- void (* parse_arg_function)(const char*));
+void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
+ void (* parse_arg_function)(void *optctx, const char*));
+
+/**
+ * Parse one given option.
+ *
+ * @return on success 1 if arg was consumed, 0 otherwise; negative number on error
+ */
+int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options);
+
+/**
+ * Find the '-loglevel' option in the command line args and apply it.
+ */
+void parse_loglevel(int argc, char **argv, const OptionDef *options);
+
+/**
+ * Check if the given stream matches a stream specifier.
+ *
+ * @param s Corresponding format context.
+ * @param st Stream from s to be checked.
+ * @param spec A stream specifier of the [v|a|s|d]:[\<stream index\>] form.
+ *
+ * @return 1 if the stream matches, 0 if it doesn't, <0 on error
+ */
+int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec);
+
+/**
+ * Filter out options for given codec.
+ *
+ * Create a new options dictionary containing only the options from
+ * opts which apply to the codec with ID codec_id.
+ *
+ * @param s Corresponding format context.
+ * @param st A stream from s for which the options should be filtered.
+ * @return a pointer to the created dictionary
+ */
+AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st);
-void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec);
+/**
+ * Setup AVCodecContext options for avformat_find_stream_info().
+ *
+ * Create an array of dictionaries, one dictionary for each stream
+ * contained in s.
+ * Each dictionary will contain the options from codec_opts which can
+ * be applied to the corresponding stream codec context.
+ *
+ * @return pointer to the created array of dictionaries, NULL if it
+ * cannot be created
+ */
+AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts);
/**
* Print an error message to stderr, indicating filename and a human
@@ -219,6 +289,12 @@ void show_protocols(void);
void show_pix_fmts(void);
/**
+ * Print a listing containing all the sample formats supported by the
+ * program.
+ */
+int show_sample_fmts(const char *opt, const char *arg);
+
+/**
* Return a positive value if a line read from standard input
* starts with [yY], otherwise return 0.
*/
@@ -233,7 +309,7 @@ int read_yesno(void);
* @return 0 in case of success, a negative value corresponding to an
* AVERROR error code in case of failure.
*/
-int read_file(const char *filename, char **bufptr, size_t *size);
+int cmdutils_read_file(const char *filename, char **bufptr, size_t *size);
typedef struct {
int64_t num_faulty_pts; /// Number of incorrect PTS values so far
@@ -264,7 +340,7 @@ int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t pts, int64_t dts);
*
* If is_path is non-zero, look for the file in the path preset_name.
* Otherwise search for a file named arg.ffpreset in the directories
- * $FFMPEG_DATADIR (if set), $HOME/.ffmpeg, and in the datadir defined
+ * $AVCONV_DATADIR (if set), $HOME/.avconv, and in the datadir defined
* at configuration time, in that order. If no such file is found and
* codec_name is defined, then search for a file named
* codec_name-preset_name.ffpreset in the above-mentioned directories.
@@ -294,4 +370,20 @@ extern AVFilter ffsink;
int get_filtered_video_frame(AVFilterContext *sink, AVFrame *frame,
AVFilterBufferRef **picref, AVRational *pts_tb);
+/**
+ * Do all the necessary cleanup and abort.
+ * This function is implemented in the avtools, not cmdutils.
+ */
+void exit_program(int ret);
+
+/**
+ * Realloc array to hold new_size elements of elem_size.
+ * Calls exit_program() on failure.
+ *
+ * @param elem_size size in bytes of each element
+ * @param size new element count will be written here
+ * @return reallocated array
+ */
+void *grow_array(void *array, int elem_size, int *size, int new_size);
+
#endif /* LIBAV_CMDUTILS_H */
diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h
index 9b5e5d2..1158afa 100644
--- a/cmdutils_common_opts.h
+++ b/cmdutils_common_opts.h
@@ -10,4 +10,6 @@
{ "protocols", OPT_EXIT, {(void*)show_protocols}, "show available protocols" },
{ "filters", OPT_EXIT, {(void*)show_filters }, "show available filters" },
{ "pix_fmts" , OPT_EXIT, {(void*)show_pix_fmts }, "show available pixel formats" },
+ { "sample_fmts", OPT_EXIT, {.func_arg = show_sample_fmts }, "show available audio sample formats" },
{ "loglevel", HAS_ARG, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" },
+ { "v", HAS_ARG, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" },
diff --git a/common.mak b/common.mak
index e9e69f2..d781ced 100644
--- a/common.mak
+++ b/common.mak
@@ -5,83 +5,46 @@
# first so "all" becomes default target
all: all-yes
-ifndef SUBDIR
-
-ifndef V
-Q = @
-ECHO = printf "$(1)\t%s\n" $(2)
-BRIEF = CC AS YASM AR LD HOSTCC
-SILENT = DEPCC YASMDEP RM RANLIB
-MSG = $@
-M = @$(call ECHO,$(TAG),$@);
-$(foreach VAR,$(BRIEF), \
- $(eval override $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR))))
-$(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))
-$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
-endif
-
-IFLAGS := -I. -I$(SRC_PATH)
-CPPFLAGS := $(IFLAGS) $(CPPFLAGS)
-CFLAGS += $(ECFLAGS)
-YASMFLAGS += $(IFLAGS) -Pconfig.asm
-
-HOSTCFLAGS += $(IFLAGS)
-
-%.o: %.c
- $(CCDEP)
- $(CC) $(CPPFLAGS) $(CFLAGS) $(CC_DEPFLAGS) -c $(CC_O) $<
-
-%.o: %.S
- $(ASDEP)
- $(AS) $(CPPFLAGS) $(ASFLAGS) $(AS_DEPFLAGS) -c -o $@ $<
-
-%.ho: %.h
- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused -c -o $@ -x c $<
-
-%.ver: %.v
- $(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@
-
-%.c %.h: TAG = GEN
-
-# Dummy rule to stop make trying to rebuild removed or renamed headers
-%.h:
- @:
-
-# Disable suffix rules. Most of the builtin rules are suffix rules,
-# so this saves some time on slow systems.
-.SUFFIXES:
-
-endif
-
OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)
OBJS += $(OBJS-yes)
FFLIBS := $(FFLIBS-yes) $(FFLIBS)
TESTPROGS += $(TESTPROGS-yes)
-FFEXTRALIBS := $(addprefix -l,$(addsuffix $(BUILDSUF),$(FFLIBS))) $(EXTRALIBS)
-FFLDFLAGS := $(addprefix -Llib,$(ALLFFLIBS)) $(LDFLAGS)
+FFEXTRALIBS := $(FFLIBS:%=-l%$(BUILDSUF)) $(EXTRALIBS)
-EXAMPLES := $(addprefix $(SUBDIR),$(addsuffix -example$(EXESUF),$(EXAMPLES)))
-OBJS := $(addprefix $(SUBDIR),$(sort $(OBJS)))
-TESTOBJS := $(addprefix $(SUBDIR),$(TESTOBJS) $(TESTPROGS:%=%-test.o))
-TESTPROGS := $(addprefix $(SUBDIR),$(addsuffix -test$(EXESUF),$(TESTPROGS)))
-HOSTOBJS := $(addprefix $(SUBDIR),$(addsuffix .o,$(HOSTPROGS)))
-HOSTPROGS := $(addprefix $(SUBDIR),$(addsuffix $(HOSTEXESUF),$(HOSTPROGS)))
+EXAMPLES := $(EXAMPLES:%=$(SUBDIR)%-example$(EXESUF))
+OBJS := $(sort $(OBJS:%=$(SUBDIR)%))
+TESTOBJS := $(TESTOBJS:%=$(SUBDIR)%) $(TESTPROGS:%=$(SUBDIR)%-test.o)
+TESTPROGS := $(TESTPROGS:%=$(SUBDIR)%-test$(EXESUF))
+HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o)
+HOSTPROGS := $(HOSTPROGS:%=$(SUBDIR)%$(HOSTEXESUF))
+TOOLS += $(TOOLS-yes)
+TOOLOBJS := $(TOOLS:%=tools/%.o)
+TOOLS := $(TOOLS:%=tools/%$(EXESUF))
DEP_LIBS := $(foreach NAME,$(FFLIBS),lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME))
ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h))
-SKIPHEADERS += $(addprefix $(ARCH)/,$(ARCH_HEADERS))
-SKIPHEADERS := $(addprefix $(SUBDIR),$(SKIPHEADERS-) $(SKIPHEADERS))
+SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-)
+SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%)
checkheaders: $(filter-out $(SKIPHEADERS:.h=.ho),$(ALLHEADERS:.h=.ho))
+alltools: $(TOOLS)
+
$(HOSTOBJS): %.o: %.c
$(HOSTCC) $(HOSTCFLAGS) -c -o $@ $<
$(HOSTPROGS): %$(HOSTEXESUF): %.o
$(HOSTCC) $(HOSTLDFLAGS) -o $@ $< $(HOSTLIBS)
+$(OBJS): | $(sort $(dir $(OBJS)))
+$(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
+$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
+$(TOOLOBJS): | tools
+
+OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOSTOBJS) $(TESTOBJS))
+
CLEANSUFFIXES = *.d *.o *~ *.ho *.map *.ver
DISTCLEANSUFFIXES = *.pc
LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a *.exp
diff --git a/configure b/configure
index f4c3274..413c02f 100755
--- a/configure
+++ b/configure
@@ -65,7 +65,7 @@ Standard options:
--disable-logging do not log configure debug information
--prefix=PREFIX install in PREFIX [$prefix]
--bindir=DIR install binaries in DIR [PREFIX/bin]
- --datadir=DIR install data files in DIR [PREFIX/share/ffmpeg]
+ --datadir=DIR install data files in DIR [PREFIX/share/avconv]
--libdir=DIR install libs in DIR [PREFIX/lib]
--shlibdir=DIR install shared libs in DIR [PREFIX/lib]
--incdir=DIR install includes in DIR [PREFIX/include]
@@ -81,9 +81,10 @@ Configuration options:
and binaries will be unredistributable [no]
--disable-doc do not build documentation
--disable-ffmpeg disable ffmpeg build
- --disable-ffplay disable ffplay build
- --disable-ffprobe disable ffprobe build
- --disable-ffserver disable ffserver build
+ --disable-avconv disable avconv build
+ --disable-avplay disable avplay build
+ --disable-avprobe disable avprobe build
+ --disable-avserver disable avserver build
--disable-avdevice disable libavdevice build
--disable-avcodec disable libavcodec build
--disable-avformat disable libavformat build
@@ -91,7 +92,7 @@ Configuration options:
--disable-postproc disable libpostproc build
--disable-avfilter disable video filter support [no]
--disable-pthreads disable pthreads [auto]
- --enable-w32threads use Win32 threads [no]
+ --disable-w32threads disable Win32 threads [auto]
--enable-x11grab enable X11 grabbing [no]
--disable-network disable network support [no]
--enable-gray enable full grayscale support (slower color)
@@ -107,10 +108,14 @@ Configuration options:
--disable-mdct disable MDCT code
--disable-rdft disable RDFT code
--enable-vaapi enable VAAPI code
+ --enable-vda enable VDA code
--enable-vdpau enable VDPAU code
--disable-dxva2 disable DXVA2 code
--enable-runtime-cpudetect detect cpu capabilities at runtime (bigger binary)
--enable-hardcoded-tables use hardcoded tables instead of runtime generation
+ --disable-safe-bitstream-reader
+ disable buffer boundary checking in bitreaders
+ (faster, but may crash)
--enable-memalign-hack emulate memalign, interferes with memory debuggers
--disable-everything disable all components listed below
--disable-encoder=NAME disable encoder NAME
@@ -161,9 +166,11 @@ External library support:
--enable-avisynth enable reading of AVISynth script files [no]
--enable-bzlib enable bzlib [autodetect]
--enable-frei0r enable frei0r video filtering
+ --enable-gnutls enable gnutls [no]
--enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
--enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
--enable-libopencv enable video filtering via libopencv [no]
+ --enable-libcdio enable audio CD grabbing with libcdio
--enable-libdc1394 enable IIDC-1394 grabbing using libdc1394
and libraw1394 [no]
--enable-libdirac enable Dirac support via libdirac [no]
@@ -174,9 +181,10 @@ External library support:
--enable-libnut enable NUT (de)muxing via libnut,
native (de)muxer exists [no]
--enable-libopenjpeg enable JPEG 2000 decoding via OpenJPEG [no]
+ --enable-libpulse enable Pulseaudio input via libpulse [no]
--enable-librtmp enable RTMP[E] support via librtmp [no]
--enable-libschroedinger enable Dirac support via libschroedinger [no]
- --enable-libspeex enable Speex decoding via libspeex [no]
+ --enable-libspeex enable Speex support via libspeex [no]
--enable-libtheora enable Theora encoding via libtheora [no]
--enable-libvo-aacenc enable AAC encoding via libvo-aacenc [no]
--enable-libvo-amrwbenc enable AMR-WB encoding via libvo-amrwbenc [no]
@@ -188,6 +196,7 @@ External library support:
--enable-libxvid enable Xvid encoding via xvidcore,
native MPEG-4/Xvid encoder exists [no]
--enable-mlib enable Sun medialib [no]
+ --enable-openssl enable openssl [no]
--enable-zlib enable zlib [autodetect]
Advanced options (experts only):
@@ -237,6 +246,7 @@ Advanced options (experts only):
--malloc-prefix=PFX prefix malloc and related names with PFX
--enable-sram allow use of on-chip SRAM
--disable-symver disable symbol versioning
+ --optflags override optimization-related compiler flags
Developer options (useful when working on Libav itself):
--disable-debug disable debugging symbols
@@ -874,9 +884,9 @@ apply(){
}
cp_if_changed(){
- cmp -s "$1" "$2" &&
- echo "$2 is unchanged" ||
- cp -f "$1" "$2"
+ cmp -s "$1" "$2" && echo "$2 is unchanged" && return
+ mkdir -p "$(dirname $2)"
+ cp -f "$1" "$2"
}
# CONFIG_LIST contains configurable options, while HAVE_LIST is for
@@ -896,8 +906,17 @@ COMPONENT_LIST="
protocols
"
+PROGRAM_LIST="
+ avconv
+ avplay
+ avprobe
+ avserver
+ ffmpeg
+"
+
CONFIG_LIST="
$COMPONENT_LIST
+ $PROGRAM_LIST
aandct
ac3dsp
avcodec
@@ -911,19 +930,18 @@ CONFIG_LIST="
dwt
dxva2
fastdiv
- ffmpeg
- ffplay
- ffprobe
- ffserver
fft
frei0r
+ gnutls
golomb
gpl
gray
+ h264chroma
h264dsp
h264pred
hardcoded_tables
huffman
+ libcdio
libdc1394
libdirac
libfaac
@@ -935,6 +953,7 @@ CONFIG_LIST="
libopencore_amrwb
libopencv
libopenjpeg
+ libpulse
librtmp
libschroedinger
libspeex
@@ -954,11 +973,13 @@ CONFIG_LIST="
mpegaudiodsp
network
nonfree
+ openssl
pic
postproc
rdft
rtpdec
runtime_cpudetect
+ safe_bitstream_reader
shared
sinewin
small
@@ -966,7 +987,9 @@ CONFIG_LIST="
static
swscale
swscale_alpha
+ thumb
vaapi
+ vda
vdpau
version3
x11grab
@@ -1036,17 +1059,17 @@ HAVE_LIST="
alsa_asoundlib_h
altivec_h
arpa_inet_h
+ asm_mod_y
attribute_may_alias
attribute_packed
- bswap
closesocket
cmov
dcbzl
dev_bktr_ioctl_bt848_h
dev_bktr_ioctl_meteor_h
dev_ic_bt8xx_h
- dev_video_meteor_ioctl_meteor_h
dev_video_bktr_ioctl_bt848_h
+ dev_video_meteor_ioctl_meteor_h
dlfcn_h
dlopen
dos_paths
@@ -1063,9 +1086,9 @@ HAVE_LIST="
gethrtime
GetProcessMemoryInfo
GetProcessTimes
+ GetSystemInfo
getrusage
gnu_as
- struct_rusage_ru_maxrss
ibm_asm
inet_aton
inline_asm
@@ -1091,34 +1114,37 @@ HAVE_LIST="
memalign
mkstemp
mmap
- pld
+ poll_h
posix_memalign
round
roundf
+ sched_getaffinity
sdl
sdl_video_size
setmode
+ setrlimit
sndio_h
socklen_t
soundcard_h
- poll_h
- setrlimit
strerror_r
+ strptime
strtok_r
struct_addrinfo
struct_ipv6_mreq
+ struct_rusage_ru_maxrss
struct_sockaddr_in6
struct_sockaddr_sa_len
struct_sockaddr_storage
symver
- symver_gnu_asm
symver_asm_label
+ symver_gnu_asm
+ sysctl
sys_mman_h
+ sys_param_h
sys_resource_h
sys_select_h
sys_soundcard_h
sys_videoio_h
- ten_operands
threads
trunc
truncf
@@ -1181,6 +1207,7 @@ CMDLINE_SET="
logfile
malloc_prefix
nm
+ optflags
pkg_config
samples
sysinclude
@@ -1227,8 +1254,8 @@ fast_64bit_if_any="alpha ia64 mips64 parisc64 ppc64 sparc64 x86_64"
fast_clz_if_any="alpha armv5te avr32 mips ppc x86"
fast_unaligned_if_any="armv6 ppc x86"
-need_memalign="altivec neon sse"
inline_asm_deps="!tms470"
+need_memalign="altivec neon sse"
symver_if_any="symver_asm_label symver_gnu_asm"
@@ -1268,6 +1295,7 @@ flac_decoder_select="golomb"
flac_encoder_select="golomb lpc"
flashsv_decoder_select="zlib"
flashsv_encoder_select="zlib"
+flashsv2_decoder_select="zlib"
flv_decoder_select="h263_decoder"
flv_encoder_select="h263_encoder"
fraps_decoder_select="huffman"
@@ -1277,10 +1305,11 @@ h263_encoder_select="aandct"
h263_vaapi_hwaccel_select="vaapi h263_decoder"
h263i_decoder_select="h263_decoder"
h263p_encoder_select="h263_encoder"
-h264_decoder_select="golomb h264dsp h264pred"
+h264_decoder_select="golomb h264chroma h264dsp h264pred"
h264_dxva2_hwaccel_deps="dxva2api_h"
h264_dxva2_hwaccel_select="dxva2 h264_decoder"
-h264_vaapi_hwaccel_select="vaapi"
+h264_vaapi_hwaccel_select="vaapi h264_decoder"
+h264_vda_hwaccel_select="vda h264_decoder"
h264_vdpau_decoder_select="vdpau h264_decoder"
imc_decoder_select="fft mdct sinewin"
jpegls_decoder_select="golomb"
@@ -1290,28 +1319,30 @@ loco_decoder_select="golomb"
mjpeg_encoder_select="aandct"
mlp_decoder_select="mlp_parser"
mp1_decoder_select="mpegaudiodsp"
-mp2_decoder_select="mpegaudiodsp"
-mp3adu_decoder_select="mpegaudiodsp"
-mp3_decoder_select="mpegaudiodsp"
-mp3on4_decoder_select="mpegaudiodsp"
mp1float_decoder_select="mpegaudiodsp"
+mp2_decoder_select="mpegaudiodsp"
mp2float_decoder_select="mpegaudiodsp"
+mp3_decoder_select="mpegaudiodsp"
+mp3adu_decoder_select="mpegaudiodsp"
mp3adufloat_decoder_select="mpegaudiodsp"
mp3float_decoder_select="mpegaudiodsp"
+mp3on4_decoder_select="mpegaudiodsp"
mp3on4float_decoder_select="mpegaudiodsp"
-mpeg1video_encoder_select="aandct"
-mpeg2video_encoder_select="aandct"
-mpeg4_decoder_select="h263_decoder mpeg4video_parser"
-mpeg4_encoder_select="h263_encoder"
+mpc7_decoder_select="mpegaudiodsp"
+mpc8_decoder_select="mpegaudiodsp"
mpeg_vdpau_decoder_select="vdpau mpegvideo_decoder"
+mpeg_xvmc_decoder_deps="X11_extensions_XvMClib_h"
+mpeg_xvmc_decoder_select="mpegvideo_decoder"
mpeg1_vdpau_decoder_select="vdpau mpeg1video_decoder"
+mpeg1video_encoder_select="aandct"
mpeg2_dxva2_hwaccel_deps="dxva2api_h"
mpeg2_dxva2_hwaccel_select="dxva2 mpeg2video_decoder"
mpeg2_vaapi_hwaccel_select="vaapi mpeg2video_decoder"
+mpeg2video_encoder_select="aandct"
+mpeg4_decoder_select="h263_decoder mpeg4video_parser"
+mpeg4_encoder_select="h263_encoder"
mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder"
mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder"
-mpeg_xvmc_decoder_deps="X11_extensions_XvMClib_h"
-mpeg_xvmc_decoder_select="mpegvideo_decoder"
msmpeg4v1_decoder_select="h263_decoder"
msmpeg4v1_encoder_select="h263_encoder"
msmpeg4v2_decoder_select="h263_decoder"
@@ -1329,14 +1360,14 @@ rv10_decoder_select="h263_decoder"
rv10_encoder_select="h263_encoder"
rv20_decoder_select="h263_decoder"
rv20_encoder_select="h263_encoder"
-rv30_decoder_select="golomb h264pred"
-rv40_decoder_select="golomb h264pred"
+rv30_decoder_select="golomb h264chroma h264pred"
+rv40_decoder_select="golomb h264chroma h264pred"
shorten_decoder_select="golomb"
sipr_decoder_select="lsp"
snow_decoder_select="dwt"
snow_encoder_select="aandct dwt"
svq1_encoder_select="aandct"
-svq3_decoder_select="golomb h264dsp h264pred"
+svq3_decoder_select="golomb h264chroma h264dsp h264pred"
svq3_decoder_suggest="zlib"
theora_decoder_select="vp3_decoder"
tiff_decoder_suggest="zlib"
@@ -1344,11 +1375,12 @@ tiff_encoder_suggest="zlib"
truehd_decoder_select="mlp_decoder"
tscc_decoder_select="zlib"
twinvq_decoder_select="mdct lsp sinewin"
-vc1_decoder_select="h263_decoder"
+vc1_decoder_select="h263_decoder h264chroma"
vc1_dxva2_hwaccel_deps="dxva2api_h DXVA_PictureParameters_wDecodedPictureIndex"
vc1_dxva2_hwaccel_select="dxva2 vc1_decoder"
vc1_vaapi_hwaccel_select="vaapi vc1_decoder"
vc1_vdpau_decoder_select="vdpau vc1_decoder"
+vc1image_decoder_select="vc1_decoder"
vorbis_decoder_select="mdct"
vorbis_encoder_select="mdct"
vp6_decoder_select="huffman"
@@ -1369,16 +1401,18 @@ wmv3_decoder_select="vc1_decoder"
wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
+wmv3image_decoder_select="wmv3_decoder"
zlib_decoder_select="zlib"
zlib_encoder_select="zlib"
zmbv_decoder_select="zlib"
zmbv_encoder_select="zlib"
vaapi_deps="va_va_h"
+vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
# parsers
-h264_parser_select="golomb h264dsp h264pred"
+h264_parser_select="golomb h264chroma h264dsp h264pred"
# external libraries
libdirac_decoder_deps="libdirac !libschroedinger"
@@ -1396,6 +1430,7 @@ libopenjpeg_decoder_deps="libopenjpeg"
libschroedinger_decoder_deps="libschroedinger"
libschroedinger_encoder_deps="libschroedinger"
libspeex_decoder_deps="libspeex"
+libspeex_encoder_deps="libspeex"
libtheora_encoder_deps="libtheora"
libvo_aacenc_encoder_deps="libvo_aacenc"
libvo_amrwbenc_encoder_deps="libvo_amrwbenc"
@@ -1444,9 +1479,11 @@ bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr
dv1394_indev_deps="dv1394 dv_demuxer"
fbdev_indev_deps="linux_fb_h"
jack_indev_deps="jack_jack_h"
+libcdio_indev_deps="libcdio"
libdc1394_indev_deps="libdc1394"
oss_indev_deps_any="soundcard_h sys_soundcard_h"
oss_outdev_deps_any="soundcard_h sys_soundcard_h"
+pulse_indev_deps="libpulse"
sndio_indev_deps="sndio_h"
sndio_outdev_deps="sndio_h"
v4l_indev_deps="linux_videodev_h"
@@ -1458,18 +1495,25 @@ x11_grab_device_indev_extralibs="-lX11 -lXext -lXfixes"
# protocols
gopher_protocol_deps="network"
+httpproxy_protocol_deps="network"
+httpproxy_protocol_select="tcp_protocol"
http_protocol_deps="network"
http_protocol_select="tcp_protocol"
+https_protocol_select="tls_protocol"
mmsh_protocol_select="http_protocol"
mmst_protocol_deps="network"
rtmp_protocol_select="tcp_protocol"
rtp_protocol_select="udp_protocol"
tcp_protocol_deps="network"
+tls_protocol_deps_any="openssl gnutls"
+tls_protocol_select="tcp_protocol"
udp_protocol_deps="network"
# filters
blackframe_filter_deps="gpl"
+boxblur_filter_deps="gpl"
cropdetect_filter_deps="gpl"
+delogo_filter_deps="gpl"
drawtext_filter_deps="libfreetype"
frei0r_filter_deps="frei0r dlopen strtok_r"
frei0r_src_filter_deps="frei0r dlopen strtok_r"
@@ -1484,13 +1528,13 @@ avformat_deps="avcodec"
postproc_deps="gpl"
# programs
+avconv_deps="avcodec avformat swscale"
+avplay_deps="avcodec avformat swscale sdl"
+avplay_select="rdft"
+avprobe_deps="avcodec avformat"
+avserver_deps="avformat ffm_muxer fork rtp_protocol rtsp_demuxer"
+avserver_extralibs='$ldl'
ffmpeg_deps="avcodec avformat swscale"
-ffmpeg_select="buffer_filter"
-ffplay_deps="avcodec avformat swscale sdl"
-ffplay_select="rdft"
-ffprobe_deps="avcodec avformat"
-ffserver_deps="avformat ffm_muxer fork rtp_protocol rtsp_demuxer"
-ffserver_extralibs='$ldl'
doc_deps="texi2html"
@@ -1509,16 +1553,10 @@ test_deps(){
done
}
-set_ne_test_deps(){
- eval ${1}_be_test_deps="bigendian"
- eval ${1}_le_test_deps="!bigendian"
-}
-
mxf_d10_test_deps="avfilter"
seek_lavf_mxf_d10_test_deps="mxf_d10_test"
test_deps _encoder _decoder \
- adpcm_g726=g726 \
adpcm_ima_qt \
adpcm_ima_wav \
adpcm_ms \
@@ -1529,11 +1567,12 @@ test_deps _encoder _decoder \
asv2 \
bmp \
dnxhd="dnxhd_1080i dnxhd_720p dnxhd_720p_rd" \
- dvvideo="dv dv50" \
+ dvvideo="dv dv_411 dv50" \
ffv1 \
flac \
flashsv \
flv \
+ adpcm_g726=g726 \
gif \
h261 \
h263="h263 h263p" \
@@ -1542,8 +1581,10 @@ test_deps _encoder _decoder \
mjpeg="jpg mjpeg ljpeg" \
mp2 \
mpeg1video="mpeg mpeg1b" \
- mpeg2video="mpeg2 mpeg2thread" \
- mpeg4="mpeg4 mpeg4adv mpeg4nr mpeg4thread error rc" \
+ mpeg2video="mpeg2 mpeg2_422 mpeg2_idct_int mpeg2_ilace mpeg2_ivlc_qprd" \
+ mpeg2video="mpeg2thread mpeg2thread_ilace" \
+ mpeg4="mpeg4 mpeg4_adap mpeg4_qpel mpeg4_qprd mpeg4adv mpeg4nr" \
+ mpeg4="mpeg4thread error rc" \
msmpeg4v3=msmpeg4 \
msmpeg4v2 \
pbm=pbmpipe \
@@ -1593,15 +1634,6 @@ test_deps _muxer _demuxer \
ac3_fixed_test_deps="ac3_fixed_encoder ac3_decoder rm_muxer rm_demuxer"
mpg_test_deps="mpeg1system_muxer mpegps_demuxer"
-set_ne_test_deps pixdesc
-set_ne_test_deps pixfmts_copy
-set_ne_test_deps pixfmts_crop
-set_ne_test_deps pixfmts_hflip
-set_ne_test_deps pixfmts_null
-set_ne_test_deps pixfmts_pad
-set_ne_test_deps pixfmts_scale
-set_ne_test_deps pixfmts_vflip
-
# default parameters
logfile="config.log"
@@ -1609,7 +1641,7 @@ logfile="config.log"
# installation paths
prefix_default="/usr/local"
bindir_default='${prefix}/bin'
-datadir_default='${prefix}/share/ffmpeg'
+datadir_default='${prefix}/share/avconv'
incdir_default='${prefix}/include'
libdir_default='${prefix}/lib'
mandir_default='${prefix}/share/man'
@@ -1626,9 +1658,9 @@ objformat="elf"
pkg_config_default=pkg-config
ranlib="ranlib"
yasmexe="yasm"
-nogas=":"
nm_opts='-g'
+nogas=":"
# machine
arch_default=$(uname -m)
@@ -1639,30 +1671,29 @@ target_os_default=$(tolower $(uname -s))
host_os=$target_os_default
# configurable options
+enable $PROGRAM_LIST
+
enable avcodec
enable avdevice
enable avfilter
enable avformat
enable avutil
+enable postproc
+enable swscale
+
enable asm
enable debug
enable doc
enable fastdiv
-enable ffmpeg
-enable ffplay
-enable ffprobe
-enable ffserver
enable network
enable optimizations
-enable postproc
-enable protocols
+enable safe_bitstream_reader
enable static
-enable swscale
enable swscale_alpha
# build settings
SHFLAGS='-shared -Wl,-soname,$$(@F)'
-FFSERVERLDFLAGS=-Wl,-E
+AVSERVERLDFLAGS=-Wl,-E
LIBPREF="lib"
LIBSUF=".a"
FULLNAME='$(NAME)$(BUILDSUF)'
@@ -1673,7 +1704,10 @@ SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)'
SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)'
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
+SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
+SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
+AS_O='-o $@'
CC_O='-o $@'
host_cflags='-D_ISOC99_SOURCE -O3 -g'
@@ -1688,11 +1722,9 @@ DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -MM'
# find source path
if test -f configure; then
- source_path="$(pwd)"
- disable source_path_used
+ source_path=.
else
source_path=$(cd $(dirname "$0"); pwd)
- enable source_path_used
echo "$source_path" | grep -q '[[:blank:]]' &&
die "Out of tree builds are impossible with whitespace in source path."
test -e "$source_path/config.h" &&
@@ -1725,6 +1757,20 @@ INDEV_LIST=$(find_things indev _IN libavdevice/alldevices.c)
PROTOCOL_LIST=$(find_things protocol PROTOCOL libavformat/allformats.c)
FILTER_LIST=$(find_things filter FILTER libavfilter/allfilters.c)
+ALL_COMPONENTS="
+ $BSF_LIST
+ $DECODER_LIST
+ $DEMUXER_LIST
+ $ENCODER_LIST
+ $FILTER_LIST
+ $HWACCEL_LIST
+ $INDEV_LIST
+ $MUXER_LIST
+ $OUTDEV_LIST
+ $PARSER_LIST
+ $PROTOCOL_LIST
+"
+
find_tests(){
map "echo ${2}\${v}_test" $(ls "$source_path"/tests/ref/$1 | grep -v '[^-a-z0-9_]')
}
@@ -1735,6 +1781,8 @@ LAVF_TESTS=$(find_tests lavf)
LAVFI_TESTS=$(find_tests lavfi)
SEEK_TESTS=$(find_tests seek seek_)
+ALL_TESTS="$ACODEC_TESTS $VCODEC_TESTS $LAVF_TESTS $LAVFI_TESTS $SEEK_TESTS"
+
pcm_test_deps=$(map 'echo ${v%_*}_decoder $v' $(filter pcm_* $ENCODER_LIST))
for n in $COMPONENT_LIST; do
@@ -1743,7 +1791,7 @@ for n in $COMPONENT_LIST; do
eval ${n}_if_any="\$$v"
done
-enable $ARCH_EXT_LIST $ACODEC_TESTS $VCODEC_TESTS $LAVF_TESTS $LAVFI_TESTS $SEEK_TESTS
+enable $ARCH_EXT_LIST $ALL_TESTS
die_unknown(){
echo "Unknown option \"$1\"."
@@ -1876,14 +1924,14 @@ tmpfile(){
trap 'rm -f -- $TMPFILES' EXIT
-tmpfile TMPC .c
-tmpfile TMPE $EXESUF
-tmpfile TMPH .h
-tmpfile TMPO .o
-tmpfile TMPS .S
-tmpfile TMPV .ver
-tmpfile TMPSH .sh
tmpfile TMPASM .asm
+tmpfile TMPC .c
+tmpfile TMPE $EXESUF
+tmpfile TMPH .h
+tmpfile TMPO .o
+tmpfile TMPS .S
+tmpfile TMPSH .sh
+tmpfile TMPV .ver
unset -f mktemp
@@ -1902,9 +1950,9 @@ EOF
die "Sanity test failed."
fi
+filter_asflags=echo
filter_cflags=echo
filter_cppflags=echo
-filter_asflags=echo
if $cc -v 2>&1 | grep -q '^gcc.*LLVM'; then
cc_type=llvm_gcc
@@ -2028,6 +2076,7 @@ elif $cc -V 2>&1 | grep -q Sun; then
cc_ident=$($cc -V 2>&1 | head -n1 | cut -d' ' -f 2-)
DEPEND_CMD='$(DEPCC) $(DEPFLAGS) $< | sed -e "1s,^.*: ,$@: ," -e "\$$!s,\$$, \\\," -e "1!s,^.*: , ," > $(@:.o=.d)'
DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -xM1'
+ add_ldflags -xc99
speed_cflags='-O5'
size_cflags='-O5 -xspace'
filter_cflags=suncc_flags
@@ -2118,7 +2167,7 @@ if test "$cpu" = host; then
gcc|llvm_gcc)
check_native(){
$cc $1=native -v -c -o $TMPO $TMPC >$TMPE 2>&1 || return
- sed -n "/$1=/{
+ sed -n "/cc1.*$1=/{
s/.*$1=\\([^ ]*\\).*/\\1/
p
q
@@ -2233,7 +2282,7 @@ elif enabled x86; then
disable cmov
;;
# targets that do support conditional mov (cmov)
- i686|pentiumpro|pentium[23]|pentium-m|athlon|athlon-tbird|athlon-4|athlon-[mx]p|athlon64|k8|opteron|athlon-fx|core2|amdfam10|barcelona|atom)
+ i686|pentiumpro|pentium[23]|pentium-m|athlon|athlon-tbird|athlon-4|athlon-[mx]p|athlon64*|k8*|opteron*|athlon-fx|core2|amdfam10|barcelona|atom)
cpuflags="-march=$cpu"
enable cmov
enable fast_cmov
@@ -2270,7 +2319,7 @@ elif enabled arm; then
case $cpu in
cortex-a*) subarch=armv7a ;;
cortex-r*) subarch=armv7r ;;
- cortex-m*) subarch=armv7m ;;
+ cortex-m*) enable thumb; subarch=armv7m ;;
arm11*) subarch=armv6 ;;
arm[79]*e*|arm9[24]6*|arm96*|arm102[26]) subarch=armv5te ;;
armv4*|arm7*|arm9[24]*) subarch=armv4 ;;
@@ -2367,11 +2416,17 @@ case $target_os in
host_libs=
;;
sunos)
- FFSERVERLDFLAGS=""
+ AVSERVERLDFLAGS=""
SHFLAGS='-shared -Wl,-h,$$(@F)'
enabled x86 && SHFLAGS="-mimpure-text $SHFLAGS"
network_extralibs="-lsocket -lnsl"
add_cppflags -D__EXTENSIONS__
+ # When using suncc to build, the Solaris linker will mark
+ # an executable with each instruction set encountered by
+ # the Solaris assembler. As our libraries contain their own
+ # guards for processor-specific code, instead suppress
+ # generation of the HWCAPS ELF section on Solaris x86 only.
+ enabled_all suncc x86 && echo "hwcap_1 = OVERRIDE;" > mapfile && add_ldflags -Wl,-M,mapfile
nm_opts='-P -g'
;;
netbsd)
@@ -2412,7 +2467,7 @@ case $target_os in
SLIBSUF=".dylib"
SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME).$(LIBVERSION)$(SLIBSUF)'
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME).$(LIBMAJOR)$(SLIBSUF)'
- FFSERVERLDFLAGS=-Wl,-bind_at_load
+ AVSERVERLDFLAGS=-Wl,-bind_at_load
objformat="macho"
enabled x86_64 && objformat="macho64"
enabled_any pic shared ||
@@ -2436,12 +2491,11 @@ case $target_os in
SLIBSUF=".dll"
SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)'
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
- SLIB_EXTRA_CMD=-'$(DLLTOOL) -m $(LIBTARGET) -d $$(@:$(SLIBSUF)=.def) -l $(SUBDIR)$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.lib) -D $(SLIBNAME_WITH_MAJOR)'
- SLIB_INSTALL_EXTRA_CMD='-install -m 644 $(SUBDIR)$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.lib) "$(SHLIBDIR)/$(SLIBNAME:$(SLIBSUF)=.lib)"; \
- install -m 644 $(SUBDIR)$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.lib) "$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.lib)"; \
- install -d "$(LIBDIR)"; \
- install -m 644 $(SUBDIR)lib$(SLIBNAME:$(SLIBSUF)=.dll.a) "$(LIBDIR)/lib$(SLIBNAME:$(SLIBSUF)=.dll.a)"'
- SLIB_UNINSTALL_EXTRA_CMD='rm -f "$(SHLIBDIR)/$(SLIBNAME:$(SLIBSUF)=.lib)"'
+ SLIB_EXTRA_CMD=-'$(DLLTOOL) -m $(LIBTARGET) -d $$(@:$(SLIBSUF)=.def) -l $(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib) -D $(SLIBNAME_WITH_MAJOR)'
+ SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
+ SLIB_INSTALL_LINKS=
+ SLIB_INSTALL_EXTRA_SHLIB='$(SLIBNAME:$(SLIBSUF)=.lib)'
+ SLIB_INSTALL_EXTRA_LIB='lib$(SLIBNAME:$(SLIBSUF)=.dll.a) $(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.def)'
SHFLAGS='-shared -Wl,--output-def,$$(@:$(SLIBSUF)=.def) -Wl,--out-implib,$(SUBDIR)lib$(SLIBNAME:$(SLIBSUF)=.dll.a) -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-auto-image-base'
objformat="win32"
dlltool="${cross_prefix}dlltool"
@@ -2485,7 +2539,7 @@ case $target_os in
add_cppflags -D_GNU_SOURCE
add_ldflags -Zomf -Zbin-files -Zargs-wild -Zmap
SHFLAGS='$(SUBDIR)$(NAME).def -Zdll -Zomf'
- FFSERVERLDFLAGS=""
+ AVSERVERLDFLAGS=""
LIBSUF="_s.a"
SLIBPREF=""
SLIBSUF=".dll"
@@ -2499,8 +2553,7 @@ case $target_os in
emxexp -o $(OBJS) >> $(SUBDIR)$(NAME).def'
SLIB_EXTRA_CMD='emximp -o $(SUBDIR)$(LIBPREF)$(NAME)_dll.a $(SUBDIR)$(NAME).def; \
emximp -o $(SUBDIR)$(LIBPREF)$(NAME)_dll.lib $(SUBDIR)$(NAME).def;'
- SLIB_INSTALL_EXTRA_CMD='install -m 644 $(SUBDIR)$(LIBPREF)$(NAME)_dll.a $(SUBDIR)$(LIBPREF)$(NAME)_dll.lib "$(LIBDIR)"'
- SLIB_UNINSTALL_EXTRA_CMD='rm -f "$(LIBDIR)"/$(LIBPREF)$(NAME)_dll.a "$(LIBDIR)"/$(LIBPREF)$(NAME)_dll.lib'
+ SLIB_INSTALL_EXTRA_LIB='$(LIBPREF)$(NAME)_dll.a $(LIBPREF)$(NAME)_dll.lib'
enable dos_paths
;;
gnu/kfreebsd)
@@ -2516,7 +2569,14 @@ case $target_os in
symbian)
SLIBSUF=".dll"
enable dos_paths
- add_cflags --include=$sysinclude/gcce/gcce.h
+ add_cflags --include=$sysinclude/gcce/gcce.h -fvisibility=default
+ add_cppflags -D__GCCE__ -D__SYMBIAN32__ -DSYMBIAN_OE_POSIX_SIGNALS
+ add_ldflags -Wl,--target1-abs,--no-undefined \
+ -Wl,-Ttext,0x80000,-Tdata,0x1000000 -shared \
+ -Wl,--entry=_E32Startup -Wl,-u,_E32Startup
+ add_extralibs -l:eexe.lib -l:usrt2_2.lib -l:dfpaeabi.dso \
+ -l:drtaeabi.dso -l:scppnwdl.dso -lsupc++ -lgcc \
+ -l:libc.dso -l:libm.dso -l:euser.dso -l:libcrt0.lib
;;
none)
;;
@@ -2542,18 +2602,18 @@ EOF
exit 1;
fi
-disabled static && LIBNAME=""
-
die_license_disabled() {
enabled $1 || { enabled $2 && die "$2 is $1 and --enable-$1 is not specified."; }
}
+die_license_disabled gpl libcdio
die_license_disabled gpl libx264
die_license_disabled gpl libxavs
die_license_disabled gpl libxvid
die_license_disabled gpl x11grab
die_license_disabled nonfree libfaac
+die_license_disabled nonfree openssl
die_license_disabled version3 libopencore_amrnb
die_license_disabled version3 libopencore_amrwb
@@ -2609,7 +2669,7 @@ if enabled alpha; then
elif enabled arm; then
- check_cflags -marm
+ enabled thumb && check_cflags -mthumb || check_cflags -marm
nogas=die
if check_cpp_condition stddef.h "defined __ARM_PCS_VFP"; then
@@ -2625,9 +2685,6 @@ EOF
warn "Compiler does not indicate floating-point ABI, guessing $fpabi."
fi
- # We have to check if pld is a nop and disable it.
- check_asm pld '"pld [r0]"'
-
enabled armv5te && check_asm armv5te '"qadd r0, r0, r0"'
enabled armv6 && check_asm armv6 '"sadd16 r0, r0, r0"'
enabled armv6t2 && check_asm armv6t2 '"movt r0, #0"'
@@ -2636,6 +2693,8 @@ EOF
enabled neon && check_asm neon '"vadd.i16 q0, q0, q0"'
enabled vfpv3 && check_asm vfpv3 '"vmov.f32 s0, #1.0"'
+ check_asm asm_mod_y '"vmul.i32 d0, d0, %y0" :: "x"(0)'
+
enabled_all armv6t2 shared !pic && enable_pic
elif enabled mips; then
@@ -2704,24 +2763,10 @@ EOF
# check whether xmm clobbers are supported
check_asm xmm_clobbers '"":::"%xmm0"'
- # check whether more than 10 operands are supported
- check_cc <<EOF && enable ten_operands
-int main(void) {
- int x=0;
- __asm__ volatile(
- ""
- :"+&rm"(x), "+&rm"(x), "+&rm"(x), "+&rm"(x), "+&rm"(x), "+&rm"(x)
- );
- return 0;
-}
-EOF
-
# check whether binutils is new enough to compile SSSE3/MMX2
enabled ssse3 && check_asm ssse3 '"pabsw %xmm0, %xmm0"'
enabled mmx2 && check_asm mmx2 '"pmaxub %mm0, %mm1"'
- check_asm bswap '"bswap %%eax" ::: "%eax"'
-
if ! disabled_any asm mmx yasm; then
if check_cmd $yasmexe --version; then
enabled x86_64 && yasm_extra="-m amd64"
@@ -2810,11 +2855,15 @@ check_func mmap
check_func ${malloc_prefix}posix_memalign && enable posix_memalign
check_func setrlimit
check_func strerror_r
+check_func strptime
check_func strtok_r
+check_func sched_getaffinity
+check_func sysctl
check_func_headers io.h setmode
check_func_headers lzo/lzo1x.h lzo1x_999_compress
check_lib2 "windows.h psapi.h" GetProcessMemoryInfo -lpsapi
check_func_headers windows.h GetProcessTimes
+check_func_headers windows.h GetSystemInfo
check_func_headers windows.h MapViewOfFile
check_func_headers windows.h VirtualAlloc
@@ -2823,6 +2872,7 @@ check_header dxva2api.h
check_header malloc.h
check_header poll.h
check_header sys/mman.h
+check_header sys/param.h
check_header sys/resource.h
check_header sys/select.h
check_header vdpau/vdpau.h
@@ -2834,6 +2884,10 @@ check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex
disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib
disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib
+if ! disabled w32threads && ! enabled pthreads; then
+ check_func _beginthreadex && enable w32threads
+fi
+
# check for some common methods of building with pthread support
# do this before the optional library checks as some of them require pthreads
if ! disabled pthreads && ! enabled w32threads; then
@@ -2880,6 +2934,7 @@ check_mathfunc truncf
# these are off by default, so fail if requested and not available
enabled avisynth && require2 vfw32 "windows.h vfw.h" AVIFileInit -lavifil32
enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; }
+enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init
enabled libdirac && require_pkg_config dirac \
"libdirac_decoder/dirac_parser.h libdirac_encoder/dirac_encoder.h" \
"dirac_decoder_init dirac_encoder_init"
@@ -2892,6 +2947,7 @@ enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_de
enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb
enabled libopencv && require_pkg_config opencv opencv/cv.h cvCreateImageHeader
enabled libopenjpeg && require libopenjpeg openjpeg.h opj_version -lopenjpeg
+enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new
enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init
enabled libspeex && require libspeex speex/speex.h speex_decoder_init -lspeex
@@ -2905,11 +2961,15 @@ enabled libvpx && {
enabled libvpx_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_enc_init_ver -lvpx ||
die "ERROR: libvpx encoder version must be >=0.9.1"; } }
enabled libx264 && require libx264 x264.h x264_encoder_encode -lx264 &&
- { check_cpp_condition x264.h "X264_BUILD >= 115" ||
- die "ERROR: libx264 version must be >= 0.115."; }
+ { check_cpp_condition x264.h "X264_BUILD >= 118" ||
+ die "ERROR: libx264 version must be >= 0.118."; }
enabled libxavs && require libxavs xavs.h xavs_encoder_encode -lxavs
enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore
enabled mlib && require mediaLib mlib_types.h mlib_VectorSub_S16_U8_Mod -lmlib
+enabled openssl && { check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto ||
+ check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
+ check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||
+ die "ERROR: openssl not found"; }
# libdc1394 check
if enabled libdc1394; then
@@ -2957,6 +3017,9 @@ enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack
enabled_any sndio_indev sndio_outdev && check_lib2 sndio.h sio_open -lsndio
+enabled libcdio &&
+ check_lib2 "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open "-lcdio_paranoia -lcdio_cdda -lcdio"
+
enabled x11grab &&
check_header X11/Xlib.h &&
check_header X11/extensions/XShm.h &&
@@ -2965,6 +3028,11 @@ check_func XOpenDisplay -lX11 &&
check_func XShmCreateImage -lX11 -lXext &&
check_func XFixesGetCursorImage -lX11 -lXext -lXfixes
+# check for VDA header
+if ! disabled vda && check_header VideoDecodeAcceleration/VDADecoder.h; then
+ enable vda && add_extralibs -framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore
+fi
+
if ! disabled vdpau && enabled vdpau_vdpau_h; then
check_cpp_condition \
vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" ||
@@ -2979,6 +3047,7 @@ check_cflags -Wdeclaration-after-statement
check_cflags -Wall
check_cflags -Wno-parentheses
check_cflags -Wno-switch
+check_cflags -Wno-format-zero-length
check_cflags -Wdisabled-optimization
check_cflags -Wpointer-arith
check_cflags -Wredundant-decls
@@ -2988,11 +3057,12 @@ check_cflags -Wwrite-strings
check_cflags -Wtype-limits
check_cflags -Wundef
check_cflags -Wmissing-prototypes
+check_cflags -Wstrict-prototypes
enabled extra_warnings && check_cflags -Winline
# add some linker flags
check_ldflags -Wl,--warn-common
-check_ldflags -Wl,-rpath-link,libpostproc -Wl,-rpath-link,libswscale -Wl,-rpath-link,libavfilter -Wl,-rpath-link,libavdevice -Wl,-rpath-link,libavformat -Wl,-rpath-link,libavcodec -Wl,-rpath-link,libavutil
+check_ldflags -Wl,-rpath-link=libpostproc:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil
test_ldflags -Wl,-Bsymbolic && append SHFLAGS -Wl,-Bsymbolic
echo "X{};" > $TMPV
@@ -3008,7 +3078,9 @@ void ff_foo(void) {}
EOF
fi
-if enabled small; then
+if [ -n "$optflags" ]; then
+ add_cflags $optflags
+elif enabled small; then
add_cflags $size_cflags
elif enabled optimizations; then
add_cflags $speed_cflags
@@ -3052,6 +3124,7 @@ elif enabled gcc; then
check_cflags -fno-tree-vectorize
check_cflags -Werror=implicit-function-declaration
check_cflags -Werror=missing-prototypes
+ check_cflags -Werror=declaration-after-statement
elif enabled llvm_gcc; then
check_cflags -mllvm -stack-alignment=16
elif enabled clang; then
@@ -3076,22 +3149,8 @@ enabled_any $THREADS_LIST && enable threads
check_deps $CONFIG_LIST \
$CONFIG_EXTRA \
$HAVE_LIST \
- $DECODER_LIST \
- $ENCODER_LIST \
- $HWACCEL_LIST \
- $PARSER_LIST \
- $BSF_LIST \
- $DEMUXER_LIST \
- $MUXER_LIST \
- $FILTER_LIST \
- $INDEV_LIST \
- $OUTDEV_LIST \
- $PROTOCOL_LIST \
- $ACODEC_TESTS \
- $VCODEC_TESTS \
- $LAVF_TESTS \
- $LAVFI_TESTS \
- $SEEK_TESTS \
+ $ALL_COMPONENTS \
+ $ALL_TESTS \
enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; }
@@ -3123,7 +3182,6 @@ if enabled x86; then
echo "CMOV is fast ${fast_cmov-no}"
echo "EBX available ${ebx_available-no}"
echo "EBP available ${ebp_available-no}"
- echo "10 operands supported ${ten_operands-no}"
fi
if enabled arm; then
echo "ARMv5TE enabled ${armv5te-no}"
@@ -3153,10 +3211,16 @@ echo "postprocessing support ${postproc-no}"
echo "new filter support ${avfilter-no}"
echo "network support ${network-no}"
echo "threading support ${thread_type-no}"
+echo "safe bitstream reader ${safe_bitstream_reader-no}"
echo "SDL support ${sdl-no}"
echo "Sun medialib support ${mlib-no}"
+echo "libdxva2 enabled ${dxva2-no}"
+echo "libva enabled ${vaapi-no}"
+echo "libvdpau enabled ${vdpau-no}"
echo "AVISynth enabled ${avisynth-no}"
echo "frei0r enabled ${frei0r-no}"
+echo "gnutls enabled ${gnutls-no}"
+echo "libcdio support ${libcdio-no}"
echo "libdc1394 support ${libdc1394-no}"
echo "libdirac enabled ${libdirac-no}"
echo "libfaac enabled ${libfaac-no}"
@@ -3167,11 +3231,11 @@ echo "libopencore-amrnb support ${libopencore_amrnb-no}"
echo "libopencore-amrwb support ${libopencore_amrwb-no}"
echo "libopencv support ${libopencv-no}"
echo "libopenjpeg enabled ${libopenjpeg-no}"
+echo "libpulse enabled ${libpulse-no}"
echo "librtmp enabled ${librtmp-no}"
echo "libschroedinger enabled ${libschroedinger-no}"
echo "libspeex enabled ${libspeex-no}"
echo "libtheora enabled ${libtheora-no}"
-echo "libva enabled ${vaapi-no}"
echo "libvo-aacenc support ${libvo_aacenc-no}"
echo "libvo-amrwbenc support ${libvo_amrwbenc-no}"
echo "libvorbis enabled ${libvorbis-no}"
@@ -3179,6 +3243,7 @@ echo "libvpx enabled ${libvpx-no}"
echo "libx264 enabled ${libx264-no}"
echo "libxavs enabled ${libxavs-no}"
echo "libxvid enabled ${libxvid-no}"
+echo "openssl enabled ${openssl-no}"
echo "zlib enabled ${zlib-no}"
echo "bzlib enabled ${bzlib-no}"
echo
@@ -3205,51 +3270,12 @@ echo "License: $license"
echo "Creating config.mak and config.h..."
-# build tree in object directory if source path is different from current one
-if enabled source_path_used; then
- DIRS="
- doc
- libavcodec
- libavcodec/$arch
- libavcodec/mlib
- libavdevice
- libavfilter
- libavfilter/$arch
- libavformat
- libavutil
- libavutil/$arch
- libpostproc
- libswscale
- libswscale/$arch
- libswscale/mlib
- tests
- tools
- "
- FILES="
- Makefile
- common.mak
- subdir.mak
- doc/texi2pod.pl
- libavcodec/Makefile
- libavcodec/${arch}/Makefile
- libavdevice/Makefile
- libavfilter/Makefile
- libavfilter/${arch}/Makefile
- libavformat/Makefile
- libavutil/Makefile
- libpostproc/Makefile
- libswscale/Makefile
- "
- map 'mkdir -p $v' $DIRS;
- map 'test -f "$source_path/$v" && $ln_s "$source_path/$v" $v' $FILES
-fi
+test -e Makefile || $ln_s "$source_path/Makefile" .
config_files="$TMPH config.mak"
cat > config.mak <<EOF
# Automatically generated by configure - do not modify!
-ifndef LIBAV_CONFIG_MAK
-LIBAV_CONFIG_MAK=1
LIBAV_CONFIGURATION=$LIBAV_CONFIGURATION
prefix=$prefix
LIBDIR=\$(DESTDIR)$libdir
@@ -3258,8 +3284,7 @@ INCDIR=\$(DESTDIR)$incdir
BINDIR=\$(DESTDIR)$bindir
DATADIR=\$(DESTDIR)$datadir
MANDIR=\$(DESTDIR)$mandir
-SRC_PATH="$source_path"
-SRC_PATH_BARE=$source_path
+SRC_PATH=$source_path
CC_IDENT=$cc_ident
ARCH=$arch
CC=$cc
@@ -3274,10 +3299,11 @@ LN_S=$ln_s
CPPFLAGS=$CPPFLAGS
CFLAGS=$CFLAGS
ASFLAGS=$ASFLAGS
+AS_O=$CC_O
CC_O=$CC_O
DLLTOOL=$dlltool
LDFLAGS=$LDFLAGS
-FFSERVERLDFLAGS=$FFSERVERLDFLAGS
+AVSERVERLDFLAGS=$AVSERVERLDFLAGS
SHFLAGS=$SHFLAGS
YASMFLAGS=$YASMFLAGS
BUILDSUF=$build_suffix
@@ -3312,8 +3338,10 @@ SLIBNAME_WITH_VERSION=${SLIBNAME_WITH_VERSION}
SLIBNAME_WITH_MAJOR=${SLIBNAME_WITH_MAJOR}
SLIB_CREATE_DEF_CMD=${SLIB_CREATE_DEF_CMD}
SLIB_EXTRA_CMD=${SLIB_EXTRA_CMD}
-SLIB_INSTALL_EXTRA_CMD=${SLIB_INSTALL_EXTRA_CMD}
-SLIB_UNINSTALL_EXTRA_CMD=${SLIB_UNINSTALL_EXTRA_CMD}
+SLIB_INSTALL_NAME=${SLIB_INSTALL_NAME}
+SLIB_INSTALL_LINKS=${SLIB_INSTALL_LINKS}
+SLIB_INSTALL_EXTRA_LIB=${SLIB_INSTALL_EXTRA_LIB}
+SLIB_INSTALL_EXTRA_SHLIB=${SLIB_INSTALL_EXTRA_SHLIB}
SAMPLES:=${samples:-\$(FATE_SAMPLES)}
EOF
@@ -3327,13 +3355,13 @@ get_version(){
eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> config.mak
}
-get_version LIBSWSCALE libswscale/swscale.h
-get_version LIBPOSTPROC libpostproc/postprocess.h
get_version LIBAVCODEC libavcodec/version.h
get_version LIBAVDEVICE libavdevice/avdevice.h
+get_version LIBAVFILTER libavfilter/avfilter.h
get_version LIBAVFORMAT libavformat/version.h
get_version LIBAVUTIL libavutil/avutil.h
-get_version LIBAVFILTER libavfilter/avfilter.h
+get_version LIBPOSTPROC libpostproc/postprocess.h
+get_version LIBSWSCALE libswscale/swscale.h
cat > $TMPH <<EOF
/* Automatically generated by configure - do not modify! */
@@ -3341,7 +3369,7 @@ cat > $TMPH <<EOF
#define LIBAV_CONFIG_H
#define LIBAV_CONFIGURATION "$(c_escape $LIBAV_CONFIGURATION)"
#define LIBAV_LICENSE "$(c_escape $license)"
-#define FFMPEG_DATADIR "$(eval c_escape $datadir)"
+#define AVCONV_DATADIR "$(eval c_escape $datadir)"
#define CC_TYPE "$cc_type"
#define CC_VERSION $cc_version
#define restrict $_restrict
@@ -3371,17 +3399,7 @@ print_config ARCH_ "$config_files" $ARCH_LIST
print_config HAVE_ "$config_files" $HAVE_LIST
print_config CONFIG_ "$config_files" $CONFIG_LIST \
$CONFIG_EXTRA \
- $DECODER_LIST \
- $ENCODER_LIST \
- $HWACCEL_LIST \
- $PARSER_LIST \
- $BSF_LIST \
- $DEMUXER_LIST \
- $MUXER_LIST \
- $FILTER_LIST \
- $PROTOCOL_LIST \
- $INDEV_LIST \
- $OUTDEV_LIST \
+ $ALL_COMPONENTS \
cat >>config.mak <<EOF
ACODEC_TESTS=$(print_enabled -n _test $ACODEC_TESTS)
@@ -3392,7 +3410,6 @@ SEEK_TESTS=$(print_enabled -n _test $SEEK_TESTS)
EOF
echo "#endif /* LIBAV_CONFIG_H */" >> $TMPH
-echo "endif # LIBAV_CONFIG_MAK" >> config.mak
# Do not overwrite an unchanged config.h to avoid superfluous rebuilds.
cp_if_changed $TMPH config.h
@@ -3424,6 +3441,7 @@ version=$3
libs=$4
requires=$5
enabled ${name#lib} || return 0
+mkdir -p $name
cat <<EOF > $name/$name.pc
prefix=$prefix
exec_prefix=\${prefix}
@@ -3461,5 +3479,5 @@ pkgconfig_generate libavcodec "Libav codec library" "$LIBAVCODEC_VERSION" "$extr
pkgconfig_generate libavformat "Libav container format library" "$LIBAVFORMAT_VERSION" "$extralibs" "libavcodec = $LIBAVCODEC_VERSION"
pkgconfig_generate libavdevice "Libav device handling library" "$LIBAVDEVICE_VERSION" "$extralibs" "libavformat = $LIBAVFORMAT_VERSION"
pkgconfig_generate libavfilter "Libav video filtering library" "$LIBAVFILTER_VERSION" "$extralibs"
-pkgconfig_generate libpostproc "Libav post processing library" "$LIBPOSTPROC_VERSION" "" "libavutil = $LIBAVUTIL_VERSION"
+pkgconfig_generate libpostproc "Libav postprocessing library" "$LIBPOSTPROC_VERSION" "" "libavutil = $LIBAVUTIL_VERSION"
pkgconfig_generate libswscale "Libav image rescaling library" "$LIBSWSCALE_VERSION" "$LIBM" "libavutil = $LIBAVUTIL_VERSION"
diff --git a/doc/APIchanges b/doc/APIchanges
index 165ea98..29a537d 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,26 +13,152 @@ libavutil: 2011-04-18
API changes, most recent first:
-2011-07-10 - xxxxxxx - lavf 53.3.0
+2011-12-25 - lavfi 2.14.0
+ e1d9dbf Add a new installed header - buffersrc.h
+ It contains a new function av_buffersrc_buffer() that allows passing
+ frames to the 'buffer' filter, but unlike av_vsrc_buffer_add_frame()
+ it allows for direct rendering.
+ 1c9e340 Add avfilter_copy_frame_props() for copying properties from
+ AVFrame to AVFilterBufferRef.
+
+2011-12-25 - lavc 53.31.0
+ Add the following new fields to AVFrame:
+ b58dbb5 sample_aspect_ratio
+ 3a2ddf7 width, height
+ 8a4a5f6 format
+
+2011-12-18 - 8400b12 - lavc 53.28.1
+ Deprecate AVFrame.age. The field is unused.
+
+2011-xx-xx - xxxxxxx - lavf 53.17.0
+ Add avformat_open_input().
+ Deprecate av_close_input_file() and av_close_input_stream().
+
+2011-xx-xx - xxxxxxx - lavc 53.25.0
+ Add nb_samples and extended_data fields to AVFrame.
+ Deprecate AVCODEC_MAX_AUDIO_FRAME_SIZE.
+ Deprecate avcodec_decode_audio3() in favor of avcodec_decode_audio4().
+ avcodec_decode_audio4() writes output samples to an AVFrame, which allows
+ audio decoders to use get_buffer().
+
+2011-xx-xx - xxxxxxx - lavc 53.24.0
+ Change AVFrame.data[4]/base[4]/linesize[4]/error[4] to [8] at next major bump.
+ Change AVPicture.data[4]/linesize[4] to [8] at next major bump.
+ Change AVCodecContext.error[4] to [8] at next major bump.
+ Add AV_NUM_DATA_POINTERS to simplify the bump transition.
+
+2011-11-23 - bbb46f3 - lavu 51.18.0
+ Add av_samples_get_buffer_size(), av_samples_fill_arrays(), and
+ av_samples_alloc(), to samplefmt.h.
+
+2011-11-23 - 8889cc4 - lavu 51.17.0
+ Add planar sample formats and av_sample_fmt_is_planar() to samplefmt.h.
+
+2011-11-19 - f3a29b7 - lavc 53.21.0
+ Move some AVCodecContext fields to a new private struct, AVCodecInternal,
+ which is accessed from a new field, AVCodecContext.internal.
+ - fields moved:
+ AVCodecContext.internal_buffer --> AVCodecInternal.buffer
+ AVCodecContext.internal_buffer_count --> AVCodecInternal.buffer_count
+ AVCodecContext.is_copy --> AVCodecInternal.is_copy
+
+2011-11-16 - 6270671 - lavu 51.16.0
+ Add av_timegm()
+
+2011-11-13 - lavf 53.15.0
+ New interrupt callback API, allowing per-AVFormatContext/AVIOContext
+ interrupt callbacks.
+ 6aa0b98 Add AVIOInterruptCB struct and the interrupt_callback field to
+ AVFormatContext.
+ 1dee0ac Add avio_open2() with additional parameters. Those are
+ an interrupt callback and an options AVDictionary.
+ This will allow passing AVOptions to protocols after lavf
+ 54.0.
+
+2011-11-06 - ba04ecf - lavu 51.14.0
+ Add av_strcasecmp() and av_strncasecmp() to avstring.h.
+
+2011-11-06 - 07b172f - lavu 51.13.0
+ Add av_toupper()/av_tolower()
+
+2011-11-05 - b6d08f4 - lavf 53.13.0
+ Add avformat_network_init()/avformat_network_uninit()
+
+2011-10-27 - 512557b - lavc 53.15.0
+ Remove avcodec_parse_frame.
+ Deprecate AVCodecContext.parse_only and CODEC_CAP_PARSE_ONLY.
+
+2011-10-19 - 569129a - lavf 53.10.0
+ Add avformat_new_stream(). Deprecate av_new_stream().
+
+2011-10-13 - b631fba - lavf 53.9.0
+ Add AVFMT_NO_BYTE_SEEK AVInputFormat flag.
+
+2011-10-12 - lavu 51.12.0
+ AVOptions API rewrite.
+
+ - 145f741 FF_OPT_TYPE* renamed to AV_OPT_TYPE_*
+ - new setting/getting functions with slightly different semantics:
+ dac66da av_set_string3 -> av_opt_set
+ av_set_double -> av_opt_set_double
+ av_set_q -> av_opt_set_q
+ av_set_int -> av_opt_set_int
+
+ 41d9d51 av_get_string -> av_opt_get
+ av_get_double -> av_opt_get_double
+ av_get_q -> av_opt_get_q
+ av_get_int -> av_opt_get_int
+
+ - 8c5dcaa trivial rename av_next_option -> av_opt_next
+ - 641c7af new functions - av_opt_child_next, av_opt_child_class_next
+ and av_opt_find2()
+
+2011-09-03 - fb4ca26 - lavc 53.10.0
+ lavf 53.6.0
+ lsws 2.1.0
+ Add {avcodec,avformat,sws}_get_class().
+
+2011-09-03 - c11fb82 - lavu 51.10.0
+ Add AV_OPT_SEARCH_FAKE_OBJ flag for av_opt_find() function.
+
+2011-08-26 - f2011ed - lavu 51.9.0
+ Add av_fifo_peek2(), deprecate av_fifo_peek().
+
+2011-08-16 - 48f9e45 - lavf 53.4.0
+ Add avformat_query_codec().
+
+2011-08-16 - bca06e7 - lavc 53.8.0
+ Add avcodec_get_type().
+
+2011-08-06 - 2f63440 - lavf 53.4.0
+ Add error_recognition to AVFormatContext.
+
+2011-08-02 - 9d39cbf - lavc 53.7.1
+ Add AV_PKT_FLAG_CORRUPT AVPacket flag.
+
+2011-07-10 - a67c061 - lavf 53.3.0
Add avformat_find_stream_info(), deprecate av_find_stream_info().
-2011-07-10 - xxxxxxx - lavc 53.6.0
+2011-07-10 - 0b950fe - lavc 53.6.0
Add avcodec_open2(), deprecate avcodec_open().
-2011-06-xx - xxxxxxx - lavf 53.2.0 - avformat.h
+2011-06-23 - 67e9ae1 - lavu 51.8.0 - attributes.h
+ Add av_printf_format().
+
+2011-06-16 - 05e84c9, 25de595 - lavf 53.2.0 - avformat.h
Add avformat_open_input and avformat_write_header().
Deprecate av_open_input_stream, av_open_input_file,
AVFormatParameters and av_write_header.
-2011-06-xx - xxxxxxx - lavu 51.7.0 - opt.h
+2011-06-16 - 7e83e1c, dc59ec5 - lavu 51.7.0 - opt.h
Add av_opt_set_dict() and av_opt_find().
Deprecate av_find_opt().
Add AV_DICT_APPEND flag.
-2011-06-xx - xxxxxxx - lavu 51.6.0 - opt.h
+2011-06-10 - cb7c11c - lavu 51.6.0 - opt.h
Add av_opt_flag_is_set().
-2011-06-xx - xxxxxxx - lavu 51.5.0 - AVMetadata
+2011-06-08 - d9f80ea - lavu 51.5.0 - AVMetadata
Move AVMetadata from lavf to lavu and rename it to
AVDictionary -- new installed header dict.h.
All av_metadata_* functions renamed to av_dict_*.
@@ -41,7 +167,7 @@ API changes, most recent first:
Add av_get_bytes_per_sample() in libavutil/samplefmt.h.
Deprecate av_get_bits_per_sample_fmt().
-2011-06-xx - xxxxxxx - lavu 51.3.0 - opt.h
+2011-06-05 - b39b062 - lavu 51.3.0 - opt.h
Add av_opt_free convenience function.
2011-05-28 - 0420bd7 - lavu 51.2.0 - pixdesc.h
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..0acd984
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,53 @@
+MANPAGES = $(PROGS-yes:%=doc/%.1)
+PODPAGES = $(PROGS-yes:%=doc/%.pod)
+HTMLPAGES = $(PROGS-yes:%=doc/%.html) \
+ doc/developer.html \
+ doc/faq.html \
+ doc/fate.html \
+ doc/general.html \
+ doc/git-howto.html \
+ doc/libavfilter.html \
+ doc/platform.html \
+
+DOCS = $(HTMLPAGES) $(MANPAGES) $(PODPAGES)
+
+all-$(CONFIG_DOC): documentation
+
+documentation: $(DOCS)
+
+TEXIDEP = awk '/^@include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d)
+
+doc/%.html: TAG = HTML
+doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.init
+ $(Q)$(TEXIDEP)
+ $(M)texi2html -monolithic --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
+
+doc/%.pod: TAG = POD
+doc/%.pod: doc/%.texi
+ $(Q)$(TEXIDEP)
+ $(M)$(SRC_PATH)/doc/texi2pod.pl $< $@
+
+doc/%.1: TAG = MAN
+doc/%.1: doc/%.pod
+ $(M)pod2man --section=1 --center=" " --release=" " $< > $@
+
+$(DOCS): | doc
+OBJDIRS += doc
+
+install-progs-$(CONFIG_DOC): install-man
+
+install-man: $(MANPAGES)
+ $(Q)mkdir -p "$(MANDIR)/man1"
+ $(INSTALL) -m 644 $(MANPAGES) "$(MANDIR)/man1"
+
+uninstall: uninstall-man
+
+uninstall-man:
+ $(RM) $(addprefix "$(MANDIR)/man1/",$(ALLMANPAGES))
+
+clean::
+ $(RM) doc/*.html doc/*.pod doc/*.1 $(CLEANSUFFIXES:%=doc/%)
+
+-include $(wildcard $(DOCS:%=%.d))
+
+.PHONY: documentation
diff --git a/doc/RELEASE_NOTES b/doc/RELEASE_NOTES
index 97875e9..f857a18 100644
--- a/doc/RELEASE_NOTES
+++ b/doc/RELEASE_NOTES
@@ -1,22 +1,29 @@
Release Notes
=============
-* 0.7 "The Big Bump" June, 2011
+* 0.8 "Forbidden Fruit"
General notes
-------------
-This release enables frame-based multithreaded decoding for a number of codecs,
-including VP8, H.263 and H.264. Additionally, there has been a major cleanup of
-both internal and external APIs. For this reason, the major versions of all
-libraries have been bumped. On the one hand, this means that 0.7 can be installed
-side-by-side with previous releases, on the other hand, in order to benefit
-from the new features, applications need to be recompiled.
-
-Other important changes are additions of decoders including, but not limited to,
-AMR-WB, single stream LATM/LOAS, G.722 ADPCM, a native VP8 decoder
-and HE-AACv2. Additionally, many new de/muxers such as WebM in Matroska, Apple
-HTTP Live Streaming, SAP, IEC 61937 (S/PDIF) have been added.
+This release continues the API cleanups that have begun with the
+previous release. While it is binary compatible with 0.7, many parts of
+the public API were deprecated and will be removed in the git master and
+later releases. Please consult the doc/APIchanges file to see intended
+replacements for the deprecated APIs.
+
+Furthermore, our work on the 'ffmpeg' command-line tool has resulted in
+major revisions to its interface. In order to not break existing scripts
+and applications, we have chosen to introduce a new tool called
+'avconv', and keep the traditional 'ffmpeg' frontend for end-user's
+convenience. Please see the Changelog file for details how 'avconv'
+differs from 'ffmpeg'.
+
+Additionally, this release introduces a number of new interesting codecs
+such as the Apple Prores, Flash Screen Video 2 and Windows Media Image,
+and muxers such as LATM or CELT in Ogg, among many others. Moreover, our
+H.264 decoder has been improved to decode 4:2:2 material and our libx264
+wrapper now allows to produce 4:2:2 and 4:4:4 video.
See the Changelog file for a list of significant changes.
@@ -30,23 +37,14 @@ report against the development code following the usual bug reporting guidelines
API changes
-----------
-Please see the file doc/APIchanges for programmer-centric information. Note that a
-lot of long-time deprecated APIs have been removed. Also, a number of additional
-APIs have been deprecated and are scheduled for removal in the next release.
+A number of additional APIs have been introduced and some existing
+functions have been deprecated and are scheduled for removal in the next
+release. Please see the file doc/APIchanges for details along with
+similar programmer-centric information.
+
Other notable changes
---------------------
-- many ARM NEON optimizations
-- libswscale cleanup started, optimizations should become easier in the future
-- nonfree libfaad support for AAC decoding removed
-- 4:4:4 H.264 decoding
-- 9/10bit H.264 decoding
-- Win64 Assembler support
-- native MMSH/MMST support
-- Windows TV demuxing
-- native AMR-WB decoding
-- native GSM-MS decoding
-- SMPTE 302M decoding
-- AVS encoding
+Please see the Changelog file for a more detailed list of changes.
diff --git a/doc/TODO b/doc/TODO
deleted file mode 100644
index 8ff8a6b..0000000
--- a/doc/TODO
+++ /dev/null
@@ -1,82 +0,0 @@
-ffmpeg TODO list:
-----------------
-
-Fabrice's TODO list: (unordered)
--------------------
-Short term:
-
-- use AVFMTCTX_DISCARD_PKT in ffplay so that DV has a chance to work
-- add RTSP regression test (both client and server)
-- make ffserver allocate AVFormatContext
-- clean up (incompatible change, for 0.5.0):
- * AVStream -> AVComponent
- * AVFormatContext -> AVInputStream/AVOutputStream
- * suppress rate_emu from AVCodecContext
-- add new float/integer audio filterting and conversion : suppress
- CODEC_ID_PCM_xxc and use CODEC_ID_RAWAUDIO.
-- fix telecine and frame rate conversion
-
-Long term (ask me if you want to help):
-
-- commit new imgconvert API and new PIX_FMT_xxx alpha formats
-- commit new LGPL'ed float and integer-only AC3 decoder
-- add WMA integer-only decoder
-- add new MPEG4-AAC audio decoder (both integer-only and float version)
-
-Michael's TODO list: (unordered) (if anyone wanna help with sth, just ask)
--------------------
-- optimize H264 CABAC
-- more optimizations
-- simper rate control
-
-Philip'a TODO list: (alphabetically ordered) (please help)
-------------------
-- Add a multi-ffm filetype so that feeds can be recorded into multiple files rather
- than one big file.
-- Authenticated users support -- where the authentication is in the URL
-- Change ASF files so that the embedded timestamp in the frames is right rather
- than being an offset from the start of the stream
-- Make ffm files more resilient to changes in the codec structures so that you
- can play old ffm files.
-
-Baptiste's TODO list:
------------------
-- mov edit list support (AVEditList)
-- YUV 10 bit per component support "2vuy"
-- mxf muxer
-- mpeg2 non linear quantizer
-
-unassigned TODO: (unordered)
----------------
-- use AVFrame for audio codecs too
-- rework aviobuf.c buffering strategy and fix url_fskip
-- generate optimal huffman tables for mjpeg encoding
-- fix ffserver regression tests
-- support xvids motion estimation
-- support x264s motion estimation
-- support x264s rate control
-- SNOW: non translational motion compensation
-- SNOW: more optimal quantization
-- SNOW: 4x4 block support
-- SNOW: 1/8 pel motion compensation support
-- SNOW: iterative motion estimation based on subsampled images
-- SNOW: try B frames and MCTF and see how their PSNR/bitrate/complexity behaves
-- SNOW: try to use the wavelet transformed MC-ed reference frame as context for the entropy coder
-- SNOW: think about/analyize how to make snow use multiple cpus/threads
-- SNOW: finish spec
-- FLAC: lossy encoding (viterbi and naive scalar quantization)
-- libavfilter
-- JPEG2000 decoder & encoder
-- MPEG4 GMC encoding support
-- macroblock based pixel format (better cache locality, somewhat complex, one paper claimed it faster for high res)
-- regression tests for codecs which do not have an encoder (I+P-frame bitstream in the 'master' branch)
-- add support for using mplayers video filters to ffmpeg
-- H264 encoder
-- per MB ratecontrol (so VCD and such do work better)
-- write a script which iteratively changes all functions between always_inline and noinline and benchmarks the result to find the best set of inlined functions
-- convert all the non SIMD asm into small asm vs. C testcases and submit them to the gcc devels so they can improve gcc
-- generic audio mixing API
-- extract PES packetizer from PS muxer and use it for new TS muxer
-- implement automatic AVBistreamFilter activation
-- make cabac encoder use bytestream (see http://trac.videolan.org/x264/changeset/?format=diff&new=651)
-- merge imdct and windowing, the current code does considerable amounts of redundant work
diff --git a/doc/avconv.texi b/doc/avconv.texi
new file mode 100644
index 0000000..157e233
--- /dev/null
+++ b/doc/avconv.texi
@@ -0,0 +1,1059 @@
+\input texinfo @c -*- texinfo -*-
+
+ at settitle avconv Documentation
+ at titlepage
+ at center @titlefont{avconv Documentation}
+ at end titlepage
+
+ at top
+
+ at contents
+
+ at chapter Synopsis
+
+The generic syntax is:
+
+ at example
+ at c man begin SYNOPSIS
+avconv [global options] [[infile options][@option{-i} @var{infile}]]... @{[outfile options] @var{outfile}@}...
+ at c man end
+ at end example
+
+ at chapter Description
+ at c man begin DESCRIPTION
+
+avconv is a very fast video and audio converter that can also grab from
+a live audio/video source. It can also convert between arbitrary sample
+rates and resize video on the fly with a high quality polyphase filter.
+
+avconv reads from an arbitrary number of input "files" (which can be regular
+files, pipes, network streams, grabbing devices, etc.), specified by the
+ at code{-i} option, and writes to an arbitrary number of output "files", which are
+specified by a plain output filename. Anything found on the command line which
+cannot be interpreted as an option is considered to be an output filename.
+
+Each input or output file can in principle contain any number of streams of
+different types (video/audio/subtitle/attachment/data). Allowed number and/or
+types of streams can be limited by the container format. Selecting, which
+streams from which inputs go into output, is done either automatically or with
+the @code{-map} option (see the Stream selection chapter).
+
+To refer to input files in options, you must use their indices (0-based). E.g.
+the first input file is @code{0}, the second is @code{1} etc. Similarly, streams
+within a file are referred to by their indices. E.g. @code{2:3} refers to the
+fourth stream in the third input file. See also the Stream specifiers chapter.
+
+As a general rule, options are applied to the next specified
+file. Therefore, order is important, and you can have the same
+option on the command line multiple times. Each occurrence is
+then applied to the next input or output file.
+Exceptions from this rule are the global options (e.g. verbosity level),
+which should be specified first.
+
+Do not mix input and output files -- first specify all input files, then all
+output files. Also do not mix options which belong to different files. All
+options apply ONLY to the next input or output file and are reset between files.
+
+ at itemize
+ at item
+To set the video bitrate of the output file to 64kbit/s:
+ at example
+avconv -i input.avi -b 64k output.avi
+ at end example
+
+ at item
+To force the frame rate of the output file to 24 fps:
+ at example
+avconv -i input.avi -r 24 output.avi
+ at end example
+
+ at item
+To force the frame rate of the input file (valid for raw formats only)
+to 1 fps and the frame rate of the output file to 24 fps:
+ at example
+avconv -r 1 -i input.m2v -r 24 output.avi
+ at end example
+ at end itemize
+
+The format option may be needed for raw input files.
+
+ at c man end DESCRIPTION
+
+ at chapter Stream selection
+ at c man begin STREAM SELECTION
+
+By default avconv tries to pick the "best" stream of each type present in input
+files and add them to each output file. For video, this means the highest
+resolution, for audio the highest channel count. For subtitle it's simply the
+first subtitle stream.
+
+You can disable some of those defaults by using @code{-vn/-an/-sn} options. For
+full manual control, use the @code{-map} option, which disables the defaults just
+described.
+
+ at c man end STREAM SELECTION
+
+ at chapter Options
+ at c man begin OPTIONS
+
+ at include avtools-common-opts.texi
+
+ at section Main options
+
+ at table @option
+
+ at item -f @var{fmt} (@emph{input/output})
+Force input or output file format. The format is normally autodetected for input
+files and guessed from file extension for output files, so this option is not
+needed in most cases.
+
+ at item -i @var{filename} (@emph{input})
+input file name
+
+ at item -y (@emph{global})
+Overwrite output files without asking.
+
+ at item -c[:@var{stream_specifier}] @var{codec} (@emph{input/output,per-stream})
+ at itemx -codec[:@var{stream_specifier}] @var{codec} (@emph{input/output,per-stream})
+Select an encoder (when used before an output file) or a decoder (when used
+before an input file) for one or more streams. @var{codec} is the name of a
+decoder/encoder or a special value @code{copy} (output only) to indicate that
+the stream is not to be reencoded.
+
+For example
+ at example
+avconv -i INPUT -map 0 -c:v libx264 -c:a copy OUTPUT
+ at end example
+encodes all video streams with libx264 and copies all audio streams.
+
+For each stream, the last matching @code{c} option is applied, so
+ at example
+avconv -i INPUT -map 0 -c copy -c:v:1 libx264 -c:a:137 libvorbis OUTPUT
+ at end example
+will copy all the streams except the second video, which will be encoded with
+libx264, and the 138th audio, which will be encoded with libvorbis.
+
+ at item -t @var{duration} (@emph{output})
+Stop writing the output after its duration reaches @var{duration}.
+ at var{duration} may be a number in seconds, or in @code{hh:mm:ss[.xxx]} form.
+
+ at item -fs @var{limit_size} (@emph{output})
+Set the file size limit.
+
+ at item -ss @var{position} (@emph{input/output})
+When used as an input option (before @code{-i}), seeks in this input file to
+ at var{position}. When used as an output option (before an output filename),
+decodes but discards input until the timestamps reach @var{position}. This is
+slower, but more accurate.
+
+ at var{position} may be either in seconds or in @code{hh:mm:ss[.xxx]} form.
+
+ at item -itsoffset @var{offset} (@emph{input})
+Set the input time offset in seconds.
+ at code{[-]hh:mm:ss[.xxx]} syntax is also supported.
+The offset is added to the timestamps of the input files.
+Specifying a positive offset means that the corresponding
+streams are delayed by @var{offset} seconds.
+
+ at item -metadata[:metadata_specifier] @var{key}=@var{value} (@emph{output,per-metadata})
+Set a metadata key/value pair.
+
+An optional @var{metadata_specifier} may be given to set metadata
+on streams or chapters. See @code{-map_metadata} documentation for
+details.
+
+This option overrides metadata set with @code{-map_metadata}. It is
+also possible to delete metadata by using an empty value.
+
+For example, for setting the title in the output file:
+ at example
+avconv -i in.avi -metadata title="my title" out.flv
+ at end example
+
+To set the language of the first audio stream:
+ at example
+avconv -i INPUT -metadata:s:a:0 language=eng OUTPUT
+ at end example
+
+ at item -target @var{type} (@emph{output})
+Specify target file type (@code{vcd}, @code{svcd}, @code{dvd}, @code{dv},
+ at code{dv50}). @var{type} may be prefixed with @code{pal-}, @code{ntsc-} or
+ at code{film-} to use the corresponding standard. All the format options
+(bitrate, codecs, buffer sizes) are then set automatically. You can just type:
+
+ at example
+avconv -i myfile.avi -target vcd /tmp/vcd.mpg
+ at end example
+
+Nevertheless you can specify additional options as long as you know
+they do not conflict with the standard, as in:
+
+ at example
+avconv -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg
+ at end example
+
+ at item -dframes @var{number} (@emph{output})
+Set the number of data frames to record. This is an alias for @code{-frames:d}.
+
+ at item -frames[:@var{stream_specifier}] @var{framecount} (@emph{output,per-stream})
+Stop writing to the stream after @var{framecount} frames.
+
+ at item -q[:@var{stream_specifier}] @var{q} (@emph{output,per-stream})
+ at itemx -qscale[:@var{stream_specifier}] @var{q} (@emph{output,per-stream})
+Use fixed quality scale (VBR). The meaning of @var{q} is
+codec-dependent.
+
+ at item -filter[:@var{stream_specifier}] @var{filter_graph} (@emph{output,per-stream})
+ at var{filter_graph} is a description of the filter graph to apply to
+the stream. Use @code{-filters} to show all the available filters
+(including also sources and sinks).
+ at item -pre[:@var{stream_specifier}] @var{preset_name} (@emph{output,per-stream})
+Specify the preset for matching stream(s).
+
+ at item -stats (@emph{global})
+Print encoding progress/statistics. On by default.
+
+ at item -attach @var{filename} (@emph{output})
+Add an attachment to the output file. This is supported by a few formats
+like Matroska for e.g. fonts used in rendering subtitles. Attachments
+are implemented as a specific type of stream, so this option will add
+a new stream to the file. It is then possible to use per-stream options
+on this stream in the usual way. Attachment streams created with this
+option will be created after all the other streams (i.e. those created
+with @code{-map} or automatic mappings).
+
+Note that for Matroska you also have to set the mimetype metadata tag:
+ at example
+avconv -i INPUT -attach DejaVuSans.ttf -metadata:s:2 mimetype=application/x-truetype-font out.mkv
+ at end example
+(assuming that the attachment stream will be third in the output file).
+
+ at item -dump_attachment[:@var{stream_specifier}] @var{filename} (@emph{input,per-stream})
+Extract the matching attachment stream into a file named @var{filename}. If
+ at var{filename} is empty, then the value of the @code{filename} metadata tag
+will be used.
+
+E.g. to extract the first attachment to a file named 'out.ttf':
+ at example
+avconv -dump_attachment:t:0 out.ttf INPUT
+ at end example
+To extract all attachments to files determined by the @code{filename} tag:
+ at example
+avconv -dump_attachment:t "" INPUT
+ at end example
+
+Technical note -- attachments are implemented as codec extradata, so this
+option can actually be used to extract extradata from any stream, not just
+attachments.
+
+ at end table
+
+ at section Video Options
+
+ at table @option
+ at item -vframes @var{number} (@emph{output})
+Set the number of video frames to record. This is an alias for @code{-frames:v}.
+ at item -r[:@var{stream_specifier}] @var{fps} (@emph{input/output,per-stream})
+Set frame rate (Hz value, fraction or abbreviation), (default = 25).
+ at item -s[:@var{stream_specifier}] @var{size} (@emph{input/output,per-stream})
+Set frame size. The format is @samp{wxh} (default - same as source).
+The following abbreviations are recognized:
+ at table @samp
+ at item sqcif
+128x96
+ at item qcif
+176x144
+ at item cif
+352x288
+ at item 4cif
+704x576
+ at item 16cif
+1408x1152
+ at item qqvga
+160x120
+ at item qvga
+320x240
+ at item vga
+640x480
+ at item svga
+800x600
+ at item xga
+1024x768
+ at item uxga
+1600x1200
+ at item qxga
+2048x1536
+ at item sxga
+1280x1024
+ at item qsxga
+2560x2048
+ at item hsxga
+5120x4096
+ at item wvga
+852x480
+ at item wxga
+1366x768
+ at item wsxga
+1600x1024
+ at item wuxga
+1920x1200
+ at item woxga
+2560x1600
+ at item wqsxga
+3200x2048
+ at item wquxga
+3840x2400
+ at item whsxga
+6400x4096
+ at item whuxga
+7680x4800
+ at item cga
+320x200
+ at item ega
+640x350
+ at item hd480
+852x480
+ at item hd720
+1280x720
+ at item hd1080
+1920x1080
+ at end table
+
+ at item -aspect[:@var{stream_specifier}] @var{aspect} (@emph{output,per-stream})
+Set the video display aspect ratio specified by @var{aspect}.
+
+ at var{aspect} can be a floating point number string, or a string of the
+form @var{num}:@var{den}, where @var{num} and @var{den} are the
+numerator and denominator of the aspect ratio. For example "4:3",
+"16:9", "1.3333", and "1.7777" are valid argument values.
+
+ at item -vn (@emph{output})
+Disable video recording.
+ at item -bt @var{tolerance}
+Set video bitrate tolerance (in bits, default 4000k).
+Has a minimum value of: (target_bitrate/target_framerate).
+In 1-pass mode, bitrate tolerance specifies how far ratecontrol is
+willing to deviate from the target average bitrate value. This is
+not related to min/max bitrate. Lowering tolerance too much has
+an adverse effect on quality.
+ at item -maxrate @var{bitrate}
+Set max video bitrate (in bit/s).
+Requires -bufsize to be set.
+ at item -minrate @var{bitrate}
+Set min video bitrate (in bit/s).
+Most useful in setting up a CBR encode:
+ at example
+avconv -i myfile.avi -b 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k out.m2v
+ at end example
+It is of little use elsewise.
+ at item -bufsize @var{size}
+Set video buffer verifier buffer size (in bits).
+ at item -vcodec @var{codec} (@emph{output})
+Set the video codec. This is an alias for @code{-codec:v}.
+ at item -same_quant
+Use same quantizer as source (implies VBR).
+
+Note that this is NOT SAME QUALITY. Do not use this option unless you know you
+need it.
+
+ at item -pass @var{n}
+Select the pass number (1 or 2). It is used to do two-pass
+video encoding. The statistics of the video are recorded in the first
+pass into a log file (see also the option -passlogfile),
+and in the second pass that log file is used to generate the video
+at the exact requested bitrate.
+On pass 1, you may just deactivate audio and set output to null,
+examples for Windows and Unix:
+ at example
+avconv -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y NUL
+avconv -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y /dev/null
+ at end example
+
+ at item -passlogfile @var{prefix} (@emph{global})
+Set two-pass log file name prefix to @var{prefix}, the default file name
+prefix is ``av2pass''. The complete file name will be
+ at file{PREFIX-N.log}, where N is a number specific to the output
+stream.
+
+ at item -vf @var{filter_graph} (@emph{output})
+ at var{filter_graph} is a description of the filter graph to apply to
+the input video.
+Use the option "-filters" to show all the available filters (including
+also sources and sinks). This is an alias for @code{-filter:v}.
+
+ at end table
+
+ at section Advanced Video Options
+
+ at table @option
+ at item -pix_fmt[:@var{stream_specifier}] @var{format} (@emph{input/output,per-stream})
+Set pixel format. Use @code{-pix_fmts} to show all the supported
+pixel formats.
+ at item -sws_flags @var{flags} (@emph{input/output})
+Set SwScaler flags.
+ at item -g @var{gop_size}
+Set the group of pictures size.
+ at item -vdt @var{n}
+Discard threshold.
+ at item -qmin @var{q}
+minimum video quantizer scale (VBR)
+ at item -qmax @var{q}
+maximum video quantizer scale (VBR)
+ at item -qdiff @var{q}
+maximum difference between the quantizer scales (VBR)
+ at item -qblur @var{blur}
+video quantizer scale blur (VBR) (range 0.0 - 1.0)
+ at item -qcomp @var{compression}
+video quantizer scale compression (VBR) (default 0.5).
+Constant of ratecontrol equation. Recommended range for default rc_eq: 0.0-1.0
+
+ at item -lmin @var{lambda}
+minimum video lagrange factor (VBR)
+ at item -lmax @var{lambda}
+max video lagrange factor (VBR)
+ at item -mblmin @var{lambda}
+minimum macroblock quantizer scale (VBR)
+ at item -mblmax @var{lambda}
+maximum macroblock quantizer scale (VBR)
+
+These four options (lmin, lmax, mblmin, mblmax) use 'lambda' units,
+but you may use the QP2LAMBDA constant to easily convert from 'q' units:
+ at example
+avconv -i src.ext -lmax 21*QP2LAMBDA dst.ext
+ at end example
+
+ at item -rc_init_cplx @var{complexity}
+initial complexity for single pass encoding
+ at item -b_qfactor @var{factor}
+qp factor between P- and B-frames
+ at item -i_qfactor @var{factor}
+qp factor between P- and I-frames
+ at item -b_qoffset @var{offset}
+qp offset between P- and B-frames
+ at item -i_qoffset @var{offset}
+qp offset between P- and I-frames
+ at item -rc_eq @var{equation}
+Set rate control equation (see section "Expression Evaluation")
+(default = @code{tex^qComp}).
+
+When computing the rate control equation expression, besides the
+standard functions defined in the section "Expression Evaluation", the
+following functions are available:
+ at table @var
+ at item bits2qp(bits)
+ at item qp2bits(qp)
+ at end table
+
+and the following constants are available:
+ at table @var
+ at item iTex
+ at item pTex
+ at item tex
+ at item mv
+ at item fCode
+ at item iCount
+ at item mcVar
+ at item var
+ at item isI
+ at item isP
+ at item isB
+ at item avgQP
+ at item qComp
+ at item avgIITex
+ at item avgPITex
+ at item avgPPTex
+ at item avgBPTex
+ at item avgTex
+ at end table
+
+ at item -rc_override[:@var{stream_specifier}] @var{override} (@emph{output,per-stream})
+rate control override for specific intervals
+ at item -me_method @var{method}
+Set motion estimation method to @var{method}.
+Available methods are (from lowest to best quality):
+ at table @samp
+ at item zero
+Try just the (0, 0) vector.
+ at item phods
+ at item log
+ at item x1
+ at item hex
+ at item umh
+ at item epzs
+(default method)
+ at item full
+exhaustive search (slow and marginally better than epzs)
+ at end table
+
+ at item -er @var{n}
+Set error resilience to @var{n}.
+ at table @samp
+ at item 1
+FF_ER_CAREFUL (default)
+ at item 2
+FF_ER_COMPLIANT
+ at item 3
+FF_ER_AGGRESSIVE
+ at item 4
+FF_ER_VERY_AGGRESSIVE
+ at end table
+
+ at item -ec @var{bit_mask}
+Set error concealment to @var{bit_mask}. @var{bit_mask} is a bit mask of
+the following values:
+ at table @samp
+ at item 1
+FF_EC_GUESS_MVS (default = enabled)
+ at item 2
+FF_EC_DEBLOCK (default = enabled)
+ at end table
+
+ at item -bf @var{frames}
+Use 'frames' B-frames (supported for MPEG-1, MPEG-2 and MPEG-4).
+ at item -mbd @var{mode}
+macroblock decision
+ at table @samp
+ at item 0
+FF_MB_DECISION_SIMPLE: Use mb_cmp (cannot change it yet in avconv).
+ at item 1
+FF_MB_DECISION_BITS: Choose the one which needs the fewest bits.
+ at item 2
+FF_MB_DECISION_RD: rate distortion
+ at end table
+
+ at item -bug @var{param}
+Work around encoder bugs that are not auto-detected.
+ at item -strict @var{strictness}
+How strictly to follow the standards.
+
+ at item -deinterlace
+Deinterlace pictures.
+ at item -vstats
+Dump video coding statistics to @file{vstats_HHMMSS.log}.
+ at item -vstats_file @var{file}
+Dump video coding statistics to @var{file}.
+ at item -top[:@var{stream_specifier}] @var{n} (@emph{output,per-stream})
+top=1/bottom=0/auto=-1 field first
+ at item -dc @var{precision}
+Intra_dc_precision.
+ at item -vtag @var{fourcc/tag} (@emph{output})
+Force video tag/fourcc. This is an alias for @code{-tag:v}.
+ at item -qphist (@emph{global})
+Show QP histogram.
+ at item -force_key_frames[:@var{stream_specifier}] @var{time}[, at var{time}...] (@emph{output,per-stream})
+Force key frames at the specified timestamps, more precisely at the first
+frames after each specified time.
+This option can be useful to ensure that a seek point is present at a
+chapter mark or any other designated place in the output file.
+The timestamps must be specified in ascending order.
+
+ at item -copyinkf[:@var{stream_specifier}] (@emph{output,per-stream})
+When doing stream copy, copy also non-key frames found at the
+beginning.
+ at end table
+
+ at section Audio Options
+
+ at table @option
+ at item -aframes @var{number} (@emph{output})
+Set the number of audio frames to record. This is an alias for @code{-frames:a}.
+ at item -ar[:@var{stream_specifier}] @var{freq} (@emph{input/output,per-stream})
+Set the audio sampling frequency. For output streams it is set by
+default to the frequency of the corresponding input stream. For input
+streams this option only makes sense for audio grabbing devices and raw
+demuxers and is mapped to the corresponding demuxer options.
+ at item -aq @var{q} (@emph{output})
+Set the audio quality (codec-specific, VBR). This is an alias for -q:a.
+ at item -ac[:@var{stream_specifier}] @var{channels} (@emph{input/output,per-stream})
+Set the number of audio channels. For output streams it is set by
+default to the number of input audio channels. For input streams
+this option only makes sense for audio grabbing devices and raw demuxers
+and is mapped to the corresponding demuxer options.
+ at item -an (@emph{output})
+Disable audio recording.
+ at item -acodec @var{codec} (@emph{input/output})
+Set the audio codec. This is an alias for @code{-codec:a}.
+ at item -sample_fmt[:@var{stream_specifier}] @var{sample_fmt} (@emph{output,per-stream})
+Set the audio sample format. Use @code{-sample_fmts} to get a list
+of supported sample formats.
+ at end table
+
+ at section Advanced Audio options:
+
+ at table @option
+ at item -atag @var{fourcc/tag} (@emph{output})
+Force audio tag/fourcc. This is an alias for @code{-tag:a}.
+ at item -audio_service_type @var{type}
+Set the type of service that the audio stream contains.
+ at table @option
+ at item ma
+Main Audio Service (default)
+ at item ef
+Effects
+ at item vi
+Visually Impaired
+ at item hi
+Hearing Impaired
+ at item di
+Dialogue
+ at item co
+Commentary
+ at item em
+Emergency
+ at item vo
+Voice Over
+ at item ka
+Karaoke
+ at end table
+ at end table
+
+ at section Subtitle options:
+
+ at table @option
+ at item -scodec @var{codec} (@emph{input/output})
+Set the subtitle codec. This is an alias for @code{-codec:s}.
+ at item -sn (@emph{output})
+Disable subtitle recording.
+ at end table
+
+ at section Audio/Video grab options
+
+ at table @option
+ at item -isync (@emph{global})
+Synchronize read on input.
+ at end table
+
+ at section Advanced options
+
+ at table @option
+ at item -map [-]@var{input_file_id}[:@var{stream_specifier}][, at var{sync_file_id}[:@var{stream_specifier}]] (@emph{output})
+
+Designate one or more input streams as a source for the output file. Each input
+stream is identified by the input file index @var{input_file_id} and
+the input stream index @var{input_stream_id} within the input
+file. Both indices start at 0. If specified,
+ at var{sync_file_id}:@var{stream_specifier} sets which input stream
+is used as a presentation sync reference.
+
+The first @code{-map} option on the command line specifies the
+source for output stream 0, the second @code{-map} option specifies
+the source for output stream 1, etc.
+
+A @code{-} character before the stream identifier creates a "negative" mapping.
+It disables matching streams from already created mappings.
+
+For example, to map ALL streams from the first input file to output
+ at example
+avconv -i INPUT -map 0 output
+ at end example
+
+For example, if you have two audio streams in the first input file,
+these streams are identified by "0:0" and "0:1". You can use
+ at code{-map} to select which streams to place in an output file. For
+example:
+ at example
+avconv -i INPUT -map 0:1 out.wav
+ at end example
+will map the input stream in @file{INPUT} identified by "0:1" to
+the (single) output stream in @file{out.wav}.
+
+For example, to select the stream with index 2 from input file
+ at file{a.mov} (specified by the identifier "0:2"), and stream with
+index 6 from input @file{b.mov} (specified by the identifier "1:6"),
+and copy them to the output file @file{out.mov}:
+ at example
+avconv -i a.mov -i b.mov -c copy -map 0:2 -map 1:6 out.mov
+ at end example
+
+To select all video and the third audio stream from an input file:
+ at example
+avconv -i INPUT -map 0:v -map 0:a:2 OUTPUT
+ at end example
+
+To map all the streams except the second audio, use negative mappings
+ at example
+avconv -i INPUT -map 0 -map -0:a:1 OUTPUT
+ at end example
+
+Note that using this option disables the default mappings for this output file.
+
+ at item -map_metadata[:@var{metadata_spec_out}] @var{infile}[:@var{metadata_spec_in}] (@emph{output,per-metadata})
+Set metadata information of the next output file from @var{infile}. Note that
+those are file indices (zero-based), not filenames.
+Optional @var{metadata_spec_in/out} parameters specify, which metadata to copy.
+A metadata specifier can have the following forms:
+ at table @option
+ at item @var{g}
+global metadata, i.e. metadata that applies to the whole file
+
+ at item @var{s}[:@var{stream_spec}]
+per-stream metadata. @var{stream_spec} is a stream specifier as described
+in the @ref{Stream specifiers} chapter. In an input metadata specifier, the first
+matching stream is copied from. In an output metadata specifier, all matching
+streams are copied to.
+
+ at item @var{c}:@var{chapter_index}
+per-chapter metadata. @var{chapter_index} is the zero-based chapter index.
+
+ at item @var{p}:@var{program_index}
+per-program metadata. @var{program_index} is the zero-based program index.
+ at end table
+If metadata specifier is omitted, it defaults to global.
+
+By default, global metadata is copied from the first input file,
+per-stream and per-chapter metadata is copied along with streams/chapters. These
+default mappings are disabled by creating any mapping of the relevant type. A negative
+file index can be used to create a dummy mapping that just disables automatic copying.
+
+For example to copy metadata from the first stream of the input file to global metadata
+of the output file:
+ at example
+avconv -i in.ogg -map_metadata 0:s:0 out.mp3
+ at end example
+
+To do the reverse, i.e. copy global metadata to all audio streams:
+ at example
+avconv -i in.mkv -map_metadata:s:a 0:g out.mkv
+ at end example
+Note that simple @code{0} would work as well in this example, since global
+metadata is assumed by default.
+
+ at item -map_chapters @var{input_file_index} (@emph{output})
+Copy chapters from input file with index @var{input_file_index} to the next
+output file. If no chapter mapping is specified, then chapters are copied from
+the first input file with at least one chapter. Use a negative file index to
+disable any chapter copying.
+ at item -debug
+Print specific debug info.
+ at item -benchmark (@emph{global})
+Show benchmarking information at the end of an encode.
+Shows CPU time used and maximum memory consumption.
+Maximum memory consumption is not supported on all systems,
+it will usually display as 0 if not supported.
+ at item -timelimit @var{duration} (@emph{global})
+Exit after avconv has been running for @var{duration} seconds.
+ at item -dump (@emph{global})
+Dump each input packet to stderr.
+ at item -hex (@emph{global})
+When dumping packets, also dump the payload.
+ at item -ps @var{size}
+Set RTP payload size in bytes.
+ at item -re (@emph{input})
+Read input at native frame rate. Mainly used to simulate a grab device.
+ at item -threads @var{count}
+Thread count.
+ at item -vsync @var{parameter}
+Video sync method.
+
+ at table @option
+ at item 0
+Each frame is passed with its timestamp from the demuxer to the muxer.
+ at item 1
+Frames will be duplicated and dropped to achieve exactly the requested
+constant framerate.
+ at item 2
+Frames are passed through with their timestamp or dropped so as to
+prevent 2 frames from having the same timestamp.
+ at item -1
+Chooses between 1 and 2 depending on muxer capabilities. This is the
+default method.
+ at end table
+
+With -map you can select from which stream the timestamps should be
+taken. You can leave either video or audio unchanged and sync the
+remaining stream(s) to the unchanged one.
+
+ at item -async @var{samples_per_second}
+Audio sync method. "Stretches/squeezes" the audio stream to match the timestamps,
+the parameter is the maximum samples per second by which the audio is changed.
+-async 1 is a special case where only the start of the audio stream is corrected
+without any later correction.
+ at item -copyts
+Copy timestamps from input to output.
+ at item -copytb
+Copy input stream time base from input to output when stream copying.
+ at item -shortest
+Finish encoding when the shortest input stream ends.
+ at item -dts_delta_threshold
+Timestamp discontinuity delta threshold.
+ at item -muxdelay @var{seconds} (@emph{input})
+Set the maximum demux-decode delay.
+ at item -muxpreload @var{seconds} (@emph{input})
+Set the initial demux-decode delay.
+ at item -streamid @var{output-stream-index}:@var{new-value} (@emph{output})
+Assign a new stream-id value to an output stream. This option should be
+specified prior to the output filename to which it applies.
+For the situation where multiple output files exist, a streamid
+may be reassigned to a different value.
+
+For example, to set the stream 0 PID to 33 and the stream 1 PID to 36 for
+an output mpegts file:
+ at example
+avconv -i infile -streamid 0:33 -streamid 1:36 out.ts
+ at end example
+
+ at item -bsf[:@var{stream_specifier}] @var{bitstream_filters} (@emph{output,per-stream})
+Set bitstream filters for matching streams. @var{bistream_filters} is
+a comma-separated list of bitstream filters. Use the @code{-bsfs} option
+to get the list of bitstream filters.
+ at example
+avconv -i h264.mp4 -c:v copy -vbsf h264_mp4toannexb -an out.h264
+ at end example
+ at example
+avconv -i file.mov -an -vn -sbsf mov2textsub -c:s copy -f rawvideo sub.txt
+ at end example
+
+ at item -tag[:@var{stream_specifier}] @var{codec_tag} (@emph{output,per-stream})
+Force a tag/fourcc for matching streams.
+ at end table
+ at c man end OPTIONS
+
+ at chapter Tips
+ at c man begin TIPS
+
+ at itemize
+ at item
+For streaming at very low bitrate application, use a low frame rate
+and a small GOP size. This is especially true for RealVideo where
+the Linux player does not seem to be very fast, so it can miss
+frames. An example is:
+
+ at example
+avconv -g 3 -r 3 -t 10 -b 50k -s qcif -f rv10 /tmp/b.rm
+ at end example
+
+ at item
+The parameter 'q' which is displayed while encoding is the current
+quantizer. The value 1 indicates that a very good quality could
+be achieved. The value 31 indicates the worst quality. If q=31 appears
+too often, it means that the encoder cannot compress enough to meet
+your bitrate. You must either increase the bitrate, decrease the
+frame rate or decrease the frame size.
+
+ at item
+If your computer is not fast enough, you can speed up the
+compression at the expense of the compression ratio. You can use
+'-me zero' to speed up motion estimation, and '-intra' to disable
+motion estimation completely (you have only I-frames, which means it
+is about as good as JPEG compression).
+
+ at item
+To have very low audio bitrates, reduce the sampling frequency
+(down to 22050 Hz for MPEG audio, 22050 or 11025 for AC-3).
+
+ at item
+To have a constant quality (but a variable bitrate), use the option
+'-qscale n' when 'n' is between 1 (excellent quality) and 31 (worst
+quality).
+
+ at end itemize
+ at c man end TIPS
+
+ at chapter Examples
+ at c man begin EXAMPLES
+
+ at section Preset files
+
+A preset file contains a sequence of @var{option=value} pairs, one for
+each line, specifying a sequence of options which can be specified also on
+the command line. Lines starting with the hash ('#') character are ignored and
+are used to provide comments. Empty lines are also ignored. Check the
+ at file{presets} directory in the Libav source tree for examples.
+
+Preset files are specified with the @code{pre} option, this option takes a
+preset name as input. Avconv searches for a file named @var{preset_name}.avpreset in
+the directories @file{$AVCONV_DATADIR} (if set), and @file{$HOME/.avconv}, and in
+the data directory defined at configuration time (usually @file{$PREFIX/share/avconv})
+in that order. For example, if the argument is @code{libx264-max}, it will
+search for the file @file{libx264-max.avpreset}.
+
+ at section Video and Audio grabbing
+
+If you specify the input format and device then avconv can grab video
+and audio directly.
+
+ at example
+avconv -f oss -i /dev/dsp -f video4linux2 -i /dev/video0 /tmp/out.mpg
+ at end example
+
+Note that you must activate the right video source and channel before
+launching avconv with any TV viewer such as
+ at uref{http://linux.bytesex.org/xawtv/, xawtv} by Gerd Knorr. You also
+have to set the audio recording levels correctly with a
+standard mixer.
+
+ at section X11 grabbing
+
+Grab the X11 display with avconv via
+
+ at example
+avconv -f x11grab -s cif -r 25 -i :0.0 /tmp/out.mpg
+ at end example
+
+0.0 is display.screen number of your X11 server, same as
+the DISPLAY environment variable.
+
+ at example
+avconv -f x11grab -s cif -r 25 -i :0.0+10,20 /tmp/out.mpg
+ at end example
+
+0.0 is display.screen number of your X11 server, same as the DISPLAY environment
+variable. 10 is the x-offset and 20 the y-offset for the grabbing.
+
+ at section Video and Audio file format conversion
+
+Any supported file format and protocol can serve as input to avconv:
+
+Examples:
+ at itemize
+ at item
+You can use YUV files as input:
+
+ at example
+avconv -i /tmp/test%d.Y /tmp/out.mpg
+ at end example
+
+It will use the files:
+ at example
+/tmp/test0.Y, /tmp/test0.U, /tmp/test0.V,
+/tmp/test1.Y, /tmp/test1.U, /tmp/test1.V, etc...
+ at end example
+
+The Y files use twice the resolution of the U and V files. They are
+raw files, without header. They can be generated by all decent video
+decoders. You must specify the size of the image with the @option{-s} option
+if avconv cannot guess it.
+
+ at item
+You can input from a raw YUV420P file:
+
+ at example
+avconv -i /tmp/test.yuv /tmp/out.avi
+ at end example
+
+test.yuv is a file containing raw YUV planar data. Each frame is composed
+of the Y plane followed by the U and V planes at half vertical and
+horizontal resolution.
+
+ at item
+You can output to a raw YUV420P file:
+
+ at example
+avconv -i mydivx.avi hugefile.yuv
+ at end example
+
+ at item
+You can set several input files and output files:
+
+ at example
+avconv -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg
+ at end example
+
+Converts the audio file a.wav and the raw YUV video file a.yuv
+to MPEG file a.mpg.
+
+ at item
+You can also do audio and video conversions at the same time:
+
+ at example
+avconv -i /tmp/a.wav -ar 22050 /tmp/a.mp2
+ at end example
+
+Converts a.wav to MPEG audio at 22050 Hz sample rate.
+
+ at item
+You can encode to several formats at the same time and define a
+mapping from input stream to output streams:
+
+ at example
+avconv -i /tmp/a.wav -map 0:a -b 64k /tmp/a.mp2 -map 0:a -b 128k /tmp/b.mp2
+ at end example
+
+Converts a.wav to a.mp2 at 64 kbits and to b.mp2 at 128 kbits. '-map
+file:index' specifies which input stream is used for each output
+stream, in the order of the definition of output streams.
+
+ at item
+You can transcode decrypted VOBs:
+
+ at example
+avconv -i snatch_1.vob -f avi -c:v mpeg4 -b:v 800k -g 300 -bf 2 -c:a libmp3lame -b:a 128k snatch.avi
+ at end example
+
+This is a typical DVD ripping example; the input is a VOB file, the
+output an AVI file with MPEG-4 video and MP3 audio. Note that in this
+command we use B-frames so the MPEG-4 stream is DivX5 compatible, and
+GOP size is 300 which means one intra frame every 10 seconds for 29.97fps
+input video. Furthermore, the audio stream is MP3-encoded so you need
+to enable LAME support by passing @code{--enable-libmp3lame} to configure.
+The mapping is particularly useful for DVD transcoding
+to get the desired audio language.
+
+NOTE: To see the supported input formats, use @code{avconv -formats}.
+
+ at item
+You can extract images from a video, or create a video from many images:
+
+For extracting images from a video:
+ at example
+avconv -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg
+ at end example
+
+This will extract one video frame per second from the video and will
+output them in files named @file{foo-001.jpeg}, @file{foo-002.jpeg},
+etc. Images will be rescaled to fit the new WxH values.
+
+If you want to extract just a limited number of frames, you can use the
+above command in combination with the -vframes or -t option, or in
+combination with -ss to start extracting from a certain point in time.
+
+For creating a video from many images:
+ at example
+avconv -f image2 -i foo-%03d.jpeg -r 12 -s WxH foo.avi
+ at end example
+
+The syntax @code{foo-%03d.jpeg} specifies to use a decimal number
+composed of three digits padded with zeroes to express the sequence
+number. It is the same syntax supported by the C printf function, but
+only formats accepting a normal integer are suitable.
+
+ at item
+You can put many streams of the same type in the output:
+
+ at example
+avconv -i test1.avi -i test2.avi -map 0.3 -map 0.2 -map 0.1 -map 0.0 -c copy test12.nut
+ at end example
+
+The resulting output file @file{test12.avi} will contain first four streams from
+the input file in reverse order.
+
+ at end itemize
+ at c man end EXAMPLES
+
+ at include eval.texi
+ at include encoders.texi
+ at include demuxers.texi
+ at include muxers.texi
+ at include indevs.texi
+ at include outdevs.texi
+ at include protocols.texi
+ at include bitstream_filters.texi
+ at include filters.texi
+ at include metadata.texi
+
+ at ignore
+
+ at setfilename avconv
+ at settitle avconv video converter
+
+ at c man begin SEEALSO
+avplay(1), avprobe(1) and the Libav HTML documentation
+ at c man end
+
+ at c man begin AUTHORS
+The Libav developers
+ at c man end
+
+ at end ignore
+
+ at bye
diff --git a/doc/avplay.texi b/doc/avplay.texi
new file mode 100644
index 0000000..8fc3308
--- /dev/null
+++ b/doc/avplay.texi
@@ -0,0 +1,184 @@
+\input texinfo @c -*- texinfo -*-
+
+ at settitle avplay Documentation
+ at titlepage
+ at center @titlefont{avplay Documentation}
+ at end titlepage
+
+ at top
+
+ at contents
+
+ at chapter Synopsis
+
+ at example
+ at c man begin SYNOPSIS
+avplay [options] @file{input_file}
+ at c man end
+ at end example
+
+ at chapter Description
+ at c man begin DESCRIPTION
+
+AVplay is a very simple and portable media player using the Libav
+libraries and the SDL library. It is mostly used as a testbed for the
+various Libav APIs.
+ at c man end
+
+ at chapter Options
+ at c man begin OPTIONS
+
+ at include avtools-common-opts.texi
+
+ at section Main options
+
+ at table @option
+ at item -x @var{width}
+Force displayed width.
+ at item -y @var{height}
+Force displayed height.
+ at item -s @var{size}
+This option has been removed. Use private format options for specifying the
+input video size. For example with the rawvideo demuxer you need to specify the
+option @var{video_size}.
+ at item -an
+Disable audio.
+ at item -vn
+Disable video.
+ at item -ss @var{pos}
+Seek to a given position in seconds.
+ at item -t @var{duration}
+play <duration> seconds of audio/video
+ at item -bytes
+Seek by bytes.
+ at item -nodisp
+Disable graphical display.
+ at item -f @var{fmt}
+Force format.
+ at item -window_title @var{title}
+Set window title (default is the input filename).
+ at item -loop @var{number}
+Loops movie playback <number> times. 0 means forever.
+ at item -vf @var{filter_graph}
+ at var{filter_graph} is a description of the filter graph to apply to
+the input video.
+Use the option "-filters" to show all the available filters (including
+also sources and sinks).
+
+ at end table
+
+ at section Advanced options
+ at table @option
+ at item -pix_fmt @var{format}
+This option has been removed. Use private options for specifying the
+input pixel format. For example with the rawvideo demuxer you need to specify
+the option @var{pixel_format}.
+ at item -stats
+Show the stream duration, the codec parameters, the current position in
+the stream and the audio/video synchronisation drift.
+ at item -debug
+Print specific debug info.
+ at item -bug
+Work around bugs.
+ at item -vismv
+Visualize motion vectors.
+ at item -fast
+Non-spec-compliant optimizations.
+ at item -genpts
+Generate pts.
+ at item -rtp_tcp
+Force RTP/TCP protocol usage instead of RTP/UDP. It is only meaningful
+if you are streaming with the RTSP protocol.
+ at item -sync @var{type}
+Set the master clock to audio (@code{type=audio}), video
+(@code{type=video}) or external (@code{type=ext}). Default is audio. The
+master clock is used to control audio-video synchronization. Most media
+players use audio as master clock, but in some cases (streaming or high
+quality broadcast) it is necessary to change that. This option is mainly
+used for debugging purposes.
+ at item -threads @var{count}
+Set the thread count.
+ at item -ast @var{audio_stream_number}
+Select the desired audio stream number, counting from 0. The number
+refers to the list of all the input audio streams. If it is greater
+than the number of audio streams minus one, then the last one is
+selected, if it is negative the audio playback is disabled.
+ at item -vst @var{video_stream_number}
+Select the desired video stream number, counting from 0. The number
+refers to the list of all the input video streams. If it is greater
+than the number of video streams minus one, then the last one is
+selected, if it is negative the video playback is disabled.
+ at item -sst @var{subtitle_stream_number}
+Select the desired subtitle stream number, counting from 0. The number
+refers to the list of all the input subtitle streams. If it is greater
+than the number of subtitle streams minus one, then the last one is
+selected, if it is negative the subtitle rendering is disabled.
+ at item -autoexit
+Exit when video is done playing.
+ at item -exitonkeydown
+Exit if any key is pressed.
+ at item -exitonmousedown
+Exit if any mouse button is pressed.
+ at end table
+
+ at section While playing
+
+ at table @key
+ at item q, ESC
+Quit.
+
+ at item f
+Toggle full screen.
+
+ at item p, SPC
+Pause.
+
+ at item a
+Cycle audio channel.
+
+ at item v
+Cycle video channel.
+
+ at item t
+Cycle subtitle channel.
+
+ at item w
+Show audio waves.
+
+ at item left/right
+Seek backward/forward 10 seconds.
+
+ at item down/up
+Seek backward/forward 1 minute.
+
+ at item mouse click
+Seek to percentage in file corresponding to fraction of width.
+
+ at end table
+
+ at c man end
+
+ at include eval.texi
+ at include demuxers.texi
+ at include muxers.texi
+ at include indevs.texi
+ at include outdevs.texi
+ at include protocols.texi
+ at include filters.texi
+
+ at ignore
+
+ at setfilename avplay
+ at settitle AVplay media player
+
+ at c man begin SEEALSO
+avconv(1), avprobe(1) and the Libav HTML documentation
+ at c man end
+
+ at c man begin AUTHORS
+The Libav developers
+ at c man end
+
+ at end ignore
+
+ at bye
diff --git a/doc/avprobe.texi b/doc/avprobe.texi
new file mode 100644
index 0000000..6b2c800
--- /dev/null
+++ b/doc/avprobe.texi
@@ -0,0 +1,134 @@
+\input texinfo @c -*- texinfo -*-
+
+ at settitle avprobe Documentation
+ at titlepage
+ at center @titlefont{avprobe Documentation}
+ at end titlepage
+
+ at top
+
+ at contents
+
+ at chapter Synopsis
+
+The generic syntax is:
+
+ at example
+ at c man begin SYNOPSIS
+avprobe [options] [@file{input_file}]
+ at c man end
+ at end example
+
+ at chapter Description
+ at c man begin DESCRIPTION
+
+avprobe gathers information from multimedia streams and prints it in
+human- and machine-readable fashion.
+
+For example it can be used to check the format of the container used
+by a multimedia stream and the format and type of each media stream
+contained in it.
+
+If a filename is specified in input, avprobe will try to open and
+probe the file content. If the file cannot be opened or recognized as
+a multimedia file, a positive exit code is returned.
+
+avprobe may be employed both as a standalone application or in
+combination with a textual filter, which may perform more
+sophisticated processing, e.g. statistical processing or plotting.
+
+Options are used to list some of the formats supported by avprobe or
+for specifying which information to display, and for setting how
+avprobe will show it.
+
+avprobe output is designed to be easily parsable by a textual filter,
+and consists of one or more sections of the form:
+ at example
+[SECTION]
+key1=val1
+...
+keyN=valN
+[/SECTION]
+ at end example
+
+Metadata tags stored in the container or in the streams are recognized
+and printed in the corresponding "FORMAT" or "STREAM" section, and
+are prefixed by the string "TAG:".
+
+ at c man end
+
+ at chapter Options
+ at c man begin OPTIONS
+
+ at include avtools-common-opts.texi
+
+ at section Main options
+
+ at table @option
+
+ at item -f @var{format}
+Force format to use.
+
+ at item -unit
+Show the unit of the displayed values.
+
+ at item -prefix
+Use SI prefixes for the displayed values.
+Unless the "-byte_binary_prefix" option is used all the prefixes
+are decimal.
+
+ at item -byte_binary_prefix
+Force the use of binary prefixes for byte values.
+
+ at item -sexagesimal
+Use sexagesimal format HH:MM:SS.MICROSECONDS for time values.
+
+ at item -pretty
+Prettify the format of the displayed values, it corresponds to the
+options "-unit -prefix -byte_binary_prefix -sexagesimal".
+
+ at item -show_format
+Show information about the container format of the input multimedia
+stream.
+
+All the container format information is printed within a section with
+name "FORMAT".
+
+ at item -show_packets
+Show information about each packet contained in the input multimedia
+stream.
+
+The information for each single packet is printed within a dedicated
+section with name "PACKET".
+
+ at item -show_streams
+Show information about each media stream contained in the input
+multimedia stream.
+
+Each media stream information is printed within a dedicated section
+with name "STREAM".
+
+ at end table
+ at c man end
+
+ at include demuxers.texi
+ at include muxers.texi
+ at include protocols.texi
+ at include indevs.texi
+
+ at ignore
+
+ at setfilename avprobe
+ at settitle avprobe media prober
+
+ at c man begin SEEALSO
+avconv(1), avplay(1) and the Libav HTML documentation
+ at c man end
+
+ at c man begin AUTHORS
+The Libav developers
+ at c man end
+
+ at end ignore
+
+ at bye
diff --git a/doc/avserver.conf b/doc/avserver.conf
new file mode 100644
index 0000000..2105ac5
--- /dev/null
+++ b/doc/avserver.conf
@@ -0,0 +1,377 @@
+# Port on which the server is listening. You must select a different
+# port from your standard HTTP web server if it is running on the same
+# computer.
+Port 8090
+
+# Address on which the server is bound. Only useful if you have
+# several network interfaces.
+BindAddress 0.0.0.0
+
+# Number of simultaneous HTTP connections that can be handled. It has
+# to be defined *before* the MaxClients parameter, since it defines the
+# MaxClients maximum limit.
+MaxHTTPConnections 2000
+
+# Number of simultaneous requests that can be handled. Since AVServer
+# is very fast, it is more likely that you will want to leave this high
+# and use MaxBandwidth, below.
+MaxClients 1000
+
+# This the maximum amount of kbit/sec that you are prepared to
+# consume when streaming to clients.
+MaxBandwidth 1000
+
+# Access log file (uses standard Apache log file format)
+# '-' is the standard output.
+CustomLog -
+
+# Suppress that if you want to launch avserver as a daemon.
+NoDaemon
+
+
+##################################################################
+# Definition of the live feeds. Each live feed contains one video
+# and/or audio sequence coming from an ffmpeg encoder or another
+# avserver. This sequence may be encoded simultaneously with several
+# codecs at several resolutions.
+
+<Feed feed1.ffm>
+
+# You must use 'ffmpeg' to send a live feed to avserver. In this
+# example, you can type:
+#
+# ffmpeg http://localhost:8090/feed1.ffm
+
+# avserver can also do time shifting. It means that it can stream any
+# previously recorded live stream. The request should contain:
+# "http://xxxx?date=[YYYY-MM-DDT][[HH:]MM:]SS[.m...]".You must specify
+# a path where the feed is stored on disk. You also specify the
+# maximum size of the feed, where zero means unlimited. Default:
+# File=/tmp/feed_name.ffm FileMaxSize=5M
+File /tmp/feed1.ffm
+FileMaxSize 200K
+
+# You could specify
+# ReadOnlyFile /saved/specialvideo.ffm
+# This marks the file as readonly and it will not be deleted or updated.
+
+# Specify launch in order to start ffmpeg automatically.
+# First ffmpeg must be defined with an appropriate path if needed,
+# after that options can follow, but avoid adding the http:// field
+#Launch ffmpeg
+
+# Only allow connections from localhost to the feed.
+ACL allow 127.0.0.1
+
+</Feed>
+
+
+##################################################################
+# Now you can define each stream which will be generated from the
+# original audio and video stream. Each format has a filename (here
+# 'test1.mpg'). AVServer will send this stream when answering a
+# request containing this filename.
+
+<Stream test1.mpg>
+
+# coming from live feed 'feed1'
+Feed feed1.ffm
+
+# Format of the stream : you can choose among:
+# mpeg : MPEG-1 multiplexed video and audio
+# mpegvideo : only MPEG-1 video
+# mp2 : MPEG-2 audio (use AudioCodec to select layer 2 and 3 codec)
+# ogg : Ogg format (Vorbis audio codec)
+# rm : RealNetworks-compatible stream. Multiplexed audio and video.
+# ra : RealNetworks-compatible stream. Audio only.
+# mpjpeg : Multipart JPEG (works with Netscape without any plugin)
+# jpeg : Generate a single JPEG image.
+# asf : ASF compatible streaming (Windows Media Player format).
+# swf : Macromedia Flash compatible stream
+# avi : AVI format (MPEG-4 video, MPEG audio sound)
+Format mpeg
+
+# Bitrate for the audio stream. Codecs usually support only a few
+# different bitrates.
+AudioBitRate 32
+
+# Number of audio channels: 1 = mono, 2 = stereo
+AudioChannels 1
+
+# Sampling frequency for audio. When using low bitrates, you should
+# lower this frequency to 22050 or 11025. The supported frequencies
+# depend on the selected audio codec.
+AudioSampleRate 44100
+
+# Bitrate for the video stream
+VideoBitRate 64
+
+# Ratecontrol buffer size
+VideoBufferSize 40
+
+# Number of frames per second
+VideoFrameRate 3
+
+# Size of the video frame: WxH (default: 160x128)
+# The following abbreviations are defined: sqcif, qcif, cif, 4cif, qqvga,
+# qvga, vga, svga, xga, uxga, qxga, sxga, qsxga, hsxga, wvga, wxga, wsxga,
+# wuxga, woxga, wqsxga, wquxga, whsxga, whuxga, cga, ega, hd480, hd720,
+# hd1080
+VideoSize 160x128
+
+# Transmit only intra frames (useful for low bitrates, but kills frame rate).
+#VideoIntraOnly
+
+# If non-intra only, an intra frame is transmitted every VideoGopSize
+# frames. Video synchronization can only begin at an intra frame.
+VideoGopSize 12
+
+# More MPEG-4 parameters
+# VideoHighQuality
+# Video4MotionVector
+
+# Choose your codecs:
+#AudioCodec mp2
+#VideoCodec mpeg1video
+
+# Suppress audio
+#NoAudio
+
+# Suppress video
+#NoVideo
+
+#VideoQMin 3
+#VideoQMax 31
+
+# Set this to the number of seconds backwards in time to start. Note that
+# most players will buffer 5-10 seconds of video, and also you need to allow
+# for a keyframe to appear in the data stream.
+#Preroll 15
+
+# ACL:
+
+# You can allow ranges of addresses (or single addresses)
+#ACL ALLOW <first address> <last address>
+
+# You can deny ranges of addresses (or single addresses)
+#ACL DENY <first address> <last address>
+
+# You can repeat the ACL allow/deny as often as you like. It is on a per
+# stream basis. The first match defines the action. If there are no matches,
+# then the default is the inverse of the last ACL statement.
+#
+# Thus 'ACL allow localhost' only allows access from localhost.
+# 'ACL deny 1.0.0.0 1.255.255.255' would deny the whole of network 1 and
+# allow everybody else.
+
+</Stream>
+
+
+##################################################################
+# Example streams
+
+
+# Multipart JPEG
+
+#<Stream test.mjpg>
+#Feed feed1.ffm
+#Format mpjpeg
+#VideoFrameRate 2
+#VideoIntraOnly
+#NoAudio
+#Strict -1
+#</Stream>
+
+
+# Single JPEG
+
+#<Stream test.jpg>
+#Feed feed1.ffm
+#Format jpeg
+#VideoFrameRate 2
+#VideoIntraOnly
+##VideoSize 352x240
+#NoAudio
+#Strict -1
+#</Stream>
+
+
+# Flash
+
+#<Stream test.swf>
+#Feed feed1.ffm
+#Format swf
+#VideoFrameRate 2
+#VideoIntraOnly
+#NoAudio
+#</Stream>
+
+
+# ASF compatible
+
+<Stream test.asf>
+Feed feed1.ffm
+Format asf
+VideoFrameRate 15
+VideoSize 352x240
+VideoBitRate 256
+VideoBufferSize 40
+VideoGopSize 30
+AudioBitRate 64
+StartSendOnKey
+</Stream>
+
+
+# MP3 audio
+
+#<Stream test.mp3>
+#Feed feed1.ffm
+#Format mp2
+#AudioCodec mp3
+#AudioBitRate 64
+#AudioChannels 1
+#AudioSampleRate 44100
+#NoVideo
+#</Stream>
+
+
+# Ogg Vorbis audio
+
+#<Stream test.ogg>
+#Feed feed1.ffm
+#Title "Stream title"
+#AudioBitRate 64
+#AudioChannels 2
+#AudioSampleRate 44100
+#NoVideo
+#</Stream>
+
+
+# Real with audio only at 32 kbits
+
+#<Stream test.ra>
+#Feed feed1.ffm
+#Format rm
+#AudioBitRate 32
+#NoVideo
+#NoAudio
+#</Stream>
+
+
+# Real with audio and video at 64 kbits
+
+#<Stream test.rm>
+#Feed feed1.ffm
+#Format rm
+#AudioBitRate 32
+#VideoBitRate 128
+#VideoFrameRate 25
+#VideoGopSize 25
+#NoAudio
+#</Stream>
+
+
+##################################################################
+# A stream coming from a file: you only need to set the input
+# filename and optionally a new format. Supported conversions:
+# AVI -> ASF
+
+#<Stream file.rm>
+#File "/usr/local/httpd/htdocs/tlive.rm"
+#NoAudio
+#</Stream>
+
+#<Stream file.asf>
+#File "/usr/local/httpd/htdocs/test.asf"
+#NoAudio
+#Author "Me"
+#Copyright "Super MegaCorp"
+#Title "Test stream from disk"
+#Comment "Test comment"
+#</Stream>
+
+
+##################################################################
+# RTSP examples
+#
+# You can access this stream with the RTSP URL:
+# rtsp://localhost:5454/test1-rtsp.mpg
+#
+# A non-standard RTSP redirector is also created. Its URL is:
+# http://localhost:8090/test1-rtsp.rtsp
+
+#<Stream test1-rtsp.mpg>
+#Format rtp
+#File "/usr/local/httpd/htdocs/test1.mpg"
+#</Stream>
+
+
+# Transcode an incoming live feed to another live feed,
+# using libx264 and video presets
+
+#<Stream live.h264>
+#Format rtp
+#Feed feed1.ffm
+#VideoCodec libx264
+#VideoFrameRate 24
+#VideoBitRate 100
+#VideoSize 480x272
+#AVPresetVideo default
+#AVPresetVideo baseline
+#AVOptionVideo flags +global_header
+#
+#AudioCodec libfaac
+#AudioBitRate 32
+#AudioChannels 2
+#AudioSampleRate 22050
+#AVOptionAudio flags +global_header
+#</Stream>
+
+##################################################################
+# SDP/multicast examples
+#
+# If you want to send your stream in multicast, you must set the
+# multicast address with MulticastAddress. The port and the TTL can
+# also be set.
+#
+# An SDP file is automatically generated by avserver by adding the
+# 'sdp' extension to the stream name (here
+# http://localhost:8090/test1-sdp.sdp). You should usually give this
+# file to your player to play the stream.
+#
+# The 'NoLoop' option can be used to avoid looping when the stream is
+# terminated.
+
+#<Stream test1-sdp.mpg>
+#Format rtp
+#File "/usr/local/httpd/htdocs/test1.mpg"
+#MulticastAddress 224.124.0.1
+#MulticastPort 5000
+#MulticastTTL 16
+#NoLoop
+#</Stream>
+
+
+##################################################################
+# Special streams
+
+# Server status
+
+<Stream stat.html>
+Format status
+
+# Only allow local people to get the status
+ACL allow localhost
+ACL allow 192.168.0.0 192.168.255.255
+
+#FaviconURL http://pond1.gladstonefamily.net:8080/favicon.ico
+</Stream>
+
+
+# Redirect index.html to the appropriate site
+
+<Redirect index.html>
+URL http://www.libav.org/
+</Redirect>
+
+
diff --git a/doc/avserver.texi b/doc/avserver.texi
new file mode 100644
index 0000000..c023814
--- /dev/null
+++ b/doc/avserver.texi
@@ -0,0 +1,282 @@
+\input texinfo @c -*- texinfo -*-
+
+ at settitle avserver Documentation
+ at titlepage
+ at center @titlefont{avserver Documentation}
+ at end titlepage
+
+ at top
+
+ at contents
+
+ at chapter Synopsys
+
+The generic syntax is:
+
+ at example
+ at c man begin SYNOPSIS
+avserver [options]
+ at c man end
+ at end example
+
+ at chapter Description
+ at c man begin DESCRIPTION
+
+WARNING: avserver is unmaintained, largely broken and in need of a
+complete rewrite. It probably won't work for you. Use at your own
+risk.
+
+avserver is a streaming server for both audio and video. It supports
+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 avserver.conf).
+
+avserver 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 avserver /
+avconv. All questions about parameters for avconv, codec questions,
+etc. are not covered here. Read @file{avconv.html} for more
+information.
+
+ at section How does it work?
+
+avserver receives prerecorded files or FFM streams from some avconv
+instance as input, then streams them over RTP/RTSP/HTTP.
+
+An avserver instance will listen on some port as specified in the
+configuration file. You can launch one or more instances of avconv and
+send one or more FFM streams to the port where avserver is expecting
+to receive them. Alternately, you can make avserver launch such avconv
+instances at startup.
+
+Input streams are called feeds, and each one is specified by a <Feed>
+section in the configuration file.
+
+For each feed you can have different output streams in various
+formats, each one specified by a <Stream> section in the configuration
+file.
+
+ at section Status stream
+
+avserver supports an HTTP interface which exposes the current status
+of the server.
+
+Simply point your browser to the address of the special status stream
+specified in the configuration file.
+
+For example if you have:
+ at example
+<Stream status.html>
+Format status
+
+# Only allow local people to get the status
+ACL allow localhost
+ACL allow 192.168.0.0 192.168.255.255
+</Stream>
+ at end example
+
+then the server will post a page with the status information when
+the special stream @file{status.html} is requested.
+
+ at section What can this do?
+
+When properly configured and running, you can capture video and audio in real
+time from a suitable capture card, and stream it out over the Internet to
+either Windows Media Player or RealAudio player (with some restrictions).
+
+It can also stream from files, though that is currently broken. Very often, a
+web server can be used to serve up the files just as well.
+
+It can stream prerecorded video from .ffm files, though it is somewhat tricky
+to make it work correctly.
+
+ at section What do I need?
+
+I use Linux on a 900 MHz Duron with a cheapo Bt848 based TV capture card. I'm
+using stock Linux 2.4.17 with the stock drivers. [Actually that isn't true,
+I needed some special drivers for my motherboard-based sound card.]
+
+I understand that FreeBSD systems work just fine as well.
+
+ at section How do I make it work?
+
+First, build the kit. It *really* helps to have installed LAME first. Then when
+you run the avserver ./configure, make sure that you have the
+ at code{--enable-libmp3lame} flag turned on.
+
+LAME is important as it allows for streaming audio to Windows Media Player.
+Don't ask why the other audio types do not work.
+
+As a simple test, just run the following two command lines where INPUTFILE
+is some file which you can decode with avconv:
+
+ at example
+./avserver -f doc/avserver.conf &
+./avconv -i INPUTFILE http://localhost:8090/feed1.ffm
+ at end example
+
+At this point you should be able to go to your Windows machine and fire up
+Windows Media Player (WMP). Go to Open URL and enter
+
+ at example
+ http://<linuxbox>:8090/test.asf
+ at end example
+
+You should (after a short delay) see video and hear audio.
+
+WARNING: trying to stream test1.mpg doesn't work with WMP as it tries to
+transfer the entire file before starting to play.
+The same is true of AVI files.
+
+ at section What happens next?
+
+You should edit the avserver.conf file to suit your needs (in terms of
+frame rates etc). Then install avserver and avconv, write a script to start
+them up, and off you go.
+
+ at section Troubleshooting
+
+ at subsection I don't hear any audio, but video is fine.
+
+Maybe you didn't install LAME, or got your ./configure statement wrong. Check
+the avconv output to see if a line referring to MP3 is present. If not, then
+your configuration was incorrect. If it is, then maybe your wiring is not
+set up correctly. Maybe the sound card is not getting data from the right
+input source. Maybe you have a really awful audio interface (like I do)
+that only captures in stereo and also requires that one channel be flipped.
+If you are one of these people, then export 'AUDIO_FLIP_LEFT=1' before
+starting avconv.
+
+ at subsection The audio and video lose sync after a while.
+
+Yes, they do.
+
+ at subsection After a long while, the video update rate goes way down in WMP.
+
+Yes, it does. Who knows why?
+
+ at subsection WMP 6.4 behaves differently to WMP 7.
+
+Yes, it does. Any thoughts on this would be gratefully received. These
+differences extend to embedding WMP into a web page. [There are two
+object IDs that you can use: The old one, which does not play well, and
+the new one, which does (both tested on the same system). However,
+I suspect that the new one is not available unless you have installed WMP 7].
+
+ at section What else can it do?
+
+You can replay video from .ffm files that was recorded earlier.
+However, there are a number of caveats, including the fact that the
+avserver parameters must match the original parameters used to record the
+file. If they do not, then avserver deletes the file before recording into it.
+(Now that I write this, it seems broken).
+
+You can fiddle with many of the codec choices and encoding parameters, and
+there are a bunch more parameters that you cannot control. Post a message
+to the mailing list if there are some 'must have' parameters. Look in
+avserver.conf for a list of the currently available controls.
+
+It will automatically generate the ASX or RAM files that are often used
+in browsers. These files are actually redirections to the underlying ASF
+or RM file. The reason for this is that the browser often fetches the
+entire file before starting up the external viewer. The redirection files
+are very small and can be transferred quickly. [The stream itself is
+often 'infinite' and thus the browser tries to download it and never
+finishes.]
+
+ at section Tips
+
+* When you connect to a live stream, most players (WMP, RA, etc) want to
+buffer a certain number of seconds of material so that they can display the
+signal continuously. However, avserver (by default) starts sending data
+in realtime. This means that there is a pause of a few seconds while the
+buffering is being done by the player. The good news is that this can be
+cured by adding a '?buffer=5' to the end of the URL. This means that the
+stream should start 5 seconds in the past -- and so the first 5 seconds
+of the stream are sent as fast as the network will allow. It will then
+slow down to real time. This noticeably improves the startup experience.
+
+You can also add a 'Preroll 15' statement into the avserver.conf that will
+add the 15 second prebuffering on all requests that do not otherwise
+specify a time. In addition, avserver will skip frames until a key_frame
+is found. This further reduces the startup delay by not transferring data
+that will be discarded.
+
+* You may want to adjust the MaxBandwidth in the avserver.conf to limit
+the amount of bandwidth consumed by live streams.
+
+ at section Why does the ?buffer / Preroll stop working after a time?
+
+It turns out that (on my machine at least) the number of frames successfully
+grabbed is marginally less than the number that ought to be grabbed. This
+means that the timestamp in the encoded data stream gets behind realtime.
+This means that if you say 'Preroll 10', then when the stream gets 10
+or more seconds behind, there is no Preroll left.
+
+Fixing this requires a change in the internals of how timestamps are
+handled.
+
+ at section Does the @code{?date=} stuff work.
+
+Yes (subject to the limitation outlined above). Also note that whenever you
+start avserver, it deletes the ffm file (if any parameters have changed),
+thus wiping out what you had recorded before.
+
+The format of the @code{?date=xxxxxx} is fairly flexible. You should use one
+of the following formats (the 'T' is literal):
+
+ at example
+* YYYY-MM-DDTHH:MM:SS (localtime)
+* YYYY-MM-DDTHH:MM:SSZ (UTC)
+ at end example
+
+You can omit the YYYY-MM-DD, and then it refers to the current day. However
+note that @samp{?date=16:00:00} refers to 16:00 on the current day -- this
+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}.
+ at c man end
+
+ at chapter Options
+ at c man begin OPTIONS
+
+ at include avtools-common-opts.texi
+
+ at section Main options
+
+ at table @option
+ at item -f @var{configfile}
+Use @file{configfile} instead of @file{/etc/avserver.conf}.
+ at item -n
+Enable no-launch mode. This option disables all the Launch directives
+within the various <Stream> sections. Since avserver will not launch
+any avconv instances, you will have to launch them manually.
+ at item -d
+Enable debug mode. This option increases log verbosity, directs log
+messages to stdout and causes avserver to run in the foreground
+rather than as a daemon.
+ at end table
+ at c man end
+
+ at ignore
+
+ at setfilename avserver
+ at settitle avserver video server
+
+ at c man begin SEEALSO
+
+avconv(1), avplay(1), avprobe(1), the @file{avserver.conf}
+example and the Libav HTML documentation
+ at c man end
+
+ at c man begin AUTHORS
+The Libav developers
+ at c man end
+
+ at end ignore
+
+ at bye
diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi
new file mode 100644
index 0000000..18e7ba5
--- /dev/null
+++ b/doc/avtools-common-opts.texi
@@ -0,0 +1,158 @@
+All the numerical options, if not specified otherwise, accept in input
+a string representing a number, which may contain one of the
+International System number postfixes, for example 'K', 'M', 'G'.
+If 'i' is appended after the postfix, powers of 2 are used instead of
+powers of 10. The 'B' postfix multiplies the value for 8, and can be
+appended after another postfix or used alone. This allows using for
+example 'KB', 'MiB', 'G' and 'B' as postfix.
+
+Options which do not take arguments are boolean options, and set the
+corresponding value to true. They can be set to false by prefixing
+with "no" the option name, for example using "-nofoo" in the
+command line will set to false the boolean option with name "foo".
+
+ at anchor{Stream specifiers}
+ at section Stream specifiers
+Some options are applied per-stream, e.g. bitrate or codec. Stream specifiers
+are used to precisely specify which stream(s) does a given option belong to.
+
+A stream specifier is a string generally appended to the option name and
+separated from it by a colon. E.g. @code{-codec:a:1 ac3} option contains
+ at code{a:1} stream specifer, which matches the second audio stream. Therefore it
+would select the ac3 codec for the second audio stream.
+
+A stream specifier can match several stream, the option is then applied to all
+of them. E.g. the stream specifier in @code{-b:a 128k} matches all audio
+streams.
+
+An empty stream specifier matches all streams, for example @code{-codec copy}
+or @code{-codec: copy} would copy all the streams without reencoding.
+
+Possible forms of stream specifiers are:
+ at table @option
+ at item @var{stream_index}
+Matches the stream with this index. E.g. @code{-threads:1 4} would set the
+thread count for the second stream to 4.
+ at item @var{stream_type}[:@var{stream_index}]
+ at var{stream_type} is one of: 'v' for video, 'a' for audio, 's' for subtitle,
+'d' for data and 't' for attachments. If @var{stream_index} is given, then
+matches stream number @var{stream_index} of this type. Otherwise matches all
+streams of this type.
+ at item p:@var{program_id}[:@var{stream_index}]
+If @var{stream_index} is given, then matches stream number @var{stream_index} in
+program with id @var{program_id}. Otherwise matches all streams in this program.
+ at end table
+ at section Generic options
+
+These options are shared amongst the av* tools.
+
+ at table @option
+
+ at item -L
+Show license.
+
+ at item -h, -?, -help, --help
+Show help.
+
+ at item -version
+Show version.
+
+ at item -formats
+Show available formats.
+
+The fields preceding the format names have the following meanings:
+ at table @samp
+ at item D
+Decoding available
+ at item E
+Encoding available
+ at end table
+
+ at item -codecs
+Show available codecs.
+
+The fields preceding the codec names have the following meanings:
+ at table @samp
+ at item D
+Decoding available
+ at item E
+Encoding available
+ at item V/A/S
+Video/audio/subtitle codec
+ at item S
+Codec supports slices
+ at item D
+Codec supports direct rendering
+ at item T
+Codec can handle input truncated at random locations instead of only at frame boundaries
+ at end table
+
+ at item -bsfs
+Show available bitstream filters.
+
+ at item -protocols
+Show available protocols.
+
+ at item -filters
+Show available libavfilter filters.
+
+ at item -pix_fmts
+Show available pixel formats.
+
+ at item -sample_fmts
+Show available sample formats.
+
+ at item -loglevel @var{loglevel} | -v @var{loglevel}
+Set the logging level used by the library.
+ at var{loglevel} is a number or a string containing one of the following values:
+ at table @samp
+ at item quiet
+ at item panic
+ at item fatal
+ at item error
+ at item warning
+ at item info
+ at item verbose
+ at item debug
+ at end table
+
+By default the program logs to stderr, if coloring is supported by the
+terminal, colors are used to mark errors and warnings. Log coloring
+can be disabled setting the environment variable
+ at env{FFMPEG_FORCE_NOCOLOR} or @env{NO_COLOR}, or can be forced setting
+the environment variable @env{FFMPEG_FORCE_COLOR}.
+The use of the environment variable @env{NO_COLOR} is deprecated and
+will be dropped in a following Libav version.
+
+ at end table
+
+ at section AVOptions
+
+These options are provided directly by the libavformat, libavdevice and
+libavcodec libraries. To see the list of available AVOptions, use the
+ at option{-help} option. They are separated into two categories:
+ at table @option
+ at item generic
+These options can be set for any container, codec or device. Generic options
+are listed under AVFormatContext options for containers/devices and under
+AVCodecContext options for codecs.
+ at item private
+These options are specific to the given container, device or codec. Private
+options are listed under their corresponding containers/devices/codecs.
+ at end table
+
+For example to write an ID3v2.3 header instead of a default ID3v2.4 to
+an MP3 file, use the @option{id3v2_version} private option of the MP3
+muxer:
+ at example
+avconv -i input.flac -id3v2_version 3 out.mp3
+ at end example
+
+All codec AVOptions are obviously per-stream, so the chapter on stream
+specifiers applies to them
+
+Note @option{-nooption} syntax cannot be used for boolean AVOptions,
+use @option{-option 0}/@option{-option 1}.
+
+Note2 old undocumented way of specifying per-stream AVOptions by prepending
+v/a/s to the options name is now obsolete and will be removed soon.
diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index c33fca6..1fbd40a 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -34,7 +34,7 @@ JPEG image. The individual frames can be extracted without loss,
e.g. by
@example
-ffmpeg -i ../some_mjpeg.avi -vcodec copy frames_%d.jpg
+avconv -i ../some_mjpeg.avi -c:v copy frames_%d.jpg
@end example
Unfortunately, these chunks are incomplete JPEG images, because
@@ -57,9 +57,9 @@ stream (carrying the AVI1 header ID and lacking a DHT segment) to
produce fully qualified JPEG images.
@example
-ffmpeg -i mjpeg-movie.avi -vcodec copy -vbsf mjpeg2jpeg frame_%d.jpg
+avconv -i mjpeg-movie.avi -c:v copy -vbsf mjpeg2jpeg frame_%d.jpg
exiftran -i -9 frame*.jpg
-ffmpeg -i frame_%d.jpg -vcodec copy rotated.avi
+avconv -i frame_%d.jpg -c:v copy rotated.avi
@end example
@section mjpega_dump_header
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 98f9fde..c3049dd 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -49,19 +49,19 @@ sequence of filenames of the form @file{i%m%g-1.jpg},
The size, the pixel format, and the format of each image must be the
same for all the files in the sequence.
-The following example shows how to use @file{ffmpeg} for creating a
+The following example shows how to use @command{avconv} for creating a
video from the images in the file sequence @file{img-001.jpeg},
@file{img-002.jpeg}, ..., assuming an input framerate of 10 frames per
second:
@example
-ffmpeg -r 10 -f image2 -i 'img-%03d.jpeg' out.avi
+avconv -i 'img-%03d.jpeg' -r 10 out.mkv
@end example
Note that the pattern must not necessarily contain "%d" or
"%0 at var{N}d", for example to convert a single image file
@file{img.jpeg} you can employ the command:
@example
-ffmpeg -f image2 -i img.jpeg img.png
+avconv -i img.jpeg img.png
@end example
@section applehttp
@@ -70,7 +70,7 @@ Apple HTTP Live Streaming demuxer.
This demuxer presents all AVStreams from all variant streams.
The id field is set to the bitrate variant index number. By setting
-the discard flags on AVStreams (by pressing 'a' or 'v' in ffplay),
+the discard flags on AVStreams (by pressing 'a' or 'v' in avplay),
the caller can decide which variant streams to actually receive.
The total bitrate of the variant that the stream belongs to is
available in a metadata key named "variant_bitrate".
diff --git a/doc/developer.texi b/doc/developer.texi
index 244ded7..046743f 100644
--- a/doc/developer.texi
+++ b/doc/developer.texi
@@ -17,7 +17,7 @@
decoding). Look at @file{libavcodec/apiexample.c} to see how to use it.
@item libavformat is the library containing the file format handling (mux and
-demux code for several formats). Look at @file{ffplay.c} to use it in a
+demux code for several formats). Look at @file{avplay.c} to use it in a
player. See @file{libavformat/output-example.c} to use it to generate
audio or video streams.
@@ -31,66 +31,88 @@ only the public api is used.
You can use Libav in your commercial program, but you must abide to the
license, LGPL or GPL depending on the specific features used, please refer
-to @url{http://libav.org/legal.html} for a quick checklist and to
- at url{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.GPLv2},
- at url{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.GPLv3},
- at url{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.LGPLv2.1},
- at url{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.LGPLv3} for the
-exact text of the licenses.
+to @uref{http://libav.org/legal.html, our legal page} for a quick checklist and to
+the following links for the exact text of each license:
+ at uref{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.GPLv2, GPL version 2},
+ at uref{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.GPLv3, GPL version 3},
+ at uref{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.LGPLv2.1, LGPL version 2.1},
+ at uref{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.LGPLv3, LGPL version 3}.
Any modification to the source code can be suggested for inclusion.
-The best way to proceed is to send your patches to the Libav mailing list.
+The best way to proceed is to send your patches to the
+ at uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
+mailing list.
@anchor{Coding Rules}
@section Coding Rules
-Libav is programmed in the ISO C90 language with a few additional
-features from ISO C99, namely:
+ at subsection Code formatting conventions
+The code is written in K&R C style. That means the following:
@itemize @bullet
@item
-the @samp{inline} keyword;
+The control statements are formatted by putting space between the statement
+and parenthesis in the following way:
+ at example
+for (i = 0; i < filter->input_count; i++) @{
+ at end example
@item
- at samp{//} comments;
+The case statement is always located at the same level as the switch itself:
+ at example
+switch (link->init_state) @{
+case AVLINK_INIT:
+ continue;
+case AVLINK_STARTINIT:
+ av_log(filter, AV_LOG_INFO, "circular filter chain detected");
+ return 0;
+ at end example
@item
-designated struct initializers (@samp{struct s x = @{ .i = 17 @};})
+Braces in function declarations are written on the new line:
+ at example
+const char *avfilter_configuration(void)
+@{
+ return LIBAV_CONFIGURATION;
+@}
+ at end example
@item
-compound literals (@samp{x = (struct s) @{ 17, 23 @};})
+In case of a single-statement if, no curly braces are required:
+ at example
+if (!pic || !picref)
+ goto fail;
+ at end example
+ at item
+Do not put spaces immediately inside parentheses. @samp{if (ret)} is
+a valid style; @samp{if ( ret )} is not.
@end itemize
-These features are supported by all compilers we care about, so we will not
-accept patches to remove their use unless they absolutely do not impair
-clarity and performance.
-
-All code must compile with recent versions of GCC and a number of other
-currently supported compilers. To ensure compatibility, please do not use
-additional C99 features or GCC extensions. Especially watch out for:
+There are the following guidelines regarding the indentation in files:
@itemize @bullet
@item
-mixing statements and declarations;
- at item
- at samp{long long} (use @samp{int64_t} instead);
- at item
- at samp{__attribute__} not protected by @samp{#ifdef __GNUC__} or similar;
- at item
-GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
- at end itemize
-
Indent size is 4.
-The presentation is one inspired by 'indent -i4 -kr -nut'.
+ at item
The TAB character is forbidden outside of Makefiles as is any
form of trailing whitespace. Commits containing either will be
rejected by the git repository.
+ at item
+You should try to limit your code lines to 80 characters; however, do so if
+and only if this improves readability.
+ at end itemize
+The presentation is one inspired by 'indent -i4 -kr -nut'.
The main priority in Libav is simplicity and small code size in order to
minimize the bug count.
-Comments: Use the JavaDoc/Doxygen
-format (see examples below) so that code documentation
+ at subsection Comments
+Use the JavaDoc/Doxygen format (see examples below) so that code documentation
can be generated automatically. All nontrivial functions should have a comment
above them explaining what the function does, even if it is just one sentence.
All structures and their member variables should be documented, too.
+
+Avoid Qt-style and similar Doxygen syntax with @code{!} in it, i.e. replace
+ at code{//!} with @code{///} and similar. Also @@ syntax should be employed
+for markup commands, i.e. use @code{@@param} and not @code{\param}.
+
@example
/**
- * @@file mpeg.c
+ * @@file
* MPEG codec.
* @@author ...
*/
@@ -118,11 +140,97 @@ int myfunc(int my_parameter)
...
@end example
+ at subsection C language features
+
+Libav is programmed in the ISO C90 language with a few additional
+features from ISO C99, namely:
+ at itemize @bullet
+ at item
+the @samp{inline} keyword;
+ at item
+ at samp{//} comments;
+ at item
+designated struct initializers (@samp{struct s x = @{ .i = 17 @};})
+ at item
+compound literals (@samp{x = (struct s) @{ 17, 23 @};})
+ at end itemize
+
+These features are supported by all compilers we care about, so we will not
+accept patches to remove their use unless they absolutely do not impair
+clarity and performance.
+
+All code must compile with recent versions of GCC and a number of other
+currently supported compilers. To ensure compatibility, please do not use
+additional C99 features or GCC extensions. Especially watch out for:
+ at itemize @bullet
+ at item
+mixing statements and declarations;
+ at item
+ at samp{long long} (use @samp{int64_t} instead);
+ at item
+ at samp{__attribute__} not protected by @samp{#ifdef __GNUC__} or similar;
+ at item
+GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
+ at end itemize
+
+ at subsection Naming conventions
+All names are using underscores (_), not CamelCase. For example,
+ at samp{avfilter_get_video_buffer} is a valid function name and
+ at samp{AVFilterGetVideo} is not. The only exception from this are structure
+names; they should always be in the CamelCase
+
+There are following conventions for naming variables and functions:
+ at itemize @bullet
+ at item
+For local variables no prefix is required.
+ at item
+For variables and functions declared as @code{static} no prefixes are required.
+ at item
+For variables and functions used internally by the library, @code{ff_} prefix
+should be used.
+For example, @samp{ff_w64_demuxer}.
+ at item
+For variables and functions used internally across multiple libraries, use
+ at code{avpriv_}. For example, @samp{avpriv_aac_parse_header}.
+ at item
+For exported names, each library has its own prefixes. Just check the existing
+code and name accordingly.
+ at end itemize
+
+ at subsection Miscellanous conventions
+ at itemize @bullet
+ at item
fprintf and printf are forbidden in libavformat and libavcodec,
please use av_log() instead.
-
+ at item
Casts should be used only when necessary. Unneeded parentheses
should also be avoided if they don't make the code easier to understand.
+ at end itemize
+
+ at subsection Editor configuration
+In order to configure Vim to follow Libav formatting conventions, paste
+the following snippet into your @file{.vimrc}:
+ at example
+" indentation rules for libav: 4 spaces, no tabs
+set expandtab
+set shiftwidth=4
+set softtabstop=4
+" allow tabs in Makefiles
+autocmd FileType make set noexpandtab shiftwidth=8 softtabstop=8
+" Trailing whitespace and tabs are forbidden, so highlight them.
+highlight ForbiddenWhitespace ctermbg=red guibg=red
+match ForbiddenWhitespace /\s\+$\|\t/
+" Do not highlight spaces at the end of line while typing on that line.
+autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@@<!$/
+ at end example
+
+For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
+ at example
+(setq c-default-style "k&r")
+(setq-default c-basic-offset 4)
+(setq-default indent-tabs-mode nil)
+(setq-default show-trailing-whitespace t)
+ at end example
@section Development Policy
@@ -177,7 +285,10 @@ should also be avoided if they don't make the code easier to understand.
When applying patches that have been discussed (at length) on the mailing
list, reference the thread in the log message.
@item
- Subscribe to the libav-devel and libav-commits mailing list.
+ Subscribe to the
+ @uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel} and
+ @uref{https://lists.libav.org/mailman/listinfo/libav-commits, libav-commits}
+ mailing lists.
Bugs and possible improvements or general questions regarding commits
are discussed on libav-devel. We expect you to react if problems with
your code are uncovered.
@@ -222,7 +333,7 @@ Note, some rules were borrowed from the MPlayer project.
@section Submitting patches
-First, read the (@pxref{Coding Rules}) above if you did not yet, in particular
+First, read the @ref{Coding Rules} above if you did not yet, in particular
the rules regarding patch submission.
As stated already, please do not submit a patch which contains several
@@ -236,13 +347,14 @@ for us and greatly increases your chances of getting your patch applied.
Use the patcheck tool of Libav to check your patch.
The tool is located in the tools directory.
-Run the @pxref{Regression Tests} before submitting a patch in order to verify
+Run the @ref{Regression Tests} before submitting a patch in order to verify
it does not cause unexpected problems.
Patches should be posted as base64 encoded attachments (or any other
encoding which ensures that the patch will not be trashed during
-transmission) to the libav-devel mailing list, see
- at url{https://lists.libav.org/mailman/listinfo/libav-devel}
+transmission) to the
+ at uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
+mailing list.
It also helps quite a bit if you tell us what the patch does (for example
'replaces lrint by lrintf'), and why (for example '*BSD isn't C99 compliant
@@ -275,7 +387,7 @@ send a reminder by email. Your patch should eventually be dealt with.
AVInputFormat/AVOutputFormat struct?
@item
Did you bump the minor version number (and reset the micro version
- number) in @file{avcodec.h} or @file{avformat.h}?
+ number) in @file{libavcodec/version.h} or @file{libavformat/version.h}?
@item
Did you register it in @file{allcodecs.c} or @file{allformats.c}?
@item
@@ -308,15 +420,15 @@ send a reminder by email. Your patch should eventually be dealt with.
@enumerate
@item
- Do the regression tests pass with the patch applied?
+ Does @code{make fate} pass with the patch applied?
@item
Does @code{make checkheaders} pass with the patch applied?
@item
Is the patch against latest Libav git master branch?
@item
- Are you subscribed to libav-devel?
- (@url{https://lists.libav.org/mailman/listinfo/libav-devel}
- the list is subscribers)
+ Are you subscribed to the
+ @uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
+ mailing list? (Only list subscribers are allowed to post.)
@item
Have you checked that the changes are minimal, so that the same cannot be
achieved with a smaller patch and/or simpler final code?
@@ -370,7 +482,9 @@ send a reminder by email. Your patch should eventually be dealt with.
@section Patch review process
-All patches posted to libav-devel will be reviewed, unless they contain a
+All patches posted to the
+ at uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
+mailing list will be reviewed, unless they contain a
clear note that the patch is not for the git master branch.
Reviews and comments will be posted as replies to the patch on the
mailing list. The patch submitter then has to take care of every comment,
@@ -400,6 +514,6 @@ Improvements to codec or demuxer might change the FATE results. Make sure
to commit the update reference with the change and to explain in the comment
why the expected result changed.
-Please refer to @file{doc/fate.txt}.
+Please refer to @url{fate.html}.
@bye
diff --git a/doc/doxy/doxy_stylesheet.css b/doc/doxy/doxy_stylesheet.css
new file mode 100644
index 0000000..ff1e214
--- /dev/null
+++ b/doc/doxy/doxy_stylesheet.css
@@ -0,0 +1,1097 @@
+/* The standard CSS for doxygen */
+
+/* @group Heading Levels */
+
+
+h1 {
+ font-size: 150%;
+}
+
+.title {
+ font-weight: bold;
+ margin: 10px 2px;
+ background-color: #7BB37B;
+ border: 1px solid #6A996A;
+ color: #151515;
+ font-size: 1.2em;
+ padding-bottom: 0.2em;
+ padding-left: 0.4em;
+ padding-top: 0.2em;
+}
+
+h2 {
+ font-size: 120%;
+}
+
+h3 {
+ font-size: 100%;
+}
+
+dt {
+ font-weight: bold;
+}
+
+div.multicol {
+ -moz-column-gap: 1em;
+ -webkit-column-gap: 1em;
+ -moz-column-count: 3;
+ -webkit-column-count: 3;
+}
+
+p.startli, p.startdd, p.starttd {
+ margin-top: 2px;
+}
+
+p.endli {
+ margin-bottom: 0px;
+}
+
+p.enddd {
+ margin-bottom: 4px;
+}
+
+p.endtd {
+ margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+}
+
+span.legend {
+ font-size: 70%;
+ text-align: center;
+}
+
+h3.version {
+ font-size: 90%;
+ text-align: center;
+}
+
+div.qindex, div.navtab{
+ background-color: #EBF6EB;
+ border: 1px solid #A3D7A3;
+ text-align: center;
+}
+
+div.qindex, div.navpath {
+ width: 100%;
+ line-height: 140%;
+}
+
+div.navtab {
+ margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+ color: #3D8C3D;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+.contents a:visited {
+ color: #46A246;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a.qindex {
+ font-weight: bold;
+}
+
+a.qindexHL {
+ font-weight: bold;
+ background-color: #9CD49C;
+ color: #ffffff;
+ border: 1px double #86CA86;
+}
+
+.contents a.qindexHL:visited {
+ color: #ffffff;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code {
+ color: #4665A2;
+}
+
+a.codeRef {
+ color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
+.fragment {
+ font-family: monospace, fixed;
+ font-size: 105%;
+}
+
+pre.fragment {
+ border: 1px solid #C4E5C4;
+ background-color: #FBFDFB;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ overflow: auto;
+ word-wrap: break-word;
+ font-size: 9pt;
+ line-height: 125%;
+}
+
+div.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px;
+ padding: 0.2em;
+ border: solid thin #333;
+ border-radius: 0.5em;
+ -webkit-border-radius: .5em;
+ -moz-border-radius: .5em;
+ box-shadow: 2px 2px 3px #999;
+ -webkit-box-shadow: 2px 2px 3px #999;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+ background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ font-weight: bold;
+}
+
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
+}
+
+div.contents {
+ margin-top: 10px;
+ margin-left: 8px;
+ margin-right: 8px;
+}
+
+td.indexkey {
+ background-color: #EBF6EB;
+ font-weight: bold;
+ border: 1px solid #C4E5C4;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
+ white-space: nowrap;
+ vertical-align: top;
+}
+
+td.indexvalue {
+ background-color: #EBF6EB;
+ border: 1px solid #C4E5C4;
+ padding: 2px 10px;
+ margin: 2px 0px;
+}
+
+tr.memlist {
+ background-color: #EEF7EE;
+}
+
+p.formulaDsp {
+ text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl {
+ vertical-align: middle;
+}
+
+div.center {
+ text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px;
+}
+
+div.center img {
+ border: 0px;
+}
+
+#footer {
+ margin: -10px 1em 0;
+ padding-top: 20px;
+ text-align: center;
+ font-size: small;
+}
+
+address.footer {
+ background-color: #ffffff;
+ text-align: center;
+}
+
+img.footer {
+ border: 0px;
+ vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
+}
+
+span.keywordtype {
+ color: #604020
+}
+
+span.keywordflow {
+ color: #e08000
+}
+
+span.comment {
+ color: #800000
+}
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+/* @end */
+
+/*
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #A3D7A3;
+}
+
+th.dirtab {
+ background: #EBF6EB;
+ font-weight: bold;
+}
+
+hr {
+ height: 0px;
+ border: none;
+ border-top: 1px solid #4AAA4A;
+}
+
+hr.footer {
+ height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+ border-spacing: 0px;
+ padding: 0px;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: #F9FCF9;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
+}
+
+.memItemLeft, .memItemRight, .memTemplParams {
+ border-top: 1px solid #C4E5C4;
+}
+
+.memItemLeft, .memTemplItemLeft {
+ white-space: nowrap;
+}
+
+.memItemRight {
+ width: 100%;
+}
+
+.memTemplParams {
+ color: #46A246;
+ white-space: nowrap;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+ font-size: 80%;
+ color: #46A246;
+ font-weight: normal;
+ margin-left: 9px;
+}
+
+.memnav {
+ background-color: #EBF6EB;
+ border: 1px solid #A3D7A3;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
+.mempage {
+ width: 100%;
+}
+
+.memitem {
+ padding: 0;
+ margin-bottom: 10px;
+ margin-right: 5px;
+}
+
+.memname {
+ white-space: nowrap;
+ font-weight: bold;
+ margin-left: 6px;
+}
+
+.memproto, dl.reflist dt {
+ border-top: 1px solid #A8D9A8;
+ border-left: 1px solid #A8D9A8;
+ border-right: 1px solid #A8D9A8;
+ padding: 6px 0px 6px 0px;
+ color: #255525;
+ font-weight: bold;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ /* opera specific markup */
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ border-top-right-radius: 8px;
+ border-top-left-radius: 8px;
+ /* firefox specific markup */
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ -moz-border-radius-topright: 8px;
+ -moz-border-radius-topleft: 8px;
+ /* webkit specific markup */
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ -webkit-border-top-right-radius: 8px;
+ -webkit-border-top-left-radius: 8px;
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #E2F2E2;
+
+}
+
+.memdoc, dl.reflist dd {
+ border-bottom: 1px solid #A8D9A8;
+ border-left: 1px solid #A8D9A8;
+ border-right: 1px solid #A8D9A8;
+ padding: 2px 5px;
+ background-color: #FBFDFB;
+ border-top-width: 0;
+ /* opera specific markup */
+ border-bottom-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ /* firefox specific markup */
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7FBF7 95%, #EEF7EE);
+ /* webkit specific markup */
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7FBF7), to(#EEF7EE));
+}
+
+dl.reflist dt {
+ padding: 5px;
+}
+
+dl.reflist dd {
+ margin: 0px 0px 10px 0px;
+ padding: 5px;
+}
+
+.paramkey {
+ text-align: right;
+}
+
+.paramtype {
+ white-space: nowrap;
+}
+
+.paramname {
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
+}
+
+.params, .retval, .exception, .tparams {
+ border-spacing: 6px 2px;
+}
+
+.params .paramname, .retval .paramname {
+ font-weight: bold;
+ vertical-align: top;
+}
+
+.params .paramtype {
+ font-style: italic;
+ vertical-align: top;
+}
+
+.params .paramdir {
+ font-family: "courier new",courier,monospace;
+ vertical-align: top;
+}
+
+
+
+
+/* @end */
+
+/* @group Directory (tree) */
+
+/* for the tree view */
+
+.ftvtree {
+ font-family: sans-serif;
+ margin: 0px;
+}
+
+/* these are for tree view when used as main index */
+
+.directory {
+ font-size: 9pt;
+ font-weight: bold;
+ margin: 5px;
+}
+
+.directory h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice. Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+/*
+.directory h3.swap {
+ height: 61px;
+ background-repeat: no-repeat;
+ background-image: url("yourimage.gif");
+}
+.directory h3.swap span {
+ display: none;
+}
+*/
+
+.directory > h3 {
+ margin-top: 0;
+}
+
+.directory p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory div {
+ display: none;
+ margin: 0px;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+/* these are for tree view when not used as main index */
+
+.directory-alt {
+ font-size: 100%;
+ font-weight: bold;
+}
+
+.directory-alt h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+.directory-alt > h3 {
+ margin-top: 0;
+}
+
+.directory-alt p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory-alt div {
+ display: none;
+ margin: 0px;
+}
+
+.directory-alt img {
+ vertical-align: -30%;
+}
+
+/* @end */
+
+div.dynheader {
+ margin-top: 8px;
+}
+
+address {
+ font-style: normal;
+ color: #2A612A;
+}
+
+table.doxtable {
+ border-collapse:collapse;
+}
+
+table.doxtable td, table.doxtable th {
+ border: 1px solid #2D682D;
+ padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+ background-color: #377F37;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+}
+
+table.fieldtable {
+ width: 100%;
+ margin-bottom: 10px;
+ border: 1px solid #A8D9A8;
+ border-spacing: 0px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+ box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+ padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+ white-space: nowrap;
+ border-right: 1px solid #A8D9A8;
+ border-bottom: 1px solid #A8D9A8;
+ vertical-align: top;
+}
+
+.fieldtable td.fielddoc {
+ border-bottom: 1px solid #A8D9A8;
+ width: 100%;
+}
+
+.fieldtable tr:last-child td {
+ border-bottom: none;
+}
+
+.fieldtable th {
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #E2F2E2;
+ font-size: 90%;
+ color: #255525;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-topright: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom: 1px solid #A8D9A8;
+}
+
+
+.tabsearch {
+ top: 0px;
+ left: 10px;
+ height: 36px;
+ background-image: url('tab_b.png');
+ z-index: 101;
+ overflow: hidden;
+ font-size: 13px;
+}
+
+.navpath ul
+{
+ font-size: 11px;
+ background-image:url('tab_b.png');
+ background-repeat:repeat-x;
+ height:30px;
+ line-height:30px;
+ color:#8ACC8A;
+ border:solid 1px #C2E4C2;
+ overflow:hidden;
+ margin:0px;
+ padding:0px;
+}
+
+.navpath li
+{
+ list-style-type:none;
+ float:left;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:url('bc_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#367C36;
+}
+
+.navpath li.navelem a
+{
+ height:32px;
+ display:block;
+ text-decoration: none;
+ outline: none;
+}
+
+.navpath li.navelem a:hover
+{
+ color:#68BD68;
+}
+
+.navpath li.footer
+{
+ list-style-type:none;
+ float:right;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:none;
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#367C36;
+ font-size: 8pt;
+}
+
+
+div.summary
+{
+ margin-top: 12px;
+ text-align: center;
+}
+
+div.summary a
+{
+ white-space: nowrap;
+}
+
+div.ingroups
+{
+ margin-left: 5px;
+ font-size: 8pt;
+ padding-left: 5px;
+ width: 50%;
+ text-align: left;
+}
+
+div.ingroups a
+{
+ white-space: nowrap;
+}
+
+div.headertitle
+{
+ padding: 5px 5px 5px 7px;
+}
+
+dl
+{
+ padding: 0 0 0 10px;
+}
+
+dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug
+{
+ border-left:4px solid;
+ padding: 0 0 0 6px;
+}
+
+dl.note
+{
+ border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+ border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+ border-color: #00D000;
+}
+
+dl.deprecated
+{
+ border-color: #505050;
+}
+
+dl.todo
+{
+ border-color: #00C0E0;
+}
+
+dl.test
+{
+ border-color: #3030E0;
+}
+
+dl.bug
+{
+ border-color: #C08050;
+}
+
+#projectlogo
+{
+ text-align: center;
+ vertical-align: bottom;
+ border-collapse: separate;
+}
+
+#projectlogo img
+{
+ border: 0px none;
+}
+
+#projectname
+{
+ font: 300% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 2px 0px;
+}
+
+#projectbrief
+{
+ font: 120% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#projectnumber
+{
+ font: 50% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#titlearea
+{
+ padding: 0px;
+ margin: 0px;
+ width: 100%;
+ border-bottom: 1px solid #53B453;
+}
+
+.image
+{
+ text-align: center;
+}
+
+.dotgraph
+{
+ text-align: center;
+}
+
+.mscgraph
+{
+ text-align: center;
+}
+
+.caption
+{
+ font-weight: bold;
+}
+
+div.zoom
+{
+ border: 1px solid #90CE90;
+}
+
+dl.citelist {
+ margin-bottom:50px;
+}
+
+dl.citelist dt {
+ color:#337533;
+ float:left;
+ font-weight:bold;
+ margin-right:10px;
+ padding:5px;
+}
+
+dl.citelist dd {
+ margin:2px 0;
+ padding:5px 0;
+}
+
+ at media print
+{
+ #top { display: none; }
+ #side-nav { display: none; }
+ #nav-path { display: none; }
+ body { overflow:visible; }
+ h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+ .summary { display: none; }
+ .memitem { page-break-inside: avoid; }
+ #doc-content
+ {
+ margin-left:0 !important;
+ height:auto !important;
+ width:auto !important;
+ overflow:inherit;
+ display:inline;
+ }
+ pre.fragment
+ {
+ overflow: visible;
+ text-wrap: unrestricted;
+ white-space: -moz-pre-wrap; /* Moz */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 */
+ word-wrap: break-word; /* IE 5.5+ */
+ }
+}
+
+/* tabs */
+
+.tabs, .tabs2, .tabs3 {
+ z-index: 101;
+}
+
+.tablist {
+ margin: auto;
+ display: table;
+}
+
+.tablist li {
+ float: left;
+ display: table-cell;
+ list-style: none;
+ margin:0 4px;
+}
+
+.tablist a {
+ display: block;
+ padding: 0 0.3em;
+ color: #285D28;
+ text-decoration: none;
+ outline: none;
+}
+
+.tabs3 .tablist a {
+ padding-left: 10px;
+}
+
+
+/* libav.org stylesheet */
+
+a {
+ color: #2D6198;
+}
+
+a:visited {
+ color: #884488;
+}
+
+h1 a, h2 a, h3 a {
+ text-decoration: inherit;
+ color: inherit;
+}
+
+#body {
+ margin: 0 1em;
+}
+
+body {
+ background-color: #313131;
+ margin: 0;
+}
+
+.center {
+ margin-left: auto;
+ margin-right: auto;
+ text-align: center;
+}
+
+#container {
+ background-color: white;
+ color: #202020;
+ margin-left: 1em;
+ margin-right: 1em;
+}
+
+h1 {
+ background-color: #7BB37B;
+ border: 1px solid #6A996A;
+ color: #151515;
+ font-size: 1.2em;
+ padding-bottom: 0.2em;
+ padding-left: 0.4em;
+ padding-top: 0.2em;
+}
+
+h2 {
+ color: #313131;
+ font-size: 1.2em;
+}
+
+h3 {
+ color: #313131;
+ font-size: 0.8em;
+ margin-bottom: -8px;
+}
+
+img {
+ border: 0;
+}
+
+.tabs {
+ margin-top: 12px;
+ border-top: 1px solid #5C665C;
+}
+
+.tabs, .tabs2, .tabs3, .tabs4 {
+ background-color: #738073;
+ border-bottom: 1px solid #5C665C;
+ border-left: 1px solid #5C665C;
+ border-right: 1px solid #5C665C;
+ position: relative;
+ text-align: center;
+}
+
+.tabs a,
+.tabs2 a,
+.tabs3 a,
+.tabs4 a {
+ color: white;
+ padding: 0.3em;
+ text-decoration: none;
+}
+
+
+.tabs ul,
+.tabs2 ul,
+.tabs3 ul,
+.tabs4 ul {
+ padding: 0;
+}
+
+.tabs li.current a,
+.tabs2 li.current a,
+.tabs3 li.current a,
+.tabs4 li.current a {
+ background-color: #414141;
+ color: white;
+ text-decoration: none;
+}
+
+.tabs a:hover,
+.tabs2 a:hover,
+.tabs3 a:hover,
+.tabs4 a:hover {
+ background-color: #313131 !important;
+ color: white;
+ text-decoration: none;
+}
+
+p {
+ margin-left: 1em;
+ margin-right: 1em;
+}
+
+table {
+ margin-left: 2em;
+}
+
+pre {
+ margin-left: 2em;
+}
+
+#proj_desc {
+ font-size: 1.2em;
+}
diff --git a/doc/doxy/footer.html b/doc/doxy/footer.html
new file mode 100644
index 0000000..7217351
--- /dev/null
+++ b/doc/doxy/footer.html
@@ -0,0 +1,10 @@
+ </div>
+
+ <div id="footer">
+ Generated on $datetime for $projectname by <a href="http://www.doxygen.org/index.html">doxygen</a> $doxygenversion
+ </div>
+
+</div>
+
+</body>
+</html>
diff --git a/doc/doxy/header.html b/doc/doxy/header.html
new file mode 100644
index 0000000..9e57c98
--- /dev/null
+++ b/doc/doxy/header.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
+<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
+<link href="$relpath$doxy_stylesheet.css" rel="stylesheet" type="text/css" />
+</head>
+
+<div id="container">
+
+<div id="body">
+ <div>
diff --git a/doc/encoders.texi b/doc/encoders.texi
index d507b66..830981f 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -320,10 +320,10 @@ apply Dolby Surround EX processing.
Not Indicated (default)
@item 1
@itemx on
-Dolby Surround EX On
+Dolby Surround EX Off
@item 2
@itemx off
-Dolby Surround EX Off
+Dolby Surround EX On
@end table
@item -dheadphone_mode @var{mode}
@@ -337,10 +337,10 @@ processing.
Not Indicated (default)
@item 1
@itemx on
-Dolby Headphone On
+Dolby Headphone Off
@item 2
@itemx off
-Dolby Headphone Off
+Dolby Headphone On
@end table
@item -ad_conv_type @var{type}
diff --git a/doc/eval.texi b/doc/eval.texi
index d8c693f..7f8f365 100644
--- a/doc/eval.texi
+++ b/doc/eval.texi
@@ -1,7 +1,7 @@
@chapter Expression Evaluation
@c man begin EXPRESSION EVALUATION
-When evaluating an arithemetic expression, Libav uses an internal
+When evaluating an arithmetic expression, Libav uses an internal
formula evaluator, implemented through the @file{libavutil/eval.h}
interface.
@@ -53,7 +53,7 @@ returns the value stored in the internal variable.
@item ld(var)
Allow to load the value of the internal variable with number
- at var{var}, which was previosly stored with st(@var{var}, @var{expr}).
+ at var{var}, which was previously stored with st(@var{var}, @var{expr}).
The function returns the loaded value.
@item while(cond, expr)
@@ -72,6 +72,13 @@ integer. For example, "floor(-1.5)" is "-2.0".
@item trunc(expr)
Round the value of expression @var{expr} towards zero to the nearest
integer. For example, "trunc(-1.5)" is "-1.0".
+
+ at item sqrt(expr)
+Compute the square root of @var{expr}. This is equivalent to
+"(@var{expr})^.5".
+
+ at item not(expr)
+Return 1.0 if @var{expr} is zero, 0.0 otherwise.
@end table
Note that:
@@ -89,11 +96,6 @@ is equivalent to
A*B + not(A)*C
@end example
-When A evaluates to either 1 or 0, that is the same as
- at example
-A*B + eq(A,0)*C
- at end example
-
In your C code, you can extend the list of unary and binary functions,
and define recognized constants, so that they are available for your
expressions.
diff --git a/doc/faq.texi b/doc/faq.texi
index 3d7a275..8044200 100644
--- a/doc/faq.texi
+++ b/doc/faq.texi
@@ -11,22 +11,6 @@
@chapter General Questions
- at section When will the next Libav version be released? / Why are Libav releases so few and far between?
-
-Like most open source projects Libav suffers from a certain lack of
-manpower. For this reason the developers have to prioritize the work
-they do and putting out releases is not at the top of the list, fixing
-bugs and reviewing patches takes precedence. Please don't complain or
-request more timely and/or frequent releases unless you are willing to
-help out creating them.
-
- at section I have a problem with an old version of Libav; where should I report it?
-Nowhere. We do not support old Libav versions in any way, we simply lack
-the time, motivation and manpower to do so. If you have a problem with an
-old version of Libav, upgrade to the latest git snapshot. If you
-still experience the problem, then you can report it according to the
-guidelines in @url{http://libav.org/bugreports.html}.
-
@section Why doesn't Libav support feature [xyz]?
Because no one has taken on that task yet. Libav development is
@@ -40,34 +24,10 @@ No. Windows DLLs are not portable, bloated and often slow.
Moreover Libav strives to support all codecs natively.
A DLL loader is not conducive to that goal.
- at section My bug report/mail to libav-devel/user has not received any replies.
-
-Likely reasons
- at itemize
- at item We are busy and haven't had time yet to read your report or
-investigate the issue.
- at item You didn't follow @url{http://libav.org/bugreports.html}.
- at item You didn't use git master.
- at item You reported a segmentation fault without gdb output.
- at item You describe a problem but not how to reproduce it.
- at item It's unclear if you use ffmpeg as command line tool or use
-libav* from another application.
- at item You speak about a video having problems on playback but
-not what you use to play it.
- at item We have no faint clue what you are talking about besides
-that it is related to Libav.
- at end itemize
-
- at section Is there a forum for Libav? I do not like mailing lists.
-
-You may view our mailing lists with a more forum-alike look here:
- at url{http://dir.gmane.org/gmane.comp.video.ffmpeg.user},
-but, if you post, please remember that our mailing list rules still apply there.
-
- at section I cannot read this file although this format seems to be supported by ffmpeg.
-
-Even if ffmpeg can read the container format, it may not support all its
-codecs. Please consult the supported codec list in the ffmpeg
+ at section I cannot read this file although this format seems to be supported by avconv.
+
+Even if avconv can read the container format, it may not support all its
+codecs. Please consult the supported codec list in the avconv
documentation.
@section Which codecs are supported by Windows?
@@ -121,11 +81,6 @@ problem and an NP-hard problem...
@chapter Usage
- at section ffmpeg does not work; what is wrong?
-
-Try a @code{make distclean} in the ffmpeg source directory before the build. If this does not help see
-(@url{http://libav.org/bugreports.html}).
-
@section How do I encode single pictures into movies?
First, rename your pictures to follow a numerical sequence.
@@ -133,7 +88,7 @@ For example, img1.jpg, img2.jpg, img3.jpg,...
Then you may run:
@example
- ffmpeg -f image2 -i img%d.jpg /tmp/a.mpg
+ avconv -f image2 -i img%d.jpg /tmp/a.mpg
@end example
Notice that @samp{%d} is replaced by the image number.
@@ -156,17 +111,17 @@ If you want to sequence them by oldest modified first, substitute
Then run:
@example
- ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
+ avconv -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
@end example
-The same logic is used for any image format that ffmpeg reads.
+The same logic is used for any image format that avconv reads.
@section How do I encode movie to single pictures?
Use:
@example
- ffmpeg -i movie.mpg movie%d.jpg
+ avconv -i movie.mpg movie%d.jpg
@end example
The @file{movie.mpg} used as input will be converted to
@@ -174,15 +129,15 @@ The @file{movie.mpg} used as input will be converted to
Instead of relying on file format self-recognition, you may also use
@table @option
- at item -vcodec ppm
- at item -vcodec png
- at item -vcodec mjpeg
+ at item -c:v ppm
+ at item -c:v png
+ at item -c:v mjpeg
@end table
to force the encoding.
Applying that to the previous example:
@example
- ffmpeg -i movie.mpg -f image2 -vcodec mjpeg menu%d.jpg
+ avconv -i movie.mpg -f image2 -c:v mjpeg menu%d.jpg
@end example
Beware that there is no "jpeg" codec. Use "mjpeg" instead.
@@ -204,56 +159,18 @@ Try '-f image2 test%d.jpg'.
@section Why can I not change the framerate?
Some codecs, like MPEG-1/2, only allow a small number of fixed framerates.
-Choose a different codec with the -vcodec command line option.
+Choose a different codec with the -c:v command line option.
- at section How do I encode Xvid or DivX video with ffmpeg?
+ at section How do I encode Xvid or DivX video with avconv?
Both Xvid and DivX (version 4+) are implementations of the ISO MPEG-4
standard (note that there are many other coding formats that use this
-same standard). Thus, use '-vcodec mpeg4' to encode in these formats. The
+same standard). Thus, use '-c:v mpeg4' to encode in these formats. The
default fourcc stored in an MPEG-4-coded file will be 'FMP4'. If you want
a different fourcc, use the '-vtag' option. E.g., '-vtag xvid' will
force the fourcc 'xvid' to be stored as the video fourcc rather than the
default.
- at section How do I encode videos which play on the iPod?
-
- at table @option
- at item needed stuff
--acodec libfaac -vcodec mpeg4 width<=320 height<=240
- at item working stuff
-mv4, title
- at item non-working stuff
-B-frames
- at item example command line
-ffmpeg -i input -acodec libfaac -ab 128k -vcodec mpeg4 -b 1200k -mbd 2 -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -s 320x180 -metadata title=X output.mp4
- at end table
-
- at section How do I encode videos which play on the PSP?
-
- at table @option
- at item needed stuff
--acodec libfaac -vcodec mpeg4 width*height<=76800 width%16=0 height%16=0 -ar 24000 -r 30000/1001 or 15000/1001 -f psp
- at item working stuff
-mv4, title
- at item non-working stuff
-B-frames
- at item example command line
-ffmpeg -i input -acodec libfaac -ab 128k -vcodec mpeg4 -b 1200k -ar 24000 -mbd 2 -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -s 368x192 -r 30000/1001 -metadata title=X -f psp output.mp4
- at item needed stuff for H.264
--acodec libfaac -vcodec libx264 width*height<=76800 width%16=0? height%16=0? -ar 48000 -coder 1 -r 30000/1001 or 15000/1001 -f psp
- at item working stuff for H.264
-title, loop filter
- at item non-working stuff for H.264
-CAVLC
- at item example command line
-ffmpeg -i input -acodec libfaac -ab 128k -vcodec libx264 -b 1200k -ar 48000 -mbd 2 -coder 1 -cmp 2 -subcmp 2 -s 368x192 -r 30000/1001 -metadata title=X -f psp -flags loop -trellis 2 -partitions parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 output.mp4
- at item higher resolution for newer PSP firmwares, width<=480, height<=272
--vcodec libx264 -level 21 -coder 1 -f psp
- at item example command line
-ffmpeg -i input -acodec libfaac -ab 128k -ac 2 -ar 48000 -vcodec libx264 -level 21 -b 640k -coder 1 -f psp -flags +loop -trellis 2 -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 -g 250 -s 480x272 output.mp4
- at end table
-
@section Which are good parameters for encoding high quality MPEG-4?
'-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -g 300 -pass 1/2',
@@ -265,7 +182,7 @@ things to try: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd'.
but beware the '-g 100' might cause problems with some decoders.
Things to try: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd.
- at section Interlaced video looks very bad when encoded with ffmpeg, what is wrong?
+ at section Interlaced video looks very bad when encoded with avconv, what is wrong?
You should use '-flags +ilme+ildct' and maybe '-flags +alt' for interlaced
material, and try '-top 0/1' if the result looks really messed-up.
@@ -280,12 +197,13 @@ Just create an "input.avs" text file with this single line ...
@example
DirectShowSource("C:\path to your file\yourfile.asf")
@end example
-... and then feed that text file to ffmpeg:
+... and then feed that text file to avconv:
@example
- ffmpeg -i input.avs
+ avconv -i input.avs
@end example
-For ANY other help on Avisynth, please visit @url{http://www.avisynth.org/}.
+For ANY other help on Avisynth, please visit the
+ at uref{http://www.avisynth.org/, Avisynth homepage}.
@section How can I join video files?
@@ -298,13 +216,13 @@ equally humble @code{copy} under Windows), and finally transcoding back to your
format of choice.
@example
-ffmpeg -i input1.avi -sameq intermediate1.mpg
-ffmpeg -i input2.avi -sameq intermediate2.mpg
+avconv -i input1.avi -same_quant intermediate1.mpg
+avconv -i input2.avi -same_quant intermediate2.mpg
cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
-ffmpeg -i intermediate_all.mpg -sameq output.avi
+avconv -i intermediate_all.mpg -same_quant output.avi
@end example
-Notice that you should either use @code{-sameq} or set a reasonably high
+Notice that you should either use @code{-same_quant} or set a reasonably high
bitrate for your intermediate and output files, if you want to preserve
video quality.
@@ -314,10 +232,10 @@ of named pipes, should your platform support it:
@example
mkfifo intermediate1.mpg
mkfifo intermediate2.mpg
-ffmpeg -i input1.avi -sameq -y intermediate1.mpg < /dev/null &
-ffmpeg -i input2.avi -sameq -y intermediate2.mpg < /dev/null &
+avconv -i input1.avi -same_quant -y intermediate1.mpg < /dev/null &
+avconv -i input2.avi -same_quant -y intermediate2.mpg < /dev/null &
cat intermediate1.mpg intermediate2.mpg |\
-ffmpeg -f mpeg -i - -sameq -vcodec mpeg4 -acodec libmp3lame output.avi
+avconv -f mpeg -i - -same_quant -c:v mpeg4 -acodec libmp3lame output.avi
@end example
Similarly, the yuv4mpegpipe format, and the raw video, raw audio codecs also
@@ -336,35 +254,37 @@ mkfifo temp2.a
mkfifo temp2.v
mkfifo all.a
mkfifo all.v
-ffmpeg -i input1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
-ffmpeg -i input2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
-ffmpeg -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
-@{ ffmpeg -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; @} &
+avconv -i input1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
+avconv -i input2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
+avconv -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
+@{ avconv -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; @} &
cat temp1.a temp2.a > all.a &
cat temp1.v temp2.v > all.v &
-ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
+avconv -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
-f yuv4mpegpipe -i all.v \
- -sameq -y output.flv
+ -same_quant -y output.flv
rm temp[12].[av] all.[av]
@end example
- at section The ffmpeg program does not respect the -maxrate setting, some frames are bigger than maxrate/fps.
+ at section -profile option fails when encoding H.264 video with AAC audio
-Read the MPEG spec about video buffer verifier.
+ at command{avconv} prints an error like
- at section I want CBR, but no matter what I do frame sizes differ.
-
-You do not understand what CBR is, please read the MPEG spec.
-Read about video buffer verifier and constant bitrate.
-The one sentence summary is that there is a buffer and the input rate is
-constant, the output can vary as needed.
+ at example
+Undefined constant or missing '(' in 'baseline'
+Unable to parse option value "baseline"
+Error setting option profile to value baseline.
+ at end example
- at section How do I check if a stream is CBR?
+Short answer: write @option{-profile:v} instead of @option{-profile}.
-To quote the MPEG-2 spec:
-"There is no way to tell that a bitstream is constant bitrate without
-examining all of the vbv_delay values and making complicated computations."
+Long answer: this happens because the @option{-profile} option can apply to both
+video and audio. Specifically the AAC encoder also defines some profiles, none
+of which are named @var{baseline}.
+The solution is to apply the @option{-profile} option to the video stream only
+by using @url{http://libav.org/avconv.html#Stream-specifiers-1, Stream specifiers}.
+Appending @code{:v} to it will do exactly that.
@chapter Development
@@ -398,7 +318,7 @@ the silver bullet that solves this problem, feel free to shoot it at us.
We strongly recommend you to move over from MSVC++ to MinGW tools.
- at section Can I use Libav or libavcodec under Windows?
+ at section Can I use Libav under Windows?
Yes, but the Cygwin or MinGW tools @emph{must} be used to compile Libav.
Read the @emph{Windows} section in the Libav documentation to find more
@@ -408,12 +328,12 @@ information.
No. These tools are too bloated and they complicate the build.
- at section Why not rewrite ffmpeg in object-oriented C++?
+ at section Why not rewrite Libav in object-oriented C++?
Libav is already organized in a highly modular manner and does not need to
be rewritten in a formal object language. Further, many of the developers
favor straight C; it works for them. For more arguments on this matter,
-read "Programming Religion" at (@url{http://www.tux.org/lkml/#s15}).
+read @uref{http://www.tux.org/lkml/#s15, "Programming Religion"}.
@section I do not like the LGPL, can I contribute code under the GPL instead?
@@ -421,15 +341,7 @@ Yes, as long as the code is optional and can easily and cleanly be placed
under #if CONFIG_GPL without breaking anything. So for example a new codec
or filter would be OK under GPL while a bug fix to LGPL code would not.
- at section I want to compile xyz.c alone but my compiler produced many errors.
-
-Common code is in its own files in libav* and is used by the individual
-codecs. They will not work without the common parts, you have to compile
-the whole libav*. If you wish, disable some parts with configure switches.
-You can also try to hack it and remove more, but if you had problems fixing
-the compilation failure then you are probably not qualified for this.
-
- at section I'm using libavcodec from within my C++ application but the linker complains about missing symbols which seem to be available.
+ at section I'm using Libav from within my C++ application but the linker complains about missing symbols which seem to be available.
Libav is a pure C project, so to use the libraries within your C++ application
you need to explicitly state that you are using a C library. You can do this by
@@ -437,39 +349,14 @@ encompassing your Libav includes using @code{extern "C"}.
See @url{http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3}
+ at section I'm using libavutil from within my C++ application but the compiler complains about 'UINT64_C' was not declared in this scope
+
+Libav is a pure C project using C99 math features, in order to enable C++
+to use them you have to append -D__STDC_CONSTANT_MACROS to your CXXFLAGS
+
@section I have a file in memory / a API different from *open/*read/ libc how do I use it with libavformat?
You have to implement a URLProtocol, see @file{libavformat/file.c} in
Libav and @file{libmpdemux/demux_lavf.c} in MPlayer sources.
- at section I get "No compatible shell script interpreter found." in MSys.
-
-The standard MSys bash (2.04) is broken. You need to install 2.05 or later.
-
- at section I get "./configure: line <xxx>: pr: command not found" in MSys.
-
-The standard MSys install doesn't come with pr. You need to get it from the coreutils package.
-
- at section Where can I find libav* headers for Pascal/Delphi?
-
-see @url{http://www.iversenit.dk/dev/ffmpeg-headers/}
-
- at section Where is the documentation about ffv1, msmpeg4, asv1, 4xm?
-
-see @url{http://www.ffmpeg.org/~michael/}
-
- at section How do I feed H.263-RTP (and other codecs in RTP) to libavcodec?
-
-Even if peculiar since it is network oriented, RTP is a container like any
-other. You have to @emph{demux} RTP before feeding the payload to libavcodec.
-In this specific case please look at RFC 4629 to see how it should be done.
-
- at section AVStream.r_frame_rate is wrong, it is much larger than the framerate.
-
-r_frame_rate is NOT the average framerate, it is the smallest framerate
-that can accurately represent all timestamps. So no, it is not
-wrong if it is larger than the average!
-For example, if you have mixed 25 and 30 fps content, then r_frame_rate
-will be 150.
-
@bye
diff --git a/doc/fate.texi b/doc/fate.texi
new file mode 100644
index 0000000..9141eeb
--- /dev/null
+++ b/doc/fate.texi
@@ -0,0 +1,135 @@
+\input texinfo @c -*- texinfo -*-
+
+ at settitle FATE Automated Testing Environment
+ at titlepage
+ at center @titlefont{FATE Automated Testing Environment}
+ at end titlepage
+
+ at top
+
+ at contents
+
+ at chapter Introduction
+
+FATE provides a regression testsuite embedded within the Libav build system.
+It can be run locally and optionally configured to send reports to a web
+aggregator and viewer @url{http://fate.libav.org}.
+
+It is advised to run FATE before submitting patches to the current codebase
+and provide new tests when submitting patches to add additional features.
+
+ at chapter Running FATE
+
+ at section Samples and References
+In order to run, FATE needs a large amount of data (samples and references)
+that is provided separately from the actual source distribution.
+
+To inform the build system about the testsuite location, pass
+ at option{--samples=<path to the samples>} to @command{configure} or set the
+ at var{SAMPLES} Make variable or the @var{FATE_SAMPLES} environment variable
+to a suitable value.
+
+The dataset is available through @command{rsync}, is possible to fetch
+the current sample using the straight rsync command or through a specific
+ at ref{Makefile target}.
+
+ at example
+# rsync -aL rsync://fate-suite.libav.org/fate-suite/ fate-suite
+ at end example
+
+ at example
+# make fate-rsync SAMPLES=fate-suite
+ at end example
+
+
+ at chapter Manual Run
+FATE regression test can be run through @command{make}.
+Specific Makefile targets and Makefile variables are available:
+
+ at anchor{Makefile target}
+ at section FATE Makefile targets
+ at table @option
+ at item fate-list
+List all fate/regression test targets.
+ at item fate-rsync
+Shortcut to download the fate test samples to the specified testsuite location.
+ at item fate
+Run the FATE test suite (requires the fate-suite dataset).
+ at end table
+
+ at section Fate Makefile variables
+ at table @option
+ at item V
+Verbosity level, can be set to 0, 1 or 2.
+ at table @option
+ @item 0
+ show just the test arguments
+ @item 1
+ show just the command used in the test
+ @item 2
+ show everything
+ at end table
+ at item SAMPLES
+Specify or override the path to the FATE samples at make time, it has a
+meaning only while running the regression tests.
+ at item THREADS
+Specify how many threads to use while running regression tests, it is
+quite useful to detect thread-related regressions.
+ at end table
+
+ at example
+ make V=1 SAMPLES=/var/fate/samples THREADS=2 fate
+ at end example
+
+ at chapter Automated Tests
+In order to automatically testing specific configurations, e.g. multiple
+compilers, @command{tests/fate.sh} is provided.
+
+This shell script builds Libav, runs the regression tests and prepares a
+report that can be sent to @url{fate.libav.org} or directly examined locally.
+
+ at section Testing Profiles
+The configuration file passed to @command{fate.sh} is shell scripts as well.
+
+It must provide at least a @var{slot} identifier, the @var{repo} from
+which fetch the sources, the @var{samples} directory, a @var{workdir} with
+enough space to build and run all the tests.
+Optional submit command @var{fate_recv} and a @var{comment} to describe
+the testing profile are available.
+
+Additional optional parameter to tune the Libav building and reporting process
+can be passed.
+
+ at example
+slot= # some unique identifier
+repo=git://git.libav.org/libav.git # the source repository
+samples=/path/to/fate/samples
+workdir= # directory in which to do all the work
+fate_recv="ssh -T fate@@fate.libav.org" # command to submit report
+comment= # optional description
+
+# the following are optional and map to configure options
+arch=
+cpu=
+cross_prefix=
+cc=
+target_os=
+sysroot=
+target_exec=
+target_path=
+extra_cflags=
+extra_ldflags=
+extra_libs=
+extra_conf= # extra configure options not covered above
+
+#make= # name of GNU make if not 'make'
+makeopts= # extra options passed to 'make'
+#tar= # command to create a tar archive from its arguments on
+ # stdout, defaults to 'tar c'
+ at end example
+
+ at section Submitting Reports
+In order to send reports you need to create an @command{ssh} key and send it
+to @email{root@@libav.org}.
+The current server fingerprint is @var{a4:99:d7:d3:1c:92:0d:56:d6:d5:61:be:01:ae:7d:e6}
+
diff --git a/doc/fate.txt b/doc/fate.txt
deleted file mode 100644
index b23d3f6..0000000
--- a/doc/fate.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-FATE Automated Testing Environment
-
-FATE provides a regression testsuite that can be run locally or configured
-to send reports to fate.libav.org.
-In order to run, it needs a large amount of data (samples and references)
-that is provided separately from the actual source distribution.
-
-Use the following command to get the fate test samples
-
-# rsync -aL rsync://fate-suite.libav.org:/fate-suite/ fate-suite
-
-To inform the build system about the testsuite location, pass
-`--samples=<path to the samples>` to configure or set the SAMPLES Make
-variable or the FATE_SAMPLES environment variable to a suitable value.
-
-For information on how to set up FATE to send results to the official Libav
-testing framework, please refer to the following wiki page:
-http://wiki.multimedia.cx/index.php?title=FATE
-
-FATE Makefile targets:
-
-fate-list
- Will list all fate/regression test targets.
-
-fate
- Run the FATE test suite (requires the fate-suite dataset).
-
-Fate Makefile variables:
-
-V
- Verbosity level, can be set to 0, 1 or 2.
- * 0: show just the test arguments
- * 1: show just the command used in the test
- * 2: show everything
-
-SAMPLES
- Specify or override the path to the FATE samples at make time, it has a
- meaning only while running the regression tests.
-
-THREADS
- Specify how many threads to use while running regression tests, it is
- quite useful to detect thread-related regressions.
-
-Example:
- make V=1 SAMPLES=/var/fate/samples THREADS=2 fate
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index cabf395..968d4f6 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -68,7 +68,7 @@ specified for the inputs.
@chapter Options
@c man begin OPTIONS
- at include fftools-common-opts.texi
+ at include avtools-common-opts.texi
@section Main options
@@ -159,14 +159,12 @@ Set the ISO 639 language code (3 letters) of the current subtitle stream.
@section Video Options
@table @option
- at item -b @var{bitrate}
-Set the video bitrate in bit/s (default = 200 kb/s).
@item -vframes @var{number}
Set the number of video frames to record.
@item -r @var{fps}
Set frame rate (Hz value, fraction or abbreviation), (default = 25).
@item -s @var{size}
-Set frame size. The format is @samp{wxh} (ffserver default = 160x128, ffmpeg default = same as source).
+Set frame size. The format is @samp{wxh} (avserver default = 160x128, ffmpeg default = same as source).
The following abbreviations are recognized:
@table @samp
@item sqcif
@@ -471,7 +469,7 @@ FF_ER_COMPLIANT
@item 3
FF_ER_AGGRESSIVE
@item 4
-FF_ER_VERY_AGGRESSIVE
+FF_ER_EXPLODE
@end table
@item -ec @var{bit_mask}
@@ -551,19 +549,17 @@ The timestamps must be specified in ascending order.
@item -aframes @var{number}
Set the number of audio frames to record.
@item -ar @var{freq}
-Set the audio sampling frequency. For input streams it is set by
-default to 44100 Hz, for output streams it is set by default to the
-frequency of the input stream. If the input file has audio streams
-with different frequencies, the behaviour is undefined.
- at item -ab @var{bitrate}
-Set the audio bitrate in bit/s (default = 64k).
+Set the audio sampling frequency. For output streams it is set by
+default to the frequency of the corresponding input stream. For input
+streams this option only makes sense for audio grabbing devices and raw
+demuxers and is mapped to the corresponding demuxer options.
@item -aq @var{q}
Set the audio quality (codec-specific, VBR).
@item -ac @var{channels}
-Set the number of audio channels. For input streams it is set by
-default to 1, for output streams it is set by default to the same
-number of audio channels in input. If the input file has audio streams
-with different channel count, the behaviour is undefined.
+Set the number of audio channels. For output streams it is set by
+default to the number of input audio channels. For input streams
+this option only makes sense for audio grabbing devices and raw demuxers
+and is mapped to the corresponding demuxer options.
@item -an
Disable audio recording.
@item -acodec @var{codec}
@@ -730,10 +726,12 @@ Set RTP payload size in bytes.
Read input at native frame rate. Mainly used to simulate a grab device.
@item -loop_input
Loop over the input stream. Currently it works only for image
-streams. This option is used for automatic FFserver testing.
+streams. This option is used for automatic AVserver testing.
+This option is deprecated, use -loop.
@item -loop_output @var{number_of_times}
Repeatedly loop output for formats that support looping such as animated GIF
(0 will loop the output infinitely).
+This option is deprecated, use -loop.
@item -threads @var{count}
Thread count.
@item -vsync @var{parameter}
@@ -793,7 +791,7 @@ A preset file contains a sequence of @var{option}=@var{value} pairs,
one for each line, specifying a sequence of options which would be
awkward to specify on the command line. Lines starting with the hash
('#') character are ignored and are used to provide comments. Check
-the @file{ffpresets} directory in the Libav source tree for examples.
+the @file{presets} directory in the Libav source tree for examples.
Preset files are specified with the @code{vpre}, @code{apre},
@code{spre}, and @code{fpre} options. The @code{fpre} option takes the
@@ -808,8 +806,8 @@ preset options identifies the preset file to use according to the
following rules:
First ffmpeg searches for a file named @var{arg}.ffpreset in the
-directories @file{$FFMPEG_DATADIR} (if set), and @file{$HOME/.ffmpeg}, and in
-the datadir defined at configuration time (usually @file{PREFIX/share/ffmpeg})
+directories @file{$AVCONV_DATADIR} (if set), and @file{$HOME/.avconv}, and in
+the datadir defined at configuration time (usually @file{PREFIX/share/avconv})
in that order. For example, if the argument is @code{libx264-max}, it will
search for the file @file{libx264-max.ffpreset}.
@@ -880,8 +878,8 @@ ffmpeg -f oss -i /dev/dsp -f video4linux2 -i /dev/video0 /tmp/out.mpg
@end example
Note that you must activate the right video source and channel before
-launching ffmpeg with any TV viewer such as xawtv
-(@url{http://linux.bytesex.org/xawtv/}) by Gerd Knorr. You also
+launching ffmpeg with any TV viewer such as
+ at uref{http://linux.bytesex.org/xawtv/, xawtv} by Gerd Knorr. You also
have to set the audio recording levels correctly with a
standard mixer.
@@ -900,8 +898,34 @@ the DISPLAY environment variable.
ffmpeg -f x11grab -s cif -r 25 -i :0.0+10,20 /tmp/out.mpg
@end example
-0.0 is display.screen number of your X11 server, same as the DISPLAY environment
-variable. 10 is the x-offset and 20 the y-offset for the grabbing.
+10 is the x-offset and 20 the y-offset for the grabbing.
+
+ at example
+ffmpeg -f x11grab -follow_mouse centered -s cif -r 25 -i :0.0 /tmp/out.mpg
+ at end example
+
+The grabbing region follows the mouse pointer, which stays at the center of
+region.
+
+ at example
+ffmpeg -f x11grab -follow_mouse 100 -s cif -r 25 -i :0.0 /tmp/out.mpg
+ at end example
+
+Only follows when mouse pointer reaches within 100 pixels to the edge of
+region.
+
+ at example
+ffmpeg -f x11grab -show_region 1 -s cif -r 25 -i :0.0+10,20 /tmp/out.mpg
+ at end example
+
+The grabbing region will be indicated on screen.
+
+ at example
+ffmpeg -f x11grab -follow_mouse centered -show_region 1 -s cif -r 25 -i :0.0 /tmp/out.mpg
+ at end example
+
+The grabbing region indication will follow the mouse pointer.
+
@section Video and Audio file format conversion
@@ -1055,7 +1079,7 @@ file to which you want to add them.
@settitle ffmpeg video converter
@c man begin SEEALSO
-ffplay(1), ffprobe(1), ffserver(1) and the Libav HTML documentation
+avplay(1), avprobe(1), avserver(1) and the Libav HTML documentation
@c man end
@c man begin AUTHORS
diff --git a/doc/ffplay.texi b/doc/ffplay.texi
deleted file mode 100644
index e5de3d2..0000000
--- a/doc/ffplay.texi
+++ /dev/null
@@ -1,181 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-
- at settitle ffplay Documentation
- at titlepage
- at center @titlefont{ffplay Documentation}
- at end titlepage
-
- at top
-
- at contents
-
- at chapter Synopsis
-
- at example
- at c man begin SYNOPSIS
-ffplay [options] @file{input_file}
- at c man end
- at end example
-
- at chapter Description
- at c man begin DESCRIPTION
-
-FFplay is a very simple and portable media player using the Libav
-libraries and the SDL library. It is mostly used as a testbed for the
-various Libav APIs.
- at c man end
-
- at chapter Options
- at c man begin OPTIONS
-
- at include fftools-common-opts.texi
-
- at section Main options
-
- at table @option
- at item -x @var{width}
-Force displayed width.
- at item -y @var{height}
-Force displayed height.
- at item -s @var{size}
-Set frame size (WxH or abbreviation), needed for videos which don't
-contain a header with the frame size like raw YUV.
- at item -an
-Disable audio.
- at item -vn
-Disable video.
- at item -ss @var{pos}
-Seek to a given position in seconds.
- at item -t @var{duration}
-play <duration> seconds of audio/video
- at item -bytes
-Seek by bytes.
- at item -nodisp
-Disable graphical display.
- at item -f @var{fmt}
-Force format.
- at item -window_title @var{title}
-Set window title (default is the input filename).
- at item -loop @var{number}
-Loops movie playback <number> times. 0 means forever.
- at item -vf @var{filter_graph}
- at var{filter_graph} is a description of the filter graph to apply to
-the input video.
-Use the option "-filters" to show all the available filters (including
-also sources and sinks).
-
- at end table
-
- at section Advanced options
- at table @option
- at item -pix_fmt @var{format}
-Set pixel format.
- at item -stats
-Show the stream duration, the codec parameters, the current position in
-the stream and the audio/video synchronisation drift.
- at item -debug
-Print specific debug info.
- at item -bug
-Work around bugs.
- at item -vismv
-Visualize motion vectors.
- at item -fast
-Non-spec-compliant optimizations.
- at item -genpts
-Generate pts.
- at item -rtp_tcp
-Force RTP/TCP protocol usage instead of RTP/UDP. It is only meaningful
-if you are streaming with the RTSP protocol.
- at item -sync @var{type}
-Set the master clock to audio (@code{type=audio}), video
-(@code{type=video}) or external (@code{type=ext}). Default is audio. The
-master clock is used to control audio-video synchronization. Most media
-players use audio as master clock, but in some cases (streaming or high
-quality broadcast) it is necessary to change that. This option is mainly
-used for debugging purposes.
- at item -threads @var{count}
-Set the thread count.
- at item -ast @var{audio_stream_number}
-Select the desired audio stream number, counting from 0. The number
-refers to the list of all the input audio streams. If it is greater
-than the number of audio streams minus one, then the last one is
-selected, if it is negative the audio playback is disabled.
- at item -vst @var{video_stream_number}
-Select the desired video stream number, counting from 0. The number
-refers to the list of all the input video streams. If it is greater
-than the number of video streams minus one, then the last one is
-selected, if it is negative the video playback is disabled.
- at item -sst @var{subtitle_stream_number}
-Select the desired subtitle stream number, counting from 0. The number
-refers to the list of all the input subtitle streams. If it is greater
-than the number of subtitle streams minus one, then the last one is
-selected, if it is negative the subtitle rendering is disabled.
- at item -autoexit
-Exit when video is done playing.
- at item -exitonkeydown
-Exit if any key is pressed.
- at item -exitonmousedown
-Exit if any mouse button is pressed.
- at end table
-
- at section While playing
-
- at table @key
- at item q, ESC
-Quit.
-
- at item f
-Toggle full screen.
-
- at item p, SPC
-Pause.
-
- at item a
-Cycle audio channel.
-
- at item v
-Cycle video channel.
-
- at item t
-Cycle subtitle channel.
-
- at item w
-Show audio waves.
-
- at item left/right
-Seek backward/forward 10 seconds.
-
- at item down/up
-Seek backward/forward 1 minute.
-
- at item mouse click
-Seek to percentage in file corresponding to fraction of width.
-
- at end table
-
- at c man end
-
- at include eval.texi
- at include demuxers.texi
- at include muxers.texi
- at include indevs.texi
- at include outdevs.texi
- at include protocols.texi
- at include filters.texi
-
- at ignore
-
- at setfilename ffplay
- at settitle FFplay media player
-
- at c man begin SEEALSO
-ffmpeg(1), ffprobe(1), ffserver(1) and the Libav HTML documentation
- at c man end
-
- at c man begin AUTHORS
-The Libav developers
- at c man end
-
- at end ignore
-
- at bye
diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi
deleted file mode 100644
index 5e856e6..0000000
--- a/doc/ffprobe.texi
+++ /dev/null
@@ -1,134 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-
- at settitle ffprobe Documentation
- at titlepage
- at center @titlefont{ffprobe Documentation}
- at end titlepage
-
- at top
-
- at contents
-
- at chapter Synopsis
-
-The generic syntax is:
-
- at example
- at c man begin SYNOPSIS
-ffprobe [options] [@file{input_file}]
- at c man end
- at end example
-
- at chapter Description
- at c man begin DESCRIPTION
-
-ffprobe gathers information from multimedia streams and prints it in
-human- and machine-readable fashion.
-
-For example it can be used to check the format of the container used
-by a multimedia stream and the format and type of each media stream
-contained in it.
-
-If a filename is specified in input, ffprobe will try to open and
-probe the file content. If the file cannot be opened or recognized as
-a multimedia file, a positive exit code is returned.
-
-ffprobe may be employed both as a standalone application or in
-combination with a textual filter, which may perform more
-sophisticated processing, e.g. statistical processing or plotting.
-
-Options are used to list some of the formats supported by ffprobe or
-for specifying which information to display, and for setting how
-ffprobe will show it.
-
-ffprobe output is designed to be easily parsable by a textual filter,
-and consists of one or more sections of the form:
- at example
-[SECTION]
-key1=val1
-...
-keyN=valN
-[/SECTION]
- at end example
-
-Metadata tags stored in the container or in the streams are recognized
-and printed in the corresponding "FORMAT" or "STREAM" section, and
-are prefixed by the string "TAG:".
-
- at c man end
-
- at chapter Options
- at c man begin OPTIONS
-
- at include fftools-common-opts.texi
-
- at section Main options
-
- at table @option
-
- at item -f @var{format}
-Force format to use.
-
- at item -unit
-Show the unit of the displayed values.
-
- at item -prefix
-Use SI prefixes for the displayed values.
-Unless the "-byte_binary_prefix" option is used all the prefixes
-are decimal.
-
- at item -byte_binary_prefix
-Force the use of binary prefixes for byte values.
-
- at item -sexagesimal
-Use sexagesimal format HH:MM:SS.MICROSECONDS for time values.
-
- at item -pretty
-Prettify the format of the displayed values, it corresponds to the
-options "-unit -prefix -byte_binary_prefix -sexagesimal".
-
- at item -show_format
-Show information about the container format of the input multimedia
-stream.
-
-All the container format information is printed within a section with
-name "FORMAT".
-
- at item -show_packets
-Show information about each packet contained in the input multimedia
-stream.
-
-The information for each single packet is printed within a dedicated
-section with name "PACKET".
-
- at item -show_streams
-Show information about each media stream contained in the input
-multimedia stream.
-
-Each media stream information is printed within a dedicated section
-with name "STREAM".
-
- at end table
- at c man end
-
- at include demuxers.texi
- at include muxers.texi
- at include protocols.texi
- at include indevs.texi
-
- at ignore
-
- at setfilename ffprobe
- at settitle ffprobe media prober
-
- at c man begin SEEALSO
-ffmpeg(1), ffplay(1), ffserver(1) and the Libav HTML documentation
- at c man end
-
- at c man begin AUTHORS
-The Libav developers
- at c man end
-
- at end ignore
-
- at bye
diff --git a/doc/ffserver.conf b/doc/ffserver.conf
deleted file mode 100644
index 62728b0..0000000
--- a/doc/ffserver.conf
+++ /dev/null
@@ -1,377 +0,0 @@
-# Port on which the server is listening. You must select a different
-# port from your standard HTTP web server if it is running on the same
-# computer.
-Port 8090
-
-# Address on which the server is bound. Only useful if you have
-# several network interfaces.
-BindAddress 0.0.0.0
-
-# Number of simultaneous HTTP connections that can be handled. It has
-# to be defined *before* the MaxClients parameter, since it defines the
-# MaxClients maximum limit.
-MaxHTTPConnections 2000
-
-# Number of simultaneous requests that can be handled. Since FFServer
-# is very fast, it is more likely that you will want to leave this high
-# and use MaxBandwidth, below.
-MaxClients 1000
-
-# This the maximum amount of kbit/sec that you are prepared to
-# consume when streaming to clients.
-MaxBandwidth 1000
-
-# Access log file (uses standard Apache log file format)
-# '-' is the standard output.
-CustomLog -
-
-# Suppress that if you want to launch ffserver as a daemon.
-NoDaemon
-
-
-##################################################################
-# Definition of the live feeds. Each live feed contains one video
-# and/or audio sequence coming from an ffmpeg encoder or another
-# ffserver. This sequence may be encoded simultaneously with several
-# codecs at several resolutions.
-
-<Feed feed1.ffm>
-
-# You must use 'ffmpeg' to send a live feed to ffserver. In this
-# example, you can type:
-#
-# ffmpeg http://localhost:8090/feed1.ffm
-
-# ffserver can also do time shifting. It means that it can stream any
-# previously recorded live stream. The request should contain:
-# "http://xxxx?date=[YYYY-MM-DDT][[HH:]MM:]SS[.m...]".You must specify
-# a path where the feed is stored on disk. You also specify the
-# maximum size of the feed, where zero means unlimited. Default:
-# File=/tmp/feed_name.ffm FileMaxSize=5M
-File /tmp/feed1.ffm
-FileMaxSize 200K
-
-# You could specify
-# ReadOnlyFile /saved/specialvideo.ffm
-# This marks the file as readonly and it will not be deleted or updated.
-
-# Specify launch in order to start ffmpeg automatically.
-# First ffmpeg must be defined with an appropriate path if needed,
-# after that options can follow, but avoid adding the http:// field
-#Launch ffmpeg
-
-# Only allow connections from localhost to the feed.
-ACL allow 127.0.0.1
-
-</Feed>
-
-
-##################################################################
-# Now you can define each stream which will be generated from the
-# original audio and video stream. Each format has a filename (here
-# 'test1.mpg'). FFServer will send this stream when answering a
-# request containing this filename.
-
-<Stream test1.mpg>
-
-# coming from live feed 'feed1'
-Feed feed1.ffm
-
-# Format of the stream : you can choose among:
-# mpeg : MPEG-1 multiplexed video and audio
-# mpegvideo : only MPEG-1 video
-# mp2 : MPEG-2 audio (use AudioCodec to select layer 2 and 3 codec)
-# ogg : Ogg format (Vorbis audio codec)
-# rm : RealNetworks-compatible stream. Multiplexed audio and video.
-# ra : RealNetworks-compatible stream. Audio only.
-# mpjpeg : Multipart JPEG (works with Netscape without any plugin)
-# jpeg : Generate a single JPEG image.
-# asf : ASF compatible streaming (Windows Media Player format).
-# swf : Macromedia Flash compatible stream
-# avi : AVI format (MPEG-4 video, MPEG audio sound)
-Format mpeg
-
-# Bitrate for the audio stream. Codecs usually support only a few
-# different bitrates.
-AudioBitRate 32
-
-# Number of audio channels: 1 = mono, 2 = stereo
-AudioChannels 1
-
-# Sampling frequency for audio. When using low bitrates, you should
-# lower this frequency to 22050 or 11025. The supported frequencies
-# depend on the selected audio codec.
-AudioSampleRate 44100
-
-# Bitrate for the video stream
-VideoBitRate 64
-
-# Ratecontrol buffer size
-VideoBufferSize 40
-
-# Number of frames per second
-VideoFrameRate 3
-
-# Size of the video frame: WxH (default: 160x128)
-# The following abbreviations are defined: sqcif, qcif, cif, 4cif, qqvga,
-# qvga, vga, svga, xga, uxga, qxga, sxga, qsxga, hsxga, wvga, wxga, wsxga,
-# wuxga, woxga, wqsxga, wquxga, whsxga, whuxga, cga, ega, hd480, hd720,
-# hd1080
-VideoSize 160x128
-
-# Transmit only intra frames (useful for low bitrates, but kills frame rate).
-#VideoIntraOnly
-
-# If non-intra only, an intra frame is transmitted every VideoGopSize
-# frames. Video synchronization can only begin at an intra frame.
-VideoGopSize 12
-
-# More MPEG-4 parameters
-# VideoHighQuality
-# Video4MotionVector
-
-# Choose your codecs:
-#AudioCodec mp2
-#VideoCodec mpeg1video
-
-# Suppress audio
-#NoAudio
-
-# Suppress video
-#NoVideo
-
-#VideoQMin 3
-#VideoQMax 31
-
-# Set this to the number of seconds backwards in time to start. Note that
-# most players will buffer 5-10 seconds of video, and also you need to allow
-# for a keyframe to appear in the data stream.
-#Preroll 15
-
-# ACL:
-
-# You can allow ranges of addresses (or single addresses)
-#ACL ALLOW <first address> <last address>
-
-# You can deny ranges of addresses (or single addresses)
-#ACL DENY <first address> <last address>
-
-# You can repeat the ACL allow/deny as often as you like. It is on a per
-# stream basis. The first match defines the action. If there are no matches,
-# then the default is the inverse of the last ACL statement.
-#
-# Thus 'ACL allow localhost' only allows access from localhost.
-# 'ACL deny 1.0.0.0 1.255.255.255' would deny the whole of network 1 and
-# allow everybody else.
-
-</Stream>
-
-
-##################################################################
-# Example streams
-
-
-# Multipart JPEG
-
-#<Stream test.mjpg>
-#Feed feed1.ffm
-#Format mpjpeg
-#VideoFrameRate 2
-#VideoIntraOnly
-#NoAudio
-#Strict -1
-#</Stream>
-
-
-# Single JPEG
-
-#<Stream test.jpg>
-#Feed feed1.ffm
-#Format jpeg
-#VideoFrameRate 2
-#VideoIntraOnly
-##VideoSize 352x240
-#NoAudio
-#Strict -1
-#</Stream>
-
-
-# Flash
-
-#<Stream test.swf>
-#Feed feed1.ffm
-#Format swf
-#VideoFrameRate 2
-#VideoIntraOnly
-#NoAudio
-#</Stream>
-
-
-# ASF compatible
-
-<Stream test.asf>
-Feed feed1.ffm
-Format asf
-VideoFrameRate 15
-VideoSize 352x240
-VideoBitRate 256
-VideoBufferSize 40
-VideoGopSize 30
-AudioBitRate 64
-StartSendOnKey
-</Stream>
-
-
-# MP3 audio
-
-#<Stream test.mp3>
-#Feed feed1.ffm
-#Format mp2
-#AudioCodec mp3
-#AudioBitRate 64
-#AudioChannels 1
-#AudioSampleRate 44100
-#NoVideo
-#</Stream>
-
-
-# Ogg Vorbis audio
-
-#<Stream test.ogg>
-#Feed feed1.ffm
-#Title "Stream title"
-#AudioBitRate 64
-#AudioChannels 2
-#AudioSampleRate 44100
-#NoVideo
-#</Stream>
-
-
-# Real with audio only at 32 kbits
-
-#<Stream test.ra>
-#Feed feed1.ffm
-#Format rm
-#AudioBitRate 32
-#NoVideo
-#NoAudio
-#</Stream>
-
-
-# Real with audio and video at 64 kbits
-
-#<Stream test.rm>
-#Feed feed1.ffm
-#Format rm
-#AudioBitRate 32
-#VideoBitRate 128
-#VideoFrameRate 25
-#VideoGopSize 25
-#NoAudio
-#</Stream>
-
-
-##################################################################
-# A stream coming from a file: you only need to set the input
-# filename and optionally a new format. Supported conversions:
-# AVI -> ASF
-
-#<Stream file.rm>
-#File "/usr/local/httpd/htdocs/tlive.rm"
-#NoAudio
-#</Stream>
-
-#<Stream file.asf>
-#File "/usr/local/httpd/htdocs/test.asf"
-#NoAudio
-#Author "Me"
-#Copyright "Super MegaCorp"
-#Title "Test stream from disk"
-#Comment "Test comment"
-#</Stream>
-
-
-##################################################################
-# RTSP examples
-#
-# You can access this stream with the RTSP URL:
-# rtsp://localhost:5454/test1-rtsp.mpg
-#
-# A non-standard RTSP redirector is also created. Its URL is:
-# http://localhost:8090/test1-rtsp.rtsp
-
-#<Stream test1-rtsp.mpg>
-#Format rtp
-#File "/usr/local/httpd/htdocs/test1.mpg"
-#</Stream>
-
-
-# Transcode an incoming live feed to another live feed,
-# using libx264 and video presets
-
-#<Stream live.h264>
-#Format rtp
-#Feed feed1.ffm
-#VideoCodec libx264
-#VideoFrameRate 24
-#VideoBitRate 100
-#VideoSize 480x272
-#AVPresetVideo default
-#AVPresetVideo baseline
-#AVOptionVideo flags +global_header
-#
-#AudioCodec libfaac
-#AudioBitRate 32
-#AudioChannels 2
-#AudioSampleRate 22050
-#AVOptionAudio flags +global_header
-#</Stream>
-
-##################################################################
-# SDP/multicast examples
-#
-# If you want to send your stream in multicast, you must set the
-# multicast address with MulticastAddress. The port and the TTL can
-# also be set.
-#
-# An SDP file is automatically generated by ffserver by adding the
-# 'sdp' extension to the stream name (here
-# http://localhost:8090/test1-sdp.sdp). You should usually give this
-# file to your player to play the stream.
-#
-# The 'NoLoop' option can be used to avoid looping when the stream is
-# terminated.
-
-#<Stream test1-sdp.mpg>
-#Format rtp
-#File "/usr/local/httpd/htdocs/test1.mpg"
-#MulticastAddress 224.124.0.1
-#MulticastPort 5000
-#MulticastTTL 16
-#NoLoop
-#</Stream>
-
-
-##################################################################
-# Special streams
-
-# Server status
-
-<Stream stat.html>
-Format status
-
-# Only allow local people to get the status
-ACL allow localhost
-ACL allow 192.168.0.0 192.168.255.255
-
-#FaviconURL http://pond1.gladstonefamily.net:8080/favicon.ico
-</Stream>
-
-
-# Redirect index.html to the appropriate site
-
-<Redirect index.html>
-URL http://www.libav.org/
-</Redirect>
-
-
diff --git a/doc/ffserver.texi b/doc/ffserver.texi
deleted file mode 100644
index d247016..0000000
--- a/doc/ffserver.texi
+++ /dev/null
@@ -1,278 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-
- at settitle ffserver Documentation
- at titlepage
- at center @titlefont{ffserver Documentation}
- at end titlepage
-
- at top
-
- at contents
-
- at chapter Synopsys
-
-The generic syntax is:
-
- at example
- at c man begin SYNOPSIS
-ffserver [options]
- at c man end
- at end example
-
- at chapter Description
- at c man begin DESCRIPTION
-
-ffserver is a streaming server for both audio and video. It supports
-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.
-
- at section How does it work?
-
-ffserver receives prerecorded files or FFM streams from some ffmpeg
-instance as input, then streams them over RTP/RTSP/HTTP.
-
-An ffserver instance will listen on some port as specified in the
-configuration file. You can launch one or more instances of ffmpeg and
-send one or more FFM streams to the port where ffserver is expecting
-to receive them. Alternately, you can make ffserver launch such ffmpeg
-instances at startup.
-
-Input streams are called feeds, and each one is specified by a <Feed>
-section in the configuration file.
-
-For each feed you can have different output streams in various
-formats, each one specified by a <Stream> section in the configuration
-file.
-
- at section Status stream
-
-ffserver supports an HTTP interface which exposes the current status
-of the server.
-
-Simply point your browser to the address of the special status stream
-specified in the configuration file.
-
-For example if you have:
- at example
-<Stream status.html>
-Format status
-
-# Only allow local people to get the status
-ACL allow localhost
-ACL allow 192.168.0.0 192.168.255.255
-</Stream>
- at end example
-
-then the server will post a page with the status information when
-the special stream @file{status.html} is requested.
-
- at section What can this do?
-
-When properly configured and running, you can capture video and audio in real
-time from a suitable capture card, and stream it out over the Internet to
-either Windows Media Player or RealAudio player (with some restrictions).
-
-It can also stream from files, though that is currently broken. Very often, a
-web server can be used to serve up the files just as well.
-
-It can stream prerecorded video from .ffm files, though it is somewhat tricky
-to make it work correctly.
-
- at section What do I need?
-
-I use Linux on a 900 MHz Duron with a cheapo Bt848 based TV capture card. I'm
-using stock Linux 2.4.17 with the stock drivers. [Actually that isn't true,
-I needed some special drivers for my motherboard-based sound card.]
-
-I understand that FreeBSD systems work just fine as well.
-
- at section How do I make it work?
-
-First, build the kit. It *really* helps to have installed LAME first. Then when
-you run the ffserver ./configure, make sure that you have the
- at code{--enable-libmp3lame} flag turned on.
-
-LAME is important as it allows for streaming audio to Windows Media Player.
-Don't ask why the other audio types do not work.
-
-As a simple test, just run the following two command lines where INPUTFILE
-is some file which you can decode with ffmpeg:
-
- at example
-./ffserver -f doc/ffserver.conf &
-./ffmpeg -i INPUTFILE http://localhost:8090/feed1.ffm
- at end example
-
-At this point you should be able to go to your Windows machine and fire up
-Windows Media Player (WMP). Go to Open URL and enter
-
- at example
- http://<linuxbox>:8090/test.asf
- at end example
-
-You should (after a short delay) see video and hear audio.
-
-WARNING: trying to stream test1.mpg doesn't work with WMP as it tries to
-transfer the entire file before starting to play.
-The same is true of AVI files.
-
- at section What happens next?
-
-You should edit the ffserver.conf file to suit your needs (in terms of
-frame rates etc). Then install ffserver and ffmpeg, write a script to start
-them up, and off you go.
-
- at section Troubleshooting
-
- at subsection I don't hear any audio, but video is fine.
-
-Maybe you didn't install LAME, or got your ./configure statement wrong. Check
-the ffmpeg output to see if a line referring to MP3 is present. If not, then
-your configuration was incorrect. If it is, then maybe your wiring is not
-set up correctly. Maybe the sound card is not getting data from the right
-input source. Maybe you have a really awful audio interface (like I do)
-that only captures in stereo and also requires that one channel be flipped.
-If you are one of these people, then export 'AUDIO_FLIP_LEFT=1' before
-starting ffmpeg.
-
- at subsection The audio and video loose sync after a while.
-
-Yes, they do.
-
- at subsection After a long while, the video update rate goes way down in WMP.
-
-Yes, it does. Who knows why?
-
- at subsection WMP 6.4 behaves differently to WMP 7.
-
-Yes, it does. Any thoughts on this would be gratefully received. These
-differences extend to embedding WMP into a web page. [There are two
-object IDs that you can use: The old one, which does not play well, and
-the new one, which does (both tested on the same system). However,
-I suspect that the new one is not available unless you have installed WMP 7].
-
- at section What else can it do?
-
-You can replay video from .ffm files that was recorded earlier.
-However, there are a number of caveats, including the fact that the
-ffserver parameters must match the original parameters used to record the
-file. If they do not, then ffserver deletes the file before recording into it.
-(Now that I write this, it seems broken).
-
-You can fiddle with many of the codec choices and encoding parameters, and
-there are a bunch more parameters that you cannot control. Post a message
-to the mailing list if there are some 'must have' parameters. Look in
-ffserver.conf for a list of the currently available controls.
-
-It will automatically generate the ASX or RAM files that are often used
-in browsers. These files are actually redirections to the underlying ASF
-or RM file. The reason for this is that the browser often fetches the
-entire file before starting up the external viewer. The redirection files
-are very small and can be transferred quickly. [The stream itself is
-often 'infinite' and thus the browser tries to download it and never
-finishes.]
-
- at section Tips
-
-* When you connect to a live stream, most players (WMP, RA, etc) want to
-buffer a certain number of seconds of material so that they can display the
-signal continuously. However, ffserver (by default) starts sending data
-in realtime. This means that there is a pause of a few seconds while the
-buffering is being done by the player. The good news is that this can be
-cured by adding a '?buffer=5' to the end of the URL. This means that the
-stream should start 5 seconds in the past -- and so the first 5 seconds
-of the stream are sent as fast as the network will allow. It will then
-slow down to real time. This noticeably improves the startup experience.
-
-You can also add a 'Preroll 15' statement into the ffserver.conf that will
-add the 15 second prebuffering on all requests that do not otherwise
-specify a time. In addition, ffserver will skip frames until a key_frame
-is found. This further reduces the startup delay by not transferring data
-that will be discarded.
-
-* You may want to adjust the MaxBandwidth in the ffserver.conf to limit
-the amount of bandwidth consumed by live streams.
-
- at section Why does the ?buffer / Preroll stop working after a time?
-
-It turns out that (on my machine at least) the number of frames successfully
-grabbed is marginally less than the number that ought to be grabbed. This
-means that the timestamp in the encoded data stream gets behind realtime.
-This means that if you say 'Preroll 10', then when the stream gets 10
-or more seconds behind, there is no Preroll left.
-
-Fixing this requires a change in the internals of how timestamps are
-handled.
-
- at section Does the @code{?date=} stuff work.
-
-Yes (subject to the limitation outlined above). Also note that whenever you
-start ffserver, it deletes the ffm file (if any parameters have changed),
-thus wiping out what you had recorded before.
-
-The format of the @code{?date=xxxxxx} is fairly flexible. You should use one
-of the following formats (the 'T' is literal):
-
- at example
-* YYYY-MM-DDTHH:MM:SS (localtime)
-* YYYY-MM-DDTHH:MM:SSZ (UTC)
- at end example
-
-You can omit the YYYY-MM-DD, and then it refers to the current day. However
-note that @samp{?date=16:00:00} refers to 16:00 on the current day -- this
-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}.
- at c man end
-
- at chapter Options
- at c man begin OPTIONS
-
- at include fftools-common-opts.texi
-
- at section Main options
-
- at table @option
- at item -f @var{configfile}
-Use @file{configfile} instead of @file{/etc/ffserver.conf}.
- at item -n
-Enable no-launch mode. This option disables all the Launch directives
-within the various <Stream> sections. Since ffserver will not launch
-any ffmpeg instances, you will have to launch them manually.
- at 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.
- at end table
- at c man end
-
- at ignore
-
- at setfilename ffserver
- at settitle ffserver video server
-
- at c man begin SEEALSO
-
-ffmpeg(1), ffplay(1), ffprobe(1), the @file{ffmpeg/doc/ffserver.conf}
-example and the Libav HTML documentation
- at c man end
-
- at c man begin AUTHORS
-The Libav developers
- at c man end
-
- at end ignore
-
- at bye
diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi
deleted file mode 100644
index 3a1cb3b..0000000
--- a/doc/fftools-common-opts.texi
+++ /dev/null
@@ -1,93 +0,0 @@
-All the numerical options, if not specified otherwise, accept in input
-a string representing a number, which may contain one of the
-International System number postfixes, for example 'K', 'M', 'G'.
-If 'i' is appended after the postfix, powers of 2 are used instead of
-powers of 10. The 'B' postfix multiplies the value for 8, and can be
-appended after another postfix or used alone. This allows using for
-example 'KB', 'MiB', 'G' and 'B' as postfix.
-
-Options which do not take arguments are boolean options, and set the
-corresponding value to true. They can be set to false by prefixing
-with "no" the option name, for example using "-nofoo" in the
-commandline will set to false the boolean option with name "foo".
-
- at section Generic options
-
-These options are shared amongst the ff* tools.
-
- at table @option
-
- at item -L
-Show license.
-
- at item -h, -?, -help, --help
-Show help.
-
- at item -version
-Show version.
-
- at item -formats
-Show available formats.
-
-The fields preceding the format names have the following meanings:
- at table @samp
- at item D
-Decoding available
- at item E
-Encoding available
- at end table
-
- at item -codecs
-Show available codecs.
-
-The fields preceding the codec names have the following meanings:
- at table @samp
- at item D
-Decoding available
- at item E
-Encoding available
- at item V/A/S
-Video/audio/subtitle codec
- at item S
-Codec supports slices
- at item D
-Codec supports direct rendering
- at item T
-Codec can handle input truncated at random locations instead of only at frame boundaries
- at end table
-
- at item -bsfs
-Show available bitstream filters.
-
- at item -protocols
-Show available protocols.
-
- at item -filters
-Show available libavfilter filters.
-
- at item -pix_fmts
-Show available pixel formats.
-
- at item -loglevel @var{loglevel}
-Set the logging level used by the library.
- at var{loglevel} is a number or a string containing one of the following values:
- at table @samp
- at item quiet
- at item panic
- at item fatal
- at item error
- at item warning
- at item info
- at item verbose
- at item debug
- at end table
-
-By default the program logs to stderr, if coloring is supported by the
-terminal, colors are used to mark errors and warnings. Log coloring
-can be disabled setting the environment variable
- at env{FFMPEG_FORCE_NOCOLOR} or @env{NO_COLOR}, or can be forced setting
-the environment variable @env{FFMPEG_FORCE_COLOR}.
-The use of the environment variable @env{NO_COLOR} is deprecated and
-will be dropped in a following Libav version.
-
- at end table
diff --git a/doc/filters.texi b/doc/filters.texi
index 9666f58..e022b46 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -17,8 +17,8 @@ output pads is called a "sink".
@section Filtergraph syntax
A filtergraph can be represented using a textual representation, which
-is recognized by the @code{-vf} and @code{-af} options of the ff*
-tools, and by the @code{av_parse_graph()} function defined in
+is recognized by the @code{-vf} and @code{-af} options in @command{avconv}
+and @command{avplay}, and by the @code{av_parse_graph()} function defined in
@file{libavfilter/avfiltergraph}.
A filterchain consists of a sequence of connected filters, each one
@@ -183,6 +183,66 @@ threshold, and defaults to 98.
@var{threshold} is the threshold below which a pixel value is
considered black, and defaults to 32.
+ at section boxblur
+
+Apply boxblur algorithm to the input video.
+
+This filter accepts the parameters:
+ at var{luma_power}:@var{luma_radius}:@var{chroma_radius}:@var{chroma_power}:@var{alpha_radius}:@var{alpha_power}
+
+Chroma and alpha parameters are optional, if not specified they default
+to the corresponding values set for @var{luma_radius} and
+ at var{luma_power}.
+
+ at var{luma_radius}, @var{chroma_radius}, and @var{alpha_radius} represent
+the radius in pixels of the box used for blurring the corresponding
+input plane. They are expressions, and can contain the following
+constants:
+ at table @option
+ at item w, h
+the input width and height in pixels
+
+ at item cw, ch
+the input chroma image width and height in pixels
+
+ at item hsub, vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+ at end table
+
+The radius must be a non-negative number, and must not be greater than
+the value of the expression @code{min(w,h)/2} for the luma and alpha planes,
+and of @code{min(cw,ch)/2} for the chroma planes.
+
+ at var{luma_power}, @var{chroma_power}, and @var{alpha_power} represent
+how many times the boxblur filter is applied to the corresponding
+plane.
+
+Some examples follow:
+
+ at itemize
+
+ at item
+Apply a boxblur filter with luma, chroma, and alpha radius
+set to 2:
+ at example
+boxblur=2:1
+ at end example
+
+ at item
+Set luma radius to 2, alpha and chroma radius to 0
+ at example
+boxblur=2:1:0:0:0:0
+ at end example
+
+ at item
+Set luma and chroma radius to a fraction of the video dimension
+ at example
+boxblur=min(h\,w)/10:1:min(cw\,ch)/10:1
+ at end example
+
+ at end itemize
+
@section copy
Copy the input source unchanged to the output. Mainly useful for
@@ -204,13 +264,13 @@ the computed values for @var{x} and @var{y}. They are evaluated for
each new frame.
@item in_w, in_h
-the input width and heigth
+the input width and height
@item iw, ih
same as @var{in_w} and @var{in_h}
@item out_w, out_h
-the output (cropped) width and heigth
+the output (cropped) width and height
@item ow, oh
same as @var{out_w} and @var{out_h}
@@ -321,6 +381,58 @@ indicates never reset and return the largest area encountered during
playback.
@end table
+ at section delogo
+
+Suppress a TV station logo by a simple interpolation of the surrounding
+pixels. Just set a rectangle covering the logo and watch it disappear
+(and sometimes something even uglier appear - your mileage may vary).
+
+The filter accepts parameters as a string of the form
+"@var{x}:@var{y}:@var{w}:@var{h}:@var{band}", or as a list of
+ at var{key}=@var{value} pairs, separated by ":".
+
+The description of the accepted parameters follows.
+
+ at table @option
+
+ at item x, y
+Specify the top left corner coordinates of the logo. They must be
+specified.
+
+ at item w, h
+Specify the width and height of the logo to clear. They must be
+specified.
+
+ at item band, t
+Specify the thickness of the fuzzy edge of the rectangle (added to
+ at var{w} and @var{h}). The default value is 4.
+
+ at item show
+When set to 1, a green rectangle is drawn on the screen to simplify
+finding the right @var{x}, @var{y}, @var{w}, @var{h} parameters, and
+ at var{band} is set to 4. The default value is 0.
+
+ at end table
+
+Some examples follow.
+
+ at itemize
+
+ at item
+Set a rectangle covering the area with top left corner coordinates 0,0
+and size 100x77, setting a band of size 10:
+ at example
+delogo=0:0:100:77:10
+ at end example
+
+ at item
+As the previous example, but use named options:
+ at example
+delogo=x=0:y=0:w=100:h=77:band=10
+ at end example
+
+ at end itemize
+
@section drawbox
Draw a colored box on the input image.
@@ -393,6 +505,32 @@ If both text and textfile are specified, an error is thrown.
@item x, y
The offsets where text will be drawn within the video frame.
Relative to the top/left border of the output image.
+They accept expressions similar to the @ref{overlay} filter:
+ at table @option
+
+ at item x, y
+the computed values for @var{x} and @var{y}. They are evaluated for
+each new frame.
+
+ at item main_w, main_h
+main input width and height
+
+ at item W, H
+same as @var{main_w} and @var{main_h}
+
+ at item text_w, text_h
+rendered text width and height
+
+ at item w, h
+same as @var{text_w} and @var{text_h}
+
+ at item n
+the number of frames processed, starting from 0
+
+ at item t
+timestamp expressed in seconds, NAN if the input timestamp is unknown
+
+ at end table
The default value of @var{x} and @var{y} is 0.
@@ -550,7 +688,7 @@ which is bottom field first.
For example:
@example
-./ffmpeg -i in.vob -vf "fieldorder=bff" out.dv
+./avconv -i in.vob -vf "fieldorder=bff" out.dv
@end example
@section fifo
@@ -668,10 +806,9 @@ gradfun=1.2
Flip the input video horizontally.
-For example to horizontally flip the video in input with
- at file{ffmpeg}:
+For example to horizontally flip the input video with @command{avconv}:
@example
-ffmpeg -i in.avi -vf "hflip" out.avi
+avconv -i in.avi -vf "hflip" out.avi
@end example
@section hqdn3d
@@ -701,7 +838,124 @@ a float number which specifies chroma temporal strength, defaults to
@var{luma_tmp}*@var{chroma_spatial}/@var{luma_spatial}
@end table
- at section noformat
+ at section lut, lutrgb, lutyuv
+
+Compute a look-up table for binding each pixel component input value
+to an output value, and apply it to input video.
+
+ at var{lutyuv} applies a lookup table to a YUV input video, @var{lutrgb}
+to an RGB input video.
+
+These filters accept in input a ":"-separated list of options, which
+specify the expressions used for computing the lookup table for the
+corresponding pixel component values.
+
+The @var{lut} filter requires either YUV or RGB pixel formats in
+input, and accepts the options:
+ at table @option
+ at var{c0} (first pixel component)
+ at var{c1} (second pixel component)
+ at var{c2} (third pixel component)
+ at var{c3} (fourth pixel component, corresponds to the alpha component)
+ at end table
+
+The exact component associated to each option depends on the format in
+input.
+
+The @var{lutrgb} filter requires RGB pixel formats in input, and
+accepts the options:
+ at table @option
+ at var{r} (red component)
+ at var{g} (green component)
+ at var{b} (blue component)
+ at var{a} (alpha component)
+ at end table
+
+The @var{lutyuv} filter requires YUV pixel formats in input, and
+accepts the options:
+ at table @option
+ at var{y} (Y/luminance component)
+ at var{u} (U/Cb component)
+ at var{v} (V/Cr component)
+ at var{a} (alpha component)
+ at end table
+
+The expressions can contain the following constants and functions:
+
+ at table @option
+ at item E, PI, PHI
+the corresponding mathematical approximated values for e
+(euler number), pi (greek PI), PHI (golden ratio)
+
+ at item w, h
+the input width and height
+
+ at item val
+input value for the pixel component
+
+ at item clipval
+the input value clipped in the @var{minval}- at var{maxval} range
+
+ at item maxval
+maximum value for the pixel component
+
+ at item minval
+minimum value for the pixel component
+
+ at item negval
+the negated value for the pixel component value clipped in the
+ at var{minval}- at var{maxval} range , it corresponds to the expression
+"maxval-clipval+minval"
+
+ at item clip(val)
+the computed value in @var{val} clipped in the
+ at var{minval}- at var{maxval} range
+
+ at item gammaval(gamma)
+the computed gamma correction value of the pixel component value
+clipped in the @var{minval}- at var{maxval} range, corresponds to the
+expression
+"pow((clipval-minval)/(maxval-minval)\, at var{gamma})*(maxval-minval)+minval"
+
+ at end table
+
+All expressions default to "val".
+
+Some examples follow:
+ at example
+# negate input video
+lutrgb="r=maxval+minval-val:g=maxval+minval-val:b=maxval+minval-val"
+lutyuv="y=maxval+minval-val:u=maxval+minval-val:v=maxval+minval-val"
+
+# the above is the same as
+lutrgb="r=negval:g=negval:b=negval"
+lutyuv="y=negval:u=negval:v=negval"
+
+# negate luminance
+lutyuv=negval
+
+# remove chroma components, turns the video into a graytone image
+lutyuv="u=128:v=128"
+
+# apply a luma burning effect
+lutyuv="y=2*val"
+
+# remove green and blue components
+lutrgb="g=0:b=0"
+
+# set a constant alpha channel value on input
+format=rgba,lutrgb=a="maxval-minval/2"
+
+# correct luminance gamma by a 0.5 factor
+lutyuv=y=gammaval(0.5)
+ at end example
+
+ at section negate
+
+Negate input video.
+
+This filter accepts an integer in input, if non-zero it negates the
+alpha component (if available). The default value in input is 0.
Force libavfilter not to use any of the specified pixel formats for the
input to the next filter.
@@ -738,7 +992,7 @@ The filter takes the parameters: @var{filter_name}@{:=@}@var{filter_params}.
filter. If not specified the default values are assumed.
Refer to the official libopencv documentation for more precise
-informations:
+information:
@url{http://opencv.willowgarage.com/documentation/c/image_filtering.html}
Follows the list of supported libopencv filters.
@@ -754,7 +1008,7 @@ It accepts the parameters: @var{struct_el}:@var{nb_iterations}.
@var{struct_el} represents a structuring element, and has the syntax:
@var{cols}x at var{rows}+ at var{anchor_x}x at var{anchor_y}/@var{shape}
- at var{cols} and @var{rows} represent the number of colums and rows of
+ at var{cols} and @var{rows} represent the number of columns and rows of
the structuring element, @var{anchor_x} and @var{anchor_y} the anchor
point, and @var{shape} the shape for the structuring element, and
can be one of the values "rect", "cross", "ellipse", "custom".
@@ -796,8 +1050,7 @@ Erode an image by using a specific structuring element.
This filter corresponds to the libopencv function @code{cvErode}.
The filter accepts the parameters: @var{struct_el}:@var{nb_iterations},
-with the same meaning and use of those of the dilate filter
-(@pxref{dilate}).
+with the same syntax and semantics as the @ref{dilate} filter.
@subsection smooth
@@ -821,6 +1074,7 @@ other parameters is 0.
These parameters correspond to the parameters assigned to the
libopencv function @code{cvSmooth}.
+ at anchor{overlay}
@section overlay
Overlay one video on top of another.
@@ -876,7 +1130,7 @@ movie=logo2.png [logo2];
color=red at .3:WxH [over]; [in][over] overlay [out]
@end example
-You can chain togheter more overlays but the efficiency of such
+You can chain together more overlays but the efficiency of such
approach is yet to be tested.
@section pad
@@ -896,13 +1150,13 @@ the corresponding mathematical approximated values for e
(euler number), pi (greek PI), phi (golden ratio)
@item in_w, in_h
-the input video width and heigth
+the input video width and height
@item iw, ih
same as @var{in_w} and @var{in_h}
@item out_w, out_h
-the output width and heigth, that is the size of the padded area as
+the output width and height, that is the size of the padded area as
specified by the @var{width} and @var{height} expressions
@item ow, oh
@@ -930,7 +1184,7 @@ value for @var{width} or @var{height} is 0, the corresponding input size
is used for the output.
The @var{width} expression can reference the value set by the
- at var{height} expression, and viceversa.
+ at var{height} expression, and vice versa.
The default value of @var{width} and @var{height} is 0.
@@ -940,7 +1194,7 @@ Specify the offsets where to place the input image in the padded area
with respect to the top/left border of the output image.
The @var{x} expression can reference the value set by the @var{y}
-expression, and viceversa.
+expression, and vice versa.
The default value of @var{x} and @var{y} is 0.
@@ -1003,20 +1257,23 @@ the corresponding mathematical approximated values for e
(euler number), pi (greek PI), phi (golden ratio)
@item in_w, in_h
-the input width and heigth
+the input width and height
@item iw, ih
same as @var{in_w} and @var{in_h}
@item out_w, out_h
-the output (cropped) width and heigth
+the output (cropped) width and height
@item ow, oh
same as @var{out_w} and @var{out_h}
- at item a
+ at item dar, a
input display aspect ratio, same as @var{iw} / @var{ih}
+ at item sar
+input sample aspect ratio
+
@item hsub, vsub
horizontal and vertical chroma subsample values. For example for the
pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
@@ -1065,6 +1322,122 @@ scale="trunc(3/2*iw/hsub)*hsub:trunc(3/2*ih/vsub)*vsub"
scale='min(500\, iw*3/2):-1'
@end example
+ at section select
+Select frames to pass in output.
+
+It accepts in input an expression, which is evaluated for each input
+frame. If the expression is evaluated to a non-zero value, the frame
+is selected and passed to the output, otherwise it is discarded.
+
+The expression can contain the following constants:
+
+ at table @option
+ at item PI
+Greek PI
+
+ at item PHI
+golden ratio
+
+ at item E
+Euler number
+
+ at item n
+the sequential number of the filtered frame, starting from 0
+
+ at item selected_n
+the sequential number of the selected frame, starting from 0
+
+ at item prev_selected_n
+the sequential number of the last selected frame, NAN if undefined
+
+ at item TB
+timebase of the input timestamps
+
+ at item pts
+the PTS (Presentation TimeStamp) of the filtered video frame,
+expressed in @var{TB} units, NAN if undefined
+
+ at item t
+the PTS (Presentation TimeStamp) of the filtered video frame,
+expressed in seconds, NAN if undefined
+
+ at item prev_pts
+the PTS of the previously filtered video frame, NAN if undefined
+
+ at item prev_selected_pts
+the PTS of the last previously filtered video frame, NAN if undefined
+
+ at item prev_selected_t
+the PTS of the last previously selected video frame, NAN if undefined
+
+ at item start_pts
+the PTS of the first video frame in the video, NAN if undefined
+
+ at item start_t
+the time of the first video frame in the video, NAN if undefined
+
+ at item pict_type
+the type of the filtered frame, can assume one of the following
+values:
+ at table @option
+ at item I
+ at item P
+ at item B
+ at item S
+ at item SI
+ at item SP
+ at item BI
+ at end table
+
+ at item interlace_type
+the frame interlace type, can assume one of the following values:
+ at table @option
+ at item PROGRESSIVE
+the frame is progressive (not interlaced)
+ at item TOPFIRST
+the frame is top-field-first
+ at item BOTTOMFIRST
+the frame is bottom-field-first
+ at end table
+
+ at item key
+1 if the filtered frame is a key-frame, 0 otherwise
+
+ at item pos
+the position in the file of the filtered frame, -1 if the information
+is not available (e.g. for synthetic video)
+ at end table
+
+The default value of the select expression is "1".
+
+Some examples follow:
+
+ at example
+# select all frames in input
+select
+
+# the above is the same as:
+select=1
+
+# skip all frames:
+select=0
+
+# select only I-frames
+select='eq(pict_type\,I)'
+
+# select one frame every 100
+select='not(mod(n\,100))'
+
+# select only frames contained in the 10-20 time interval
+select='gte(t\,10)*lte(t\,20)'
+
+# select only I frames contained in the 10-20 time interval
+select='gte(t\,10)*lte(t\,20)*eq(pict_type\,I)'
+
+# select frames with a minimum distance of 10 seconds
+select='isnan(prev_selected_t)+gte(t-prev_selected_t\,10)'
+ at end example
+
@anchor{setdar}
@section setdar
@@ -1093,7 +1466,7 @@ setdar=16:9
setdar=1.77777
@end example
-See also the "setsar" filter documentation (@pxref{setsar}).
+See also the @ref{setsar} filter documentation.
@section setpts
@@ -1211,13 +1584,72 @@ settb=2*intb
settb=AVTB
@end example
+ at section showinfo
+
+Show a line containing various information for each input video frame.
+The input video is not modified.
+
+The shown line contains a sequence of key/value pairs of the form
+ at var{key}:@var{value}.
+
+A description of each shown parameter follows:
+
+ at table @option
+ at item n
+sequential number of the input frame, starting from 0
+
+ at item pts
+Presentation TimeStamp of the input frame, expressed as a number of
+time base units. The time base unit depends on the filter input pad.
+
+ at item pts_time
+Presentation TimeStamp of the input frame, expressed as a number of
+seconds
+
+ at item pos
+position of the frame in the input stream, -1 if this information in
+unavailable and/or meaningless (for example in case of synthetic video)
+
+ at item fmt
+pixel format name
+
+ at item sar
+sample aspect ratio of the input frame, expressed in the form
+ at var{num}/@var{den}
+
+ at item s
+size of the input frame, expressed in the form
+ at var{width}x at var{height}
+
+ at item i
+interlaced mode ("P" for "progressive", "T" for top field first, "B"
+for bottom field first)
+
+ at item iskey
+1 if the frame is a key frame, 0 otherwise
+
+ at item type
+picture type of the input frame ("I" for an I-frame, "P" for a
+P-frame, "B" for a B-frame, "?" for unknown type).
+Check also the documentation of the @code{AVPictureType} enum and of
+the @code{av_get_picture_type_char} function defined in
+ at file{libavutil/avutil.h}.
+
+ at item checksum
+Adler-32 checksum of all the planes of the input frame
+
+ at item plane_checksum
+Adler-32 checksum of each plane of the input frame, expressed in the form
+"[@var{c0} @var{c1} @var{c2} @var{c3}]"
+ at end table
+
@section slicify
Pass the images of input video on to next video filter as multiple
slices.
@example
-./ffmpeg -i in.avi -vf "slicify=32" out.avi
+./avconv -i in.avi -vf "slicify=32" out.avi
@end example
The filter accepts the slice height as parameter. If the parameter is
@@ -1276,7 +1708,7 @@ It accepts the following parameters:
Negative values for the amount will blur the input video, while positive
values will sharpen. All parameters are optional and default to the
-equivalent of the string '5:5:1.0:0:0:0.0'.
+equivalent of the string '5:5:1.0:5:5:0.0'.
@table @option
@@ -1294,11 +1726,11 @@ and 5.0, default value is 1.0.
@item chroma_msize_x
Set the chroma matrix horizontal size. It can be an integer between 3
-and 13, default value is 0.
+and 13, default value is 5.
@item chroma_msize_y
Set the chroma matrix vertical size. It can be an integer between 3
-and 13, default value is 0.
+and 13, default value is 5.
@item luma_amount
Set the chroma effect strength. It can be a float number between -2.0
@@ -1313,8 +1745,8 @@ unsharp=7:7:2.5
# Strong blur of both luma and chroma parameters
unsharp=7:7:-2:7:7:-2
-# Use the default values with @command{ffmpeg}
-./ffmpeg -i in.avi -vf "unsharp" out.mp4
+# Use the default values with @command{avconv}
+./avconv -i in.avi -vf "unsharp" out.mp4
@end example
@section vflip
@@ -1322,7 +1754,7 @@ unsharp=7:7:-2:7:7:-2
Flip the input video vertically.
@example
-./ffmpeg -i in.avi -vf "vflip" out.avi
+./avconv -i in.avi -vf "vflip" out.avi
@end example
@section yadif
@@ -1330,7 +1762,7 @@ Flip the input video vertically.
Deinterlace the input video ("yadif" means "yet another deinterlacing
filter").
-It accepts the optional parameters: @var{mode}:@var{parity}.
+It accepts the optional parameters: @var{mode}:@var{parity}:@var{auto}.
@var{mode} specifies the interlacing mode to adopt, accepts one of the
following values:
@@ -1353,9 +1785,9 @@ interlaced video, accepts one of the following values:
@table @option
@item 0
-assume bottom field first
- at item 1
assume top field first
+ at item 1
+assume bottom field first
@item -1
enable automatic detection
@end table
@@ -1364,6 +1796,18 @@ Default value is -1.
If interlacing is unknown or decoder does not export this information,
top field first will be assumed.
+ at var{auto} specifies if deinterlacer should trust the interlaced flag
+and only deinterlace frames marked as interlaced
+
+ at table @option
+ at item 0
+deinterlace all frames
+ at item 1
+only deinterlace frames marked as interlaced
+ at end table
+
+Default value is 0.
+
@c man end VIDEO FILTERS
@chapter Video Sources
@@ -1381,7 +1825,7 @@ through the interface defined in @file{libavfilter/vsrc_buffer.h}.
It accepts the following parameters:
@var{width}:@var{height}:@var{pix_fmt_string}:@var{timebase_num}:@var{timebase_den}:@var{sample_aspect_ratio_num}:@var{sample_aspect_ratio.den}
-All the parameters need to be explicitely defined.
+All the parameters need to be explicitly defined.
Follows the list of the accepted parameters.
@@ -1437,7 +1881,7 @@ alpha specifier. The default value is "black".
@item frame_size
Specify the size of the sourced video, it may be a string of the form
- at var{width}x at var{heigth}, or the name of a size abbreviation. The
+ at var{width}x at var{height}, or the name of a size abbreviation. The
default value is "320x240".
@item frame_rate
@@ -1547,8 +1991,7 @@ form @var{width}x at var{height} or a frame size abbreviation.
the form @var{num}/@var{den} or a frame rate abbreviation.
@var{src_name} is the name to the frei0r source to load. For more
information regarding frei0r and how to set the parameters read the
-section "frei0r" (@pxref{frei0r}) in the description of the video
-filters.
+section @ref{frei0r} in the description of the video filters.
Some examples follow:
@example
@@ -1557,6 +2000,56 @@ Some examples follow:
frei0r_src=200x200:10:partik0l=1234 [overlay]; [in][overlay] overlay
@end example
+ at section rgbtestsrc, testsrc
+
+The @code{rgbtestsrc} source generates an RGB test pattern useful for
+detecting RGB vs BGR issues. You should see a red, green and blue
+stripe from top to bottom.
+
+The @code{testsrc} source generates a test video pattern, showing a
+color pattern, a scrolling gradient and a timestamp. This is mainly
+intended for testing purposes.
+
+Both sources accept an optional sequence of @var{key}=@var{value} pairs,
+separated by ":". The description of the accepted options follows.
+
+ at table @option
+
+ at item size, s
+Specify the size of the sourced video, it may be a string of the form
+ at var{width}x at var{height}, or the name of a size abbreviation. The
+default value is "320x240".
+
+ at item rate, r
+Specify the frame rate of the sourced video, as the number of frames
+generated per second. It has to be a string in the format
+ at var{frame_rate_num}/@var{frame_rate_den}, an integer number, a float
+number or a valid video frame rate abbreviation. The default value is
+"25".
+
+ at item sar
+Set the sample aspect ratio of the sourced video.
+
+ at item duration
+Set the video duration of the sourced video. The accepted syntax is:
+ at example
+[-]HH[:MM[:SS[.m...]]]
+[-]S+[.m...]
+ at end example
+See also the function @code{av_parse_time()}.
+
+If not specified, or the expressed duration is negative, the video is
+supposed to be generated forever.
+ at end table
+
+For example the following:
+ at example
+testsrc=duration=5.3:size=qcif:rate=10
+ at end example
+
+will generate a video with a duration of 5.3 seconds, with size
+176x144 and a framerate of 10 frames per second.
+
@c man end VIDEO SOURCES
@chapter Video Sinks
diff --git a/doc/general.texi b/doc/general.texi
index da6b621..8eaa97b 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -9,26 +9,81 @@
@contents
- at chapter external libraries
+ at chapter External libraries
Libav can be hooked up with a number of external libraries to add support
for more formats. None of them are used by default, their use has to be
explicitly requested by passing the appropriate flags to @file{./configure}.
- at section OpenCORE AMR
+ at section OpenCORE and VisualOn libraries
-Libav can make use of the OpenCORE libraries for AMR-NB
-decoding/encoding and AMR-WB decoding.
+Spun off Google Android sources, OpenCore and VisualOn libraries provide
+encoders for a number of audio codecs.
-Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the instructions for
-installing the libraries. Then pass @code{--enable-libopencore-amrnb} and/or
- at code{--enable-libopencore-amrwb} to configure to enable the libraries.
-
-Note that OpenCORE is under the Apache License 2.0 (see
- at url{http://www.apache.org/licenses/LICENSE-2.0} for details), which is
+ at float NOTE
+OpenCORE and VisualOn libraries are under the Apache License 2.0
+(see @url{http://www.apache.org/licenses/LICENSE-2.0} for details), which is
incompatible with the LGPL version 2.1 and GPL version 2. You have to
upgrade Libav's license to LGPL version 3 (or if you have enabled
GPL components, GPL version 3) to use it.
+ at end float
+
+ at subsection OpenCORE AMR
+
+Libav can make use of the OpenCORE libraries for AMR-NB
+decoding/encoding and AMR-WB decoding.
+
+Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the
+instructions for installing the libraries.
+Then pass @code{--enable-libopencore-amrnb} and/or
+ at code{--enable-libopencore-amrwb} to configure to enable them.
+
+ at subsection VisualOn AAC encoder library
+
+Libav can make use of the VisualOn AACenc library for AAC encoding.
+
+Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the
+instructions for installing the library.
+Then pass @code{--enable-libvo-aacenc} to configure to enable it.
+
+ at subsection VisualOn AMR-WB encoder library
+
+Libav can make use of the VisualOn AMR-WBenc library for AMR-WB encoding.
+
+Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the
+instructions for installing the library.
+Then pass @code{--enable-libvo-amrwbenc} to configure to enable it.
+
+ at section LAME
+
+Libav can make use of the LAME library for MP3 encoding.
+
+Go to @url{http://lame.sourceforge.net/} and follow the
+instructions for installing the library.
+Then pass @code{--enable-libmp3lame} to configure to enable it.
+
+ at section libvpx
+
+Libav can make use of the libvpx library for VP8 encoding.
+
+Go to @url{http://www.webmproject.org/} and follow the instructions for
+installing the library. Then pass @code{--enable-libvpx} to configure to
+enable it.
+
+ at section x264
+
+Libav can make use of the x264 library for H.264 encoding.
+
+Go to @url{http://www.videolan.org/developers/x264.html} and follow the
+instructions for installing the library. Then pass @code{--enable-libx264} to
+configure to enable it.
+
+ at float NOTE
+x264 is under the GNU Public License Version 2 or later
+(see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for
+details), you must upgrade Libav's license to GPL in order to use it.
+ at end float
+
@chapter Supported File Formats and Codecs
@@ -66,6 +121,10 @@ library:
@tab Used in Z and Z95 games.
@item Brute Force & Ignorance @tab @tab X
@tab Used in the game Flash Traffic: City of Angels.
+ at item BWF @tab X @tab X
+ at item CRI ADX @tab @tab X
+ @tab Audio-only format used in console video games.
+ at item Discworld II BMV @tab @tab X
@item Interplay C93 @tab @tab X
@tab Used in the game Cyberia from Interplay.
@item Delphine Software International CIN @tab @tab X
@@ -90,7 +149,7 @@ library:
@item Electronic Arts cdata @tab @tab X
@item Electronic Arts Multimedia @tab @tab X
@tab Used in various EA games; files have extensions like WVE and UV2.
- at item FFM (FFserver live feed) @tab X @tab X
+ at item FFM (AVserver live feed) @tab X @tab X
@item Flash (SWF) @tab X @tab X
@item Flash 9 (AVM2) @tab X @tab X
@tab Only embedded audio is decoded.
@@ -117,6 +176,7 @@ library:
@tab A format generated by IndigoVision 8000 video server.
@item IVF (On2) @tab X @tab X
@tab A format used by libvpx
+ at item LATM @tab X @tab X
@item LMLM4 @tab @tab X
@tab Used by Linux Media Labs MPEG-4 PCI boards
@item LXF @tab @tab X
@@ -162,6 +222,7 @@ library:
@item NUT @tab X @tab X
@tab NUT Open Container Format
@item Ogg @tab X @tab X
+ at item Playstation Portable PMP @tab @tab X
@item TechnoTrend PVA @tab @tab X
@tab Used by TechnoTrend DVB PCI boards.
@item QCP @tab @tab X
@@ -235,7 +296,9 @@ library:
@tab Used in Sierra CD-ROM games.
@item Smacker @tab @tab X
@tab Multimedia format used by many games.
- at item Sony OpenMG (OMA) @tab @tab X
+ at item SMJPEG @tab @tab X
+ @tab Used in certain Loki game ports.
+ at item Sony OpenMG (OMA) @tab X @tab X
@tab Audio format used in Sony Sonic Stage and Sony Vegas.
@item Sony PlayStation STR @tab @tab X
@item Sony Wave64 (W64) @tab @tab X
@@ -258,6 +321,8 @@ library:
@tab Multimedia format used in Westwood Studios games.
@item Westwood Studios VQA @tab @tab X
@tab Multimedia format used in Westwood Studios games.
+ at item XMV @tab @tab X
+ @tab Microsoft video container used in Xbox games.
@item xWMA @tab @tab X
@tab Microsoft audio container used by XAudio 2.
@item YUV4MPEG pipe @tab X @tab X
@@ -337,6 +402,7 @@ following image formats are supported:
@tab Used in Chinese MP3 players.
@item ANSI/ASCII art @tab @tab X
@item Apple MJPEG-B @tab @tab X
+ at item Apple ProRes @tab @tab X
@item Apple QuickDraw @tab @tab X
@tab fourcc: qdrw
@item Asus v1 @tab X @tab X
@@ -371,8 +437,9 @@ following image formats are supported:
@tab AVS1-P2, JiZhun profile, encoding through external library libxavs
@item Delphine Software International CIN video @tab @tab X
@tab Codec used in Delphine Software International games.
+ at item Discworld II BMV Video @tab @tab X
@item Cinepak @tab @tab X
- at item Cirrus Logic AccuPak @tab @tab X
+ at item Cirrus Logic AccuPak @tab X @tab X
@tab fourcc: CLJR
@item Creative YUV (CYUV) @tab @tab X
@item DFA @tab @tab X
@@ -387,6 +454,7 @@ following image formats are supported:
@item Duck TrueMotion 2.0 @tab @tab X
@tab fourcc: TM20
@item DV (Digital Video) @tab X @tab X
+ at item Dxtory capture format @tab @tab X
@item Feeble Files/ScummVM DXA @tab @tab X
@tab Codec originally used in Feeble Files game.
@item Electronic Arts CMV video @tab @tab X
@@ -400,6 +468,7 @@ following image formats are supported:
@tab experimental lossless codec (fourcc: FFV1)
@item Flash Screen Video v1 @tab X @tab X
@tab fourcc: FSV1
+ at item Flash Screen Video v2 @tab @tab X
@item Flash Video (FLV) @tab X @tab X
@tab Sorenson H.263 used in Flash
@item Fraps @tab @tab X
@@ -418,12 +487,13 @@ following image formats are supported:
@item id RoQ video @tab X @tab X
@tab Used in Quake III, Jedi Knight 2, other computer games.
@item IFF ILBM @tab @tab X
- @tab IFF interlaved bitmap
+ @tab IFF interleaved bitmap
@item IFF ByteRun1 @tab @tab X
@tab IFF run length encoded bitmap
@item Intel H.263 @tab @tab X
@item Intel Indeo 2 @tab @tab X
@item Intel Indeo 3 @tab @tab X
+ at item Intel Indeo 4 @tab @tab X
@item Intel Indeo 5 @tab @tab X
@item Interplay C93 @tab @tab X
@tab Used in the game Cyberia from Interplay.
@@ -510,10 +580,14 @@ following image formats are supported:
@tab encoding supported through external library libtheora
@item Tiertex Limited SEQ video @tab @tab X
@tab Codec used in DOS CD-ROM FlashBack game.
- at item V210 Quicktime Uncompressed 4:2:2 10-bit @tab X @tab X
+ at item Ut Video @tab @tab X
+ at item v210 QuickTime uncompressed 4:2:2 10-bit @tab X @tab X
+ at item v410 QuickTime uncompressed 4:4:4 10-bit @tab X @tab X
+ at item VBLE Lossless Codec @tab @tab X
@item VMware Screen Codec / VMware Video @tab @tab X
@tab Codec used in videos captured by VMware.
@item Westwood Studios VQA (Vector Quantized Animation) video @tab @tab X
+ at item Windows Media Image @tab @tab X
@item Windows Media Video 7 @tab X @tab X
@item Windows Media Video 8 @tab X @tab X
@item Windows Media Video 9 @tab @tab X
@@ -600,6 +674,7 @@ following image formats are supported:
@tab Used in Bink and Smacker files in many games.
@item Delphine Software International CIN audio @tab @tab X
@tab Codec used in Delphine Software International games.
+ at item Discworld II BMV Audio @tab @tab X
@item COOK @tab @tab X
@tab All versions except 5.1 are supported.
@item DCA (DTS Coherent Acoustics) @tab @tab X
@@ -658,7 +733,7 @@ following image formats are supported:
@item PCM unsigned 24-bit little-endian @tab X @tab X
@item PCM unsigned 32-bit big-endian @tab X @tab X
@item PCM unsigned 32-bit little-endian @tab X @tab X
- at item PCM Zork @tab X @tab X
+ at item PCM Zork @tab @tab X
@item QCELP / PureVoice @tab @tab X
@item QDesign Music Codec 2 @tab @tab X
@tab There are still some distortions.
@@ -674,7 +749,7 @@ following image formats are supported:
@tab Used in Sierra VMD files.
@item Smacker audio @tab @tab X
@item SMPTE 302M AES3 audio @tab @tab X
- at item Speex @tab @tab E
+ at item Speex @tab E @tab E
@tab supported through external library libspeex
@item True Audio (TTA) @tab @tab X
@item TrueHD @tab @tab X
@@ -739,6 +814,7 @@ performance on systems without hardware floating point support).
@item JACK @tab X @tab
@item LIBDC1394 @tab X @tab
@item OSS @tab X @tab X
+ at item Pulseaudio @tab X @tab
@item Video4Linux @tab X @tab
@item Video4Linux2 @tab X @tab
@item VfW capture @tab X @tab
@@ -747,338 +823,4 @@ performance on systems without hardware floating point support).
@code{X} means that input/output is supported.
-
- at chapter Platform Specific information
-
- at section DOS
-
-Using a cross-compiler is preferred for various reasons.
-
- at section OS/2
-
-For information about compiling Libav on OS/2 see
- at url{http://www.edm2.com/index.php/FFmpeg}.
-
- at section Unix-like
-
-Some parts of Libav cannot be built with version 2.15 of the GNU
-assembler which is still provided by a few AMD64 distributions. To
-make sure your compiler really uses the required version of gas
-after a binutils upgrade, run:
-
- at example
-$(gcc -print-prog-name=as) --version
- at end example
-
-If not, then you should install a different compiler that has no
-hard-coded path to gas. In the worst case pass @code{--disable-asm}
-to configure.
-
- at subsection BSD
-
-BSD make will not build Libav, you need to install and use GNU Make
-(@file{gmake}).
-
- at subsection (Open)Solaris
-
-GNU Make is required to build Libav, so you have to invoke (@file{gmake}),
-standard Solaris Make will not work. When building with a non-c99 front-end
-(gcc, generic suncc) add either @code{--extra-libs=/usr/lib/values-xpg6.o}
-or @code{--extra-libs=/usr/lib/64/values-xpg6.o} to the configure options
-since the libc is not c99-compliant by default. The probes performed by
-configure may raise an exception leading to the death of configure itself
-due to a bug in the system shell. Simply invoke a different shell such as
-bash directly to work around this:
-
- at example
-bash ./configure
- at end example
-
- at subsection Darwin (MacOS X, iPhone)
-
-MacOS X on PowerPC or ARM (iPhone) requires a preprocessor from
- at url{http://github.com/yuvi/gas-preprocessor} to build the optimized
-assembler functions. Just download the Perl script and put it somewhere
-in your PATH, Libav's configure will pick it up automatically.
-
- at section Windows
-
- at subsection Native Windows compilation
-
-Libav can be built to run natively on Windows using the MinGW tools. Install
-the latest versions of MSYS and MinGW from @url{http://www.mingw.org/}.
-You can find detailed installation
-instructions in the download section and the FAQ.
-
-Libav does not build out-of-the-box with the packages the automated MinGW
-installer provides. It also requires coreutils to be installed and many other
-packages updated to the latest version. The minimum version for some packages
-are listed below:
-
- at itemize
- at item bash 3.1
- at item msys-make 3.81-2 (note: not mingw32-make)
- at item w32api 3.13
- at item mingw-runtime 3.15
- at end itemize
-
-Libav automatically passes @code{-fno-common} to the compiler to work around
-a GCC bug (see @url{http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37216}).
-
-Notes:
-
- at itemize
-
- at item Building natively using MSYS can be sped up by disabling implicit rules
-in the Makefile by calling @code{make -r} instead of plain @code{make}. This
-speed up is close to non-existent for normal one-off builds and is only
-noticeable when running make for a second time (for example in
- at code{make install}).
-
- at item In order to compile FFplay, you must have the MinGW development library
-of SDL. Get it from @url{http://www.libsdl.org}.
-Edit the @file{bin/sdl-config} script so that it points to the correct prefix
-where SDL was installed. Verify that @file{sdl-config} can be launched from
-the MSYS command line.
-
- at item By using @code{./configure --enable-shared} when configuring Libav,
-you can build libavutil, libavcodec and libavformat as DLLs.
-
- at end itemize
-
- at subsection Microsoft Visual C++ compatibility
-
-As stated in the FAQ, Libav will not compile under MSVC++. However, if you
-want to use the libav* libraries in your own applications, you can still
-compile those applications using MSVC++. But the libav* libraries you link
-to @emph{must} be built with MinGW. However, you will not be able to debug
-inside the libav* libraries, since MSVC++ does not recognize the debug
-symbols generated by GCC.
-We strongly recommend you to move over from MSVC++ to MinGW tools.
-
-This description of how to use the Libav libraries with MSVC++ is based on
-Microsoft Visual C++ 2005 Express Edition. If you have a different version,
-you might have to modify the procedures slightly.
-
- at subsubsection Using static libraries
-
-Assuming you have just built and installed Libav in @file{/usr/local}.
-
- at enumerate
-
- at item Create a new console application ("File / New / Project") and then
-select "Win32 Console Application". On the appropriate page of the
-Application Wizard, uncheck the "Precompiled headers" option.
-
- at item Write the source code for your application, or, for testing, just
-copy the code from an existing sample application into the source file
-that MSVC++ has already created for you. For example, you can copy
- at file{libavformat/output-example.c} from the Libav distribution.
-
- at item Open the "Project / Properties" dialog box. In the "Configuration"
-combo box, select "All Configurations" so that the changes you make will
-affect both debug and release builds. In the tree view on the left hand
-side, select "C/C++ / General", then edit the "Additional Include
-Directories" setting to contain the path where the Libav includes were
-installed (i.e. @file{c:\msys\1.0\local\include}).
-Do not add MinGW's include directory here, or the include files will
-conflict with MSVC's.
-
- at item Still in the "Project / Properties" dialog box, select
-"Linker / General" from the tree view and edit the
-"Additional Library Directories" setting to contain the @file{lib}
-directory where Libav was installed (i.e. @file{c:\msys\1.0\local\lib}),
-the directory where MinGW libs are installed (i.e. @file{c:\mingw\lib}),
-and the directory where MinGW's GCC libs are installed
-(i.e. @file{C:\mingw\lib\gcc\mingw32\4.2.1-sjlj}). Then select
-"Linker / Input" from the tree view, and add the files @file{libavformat.a},
- at file{libavcodec.a}, @file{libavutil.a}, @file{libmingwex.a},
- at file{libgcc.a}, and any other libraries you used (i.e. @file{libz.a})
-to the end of "Additional Dependencies".
-
- at item Now, select "C/C++ / Code Generation" from the tree view. Select
-"Debug" in the "Configuration" combo box. Make sure that "Runtime
-Library" is set to "Multi-threaded Debug DLL". Then, select "Release" in
-the "Configuration" combo box and make sure that "Runtime Library" is
-set to "Multi-threaded DLL".
-
- at item Click "OK" to close the "Project / Properties" dialog box.
-
- at item MSVC++ lacks some C99 header files that are fundamental for Libav.
-Get msinttypes from @url{http://code.google.com/p/msinttypes/downloads/list}
-and install it in MSVC++'s include directory
-(i.e. @file{C:\Program Files\Microsoft Visual Studio 8\VC\include}).
-
- at item MSVC++ also does not understand the @code{inline} keyword used by
-Libav, so you must add this line before @code{#include}ing libav*:
- at example
-#define inline _inline
- at end example
-
- at item Build your application, everything should work.
-
- at end enumerate
-
- at subsubsection Using shared libraries
-
-This is how to create DLL and LIB files that are compatible with MSVC++:
-
- at enumerate
-
- at item Add a call to @file{vcvars32.bat} (which sets up the environment
-variables for the Visual C++ tools) as the first line of @file{msys.bat}.
-The standard location for @file{vcvars32.bat} is
- at file{C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat},
-and the standard location for @file{msys.bat} is @file{C:\msys\1.0\msys.bat}.
-If this corresponds to your setup, add the following line as the first line
-of @file{msys.bat}:
-
- at example
-call "C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat"
- at end example
-
-Alternatively, you may start the @file{Visual Studio 2005 Command Prompt},
-and run @file{c:\msys\1.0\msys.bat} from there.
-
- at item Within the MSYS shell, run @code{lib.exe}. If you get a help message
-from @file{Microsoft (R) Library Manager}, this means your environment
-variables are set up correctly, the @file{Microsoft (R) Library Manager}
-is on the path and will be used by Libav to create
-MSVC++-compatible import libraries.
-
- at item Build Libav with
-
- at example
-./configure --enable-shared
-make
-make install
- at end example
-
-Your install path (@file{/usr/local/} by default) should now have the
-necessary DLL and LIB files under the @file{bin} directory.
-
- at end enumerate
-
-To use those files with MSVC++, do the same as you would do with
-the static libraries, as described above. But in Step 4,
-you should only need to add the directory where the LIB files are installed
-(i.e. @file{c:\msys\usr\local\bin}). This is not a typo, the LIB files are
-installed in the @file{bin} directory. And instead of adding the static
-libraries (@file{libxxx.a} files) you should add the MSVC import libraries
-(@file{avcodec.lib}, @file{avformat.lib}, and
- at file{avutil.lib}). Note that you should not use the GCC import
-libraries (@file{libxxx.dll.a} files), as these will give you undefined
-reference errors. There should be no need for @file{libmingwex.a},
- at file{libgcc.a}, and @file{wsock32.lib}, nor any other external library
-statically linked into the DLLs. The @file{bin} directory contains a bunch
-of DLL files, but the ones that are actually used to run your application
-are the ones with a major version number in their filenames
-(i.e. @file{avcodec-51.dll}).
-
-Libav headers do not declare global data for Windows DLLs through the usual
-dllexport/dllimport interface. Such data will be exported properly while
-building, but to use them in your MSVC++ code you will have to edit the
-appropriate headers and mark the data as dllimport. For example, in
-libavutil/pixdesc.h you should have:
- at example
-extern __declspec(dllimport) const AVPixFmtDescriptor av_pix_fmt_descriptors[];
- at end example
-
-Note that using import libraries created by dlltool requires
-the linker optimization option to be set to
-"References: Keep Unreferenced Data (@code{/OPT:NOREF})", otherwise
-the resulting binaries will fail during runtime. This isn't
-required when using import libraries generated by lib.exe.
-This issue is reported upstream at
- at url{http://sourceware.org/bugzilla/show_bug.cgi?id=12633}.
-
- at subsection Cross compilation for Windows with Linux
-
-You must use the MinGW cross compilation tools available at
- at url{http://www.mingw.org/}.
-
-Then configure Libav with the following options:
- at example
-./configure --target-os=mingw32 --cross-prefix=i386-mingw32msvc-
- at end example
-(you can change the cross-prefix according to the prefix chosen for the
-MinGW tools).
-
-Then you can easily test Libav with Wine
-(@url{http://www.winehq.com/}).
-
- at subsection Compilation under Cygwin
-
-Please use Cygwin 1.7.x as the obsolete 1.5.x Cygwin versions lack
-llrint() in its C library.
-
-Install your Cygwin with all the "Base" packages, plus the
-following "Devel" ones:
- at example
-binutils, gcc4-core, make, git, mingw-runtime, texi2html
- at end example
-
-And the following "Utils" one:
- at example
-diffutils
- at end example
-
-Then run
-
- at example
-./configure
- at end example
-
-to make a static build.
-
-The current @code{gcc4-core} package is buggy and needs this flag to build
-shared libraries:
-
- at example
-./configure --enable-shared --disable-static --extra-cflags=-fno-reorder-functions
- at end example
-
-If you want to build Libav with additional libraries, download Cygwin
-"Devel" packages for Ogg and Vorbis from any Cygwin packages repository:
- at example
-libogg-devel, libvorbis-devel
- at end example
-
-These library packages are only available from Cygwin Ports
-(@url{http://sourceware.org/cygwinports/}) :
-
- at example
-yasm, libSDL-devel, libdirac-devel, libfaac-devel, libgsm-devel,
-libmp3lame-devel, libschroedinger1.0-devel, speex-devel, libtheora-devel,
-libxvidcore-devel
- at end example
-
-The recommendation for libnut and x264 is to build them from source by
-yourself, as they evolve too quickly for Cygwin Ports to be up to date.
-
-Cygwin 1.7.x has IPv6 support. You can add IPv6 to Cygwin 1.5.x by means
-of the @code{libgetaddrinfo-devel} package, available at Cygwin Ports.
-
- at subsection Crosscompilation for Windows under Cygwin
-
-With Cygwin you can create Windows binaries that do not need the cygwin1.dll.
-
-Just install your Cygwin as explained before, plus these additional
-"Devel" packages:
- at example
-gcc-mingw-core, mingw-runtime, mingw-zlib
- at end example
-
-and add some special flags to your configure invocation.
-
-For a static build run
- at example
-./configure --target-os=mingw32 --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin
- at end example
-
-and for a build with shared libraries
- at example
-./configure --target-os=mingw32 --enable-shared --disable-static --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin
- at end example
-
@bye
diff --git a/doc/git-howto.texi b/doc/git-howto.texi
new file mode 100644
index 0000000..b01981e
--- /dev/null
+++ b/doc/git-howto.texi
@@ -0,0 +1,344 @@
+\input texinfo @c -*- texinfo -*-
+
+ at settitle Using git to develop Libav
+
+ at titlepage
+ at center @titlefont{Using git to develop Libav}
+ at end titlepage
+
+ at top
+
+ at contents
+
+ at chapter Introduction
+
+This document aims in giving some quick references on a set of useful git
+commands. You should always use the extensive and detailed documentation
+provided directly by git:
+
+ at example
+git --help
+man git
+ at end example
+
+shows you the available subcommands,
+
+ at example
+git <command> --help
+man git-<command>
+ at end example
+
+shows information about the subcommand <command>.
+
+Additional information could be found on the
+ at url{http://gitref.org, Git Reference} website
+
+For more information about the Git project, visit the
+
+ at url{http://git-scm.com/, Git website}
+
+Consult these resources whenever you have problems, they are quite exhaustive.
+
+What follows now is a basic introduction to Git and some Libav-specific
+guidelines to ease the contribution to the project
+
+ at chapter Basics Usage
+
+ at section Get GIT
+
+You can get git from @url{http://git-scm.com/}
+Most distribution and operating system provide a package for it.
+
+
+ at section Cloning the source tree
+
+ at example
+git clone git://git.libav.org/libav.git <target>
+ at end example
+
+This will put the Libav sources into the directory @var{<target>}.
+
+ at example
+git clone git@@git.libav.org:libav.git <target>
+ at end example
+
+This will put the Libav sources into the directory @var{<target>} and let
+you push back your changes to the remote repository.
+
+
+ at section Updating the source tree to the latest revision
+
+ at example
+git pull (--rebase)
+ at end example
+
+pulls in the latest changes from the tracked branch. The tracked branch
+can be remote. By default the master branch tracks the branch master in
+the remote origin.
+
+ at float IMPORTANT
+Since merge commits are forbidden @command{--rebase} (see below) is recommended.
+ at end float
+
+ at section Rebasing your local branches
+
+ at example
+git pull --rebase
+ at end example
+
+fetches the changes from the main repository and replays your local commits
+over it. This is required to keep all your local changes at the top of
+Libav's master tree. The master tree will reject pushes with merge commits.
+
+
+ at section Adding/removing files/directories
+
+ at example
+git add [-A] <filename/dirname>
+git rm [-r] <filename/dirname>
+ at end example
+
+GIT needs to get notified of all changes you make to your working
+directory that makes files appear or disappear.
+Line moves across files are automatically tracked.
+
+
+ at section Showing modifications
+
+ at example
+git diff <filename(s)>
+ at end example
+
+will show all local modifications in your working directory as unified diff.
+
+
+ at section Inspecting the changelog
+
+ at example
+git log <filename(s)>
+ at end example
+
+You may also use the graphical tools like gitview or gitk or the web
+interface available at http://git.libav.org/
+
+ at section Checking source tree status
+
+ at example
+git status
+ at end example
+
+detects all the changes you made and lists what actions will be taken in case
+of a commit (additions, modifications, deletions, etc.).
+
+
+ at section Committing
+
+ at example
+git diff --check
+ at end example
+
+to double check your changes before committing them to avoid trouble later
+on. All experienced developers do this on each and every commit, no matter
+how small.
+Every one of them has been saved from looking like a fool by this many times.
+It's very easy for stray debug output or cosmetic modifications to slip in,
+please avoid problems through this extra level of scrutiny.
+
+For cosmetics-only commits you should get (almost) empty output from
+
+ at example
+git diff -w -b <filename(s)>
+ at end example
+
+Also check the output of
+
+ at example
+git status
+ at end example
+
+to make sure you don't have untracked files or deletions.
+
+ at example
+git add [-i|-p|-A] <filenames/dirnames>
+ at end example
+
+Make sure you have told git your name and email address
+
+ at example
+git config --global user.name "My Name"
+git config --global user.email my@@email.invalid
+ at end example
+
+Use @var{--global} to set the global configuration for all your git checkouts.
+
+Git will select the changes to the files for commit. Optionally you can use
+the interactive or the patch mode to select hunk by hunk what should be
+added to the commit.
+
+
+ at example
+git commit
+ at end example
+
+Git will commit the selected changes to your current local branch.
+
+You will be prompted for a log message in an editor, which is either
+set in your personal configuration file through
+
+ at example
+git config --global core.editor
+ at end example
+
+or set by one of the following environment variables:
+ at var{GIT_EDITOR}, @var{VISUAL} or @var{EDITOR}.
+
+Log messages should be concise but descriptive. Explain why you made a change,
+what you did will be obvious from the changes themselves most of the time.
+Saying just "bug fix" or "10l" is bad. Remember that people of varying skill
+levels look at and educate themselves while reading through your code. Don't
+include filenames in log messages, Git provides that information.
+
+Possibly make the commit message have a terse, descriptive first line, an
+empty line and then a full description. The first line will be used to name
+the patch by git format-patch.
+
+ at section Preparing a patchset
+
+ at example
+git format-patch <commit> [-o directory]
+ at end example
+
+will generate a set of patches for each commit between @var{<commit>} and
+current @var{HEAD}. E.g.
+
+ at example
+git format-patch origin/master
+ at end example
+
+will generate patches for all commits on current branch which are not
+present in upstream.
+A useful shortcut is also
+
+ at example
+git format-patch -n
+ at end example
+
+which will generate patches from last @var{n} commits.
+By default the patches are created in the current directory.
+
+ at section Sending patches for review
+
+ at example
+git send-email <commit list|directory>
+ at end example
+
+will send the patches created by @command{git format-patch} or directly
+generates them. All the email fields can be configured in the global/local
+configuration or overridden by command line.
+Note that this tool must often be installed separately (e.g. @var{git-email}
+package on Debian-based distros).
+
+
+ at section Renaming/moving/copying files or contents of files
+
+Git automatically tracks such changes, making those normal commits.
+
+ at example
+mv/cp path/file otherpath/otherfile
+git add [-A] .
+git commit
+ at end example
+
+
+ at chapter Libav specific
+
+ at section Reverting broken commits
+
+ at example
+git reset <commit>
+ at end example
+
+ at command{git reset} will uncommit the changes till @var{<commit>} rewriting
+the current branch history.
+
+ at example
+git commit --amend
+ at end example
+
+allows to amend the last commit details quickly.
+
+ at example
+git rebase -i origin/master
+ at end example
+
+will replay local commits over the main repository allowing to edit, merge
+or remove some of them in the process.
+
+ at float NOTE
+ at command{git reset}, @command{git commit --amend} and @command{git rebase}
+rewrite history, so you should use them ONLY on your local or topic branches.
+The main repository will reject those changes.
+ at end float
+
+ at example
+git revert <commit>
+ at end example
+
+ at command{git revert} will generate a revert commit. This will not make the
+faulty commit disappear from the history.
+
+ at section Pushing changes to remote trees
+
+ at example
+git push
+ at end example
+
+Will push the changes to the default remote (@var{origin}).
+Git will prevent you from pushing changes if the local and remote trees are
+out of sync. Refer to and to sync the local tree.
+
+ at example
+git remote add <name> <url>
+ at end example
+
+Will add additional remote with a name reference, it is useful if you want
+to push your local branch for review on a remote host.
+
+ at example
+git push <remote> <refspec>
+ at end example
+
+Will push the changes to the @var{<remote>} repository.
+Omitting @var{<refspec>} makes @command{git push} update all the remote
+branches matching the local ones.
+
+ at section Finding a specific svn revision
+
+Since version 1.7.1 git supports @var{:/foo} syntax for specifying commits
+based on a regular expression. see man gitrevisions
+
+ at example
+git show :/'as revision 23456'
+ at end example
+
+will show the svn changeset @var{r23456}. With older git versions searching in
+the @command{git log} output is the easiest option (especially if a pager with
+search capabilities is used).
+This commit can be checked out with
+
+ at example
+git checkout -b svn_23456 :/'as revision 23456'
+ at end example
+
+or for git < 1.7.1 with
+
+ at example
+git checkout -b svn_23456 $SHA1
+ at end example
+
+where @var{$SHA1} is the commit hash from the @command{git log} output.
+
+ at chapter Server Issues
+
+Contact the project admins @email{git@@libav.org} if you have technical
+problems with the GIT server.
diff --git a/doc/git-howto.txt b/doc/git-howto.txt
index ba377c9..036b567 100644
--- a/doc/git-howto.txt
+++ b/doc/git-howto.txt
@@ -205,8 +205,19 @@ I. BASICS:
git format-patch <commit> [-o directory]
- will generate a set of patches out of the current branch starting from
- commit. By default the patches are created in the current directory.
+ will generate a set of patches for each commit between <commit> and
+ current HEAD. E.g.
+
+ git format-patch origin/master
+
+ will generate patches for all commits on current branch which are not
+ present in upstream.
+ A useful shortcut is also
+
+ git format-patch -n
+
+ which will generate patches from last n commits.
+ By default the patches are created in the current directory.
11. Sending patches for review
@@ -215,6 +226,8 @@ I. BASICS:
will send the patches created by git format-patch or directly generates
them. All the email fields can be configured in the global/local
configuration or overridden by command line.
+ Note that this tool must often be installed separately (e.g. git-email
+ package on Debian-based distros).
12. Pushing changes to remote trees
diff --git a/doc/indevs.texi b/doc/indevs.texi
index c5e04b0..4405a5b 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -42,10 +42,10 @@ specify card number or identifier, device number and subdevice number
To see the list of cards currently recognized by your system check the
files @file{/proc/asound/cards} and @file{/proc/asound/devices}.
-For example to capture with @file{ffmpeg} from an ALSA device with
+For example to capture with @command{avconv} from an ALSA device with
card id 0, you may run the command:
@example
-ffmpeg -f alsa -i hw:0 alsaout.wav
+avconv -f alsa -i hw:0 alsaout.wav
@end example
For more information see:
@@ -72,14 +72,14 @@ For more detailed information read the file
Documentation/fb/framebuffer.txt included in the Linux source tree.
To record from the framebuffer device @file{/dev/fb0} with
- at file{ffmpeg}:
+ at command{avconv}:
@example
-ffmpeg -f fbdev -r 10 -i /dev/fb0 out.avi
+avconv -f fbdev -r 10 -i /dev/fb0 out.avi
@end example
You can take a single screenshot image with the command:
@example
-ffmpeg -f fbdev -vframes 1 -r 1 -i /dev/fb0 screenshot.jpeg
+avconv -f fbdev -frames:v 1 -r 1 -i /dev/fb0 screenshot.jpeg
@end example
See also @url{http://linux-fbdev.sourceforge.net/}, and fbset(1).
@@ -109,10 +109,10 @@ To list the JACK clients and their properties you can invoke the command
@file{jack_lsp}.
Follows an example which shows how to capture a JACK readable client
-with @file{ffmpeg}.
+with @command{avconv}.
@example
-# Create a JACK writable client with name "ffmpeg".
-$ ffmpeg -f jack -i ffmpeg -y out.wav
+# Create a JACK writable client with name "libav".
+$ avconv -f jack -i libav -y out.wav
# Start the sample jack_metro readable client.
$ jack_metro -b 120 -d 0.2 -f 4000
@@ -123,11 +123,11 @@ system:capture_1
system:capture_2
system:playback_1
system:playback_2
-ffmpeg:input_1
+libav:input_1
metro:120_bpm
-# Connect metro to the ffmpeg writable client.
-$ jack_connect metro:120_bpm ffmpeg:input_1
+# Connect metro to the avconv writable client.
+$ jack_connect metro:120_bpm libav:input_1
@end example
For more information read:
@@ -145,15 +145,98 @@ The filename to provide to the input device is the device node
representing the OSS input device, and is usually set to
@file{/dev/dsp}.
-For example to grab from @file{/dev/dsp} using @file{ffmpeg} use the
+For example to grab from @file{/dev/dsp} using @command{avconv} use the
command:
@example
-ffmpeg -f oss -i /dev/dsp /tmp/oss.wav
+avconv -f oss -i /dev/dsp /tmp/oss.wav
@end example
For more information about OSS see:
@url{http://manuals.opensound.com/usersguide/dsp.html}
+ at section pulse
+
+pulseaudio input device.
+
+To enable this input device during configuration you need libpulse-simple
+installed in your system.
+
+The filename to provide to the input device is a source device or the
+string "default"
+
+To list the pulse source devices and their properties you can invoke
+the command @file{pactl list sources}.
+
+ at example
+avconv -f pulse -i default /tmp/pulse.wav
+ at end example
+
+ at subsection @var{server} AVOption
+
+The syntax is:
+ at example
+-server @var{server name}
+ at end example
+
+Connects to a specific server.
+
+ at subsection @var{name} AVOption
+
+The syntax is:
+ at example
+-name @var{application name}
+ at end example
+
+Specify the application name pulse will use when showing active clients,
+by default it is "libav"
+
+ at subsection @var{stream_name} AVOption
+
+The syntax is:
+ at example
+-stream_name @var{stream name}
+ at end example
+
+Specify the stream name pulse will use when showing active streams,
+by default it is "record"
+
+ at subsection @var{sample_rate} AVOption
+
+The syntax is:
+ at example
+-sample_rate @var{samplerate}
+ at end example
+
+Specify the samplerate in Hz, by default 48kHz is used.
+
+ at subsection @var{channels} AVOption
+
+The syntax is:
+ at example
+-channels @var{N}
+ at end example
+
+Specify the channels in use, by default 2 (stereo) is set.
+
+ at subsection @var{frame_size} AVOption
+
+The syntax is:
+ at example
+-frame_size @var{bytes}
+ at end example
+
+Specify the number of byte per frame, by default it is set to 1024.
+
+ at subsection @var{fragment_size} AVOption
+
+The syntax is:
+ at example
+-fragment_size @var{bytes}
+ at end example
+
+Specify the minimal buffering fragment in pulseaudio, it will affect the
+audio latency. By default it is unset.
+
@section sndio
sndio input device.
@@ -165,10 +248,10 @@ The filename to provide to the input device is the device node
representing the sndio input device, and is usually set to
@file{/dev/audio0}.
-For example to grab from @file{/dev/audio0} using @file{ffmpeg} use the
+For example to grab from @file{/dev/audio0} using @command{avconv} use the
command:
@example
-ffmpeg -f sndio -i /dev/audio0 /tmp/oss.wav
+avconv -f sndio -i /dev/audio0 /tmp/oss.wav
@end example
@section video4linux and video4linux2
@@ -199,15 +282,15 @@ tools.
@example
# Grab and show the input of a video4linux device, frame rate is set
# to the default of 25/1.
-ffplay -s 320x240 -f video4linux /dev/video0
+avplay -s 320x240 -f video4linux /dev/video0
# Grab and show the input of a video4linux2 device, autoadjust size.
-ffplay -f video4linux2 /dev/video0
+avplay -f video4linux2 /dev/video0
# Grab and record the input of a video4linux2 device, autoadjust size,
# frame rate value defaults to 0/0 so it is read from the video4linux2
# driver.
-ffmpeg -f video4linux2 -i /dev/video0 out.mpeg
+avconv -f video4linux2 -i /dev/video0 out.mpeg
@end example
@section vfwcap
@@ -243,12 +326,51 @@ Check the X11 documentation (e.g. man X) for more detailed information.
Use the @file{dpyinfo} program for getting basic information about the
properties of your X11 display (e.g. grep for "name" or "dimensions").
-For example to grab from @file{:0.0} using @file{ffmpeg}:
+For example to grab from @file{:0.0} using @command{avconv}:
@example
-ffmpeg -f x11grab -r 25 -s cif -i :0.0 out.mpg
+avconv -f x11grab -r 25 -s cif -i :0.0 out.mpg
# Grab at position 10,20.
-ffmpeg -f x11grab -25 -s cif -i :0.0+10,20 out.mpg
+avconv -f x11grab -r 25 -s cif -i :0.0+10,20 out.mpg
+ at end example
+
+ at subsection @var{follow_mouse} AVOption
+
+The syntax is:
+ at example
+-follow_mouse centered|@var{PIXELS}
+ at end example
+
+When it is specified with "centered", the grabbing region follows the mouse
+pointer and keeps the pointer at the center of region; otherwise, the region
+follows only when the mouse pointer reaches within @var{PIXELS} (greater than
+zero) to the edge of region.
+
+For example:
+ at example
+avconv -f x11grab -follow_mouse centered -r 25 -s cif -i :0.0 out.mpg
+
+# Follows only when the mouse pointer reaches within 100 pixels to edge
+avconv -f x11grab -follow_mouse 100 -r 25 -s cif -i :0.0 out.mpg
+ at end example
+
+ at subsection @var{show_region} AVOption
+
+The syntax is:
+ at example
+-show_region 1
+ at end example
+
+If @var{show_region} AVOption is specified with @var{1}, then the grabbing
+region will be indicated on screen. With this option, it's easy to know what is
+being grabbed if only a portion of the screen is grabbed.
+
+For example:
+ at example
+avconv -f x11grab -show_region 1 -r 25 -s cif -i :0.0+10,20 out.mpg
+
+# With follow_mouse
+avconv -f x11grab -follow_mouse centered -show_region 1 -r 25 -s cif -i :0.0 out.mpg
@end example
@c man end INPUT DEVICES
diff --git a/doc/issue_tracker.txt b/doc/issue_tracker.txt
deleted file mode 100644
index e5733ec..0000000
--- a/doc/issue_tracker.txt
+++ /dev/null
@@ -1,228 +0,0 @@
-Libav's bug/patch/feature request tracker manual
-================================================
-
-NOTE: This is a draft.
-
-Overview:
----------
-Libav uses Roundup for tracking issues, new issues and changes to
-existing issues can be done through a web interface and through email.
-It is possible to subscribe to individual issues by adding yourself to the
-nosy list or to subscribe to the ffmpeg-issues mailing list which receives
-a mail for every change to every issue. Replies to such mails will also
-be properly added to the respective issue.
-(the above does all work already after light testing)
-The subscription URL for the ffmpeg-issues list is:
-http://live.polito/mailman/listinfo/ffmpeg-issues
-The URL of the webinterface of the tracker is:
-http(s)://roundup.libav.org/
-Note the URLs in this document are obfuscated, you must append the top level
-domain for non-profit organizations to the tracker, and of Italy to the
-mailing list.
-
-Email Interface:
-----------------
-There is a mailing list to which all new issues and changes to existing issues
-are sent. You can subscribe through
-http://live.polito/mailman/listinfo/ffmpeg-issues
-Replies to messages there will have their text added to the specific issues.
-Attachments will be added as if they had been uploaded via the web interface.
-You can change the status, substatus, topic, ... by changing the subject in
-your reply like:
-Re: [issue94] register_avcodec and allcodecs.h [type=patch;status=open;substatus=approved]
-Roundup will then change things as you requested and remove the [...] from
-the subject before forwarding the mail to the mailing list.
-
-
-NOTE: issue = (bug report || patch || feature request)
-
-Type:
------
-bug
- An error, flaw, mistake, failure, or fault in ffmpeg or libav* that
- prevents it from behaving as intended.
-
-feature request
- Request of support for encoding or decoding of a new codec, container
- or variant.
- Request of support for more, less or plain different output or behavior
- where the current implementation cannot be considered wrong.
-
-patch
- A patch as generated by diff which conforms to the patch submission and
- development policy.
-
-
-Priority:
----------
-critical
- Bugs and patches which deal with data loss and security issues.
- No feature request can be critical.
-
-important
- Bugs which make Libav unusable for a significant number of users, and
- patches fixing them.
- Examples here might be completely broken MPEG-4 decoding or a build issue
- on Linux.
- While broken 4xm decoding or a broken OS/2 build would not be important,
- the separation to normal is somewhat fuzzy.
- For feature requests this priority would be used for things many people
- want.
-
-normal
-
-
-minor
- Bugs and patches about things like spelling errors, "mp2" instead of
- "mp3" being shown and such.
- Feature requests about things few people want or which do not make a big
- difference.
-
-wish
- Something that is desirable to have but that there is no urgency at
- all to implement, e.g. something completely cosmetic like a website
- restyle or a personalized doxy template or the Libav logo.
- This priority is not valid for bugs.
-
-
-Status:
--------
-new
- initial state
-
-open
- intermediate states
-
-closed
- final state
-
-
-Type/Status/Substatus:
-----------
-*/new/new
- Initial state of new bugs, patches and feature requests submitted by
- users.
-
-*/open/open
- Issues which have been briefly looked at and which did not look outright
- invalid.
- This implicates that no real more detailed state applies yet. Conversely,
- the more detailed states below implicate that the issue has been briefly
- looked at.
-
-*/closed/duplicate
- Bugs, patches or feature requests which are duplicates.
- Note that patches dealing with the same thing in a different way are not
- duplicates.
- Note, if you mark something as duplicate, do not forget setting the
- superseder so bug reports are properly linked.
-
-*/closed/invalid
- Bugs caused by user errors, random ineligible or otherwise nonsense stuff.
-
-*/closed/needs_more_info
- Issues for which some information has been requested by the developers,
- but which has not been provided by anyone within reasonable time.
-
-bug/open/reproduced
- Bugs which have been reproduced.
-
-bug/open/analyzed
- Bugs which have been analyzed and where it is understood what causes them
- and which exact chain of events triggers them. This analysis should be
- available as a message in the bug report.
- Note, do not change the status to analyzed without also providing a clear
- and understandable analysis.
- This state implicates that the bug either has been reproduced or that
- reproduction is not needed as the bug is already understood.
-
-bug/open/needs_more_info
- Bug reports which are incomplete and or where more information is needed
- from the submitter or another person who can provide it.
- This state implicates that the bug has not been analyzed or reproduced.
- Note, the idea behind needs_more_info is to offload work from the
- developers to the users whenever possible.
-
-bug/closed/fixed
- Bugs which have to the best of our knowledge been fixed.
-
-bug/closed/wont_fix
- Bugs which we will not fix. Possible reasons include legality, high
- complexity for the sake of supporting obscure corner cases, speed loss
- for similarly esoteric purposes, et cetera.
- This also means that we would reject a patch.
- If we are just too lazy to fix a bug then the correct state is open
- and unassigned. Closed means that the case is closed which is not
- the case if we are just waiting for a patch.
-
-bug/closed/works_for_me
- Bugs for which sufficient information was provided to reproduce but
- reproduction failed - that is the code seems to work correctly to the
- best of our knowledge.
-
-patch/open/approved
- Patches which have been reviewed and approved by a developer.
- Such patches can be applied anytime by any other developer after some
- reasonable testing (compile + regression tests + does the patch do
- what the author claimed).
-
-patch/open/needs_changes
- Patches which have been reviewed and need changes to be accepted.
-
-patch/closed/applied
- Patches which have been applied.
-
-patch/closed/rejected
- Patches which have been rejected.
-
-feature_request/open/needs_more_info
- Feature requests where it is not clear what exactly is wanted
- (these also could be closed as invalid ...).
-
-feature_request/closed/implemented
- Feature requests which have been implemented.
-
-feature_request/closed/wont_implement
- Feature requests which will not be implemented. The reasons here could
- be legal, philosophical or others.
-
-Note, please do not use type-status-substatus combinations other than the
-above without asking on libav-devel first!
-
-Note2, if you provide the requested info do not forget to remove the
-needs_more_info substate.
-
-Topic:
-------
-A topic is a tag you should add to your issue in order to make grouping them
-easier.
-
-avcodec
- issues in libavcodec/*
-
-avformat
- issues in libavformat/*
-
-avutil
- issues in libavutil/*
-
-regression test
- issues in tests/*
-
-ffmpeg
- issues in or related to ffmpeg.c
-
-ffplay
- issues in or related to ffplay.c
-
-ffserver
- issues in or related to ffserver.c
-
-build system
- issues in or related to configure/Makefile
-
-regression
- bugs which were working in a past revision
-
-roundup
- issues related to our issue tracker
diff --git a/doc/libavfilter.texi b/doc/libavfilter.texi
index 1c12205..b452294 100644
--- a/doc/libavfilter.texi
+++ b/doc/libavfilter.texi
@@ -14,18 +14,6 @@
Libavfilter is the filtering API of Libav. It is the substitute of the
now deprecated 'vhooks' and started as a Google Summer of Code project.
-Integrating libavfilter into the main Libav repository is a work in
-progress. If you wish to try the unfinished development code of
-libavfilter then check it out from the libavfilter repository into
-some directory of your choice by:
-
- at example
- svn checkout svn://svn.libav.org/soc/libavfilter
- at end example
-
-And then read the README file in the top directory to learn how to
-integrate it into ffmpeg and ffplay.
-
But note that there may still be serious bugs in the code and its API
and ABI should not be considered stable yet!
@@ -48,15 +36,14 @@ and the vflip filter before merging it back with the other stream by
overlaying it on top. You can use the following command to achieve this:
@example
-./ffmpeg -i in.avi -s 240x320 -vf "[in] split [T1], fifo, [T2] overlay= 0:240 [out]; [T1] fifo, crop=0:0:-1:240, vflip [T2]
+./avconv -i input -vf "[in] split [T1], fifo, [T2] overlay=0:H/2 [out]; [T1] fifo, crop=iw:ih/2:0:ih/2, vflip [T2]" output
@end example
-where input_video.avi has a vertical resolution of 480 pixels. The
-result will be that in output the top half of the video is mirrored
+The result will be that in output the top half of the video is mirrored
onto the bottom half.
Video filters are loaded using the @var{-vf} option passed to
-ffmpeg or to ffplay. Filters in the same linear chain are separated by
+avconv or to avplay. Filters in the same linear chain are separated by
commas. In our example, @var{split, fifo, overlay} are in one linear
chain, and @var{fifo, crop, vflip} are in another. The points where
the linear chains join are labeled by names enclosed in square
diff --git a/doc/muxers.texi b/doc/muxers.texi
index 74c014b..5a609c8 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -35,23 +35,23 @@ CRC=0x at var{CRC}, where @var{CRC} is a hexadecimal number 0-padded to
For example to compute the CRC of the input, and store it in the file
@file{out.crc}:
@example
-ffmpeg -i INPUT -f crc out.crc
+avconv -i INPUT -f crc out.crc
@end example
You can print the CRC to stdout with the command:
@example
-ffmpeg -i INPUT -f crc -
+avconv -i INPUT -f crc -
@end example
-You can select the output format of each frame with @file{ffmpeg} by
+You can select the output format of each frame with @command{avconv} by
specifying the audio and video codec and format. For example to
compute the CRC of the input audio converted to PCM unsigned 8-bit
and the input video converted to MPEG-2 video, use the command:
@example
-ffmpeg -i INPUT -acodec pcm_u8 -vcodec mpeg2video -f crc -
+avconv -i INPUT -c:a pcm_u8 -c:v mpeg2video -f crc -
@end example
-See also the @code{framecrc} muxer (@pxref{framecrc}).
+See also the @ref{framecrc} muxer.
@anchor{framecrc}
@section framecrc
@@ -71,25 +71,26 @@ number 0-padded to 8 digits containing the CRC of the decoded frame.
For example to compute the CRC of each decoded frame in the input, and
store it in the file @file{out.crc}:
@example
-ffmpeg -i INPUT -f framecrc out.crc
+avconv -i INPUT -f framecrc out.crc
@end example
You can print the CRC of each decoded frame to stdout with the command:
@example
-ffmpeg -i INPUT -f framecrc -
+avconv -i INPUT -f framecrc -
@end example
-You can select the output format of each frame with @file{ffmpeg} by
+You can select the output format of each frame with @command{avconv} by
specifying the audio and video codec and format. For example, to
compute the CRC of each decoded input audio frame converted to PCM
unsigned 8-bit and of each decoded input video frame converted to
MPEG-2 video, use the command:
@example
-ffmpeg -i INPUT -acodec pcm_u8 -vcodec mpeg2video -f framecrc -
+avconv -i INPUT -c:a pcm_u8 -c:v mpeg2video -f framecrc -
@end example
-See also the @code{crc} muxer (@pxref{crc}).
+See also the @ref{crc} muxer.
+ at anchor{image2}
@section image2
Image file muxer.
@@ -119,26 +120,26 @@ The pattern "img%%-%d.jpg" will specify a sequence of filenames of the
form @file{img%-1.jpg}, @file{img%-2.jpg}, ..., @file{img%-10.jpg},
etc.
-The following example shows how to use @file{ffmpeg} for creating a
+The following example shows how to use @command{avconv} for creating a
sequence of files @file{img-001.jpeg}, @file{img-002.jpeg}, ...,
taking one image every second from the input video:
@example
-ffmpeg -i in.avi -r 1 -f image2 'img-%03d.jpeg'
+avconv -i in.avi -vsync 1 -r 1 -f image2 'img-%03d.jpeg'
@end example
-Note that with @file{ffmpeg}, if the format is not specified with the
+Note that with @command{avconv}, if the format is not specified with the
@code{-f} option and the output filename specifies an image file
format, the image2 muxer is automatically selected, so the previous
command can be written as:
@example
-ffmpeg -i in.avi -r 1 'img-%03d.jpeg'
+avconv -i in.avi -vsync 1 -r 1 'img-%03d.jpeg'
@end example
Note also that the pattern must not necessarily contain "%d" or
"%0 at var{N}d", for example to create a single image file
@file{img.jpeg} from the input video you can employ the command:
@example
-ffmpeg -i in.avi -f image2 -vframes 1 img.jpeg
+avconv -i in.avi -f image2 -frames:v 1 img.jpeg
@end example
@section mpegts
@@ -171,7 +172,7 @@ and @code{service_name}. If they are not set the default for
@code{service_name} is "Service01".
@example
-ffmpeg -i file.mpg -acodec copy -vcodec copy \
+avconv -i file.mpg -c copy \
-mpegts_original_network_id 0x1122 \
-mpegts_transport_stream_id 0x3344 \
-mpegts_service_id 0x5566 \
@@ -189,19 +190,19 @@ Null muxer.
This muxer does not generate any output file, it is mainly useful for
testing or benchmarking purposes.
-For example to benchmark decoding with @file{ffmpeg} you can use the
+For example to benchmark decoding with @command{avconv} you can use the
command:
@example
-ffmpeg -benchmark -i INPUT -f null out.null
+avconv -benchmark -i INPUT -f null out.null
@end example
Note that the above command does not read or write the @file{out.null}
-file, but specifying the output file is required by the @file{ffmpeg}
+file, but specifying the output file is required by the @command{avconv}
syntax.
Alternatively you can write the command as:
@example
-ffmpeg -benchmark -i INPUT -f null -
+avconv -benchmark -i INPUT -f null -
@end example
@section matroska
@@ -264,7 +265,38 @@ Both eyes laced in one Block, Right-eye view is first
For example a 3D WebM clip can be created using the following command line:
@example
-ffmpeg -i sample_left_right_clip.mpg -an -vcodec libvpx -metadata STEREO_MODE=left_right -y stereo_clip.webm
+avconv -i sample_left_right_clip.mpg -an -c:v libvpx -metadata STEREO_MODE=left_right -y stereo_clip.webm
@end example
+ at section segment
+
+Basic stream segmenter.
+
+The segmenter muxer outputs streams to a number of separate files of nearly
+fixed duration. Output filename pattern can be set in a fashion similar to
+ at ref{image2}.
+
+Every segment starts with a video keyframe, if a video stream is present.
+The segment muxer works best with a single constant frame rate video.
+
+Optionally it can generate a flat list of the created segments, one segment
+per line.
+
+ at table @option
+ at item segment_format @var{format}
+Override the inner container format, by default it is guessed by the filename
+extension.
+ at item segment_time @var{t}
+Set segment duration to @var{t} seconds.
+ at item segment_list @var{name}
+Generate also a listfile named @var{name}.
+ at item segment_list_size @var{size}
+Overwrite the listfile once it reaches @var{size} entries.
+ at end table
+
+ at example
+avconv -i in.mkv -c copy -map 0 -f segment -list out.list out%03d.nut
+ at end example
+
+
@c man end MUXERS
diff --git a/doc/platform.texi b/doc/platform.texi
new file mode 100644
index 0000000..6a44640
--- /dev/null
+++ b/doc/platform.texi
@@ -0,0 +1,359 @@
+\input texinfo @c -*- texinfo -*-
+
+ at settitle Platform Specific information
+ at titlepage
+ at center @titlefont{Platform Specific information}
+ at end titlepage
+
+ at top
+
+ at contents
+
+ at chapter Unix-like
+
+Some parts of Libav cannot be built with version 2.15 of the GNU
+assembler which is still provided by a few AMD64 distributions. To
+make sure your compiler really uses the required version of gas
+after a binutils upgrade, run:
+
+ at example
+$(gcc -print-prog-name=as) --version
+ at end example
+
+If not, then you should install a different compiler that has no
+hard-coded path to gas. In the worst case pass @code{--disable-asm}
+to configure.
+
+ at section BSD
+
+BSD make will not build Libav, you need to install and use GNU Make
+(@file{gmake}).
+
+ at section (Open)Solaris
+
+GNU Make is required to build Libav, so you have to invoke (@file{gmake}),
+standard Solaris Make will not work. When building with a non-c99 front-end
+(gcc, generic suncc) add either @code{--extra-libs=/usr/lib/values-xpg6.o}
+or @code{--extra-libs=/usr/lib/64/values-xpg6.o} to the configure options
+since the libc is not c99-compliant by default. The probes performed by
+configure may raise an exception leading to the death of configure itself
+due to a bug in the system shell. Simply invoke a different shell such as
+bash directly to work around this:
+
+ at example
+bash ./configure
+ at end example
+
+ at anchor{Darwin}
+ at section Darwin (OSX, iPhone)
+
+The toolchain provided with Xcode is sufficient to build the basic
+unacelerated code.
+
+OSX on PowerPC or ARM (iPhone) requires a preprocessor from
+ at url{http://github.com/yuvi/gas-preprocessor} to build the optimized
+assembler functions. Just download the Perl script and put it somewhere
+in your PATH, Libav's configure will pick it up automatically.
+
+OSX on amd64 and x86 requires @command{yasm} to build most of the
+optimized assembler functions @url{http://mxcl.github.com/homebrew/, Homebrew},
+ at url{http://www.gentoo.org/proj/en/gentoo-alt/prefix/bootstrap-macos.xml, Gentoo Prefix}
+or @url{http://www.macports.org, MacPorts} can easily provide it.
+
+
+ at chapter DOS
+
+Using a cross-compiler is preferred for various reasons.
+ at url{http://www.delorie.com/howto/djgpp/linux-x-djgpp.html}
+
+
+ at chapter OS/2
+
+For information about compiling Libav on OS/2 see
+ at url{http://www.edm2.com/index.php/FFmpeg}.
+
+
+ at chapter Windows
+
+ at section Native Windows compilation
+
+Libav can be built to run natively on Windows using the MinGW tools. Install
+the latest versions of MSYS and MinGW from @url{http://www.mingw.org/}.
+You can find detailed installation
+instructions in the download section and the FAQ.
+
+Libav does not build out-of-the-box with the packages the automated MinGW
+installer provides. It also requires coreutils to be installed and many other
+packages updated to the latest version. The minimum version for some packages
+are listed below:
+
+ at itemize
+ at item bash 3.1
+ at item msys-make 3.81-2 (note: not mingw32-make)
+ at item w32api 3.13
+ at item mingw-runtime 3.15
+ at end itemize
+
+Libav automatically passes @code{-fno-common} to the compiler to work around
+a GCC bug (see @url{http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37216}).
+
+Notes:
+
+ at itemize
+
+ at item Building natively using MSYS can be sped up by disabling implicit rules
+in the Makefile by calling @code{make -r} instead of plain @code{make}. This
+speed up is close to non-existent for normal one-off builds and is only
+noticeable when running make for a second time (for example in
+ at code{make install}).
+
+ at item In order to compile AVplay, you must have the MinGW development library
+of @uref{http://www.libsdl.org/, SDL}.
+Edit the @file{bin/sdl-config} script so that it points to the correct prefix
+where SDL was installed. Verify that @file{sdl-config} can be launched from
+the MSYS command line.
+
+ at item By using @code{./configure --enable-shared} when configuring Libav,
+you can build libavutil, libavcodec and libavformat as DLLs.
+
+ at end itemize
+
+ at section Microsoft Visual C++ compatibility
+
+As stated in the FAQ, Libav will not compile under MSVC++. However, if you
+want to use the libav* libraries in your own applications, you can still
+compile those applications using MSVC++. But the libav* libraries you link
+to @emph{must} be built with MinGW. However, you will not be able to debug
+inside the libav* libraries, since MSVC++ does not recognize the debug
+symbols generated by GCC.
+We strongly recommend you to move over from MSVC++ to MinGW tools.
+
+This description of how to use the Libav libraries with MSVC++ is based on
+Microsoft Visual C++ 2005 Express Edition. If you have a different version,
+you might have to modify the procedures slightly.
+
+ at subsection Using static libraries
+
+Assuming you have just built and installed Libav in @file{/usr/local}.
+
+ at enumerate
+
+ at item Create a new console application ("File / New / Project") and then
+select "Win32 Console Application". On the appropriate page of the
+Application Wizard, uncheck the "Precompiled headers" option.
+
+ at item Write the source code for your application, or, for testing, just
+copy the code from an existing sample application into the source file
+that MSVC++ has already created for you. For example, you can copy
+ at file{libavformat/output-example.c} from the Libav distribution.
+
+ at item Open the "Project / Properties" dialog box. In the "Configuration"
+combo box, select "All Configurations" so that the changes you make will
+affect both debug and release builds. In the tree view on the left hand
+side, select "C/C++ / General", then edit the "Additional Include
+Directories" setting to contain the path where the Libav includes were
+installed (i.e. @file{c:\msys\1.0\local\include}).
+Do not add MinGW's include directory here, or the include files will
+conflict with MSVC's.
+
+ at item Still in the "Project / Properties" dialog box, select
+"Linker / General" from the tree view and edit the
+"Additional Library Directories" setting to contain the @file{lib}
+directory where Libav was installed (i.e. @file{c:\msys\1.0\local\lib}),
+the directory where MinGW libs are installed (i.e. @file{c:\mingw\lib}),
+and the directory where MinGW's GCC libs are installed
+(i.e. @file{C:\mingw\lib\gcc\mingw32\4.2.1-sjlj}). Then select
+"Linker / Input" from the tree view, and add the files @file{libavformat.a},
+ at file{libavcodec.a}, @file{libavutil.a}, @file{libmingwex.a},
+ at file{libgcc.a}, and any other libraries you used (i.e. @file{libz.a})
+to the end of "Additional Dependencies".
+
+ at item Now, select "C/C++ / Code Generation" from the tree view. Select
+"Debug" in the "Configuration" combo box. Make sure that "Runtime
+Library" is set to "Multi-threaded Debug DLL". Then, select "Release" in
+the "Configuration" combo box and make sure that "Runtime Library" is
+set to "Multi-threaded DLL".
+
+ at item Click "OK" to close the "Project / Properties" dialog box.
+
+ at item MSVC++ lacks some C99 header files that are fundamental for Libav.
+Get msinttypes from @url{http://code.google.com/p/msinttypes/downloads/list}
+and install it in MSVC++'s include directory
+(i.e. @file{C:\Program Files\Microsoft Visual Studio 8\VC\include}).
+
+ at item MSVC++ also does not understand the @code{inline} keyword used by
+Libav, so you must add this line before @code{#include}ing libav*:
+ at example
+#define inline _inline
+ at end example
+
+ at item Build your application, everything should work.
+
+ at end enumerate
+
+ at subsection Using shared libraries
+
+This is how to create DLL and LIB files that are compatible with MSVC++:
+
+Within the MSYS shell, build Libav with
+
+ at example
+./configure --enable-shared
+make
+make install
+ at end example
+
+Your install path (@file{/usr/local/} by default) should now have the
+necessary DLL and LIB files under the @file{bin} directory.
+
+Alternatively, build the libraries with a cross compiler, according to
+the instructions below in @ref{Cross compilation for Windows with Linux}.
+
+To use those files with MSVC++, do the same as you would do with
+the static libraries, as described above. But in Step 4,
+you should only need to add the directory where the LIB files are installed
+(i.e. @file{c:\msys\usr\local\bin}). This is not a typo, the LIB files are
+installed in the @file{bin} directory. And instead of adding the static
+libraries (@file{libxxx.a} files) you should add the MSVC import libraries
+(@file{avcodec.lib}, @file{avformat.lib}, and
+ at file{avutil.lib}). Note that you should not use the GCC import
+libraries (@file{libxxx.dll.a} files), as these will give you undefined
+reference errors. There should be no need for @file{libmingwex.a},
+ at file{libgcc.a}, and @file{wsock32.lib}, nor any other external library
+statically linked into the DLLs.
+
+Libav headers do not declare global data for Windows DLLs through the usual
+dllexport/dllimport interface. Such data will be exported properly while
+building, but to use them in your MSVC++ code you will have to edit the
+appropriate headers and mark the data as dllimport. For example, in
+libavutil/pixdesc.h you should have:
+ at example
+extern __declspec(dllimport) const AVPixFmtDescriptor av_pix_fmt_descriptors[];
+ at end example
+
+Note that using import libraries created by dlltool requires
+the linker optimization option to be set to
+"References: Keep Unreferenced Data (@code{/OPT:NOREF})", otherwise
+the resulting binaries will fail during runtime. This isn't
+required when using import libraries generated by lib.exe.
+This issue is reported upstream at
+ at url{http://sourceware.org/bugzilla/show_bug.cgi?id=12633}.
+
+To create import libraries that work with the @code{/OPT:REF} option
+(which is enabled by default in Release mode), follow these steps:
+
+ at enumerate
+
+ at item Open @file{Visual Studio 2005 Command Prompt}.
+
+Alternatively, in a normal command line prompt, call @file{vcvars32.bat}
+which sets up the environment variables for the Visual C++ tools
+(the standard location for this file is
+ at file{C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat}).
+
+ at item Enter the @file{bin} directory where the created LIB and DLL files
+are stored.
+
+ at item Generate new import libraries with @file{lib.exe}:
+
+ at example
+lib /machine:i386 /def:..\lib\avcodec-53.def /out:avcodec.lib
+lib /machine:i386 /def:..\lib\avdevice-53.def /out:avdevice.lib
+lib /machine:i386 /def:..\lib\avfilter-2.def /out:avfilter.lib
+lib /machine:i386 /def:..\lib\avformat-53.def /out:avformat.lib
+lib /machine:i386 /def:..\lib\avutil-51.def /out:avutil.lib
+lib /machine:i386 /def:..\lib\swscale-2.def /out:swscale.lib
+ at end example
+
+ at end enumerate
+
+ at anchor{Cross compilation for Windows with Linux}
+ at section Cross compilation for Windows with Linux
+
+You must use the MinGW cross compilation tools available at
+ at url{http://www.mingw.org/}.
+
+Then configure Libav with the following options:
+ at example
+./configure --target-os=mingw32 --cross-prefix=i386-mingw32msvc-
+ at end example
+(you can change the cross-prefix according to the prefix chosen for the
+MinGW tools).
+
+Then you can easily test Libav with @uref{http://www.winehq.com/, Wine}.
+
+ at section Compilation under Cygwin
+
+Please use Cygwin 1.7.x as the obsolete 1.5.x Cygwin versions lack
+llrint() in its C library.
+
+Install your Cygwin with all the "Base" packages, plus the
+following "Devel" ones:
+ at example
+binutils, gcc4-core, make, git, mingw-runtime, texi2html
+ at end example
+
+And the following "Utils" one:
+ at example
+diffutils
+ at end example
+
+Then run
+
+ at example
+./configure
+ at end example
+
+to make a static build.
+
+The current @code{gcc4-core} package is buggy and needs this flag to build
+shared libraries:
+
+ at example
+./configure --enable-shared --disable-static --extra-cflags=-fno-reorder-functions
+ at end example
+
+If you want to build Libav with additional libraries, download Cygwin
+"Devel" packages for Ogg and Vorbis from any Cygwin packages repository:
+ at example
+libogg-devel, libvorbis-devel
+ at end example
+
+These library packages are only available from
+ at uref{http://sourceware.org/cygwinports/, Cygwin Ports}:
+
+ at example
+yasm, libSDL-devel, libdirac-devel, libfaac-devel, libgsm-devel,
+libmp3lame-devel, libschroedinger1.0-devel, speex-devel, libtheora-devel,
+libxvidcore-devel
+ at end example
+
+The recommendation for libnut and x264 is to build them from source by
+yourself, as they evolve too quickly for Cygwin Ports to be up to date.
+
+Cygwin 1.7.x has IPv6 support. You can add IPv6 to Cygwin 1.5.x by means
+of the @code{libgetaddrinfo-devel} package, available at Cygwin Ports.
+
+ at section Crosscompilation for Windows under Cygwin
+
+With Cygwin you can create Windows binaries that do not need the cygwin1.dll.
+
+Just install your Cygwin as explained before, plus these additional
+"Devel" packages:
+ at example
+gcc-mingw-core, mingw-runtime, mingw-zlib
+ at end example
+
+and add some special flags to your configure invocation.
+
+For a static build run
+ at example
+./configure --target-os=mingw32 --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin
+ at end example
+
+and for a build with shared libraries
+ at example
+./configure --target-os=mingw32 --enable-shared --disable-static --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin
+ at end example
+
+ at bye
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 18749ef..f5bb532 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -52,10 +52,10 @@ resource to be concatenated, each one possibly specifying a distinct
protocol.
For example to read a sequence of files @file{split1.mpeg},
- at file{split2.mpeg}, @file{split3.mpeg} with @file{ffplay} use the
+ at file{split2.mpeg}, @file{split3.mpeg} with @file{avplay} use the
command:
@example
-ffplay concat:split1.mpeg\|split2.mpeg\|split3.mpeg
+avplay concat:split1.mpeg\|split2.mpeg\|split3.mpeg
@end example
Note that you may need to escape the character "|" which is special for
@@ -67,10 +67,10 @@ File access protocol.
Allow to read from or read to a file.
-For example to read from a file @file{input.mpeg} with @file{ffmpeg}
+For example to read from a file @file{input.mpeg} with @command{avconv}
use the command:
@example
-ffmpeg -i file:input.mpeg output.mpeg
+avconv -i file:input.mpeg output.mpeg
@end example
The ff* tools default to the file protocol, that is a resource
@@ -109,10 +109,10 @@ be used to test muxers without writing an actual file.
Some examples follow.
@example
# Write the MD5 hash of the encoded AVI file to the file output.avi.md5.
-ffmpeg -i input.flv -f avi -y md5:output.avi.md5
+avconv -i input.flv -f avi -y md5:output.avi.md5
# Write the MD5 hash of the encoded AVI file to stdout.
-ffmpeg -i input.flv -f avi -y md5:
+avconv -i input.flv -f avi -y md5:
@end example
Note that some formats (typically MOV) require the output protocol to
@@ -134,18 +134,18 @@ pipe (e.g. 0 for stdin, 1 for stdout, 2 for stderr). If @var{number}
is not specified, by default the stdout file descriptor will be used
for writing, stdin for reading.
-For example to read from stdin with @file{ffmpeg}:
+For example to read from stdin with @command{avconv}:
@example
-cat test.wav | ffmpeg -i pipe:0
+cat test.wav | avconv -i pipe:0
# ...this is the same as...
-cat test.wav | ffmpeg -i pipe:
+cat test.wav | avconv -i pipe:
@end example
-For writing to stdout with @file{ffmpeg}:
+For writing to stdout with @command{avconv}:
@example
-ffmpeg -i test.wav -f avi pipe:1 | cat > test.avi
+avconv -i test.wav -f avi pipe:1 | cat > test.avi
# ...this is the same as...
-ffmpeg -i test.wav -f avi pipe: | cat > test.avi
+avconv -i test.wav -f avi pipe: | cat > test.avi
@end example
Note that some formats (typically MOV), require the output protocol to
@@ -155,8 +155,8 @@ be seekable, so they will fail with the pipe output protocol.
Real-Time Messaging Protocol.
-The Real-Time Messaging Protocol (RTMP) is used for streaming multime‐
-dia content across a TCP/IP network.
+The Real-Time Messaging Protocol (RTMP) is used for streaming multimedia
+content across a TCP/IP network.
The required syntax is:
@example
@@ -183,10 +183,10 @@ application specified in @var{app}, may be prefixed by "mp4:".
@end table
-For example to read with @file{ffplay} a multimedia resource named
+For example to read with @file{avplay} a multimedia resource named
"sample" from the application "vod" from an RTMP server "myserver":
@example
-ffplay rtmp://myserver/vod/sample
+avplay rtmp://myserver/vod/sample
@end example
@section rtmp, rtmpe, rtmps, rtmpt, rtmpte
@@ -195,7 +195,7 @@ Real-Time Messaging Protocol and its variants supported through
librtmp.
Requires the presence of the librtmp headers and library during
-configuration. You need to explicitely configure the build with
+configuration. You need to explicitly configure the build with
"--enable-librtmp". If enabled this will replace the native RTMP
protocol.
@@ -219,14 +219,14 @@ meaning as specified for the RTMP native protocol.
See the librtmp manual page (man 3 librtmp) for more information.
For example, to stream a file in real-time to an RTMP server using
- at file{ffmpeg}:
+ at command{avconv}:
@example
-ffmpeg -re -i myfile -f flv rtmp://myserver/live/mystream
+avconv -re -i myfile -f flv rtmp://myserver/live/mystream
@end example
-To play the same stream using @file{ffplay}:
+To play the same stream using @file{avplay}:
@example
-ffplay "rtmp://myserver/live/mystream live=1"
+avplay "rtmp://myserver/live/mystream live=1"
@end example
@section rtp
@@ -242,16 +242,19 @@ data transferred over RDT).
The muxer can be used to send a stream using RTSP ANNOUNCE to a server
supporting it (currently Darwin Streaming Server and Mischa Spiegelmock's
-RTSP server, @url{http://github.com/revmischa/rtsp-server}).
+ at uref{http://github.com/revmischa/rtsp-server, RTSP server}).
The required syntax for a RTSP url is:
@example
-rtsp://@var{hostname}[:@var{port}]/@var{path}[?@var{options}]
+rtsp://@var{hostname}[:@var{port}]/@var{path}
@end example
- at var{options} is a @code{&}-separated list. The following options
+The following options (set on the @command{avconv}/@file{avplay} command
+line, or set in code via @code{AVOption}s or in @code{avformat_open_input}),
are supported:
+Flags for @code{rtsp_transport}:
+
@table @option
@item udp
@@ -261,27 +264,31 @@ Use UDP as lower transport protocol.
Use TCP (interleaving within the RTSP control channel) as lower
transport protocol.
- at item multicast
+ at item udp_multicast
Use UDP multicast as lower transport protocol.
@item http
Use HTTP tunneling as lower transport protocol, which is useful for
passing proxies.
-
- at item filter_src
-Accept packets only from negotiated peer address and port.
@end table
Multiple lower transport protocols may be specified, in that case they are
tried one at a time (if the setup of one fails, the next one is tried).
For the muxer, only the @code{tcp} and @code{udp} options are supported.
+Flags for @code{rtsp_flags}:
+
+ at table @option
+ at item filter_src
+Accept packets only from negotiated peer address and port.
+ at end table
+
When receiving data over UDP, the demuxer tries to reorder received packets
(since they may arrive out of order, or packets may get lost totally). In
order for this to be enabled, a maximum delay must be specified in the
@code{max_delay} field of AVFormatContext.
-When watching multi-bitrate Real-RTSP streams with @file{ffplay}, the
+When watching multi-bitrate Real-RTSP streams with @file{avplay}, the
streams to display can be chosen with @code{-vst} @var{n} and
@code{-ast} @var{n} for video and audio respectively, and can be switched
on the fly by pressing @code{v} and @code{a}.
@@ -291,19 +298,19 @@ Example command lines:
To watch a stream over UDP, with a max reordering delay of 0.5 seconds:
@example
-ffplay -max_delay 500000 rtsp://server/video.mp4?udp
+avplay -max_delay 500000 -rtsp_transport udp rtsp://server/video.mp4
@end example
To watch a stream tunneled over HTTP:
@example
-ffplay rtsp://server/video.mp4?http
+avplay -rtsp_transport http rtsp://server/video.mp4
@end example
To send a stream in realtime to a RTSP server, for others to watch:
@example
-ffmpeg -re -i @var{input} -f rtsp -muxdelay 0.1 rtsp://server/live.sdp
+avconv -re -i @var{input} -f rtsp -muxdelay 0.1 rtsp://server/live.sdp
@end example
@section sap
@@ -355,19 +362,19 @@ Example command lines follow.
To broadcast a stream on the local subnet, for watching in VLC:
@example
-ffmpeg -re -i @var{input} -f sap sap://224.0.0.255?same_port=1
+avconv -re -i @var{input} -f sap sap://224.0.0.255?same_port=1
@end example
-Similarly, for watching in ffplay:
+Similarly, for watching in avplay:
@example
-ffmpeg -re -i @var{input} -f sap sap://224.0.0.255
+avconv -re -i @var{input} -f sap sap://224.0.0.255
@end example
-And for watching in ffplay, over IPv6:
+And for watching in avplay, over IPv6:
@example
-ffmpeg -re -i @var{input} -f sap sap://[ff0e::1:2:3:4]
+avconv -re -i @var{input} -f sap sap://[ff0e::1:2:3:4]
@end example
@subsection Demuxer
@@ -389,13 +396,13 @@ Example command lines follow.
To play back the first stream announced on the normal SAP multicast address:
@example
-ffplay sap://
+avplay sap://
@end example
To play back the first stream announced on one the default IPv6 SAP multicast address:
@example
-ffplay sap://[ff0e::2:7ffe]
+avplay sap://[ff0e::2:7ffe]
@end example
@section tcp
@@ -413,8 +420,8 @@ tcp://@var{hostname}:@var{port}[?@var{options}]
Listen for an incoming connection
@example
-ffmpeg -i @var{input} -f @var{format} tcp://@var{hostname}:@var{port}?listen
-ffplay tcp://@var{hostname}:@var{port}
+avconv -i @var{input} -f @var{format} tcp://@var{hostname}:@var{port}?listen
+avplay tcp://@var{hostname}:@var{port}
@end example
@end table
@@ -439,6 +446,11 @@ set the UDP buffer size in bytes
@item localport=@var{port}
override the local UDP port to bind with
+ at item localaddr=@var{addr}
+Choose the local IP address. This is useful e.g. if sending multicast
+and the host has multiple interfaces, where the user can choose
+which interface to send on by specifying the IP address of that interface.
+
@item pkt_size=@var{size}
set the size in bytes of UDP packets
@@ -460,21 +472,21 @@ For receiving, this gives the benefit of only receiving packets from
the specified peer address/port.
@end table
-Some usage examples of the udp protocol with @file{ffmpeg} follow.
+Some usage examples of the udp protocol with @command{avconv} follow.
To stream over UDP to a remote endpoint:
@example
-ffmpeg -i @var{input} -f @var{format} udp://@var{hostname}:@var{port}
+avconv -i @var{input} -f @var{format} udp://@var{hostname}:@var{port}
@end example
To stream in mpegts format over UDP using 188 sized UDP packets, using a large input buffer:
@example
-ffmpeg -i @var{input} -f mpegts udp://@var{hostname}:@var{port}?pkt_size=188&buffer_size=65535
+avconv -i @var{input} -f mpegts udp://@var{hostname}:@var{port}?pkt_size=188&buffer_size=65535
@end example
To receive over UDP from a remote endpoint:
@example
-ffmpeg -i udp://[@var{multicast-address}]:@var{port}
+avconv -i udp://[@var{multicast-address}]:@var{port}
@end example
@c man end PROTOCOLS
diff --git a/doc/soc.txt b/doc/soc.txt
index e45bd6c..89728b5 100644
--- a/doc/soc.txt
+++ b/doc/soc.txt
@@ -18,7 +18,7 @@ essential that changes to their codebase are publicly visible, clean and
easy reviewable that again leads us to:
* use of a revision control system like git
* separation of cosmetic from non-cosmetic changes (this is almost entirely
- ignored by mentors and students in soc 2006 which might lead to a suprise
+ ignored by mentors and students in soc 2006 which might lead to a surprise
when the code will be reviewed at the end before a possible inclusion in
Libav, individual changes were generally not reviewable due to cosmetics).
* frequent commits, so that comments can be provided early
diff --git a/doc/t2h.init b/doc/t2h.init
index cd38a3e..d91d7b6 100644
--- a/doc/t2h.init
+++ b/doc/t2h.init
@@ -1,15 +1,161 @@
# no horiz rules between sections
-$end_section = \&FFMPEG_end_section;
-sub FFMPEG_end_section($$)
+$end_section = \&Libav_end_section;
+sub Libav_end_section($$)
{
}
-$print_page_foot = \&FFMPEG_print_page_foot;
-sub FFMPEG_print_page_foot($$)
+$EXTRA_HEAD =
+'<link rel="icon" href="favicon.png" type="image/png" />
+<link rel="stylesheet" type="text/css" href="default.css" />
+';
+
+$CSS_LINES = <<EOT;
+<style type="text/css">
+<!--
+a.summary-letter { text-decoration: none }
+a { color: #2D6198; }
+a:visited { color: #884488; }
+h1 a, h2 a, h3 a { text-decoration: inherit; color: inherit; }
+p { margin-left: 1em; margin-right: 1em; }
+table { margin-left: 2em; }
+pre { margin-left: 2em; }
+#footer { text-align: center; }
+#body { margin-left: 1em; margin-right: 1em; }
+body { background-color: #313131; margin: 0; }
+
+#container {
+ background-color: white;
+ color: #202020;
+ margin-left: 1em;
+ margin-right: 1em;
+}
+
+h1 {
+ background-color: #7BB37B;
+ border: 1px solid #6A996A;
+ color: #151515;
+ font-size: 1.2em;
+ padding-bottom: 0.2em;
+ padding-left: 0.4em;
+ padding-top: 0.2em;
+}
+
+h2 {
+ color: #313131;
+ font-size: 1.2em;
+}
+
+h3 {
+ color: #313131;
+ font-size: 0.8em;
+ margin-bottom: -8px;
+}
+
+.note {
+ margin: 1em;
+ border: 1px solid #bbc9d8;
+ background-color: #dde1e1;
+}
+
+.important {
+ margin: 1em;
+ border: 1px solid #d26767;
+ background-color: #f8e1e1;
+}
+
+-->
+</style>
+EOT
+
+my $LIBAV_NAVBAR = $ENV{"LIBAV_NAVBAR"} || '';
+
+$AFTER_BODY_OPEN =
+'<div id="container">' .
+"\n$LIBAV_NAVBAR\n" .
+'<div id="body">';
+
+$PRE_BODY_CLOSE = '</div></div>';
+
+$SMALL_RULE = '';
+$BODYTEXT = '';
+
+$print_page_foot = \&Libav_print_page_foot;
+sub Libav_print_page_foot($$)
{
my $fh = shift;
- print $fh "$SMALL_RULE\n";
+ print $fh '<div id="footer">' . "\n";
T2H_DEFAULT_print_page_foot($fh);
+ print $fh "</div>\n";
+}
+
+$float = \&Libav_float;
+
+sub Libav_float($$$$)
+{
+ my $text = shift;
+ my $float = shift;
+ my $caption = shift;
+ my $shortcaption = shift;
+
+ my $label = '';
+ if (exists($float->{'id'}))
+ {
+ $label = &$anchor($float->{'id'});
+ }
+ my $class = '';
+ my $subject = '';
+
+ if ($caption =~ /NOTE/)
+ {
+ $class = "note";
+ }
+ elsif ($caption =~ /IMPORTANT/)
+ {
+ $class = "important";
+ }
+
+ return '<div class="float ' . $class . '">' . "$label\n" . $text . '</div>';
+}
+
+$print_page_head = \&Libav_print_page_head;
+sub Libav_print_page_head($$)
+{
+ my $fh = shift;
+ my $longtitle = "$Texi2HTML::THISDOC{'title_no_texi'}";
+ $longtitle .= ": $Texi2HTML::NO_TEXI{'This'}" if exists $Texi2HTML::NO_TEXI{'This'};
+ my $description = $DOCUMENT_DESCRIPTION;
+ $description = $longtitle if (!defined($description));
+ $description = "<meta name=\"description\" content=\"$description\">" if
+ ($description ne '');
+ $description = $Texi2HTML::THISDOC{'documentdescription'} if (defined($Texi2HTML::THISDOC{'documentdescription'}));
+ my $encoding = '';
+ $encoding = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=$ENCODING\">" if (defined($ENCODING) and ($ENCODING ne ''));
+ $longtitle =~ s/Documentation.*//g;
+ $longtitle = "Libav documentation : " . $longtitle;
+
+ print $fh <<EOT;
+$DOCTYPE
+<html>
+$Texi2HTML::THISDOC{'copying'}<!-- Created on $Texi2HTML::THISDOC{today} by $Texi2HTML::THISDOC{program} -->
+<!--
+$Texi2HTML::THISDOC{program_authors}
+-->
+<head>
+<title>$longtitle</title>
+
+$description
+<meta name="keywords" content="$longtitle">
+<meta name="resource-type" content="document">
+<meta name="distribution" content="global">
+<meta name="Generator" content="$Texi2HTML::THISDOC{program}">
+$encoding
+$CSS_LINES
+$EXTRA_HEAD
+</head>
+
+<body $BODYTEXT>
+$AFTER_BODY_OPEN
+EOT
}
# no navigation elements
diff --git a/doc/texi2pod.pl b/doc/texi2pod.pl
index 84c36ff..0eb5e8d 100755
--- a/doc/texi2pod.pl
+++ b/doc/texi2pod.pl
@@ -352,6 +352,7 @@ sub postprocess
s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g;
s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;
s/;\s+\@pxref\{(?:[^\}]*)\}//g;
+ s/\@ref\{([^\}]*)\}/$1/g;
s/\@noindent\s*//g;
s/\@refill//g;
s/\@gol//g;
diff --git a/ffmpeg.c b/ffmpeg.c
index 76d1cf3..0ec3b24 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -40,6 +40,7 @@
#include "libavutil/fifo.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avstring.h"
#include "libavutil/libm.h"
@@ -77,56 +78,50 @@ const char program_name[] = "ffmpeg";
const int program_birth_year = 2000;
/* select an input stream for an output stream */
-typedef struct AVStreamMap {
+typedef struct StreamMap {
int file_index;
int stream_index;
int sync_file_index;
int sync_stream_index;
-} AVStreamMap;
+} StreamMap;
/**
* select an input file for an output file
*/
-typedef struct AVMetaDataMap {
- int file; //< file index
- char type; //< type of metadata to copy -- (g)lobal, (s)tream, (c)hapter or (p)rogram
- int index; //< stream/chapter/program number
-} AVMetaDataMap;
+typedef struct MetadataMap {
+ int file; ///< file index
+ char type; ///< type of metadata to copy -- (g)lobal, (s)tream, (c)hapter or (p)rogram
+ int index; ///< stream/chapter/program number
+} MetadataMap;
-typedef struct AVChapterMap {
+typedef struct ChapterMap {
int in_file;
int out_file;
-} AVChapterMap;
+} ChapterMap;
static const OptionDef options[];
#define MAX_FILES 100
-#define MAX_STREAMS 1024 /* arbitrary sanity check value */
-
-#define FFM_PACKET_SIZE 4096 //XXX a duplicate of the line in ffm.h
static const char *last_asked_format = NULL;
-static int64_t input_files_ts_offset[MAX_FILES];
-static double *input_files_ts_scale[MAX_FILES] = {NULL};
-static AVCodec **input_codecs = NULL;
-static int nb_input_codecs = 0;
-static int nb_input_files_ts_scale[MAX_FILES] = {0};
+static double *ts_scale;
+static int nb_ts_scale;
static AVFormatContext *output_files[MAX_FILES];
static AVDictionary *output_opts[MAX_FILES];
static int nb_output_files = 0;
-static AVStreamMap *stream_maps = NULL;
+static StreamMap *stream_maps = NULL;
static int nb_stream_maps;
/* first item specifies output metadata, second is input */
-static AVMetaDataMap (*meta_data_maps)[2] = NULL;
+static MetadataMap (*meta_data_maps)[2] = NULL;
static int nb_meta_data_maps;
static int metadata_global_autocopy = 1;
static int metadata_streams_autocopy = 1;
static int metadata_chapters_autocopy = 1;
-static AVChapterMap *chapter_maps = NULL;
+static ChapterMap *chapter_maps = NULL;
static int nb_chapter_maps;
/* indexed by output file stream index */
@@ -163,7 +158,6 @@ static char *vfilters = NULL;
static int intra_only = 0;
static int audio_sample_rate = 0;
-static int64_t channel_layout = 0;
#define QSCALE_NONE -99999
static float audio_qscale = QSCALE_NONE;
static int audio_disable = 0;
@@ -186,7 +180,6 @@ static float mux_max_delay= 0.7;
static int64_t recording_time = INT64_MAX;
static int64_t start_time = 0;
-static int64_t recording_timestamp = 0;
static int64_t input_ts_offset = 0;
static int file_overwrite = 0;
static AVDictionary *metadata;
@@ -245,19 +238,19 @@ static AVBitStreamFilterContext *subtitle_bitstream_filters=NULL;
#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
-struct AVInputStream;
+struct InputStream;
-typedef struct AVOutputStream {
+typedef struct OutputStream {
int file_index; /* file index */
int index; /* stream index in the output file */
- int source_index; /* AVInputStream index */
+ int source_index; /* InputStream index */
AVStream *st; /* stream in the output file */
int encoding_needed; /* true if encoding needed for this stream */
int frame_number;
/* input pts and corresponding output pts
for A/V sync */
//double sync_ipts; /* dts from the AVPacket of the demuxer in second units */
- struct AVInputStream *sync_ist; /* input stream to sync against */
+ struct InputStream *sync_ist; /* input stream to sync against */
int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ //FIXME look at frame_number
AVBitStreamFilterContext *bitstream_filters;
AVCodec *enc;
@@ -298,48 +291,48 @@ typedef struct AVOutputStream {
#endif
int sws_flags;
-} AVOutputStream;
+ AVDictionary *opts;
+} OutputStream;
-static AVOutputStream **output_streams_for_file[MAX_FILES] = { NULL };
+static OutputStream **output_streams_for_file[MAX_FILES] = { NULL };
static int nb_output_streams_for_file[MAX_FILES] = { 0 };
-typedef struct AVInputStream {
+typedef struct InputStream {
int file_index;
AVStream *st;
int discard; /* true if stream data should be discarded */
int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
- int64_t sample_index; /* current sample */
+ AVCodec *dec;
int64_t start; /* time when read started */
int64_t next_pts; /* synthetic pts for cases where pkt.pts
is not defined */
int64_t pts; /* current pts */
PtsCorrectionContext pts_ctx;
+ double ts_scale;
int is_start; /* is 1 at the start and after a discontinuity */
int showed_multi_packet_warning;
int is_past_recording_time;
-#if CONFIG_AVFILTER
- AVFrame *filter_frame;
- int has_filter_frame;
-#endif
-} AVInputStream;
+ AVDictionary *opts;
+} InputStream;
-typedef struct AVInputFile {
+typedef struct InputFile {
AVFormatContext *ctx;
int eof_reached; /* true if eof reached */
int ist_index; /* index of first stream in ist_table */
int buffer_size; /* current total buffer size */
+ int64_t ts_offset;
int nb_streams; /* nb streams we are aware of */
-} AVInputFile;
+} InputFile;
-static AVInputStream *input_streams = NULL;
+static InputStream *input_streams = NULL;
static int nb_input_streams = 0;
-static AVInputFile *input_files = NULL;
+static InputFile *input_files = NULL;
static int nb_input_files = 0;
#if CONFIG_AVFILTER
-static int configure_video_filters(AVInputStream *ist, AVOutputStream *ost)
+static int configure_video_filters(InputStream *ist, OutputStream *ost)
{
AVFilterContext *last_filter, *filter;
/** filter graph containing all filters including input & output */
@@ -453,7 +446,7 @@ static int decode_interrupt_cb(void)
return received_nb_signals > 1;
}
-static int ffmpeg_exit(int ret)
+void exit_program(int ret)
{
int i;
@@ -468,8 +461,9 @@ static int ffmpeg_exit(int ret)
}
for(i=0;i<nb_input_files;i++) {
av_close_input_file(input_files[i].ctx);
- av_free(input_files_ts_scale[i]);
}
+ for (i = 0; i < nb_input_streams; i++)
+ av_dict_free(&input_streams[i].opts);
av_free(intra_matrix);
av_free(inter_matrix);
@@ -479,7 +473,6 @@ static int ffmpeg_exit(int ret)
av_free(vstats_filename);
av_free(streamid_map);
- av_free(input_codecs);
av_free(stream_maps);
av_free(meta_data_maps);
@@ -500,6 +493,7 @@ static int ffmpeg_exit(int ret)
#if CONFIG_AVFILTER
avfilter_uninit();
#endif
+ avformat_network_deinit();
if (received_sigterm) {
fprintf(stderr,
@@ -509,7 +503,6 @@ static int ffmpeg_exit(int ret)
}
exit(ret); /* not all OS-es handle main() return value */
- return ret;
}
static void assert_avoptions(AVDictionary *m)
@@ -517,28 +510,25 @@ static void assert_avoptions(AVDictionary *m)
AVDictionaryEntry *t;
if ((t = av_dict_get(m, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
- ffmpeg_exit(1);
+ exit_program(1);
}
}
-/* similar to ff_dynarray_add() and av_fast_realloc() */
-static void *grow_array(void *array, int elem_size, int *size, int new_size)
+static void assert_codec_experimental(AVCodecContext *c, int encoder)
{
- if (new_size >= INT_MAX / elem_size) {
- fprintf(stderr, "Array too big.\n");
- ffmpeg_exit(1);
- }
- if (*size < new_size) {
- uint8_t *tmp = av_realloc(array, new_size*elem_size);
- if (!tmp) {
- fprintf(stderr, "Could not alloc buffer.\n");
- ffmpeg_exit(1);
- }
- memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
- *size = new_size;
- return tmp;
+ const char *codec_string = encoder ? "encoder" : "decoder";
+ AVCodec *codec;
+ if (c->codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
+ c->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+ av_log(NULL, AV_LOG_ERROR, "%s '%s' is experimental and might produce bad "
+ "results.\nAdd '-strict experimental' if you want to use it.\n",
+ codec_string, c->codec->name);
+ codec = encoder ? avcodec_find_encoder(c->codec->id) : avcodec_find_decoder(c->codec->id);
+ if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
+ av_log(NULL, AV_LOG_ERROR, "Or use the non experimental %s '%s'.\n",
+ codec_string, codec->name);
+ exit_program(1);
}
- return array;
}
static void choose_sample_fmt(AVStream *st, AVCodec *codec)
@@ -647,10 +637,16 @@ static void choose_pixel_fmt(AVStream *st, AVCodec *codec)
}
}
-static AVOutputStream *new_output_stream(AVFormatContext *oc, int file_idx)
+static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx, AVCodec *codec)
{
- int idx = oc->nb_streams - 1;
- AVOutputStream *ost;
+ OutputStream *ost;
+ AVStream *st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
+ int idx = oc->nb_streams - 1;
+
+ if (!st) {
+ av_log(NULL, AV_LOG_ERROR, "Could not alloc stream.\n");
+ exit_program(1);
+ }
output_streams_for_file[file_idx] =
grow_array(output_streams_for_file[file_idx],
@@ -658,49 +654,47 @@ static AVOutputStream *new_output_stream(AVFormatContext *oc, int file_idx)
&nb_output_streams_for_file[file_idx],
oc->nb_streams);
ost = output_streams_for_file[file_idx][idx] =
- av_mallocz(sizeof(AVOutputStream));
+ av_mallocz(sizeof(OutputStream));
if (!ost) {
fprintf(stderr, "Could not alloc output stream\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
ost->file_index = file_idx;
ost->index = idx;
+ ost->st = st;
+ ost->enc = codec;
+ if (codec)
+ ost->opts = filter_codec_opts(codec_opts, codec->id, oc, st);
+
+ avcodec_get_context_defaults3(st->codec, codec);
ost->sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
return ost;
}
-static int read_ffserver_streams(AVFormatContext *s, const char *filename)
+static int read_avserver_streams(AVFormatContext *s, const char *filename)
{
int i, err;
AVFormatContext *ic = NULL;
- int nopts = 0;
err = avformat_open_input(&ic, filename, NULL, NULL);
if (err < 0)
return err;
/* copy stream format */
- s->nb_streams = 0;
- s->streams = av_mallocz(sizeof(AVStream *) * ic->nb_streams);
for(i=0;i<ic->nb_streams;i++) {
AVStream *st;
+ OutputStream *ost;
AVCodec *codec;
- s->nb_streams++;
+ codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
+ ost = new_output_stream(s, nb_output_files, codec);
+ st = ost->st;
// FIXME: a more elegant solution is needed
- st = av_mallocz(sizeof(AVStream));
memcpy(st, ic->streams[i], sizeof(AVStream));
st->info = NULL;
- st->codec = avcodec_alloc_context();
- if (!st->codec) {
- print_error(filename, AVERROR(ENOMEM));
- ffmpeg_exit(1);
- }
avcodec_copy_context(st->codec, ic->streams[i]->codec);
- s->streams[i] = st;
- codec = avcodec_find_encoder(st->codec->codec_id);
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
if (audio_stream_copy) {
st->stream_copy = 1;
@@ -712,24 +706,16 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename)
} else
choose_pixel_fmt(st, codec);
}
-
- if(st->codec->flags & CODEC_FLAG_BITEXACT)
- nopts = 1;
-
- new_output_stream(s, nb_output_files);
}
- if (!nopts)
- s->timestamp = av_gettime();
-
av_close_input_file(ic);
return 0;
}
static double
-get_sync_ipts(const AVOutputStream *ost)
+get_sync_ipts(const OutputStream *ost)
{
- const AVInputStream *ist = ost->sync_ist;
+ const InputStream *ist = ost->sync_ist;
return (double)(ist->pts - start_time)/AV_TIME_BASE;
}
@@ -751,7 +737,7 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx
avctx->codec ? avctx->codec->name : "copy");
print_error("", a);
if (exit_on_error)
- ffmpeg_exit(1);
+ exit_program(1);
}
*pkt= new_pkt;
@@ -761,15 +747,15 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx
ret= av_interleaved_write_frame(s, pkt);
if(ret < 0){
print_error("av_interleaved_write_frame()", ret);
- ffmpeg_exit(1);
+ exit_program(1);
}
}
#define MAX_AUDIO_PACKET_SIZE (128 * 1024)
static void do_audio_out(AVFormatContext *s,
- AVOutputStream *ost,
- AVInputStream *ist,
+ OutputStream *ost,
+ InputStream *ist,
unsigned char *buf, int size)
{
uint8_t *buftmp;
@@ -779,8 +765,8 @@ static void do_audio_out(AVFormatContext *s,
int size_out, frame_bytes, ret, resample_changed;
AVCodecContext *enc= ost->st->codec;
AVCodecContext *dec= ist->st->codec;
- int osize= av_get_bits_per_sample_fmt(enc->sample_fmt)/8;
- int isize= av_get_bits_per_sample_fmt(dec->sample_fmt)/8;
+ int osize = av_get_bytes_per_sample(enc->sample_fmt);
+ int isize = av_get_bytes_per_sample(dec->sample_fmt);
const int coded_bps = av_get_bits_per_sample(enc->codec->id);
need_realloc:
@@ -797,14 +783,14 @@ need_realloc:
if(audio_out_size > INT_MAX || audio_buf_size > INT_MAX){
fprintf(stderr, "Buffer sizes too large\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size);
av_fast_malloc(&audio_out, &allocated_audio_out_size, audio_out_size);
if (!audio_buf || !audio_out){
fprintf(stderr, "Out of memory in do_audio_out\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
if (enc->channels != dec->channels || enc->sample_rate != dec->sample_rate)
@@ -844,7 +830,7 @@ need_realloc:
fprintf(stderr, "Can not resample %d channels @ %d Hz to %d channels @ %d Hz\n",
dec->channels, dec->sample_rate,
enc->channels, enc->sample_rate);
- ffmpeg_exit(1);
+ exit_program(1);
}
}
}
@@ -860,7 +846,7 @@ need_realloc:
fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
av_get_sample_fmt_name(dec->sample_fmt),
av_get_sample_fmt_name(enc->sample_fmt));
- ffmpeg_exit(1);
+ exit_program(1);
}
ost->reformat_pair=MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt);
}
@@ -933,7 +919,7 @@ need_realloc:
if (av_audio_convert(ost->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
printf("av_audio_convert() failed\n");
if (exit_on_error)
- ffmpeg_exit(1);
+ exit_program(1);
return;
}
buftmp = audio_buf;
@@ -945,7 +931,7 @@ need_realloc:
/* output resampled raw samples */
if (av_fifo_realloc2(ost->fifo, av_fifo_size(ost->fifo) + size_out) < 0) {
fprintf(stderr, "av_fifo_realloc2() failed\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
av_fifo_generic_write(ost->fifo, buftmp, size_out, NULL);
@@ -963,7 +949,7 @@ need_realloc:
(short *)audio_buf);
if (ret < 0) {
fprintf(stderr, "Audio encoding failed\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
audio_size += ret;
pkt.stream_index= ost->index;
@@ -990,7 +976,7 @@ need_realloc:
if(size_out > audio_out_size){
fprintf(stderr, "Internal error, buffer size too small\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
//FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
@@ -998,7 +984,7 @@ need_realloc:
(short *)buftmp);
if (ret < 0) {
fprintf(stderr, "Audio encoding failed\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
audio_size += ret;
pkt.stream_index= ost->index;
@@ -1011,7 +997,7 @@ need_realloc:
}
}
-static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void **bufp)
+static void pre_process_video_frame(InputStream *ist, AVPicture *picture, void **bufp)
{
AVCodecContext *dec;
AVPicture *picture2;
@@ -1054,8 +1040,8 @@ static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void
#define AV_DELAY_MAX 0.100
static void do_subtitle_out(AVFormatContext *s,
- AVOutputStream *ost,
- AVInputStream *ist,
+ OutputStream *ost,
+ InputStream *ist,
AVSubtitle *sub,
int64_t pts)
{
@@ -1068,7 +1054,7 @@ static void do_subtitle_out(AVFormatContext *s,
if (pts == AV_NOPTS_VALUE) {
fprintf(stderr, "Subtitle packets must have a pts\n");
if (exit_on_error)
- ffmpeg_exit(1);
+ exit_program(1);
return;
}
@@ -1096,7 +1082,7 @@ static void do_subtitle_out(AVFormatContext *s,
subtitle_out_max_size, sub);
if (subtitle_out_size < 0) {
fprintf(stderr, "Subtitle encoding failed\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
av_init_packet(&pkt);
@@ -1120,10 +1106,10 @@ static int bit_buffer_size= 1024*256;
static uint8_t *bit_buffer= NULL;
static void do_video_out(AVFormatContext *s,
- AVOutputStream *ost,
- AVInputStream *ist,
+ OutputStream *ost,
+ InputStream *ist,
AVFrame *in_picture,
- int *frame_size)
+ int *frame_size, float quality)
{
int nb_frames, i, ret, resample_changed;
AVFrame *final_picture, *formatted_picture;
@@ -1183,7 +1169,7 @@ static void do_video_out(AVFormatContext *s,
ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt),
dec->width , dec->height , av_get_pix_fmt_name(dec->pix_fmt));
if(!ost->video_resample)
- ffmpeg_exit(1);
+ exit_program(1);
}
#if !CONFIG_AVFILTER
@@ -1202,7 +1188,7 @@ static void do_video_out(AVFormatContext *s,
ost->sws_flags, NULL, NULL, NULL);
if (ost->img_resample_ctx == NULL) {
fprintf(stderr, "Cannot get resampling context\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
}
sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize,
@@ -1245,7 +1231,7 @@ static void do_video_out(AVFormatContext *s,
/* handles sameq here. This is not correct because it may
not be a global option */
- big_picture.quality = same_quality ? ist->st->quality : ost->st->quality;
+ big_picture.quality = quality;
if(!me_threshold)
big_picture.pict_type = 0;
// big_picture.pts = AV_NOPTS_VALUE;
@@ -1262,7 +1248,7 @@ static void do_video_out(AVFormatContext *s,
&big_picture);
if (ret < 0) {
fprintf(stderr, "Video encoding failed\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
if(ret>0){
@@ -1296,7 +1282,7 @@ static double psnr(double d){
return -10.0*log(d)/log(10.0);
}
-static void do_video_stats(AVFormatContext *os, AVOutputStream *ost,
+static void do_video_stats(AVFormatContext *os, OutputStream *ost,
int frame_size)
{
AVCodecContext *enc;
@@ -1308,7 +1294,7 @@ static void do_video_stats(AVFormatContext *os, AVOutputStream *ost,
vstats_file = fopen(vstats_filename, "w");
if (!vstats_file) {
perror("fopen");
- ffmpeg_exit(1);
+ exit_program(1);
}
}
@@ -1334,11 +1320,11 @@ static void do_video_stats(AVFormatContext *os, AVOutputStream *ost,
}
static void print_report(AVFormatContext **output_files,
- AVOutputStream **ost_table, int nb_ostreams,
+ OutputStream **ost_table, int nb_ostreams,
int is_last_report)
{
char buf[1024];
- AVOutputStream *ost;
+ OutputStream *ost;
AVFormatContext *oc;
int64_t total_size;
AVCodecContext *enc;
@@ -1464,12 +1450,12 @@ static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_
}
/* pkt = NULL means EOF (needed to flush decoder buffers) */
-static int output_packet(AVInputStream *ist, int ist_index,
- AVOutputStream **ost_table, int nb_ostreams,
+static int output_packet(InputStream *ist, int ist_index,
+ OutputStream **ost_table, int nb_ostreams,
const AVPacket *pkt)
{
AVFormatContext *os;
- AVOutputStream *ost;
+ OutputStream *ost;
int ret, i;
int got_output;
AVFrame picture;
@@ -1480,9 +1466,10 @@ static int output_packet(AVInputStream *ist, int ist_index,
#if CONFIG_AVFILTER
int frame_available;
#endif
+ float quality;
AVPacket avpkt;
- int bps = av_get_bits_per_sample_fmt(ist->st->codec->sample_fmt)>>3;
+ int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt);
if(ist->next_pts == AV_NOPTS_VALUE)
ist->next_pts= ist->pts;
@@ -1535,7 +1522,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
ret = avcodec_decode_audio3(ist->st->codec, samples, &decoded_data_size,
&avpkt);
if (ret < 0)
- goto fail_decode;
+ return ret;
avpkt.data += ret;
avpkt.size -= ret;
data_size = ret;
@@ -1560,9 +1547,9 @@ static int output_packet(AVInputStream *ist, int ist_index,
ret = avcodec_decode_video2(ist->st->codec,
&picture, &got_output, &avpkt);
- ist->st->quality= picture.quality;
+ quality = same_quality ? picture.quality : 0;
if (ret < 0)
- goto fail_decode;
+ return ret;
if (!got_output) {
/* no picture yet */
goto discard_packet;
@@ -1582,7 +1569,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
ret = avcodec_decode_subtitle2(ist->st->codec,
&subtitle, &got_output, &avpkt);
if (ret < 0)
- goto fail_decode;
+ return ret;
if (!got_output) {
goto discard_packet;
}
@@ -1590,7 +1577,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
avpkt.size = 0;
break;
default:
- goto fail_decode;
+ return -1;
}
} else {
switch(ist->st->codec->codec_type) {
@@ -1672,7 +1659,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
os = output_files[ost->file_index];
/* set the input output pts pairs */
- //ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/ AV_TIME_BASE;
+ //ost->sync_ipts = (double)(ist->pts + input_files[ist->file_index].ts_offset - start_time)/ AV_TIME_BASE;
if (ost->encoding_needed) {
av_assert0(ist->decoding_needed);
@@ -1685,7 +1672,8 @@ static int output_packet(AVInputStream *ist, int ist_index,
if (ost->picref->video && !ost->frame_aspect_ratio)
ost->st->codec->sample_aspect_ratio = ost->picref->video->pixel_aspect;
#endif
- do_video_out(os, ost, ist, &picture, &frame_size);
+ do_video_out(os, ost, ist, &picture, &frame_size,
+ same_quality ? quality : ost->st->codec->global_quality);
if (vstats_filename && frame_size)
do_video_stats(os, ost, frame_size);
break;
@@ -1811,7 +1799,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
} else { /* pad */
int frame_bytes = enc->frame_size*osize*enc->channels;
if (allocated_audio_buf_size < frame_bytes)
- ffmpeg_exit(1);
+ exit_program(1);
generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes);
}
@@ -1825,7 +1813,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
}
if (ret < 0) {
fprintf(stderr, "Audio encoding failed\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
audio_size += ret;
pkt.flags |= AV_PKT_FLAG_KEY;
@@ -1834,7 +1822,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL);
if (ret < 0) {
fprintf(stderr, "Video encoding failed\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
video_size += ret;
if(enc->coded_frame && enc->coded_frame->key_frame)
@@ -1861,8 +1849,6 @@ static int output_packet(AVInputStream *ist, int ist_index,
}
return 0;
- fail_decode:
- return -1;
}
static void print_sdp(AVFormatContext **avc, int n)
@@ -1882,7 +1868,7 @@ static int copy_chapters(int infile, int outfile)
for (i = 0; i < is->nb_chapters; i++) {
AVChapter *in_ch = is->chapters[i], *out_ch;
- int64_t ts_off = av_rescale_q(start_time - input_files_ts_offset[infile],
+ int64_t ts_off = av_rescale_q(start_time - input_files[infile].ts_offset,
AV_TIME_BASE_Q, in_ch->time_base);
int64_t rt = (recording_time == INT64_MAX) ? INT64_MAX :
av_rescale_q(recording_time, AV_TIME_BASE_Q, in_ch->time_base);
@@ -1914,7 +1900,7 @@ static int copy_chapters(int infile, int outfile)
return 0;
}
-static void parse_forced_key_frames(char *kf, AVOutputStream *ost,
+static void parse_forced_key_frames(char *kf, OutputStream *ost,
AVCodecContext *avctx)
{
char *p;
@@ -1928,7 +1914,7 @@ static void parse_forced_key_frames(char *kf, AVOutputStream *ost,
ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n);
if (!ost->forced_kf_pts) {
av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
for (i = 0; i < n; i++) {
p = i ? strchr(p, ',') + 1 : kf;
@@ -1942,15 +1928,15 @@ static void parse_forced_key_frames(char *kf, AVOutputStream *ost,
*/
static int transcode(AVFormatContext **output_files,
int nb_output_files,
- AVInputFile *input_files,
+ InputFile *input_files,
int nb_input_files,
- AVStreamMap *stream_maps, int nb_stream_maps)
+ StreamMap *stream_maps, int nb_stream_maps)
{
int ret = 0, i, j, k, n, nb_ostreams = 0;
AVFormatContext *is, *os;
AVCodecContext *codec, *icodec;
- AVOutputStream *ost, **ost_table = NULL;
- AVInputStream *ist;
+ OutputStream *ost, **ost_table = NULL;
+ InputStream *ist;
char error[1024];
int want_sdp = 1;
uint8_t no_packet[MAX_FILES]={0};
@@ -1999,7 +1985,7 @@ static int transcode(AVFormatContext **output_files,
}
}
- ost_table = av_mallocz(sizeof(AVOutputStream *) * nb_ostreams);
+ ost_table = av_mallocz(sizeof(OutputStream *) * nb_ostreams);
if (!ost_table)
goto fail;
n = 0;
@@ -2008,7 +1994,6 @@ static int transcode(AVFormatContext **output_files,
for(i=0;i<os->nb_streams;i++,n++) {
int found;
ost = ost_table[n] = output_streams_for_file[k][i];
- ost->st = os->streams[i];
if (nb_stream_maps > 0) {
ost->source_index = input_files[stream_maps[n].file_index].ist_index +
stream_maps[n].stream_index;
@@ -2020,7 +2005,7 @@ static int transcode(AVFormatContext **output_files,
fprintf(stderr, "Codec type mismatch for mapping #%d.%d -> #%d.%d\n",
stream_maps[n].file_index, stream_maps[n].stream_index,
ost->file_index, ost->index);
- ffmpeg_exit(1);
+ exit_program(1);
}
} else {
@@ -2070,7 +2055,7 @@ static int transcode(AVFormatContext **output_files,
av_dump_format(output_files[i], i, output_files[i]->filename, 1);
fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n",
ost->file_index, ost->index);
- ffmpeg_exit(1);
+ exit_program(1);
}
}
}
@@ -2135,7 +2120,7 @@ static int transcode(AVFormatContext **output_files,
case AVMEDIA_TYPE_AUDIO:
if(audio_volume != 256) {
fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
codec->channel_layout = icodec->channel_layout;
codec->sample_rate = icodec->sample_rate;
@@ -2186,8 +2171,12 @@ static int transcode(AVFormatContext **output_files,
}
choose_sample_rate(ost->st, ost->enc);
codec->time_base = (AVRational){1, codec->sample_rate};
+ if (codec->sample_fmt == AV_SAMPLE_FMT_NONE)
+ codec->sample_fmt = icodec->sample_fmt;
+ choose_sample_fmt(ost->st, ost->enc);
if (!codec->channels)
codec->channels = icodec->channels;
+ codec->channel_layout = icodec->channel_layout;
if (av_get_channel_layout_nb_channels(codec->channel_layout) != codec->channels)
codec->channel_layout = 0;
ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;
@@ -2205,7 +2194,7 @@ static int transcode(AVFormatContext **output_files,
if (ost->st->codec->pix_fmt == PIX_FMT_NONE) {
fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
if (!codec->width || !codec->height) {
@@ -2220,21 +2209,21 @@ static int transcode(AVFormatContext **output_files,
#if !CONFIG_AVFILTER
avcodec_get_frame_defaults(&ost->pict_tmp);
if(avpicture_alloc((AVPicture*)&ost->pict_tmp, codec->pix_fmt,
- codec->width, codec->height)) {
+ codec->width, codec->height)) {
fprintf(stderr, "Cannot allocate temp picture, check pix fmt\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
ost->img_resample_ctx = sws_getContext(
icodec->width,
icodec->height,
- icodec->pix_fmt,
- codec->width,
- codec->height,
- codec->pix_fmt,
- ost->sws_flags, NULL, NULL, NULL);
+ icodec->pix_fmt,
+ codec->width,
+ codec->height,
+ codec->pix_fmt,
+ ost->sws_flags, NULL, NULL, NULL);
if (ost->img_resample_ctx == NULL) {
fprintf(stderr, "Cannot get resampling context\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
#endif
codec->bits_per_raw_sample= 0;
@@ -2282,15 +2271,15 @@ static int transcode(AVFormatContext **output_files,
f = fopen(logfilename, "wb");
if (!f) {
fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno));
- ffmpeg_exit(1);
+ exit_program(1);
}
ost->logfile = f;
} else {
char *logbuffer;
size_t logbuffer_size;
- if (read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
+ if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
fprintf(stderr, "Error reading log file '%s' for pass-2 encoding\n", logfilename);
- ffmpeg_exit(1);
+ exit_program(1);
}
codec->stats_in = logbuffer;
}
@@ -2332,12 +2321,17 @@ static int transcode(AVFormatContext **output_files,
memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
ost->st->codec->subtitle_header_size = dec->subtitle_header_size;
}
- if (avcodec_open(ost->st->codec, codec) < 0) {
+ if (avcodec_open2(ost->st->codec, codec, &ost->opts) < 0) {
snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height",
ost->file_index, ost->index);
ret = AVERROR(EINVAL);
goto dump_format;
}
+ assert_codec_experimental(ost->st->codec, 1);
+ assert_avoptions(ost->opts);
+ if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000)
+ av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
+ "It takes bits/s as argument, not kbits/s\n");
extra_size += ost->st->codec->extradata_size;
}
}
@@ -2346,7 +2340,7 @@ static int transcode(AVFormatContext **output_files,
for (i = 0; i < nb_input_streams; i++) {
ist = &input_streams[i];
if (ist->decoding_needed) {
- AVCodec *codec = i < nb_input_codecs ? input_codecs[i] : NULL;
+ AVCodec *codec = ist->dec;
if (!codec)
codec = avcodec_find_decoder(ist->st->codec->codec_id);
if (!codec) {
@@ -2366,14 +2360,14 @@ static int transcode(AVFormatContext **output_files,
}
}
- if (avcodec_open(ist->st->codec, codec) < 0) {
+ if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) {
snprintf(error, sizeof(error), "Error while opening decoder for input stream #%d.%d",
ist->file_index, ist->st->index);
ret = AVERROR(EINVAL);
goto dump_format;
}
- //if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
- // ist->st->codec->flags |= CODEC_FLAG_REPEAT_FIELD;
+ assert_codec_experimental(ist->st->codec, 0);
+ assert_avoptions(ost->opts);
}
}
@@ -2413,7 +2407,7 @@ static int transcode(AVFormatContext **output_files,
files[1] = input_files[in_file_index].ctx;
for (j = 0; j < 2; j++) {
- AVMetaDataMap *map = &meta_data_maps[i][j];
+ MetadataMap *map = &meta_data_maps[i][j];
switch (map->type) {
case 'g':
@@ -2616,27 +2610,27 @@ static int transcode(AVFormatContext **output_files,
goto discard_packet;
if (pkt.dts != AV_NOPTS_VALUE)
- pkt.dts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base);
+ pkt.dts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
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);
+ pkt.pts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
- if (pkt.stream_index < nb_input_files_ts_scale[file_index]
- && input_files_ts_scale[file_index][pkt.stream_index]){
+ if (ist->ts_scale) {
if(pkt.pts != AV_NOPTS_VALUE)
- pkt.pts *= input_files_ts_scale[file_index][pkt.stream_index];
+ pkt.pts *= ist->ts_scale;
if(pkt.dts != AV_NOPTS_VALUE)
- pkt.dts *= input_files_ts_scale[file_index][pkt.stream_index];
+ pkt.dts *= ist->ts_scale;
}
-// 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);
+// fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files[ist->file_index].ts_offset, ist->st->codec->codec_type);
if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE
&& (is->iformat->flags & AVFMT_TS_DISCONT)) {
int64_t pkt_dts= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
int64_t delta= pkt_dts - ist->next_pts;
if((FFABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE || pkt_dts+1<ist->pts)&& !copy_ts){
- input_files_ts_offset[ist->file_index]-= delta;
+ input_files[ist->file_index].ts_offset -= delta;
if (verbose > 2)
- fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", delta, input_files_ts_offset[ist->file_index]);
+ fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
+ delta, input_files[ist->file_index].ts_offset);
pkt.dts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
if(pkt.pts != AV_NOPTS_VALUE)
pkt.pts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
@@ -2657,7 +2651,7 @@ static int transcode(AVFormatContext **output_files,
fprintf(stderr, "Error while decoding stream #%d.%d\n",
ist->file_index, ist->st->index);
if (exit_on_error)
- ffmpeg_exit(1);
+ exit_program(1);
av_free_packet(&pkt);
goto redo;
}
@@ -2735,6 +2729,7 @@ static int transcode(AVFormatContext **output_files,
audio_resample_close(ost->resample);
if (ost->reformat_ctx)
av_audio_convert_free(ost->reformat_ctx);
+ av_dict_free(&ost->opts);
av_free(ost);
}
}
@@ -2771,23 +2766,11 @@ static int opt_frame_rate(const char *opt, const char *arg)
{
if (av_parse_video_rate(&frame_rate, arg) < 0) {
fprintf(stderr, "Incorrect value for %s: %s\n", opt, arg);
- ffmpeg_exit(1);
+ exit_program(1);
}
return 0;
}
-static int opt_bitrate(const char *opt, const char *arg)
-{
- int codec_type = opt[0]=='a' ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO;
-
- opt_default(opt, arg);
-
- if (av_get_int(avcodec_opts[codec_type], "b", NULL) < 1000)
- fprintf(stderr, "WARNING: The bitrate parameter is set too low. It takes bits/s as argument, not kbits/s\n");
-
- return 0;
-}
-
static int opt_frame_crop(const char *opt, const char *arg)
{
fprintf(stderr, "Option '%s' has been removed, use the crop filter instead\n", opt);
@@ -2818,7 +2801,7 @@ static int opt_frame_pix_fmt(const char *opt, const char *arg)
}
} else {
show_pix_fmts();
- ffmpeg_exit(0);
+ exit_program(0);
}
return 0;
}
@@ -2854,7 +2837,7 @@ static int opt_metadata(const char *opt, const char *arg)
if(!mid){
fprintf(stderr, "Missing =\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
*mid++= 0;
@@ -2902,7 +2885,7 @@ static int opt_audio_sample_fmt(const char *opt, const char *arg)
char fmt_str[128];
for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
- ffmpeg_exit(0);
+ exit_program(0);
}
return 0;
}
@@ -2985,7 +2968,7 @@ static int opt_codec_tag(const char *opt, const char *arg)
static int opt_map(const char *opt, const char *arg)
{
- AVStreamMap *m;
+ StreamMap *m;
char *p;
stream_maps = grow_array(stream_maps, sizeof(*stream_maps), &nb_stream_maps, nb_stream_maps + 1);
@@ -3024,7 +3007,7 @@ static void parse_meta_type(char *arg, char *type, int *index, char **endptr)
break;
default:
fprintf(stderr, "Invalid metadata type %c.\n", *arg);
- ffmpeg_exit(1);
+ exit_program(1);
}
} else
*type = 'g';
@@ -3032,7 +3015,7 @@ static void parse_meta_type(char *arg, char *type, int *index, char **endptr)
static int opt_map_metadata(const char *opt, const char *arg)
{
- AVMetaDataMap *m, *m1;
+ MetadataMap *m, *m1;
char *p;
meta_data_maps = grow_array(meta_data_maps, sizeof(*meta_data_maps),
@@ -3067,7 +3050,7 @@ static int opt_map_meta_data(const char *opt, const char *arg)
static int opt_map_chapters(const char *opt, const char *arg)
{
- AVChapterMap *c;
+ ChapterMap *c;
char *p;
chapter_maps = grow_array(chapter_maps, sizeof(*chapter_maps), &nb_chapter_maps,
@@ -3092,11 +3075,8 @@ static int opt_input_ts_scale(const char *opt, const char *arg)
p++;
scale= strtod(p, &p);
- if(stream >= MAX_STREAMS)
- ffmpeg_exit(1);
-
- input_files_ts_scale[nb_input_files] = grow_array(input_files_ts_scale[nb_input_files], sizeof(*input_files_ts_scale[nb_input_files]), &nb_input_files_ts_scale[nb_input_files], stream + 1);
- input_files_ts_scale[nb_input_files][stream]= scale;
+ ts_scale = grow_array(ts_scale, sizeof(*ts_scale), &nb_ts_scale, stream + 1);
+ ts_scale[stream] = scale;
return 0;
}
@@ -3114,7 +3094,14 @@ static int opt_start_time(const char *opt, const char *arg)
static int opt_recording_timestamp(const char *opt, const char *arg)
{
- recording_timestamp = parse_time_or_die(opt, arg, 0) / 1000000;
+ char buf[128];
+ int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6;
+ struct tm time = *gmtime((time_t*)&recording_timestamp);
+ strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time);
+ opt_metadata("metadata", buf);
+
+ av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata "
+ "tag instead.\n", opt);
return 0;
}
@@ -3124,7 +3111,7 @@ static int opt_input_ts_offset(const char *opt, const char *arg)
return 0;
}
-static enum CodecID find_codec_or_die(const char *name, int type, int encoder, int strict)
+static enum CodecID find_codec_or_die(const char *name, int type, int encoder)
{
const char *codec_string = encoder ? "encoder" : "decoder";
AVCodec *codec;
@@ -3136,24 +3123,11 @@ static enum CodecID find_codec_or_die(const char *name, int type, int encoder, i
avcodec_find_decoder_by_name(name);
if(!codec) {
fprintf(stderr, "Unknown %s '%s'\n", codec_string, name);
- ffmpeg_exit(1);
+ exit_program(1);
}
if(codec->type != type) {
fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name);
- ffmpeg_exit(1);
- }
- if(codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
- strict > FF_COMPLIANCE_EXPERIMENTAL) {
- fprintf(stderr, "%s '%s' is experimental and might produce bad "
- "results.\nAdd '-strict experimental' if you want to use it.\n",
- codec_string, codec->name);
- codec = encoder ?
- avcodec_find_encoder(codec->id) :
- avcodec_find_decoder(codec->id);
- if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
- fprintf(stderr, "Or use the non experimental %s '%s'.\n",
- codec_string, codec->name);
- ffmpeg_exit(1);
+ exit_program(1);
}
return codec->id;
}
@@ -3165,11 +3139,13 @@ static int opt_input_file(const char *opt, const char *filename)
int err, i, ret, rfps, rfps_base;
int64_t timestamp;
uint8_t buf[128];
+ AVDictionary **opts;
+ int orig_nb_streams; // number of streams before avformat_find_stream_info
if (last_asked_format) {
if (!(file_iformat = av_find_input_format(last_asked_format))) {
fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format);
- ffmpeg_exit(1);
+ exit_program(1);
}
last_asked_format = NULL;
}
@@ -3184,7 +3160,7 @@ static int opt_input_file(const char *opt, const char *filename)
ic = avformat_alloc_context();
if (!ic) {
print_error(filename, AVERROR(ENOMEM));
- ffmpeg_exit(1);
+ exit_program(1);
}
if (audio_sample_rate) {
snprintf(buf, sizeof(buf), "%d", audio_sample_rate);
@@ -3206,21 +3182,18 @@ static int opt_input_file(const char *opt, const char *filename)
av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(frame_pix_fmt), 0);
ic->video_codec_id =
- find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0,
- avcodec_opts[AVMEDIA_TYPE_VIDEO ]->strict_std_compliance);
+ find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0);
ic->audio_codec_id =
- find_codec_or_die(audio_codec_name , AVMEDIA_TYPE_AUDIO , 0,
- avcodec_opts[AVMEDIA_TYPE_AUDIO ]->strict_std_compliance);
+ find_codec_or_die(audio_codec_name , AVMEDIA_TYPE_AUDIO , 0);
ic->subtitle_codec_id=
- find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0,
- avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
+ find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0);
ic->flags |= AVFMT_FLAG_NONBLOCK;
/* open the input file with generic libav function */
err = avformat_open_input(&ic, filename, file_iformat, &format_opts);
if (err < 0) {
print_error(filename, err);
- ffmpeg_exit(1);
+ exit_program(1);
}
assert_avoptions(format_opts);
@@ -3243,37 +3216,27 @@ static int opt_input_file(const char *opt, const char *filename)
}
if(!found){
fprintf(stderr, "Specified program id not found\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
opt_programid=0;
}
- ic->loop_input = loop_input;
-
- /* Set AVCodecContext options so they will be seen by av_find_stream_info() */
- for (i = 0; i < ic->nb_streams; i++) {
- AVCodecContext *dec = ic->streams[i]->codec;
- switch (dec->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO],
- AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM,
- NULL);
- break;
- case AVMEDIA_TYPE_VIDEO:
- set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO],
- AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM,
- NULL);
- break;
- }
+ if (loop_input) {
+ av_log(NULL, AV_LOG_WARNING, "-loop_input is deprecated, use -loop 1\n");
+ ic->loop_input = loop_input;
}
+ /* Set AVCodecContext options for avformat_find_stream_info */
+ opts = setup_find_stream_info_opts(ic, codec_opts);
+ orig_nb_streams = ic->nb_streams;
+
/* If not enough info to get the stream parameters, we decode the
first frames to get it. (used in mpeg case for example) */
- ret = av_find_stream_info(ic);
+ ret = avformat_find_stream_info(ic, opts);
if (ret < 0 && verbose >= 0) {
fprintf(stderr, "%s: could not find codec parameters\n", filename);
av_close_input_file(ic);
- ffmpeg_exit(1);
+ exit_program(1);
}
timestamp = start_time;
@@ -3296,29 +3259,28 @@ static int opt_input_file(const char *opt, const char *filename)
for(i=0;i<ic->nb_streams;i++) {
AVStream *st = ic->streams[i];
AVCodecContext *dec = st->codec;
- AVInputStream *ist;
+ InputStream *ist;
dec->thread_count = thread_count;
- input_codecs = grow_array(input_codecs, sizeof(*input_codecs), &nb_input_codecs, nb_input_codecs + 1);
input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1);
ist = &input_streams[nb_input_streams - 1];
ist->st = st;
ist->file_index = nb_input_files;
ist->discard = 1;
+ ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st);
+
+ if (i < nb_ts_scale)
+ ist->ts_scale = ts_scale[i];
switch (dec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(audio_codec_name);
- set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]);
- channel_layout = dec->channel_layout;
- audio_sample_fmt = dec->sample_fmt;
+ ist->dec = avcodec_find_decoder_by_name(audio_codec_name);
if(audio_disable)
st->discard= AVDISCARD_ALL;
break;
case AVMEDIA_TYPE_VIDEO:
- input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(video_codec_name);
- set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]);
+ ist->dec = avcodec_find_decoder_by_name(video_codec_name);
rfps = ic->streams[i]->r_frame_rate.num;
rfps_base = ic->streams[i]->r_frame_rate.den;
if (dec->lowres) {
@@ -3346,7 +3308,7 @@ static int opt_input_file(const char *opt, const char *filename)
case AVMEDIA_TYPE_DATA:
break;
case AVMEDIA_TYPE_SUBTITLE:
- input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(subtitle_codec_name);
+ ist->dec = avcodec_find_decoder_by_name(subtitle_codec_name);
if(subtitle_disable)
st->discard = AVDISCARD_ALL;
break;
@@ -3358,7 +3320,6 @@ static int opt_input_file(const char *opt, const char *filename)
}
}
- input_files_ts_offset[nb_input_files] = input_ts_offset - (copy_ts ? 0 : timestamp);
/* dump the file content */
if (verbose >= 0)
av_dump_format(ic, nb_input_files, filename, 0);
@@ -3366,6 +3327,7 @@ static int opt_input_file(const char *opt, const char *filename)
input_files = grow_array(input_files, sizeof(*input_files), &nb_input_files, nb_input_files + 1);
input_files[nb_input_files - 1].ctx = ic;
input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams;
+ input_files[nb_input_files - 1].ts_offset = input_ts_offset - (copy_ts ? 0 : timestamp);
input_files[nb_input_files - 1].nb_streams = ic->nb_streams;
frame_rate = (AVRational){0, 0};
@@ -3374,7 +3336,13 @@ static int opt_input_file(const char *opt, const char *filename)
frame_width = 0;
audio_sample_rate = 0;
audio_channels = 0;
+ audio_sample_fmt = AV_SAMPLE_FMT_NONE;
+ av_freep(&ts_scale);
+ nb_ts_scale = 0;
+ for (i = 0; i < orig_nb_streams; i++)
+ av_dict_free(&opts[i]);
+ av_freep(&opts);
av_freep(&video_codec_name);
av_freep(&audio_codec_name);
av_freep(&subtitle_codec_name);
@@ -3429,29 +3397,24 @@ static void check_inputs(int *has_video_ptr,
static void new_video_stream(AVFormatContext *oc, int file_idx)
{
AVStream *st;
- AVOutputStream *ost;
+ OutputStream *ost;
AVCodecContext *video_enc;
enum CodecID codec_id = CODEC_ID_NONE;
AVCodec *codec= NULL;
- st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
- if (!st) {
- fprintf(stderr, "Could not alloc stream\n");
- ffmpeg_exit(1);
- }
- ost = new_output_stream(oc, file_idx);
-
if(!video_stream_copy){
if (video_codec_name) {
- codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1,
- avcodec_opts[AVMEDIA_TYPE_VIDEO]->strict_std_compliance);
+ codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1);
codec = avcodec_find_encoder_by_name(video_codec_name);
- ost->enc = codec;
} else {
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
codec = avcodec_find_encoder(codec_id);
}
+ }
+ ost = new_output_stream(oc, file_idx, codec);
+ st = ost->st;
+ if (!video_stream_copy) {
ost->frame_aspect_ratio = frame_aspect_ratio;
frame_aspect_ratio = 0;
#if CONFIG_AVFILTER
@@ -3460,7 +3423,6 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
#endif
}
- avcodec_get_context_defaults3(st->codec, codec);
ost->bitstream_filters = video_bitstream_filters;
video_bitstream_filters= NULL;
@@ -3473,12 +3435,11 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
if(oc->oformat->flags & AVFMT_GLOBALHEADER) {
video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
- avcodec_opts[AVMEDIA_TYPE_VIDEO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
}
+ video_enc->codec_type = AVMEDIA_TYPE_VIDEO;
if (video_stream_copy) {
st->stream_copy = 1;
- video_enc->codec_type = AVMEDIA_TYPE_VIDEO;
video_enc->sample_aspect_ratio =
st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
} else {
@@ -3488,7 +3449,6 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
if (frame_rate.num)
ost->frame_rate = frame_rate;
video_enc->codec_id = codec_id;
- set_context_opts(video_enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
video_enc->width = frame_width;
video_enc->height = frame_height;
@@ -3499,8 +3459,7 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
video_enc->gop_size = 0;
if (video_qscale || same_quality) {
video_enc->flags |= CODEC_FLAG_QSCALE;
- video_enc->global_quality=
- st->quality = FF_QP2LAMBDA * video_qscale;
+ video_enc->global_quality = FF_QP2LAMBDA * video_qscale;
}
if(intra_matrix)
@@ -3514,7 +3473,7 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
int e=sscanf(p, "%d,%d,%d", &start, &end, &q);
if(e!=3){
fprintf(stderr, "error parsing rc_override\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
video_enc->rc_override=
av_realloc(video_enc->rc_override,
@@ -3569,31 +3528,22 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
static void new_audio_stream(AVFormatContext *oc, int file_idx)
{
AVStream *st;
- AVOutputStream *ost;
+ OutputStream *ost;
AVCodec *codec= NULL;
AVCodecContext *audio_enc;
enum CodecID codec_id = CODEC_ID_NONE;
- st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
- if (!st) {
- fprintf(stderr, "Could not alloc stream\n");
- ffmpeg_exit(1);
- }
- ost = new_output_stream(oc, file_idx);
-
if(!audio_stream_copy){
if (audio_codec_name) {
- codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1,
- avcodec_opts[AVMEDIA_TYPE_AUDIO]->strict_std_compliance);
+ codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1);
codec = avcodec_find_encoder_by_name(audio_codec_name);
- ost->enc = codec;
} else {
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO);
codec = avcodec_find_encoder(codec_id);
}
}
-
- avcodec_get_context_defaults3(st->codec, codec);
+ ost = new_output_stream(oc, file_idx, codec);
+ st = ost->st;
ost->bitstream_filters = audio_bitstream_filters;
audio_bitstream_filters= NULL;
@@ -3608,25 +3558,22 @@ static void new_audio_stream(AVFormatContext *oc, int file_idx)
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
- avcodec_opts[AVMEDIA_TYPE_AUDIO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
}
if (audio_stream_copy) {
st->stream_copy = 1;
} else {
audio_enc->codec_id = codec_id;
- set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
if (audio_qscale > QSCALE_NONE) {
audio_enc->flags |= CODEC_FLAG_QSCALE;
- audio_enc->global_quality = st->quality = FF_QP2LAMBDA * audio_qscale;
+ audio_enc->global_quality = FF_QP2LAMBDA * audio_qscale;
}
if (audio_channels)
audio_enc->channels = audio_channels;
- audio_enc->sample_fmt = audio_sample_fmt;
+ if (audio_sample_fmt != AV_SAMPLE_FMT_NONE)
+ audio_enc->sample_fmt = audio_sample_fmt;
if (audio_sample_rate)
audio_enc->sample_rate = audio_sample_rate;
- audio_enc->channel_layout = channel_layout;
- choose_sample_fmt(st, codec);
}
if (audio_language) {
av_dict_set(&st->metadata, "language", audio_language, 0);
@@ -3642,21 +3589,16 @@ static void new_audio_stream(AVFormatContext *oc, int file_idx)
static void new_data_stream(AVFormatContext *oc, int file_idx)
{
AVStream *st;
- AVCodec *codec=NULL;
+ OutputStream *ost;
AVCodecContext *data_enc;
- st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
- if (!st) {
- fprintf(stderr, "Could not alloc stream\n");
- ffmpeg_exit(1);
- }
- new_output_stream(oc, file_idx);
+ ost = new_output_stream(oc, file_idx, NULL);
+ st = ost->st;
data_enc = st->codec;
if (!data_stream_copy) {
fprintf(stderr, "Data stream encoding not supported yet (only streamcopy)\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
- avcodec_get_context_defaults3(st->codec, codec);
data_enc->codec_type = AVMEDIA_TYPE_DATA;
@@ -3665,7 +3607,6 @@ static void new_data_stream(AVFormatContext *oc, int file_idx)
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
data_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
- avcodec_opts[AVMEDIA_TYPE_DATA]->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
if (data_stream_copy) {
st->stream_copy = 1;
@@ -3679,30 +3620,23 @@ static void new_data_stream(AVFormatContext *oc, int file_idx)
static void new_subtitle_stream(AVFormatContext *oc, int file_idx)
{
AVStream *st;
- AVOutputStream *ost;
+ OutputStream *ost;
AVCodec *codec=NULL;
AVCodecContext *subtitle_enc;
enum CodecID codec_id = CODEC_ID_NONE;
- st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
- if (!st) {
- fprintf(stderr, "Could not alloc stream\n");
- ffmpeg_exit(1);
- }
- ost = new_output_stream(oc, file_idx);
- subtitle_enc = st->codec;
if(!subtitle_stream_copy){
if (subtitle_codec_name) {
- codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,
- avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
+ codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1);
codec = avcodec_find_encoder_by_name(subtitle_codec_name);
- ost->enc = codec;
} else {
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_SUBTITLE);
codec = avcodec_find_encoder(codec_id);
}
}
- avcodec_get_context_defaults3(st->codec, codec);
+ ost = new_output_stream(oc, file_idx, codec);
+ st = ost->st;
+ subtitle_enc = st->codec;
ost->bitstream_filters = subtitle_bitstream_filters;
subtitle_bitstream_filters= NULL;
@@ -3714,13 +3648,11 @@ static void new_subtitle_stream(AVFormatContext *oc, int file_idx)
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
subtitle_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
- avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
if (subtitle_stream_copy) {
st->stream_copy = 1;
} else {
subtitle_enc->codec_id = codec_id;
- set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
}
if (subtitle_language) {
@@ -3739,7 +3671,7 @@ static int opt_new_stream(const char *opt, const char *arg)
int file_idx = nb_output_files - 1;
if (nb_output_files <= 0) {
fprintf(stderr, "At least one output file must be specified\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
oc = output_files[file_idx];
@@ -3764,16 +3696,16 @@ static int opt_streamid(const char *opt, const char *arg)
fprintf(stderr,
"Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
arg, opt);
- ffmpeg_exit(1);
+ exit_program(1);
}
*p++ = '\0';
- idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
+ idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
streamid_map = grow_array(streamid_map, sizeof(*streamid_map), &nb_streamid_map, idx+1);
streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
return 0;
}
-static void opt_output_file(const char *filename)
+static void opt_output_file(void *optctx, const char *filename)
{
AVFormatContext *oc;
int err, use_video, use_audio, use_subtitle, use_data;
@@ -3786,14 +3718,14 @@ static void opt_output_file(const char *filename)
oc = avformat_alloc_context();
if (!oc) {
print_error(filename, AVERROR(ENOMEM));
- ffmpeg_exit(1);
+ exit_program(1);
}
if (last_asked_format) {
file_oformat = av_guess_format(last_asked_format, NULL, NULL);
if (!file_oformat) {
fprintf(stderr, "Requested output format '%s' is not a suitable output format\n", last_asked_format);
- ffmpeg_exit(1);
+ exit_program(1);
}
last_asked_format = NULL;
} else {
@@ -3801,7 +3733,7 @@ static void opt_output_file(const char *filename)
if (!file_oformat) {
fprintf(stderr, "Unable to find a suitable output format for '%s'\n",
filename);
- ffmpeg_exit(1);
+ exit_program(1);
}
}
@@ -3810,12 +3742,12 @@ static void opt_output_file(const char *filename)
if (!strcmp(file_oformat->name, "ffm") &&
av_strstart(filename, "http:", NULL)) {
- /* special case for files sent to ffserver: we get the stream
- parameters from ffserver */
- int err = read_ffserver_streams(oc, filename);
+ /* special case for files sent to avserver: we get the stream
+ parameters from avserver */
+ int err = read_avserver_streams(oc, filename);
if (err < 0) {
print_error(filename, err);
- ffmpeg_exit(1);
+ exit_program(1);
}
} else {
use_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_name;
@@ -3823,23 +3755,20 @@ static void opt_output_file(const char *filename)
use_subtitle = file_oformat->subtitle_codec != CODEC_ID_NONE || subtitle_stream_copy || subtitle_codec_name;
use_data = data_stream_copy || data_codec_name; /* XXX once generic data codec will be available add a ->data_codec reference and use it here */
- /* disable if no corresponding type found and at least one
- input file */
- if (nb_input_files > 0) {
- check_inputs(&input_has_video,
- &input_has_audio,
- &input_has_subtitle,
- &input_has_data);
-
- if (!input_has_video)
- use_video = 0;
- if (!input_has_audio)
- use_audio = 0;
- if (!input_has_subtitle)
- use_subtitle = 0;
- if (!input_has_data)
- use_data = 0;
- }
+ /* disable if no corresponding type found */
+ check_inputs(&input_has_video,
+ &input_has_audio,
+ &input_has_subtitle,
+ &input_has_data);
+
+ if (!input_has_video)
+ use_video = 0;
+ if (!input_has_audio)
+ use_audio = 0;
+ if (!input_has_subtitle)
+ use_subtitle = 0;
+ if (!input_has_data)
+ use_data = 0;
/* manual disable */
if (audio_disable) use_audio = 0;
@@ -3852,8 +3781,6 @@ static void opt_output_file(const char *filename)
if (use_subtitle) new_subtitle_stream(oc, nb_output_files);
if (use_data) new_data_stream(oc, nb_output_files);
- oc->timestamp = recording_timestamp;
-
av_dict_copy(&oc->metadata, metadata, 0);
av_dict_free(&metadata);
}
@@ -3865,12 +3792,12 @@ static void opt_output_file(const char *filename)
if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
if (!av_filename_number_test(oc->filename)) {
print_error(oc->filename, AVERROR(EINVAL));
- ffmpeg_exit(1);
+ exit_program(1);
}
}
if (!(oc->oformat->flags & AVFMT_NOFILE)) {
- /* test if it already exists to avoid loosing precious files */
+ /* test if it already exists to avoid losing precious files */
if (!file_overwrite &&
(strchr(filename, ':') == NULL ||
filename[1] == ':' ||
@@ -3881,12 +3808,12 @@ static void opt_output_file(const char *filename)
fflush(stderr);
if (!read_yesno()) {
fprintf(stderr, "Not overwriting - exiting\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
}
else {
fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
- ffmpeg_exit(1);
+ exit_program(1);
}
}
}
@@ -3894,13 +3821,16 @@ static void opt_output_file(const char *filename)
/* open the file */
if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) {
print_error(filename, err);
- ffmpeg_exit(1);
+ exit_program(1);
}
}
oc->preload= (int)(mux_preload*AV_TIME_BASE);
oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE);
- oc->loop_output = loop_output;
+ if (loop_output >= 0) {
+ av_log(NULL, AV_LOG_WARNING, "-loop_output is deprecated, use -loop\n");
+ oc->loop_output = loop_output;
+ }
oc->flags |= AVFMT_FLAG_NONBLOCK;
frame_rate = (AVRational){0, 0};
@@ -3908,6 +3838,7 @@ static void opt_output_file(const char *filename)
frame_height = 0;
audio_sample_rate = 0;
audio_channels = 0;
+ audio_sample_fmt = AV_SAMPLE_FMT_NONE;
av_freep(&forced_key_frames);
uninit_opts();
@@ -3968,7 +3899,7 @@ static void parse_matrix_coeffs(uint16_t *dest, const char *str)
p = strchr(p, ',');
if(!p) {
fprintf(stderr, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
- ffmpeg_exit(1);
+ exit_program(1);
}
p++;
}
@@ -3998,6 +3929,7 @@ static void show_help(void)
AVCodec *c;
AVOutputFormat *oformat = NULL;
AVInputFormat *iformat = NULL;
+ const AVClass *class;
av_log_set_callback(log_callback_help);
show_usage();
@@ -4025,7 +3957,8 @@ static void show_help(void)
OPT_GRAB,
OPT_GRAB);
printf("\n");
- av_opt_show2(avcodec_opts[0], NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
+ class = avcodec_get_class();
+ av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
printf("\n");
/* individual codec options */
@@ -4037,7 +3970,8 @@ static void show_help(void)
}
}
- av_opt_show2(avformat_opts, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
+ class = avformat_get_class();
+ av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
printf("\n");
/* individual muxer options */
@@ -4056,7 +3990,8 @@ static void show_help(void)
}
}
- av_opt_show2(sws_opts, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
+ class = sws_get_class();
+ av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
}
static int opt_target(const char *opt, const char *arg)
@@ -4112,7 +4047,7 @@ static int opt_target(const char *opt, const char *arg)
fprintf(stderr, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
fprintf(stderr, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
fprintf(stderr, "or set a framerate with \"-r xxx\".\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
if(!strcmp(arg, "vcd")) {
@@ -4229,7 +4164,7 @@ static int opt_bsf(const char *opt, const char *arg)
if(!bsfc){
fprintf(stderr, "Unknown bitstream filter %s\n", arg);
- ffmpeg_exit(1);
+ exit_program(1);
}
bsfp= *opt == 'v' ? &video_bitstream_filters :
@@ -4253,7 +4188,7 @@ static int opt_preset(const char *opt, const char *arg)
if (!(f = get_preset_file(filename, sizeof(filename), arg, *opt == 'f', codec_name))) {
fprintf(stderr, "File for preset '%s' not found\n", arg);
- ffmpeg_exit(1);
+ exit_program(1);
}
while(!feof(f)){
@@ -4263,7 +4198,7 @@ static int opt_preset(const char *opt, const char *arg)
e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
if(e){
fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line);
- ffmpeg_exit(1);
+ exit_program(1);
}
if(!strcmp(tmp, "acodec")){
opt_audio_codec(tmp, tmp2);
@@ -4275,7 +4210,7 @@ static int opt_preset(const char *opt, const char *arg)
opt_data_codec(tmp, tmp2);
}else if(opt_default(tmp, tmp2) < 0){
fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2);
- ffmpeg_exit(1);
+ exit_program(1);
}
}
@@ -4312,8 +4247,8 @@ static const OptionDef options[] = {
{ "hex", OPT_BOOL | OPT_EXPERT, {(void*)&do_hex_dump},
"when dumping packets, also dump the payload" },
{ "re", OPT_BOOL | OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate", "" },
- { "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "loop (current only works with images)" },
- { "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "number of times to loop output in formats that support looping (0 loops forever)", "" },
+ { "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "deprecated, use -loop" },
+ { "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "deprecated, use -loop", "" },
{ "v", HAS_ARG, {(void*)opt_verbose}, "set ffmpeg verbosity level", "number" },
{ "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
{ "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
@@ -4329,8 +4264,6 @@ static const OptionDef options[] = {
{ "copyinkf", OPT_BOOL | OPT_EXPERT, {(void*)©_initial_nonkeyframes}, "copy initial non-keyframes" },
/* video options */
- { "b", HAS_ARG | OPT_VIDEO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" },
- { "vb", HAS_ARG | OPT_VIDEO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" },
{ "vframes", OPT_INT | HAS_ARG | OPT_VIDEO, {(void*)&max_frames[AVMEDIA_TYPE_VIDEO]}, "set the number of video 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" },
@@ -4377,7 +4310,6 @@ static const OptionDef options[] = {
{ "force_key_frames", OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void *)&forced_key_frames}, "force key frames at specified timestamps", "timestamps" },
/* audio options */
- { "ab", HAS_ARG | OPT_AUDIO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" },
{ "aframes", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&max_frames[AVMEDIA_TYPE_AUDIO]}, "set the number of audio frames to record", "number" },
{ "aq", OPT_FLOAT | HAS_ARG | OPT_AUDIO, {(void*)&audio_qscale}, "set audio quality (codec-specific)", "quality", },
{ "ar", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_rate}, "set audio sampling rate (in Hz)", "rate" },
@@ -4426,6 +4358,7 @@ int main(int argc, char **argv)
int64_t ti;
av_log_set_flags(AV_LOG_SKIP_REPEATED);
+ parse_loglevel(argc, argv, options);
avcodec_register_all();
#if CONFIG_AVDEVICE
@@ -4435,6 +4368,7 @@ int main(int argc, char **argv)
avfilter_register_all();
#endif
av_register_all();
+ avformat_network_init();
avio_set_interrupt_cb(decode_interrupt_cb);
@@ -4442,35 +4376,40 @@ int main(int argc, char **argv)
show_banner();
+ av_log(NULL, AV_LOG_WARNING, "This program is not developed anymore and is only "
+ "provided for compatibility. Use avconv instead "
+ "(see Changelog for the list of incompatible changes).\n");
+
/* parse options */
- parse_options(argc, argv, options, opt_output_file);
+ parse_options(NULL, argc, argv, options, opt_output_file);
if(nb_output_files <= 0 && nb_input_files == 0) {
show_usage();
fprintf(stderr, "Use -h to get full help or, even better, run 'man ffmpeg'\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
/* file converter / grab */
if (nb_output_files <= 0) {
fprintf(stderr, "At least one output file must be specified\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
if (nb_input_files == 0) {
fprintf(stderr, "At least one input file must be specified\n");
- ffmpeg_exit(1);
+ exit_program(1);
}
ti = getutime();
if (transcode(output_files, nb_output_files, input_files, nb_input_files,
stream_maps, nb_stream_maps) < 0)
- ffmpeg_exit(1);
+ exit_program(1);
ti = getutime() - ti;
if (do_benchmark) {
int maxrss = getmaxrss() / 1024;
printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss);
}
- return ffmpeg_exit(0);
+ exit_program(0);
+ return 0;
}
diff --git a/ffplay.c b/ffplay.c
deleted file mode 100644
index c9891d3..0000000
--- a/ffplay.c
+++ /dev/null
@@ -1,3085 +0,0 @@
-/*
- * ffplay : Simple Media Player based on the Libav libraries
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include <inttypes.h>
-#include <math.h>
-#include <limits.h>
-#include "libavutil/avstring.h"
-#include "libavutil/colorspace.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/dict.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/samplefmt.h"
-#include "libavformat/avformat.h"
-#include "libavdevice/avdevice.h"
-#include "libswscale/swscale.h"
-#include "libavcodec/audioconvert.h"
-#include "libavutil/opt.h"
-#include "libavcodec/avfft.h"
-
-#if CONFIG_AVFILTER
-# include "libavfilter/avfilter.h"
-# include "libavfilter/avfiltergraph.h"
-#endif
-
-#include "cmdutils.h"
-
-#include <SDL.h>
-#include <SDL_thread.h>
-
-#ifdef __MINGW32__
-#undef main /* We don't want SDL to override our main() */
-#endif
-
-#include <unistd.h>
-#include <assert.h>
-
-const char program_name[] = "ffplay";
-const int program_birth_year = 2003;
-
-#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
-#define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
-#define MIN_FRAMES 5
-
-/* SDL audio buffer size, in samples. Should be small to have precise
- A/V sync as SDL does not have hardware buffer fullness info. */
-#define SDL_AUDIO_BUFFER_SIZE 1024
-
-/* no AV sync correction is done if below the AV sync threshold */
-#define AV_SYNC_THRESHOLD 0.01
-/* no AV correction is done if too big error */
-#define AV_NOSYNC_THRESHOLD 10.0
-
-#define FRAME_SKIP_FACTOR 0.05
-
-/* maximum audio speed change to get correct sync */
-#define SAMPLE_CORRECTION_PERCENT_MAX 10
-
-/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
-#define AUDIO_DIFF_AVG_NB 20
-
-/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
-#define SAMPLE_ARRAY_SIZE (2*65536)
-
-static int sws_flags = SWS_BICUBIC;
-
-typedef struct PacketQueue {
- AVPacketList *first_pkt, *last_pkt;
- int nb_packets;
- int size;
- int abort_request;
- SDL_mutex *mutex;
- SDL_cond *cond;
-} PacketQueue;
-
-#define VIDEO_PICTURE_QUEUE_SIZE 2
-#define SUBPICTURE_QUEUE_SIZE 4
-
-typedef struct VideoPicture {
- double pts; ///<presentation time stamp for this picture
- double target_clock; ///<av_gettime() time at which this should be displayed ideally
- int64_t pos; ///<byte position in file
- SDL_Overlay *bmp;
- int width, height; /* source height & width */
- int allocated;
- enum PixelFormat pix_fmt;
-
-#if CONFIG_AVFILTER
- AVFilterBufferRef *picref;
-#endif
-} VideoPicture;
-
-typedef struct SubPicture {
- double pts; /* presentation time stamp for this picture */
- AVSubtitle sub;
-} SubPicture;
-
-enum {
- AV_SYNC_AUDIO_MASTER, /* default choice */
- AV_SYNC_VIDEO_MASTER,
- AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
-};
-
-typedef struct VideoState {
- SDL_Thread *parse_tid;
- SDL_Thread *video_tid;
- SDL_Thread *refresh_tid;
- AVInputFormat *iformat;
- int no_background;
- int abort_request;
- int paused;
- int last_paused;
- int seek_req;
- int seek_flags;
- int64_t seek_pos;
- int64_t seek_rel;
- int read_pause_return;
- AVFormatContext *ic;
- int dtg_active_format;
-
- int audio_stream;
-
- int av_sync_type;
- double external_clock; /* external clock base */
- int64_t external_clock_time;
-
- double audio_clock;
- double audio_diff_cum; /* used for AV difference average computation */
- double audio_diff_avg_coef;
- double audio_diff_threshold;
- int audio_diff_avg_count;
- AVStream *audio_st;
- PacketQueue audioq;
- int audio_hw_buf_size;
- /* samples output by the codec. we reserve more space for avsync
- compensation */
- DECLARE_ALIGNED(16,uint8_t,audio_buf1)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
- DECLARE_ALIGNED(16,uint8_t,audio_buf2)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
- uint8_t *audio_buf;
- unsigned int audio_buf_size; /* in bytes */
- int audio_buf_index; /* in bytes */
- AVPacket audio_pkt_temp;
- AVPacket audio_pkt;
- enum AVSampleFormat audio_src_fmt;
- AVAudioConvert *reformat_ctx;
-
- int show_audio; /* if true, display audio samples */
- int16_t sample_array[SAMPLE_ARRAY_SIZE];
- int sample_array_index;
- int last_i_start;
- RDFTContext *rdft;
- int rdft_bits;
- FFTSample *rdft_data;
- int xpos;
-
- SDL_Thread *subtitle_tid;
- int subtitle_stream;
- int subtitle_stream_changed;
- AVStream *subtitle_st;
- PacketQueue subtitleq;
- SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
- int subpq_size, subpq_rindex, subpq_windex;
- SDL_mutex *subpq_mutex;
- SDL_cond *subpq_cond;
-
- double frame_timer;
- double frame_last_pts;
- double frame_last_delay;
- double video_clock; ///<pts of last decoded frame / predicted pts of next decoded frame
- int video_stream;
- AVStream *video_st;
- PacketQueue videoq;
- double video_current_pts; ///<current displayed pts (different from video_clock if frame fifos are used)
- double video_current_pts_drift; ///<video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
- int64_t video_current_pos; ///<current displayed file pos
- VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
- int pictq_size, pictq_rindex, pictq_windex;
- SDL_mutex *pictq_mutex;
- SDL_cond *pictq_cond;
-#if !CONFIG_AVFILTER
- struct SwsContext *img_convert_ctx;
-#endif
-
- // QETimer *video_timer;
- char filename[1024];
- int width, height, xleft, ytop;
-
- PtsCorrectionContext pts_ctx;
-
-#if CONFIG_AVFILTER
- AVFilterContext *out_video_filter; ///<the last filter in the video chain
-#endif
-
- float skip_frames;
- float skip_frames_index;
- int refresh;
-} VideoState;
-
-static void show_help(void);
-
-/* options specified by the user */
-static AVInputFormat *file_iformat;
-static const char *input_filename;
-static const char *window_title;
-static int fs_screen_width;
-static int fs_screen_height;
-static int screen_width = 0;
-static int screen_height = 0;
-static int frame_width = 0;
-static int frame_height = 0;
-static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
-static int audio_disable;
-static int video_disable;
-static int wanted_stream[AVMEDIA_TYPE_NB]={
- [AVMEDIA_TYPE_AUDIO]=-1,
- [AVMEDIA_TYPE_VIDEO]=-1,
- [AVMEDIA_TYPE_SUBTITLE]=-1,
-};
-static int seek_by_bytes=-1;
-static int display_disable;
-static int show_status = 1;
-static int av_sync_type = AV_SYNC_AUDIO_MASTER;
-static int64_t start_time = AV_NOPTS_VALUE;
-static int64_t duration = AV_NOPTS_VALUE;
-static int debug = 0;
-static int debug_mv = 0;
-static int step = 0;
-static int thread_count = 1;
-static int workaround_bugs = 1;
-static int fast = 0;
-static int genpts = 0;
-static int lowres = 0;
-static int idct = FF_IDCT_AUTO;
-static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
-static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
-static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
-static int error_recognition = FF_ER_CAREFUL;
-static int error_concealment = 3;
-static int decoder_reorder_pts= -1;
-static int autoexit;
-static int exit_on_keydown;
-static int exit_on_mousedown;
-static int loop=1;
-static int framedrop=1;
-
-static int rdftspeed=20;
-#if CONFIG_AVFILTER
-static char *vfilters = NULL;
-#endif
-
-/* current context */
-static int is_full_screen;
-static VideoState *cur_stream;
-static int64_t audio_callback_time;
-
-static AVPacket flush_pkt;
-
-#define FF_ALLOC_EVENT (SDL_USEREVENT)
-#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
-#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
-
-static SDL_Surface *screen;
-
-static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
-
-/* packet queue handling */
-static void packet_queue_init(PacketQueue *q)
-{
- memset(q, 0, sizeof(PacketQueue));
- q->mutex = SDL_CreateMutex();
- q->cond = SDL_CreateCond();
- packet_queue_put(q, &flush_pkt);
-}
-
-static void packet_queue_flush(PacketQueue *q)
-{
- AVPacketList *pkt, *pkt1;
-
- SDL_LockMutex(q->mutex);
- for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
- pkt1 = pkt->next;
- av_free_packet(&pkt->pkt);
- av_freep(&pkt);
- }
- q->last_pkt = NULL;
- q->first_pkt = NULL;
- q->nb_packets = 0;
- q->size = 0;
- SDL_UnlockMutex(q->mutex);
-}
-
-static void packet_queue_end(PacketQueue *q)
-{
- packet_queue_flush(q);
- SDL_DestroyMutex(q->mutex);
- SDL_DestroyCond(q->cond);
-}
-
-static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
-{
- AVPacketList *pkt1;
-
- /* duplicate the packet */
- if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
- return -1;
-
- pkt1 = av_malloc(sizeof(AVPacketList));
- if (!pkt1)
- return -1;
- pkt1->pkt = *pkt;
- pkt1->next = NULL;
-
-
- SDL_LockMutex(q->mutex);
-
- if (!q->last_pkt)
-
- q->first_pkt = pkt1;
- else
- q->last_pkt->next = pkt1;
- q->last_pkt = pkt1;
- q->nb_packets++;
- q->size += pkt1->pkt.size + sizeof(*pkt1);
- /* XXX: should duplicate packet data in DV case */
- SDL_CondSignal(q->cond);
-
- SDL_UnlockMutex(q->mutex);
- return 0;
-}
-
-static void packet_queue_abort(PacketQueue *q)
-{
- SDL_LockMutex(q->mutex);
-
- q->abort_request = 1;
-
- SDL_CondSignal(q->cond);
-
- SDL_UnlockMutex(q->mutex);
-}
-
-/* return < 0 if aborted, 0 if no packet and > 0 if packet. */
-static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
-{
- AVPacketList *pkt1;
- int ret;
-
- SDL_LockMutex(q->mutex);
-
- for(;;) {
- if (q->abort_request) {
- ret = -1;
- break;
- }
-
- pkt1 = q->first_pkt;
- if (pkt1) {
- q->first_pkt = pkt1->next;
- if (!q->first_pkt)
- q->last_pkt = NULL;
- q->nb_packets--;
- q->size -= pkt1->pkt.size + sizeof(*pkt1);
- *pkt = pkt1->pkt;
- av_free(pkt1);
- ret = 1;
- break;
- } else if (!block) {
- ret = 0;
- break;
- } else {
- SDL_CondWait(q->cond, q->mutex);
- }
- }
- SDL_UnlockMutex(q->mutex);
- return ret;
-}
-
-static inline void fill_rectangle(SDL_Surface *screen,
- int x, int y, int w, int h, int color)
-{
- SDL_Rect rect;
- rect.x = x;
- rect.y = y;
- rect.w = w;
- rect.h = h;
- SDL_FillRect(screen, &rect, color);
-}
-
-#define ALPHA_BLEND(a, oldp, newp, s)\
-((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
-
-#define RGBA_IN(r, g, b, a, s)\
-{\
- unsigned int v = ((const uint32_t *)(s))[0];\
- a = (v >> 24) & 0xff;\
- r = (v >> 16) & 0xff;\
- g = (v >> 8) & 0xff;\
- b = v & 0xff;\
-}
-
-#define YUVA_IN(y, u, v, a, s, pal)\
-{\
- unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
- a = (val >> 24) & 0xff;\
- y = (val >> 16) & 0xff;\
- u = (val >> 8) & 0xff;\
- v = val & 0xff;\
-}
-
-#define YUVA_OUT(d, y, u, v, a)\
-{\
- ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
-}
-
-
-#define BPP 1
-
-static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
-{
- int wrap, wrap3, width2, skip2;
- int y, u, v, a, u1, v1, a1, w, h;
- uint8_t *lum, *cb, *cr;
- const uint8_t *p;
- const uint32_t *pal;
- int dstx, dsty, dstw, dsth;
-
- dstw = av_clip(rect->w, 0, imgw);
- dsth = av_clip(rect->h, 0, imgh);
- dstx = av_clip(rect->x, 0, imgw - dstw);
- dsty = av_clip(rect->y, 0, imgh - dsth);
- lum = dst->data[0] + dsty * dst->linesize[0];
- cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
- cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
-
- width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
- skip2 = dstx >> 1;
- wrap = dst->linesize[0];
- wrap3 = rect->pict.linesize[0];
- p = rect->pict.data[0];
- pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
-
- if (dsty & 1) {
- lum += dstx;
- cb += skip2;
- cr += skip2;
-
- if (dstx & 1) {
- YUVA_IN(y, u, v, a, p, pal);
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
- cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
- cb++;
- cr++;
- lum++;
- p += BPP;
- }
- for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
- YUVA_IN(y, u, v, a, p, pal);
- u1 = u;
- v1 = v;
- a1 = a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-
- YUVA_IN(y, u, v, a, p + BPP, pal);
- u1 += u;
- v1 += v;
- a1 += a;
- lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
- cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
- cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
- cb++;
- cr++;
- p += 2 * BPP;
- lum += 2;
- }
- if (w) {
- YUVA_IN(y, u, v, a, p, pal);
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
- cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
- p++;
- lum++;
- }
- p += wrap3 - dstw * BPP;
- lum += wrap - dstw - dstx;
- cb += dst->linesize[1] - width2 - skip2;
- cr += dst->linesize[2] - width2 - skip2;
- }
- for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
- lum += dstx;
- cb += skip2;
- cr += skip2;
-
- if (dstx & 1) {
- YUVA_IN(y, u, v, a, p, pal);
- u1 = u;
- v1 = v;
- a1 = a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- p += wrap3;
- lum += wrap;
- YUVA_IN(y, u, v, a, p, pal);
- u1 += u;
- v1 += v;
- a1 += a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
- cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
- cb++;
- cr++;
- p += -wrap3 + BPP;
- lum += -wrap + 1;
- }
- for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
- YUVA_IN(y, u, v, a, p, pal);
- u1 = u;
- v1 = v;
- a1 = a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-
- YUVA_IN(y, u, v, a, p + BPP, pal);
- u1 += u;
- v1 += v;
- a1 += a;
- lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
- p += wrap3;
- lum += wrap;
-
- YUVA_IN(y, u, v, a, p, pal);
- u1 += u;
- v1 += v;
- a1 += a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-
- YUVA_IN(y, u, v, a, p + BPP, pal);
- u1 += u;
- v1 += v;
- a1 += a;
- lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
-
- cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
- cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
-
- cb++;
- cr++;
- p += -wrap3 + 2 * BPP;
- lum += -wrap + 2;
- }
- if (w) {
- YUVA_IN(y, u, v, a, p, pal);
- u1 = u;
- v1 = v;
- a1 = a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- p += wrap3;
- lum += wrap;
- YUVA_IN(y, u, v, a, p, pal);
- u1 += u;
- v1 += v;
- a1 += a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
- cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
- cb++;
- cr++;
- p += -wrap3 + BPP;
- lum += -wrap + 1;
- }
- p += wrap3 + (wrap3 - dstw * BPP);
- lum += wrap + (wrap - dstw - dstx);
- cb += dst->linesize[1] - width2 - skip2;
- cr += dst->linesize[2] - width2 - skip2;
- }
- /* handle odd height */
- if (h) {
- lum += dstx;
- cb += skip2;
- cr += skip2;
-
- if (dstx & 1) {
- YUVA_IN(y, u, v, a, p, pal);
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
- cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
- cb++;
- cr++;
- lum++;
- p += BPP;
- }
- for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
- YUVA_IN(y, u, v, a, p, pal);
- u1 = u;
- v1 = v;
- a1 = a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-
- YUVA_IN(y, u, v, a, p + BPP, pal);
- u1 += u;
- v1 += v;
- a1 += a;
- lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
- cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
- cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
- cb++;
- cr++;
- p += 2 * BPP;
- lum += 2;
- }
- if (w) {
- YUVA_IN(y, u, v, a, p, pal);
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
- cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
- }
- }
-}
-
-static void free_subpicture(SubPicture *sp)
-{
- avsubtitle_free(&sp->sub);
-}
-
-static void video_image_display(VideoState *is)
-{
- VideoPicture *vp;
- SubPicture *sp;
- AVPicture pict;
- float aspect_ratio;
- int width, height, x, y;
- SDL_Rect rect;
- int i;
-
- vp = &is->pictq[is->pictq_rindex];
- if (vp->bmp) {
-#if CONFIG_AVFILTER
- if (vp->picref->video->pixel_aspect.num == 0)
- aspect_ratio = 0;
- else
- aspect_ratio = av_q2d(vp->picref->video->pixel_aspect);
-#else
-
- /* XXX: use variable in the frame */
- if (is->video_st->sample_aspect_ratio.num)
- aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
- else if (is->video_st->codec->sample_aspect_ratio.num)
- aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
- else
- aspect_ratio = 0;
-#endif
- if (aspect_ratio <= 0.0)
- aspect_ratio = 1.0;
- aspect_ratio *= (float)vp->width / (float)vp->height;
-
- if (is->subtitle_st)
- {
- if (is->subpq_size > 0)
- {
- sp = &is->subpq[is->subpq_rindex];
-
- if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
- {
- SDL_LockYUVOverlay (vp->bmp);
-
- pict.data[0] = vp->bmp->pixels[0];
- pict.data[1] = vp->bmp->pixels[2];
- pict.data[2] = vp->bmp->pixels[1];
-
- pict.linesize[0] = vp->bmp->pitches[0];
- pict.linesize[1] = vp->bmp->pitches[2];
- pict.linesize[2] = vp->bmp->pitches[1];
-
- for (i = 0; i < sp->sub.num_rects; i++)
- blend_subrect(&pict, sp->sub.rects[i],
- vp->bmp->w, vp->bmp->h);
-
- SDL_UnlockYUVOverlay (vp->bmp);
- }
- }
- }
-
-
- /* XXX: we suppose the screen has a 1.0 pixel ratio */
- height = is->height;
- width = ((int)rint(height * aspect_ratio)) & ~1;
- if (width > is->width) {
- width = is->width;
- height = ((int)rint(width / aspect_ratio)) & ~1;
- }
- x = (is->width - width) / 2;
- y = (is->height - height) / 2;
- is->no_background = 0;
- rect.x = is->xleft + x;
- rect.y = is->ytop + y;
- rect.w = width;
- rect.h = height;
- SDL_DisplayYUVOverlay(vp->bmp, &rect);
- }
-}
-
-/* get the current audio output buffer size, in samples. With SDL, we
- cannot have a precise information */
-static int audio_write_get_buf_size(VideoState *is)
-{
- return is->audio_buf_size - is->audio_buf_index;
-}
-
-static inline int compute_mod(int a, int b)
-{
- a = a % b;
- if (a >= 0)
- return a;
- else
- return a + b;
-}
-
-static void video_audio_display(VideoState *s)
-{
- int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
- int ch, channels, h, h2, bgcolor, fgcolor;
- int16_t time_diff;
- int rdft_bits, nb_freq;
-
- for(rdft_bits=1; (1<<rdft_bits)<2*s->height; rdft_bits++)
- ;
- nb_freq= 1<<(rdft_bits-1);
-
- /* compute display index : center on currently output samples */
- channels = s->audio_st->codec->channels;
- nb_display_channels = channels;
- if (!s->paused) {
- int data_used= s->show_audio==1 ? s->width : (2*nb_freq);
- n = 2 * channels;
- delay = audio_write_get_buf_size(s);
- delay /= n;
-
- /* to be more precise, we take into account the time spent since
- the last buffer computation */
- if (audio_callback_time) {
- time_diff = av_gettime() - audio_callback_time;
- delay -= (time_diff * s->audio_st->codec->sample_rate) / 1000000;
- }
-
- delay += 2*data_used;
- if (delay < data_used)
- delay = data_used;
-
- i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
- if(s->show_audio==1){
- h= INT_MIN;
- for(i=0; i<1000; i+=channels){
- int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
- int a= s->sample_array[idx];
- int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
- int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
- int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
- int score= a-d;
- if(h<score && (b^c)<0){
- h= score;
- i_start= idx;
- }
- }
- }
-
- s->last_i_start = i_start;
- } else {
- i_start = s->last_i_start;
- }
-
- bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
- if(s->show_audio==1){
- fill_rectangle(screen,
- s->xleft, s->ytop, s->width, s->height,
- bgcolor);
-
- fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
-
- /* total height for one channel */
- h = s->height / nb_display_channels;
- /* graph height / 2 */
- h2 = (h * 9) / 20;
- for(ch = 0;ch < nb_display_channels; ch++) {
- i = i_start + ch;
- y1 = s->ytop + ch * h + (h / 2); /* position of center line */
- for(x = 0; x < s->width; x++) {
- y = (s->sample_array[i] * h2) >> 15;
- if (y < 0) {
- y = -y;
- ys = y1 - y;
- } else {
- ys = y1;
- }
- fill_rectangle(screen,
- s->xleft + x, ys, 1, y,
- fgcolor);
- i += channels;
- if (i >= SAMPLE_ARRAY_SIZE)
- i -= SAMPLE_ARRAY_SIZE;
- }
- }
-
- fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
-
- for(ch = 1;ch < nb_display_channels; ch++) {
- y = s->ytop + ch * h;
- fill_rectangle(screen,
- s->xleft, y, s->width, 1,
- fgcolor);
- }
- SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
- }else{
- nb_display_channels= FFMIN(nb_display_channels, 2);
- if(rdft_bits != s->rdft_bits){
- av_rdft_end(s->rdft);
- av_free(s->rdft_data);
- s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
- s->rdft_bits= rdft_bits;
- s->rdft_data= av_malloc(4*nb_freq*sizeof(*s->rdft_data));
- }
- {
- FFTSample *data[2];
- for(ch = 0;ch < nb_display_channels; ch++) {
- data[ch] = s->rdft_data + 2*nb_freq*ch;
- i = i_start + ch;
- for(x = 0; x < 2*nb_freq; x++) {
- double w= (x-nb_freq)*(1.0/nb_freq);
- data[ch][x]= s->sample_array[i]*(1.0-w*w);
- i += channels;
- if (i >= SAMPLE_ARRAY_SIZE)
- i -= SAMPLE_ARRAY_SIZE;
- }
- av_rdft_calc(s->rdft, data[ch]);
- }
- //least efficient way to do this, we should of course directly access it but its more than fast enough
- for(y=0; y<s->height; y++){
- double w= 1/sqrt(nb_freq);
- int a= sqrt(w*sqrt(data[0][2*y+0]*data[0][2*y+0] + data[0][2*y+1]*data[0][2*y+1]));
- int b= (nb_display_channels == 2 ) ? sqrt(w*sqrt(data[1][2*y+0]*data[1][2*y+0]
- + data[1][2*y+1]*data[1][2*y+1])) : a;
- a= FFMIN(a,255);
- b= FFMIN(b,255);
- fgcolor = SDL_MapRGB(screen->format, a, b, (a+b)/2);
-
- fill_rectangle(screen,
- s->xpos, s->height-y, 1, 1,
- fgcolor);
- }
- }
- SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
- s->xpos++;
- if(s->xpos >= s->width)
- s->xpos= s->xleft;
- }
-}
-
-static int video_open(VideoState *is){
- int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
- int w,h;
-
- if(is_full_screen) flags |= SDL_FULLSCREEN;
- else flags |= SDL_RESIZABLE;
-
- if (is_full_screen && fs_screen_width) {
- w = fs_screen_width;
- h = fs_screen_height;
- } else if(!is_full_screen && screen_width){
- w = screen_width;
- h = screen_height;
-#if CONFIG_AVFILTER
- }else if (is->out_video_filter && is->out_video_filter->inputs[0]){
- w = is->out_video_filter->inputs[0]->w;
- h = is->out_video_filter->inputs[0]->h;
-#else
- }else if (is->video_st && is->video_st->codec->width){
- w = is->video_st->codec->width;
- h = is->video_st->codec->height;
-#endif
- } else {
- w = 640;
- h = 480;
- }
- if(screen && is->width == screen->w && screen->w == w
- && is->height== screen->h && screen->h == h)
- return 0;
-
-#ifndef __APPLE__
- screen = SDL_SetVideoMode(w, h, 0, flags);
-#else
- /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
- screen = SDL_SetVideoMode(w, h, 24, flags);
-#endif
- if (!screen) {
- fprintf(stderr, "SDL: could not set video mode - exiting\n");
- return -1;
- }
- if (!window_title)
- window_title = input_filename;
- SDL_WM_SetCaption(window_title, window_title);
-
- is->width = screen->w;
- is->height = screen->h;
-
- return 0;
-}
-
-/* display the current picture, if any */
-static void video_display(VideoState *is)
-{
- if(!screen)
- video_open(cur_stream);
- if (is->audio_st && is->show_audio)
- video_audio_display(is);
- else if (is->video_st)
- video_image_display(is);
-}
-
-static int refresh_thread(void *opaque)
-{
- VideoState *is= opaque;
- while(!is->abort_request){
- SDL_Event event;
- event.type = FF_REFRESH_EVENT;
- event.user.data1 = opaque;
- if(!is->refresh){
- is->refresh=1;
- SDL_PushEvent(&event);
- }
- usleep(is->audio_st && is->show_audio ? rdftspeed*1000 : 5000); //FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
- }
- return 0;
-}
-
-/* get the current audio clock value */
-static double get_audio_clock(VideoState *is)
-{
- double pts;
- int hw_buf_size, bytes_per_sec;
- pts = is->audio_clock;
- hw_buf_size = audio_write_get_buf_size(is);
- bytes_per_sec = 0;
- if (is->audio_st) {
- bytes_per_sec = is->audio_st->codec->sample_rate *
- 2 * is->audio_st->codec->channels;
- }
- if (bytes_per_sec)
- pts -= (double)hw_buf_size / bytes_per_sec;
- return pts;
-}
-
-/* get the current video clock value */
-static double get_video_clock(VideoState *is)
-{
- if (is->paused) {
- return is->video_current_pts;
- } else {
- return is->video_current_pts_drift + av_gettime() / 1000000.0;
- }
-}
-
-/* get the current external clock value */
-static double get_external_clock(VideoState *is)
-{
- int64_t ti;
- ti = av_gettime();
- return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
-}
-
-/* get the current master clock value */
-static double get_master_clock(VideoState *is)
-{
- double val;
-
- if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
- if (is->video_st)
- val = get_video_clock(is);
- else
- val = get_audio_clock(is);
- } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
- if (is->audio_st)
- val = get_audio_clock(is);
- else
- val = get_video_clock(is);
- } else {
- val = get_external_clock(is);
- }
- return val;
-}
-
-/* seek in the stream */
-static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
-{
- if (!is->seek_req) {
- is->seek_pos = pos;
- is->seek_rel = rel;
- is->seek_flags &= ~AVSEEK_FLAG_BYTE;
- if (seek_by_bytes)
- is->seek_flags |= AVSEEK_FLAG_BYTE;
- is->seek_req = 1;
- }
-}
-
-/* pause or resume the video */
-static void stream_pause(VideoState *is)
-{
- if (is->paused) {
- is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
- if(is->read_pause_return != AVERROR(ENOSYS)){
- is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
- }
- is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
- }
- is->paused = !is->paused;
-}
-
-static double compute_target_time(double frame_current_pts, VideoState *is)
-{
- double delay, sync_threshold, diff;
-
- /* compute nominal delay */
- delay = frame_current_pts - is->frame_last_pts;
- if (delay <= 0 || delay >= 10.0) {
- /* if incorrect delay, use previous one */
- delay = is->frame_last_delay;
- } else {
- is->frame_last_delay = delay;
- }
- is->frame_last_pts = frame_current_pts;
-
- /* update delay to follow master synchronisation source */
- if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
- is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
- /* if video is slave, we try to correct big delays by
- duplicating or deleting a frame */
- diff = get_video_clock(is) - get_master_clock(is);
-
- /* skip or repeat frame. We take into account the
- delay to compute the threshold. I still don't know
- if it is the best guess */
- sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
- if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
- if (diff <= -sync_threshold)
- delay = 0;
- else if (diff >= sync_threshold)
- delay = 2 * delay;
- }
- }
- is->frame_timer += delay;
-
- av_dlog(NULL, "video: delay=%0.3f pts=%0.3f A-V=%f\n",
- delay, frame_current_pts, -diff);
-
- return is->frame_timer;
-}
-
-/* called to display each frame */
-static void video_refresh_timer(void *opaque)
-{
- VideoState *is = opaque;
- VideoPicture *vp;
-
- SubPicture *sp, *sp2;
-
- if (is->video_st) {
-retry:
- if (is->pictq_size == 0) {
- //nothing to do, no picture to display in the que
- } else {
- double time= av_gettime()/1000000.0;
- double next_target;
- /* dequeue the picture */
- vp = &is->pictq[is->pictq_rindex];
-
- if(time < vp->target_clock)
- return;
- /* update current video pts */
- is->video_current_pts = vp->pts;
- is->video_current_pts_drift = is->video_current_pts - time;
- is->video_current_pos = vp->pos;
- if(is->pictq_size > 1){
- VideoPicture *nextvp= &is->pictq[(is->pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE];
- assert(nextvp->target_clock >= vp->target_clock);
- next_target= nextvp->target_clock;
- }else{
- next_target= vp->target_clock + is->video_clock - vp->pts; //FIXME pass durations cleanly
- }
- if(framedrop && time > next_target){
- is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR;
- if(is->pictq_size > 1 || time > next_target + 0.5){
- /* update queue size and signal for next picture */
- if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
- is->pictq_rindex = 0;
-
- SDL_LockMutex(is->pictq_mutex);
- is->pictq_size--;
- SDL_CondSignal(is->pictq_cond);
- SDL_UnlockMutex(is->pictq_mutex);
- goto retry;
- }
- }
-
- if(is->subtitle_st) {
- if (is->subtitle_stream_changed) {
- SDL_LockMutex(is->subpq_mutex);
-
- while (is->subpq_size) {
- free_subpicture(&is->subpq[is->subpq_rindex]);
-
- /* update queue size and signal for next picture */
- if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
- is->subpq_rindex = 0;
-
- is->subpq_size--;
- }
- is->subtitle_stream_changed = 0;
-
- SDL_CondSignal(is->subpq_cond);
- SDL_UnlockMutex(is->subpq_mutex);
- } else {
- if (is->subpq_size > 0) {
- sp = &is->subpq[is->subpq_rindex];
-
- if (is->subpq_size > 1)
- sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
- else
- sp2 = NULL;
-
- if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
- || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
- {
- free_subpicture(sp);
-
- /* update queue size and signal for next picture */
- if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
- is->subpq_rindex = 0;
-
- SDL_LockMutex(is->subpq_mutex);
- is->subpq_size--;
- SDL_CondSignal(is->subpq_cond);
- SDL_UnlockMutex(is->subpq_mutex);
- }
- }
- }
- }
-
- /* display picture */
- if (!display_disable)
- video_display(is);
-
- /* update queue size and signal for next picture */
- if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
- is->pictq_rindex = 0;
-
- SDL_LockMutex(is->pictq_mutex);
- is->pictq_size--;
- SDL_CondSignal(is->pictq_cond);
- SDL_UnlockMutex(is->pictq_mutex);
- }
- } else if (is->audio_st) {
- /* draw the next audio frame */
-
- /* if only audio stream, then display the audio bars (better
- than nothing, just to test the implementation */
-
- /* display picture */
- if (!display_disable)
- video_display(is);
- }
- if (show_status) {
- static int64_t last_time;
- int64_t cur_time;
- int aqsize, vqsize, sqsize;
- double av_diff;
-
- cur_time = av_gettime();
- if (!last_time || (cur_time - last_time) >= 30000) {
- aqsize = 0;
- vqsize = 0;
- sqsize = 0;
- if (is->audio_st)
- aqsize = is->audioq.size;
- if (is->video_st)
- vqsize = is->videoq.size;
- if (is->subtitle_st)
- sqsize = is->subtitleq.size;
- av_diff = 0;
- if (is->audio_st && is->video_st)
- av_diff = get_audio_clock(is) - get_video_clock(is);
- printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
- get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->pts_ctx.num_faulty_dts, is->pts_ctx.num_faulty_pts);
- fflush(stdout);
- last_time = cur_time;
- }
- }
-}
-
-static void stream_close(VideoState *is)
-{
- VideoPicture *vp;
- int i;
- /* XXX: use a special url_shutdown call to abort parse cleanly */
- is->abort_request = 1;
- SDL_WaitThread(is->parse_tid, NULL);
- SDL_WaitThread(is->refresh_tid, NULL);
-
- /* free all pictures */
- for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
- vp = &is->pictq[i];
-#if CONFIG_AVFILTER
- if (vp->picref) {
- avfilter_unref_buffer(vp->picref);
- vp->picref = NULL;
- }
-#endif
- if (vp->bmp) {
- SDL_FreeYUVOverlay(vp->bmp);
- vp->bmp = NULL;
- }
- }
- SDL_DestroyMutex(is->pictq_mutex);
- SDL_DestroyCond(is->pictq_cond);
- SDL_DestroyMutex(is->subpq_mutex);
- SDL_DestroyCond(is->subpq_cond);
-#if !CONFIG_AVFILTER
- if (is->img_convert_ctx)
- sws_freeContext(is->img_convert_ctx);
-#endif
- av_free(is);
-}
-
-static void do_exit(void)
-{
- if (cur_stream) {
- stream_close(cur_stream);
- cur_stream = NULL;
- }
- uninit_opts();
-#if CONFIG_AVFILTER
- avfilter_uninit();
-#endif
- if (show_status)
- printf("\n");
- SDL_Quit();
- av_log(NULL, AV_LOG_QUIET, "");
- exit(0);
-}
-
-/* allocate a picture (needs to do that in main thread to avoid
- potential locking problems */
-static void alloc_picture(void *opaque)
-{
- VideoState *is = opaque;
- VideoPicture *vp;
-
- vp = &is->pictq[is->pictq_windex];
-
- if (vp->bmp)
- SDL_FreeYUVOverlay(vp->bmp);
-
-#if CONFIG_AVFILTER
- if (vp->picref)
- avfilter_unref_buffer(vp->picref);
- vp->picref = NULL;
-
- vp->width = is->out_video_filter->inputs[0]->w;
- vp->height = is->out_video_filter->inputs[0]->h;
- vp->pix_fmt = is->out_video_filter->inputs[0]->format;
-#else
- vp->width = is->video_st->codec->width;
- vp->height = is->video_st->codec->height;
- vp->pix_fmt = is->video_st->codec->pix_fmt;
-#endif
-
- vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
- SDL_YV12_OVERLAY,
- screen);
- if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
- /* SDL allocates a buffer smaller than requested if the video
- * overlay hardware is unable to support the requested size. */
- fprintf(stderr, "Error: the video system does not support an image\n"
- "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
- "to reduce the image size.\n", vp->width, vp->height );
- do_exit();
- }
-
- SDL_LockMutex(is->pictq_mutex);
- vp->allocated = 1;
- SDL_CondSignal(is->pictq_cond);
- SDL_UnlockMutex(is->pictq_mutex);
-}
-
-/**
- *
- * @param pts the dts of the pkt / pts of the frame and guessed if not known
- */
-static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos)
-{
- VideoPicture *vp;
- int dst_pix_fmt;
-#if CONFIG_AVFILTER
- AVPicture pict_src;
-#endif
- /* wait until we have space to put a new picture */
- SDL_LockMutex(is->pictq_mutex);
-
- if(is->pictq_size>=VIDEO_PICTURE_QUEUE_SIZE && !is->refresh)
- is->skip_frames= FFMAX(1.0 - FRAME_SKIP_FACTOR, is->skip_frames * (1.0-FRAME_SKIP_FACTOR));
-
- while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
- !is->videoq.abort_request) {
- SDL_CondWait(is->pictq_cond, is->pictq_mutex);
- }
- SDL_UnlockMutex(is->pictq_mutex);
-
- if (is->videoq.abort_request)
- return -1;
-
- vp = &is->pictq[is->pictq_windex];
-
- /* alloc or resize hardware picture buffer */
- if (!vp->bmp ||
-#if CONFIG_AVFILTER
- vp->width != is->out_video_filter->inputs[0]->w ||
- vp->height != is->out_video_filter->inputs[0]->h) {
-#else
- vp->width != is->video_st->codec->width ||
- vp->height != is->video_st->codec->height) {
-#endif
- SDL_Event event;
-
- vp->allocated = 0;
-
- /* the allocation must be done in the main thread to avoid
- locking problems */
- event.type = FF_ALLOC_EVENT;
- event.user.data1 = is;
- SDL_PushEvent(&event);
-
- /* wait until the picture is allocated */
- SDL_LockMutex(is->pictq_mutex);
- while (!vp->allocated && !is->videoq.abort_request) {
- SDL_CondWait(is->pictq_cond, is->pictq_mutex);
- }
- SDL_UnlockMutex(is->pictq_mutex);
-
- if (is->videoq.abort_request)
- return -1;
- }
-
- /* if the frame is not skipped, then display it */
- if (vp->bmp) {
- AVPicture pict;
-#if CONFIG_AVFILTER
- if(vp->picref)
- avfilter_unref_buffer(vp->picref);
- vp->picref = src_frame->opaque;
-#endif
-
- /* get a pointer on the bitmap */
- SDL_LockYUVOverlay (vp->bmp);
-
- dst_pix_fmt = PIX_FMT_YUV420P;
- memset(&pict,0,sizeof(AVPicture));
- pict.data[0] = vp->bmp->pixels[0];
- pict.data[1] = vp->bmp->pixels[2];
- pict.data[2] = vp->bmp->pixels[1];
-
- pict.linesize[0] = vp->bmp->pitches[0];
- pict.linesize[1] = vp->bmp->pitches[2];
- pict.linesize[2] = vp->bmp->pitches[1];
-
-#if CONFIG_AVFILTER
- pict_src.data[0] = src_frame->data[0];
- pict_src.data[1] = src_frame->data[1];
- pict_src.data[2] = src_frame->data[2];
-
- pict_src.linesize[0] = src_frame->linesize[0];
- pict_src.linesize[1] = src_frame->linesize[1];
- pict_src.linesize[2] = src_frame->linesize[2];
-
- //FIXME use direct rendering
- av_picture_copy(&pict, &pict_src,
- vp->pix_fmt, vp->width, vp->height);
-#else
- sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
- is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
- vp->width, vp->height, vp->pix_fmt, vp->width, vp->height,
- dst_pix_fmt, sws_flags, NULL, NULL, NULL);
- if (is->img_convert_ctx == NULL) {
- fprintf(stderr, "Cannot initialize the conversion context\n");
- exit(1);
- }
- sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
- 0, vp->height, pict.data, pict.linesize);
-#endif
- /* update the bitmap content */
- SDL_UnlockYUVOverlay(vp->bmp);
-
- vp->pts = pts;
- vp->pos = pos;
-
- /* now we can update the picture count */
- if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
- is->pictq_windex = 0;
- SDL_LockMutex(is->pictq_mutex);
- vp->target_clock= compute_target_time(vp->pts, is);
-
- is->pictq_size++;
- SDL_UnlockMutex(is->pictq_mutex);
- }
- return 0;
-}
-
-/**
- * compute the exact PTS for the picture if it is omitted in the stream
- * @param pts1 the dts of the pkt / pts of the frame
- */
-static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
-{
- double frame_delay, pts;
-
- pts = pts1;
-
- if (pts != 0) {
- /* update video clock with pts, if present */
- is->video_clock = pts;
- } else {
- pts = is->video_clock;
- }
- /* update video clock for next frame */
- frame_delay = av_q2d(is->video_st->codec->time_base);
- /* for MPEG2, the frame can be repeated, so we update the
- clock accordingly */
- frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
- is->video_clock += frame_delay;
-
- return queue_picture(is, src_frame, pts, pos);
-}
-
-static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
-{
- int len1, got_picture, i;
-
- if (packet_queue_get(&is->videoq, pkt, 1) < 0)
- return -1;
-
- if (pkt->data == flush_pkt.data) {
- avcodec_flush_buffers(is->video_st->codec);
-
- SDL_LockMutex(is->pictq_mutex);
- //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
- for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
- is->pictq[i].target_clock= 0;
- }
- while (is->pictq_size && !is->videoq.abort_request) {
- SDL_CondWait(is->pictq_cond, is->pictq_mutex);
- }
- is->video_current_pos = -1;
- SDL_UnlockMutex(is->pictq_mutex);
-
- init_pts_correction(&is->pts_ctx);
- is->frame_last_pts = AV_NOPTS_VALUE;
- is->frame_last_delay = 0;
- is->frame_timer = (double)av_gettime() / 1000000.0;
- is->skip_frames = 1;
- is->skip_frames_index = 0;
- return 0;
- }
-
- len1 = avcodec_decode_video2(is->video_st->codec,
- frame, &got_picture,
- pkt);
-
- if (got_picture) {
- if (decoder_reorder_pts == -1) {
- *pts = guess_correct_pts(&is->pts_ctx, frame->pkt_pts, frame->pkt_dts);
- } else if (decoder_reorder_pts) {
- *pts = frame->pkt_pts;
- } else {
- *pts = frame->pkt_dts;
- }
-
- if (*pts == AV_NOPTS_VALUE) {
- *pts = 0;
- }
-
- is->skip_frames_index += 1;
- if(is->skip_frames_index >= is->skip_frames){
- is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);
- return 1;
- }
-
- }
- return 0;
-}
-
-#if CONFIG_AVFILTER
-typedef struct {
- VideoState *is;
- AVFrame *frame;
- int use_dr1;
-} FilterPriv;
-
-static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
-{
- AVFilterContext *ctx = codec->opaque;
- AVFilterBufferRef *ref;
- int perms = AV_PERM_WRITE;
- int i, w, h, stride[4];
- unsigned edge;
- int pixel_size;
-
- if (codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES)
- perms |= AV_PERM_NEG_LINESIZES;
-
- if(pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
- if(pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
- if(pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
- if(pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2;
- }
- if(pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE;
-
- w = codec->width;
- h = codec->height;
- avcodec_align_dimensions2(codec, &w, &h, stride);
- edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width();
- w += edge << 1;
- h += edge << 1;
-
- if(!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h)))
- return -1;
-
- pixel_size = av_pix_fmt_descriptors[ref->format].comp[0].step_minus1+1;
- ref->video->w = codec->width;
- ref->video->h = codec->height;
- for(i = 0; i < 4; i ++) {
- unsigned hshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_w : 0;
- unsigned vshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_h : 0;
-
- if (ref->data[i]) {
- ref->data[i] += ((edge * pixel_size) >> hshift) + ((edge * ref->linesize[i]) >> vshift);
- }
- pic->data[i] = ref->data[i];
- pic->linesize[i] = ref->linesize[i];
- }
- pic->opaque = ref;
- pic->age = INT_MAX;
- pic->type = FF_BUFFER_TYPE_USER;
- pic->reordered_opaque = codec->reordered_opaque;
- if(codec->pkt) pic->pkt_pts = codec->pkt->pts;
- else pic->pkt_pts = AV_NOPTS_VALUE;
- return 0;
-}
-
-static void input_release_buffer(AVCodecContext *codec, AVFrame *pic)
-{
- memset(pic->data, 0, sizeof(pic->data));
- avfilter_unref_buffer(pic->opaque);
-}
-
-static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic)
-{
- AVFilterBufferRef *ref = pic->opaque;
-
- if (pic->data[0] == NULL) {
- pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
- return codec->get_buffer(codec, pic);
- }
-
- if ((codec->width != ref->video->w) || (codec->height != ref->video->h) ||
- (codec->pix_fmt != ref->format)) {
- av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n");
- return -1;
- }
-
- pic->reordered_opaque = codec->reordered_opaque;
- if(codec->pkt) pic->pkt_pts = codec->pkt->pts;
- else pic->pkt_pts = AV_NOPTS_VALUE;
- return 0;
-}
-
-static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
-{
- FilterPriv *priv = ctx->priv;
- AVCodecContext *codec;
- if(!opaque) return -1;
-
- priv->is = opaque;
- codec = priv->is->video_st->codec;
- codec->opaque = ctx;
- if(codec->codec->capabilities & CODEC_CAP_DR1) {
- priv->use_dr1 = 1;
- codec->get_buffer = input_get_buffer;
- codec->release_buffer = input_release_buffer;
- codec->reget_buffer = input_reget_buffer;
- codec->thread_safe_callbacks = 1;
- }
-
- priv->frame = avcodec_alloc_frame();
-
- return 0;
-}
-
-static void input_uninit(AVFilterContext *ctx)
-{
- FilterPriv *priv = ctx->priv;
- av_free(priv->frame);
-}
-
-static int input_request_frame(AVFilterLink *link)
-{
- FilterPriv *priv = link->src->priv;
- AVFilterBufferRef *picref;
- int64_t pts = 0;
- AVPacket pkt;
- int ret;
-
- while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
- av_free_packet(&pkt);
- if (ret < 0)
- return -1;
-
- if(priv->use_dr1) {
- picref = avfilter_ref_buffer(priv->frame->opaque, ~0);
- } else {
- picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
- av_image_copy(picref->data, picref->linesize,
- priv->frame->data, priv->frame->linesize,
- picref->format, link->w, link->h);
- }
- av_free_packet(&pkt);
-
- picref->pts = pts;
- picref->pos = pkt.pos;
- picref->video->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio;
- avfilter_start_frame(link, picref);
- avfilter_draw_slice(link, 0, link->h, 1);
- avfilter_end_frame(link);
-
- return 0;
-}
-
-static int input_query_formats(AVFilterContext *ctx)
-{
- FilterPriv *priv = ctx->priv;
- enum PixelFormat pix_fmts[] = {
- priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
- };
-
- avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
- return 0;
-}
-
-static int input_config_props(AVFilterLink *link)
-{
- FilterPriv *priv = link->src->priv;
- AVCodecContext *c = priv->is->video_st->codec;
-
- link->w = c->width;
- link->h = c->height;
- link->time_base = priv->is->video_st->time_base;
-
- return 0;
-}
-
-static AVFilter input_filter =
-{
- .name = "ffplay_input",
-
- .priv_size = sizeof(FilterPriv),
-
- .init = input_init,
- .uninit = input_uninit,
-
- .query_formats = input_query_formats,
-
- .inputs = (AVFilterPad[]) {{ .name = NULL }},
- .outputs = (AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .request_frame = input_request_frame,
- .config_props = input_config_props, },
- { .name = NULL }},
-};
-
-static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
-{
- char sws_flags_str[128];
- int ret;
- FFSinkContext ffsink_ctx = { .pix_fmt = PIX_FMT_YUV420P };
- AVFilterContext *filt_src = NULL, *filt_out = NULL;
- snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
- graph->scale_sws_opts = av_strdup(sws_flags_str);
-
- if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
- NULL, is, graph)) < 0)
- goto the_end;
- if ((ret = avfilter_graph_create_filter(&filt_out, &ffsink, "out",
- NULL, &ffsink_ctx, graph)) < 0)
- goto the_end;
-
- if(vfilters) {
- AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
- AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut));
-
- outputs->name = av_strdup("in");
- outputs->filter_ctx = filt_src;
- outputs->pad_idx = 0;
- outputs->next = NULL;
-
- inputs->name = av_strdup("out");
- inputs->filter_ctx = filt_out;
- inputs->pad_idx = 0;
- inputs->next = NULL;
-
- if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0)
- goto the_end;
- av_freep(&vfilters);
- } else {
- if ((ret = avfilter_link(filt_src, 0, filt_out, 0)) < 0)
- goto the_end;
- }
-
- if ((ret = avfilter_graph_config(graph, NULL)) < 0)
- goto the_end;
-
- is->out_video_filter = filt_out;
-the_end:
- return ret;
-}
-
-#endif /* CONFIG_AVFILTER */
-
-static int video_thread(void *arg)
-{
- VideoState *is = arg;
- AVFrame *frame= avcodec_alloc_frame();
- int64_t pts_int;
- double pts;
- int ret;
-
-#if CONFIG_AVFILTER
- AVFilterGraph *graph = avfilter_graph_alloc();
- AVFilterContext *filt_out = NULL;
- int64_t pos;
-
- if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
- goto the_end;
- filt_out = is->out_video_filter;
-#endif
-
- for(;;) {
-#if !CONFIG_AVFILTER
- AVPacket pkt;
-#else
- AVFilterBufferRef *picref;
- AVRational tb;
-#endif
- while (is->paused && !is->videoq.abort_request)
- SDL_Delay(10);
-#if CONFIG_AVFILTER
- ret = get_filtered_video_frame(filt_out, frame, &picref, &tb);
- if (picref) {
- pts_int = picref->pts;
- pos = picref->pos;
- frame->opaque = picref;
- }
-
- if (av_cmp_q(tb, is->video_st->time_base)) {
- av_unused int64_t pts1 = pts_int;
- pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
- av_dlog(NULL, "video_thread(): "
- "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
- tb.num, tb.den, pts1,
- is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
- }
-#else
- ret = get_video_frame(is, frame, &pts_int, &pkt);
-#endif
-
- if (ret < 0) goto the_end;
-
- if (!ret)
- continue;
-
- pts = pts_int*av_q2d(is->video_st->time_base);
-
-#if CONFIG_AVFILTER
- ret = output_picture2(is, frame, pts, pos);
-#else
- ret = output_picture2(is, frame, pts, pkt.pos);
- av_free_packet(&pkt);
-#endif
- if (ret < 0)
- goto the_end;
-
- if (step)
- if (cur_stream)
- stream_pause(cur_stream);
- }
- the_end:
-#if CONFIG_AVFILTER
- avfilter_graph_free(&graph);
-#endif
- av_free(frame);
- return 0;
-}
-
-static int subtitle_thread(void *arg)
-{
- VideoState *is = arg;
- SubPicture *sp;
- AVPacket pkt1, *pkt = &pkt1;
- int len1, got_subtitle;
- double pts;
- int i, j;
- int r, g, b, y, u, v, a;
-
- for(;;) {
- while (is->paused && !is->subtitleq.abort_request) {
- SDL_Delay(10);
- }
- if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
- break;
-
- if(pkt->data == flush_pkt.data){
- avcodec_flush_buffers(is->subtitle_st->codec);
- continue;
- }
- SDL_LockMutex(is->subpq_mutex);
- while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
- !is->subtitleq.abort_request) {
- SDL_CondWait(is->subpq_cond, is->subpq_mutex);
- }
- SDL_UnlockMutex(is->subpq_mutex);
-
- if (is->subtitleq.abort_request)
- goto the_end;
-
- sp = &is->subpq[is->subpq_windex];
-
- /* NOTE: ipts is the PTS of the _first_ picture beginning in
- this packet, if any */
- pts = 0;
- if (pkt->pts != AV_NOPTS_VALUE)
- pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
-
- len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
- &sp->sub, &got_subtitle,
- pkt);
- if (got_subtitle && sp->sub.format == 0) {
- sp->pts = pts;
-
- for (i = 0; i < sp->sub.num_rects; i++)
- {
- for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
- {
- RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
- y = RGB_TO_Y_CCIR(r, g, b);
- u = RGB_TO_U_CCIR(r, g, b, 0);
- v = RGB_TO_V_CCIR(r, g, b, 0);
- YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
- }
- }
-
- /* now we can update the picture count */
- if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
- is->subpq_windex = 0;
- SDL_LockMutex(is->subpq_mutex);
- is->subpq_size++;
- SDL_UnlockMutex(is->subpq_mutex);
- }
- av_free_packet(pkt);
- }
- the_end:
- return 0;
-}
-
-/* copy samples for viewing in editor window */
-static void update_sample_display(VideoState *is, short *samples, int samples_size)
-{
- int size, len, channels;
-
- channels = is->audio_st->codec->channels;
-
- size = samples_size / sizeof(short);
- while (size > 0) {
- len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
- if (len > size)
- len = size;
- memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
- samples += len;
- is->sample_array_index += len;
- if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
- is->sample_array_index = 0;
- size -= len;
- }
-}
-
-/* return the new audio buffer size (samples can be added or deleted
- to get better sync if video or external master clock) */
-static int synchronize_audio(VideoState *is, short *samples,
- int samples_size1, double pts)
-{
- int n, samples_size;
- double ref_clock;
-
- n = 2 * is->audio_st->codec->channels;
- samples_size = samples_size1;
-
- /* if not master, then we try to remove or add samples to correct the clock */
- if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
- is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
- double diff, avg_diff;
- int wanted_size, min_size, max_size, nb_samples;
-
- ref_clock = get_master_clock(is);
- diff = get_audio_clock(is) - ref_clock;
-
- if (diff < AV_NOSYNC_THRESHOLD) {
- is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
- if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
- /* not enough measures to have a correct estimate */
- is->audio_diff_avg_count++;
- } else {
- /* estimate the A-V difference */
- avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
-
- if (fabs(avg_diff) >= is->audio_diff_threshold) {
- wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
- nb_samples = samples_size / n;
-
- min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
- max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
- if (wanted_size < min_size)
- wanted_size = min_size;
- else if (wanted_size > max_size)
- wanted_size = max_size;
-
- /* add or remove samples to correction the synchro */
- if (wanted_size < samples_size) {
- /* remove samples */
- samples_size = wanted_size;
- } else if (wanted_size > samples_size) {
- uint8_t *samples_end, *q;
- int nb;
-
- /* add samples */
- nb = (samples_size - wanted_size);
- samples_end = (uint8_t *)samples + samples_size - n;
- q = samples_end + n;
- while (nb > 0) {
- memcpy(q, samples_end, n);
- q += n;
- nb -= n;
- }
- samples_size = wanted_size;
- }
- }
- av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
- diff, avg_diff, samples_size - samples_size1,
- is->audio_clock, is->video_clock, is->audio_diff_threshold);
- }
- } else {
- /* too big difference : may be initial PTS errors, so
- reset A-V filter */
- is->audio_diff_avg_count = 0;
- is->audio_diff_cum = 0;
- }
- }
-
- return samples_size;
-}
-
-/* decode one audio frame and returns its uncompressed size */
-static int audio_decode_frame(VideoState *is, double *pts_ptr)
-{
- AVPacket *pkt_temp = &is->audio_pkt_temp;
- AVPacket *pkt = &is->audio_pkt;
- AVCodecContext *dec= is->audio_st->codec;
- int n, len1, data_size;
- double pts;
-
- for(;;) {
- /* NOTE: the audio packet can contain several frames */
- while (pkt_temp->size > 0) {
- data_size = sizeof(is->audio_buf1);
- len1 = avcodec_decode_audio3(dec,
- (int16_t *)is->audio_buf1, &data_size,
- pkt_temp);
- if (len1 < 0) {
- /* if error, we skip the frame */
- pkt_temp->size = 0;
- break;
- }
-
- pkt_temp->data += len1;
- pkt_temp->size -= len1;
- if (data_size <= 0)
- continue;
-
- if (dec->sample_fmt != is->audio_src_fmt) {
- if (is->reformat_ctx)
- av_audio_convert_free(is->reformat_ctx);
- is->reformat_ctx= av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,
- dec->sample_fmt, 1, NULL, 0);
- if (!is->reformat_ctx) {
- fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
- av_get_sample_fmt_name(dec->sample_fmt),
- av_get_sample_fmt_name(AV_SAMPLE_FMT_S16));
- break;
- }
- is->audio_src_fmt= dec->sample_fmt;
- }
-
- if (is->reformat_ctx) {
- const void *ibuf[6]= {is->audio_buf1};
- void *obuf[6]= {is->audio_buf2};
- int istride[6]= {av_get_bits_per_sample_fmt(dec->sample_fmt)/8};
- int ostride[6]= {2};
- int len= data_size/istride[0];
- if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
- printf("av_audio_convert() failed\n");
- break;
- }
- is->audio_buf= is->audio_buf2;
- /* FIXME: existing code assume that data_size equals framesize*channels*2
- remove this legacy cruft */
- data_size= len*2;
- }else{
- is->audio_buf= is->audio_buf1;
- }
-
- /* if no pts, then compute it */
- pts = is->audio_clock;
- *pts_ptr = pts;
- n = 2 * dec->channels;
- is->audio_clock += (double)data_size /
- (double)(n * dec->sample_rate);
-#ifdef DEBUG
- {
- static double last_clock;
- printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
- is->audio_clock - last_clock,
- is->audio_clock, pts);
- last_clock = is->audio_clock;
- }
-#endif
- return data_size;
- }
-
- /* free the current packet */
- if (pkt->data)
- av_free_packet(pkt);
-
- if (is->paused || is->audioq.abort_request) {
- return -1;
- }
-
- /* read next packet */
- if (packet_queue_get(&is->audioq, pkt, 1) < 0)
- return -1;
- if(pkt->data == flush_pkt.data){
- avcodec_flush_buffers(dec);
- continue;
- }
-
- pkt_temp->data = pkt->data;
- pkt_temp->size = pkt->size;
-
- /* if update the audio clock with the pts */
- if (pkt->pts != AV_NOPTS_VALUE) {
- is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
- }
- }
-}
-
-/* prepare a new audio buffer */
-static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
-{
- VideoState *is = opaque;
- int audio_size, len1;
- double pts;
-
- audio_callback_time = av_gettime();
-
- while (len > 0) {
- if (is->audio_buf_index >= is->audio_buf_size) {
- audio_size = audio_decode_frame(is, &pts);
- if (audio_size < 0) {
- /* if error, just output silence */
- is->audio_buf = is->audio_buf1;
- is->audio_buf_size = 1024;
- memset(is->audio_buf, 0, is->audio_buf_size);
- } else {
- if (is->show_audio)
- update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
- audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
- pts);
- is->audio_buf_size = audio_size;
- }
- is->audio_buf_index = 0;
- }
- len1 = is->audio_buf_size - is->audio_buf_index;
- if (len1 > len)
- len1 = len;
- memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
- len -= len1;
- stream += len1;
- is->audio_buf_index += len1;
- }
-}
-
-/* open a given stream. Return 0 if OK */
-static int stream_component_open(VideoState *is, int stream_index)
-{
- AVFormatContext *ic = is->ic;
- AVCodecContext *avctx;
- AVCodec *codec;
- SDL_AudioSpec wanted_spec, spec;
-
- if (stream_index < 0 || stream_index >= ic->nb_streams)
- return -1;
- avctx = ic->streams[stream_index]->codec;
-
- /* prepare audio output */
- if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
- if (avctx->channels > 0) {
- avctx->request_channels = FFMIN(2, avctx->channels);
- } else {
- avctx->request_channels = 2;
- }
- }
-
- codec = avcodec_find_decoder(avctx->codec_id);
- avctx->debug_mv = debug_mv;
- avctx->debug = debug;
- avctx->workaround_bugs = workaround_bugs;
- avctx->lowres = lowres;
- if(lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
- avctx->idct_algo= idct;
- if(fast) avctx->flags2 |= CODEC_FLAG2_FAST;
- avctx->skip_frame= skip_frame;
- avctx->skip_idct= skip_idct;
- avctx->skip_loop_filter= skip_loop_filter;
- avctx->error_recognition= error_recognition;
- avctx->error_concealment= error_concealment;
- avctx->thread_count= thread_count;
-
- set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0, codec);
-
- if (!codec ||
- avcodec_open(avctx, codec) < 0)
- return -1;
-
- /* prepare audio output */
- if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
- wanted_spec.freq = avctx->sample_rate;
- wanted_spec.format = AUDIO_S16SYS;
- wanted_spec.channels = avctx->channels;
- wanted_spec.silence = 0;
- wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
- wanted_spec.callback = sdl_audio_callback;
- wanted_spec.userdata = is;
- if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
- fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
- return -1;
- }
- is->audio_hw_buf_size = spec.size;
- is->audio_src_fmt= AV_SAMPLE_FMT_S16;
- }
-
- ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
- switch(avctx->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- is->audio_stream = stream_index;
- is->audio_st = ic->streams[stream_index];
- is->audio_buf_size = 0;
- is->audio_buf_index = 0;
-
- /* init averaging filter */
- is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
- is->audio_diff_avg_count = 0;
- /* since we do not have a precise anough audio fifo fullness,
- we correct audio sync only if larger than this threshold */
- is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / avctx->sample_rate;
-
- memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
- packet_queue_init(&is->audioq);
- SDL_PauseAudio(0);
- break;
- case AVMEDIA_TYPE_VIDEO:
- is->video_stream = stream_index;
- is->video_st = ic->streams[stream_index];
-
- packet_queue_init(&is->videoq);
- is->video_tid = SDL_CreateThread(video_thread, is);
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- is->subtitle_stream = stream_index;
- is->subtitle_st = ic->streams[stream_index];
- packet_queue_init(&is->subtitleq);
-
- is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
- break;
- default:
- break;
- }
- return 0;
-}
-
-static void stream_component_close(VideoState *is, int stream_index)
-{
- AVFormatContext *ic = is->ic;
- AVCodecContext *avctx;
-
- if (stream_index < 0 || stream_index >= ic->nb_streams)
- return;
- avctx = ic->streams[stream_index]->codec;
-
- switch(avctx->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- packet_queue_abort(&is->audioq);
-
- SDL_CloseAudio();
-
- packet_queue_end(&is->audioq);
- if (is->reformat_ctx)
- av_audio_convert_free(is->reformat_ctx);
- is->reformat_ctx = NULL;
- break;
- case AVMEDIA_TYPE_VIDEO:
- packet_queue_abort(&is->videoq);
-
- /* note: we also signal this mutex to make sure we deblock the
- video thread in all cases */
- SDL_LockMutex(is->pictq_mutex);
- SDL_CondSignal(is->pictq_cond);
- SDL_UnlockMutex(is->pictq_mutex);
-
- SDL_WaitThread(is->video_tid, NULL);
-
- packet_queue_end(&is->videoq);
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- packet_queue_abort(&is->subtitleq);
-
- /* note: we also signal this mutex to make sure we deblock the
- video thread in all cases */
- SDL_LockMutex(is->subpq_mutex);
- is->subtitle_stream_changed = 1;
-
- SDL_CondSignal(is->subpq_cond);
- SDL_UnlockMutex(is->subpq_mutex);
-
- SDL_WaitThread(is->subtitle_tid, NULL);
-
- packet_queue_end(&is->subtitleq);
- break;
- default:
- break;
- }
-
- ic->streams[stream_index]->discard = AVDISCARD_ALL;
- avcodec_close(avctx);
- switch(avctx->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- is->audio_st = NULL;
- is->audio_stream = -1;
- break;
- case AVMEDIA_TYPE_VIDEO:
- is->video_st = NULL;
- is->video_stream = -1;
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- is->subtitle_st = NULL;
- is->subtitle_stream = -1;
- break;
- default:
- break;
- }
-}
-
-/* since we have only one decoding thread, we can use a global
- variable instead of a thread local variable */
-static VideoState *global_video_state;
-
-static int decode_interrupt_cb(void)
-{
- return (global_video_state && global_video_state->abort_request);
-}
-
-/* this thread gets the stream from the disk or the network */
-static int decode_thread(void *arg)
-{
- VideoState *is = arg;
- AVFormatContext *ic = NULL;
- int err, i, ret;
- int st_index[AVMEDIA_TYPE_NB];
- AVPacket pkt1, *pkt = &pkt1;
- int eof=0;
- int pkt_in_play_range = 0;
- AVDictionaryEntry *t;
-
- memset(st_index, -1, sizeof(st_index));
- is->video_stream = -1;
- is->audio_stream = -1;
- is->subtitle_stream = -1;
-
- global_video_state = is;
- avio_set_interrupt_cb(decode_interrupt_cb);
-
- err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
- if (err < 0) {
- print_error(is->filename, err);
- ret = -1;
- goto fail;
- }
- if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
- av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
- ret = AVERROR_OPTION_NOT_FOUND;
- goto fail;
- }
- is->ic = ic;
-
- if(genpts)
- ic->flags |= AVFMT_FLAG_GENPTS;
-
- /* Set AVCodecContext options so they will be seen by av_find_stream_info() */
- for (i = 0; i < ic->nb_streams; i++) {
- AVCodecContext *dec = ic->streams[i]->codec;
- switch (dec->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO],
- AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM,
- NULL);
- break;
- case AVMEDIA_TYPE_VIDEO:
- set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO],
- AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM,
- NULL);
- break;
- }
- }
-
- err = av_find_stream_info(ic);
- if (err < 0) {
- fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
- ret = -1;
- goto fail;
- }
- if(ic->pb)
- ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
-
- if(seek_by_bytes<0)
- seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT);
-
- /* if seeking requested, we execute it */
- if (start_time != AV_NOPTS_VALUE) {
- int64_t timestamp;
-
- timestamp = start_time;
- /* add the stream start time */
- if (ic->start_time != AV_NOPTS_VALUE)
- timestamp += ic->start_time;
- ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
- if (ret < 0) {
- fprintf(stderr, "%s: could not seek to position %0.3f\n",
- is->filename, (double)timestamp / AV_TIME_BASE);
- }
- }
-
- for (i = 0; i < ic->nb_streams; i++)
- ic->streams[i]->discard = AVDISCARD_ALL;
- if (!video_disable)
- st_index[AVMEDIA_TYPE_VIDEO] =
- av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
- wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
- if (!audio_disable)
- st_index[AVMEDIA_TYPE_AUDIO] =
- av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
- wanted_stream[AVMEDIA_TYPE_AUDIO],
- st_index[AVMEDIA_TYPE_VIDEO],
- NULL, 0);
- if (!video_disable)
- st_index[AVMEDIA_TYPE_SUBTITLE] =
- av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
- wanted_stream[AVMEDIA_TYPE_SUBTITLE],
- (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
- st_index[AVMEDIA_TYPE_AUDIO] :
- st_index[AVMEDIA_TYPE_VIDEO]),
- NULL, 0);
- if (show_status) {
- av_dump_format(ic, 0, is->filename, 0);
- }
-
- /* open the streams */
- if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
- stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
- }
-
- ret=-1;
- if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
- ret= stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
- }
- is->refresh_tid = SDL_CreateThread(refresh_thread, is);
- if(ret<0) {
- if (!display_disable)
- is->show_audio = 2;
- }
-
- if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
- stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
- }
-
- if (is->video_stream < 0 && is->audio_stream < 0) {
- fprintf(stderr, "%s: could not open codecs\n", is->filename);
- ret = -1;
- goto fail;
- }
-
- for(;;) {
- if (is->abort_request)
- break;
- if (is->paused != is->last_paused) {
- is->last_paused = is->paused;
- if (is->paused)
- is->read_pause_return= av_read_pause(ic);
- else
- av_read_play(ic);
- }
-#if CONFIG_RTSP_DEMUXER
- if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
- /* wait 10 ms to avoid trying to get another packet */
- /* XXX: horrible */
- SDL_Delay(10);
- continue;
- }
-#endif
- if (is->seek_req) {
- int64_t seek_target= is->seek_pos;
- int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
- int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
-//FIXME the +-2 is due to rounding being not done in the correct direction in generation
-// of the seek_pos/seek_rel variables
-
- ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
- if (ret < 0) {
- fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
- }else{
- if (is->audio_stream >= 0) {
- packet_queue_flush(&is->audioq);
- packet_queue_put(&is->audioq, &flush_pkt);
- }
- if (is->subtitle_stream >= 0) {
- packet_queue_flush(&is->subtitleq);
- packet_queue_put(&is->subtitleq, &flush_pkt);
- }
- if (is->video_stream >= 0) {
- packet_queue_flush(&is->videoq);
- packet_queue_put(&is->videoq, &flush_pkt);
- }
- }
- is->seek_req = 0;
- eof= 0;
- }
-
- /* if the queue are full, no need to read more */
- if ( is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
- || ( (is->audioq .size > MIN_AUDIOQ_SIZE || is->audio_stream<0)
- && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream<0)
- && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
- /* wait 10 ms */
- SDL_Delay(10);
- continue;
- }
- if(eof) {
- if(is->video_stream >= 0){
- av_init_packet(pkt);
- pkt->data=NULL;
- pkt->size=0;
- pkt->stream_index= is->video_stream;
- packet_queue_put(&is->videoq, pkt);
- }
- SDL_Delay(10);
- if(is->audioq.size + is->videoq.size + is->subtitleq.size ==0){
- if(loop!=1 && (!loop || --loop)){
- stream_seek(cur_stream, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
- }else if(autoexit){
- ret=AVERROR_EOF;
- goto fail;
- }
- }
- continue;
- }
- ret = av_read_frame(ic, pkt);
- if (ret < 0) {
- if (ret == AVERROR_EOF || (ic->pb && ic->pb->eof_reached))
- eof=1;
- if (ic->pb && ic->pb->error)
- break;
- SDL_Delay(100); /* wait for user event */
- continue;
- }
- /* check if packet is in play range specified by user, then queue, otherwise discard */
- pkt_in_play_range = duration == AV_NOPTS_VALUE ||
- (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
- av_q2d(ic->streams[pkt->stream_index]->time_base) -
- (double)(start_time != AV_NOPTS_VALUE ? start_time : 0)/1000000
- <= ((double)duration/1000000);
- if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
- packet_queue_put(&is->audioq, pkt);
- } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
- packet_queue_put(&is->videoq, pkt);
- } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
- packet_queue_put(&is->subtitleq, pkt);
- } else {
- av_free_packet(pkt);
- }
- }
- /* wait until the end */
- while (!is->abort_request) {
- SDL_Delay(100);
- }
-
- ret = 0;
- fail:
- /* disable interrupting */
- global_video_state = NULL;
-
- /* close each stream */
- if (is->audio_stream >= 0)
- stream_component_close(is, is->audio_stream);
- if (is->video_stream >= 0)
- stream_component_close(is, is->video_stream);
- if (is->subtitle_stream >= 0)
- stream_component_close(is, is->subtitle_stream);
- if (is->ic) {
- av_close_input_file(is->ic);
- is->ic = NULL; /* safety */
- }
- avio_set_interrupt_cb(NULL);
-
- if (ret != 0) {
- SDL_Event event;
-
- event.type = FF_QUIT_EVENT;
- event.user.data1 = is;
- SDL_PushEvent(&event);
- }
- return 0;
-}
-
-static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
-{
- VideoState *is;
-
- is = av_mallocz(sizeof(VideoState));
- if (!is)
- return NULL;
- av_strlcpy(is->filename, filename, sizeof(is->filename));
- is->iformat = iformat;
- is->ytop = 0;
- is->xleft = 0;
-
- /* start video display */
- is->pictq_mutex = SDL_CreateMutex();
- is->pictq_cond = SDL_CreateCond();
-
- is->subpq_mutex = SDL_CreateMutex();
- is->subpq_cond = SDL_CreateCond();
-
- is->av_sync_type = av_sync_type;
- is->parse_tid = SDL_CreateThread(decode_thread, is);
- if (!is->parse_tid) {
- av_free(is);
- return NULL;
- }
- return is;
-}
-
-static void stream_cycle_channel(VideoState *is, int codec_type)
-{
- AVFormatContext *ic = is->ic;
- int start_index, stream_index;
- AVStream *st;
-
- if (codec_type == AVMEDIA_TYPE_VIDEO)
- start_index = is->video_stream;
- else if (codec_type == AVMEDIA_TYPE_AUDIO)
- start_index = is->audio_stream;
- else
- start_index = is->subtitle_stream;
- if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
- return;
- stream_index = start_index;
- for(;;) {
- if (++stream_index >= is->ic->nb_streams)
- {
- if (codec_type == AVMEDIA_TYPE_SUBTITLE)
- {
- stream_index = -1;
- goto the_end;
- } else
- stream_index = 0;
- }
- if (stream_index == start_index)
- return;
- st = ic->streams[stream_index];
- if (st->codec->codec_type == codec_type) {
- /* check that parameters are OK */
- switch(codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- if (st->codec->sample_rate != 0 &&
- st->codec->channels != 0)
- goto the_end;
- break;
- case AVMEDIA_TYPE_VIDEO:
- case AVMEDIA_TYPE_SUBTITLE:
- goto the_end;
- default:
- break;
- }
- }
- }
- the_end:
- stream_component_close(is, start_index);
- stream_component_open(is, stream_index);
-}
-
-
-static void toggle_full_screen(void)
-{
- is_full_screen = !is_full_screen;
- video_open(cur_stream);
-}
-
-static void toggle_pause(void)
-{
- if (cur_stream)
- stream_pause(cur_stream);
- step = 0;
-}
-
-static void step_to_next_frame(void)
-{
- if (cur_stream) {
- /* if the stream is paused unpause it, then step */
- if (cur_stream->paused)
- stream_pause(cur_stream);
- }
- step = 1;
-}
-
-static void toggle_audio_display(void)
-{
- if (cur_stream) {
- int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
- cur_stream->show_audio = (cur_stream->show_audio + 1) % 3;
- fill_rectangle(screen,
- cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height,
- bgcolor);
- SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height);
- }
-}
-
-/* handle an event sent by the GUI */
-static void event_loop(void)
-{
- SDL_Event event;
- double incr, pos, frac;
-
- for(;;) {
- double x;
- SDL_WaitEvent(&event);
- switch(event.type) {
- case SDL_KEYDOWN:
- if (exit_on_keydown) {
- do_exit();
- break;
- }
- switch(event.key.keysym.sym) {
- case SDLK_ESCAPE:
- case SDLK_q:
- do_exit();
- break;
- case SDLK_f:
- toggle_full_screen();
- break;
- case SDLK_p:
- case SDLK_SPACE:
- toggle_pause();
- break;
- case SDLK_s: //S: Step to next frame
- step_to_next_frame();
- break;
- case SDLK_a:
- if (cur_stream)
- stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
- break;
- case SDLK_v:
- if (cur_stream)
- stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
- break;
- case SDLK_t:
- if (cur_stream)
- stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
- break;
- case SDLK_w:
- toggle_audio_display();
- break;
- case SDLK_LEFT:
- incr = -10.0;
- goto do_seek;
- case SDLK_RIGHT:
- incr = 10.0;
- goto do_seek;
- case SDLK_UP:
- incr = 60.0;
- goto do_seek;
- case SDLK_DOWN:
- incr = -60.0;
- do_seek:
- if (cur_stream) {
- if (seek_by_bytes) {
- if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){
- pos= cur_stream->video_current_pos;
- }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
- pos= cur_stream->audio_pkt.pos;
- }else
- pos = avio_tell(cur_stream->ic->pb);
- if (cur_stream->ic->bit_rate)
- incr *= cur_stream->ic->bit_rate / 8.0;
- else
- incr *= 180000.0;
- pos += incr;
- stream_seek(cur_stream, pos, incr, 1);
- } else {
- pos = get_master_clock(cur_stream);
- pos += incr;
- stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
- }
- }
- break;
- default:
- break;
- }
- break;
- case SDL_MOUSEBUTTONDOWN:
- if (exit_on_mousedown) {
- do_exit();
- break;
- }
- case SDL_MOUSEMOTION:
- if(event.type ==SDL_MOUSEBUTTONDOWN){
- x= event.button.x;
- }else{
- if(event.motion.state != SDL_PRESSED)
- break;
- x= event.motion.x;
- }
- if (cur_stream) {
- if(seek_by_bytes || cur_stream->ic->duration<=0){
- uint64_t size= avio_size(cur_stream->ic->pb);
- stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
- }else{
- int64_t ts;
- int ns, hh, mm, ss;
- int tns, thh, tmm, tss;
- tns = cur_stream->ic->duration/1000000LL;
- thh = tns/3600;
- tmm = (tns%3600)/60;
- tss = (tns%60);
- frac = x/cur_stream->width;
- ns = frac*tns;
- hh = ns/3600;
- mm = (ns%3600)/60;
- ss = (ns%60);
- fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
- hh, mm, ss, thh, tmm, tss);
- ts = frac*cur_stream->ic->duration;
- if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
- ts += cur_stream->ic->start_time;
- stream_seek(cur_stream, ts, 0, 0);
- }
- }
- break;
- case SDL_VIDEORESIZE:
- if (cur_stream) {
- screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
- SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
- screen_width = cur_stream->width = event.resize.w;
- screen_height= cur_stream->height= event.resize.h;
- }
- break;
- case SDL_QUIT:
- case FF_QUIT_EVENT:
- do_exit();
- break;
- case FF_ALLOC_EVENT:
- video_open(event.user.data1);
- alloc_picture(event.user.data1);
- break;
- case FF_REFRESH_EVENT:
- video_refresh_timer(event.user.data1);
- cur_stream->refresh=0;
- break;
- default:
- break;
- }
- }
-}
-
-static int opt_frame_size(const char *opt, const char *arg)
-{
- if (av_parse_video_size(&frame_width, &frame_height, arg) < 0) {
- fprintf(stderr, "Incorrect frame size\n");
- return AVERROR(EINVAL);
- }
- if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
- fprintf(stderr, "Frame size must be a multiple of 2\n");
- return AVERROR(EINVAL);
- }
- return 0;
-}
-
-static int opt_width(const char *opt, const char *arg)
-{
- screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
- return 0;
-}
-
-static int opt_height(const char *opt, const char *arg)
-{
- screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
- return 0;
-}
-
-static int opt_format(const char *opt, const char *arg)
-{
- file_iformat = av_find_input_format(arg);
- if (!file_iformat) {
- fprintf(stderr, "Unknown input format: %s\n", arg);
- return AVERROR(EINVAL);
- }
- return 0;
-}
-
-static int opt_frame_pix_fmt(const char *opt, const char *arg)
-{
- frame_pix_fmt = av_get_pix_fmt(arg);
- return 0;
-}
-
-static int opt_sync(const char *opt, const char *arg)
-{
- if (!strcmp(arg, "audio"))
- av_sync_type = AV_SYNC_AUDIO_MASTER;
- else if (!strcmp(arg, "video"))
- av_sync_type = AV_SYNC_VIDEO_MASTER;
- else if (!strcmp(arg, "ext"))
- av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
- else {
- fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
- exit(1);
- }
- return 0;
-}
-
-static int opt_seek(const char *opt, const char *arg)
-{
- start_time = parse_time_or_die(opt, arg, 1);
- return 0;
-}
-
-static int opt_duration(const char *opt, const char *arg)
-{
- duration = parse_time_or_die(opt, arg, 1);
- return 0;
-}
-
-static int opt_debug(const char *opt, const char *arg)
-{
- av_log_set_level(99);
- debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
- return 0;
-}
-
-static int opt_vismv(const char *opt, const char *arg)
-{
- debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
- return 0;
-}
-
-static int opt_thread_count(const char *opt, const char *arg)
-{
- thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
-#if !HAVE_THREADS
- fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
-#endif
- return 0;
-}
-
-static const OptionDef options[] = {
-#include "cmdutils_common_opts.h"
- { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
- { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
- { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
- { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
- { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
- { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
- { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_AUDIO]}, "select desired audio stream", "stream_number" },
- { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_VIDEO]}, "select desired video stream", "stream_number" },
- { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_SUBTITLE]}, "select desired subtitle stream", "stream_number" },
- { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
- { "t", HAS_ARG, {(void*)&opt_duration}, "play \"duration\" seconds of audio/video", "duration" },
- { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto", "val" },
- { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
- { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
- { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
- { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
- { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
- { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
- { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
- { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
- { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
- { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
- { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
- { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
- { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
- { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
- { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" },
- { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)", "threshold" },
- { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" },
- { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
- { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
- { "autoexit", OPT_BOOL | OPT_EXPERT, {(void*)&autoexit}, "exit at the end", "" },
- { "exitonkeydown", OPT_BOOL | OPT_EXPERT, {(void*)&exit_on_keydown}, "exit on key down", "" },
- { "exitonmousedown", OPT_BOOL | OPT_EXPERT, {(void*)&exit_on_mousedown}, "exit on mouse down", "" },
- { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&loop}, "set number of times the playback shall be looped", "loop count" },
- { "framedrop", OPT_BOOL | OPT_EXPERT, {(void*)&framedrop}, "drop frames when cpu is too slow", "" },
- { "window_title", OPT_STRING | HAS_ARG, {(void*)&window_title}, "set window title", "window title" },
-#if CONFIG_AVFILTER
- { "vf", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
-#endif
- { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, {(void*)&rdftspeed}, "rdft speed", "msecs" },
- { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
- { "i", 0, {NULL}, "ffmpeg compatibility dummy option", ""},
- { NULL, },
-};
-
-static void show_usage(void)
-{
- printf("Simple media player\n");
- printf("usage: ffplay [options] input_file\n");
- printf("\n");
-}
-
-static void show_help(void)
-{
- av_log_set_callback(log_callback_help);
- show_usage();
- show_help_options(options, "Main options:\n",
- OPT_EXPERT, 0);
- show_help_options(options, "\nAdvanced options:\n",
- OPT_EXPERT, OPT_EXPERT);
- printf("\n");
- av_opt_show2(avcodec_opts[0], NULL,
- AV_OPT_FLAG_DECODING_PARAM, 0);
- printf("\n");
- av_opt_show2(avformat_opts, NULL,
- AV_OPT_FLAG_DECODING_PARAM, 0);
-#if !CONFIG_AVFILTER
- printf("\n");
- av_opt_show2(sws_opts, NULL,
- AV_OPT_FLAG_ENCODING_PARAM, 0);
-#endif
- printf("\nWhile playing:\n"
- "q, ESC quit\n"
- "f toggle full screen\n"
- "p, SPC pause\n"
- "a cycle audio channel\n"
- "v cycle video channel\n"
- "t cycle subtitle channel\n"
- "w show audio waves\n"
- "s activate frame-step mode\n"
- "left/right seek backward/forward 10 seconds\n"
- "down/up seek backward/forward 1 minute\n"
- "mouse click seek to percentage in file corresponding to fraction of width\n"
- );
-}
-
-static void opt_input_file(const char *filename)
-{
- if (input_filename) {
- fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
- filename, input_filename);
- exit(1);
- }
- if (!strcmp(filename, "-"))
- filename = "pipe:";
- input_filename = filename;
-}
-
-/* Called from the main */
-int main(int argc, char **argv)
-{
- int flags;
-
- av_log_set_flags(AV_LOG_SKIP_REPEATED);
-
- /* register all codecs, demux and protocols */
- avcodec_register_all();
-#if CONFIG_AVDEVICE
- avdevice_register_all();
-#endif
-#if CONFIG_AVFILTER
- avfilter_register_all();
-#endif
- av_register_all();
-
- init_opts();
-
- show_banner();
-
- parse_options(argc, argv, options, opt_input_file);
-
- if (!input_filename) {
- show_usage();
- fprintf(stderr, "An input file must be specified\n");
- fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
- exit(1);
- }
-
- if (display_disable) {
- video_disable = 1;
- }
- flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
-#if !defined(__MINGW32__) && !defined(__APPLE__)
- flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
-#endif
- if (SDL_Init (flags)) {
- fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
- exit(1);
- }
-
- if (!display_disable) {
-#if HAVE_SDL_VIDEO_SIZE
- const SDL_VideoInfo *vi = SDL_GetVideoInfo();
- fs_screen_width = vi->current_w;
- fs_screen_height = vi->current_h;
-#endif
- }
-
- SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
- SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
- SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
-
- av_init_packet(&flush_pkt);
- flush_pkt.data= "FLUSH";
-
- cur_stream = stream_open(input_filename, file_iformat);
-
- event_loop();
-
- /* never returns */
-
- return 0;
-}
diff --git a/ffpresets/libx264-baseline.ffpreset b/ffpresets/libx264-baseline.ffpreset
deleted file mode 100644
index ee7654b..0000000
--- a/ffpresets/libx264-baseline.ffpreset
+++ /dev/null
@@ -1,4 +0,0 @@
-coder=0
-bf=0
-flags2=-wpred-dct8x8
-wpredp=0
diff --git a/ffpresets/libx264-fast.ffpreset b/ffpresets/libx264-fast.ffpreset
deleted file mode 100644
index 6520133..0000000
--- a/ffpresets/libx264-fast.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partb8x8
-me_method=hex
-subq=6
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=2
-directpred=1
-trellis=1
-flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip
-wpredp=2
-rc_lookahead=30
diff --git a/ffpresets/libx264-fast_firstpass.ffpreset b/ffpresets/libx264-fast_firstpass.ffpreset
deleted file mode 100644
index 6fdb4b9..0000000
--- a/ffpresets/libx264-fast_firstpass.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=2
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=1
-directpred=1
-trellis=0
-flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip
-wpredp=2
-rc_lookahead=30
diff --git a/ffpresets/libx264-faster.ffpreset b/ffpresets/libx264-faster.ffpreset
deleted file mode 100644
index 52efc1a..0000000
--- a/ffpresets/libx264-faster.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partb8x8
-me_method=hex
-subq=4
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=2
-directpred=1
-trellis=1
-flags2=+bpyramid-mixed_refs+wpred+dct8x8+fastpskip
-wpredp=1
-rc_lookahead=20
diff --git a/ffpresets/libx264-faster_firstpass.ffpreset b/ffpresets/libx264-faster_firstpass.ffpreset
deleted file mode 100644
index 41a87fb..0000000
--- a/ffpresets/libx264-faster_firstpass.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=2
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=1
-directpred=1
-trellis=0
-flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip
-wpredp=1
-rc_lookahead=20
diff --git a/ffpresets/libx264-ipod320.ffpreset b/ffpresets/libx264-ipod320.ffpreset
deleted file mode 100644
index 943b521..0000000
--- a/ffpresets/libx264-ipod320.ffpreset
+++ /dev/null
@@ -1,7 +0,0 @@
-coder=0
-bf=0
-flags2=-wpred-dct8x8
-level=13
-maxrate=768000
-bufsize=3000000
-wpredp=0
diff --git a/ffpresets/libx264-ipod640.ffpreset b/ffpresets/libx264-ipod640.ffpreset
deleted file mode 100644
index 1ed3d9f..0000000
--- a/ffpresets/libx264-ipod640.ffpreset
+++ /dev/null
@@ -1,8 +0,0 @@
-coder=0
-bf=0
-refs=1
-flags2=-wpred-dct8x8
-level=30
-maxrate=10000000
-bufsize=10000000
-wpredp=0
diff --git a/ffpresets/libx264-lossless_fast.ffpreset b/ffpresets/libx264-lossless_fast.ffpreset
deleted file mode 100644
index 49b9ed1..0000000
--- a/ffpresets/libx264-lossless_fast.ffpreset
+++ /dev/null
@@ -1,20 +0,0 @@
-coder=0
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8+parti4x4+partp8x8-partp4x4-partb8x8
-me_method=hex
-subq=3
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-directpred=1
-flags2=+fastpskip
-cqp=0
-wpredp=0
diff --git a/ffpresets/libx264-lossless_max.ffpreset b/ffpresets/libx264-lossless_max.ffpreset
deleted file mode 100644
index f32d7b4..0000000
--- a/ffpresets/libx264-lossless_max.ffpreset
+++ /dev/null
@@ -1,21 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partp4x4-partb8x8
-me_method=esa
-subq=8
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-refs=16
-directpred=1
-flags2=+mixed_refs+dct8x8+fastpskip
-cqp=0
-wpredp=2
diff --git a/ffpresets/libx264-lossless_medium.ffpreset b/ffpresets/libx264-lossless_medium.ffpreset
deleted file mode 100644
index 0b84612..0000000
--- a/ffpresets/libx264-lossless_medium.ffpreset
+++ /dev/null
@@ -1,20 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8+parti4x4+partp8x8+partp4x4-partb8x8
-me_method=hex
-subq=5
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-directpred=1
-flags2=+fastpskip
-cqp=0
-wpredp=2
diff --git a/ffpresets/libx264-lossless_slow.ffpreset b/ffpresets/libx264-lossless_slow.ffpreset
deleted file mode 100644
index 857d3d1..0000000
--- a/ffpresets/libx264-lossless_slow.ffpreset
+++ /dev/null
@@ -1,21 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partp4x4-partb8x8
-me_method=umh
-subq=6
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-refs=2
-directpred=1
-flags2=+dct8x8+fastpskip
-cqp=0
-wpredp=2
diff --git a/ffpresets/libx264-lossless_slower.ffpreset b/ffpresets/libx264-lossless_slower.ffpreset
deleted file mode 100644
index ef0609f..0000000
--- a/ffpresets/libx264-lossless_slower.ffpreset
+++ /dev/null
@@ -1,21 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partp4x4-partb8x8
-me_method=umh
-subq=8
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-refs=4
-directpred=1
-flags2=+mixed_refs+dct8x8+fastpskip
-cqp=0
-wpredp=2
diff --git a/ffpresets/libx264-lossless_ultrafast.ffpreset b/ffpresets/libx264-lossless_ultrafast.ffpreset
deleted file mode 100644
index 4cc84f1..0000000
--- a/ffpresets/libx264-lossless_ultrafast.ffpreset
+++ /dev/null
@@ -1,19 +0,0 @@
-coder=0
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partp4x4-partb8x8
-me_method=dia
-subq=0
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-directpred=1
-flags2=+fastpskip
-cqp=0
diff --git a/ffpresets/libx264-main.ffpreset b/ffpresets/libx264-main.ffpreset
deleted file mode 100644
index d1dc7dd..0000000
--- a/ffpresets/libx264-main.ffpreset
+++ /dev/null
@@ -1 +0,0 @@
-flags2=-dct8x8
diff --git a/ffpresets/libx264-medium.ffpreset b/ffpresets/libx264-medium.ffpreset
deleted file mode 100644
index 6859952..0000000
--- a/ffpresets/libx264-medium.ffpreset
+++ /dev/null
@@ -1,22 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partb8x8
-me_method=hex
-subq=7
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=3
-directpred=1
-trellis=1
-flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip
-wpredp=2
diff --git a/ffpresets/libx264-medium_firstpass.ffpreset b/ffpresets/libx264-medium_firstpass.ffpreset
deleted file mode 100644
index ca304ee..0000000
--- a/ffpresets/libx264-medium_firstpass.ffpreset
+++ /dev/null
@@ -1,22 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=2
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=1
-directpred=1
-trellis=0
-flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip
-wpredp=2
diff --git a/ffpresets/libx264-placebo.ffpreset b/ffpresets/libx264-placebo.ffpreset
deleted file mode 100644
index 7923a76..0000000
--- a/ffpresets/libx264-placebo.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partp4x4+partb8x8
-me_method=tesa
-subq=10
-me_range=24
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=2
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=16
-refs=16
-directpred=3
-trellis=2
-flags2=+bpyramid+mixed_refs+wpred+dct8x8-fastpskip
-wpredp=2
-rc_lookahead=60
diff --git a/ffpresets/libx264-placebo_firstpass.ffpreset b/ffpresets/libx264-placebo_firstpass.ffpreset
deleted file mode 100644
index 7923a76..0000000
--- a/ffpresets/libx264-placebo_firstpass.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partp4x4+partb8x8
-me_method=tesa
-subq=10
-me_range=24
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=2
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=16
-refs=16
-directpred=3
-trellis=2
-flags2=+bpyramid+mixed_refs+wpred+dct8x8-fastpskip
-wpredp=2
-rc_lookahead=60
diff --git a/ffpresets/libx264-slow.ffpreset b/ffpresets/libx264-slow.ffpreset
deleted file mode 100644
index fcbef4b..0000000
--- a/ffpresets/libx264-slow.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partb8x8
-me_method=umh
-subq=8
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=2
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=5
-directpred=3
-trellis=1
-flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip
-wpredp=2
-rc_lookahead=50
diff --git a/ffpresets/libx264-slow_firstpass.ffpreset b/ffpresets/libx264-slow_firstpass.ffpreset
deleted file mode 100644
index 74f87b0..0000000
--- a/ffpresets/libx264-slow_firstpass.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=2
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=2
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=1
-directpred=3
-trellis=0
-flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip
-wpredp=2
-rc_lookahead=50
diff --git a/ffpresets/libx264-slower.ffpreset b/ffpresets/libx264-slower.ffpreset
deleted file mode 100644
index 741d21f..0000000
--- a/ffpresets/libx264-slower.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partp4x4+partb8x8
-me_method=umh
-subq=9
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=2
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=8
-directpred=3
-trellis=2
-flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip
-wpredp=2
-rc_lookahead=60
diff --git a/ffpresets/libx264-slower_firstpass.ffpreset b/ffpresets/libx264-slower_firstpass.ffpreset
deleted file mode 100644
index 0be886a..0000000
--- a/ffpresets/libx264-slower_firstpass.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=2
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=2
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=1
-directpred=3
-trellis=0
-flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip
-wpredp=2
-rc_lookahead=60
diff --git a/ffpresets/libx264-superfast.ffpreset b/ffpresets/libx264-superfast.ffpreset
deleted file mode 100644
index 7f0f50b..0000000
--- a/ffpresets/libx264-superfast.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=1
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=1
-directpred=1
-trellis=0
-flags2=+bpyramid-mixed_refs+wpred+dct8x8+fastpskip-mbtree
-wpredp=0
-rc_lookahead=0
diff --git a/ffpresets/libx264-superfast_firstpass.ffpreset b/ffpresets/libx264-superfast_firstpass.ffpreset
deleted file mode 100644
index 87b4f29..0000000
--- a/ffpresets/libx264-superfast_firstpass.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=1
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=1
-directpred=1
-trellis=0
-flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip-mbtree
-wpredp=0
-rc_lookahead=0
diff --git a/ffpresets/libx264-ultrafast.ffpreset b/ffpresets/libx264-ultrafast.ffpreset
deleted file mode 100644
index 561191e..0000000
--- a/ffpresets/libx264-ultrafast.ffpreset
+++ /dev/null
@@ -1,24 +0,0 @@
-coder=0
-flags=-loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=0
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=0
-i_qfactor=0.71
-b_strategy=0
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=0
-refs=1
-directpred=1
-trellis=0
-flags2=-bpyramid-mixed_refs-wpred-dct8x8+fastpskip-mbtree
-wpredp=0
-aq_mode=0
-rc_lookahead=0
diff --git a/ffpresets/libx264-ultrafast_firstpass.ffpreset b/ffpresets/libx264-ultrafast_firstpass.ffpreset
deleted file mode 100644
index 561191e..0000000
--- a/ffpresets/libx264-ultrafast_firstpass.ffpreset
+++ /dev/null
@@ -1,24 +0,0 @@
-coder=0
-flags=-loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=0
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=0
-i_qfactor=0.71
-b_strategy=0
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=0
-refs=1
-directpred=1
-trellis=0
-flags2=-bpyramid-mixed_refs-wpred-dct8x8+fastpskip-mbtree
-wpredp=0
-aq_mode=0
-rc_lookahead=0
diff --git a/ffpresets/libx264-veryfast.ffpreset b/ffpresets/libx264-veryfast.ffpreset
deleted file mode 100644
index d8c7f7a..0000000
--- a/ffpresets/libx264-veryfast.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partb8x8
-me_method=hex
-subq=2
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=1
-directpred=1
-trellis=0
-flags2=+bpyramid-mixed_refs+wpred+dct8x8+fastpskip
-wpredp=0
-rc_lookahead=10
diff --git a/ffpresets/libx264-veryfast_firstpass.ffpreset b/ffpresets/libx264-veryfast_firstpass.ffpreset
deleted file mode 100644
index 7b2a1e9..0000000
--- a/ffpresets/libx264-veryfast_firstpass.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=2
-me_range=16
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=1
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=3
-refs=1
-directpred=1
-trellis=0
-flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip
-wpredp=0
-rc_lookahead=10
diff --git a/ffpresets/libx264-veryslow.ffpreset b/ffpresets/libx264-veryslow.ffpreset
deleted file mode 100644
index 8233365..0000000
--- a/ffpresets/libx264-veryslow.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=+parti8x8+parti4x4+partp8x8+partp4x4+partb8x8
-me_method=umh
-subq=10
-me_range=24
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=2
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=8
-refs=16
-directpred=3
-trellis=2
-flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip
-wpredp=2
-rc_lookahead=60
diff --git a/ffpresets/libx264-veryslow_firstpass.ffpreset b/ffpresets/libx264-veryslow_firstpass.ffpreset
deleted file mode 100644
index 2bbf473..0000000
--- a/ffpresets/libx264-veryslow_firstpass.ffpreset
+++ /dev/null
@@ -1,23 +0,0 @@
-coder=1
-flags=+loop+cgop
-cmp=+chroma
-partitions=-parti8x8-parti4x4-partp8x8-partb8x8
-me_method=dia
-subq=2
-me_range=24
-g=250
-keyint_min=25
-sc_threshold=40
-i_qfactor=0.71
-b_strategy=2
-qcomp=0.6
-qmin=0
-qmax=69
-qdiff=4
-bf=8
-refs=1
-directpred=3
-trellis=0
-flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip
-wpredp=2
-rc_lookahead=60
diff --git a/ffprobe.c b/ffprobe.c
deleted file mode 100644
index cb4a4c3..0000000
--- a/ffprobe.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * ffprobe : Simple Media Prober based on the Libav libraries
- * Copyright (c) 2007-2010 Stefano Sabatini
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#include "libavformat/avformat.h"
-#include "libavcodec/avcodec.h"
-#include "libavutil/opt.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/dict.h"
-#include "libavdevice/avdevice.h"
-#include "cmdutils.h"
-
-const char program_name[] = "ffprobe";
-const int program_birth_year = 2007;
-
-static int do_show_format = 0;
-static int do_show_packets = 0;
-static int do_show_streams = 0;
-
-static int show_value_unit = 0;
-static int use_value_prefix = 0;
-static int use_byte_value_binary_prefix = 0;
-static int use_value_sexagesimal_format = 0;
-
-/* globals */
-static const OptionDef options[];
-
-/* FFprobe context */
-static const char *input_filename;
-static AVInputFormat *iformat = NULL;
-
-static const char *binary_unit_prefixes [] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" };
-static const char *decimal_unit_prefixes[] = { "", "K" , "M" , "G" , "T" , "P" };
-
-static const char *unit_second_str = "s" ;
-static const char *unit_hertz_str = "Hz" ;
-static const char *unit_byte_str = "byte" ;
-static const char *unit_bit_per_second_str = "bit/s";
-
-static char *value_string(char *buf, int buf_size, double val, const char *unit)
-{
- if (unit == unit_second_str && use_value_sexagesimal_format) {
- double secs;
- int hours, mins;
- secs = val;
- mins = (int)secs / 60;
- secs = secs - mins * 60;
- hours = mins / 60;
- mins %= 60;
- snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs);
- } else if (use_value_prefix) {
- const char *prefix_string;
- int index;
-
- if (unit == unit_byte_str && use_byte_value_binary_prefix) {
- index = (int) (log(val)/log(2)) / 10;
- index = av_clip(index, 0, FF_ARRAY_ELEMS(binary_unit_prefixes) -1);
- val /= pow(2, index*10);
- prefix_string = binary_unit_prefixes[index];
- } else {
- index = (int) (log10(val)) / 3;
- index = av_clip(index, 0, FF_ARRAY_ELEMS(decimal_unit_prefixes) -1);
- val /= pow(10, index*3);
- prefix_string = decimal_unit_prefixes[index];
- }
-
- snprintf(buf, buf_size, "%.3f %s%s", val, prefix_string, show_value_unit ? unit : "");
- } else {
- snprintf(buf, buf_size, "%f %s", val, show_value_unit ? unit : "");
- }
-
- return buf;
-}
-
-static char *time_value_string(char *buf, int buf_size, int64_t val, const AVRational *time_base)
-{
- if (val == AV_NOPTS_VALUE) {
- snprintf(buf, buf_size, "N/A");
- } else {
- value_string(buf, buf_size, val * av_q2d(*time_base), unit_second_str);
- }
-
- return buf;
-}
-
-static char *ts_value_string (char *buf, int buf_size, int64_t ts)
-{
- if (ts == AV_NOPTS_VALUE) {
- snprintf(buf, buf_size, "N/A");
- } else {
- snprintf(buf, buf_size, "%"PRId64, ts);
- }
-
- return buf;
-}
-
-static const char *media_type_string(enum AVMediaType media_type)
-{
- switch (media_type) {
- case AVMEDIA_TYPE_VIDEO: return "video";
- case AVMEDIA_TYPE_AUDIO: return "audio";
- case AVMEDIA_TYPE_DATA: return "data";
- case AVMEDIA_TYPE_SUBTITLE: return "subtitle";
- case AVMEDIA_TYPE_ATTACHMENT: return "attachment";
- default: return "unknown";
- }
-}
-
-static void show_packet(AVFormatContext *fmt_ctx, AVPacket *pkt)
-{
- char val_str[128];
- AVStream *st = fmt_ctx->streams[pkt->stream_index];
-
- printf("[PACKET]\n");
- printf("codec_type=%s\n" , media_type_string(st->codec->codec_type));
- printf("stream_index=%d\n" , pkt->stream_index);
- printf("pts=%s\n" , ts_value_string (val_str, sizeof(val_str), pkt->pts));
- printf("pts_time=%s\n" , time_value_string(val_str, sizeof(val_str), pkt->pts, &st->time_base));
- printf("dts=%s\n" , ts_value_string (val_str, sizeof(val_str), pkt->dts));
- printf("dts_time=%s\n" , time_value_string(val_str, sizeof(val_str), pkt->dts, &st->time_base));
- printf("duration=%s\n" , ts_value_string (val_str, sizeof(val_str), pkt->duration));
- printf("duration_time=%s\n", time_value_string(val_str, sizeof(val_str), pkt->duration, &st->time_base));
- printf("size=%s\n" , value_string (val_str, sizeof(val_str), pkt->size, unit_byte_str));
- printf("pos=%"PRId64"\n" , pkt->pos);
- printf("flags=%c\n" , pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_');
- printf("[/PACKET]\n");
-}
-
-static void show_packets(AVFormatContext *fmt_ctx)
-{
- AVPacket pkt;
-
- av_init_packet(&pkt);
-
- while (!av_read_frame(fmt_ctx, &pkt))
- show_packet(fmt_ctx, &pkt);
-}
-
-static void show_stream(AVFormatContext *fmt_ctx, int stream_idx)
-{
- AVStream *stream = fmt_ctx->streams[stream_idx];
- AVCodecContext *dec_ctx;
- AVCodec *dec;
- char val_str[128];
- AVDictionaryEntry *tag = NULL;
- AVRational display_aspect_ratio;
-
- printf("[STREAM]\n");
-
- printf("index=%d\n", stream->index);
-
- if ((dec_ctx = stream->codec)) {
- if ((dec = dec_ctx->codec)) {
- printf("codec_name=%s\n", dec->name);
- printf("codec_long_name=%s\n", dec->long_name);
- } else {
- printf("codec_name=unknown\n");
- }
-
- printf("codec_type=%s\n", media_type_string(dec_ctx->codec_type));
- printf("codec_time_base=%d/%d\n", dec_ctx->time_base.num, dec_ctx->time_base.den);
-
- /* print AVI/FourCC tag */
- av_get_codec_tag_string(val_str, sizeof(val_str), dec_ctx->codec_tag);
- printf("codec_tag_string=%s\n", val_str);
- printf("codec_tag=0x%04x\n", dec_ctx->codec_tag);
-
- switch (dec_ctx->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- printf("width=%d\n", dec_ctx->width);
- printf("height=%d\n", dec_ctx->height);
- printf("has_b_frames=%d\n", dec_ctx->has_b_frames);
- if (dec_ctx->sample_aspect_ratio.num) {
- printf("sample_aspect_ratio=%d:%d\n", dec_ctx->sample_aspect_ratio.num,
- dec_ctx->sample_aspect_ratio.den);
- av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
- dec_ctx->width * dec_ctx->sample_aspect_ratio.num,
- dec_ctx->height * dec_ctx->sample_aspect_ratio.den,
- 1024*1024);
- printf("display_aspect_ratio=%d:%d\n", display_aspect_ratio.num,
- display_aspect_ratio.den);
- }
- printf("pix_fmt=%s\n", dec_ctx->pix_fmt != PIX_FMT_NONE ?
- av_pix_fmt_descriptors[dec_ctx->pix_fmt].name : "unknown");
- break;
-
- case AVMEDIA_TYPE_AUDIO:
- printf("sample_rate=%s\n", value_string(val_str, sizeof(val_str),
- dec_ctx->sample_rate,
- unit_hertz_str));
- printf("channels=%d\n", dec_ctx->channels);
- printf("bits_per_sample=%d\n", av_get_bits_per_sample(dec_ctx->codec_id));
- break;
- }
- } else {
- printf("codec_type=unknown\n");
- }
-
- if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS)
- printf("id=0x%x\n", stream->id);
- printf("r_frame_rate=%d/%d\n", stream->r_frame_rate.num, stream->r_frame_rate.den);
- printf("avg_frame_rate=%d/%d\n", stream->avg_frame_rate.num, stream->avg_frame_rate.den);
- printf("time_base=%d/%d\n", stream->time_base.num, stream->time_base.den);
- printf("start_time=%s\n", time_value_string(val_str, sizeof(val_str), stream->start_time,
- &stream->time_base));
- printf("duration=%s\n", time_value_string(val_str, sizeof(val_str), stream->duration,
- &stream->time_base));
- if (stream->nb_frames)
- printf("nb_frames=%"PRId64"\n", stream->nb_frames);
-
- while ((tag = av_dict_get(stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
- printf("TAG:%s=%s\n", tag->key, tag->value);
-
- printf("[/STREAM]\n");
-}
-
-static void show_format(AVFormatContext *fmt_ctx)
-{
- AVDictionaryEntry *tag = NULL;
- char val_str[128];
-
- printf("[FORMAT]\n");
-
- printf("filename=%s\n", fmt_ctx->filename);
- printf("nb_streams=%d\n", fmt_ctx->nb_streams);
- printf("format_name=%s\n", fmt_ctx->iformat->name);
- printf("format_long_name=%s\n", fmt_ctx->iformat->long_name);
- printf("start_time=%s\n", time_value_string(val_str, sizeof(val_str), fmt_ctx->start_time,
- &AV_TIME_BASE_Q));
- printf("duration=%s\n", time_value_string(val_str, sizeof(val_str), fmt_ctx->duration,
- &AV_TIME_BASE_Q));
- printf("size=%s\n", value_string(val_str, sizeof(val_str), fmt_ctx->file_size,
- unit_byte_str));
- printf("bit_rate=%s\n", value_string(val_str, sizeof(val_str), fmt_ctx->bit_rate,
- unit_bit_per_second_str));
-
- while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
- printf("TAG:%s=%s\n", tag->key, tag->value);
-
- printf("[/FORMAT]\n");
-}
-
-static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
-{
- int err, i;
- AVFormatContext *fmt_ctx = NULL;
- AVDictionaryEntry *t;
-
- if ((err = avformat_open_input(&fmt_ctx, filename, iformat, &format_opts)) < 0) {
- print_error(filename, err);
- return err;
- }
- if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
- av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
- return AVERROR_OPTION_NOT_FOUND;
- }
-
-
- /* fill the streams in the format context */
- if ((err = av_find_stream_info(fmt_ctx)) < 0) {
- print_error(filename, err);
- return err;
- }
-
- av_dump_format(fmt_ctx, 0, filename, 0);
-
- /* bind a decoder to each input stream */
- for (i = 0; i < fmt_ctx->nb_streams; i++) {
- AVStream *stream = fmt_ctx->streams[i];
- AVCodec *codec;
-
- if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
- fprintf(stderr, "Unsupported codec with id %d for input stream %d\n",
- stream->codec->codec_id, stream->index);
- } else if (avcodec_open2(stream->codec, codec, NULL) < 0) {
- fprintf(stderr, "Error while opening codec for input stream %d\n",
- stream->index);
- }
- }
-
- *fmt_ctx_ptr = fmt_ctx;
- return 0;
-}
-
-static int probe_file(const char *filename)
-{
- AVFormatContext *fmt_ctx;
- int ret, i;
-
- if ((ret = open_input_file(&fmt_ctx, filename)))
- return ret;
-
- if (do_show_packets)
- show_packets(fmt_ctx);
-
- if (do_show_streams)
- for (i = 0; i < fmt_ctx->nb_streams; i++)
- show_stream(fmt_ctx, i);
-
- if (do_show_format)
- show_format(fmt_ctx);
-
- av_close_input_file(fmt_ctx);
- return 0;
-}
-
-static void show_usage(void)
-{
- printf("Simple multimedia streams analyzer\n");
- printf("usage: ffprobe [OPTIONS] [INPUT_FILE]\n");
- printf("\n");
-}
-
-static int opt_format(const char *opt, const char *arg)
-{
- iformat = av_find_input_format(arg);
- if (!iformat) {
- fprintf(stderr, "Unknown input format: %s\n", arg);
- return AVERROR(EINVAL);
- }
- return 0;
-}
-
-static void opt_input_file(const char *arg)
-{
- if (input_filename) {
- fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
- arg, input_filename);
- exit(1);
- }
- if (!strcmp(arg, "-"))
- arg = "pipe:";
- input_filename = arg;
-}
-
-static void show_help(void)
-{
- av_log_set_callback(log_callback_help);
- show_usage();
- show_help_options(options, "Main options:\n", 0, 0);
- printf("\n");
- av_opt_show2(avformat_opts, NULL,
- AV_OPT_FLAG_DECODING_PARAM, 0);
-}
-
-static void opt_pretty(void)
-{
- show_value_unit = 1;
- use_value_prefix = 1;
- use_byte_value_binary_prefix = 1;
- use_value_sexagesimal_format = 1;
-}
-
-static const OptionDef options[] = {
-#include "cmdutils_common_opts.h"
- { "f", HAS_ARG, {(void*)opt_format}, "force format", "format" },
- { "unit", OPT_BOOL, {(void*)&show_value_unit}, "show unit of the displayed values" },
- { "prefix", OPT_BOOL, {(void*)&use_value_prefix}, "use SI prefixes for the displayed values" },
- { "byte_binary_prefix", OPT_BOOL, {(void*)&use_byte_value_binary_prefix},
- "use binary prefixes for byte units" },
- { "sexagesimal", OPT_BOOL, {(void*)&use_value_sexagesimal_format},
- "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
- { "pretty", 0, {(void*)&opt_pretty},
- "prettify the format of displayed values, make it more human readable" },
- { "show_format", OPT_BOOL, {(void*)&do_show_format} , "show format/container info" },
- { "show_packets", OPT_BOOL, {(void*)&do_show_packets}, "show packets info" },
- { "show_streams", OPT_BOOL, {(void*)&do_show_streams}, "show streams info" },
- { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
- { NULL, },
-};
-
-int main(int argc, char **argv)
-{
- int ret;
-
- av_register_all();
- init_opts();
-#if CONFIG_AVDEVICE
- avdevice_register_all();
-#endif
-
- avformat_opts = avformat_alloc_context();
-
- show_banner();
- parse_options(argc, argv, options, opt_input_file);
-
- if (!input_filename) {
- show_usage();
- fprintf(stderr, "You have to specify one input file.\n");
- fprintf(stderr, "Use -h to get full help or, even better, run 'man ffprobe'.\n");
- exit(1);
- }
-
- ret = probe_file(input_filename);
-
- av_free(avformat_opts);
-
- return ret;
-}
diff --git a/ffserver.c b/ffserver.c
deleted file mode 100644
index 179cac4..0000000
--- a/ffserver.c
+++ /dev/null
@@ -1,4753 +0,0 @@
-/*
- * Multiple format streaming server
- * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#if !HAVE_CLOSESOCKET
-#define closesocket close
-#endif
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include "libavformat/avformat.h"
-#include "libavformat/ffm.h"
-#include "libavformat/network.h"
-#include "libavformat/os_support.h"
-#include "libavformat/rtpdec.h"
-#include "libavformat/rtsp.h"
-// XXX for ffio_open_dyn_packet_buffer, to be removed
-#include "libavformat/avio_internal.h"
-#include "libavutil/avstring.h"
-#include "libavutil/lfg.h"
-#include "libavutil/dict.h"
-#include "libavutil/random_seed.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/opt.h"
-#include <stdarg.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#if HAVE_POLL_H
-#include <poll.h>
-#endif
-#include <errno.h>
-#include <sys/time.h>
-#include <time.h>
-#include <sys/wait.h>
-#include <signal.h>
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include "cmdutils.h"
-
-const char program_name[] = "ffserver";
-const int program_birth_year = 2000;
-
-static const OptionDef options[];
-
-enum HTTPState {
- HTTPSTATE_WAIT_REQUEST,
- HTTPSTATE_SEND_HEADER,
- HTTPSTATE_SEND_DATA_HEADER,
- HTTPSTATE_SEND_DATA, /* sending TCP or UDP data */
- HTTPSTATE_SEND_DATA_TRAILER,
- HTTPSTATE_RECEIVE_DATA,
- HTTPSTATE_WAIT_FEED, /* wait for data from the feed */
- HTTPSTATE_READY,
-
- RTSPSTATE_WAIT_REQUEST,
- RTSPSTATE_SEND_REPLY,
- RTSPSTATE_SEND_PACKET,
-};
-
-static const char *http_state[] = {
- "HTTP_WAIT_REQUEST",
- "HTTP_SEND_HEADER",
-
- "SEND_DATA_HEADER",
- "SEND_DATA",
- "SEND_DATA_TRAILER",
- "RECEIVE_DATA",
- "WAIT_FEED",
- "READY",
-
- "RTSP_WAIT_REQUEST",
- "RTSP_SEND_REPLY",
- "RTSP_SEND_PACKET",
-};
-
-#define MAX_STREAMS 20
-
-#define IOBUFFER_INIT_SIZE 8192
-
-/* timeouts are in ms */
-#define HTTP_REQUEST_TIMEOUT (15 * 1000)
-#define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000)
-
-#define SYNC_TIMEOUT (10 * 1000)
-
-typedef struct RTSPActionServerSetup {
- uint32_t ipaddr;
- char transport_option[512];
-} RTSPActionServerSetup;
-
-typedef struct {
- int64_t count1, count2;
- int64_t time1, time2;
-} DataRateData;
-
-/* context associated with one connection */
-typedef struct HTTPContext {
- enum HTTPState state;
- int fd; /* socket file descriptor */
- struct sockaddr_in from_addr; /* origin */
- struct pollfd *poll_entry; /* used when polling */
- int64_t timeout;
- uint8_t *buffer_ptr, *buffer_end;
- int http_error;
- int post;
- int chunked_encoding;
- int chunk_size; /* 0 if it needs to be read */
- struct HTTPContext *next;
- int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
- int64_t data_count;
- /* feed input */
- int feed_fd;
- /* input format handling */
- AVFormatContext *fmt_in;
- int64_t start_time; /* In milliseconds - this wraps fairly often */
- int64_t first_pts; /* initial pts value */
- int64_t cur_pts; /* current pts value from the stream in us */
- int64_t cur_frame_duration; /* duration of the current frame in us */
- int cur_frame_bytes; /* output frame size, needed to compute
- the time at which we send each
- packet */
- int pts_stream_index; /* stream we choose as clock reference */
- int64_t cur_clock; /* current clock reference value in us */
- /* output format handling */
- struct FFStream *stream;
- /* -1 is invalid stream */
- int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
- int switch_feed_streams[MAX_STREAMS]; /* index of streams in the feed */
- int switch_pending;
- AVFormatContext fmt_ctx; /* instance of FFStream for one user */
- int last_packet_sent; /* true if last data packet was sent */
- int suppress_log;
- DataRateData datarate;
- int wmp_client_id;
- char protocol[16];
- char method[16];
- char url[128];
- int buffer_size;
- uint8_t *buffer;
- int is_packetized; /* if true, the stream is packetized */
- int packet_stream_index; /* current stream for output in state machine */
-
- /* RTSP state specific */
- uint8_t *pb_buffer; /* XXX: use that in all the code */
- AVIOContext *pb;
- int seq; /* RTSP sequence number */
-
- /* RTP state specific */
- enum RTSPLowerTransport rtp_protocol;
- char session_id[32]; /* session id */
- AVFormatContext *rtp_ctx[MAX_STREAMS];
-
- /* RTP/UDP specific */
- URLContext *rtp_handles[MAX_STREAMS];
-
- /* RTP/TCP specific */
- struct HTTPContext *rtsp_c;
- uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
-} HTTPContext;
-
-/* each generated stream is described here */
-enum StreamType {
- STREAM_TYPE_LIVE,
- STREAM_TYPE_STATUS,
- STREAM_TYPE_REDIRECT,
-};
-
-enum IPAddressAction {
- IP_ALLOW = 1,
- IP_DENY,
-};
-
-typedef struct IPAddressACL {
- struct IPAddressACL *next;
- enum IPAddressAction action;
- /* These are in host order */
- struct in_addr first;
- struct in_addr last;
-} IPAddressACL;
-
-/* description of each stream of the ffserver.conf file */
-typedef struct FFStream {
- enum StreamType stream_type;
- char filename[1024]; /* stream filename */
- struct FFStream *feed; /* feed we are using (can be null if
- coming from file) */
- AVDictionary *in_opts; /* input parameters */
- AVInputFormat *ifmt; /* if non NULL, force input format */
- AVOutputFormat *fmt;
- IPAddressACL *acl;
- char dynamic_acl[1024];
- int nb_streams;
- int prebuffer; /* Number of millseconds early to start */
- int64_t max_time; /* Number of milliseconds to run */
- int send_on_key;
- AVStream *streams[MAX_STREAMS];
- int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
- char feed_filename[1024]; /* file name of the feed storage, or
- input file name for a stream */
- char author[512];
- char title[512];
- char copyright[512];
- char comment[512];
- pid_t pid; /* Of ffmpeg process */
- time_t pid_start; /* Of ffmpeg process */
- char **child_argv;
- struct FFStream *next;
- unsigned bandwidth; /* bandwidth, in kbits/s */
- /* RTSP options */
- char *rtsp_option;
- /* multicast specific */
- int is_multicast;
- struct in_addr multicast_ip;
- int multicast_port; /* first port used for multicast */
- int multicast_ttl;
- int loop; /* if true, send the stream in loops (only meaningful if file) */
-
- /* feed specific */
- int feed_opened; /* true if someone is writing to the feed */
- int is_feed; /* true if it is a feed */
- int readonly; /* True if writing is prohibited to the file */
- int truncate; /* True if feeder connection truncate the feed file */
- int conns_served;
- int64_t bytes_served;
- int64_t feed_max_size; /* maximum storage size, zero means unlimited */
- int64_t feed_write_index; /* current write position in feed (it wraps around) */
- int64_t feed_size; /* current size of feed */
- struct FFStream *next_feed;
-} FFStream;
-
-typedef struct FeedData {
- long long data_count;
- float avg_frame_size; /* frame size averaged over last frames with exponential mean */
-} FeedData;
-
-static struct sockaddr_in my_http_addr;
-static struct sockaddr_in my_rtsp_addr;
-
-static char logfilename[1024];
-static HTTPContext *first_http_ctx;
-static FFStream *first_feed; /* contains only feeds */
-static FFStream *first_stream; /* contains all streams, including feeds */
-
-static void new_connection(int server_fd, int is_rtsp);
-static void close_connection(HTTPContext *c);
-
-/* HTTP handling */
-static int handle_connection(HTTPContext *c);
-static int http_parse_request(HTTPContext *c);
-static int http_send_data(HTTPContext *c);
-static void compute_status(HTTPContext *c);
-static int open_input_stream(HTTPContext *c, const char *info);
-static int http_start_receive_data(HTTPContext *c);
-static int http_receive_data(HTTPContext *c);
-
-/* RTSP handling */
-static int rtsp_parse_request(HTTPContext *c);
-static void rtsp_cmd_describe(HTTPContext *c, const char *url);
-static void rtsp_cmd_options(HTTPContext *c, const char *url);
-static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPMessageHeader *h);
-static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h);
-static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h);
-static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h);
-
-/* SDP handling */
-static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
- struct in_addr my_ip);
-
-/* RTP handling */
-static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
- FFStream *stream, const char *session_id,
- enum RTSPLowerTransport rtp_protocol);
-static int rtp_new_av_stream(HTTPContext *c,
- int stream_index, struct sockaddr_in *dest_addr,
- HTTPContext *rtsp_c);
-
-static const char *my_program_name;
-static const char *my_program_dir;
-
-static const char *config_filename = "/etc/ffserver.conf";
-
-static int ffserver_debug;
-static int ffserver_daemon;
-static int no_launch;
-static int need_to_start_children;
-
-/* maximum number of simultaneous HTTP connections */
-static unsigned int nb_max_http_connections = 2000;
-static unsigned int nb_max_connections = 5;
-static unsigned int nb_connections;
-
-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
-
-static AVLFG random_state;
-
-static FILE *logfile = NULL;
-
-/* FIXME: make ffserver work with IPv6 */
-/* resolve host with also IP address parsing */
-static int resolve_host(struct in_addr *sin_addr, const char *hostname)
-{
-
- if (!ff_inet_aton(hostname, sin_addr)) {
-#if HAVE_GETADDRINFO
- struct addrinfo *ai, *cur;
- struct addrinfo hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET;
- if (getaddrinfo(hostname, NULL, &hints, &ai))
- return -1;
- /* getaddrinfo returns a linked list of addrinfo structs.
- * Even if we set ai_family = AF_INET above, make sure
- * that the returned one actually is of the correct type. */
- for (cur = ai; cur; cur = cur->ai_next) {
- if (cur->ai_family == AF_INET) {
- *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr;
- freeaddrinfo(ai);
- return 0;
- }
- }
- freeaddrinfo(ai);
- return -1;
-#else
- struct hostent *hp;
- hp = gethostbyname(hostname);
- if (!hp)
- return -1;
- memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
-#endif
- }
- return 0;
-}
-
-static char *ctime1(char *buf2)
-{
- time_t ti;
- char *p;
-
- ti = time(NULL);
- p = ctime(&ti);
- strcpy(buf2, p);
- p = buf2 + strlen(p) - 1;
- if (*p == '\n')
- *p = '\0';
- return buf2;
-}
-
-static void http_vlog(const char *fmt, va_list vargs)
-{
- 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);
- }
-}
-
-#ifdef __GNUC__
-__attribute__ ((format (printf, 1, 2)))
-#endif
-static void 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_get_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\" %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);
-}
-
-static void update_datarate(DataRateData *drd, int64_t count)
-{
- if (!drd->time1 && !drd->count1) {
- drd->time1 = drd->time2 = cur_time;
- drd->count1 = drd->count2 = count;
- } else if (cur_time - drd->time2 > 5000) {
- drd->time1 = drd->time2;
- drd->count1 = drd->count2;
- drd->time2 = cur_time;
- drd->count2 = count;
- }
-}
-
-/* In bytes per second */
-static int compute_datarate(DataRateData *drd, int64_t count)
-{
- if (cur_time == drd->time1)
- return 0;
-
- return ((count - drd->count1) * 1000) / (cur_time - drd->time1);
-}
-
-
-static void start_children(FFStream *feed)
-{
- if (no_launch)
- return;
-
- for (; feed; feed = feed->next) {
- if (feed->child_argv && !feed->pid) {
- feed->pid_start = time(0);
-
- feed->pid = fork();
-
- if (feed->pid < 0) {
- http_log("Unable to create children\n");
- exit(1);
- }
- if (!feed->pid) {
- /* In child */
- char pathname[1024];
- char *slash;
- int i;
-
- av_strlcpy(pathname, my_program_name, sizeof(pathname));
-
- slash = strrchr(pathname, '/');
- if (!slash)
- slash = pathname;
- else
- 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);
-
- signal(SIGPIPE, SIG_DFL);
-
- execvp(pathname, feed->child_argv);
-
- _exit(1);
- }
- }
- }
-}
-
-/* open a listening socket */
-static int socket_open_listen(struct sockaddr_in *my_addr)
-{
- int server_fd, tmp;
-
- server_fd = socket(AF_INET,SOCK_STREAM,0);
- if (server_fd < 0) {
- perror ("socket");
- return -1;
- }
-
- tmp = 1;
- setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
-
- if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) {
- char bindmsg[32];
- snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port));
- perror (bindmsg);
- closesocket(server_fd);
- return -1;
- }
-
- if (listen (server_fd, 5) < 0) {
- perror ("listen");
- closesocket(server_fd);
- return -1;
- }
- ff_socket_nonblock(server_fd, 1);
-
- return server_fd;
-}
-
-/* start all multicast streams */
-static void start_multicast(void)
-{
- FFStream *stream;
- char session_id[32];
- HTTPContext *rtp_c;
- struct sockaddr_in dest_addr;
- int default_port, stream_index;
-
- default_port = 6000;
- for(stream = first_stream; stream != NULL; stream = stream->next) {
- if (stream->is_multicast) {
- /* open the RTP connection */
- snprintf(session_id, sizeof(session_id), "%08x%08x",
- av_lfg_get(&random_state), av_lfg_get(&random_state));
-
- /* choose a port if none given */
- if (stream->multicast_port == 0) {
- stream->multicast_port = default_port;
- default_port += 100;
- }
-
- dest_addr.sin_family = AF_INET;
- dest_addr.sin_addr = stream->multicast_ip;
- dest_addr.sin_port = htons(stream->multicast_port);
-
- rtp_c = rtp_new_connection(&dest_addr, stream, session_id,
- RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
- if (!rtp_c)
- continue;
-
- if (open_input_stream(rtp_c, "") < 0) {
- http_log("Could not open input stream for stream '%s'\n",
- stream->filename);
- continue;
- }
-
- /* open each RTP stream */
- for(stream_index = 0; stream_index < stream->nb_streams;
- stream_index++) {
- dest_addr.sin_port = htons(stream->multicast_port +
- 2 * stream_index);
- if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, NULL) < 0) {
- http_log("Could not open output stream '%s/streamid=%d'\n",
- stream->filename, stream_index);
- exit(1);
- }
- }
-
- /* change state to send data */
- rtp_c->state = HTTPSTATE_SEND_DATA;
- }
- }
-}
-
-/* main loop of the http server */
-static int http_server(void)
-{
- int server_fd = 0, rtsp_server_fd = 0;
- int ret, delay, delay1;
- struct pollfd *poll_table, *poll_entry;
- HTTPContext *c, *c_next;
-
- if(!(poll_table = av_mallocz((nb_max_http_connections + 2)*sizeof(*poll_table)))) {
- http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections);
- 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;
- }
-
- if (!rtsp_server_fd && !server_fd) {
- http_log("HTTP and RTSP disabled.\n");
- return -1;
- }
-
- http_log("FFserver started.\n");
-
- start_children(first_feed);
-
- start_multicast();
-
- for(;;) {
- poll_entry = poll_table;
- 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;
- delay = 1000;
- while (c != NULL) {
- int fd;
- fd = c->fd;
- switch(c->state) {
- case HTTPSTATE_SEND_HEADER:
- case RTSPSTATE_SEND_REPLY:
- case RTSPSTATE_SEND_PACKET:
- c->poll_entry = poll_entry;
- poll_entry->fd = fd;
- poll_entry->events = POLLOUT;
- poll_entry++;
- break;
- case HTTPSTATE_SEND_DATA_HEADER:
- case HTTPSTATE_SEND_DATA:
- case HTTPSTATE_SEND_DATA_TRAILER:
- if (!c->is_packetized) {
- /* for TCP, we output as much as we can (may need to put a limit) */
- c->poll_entry = poll_entry;
- poll_entry->fd = fd;
- poll_entry->events = POLLOUT;
- poll_entry++;
- } else {
- /* when ffserver is doing the timing, we work by
- looking at which packet need to be sent every
- 10 ms */
- delay1 = 10; /* one tick wait XXX: 10 ms assumed */
- if (delay1 < delay)
- delay = delay1;
- }
- break;
- case HTTPSTATE_WAIT_REQUEST:
- case HTTPSTATE_RECEIVE_DATA:
- case HTTPSTATE_WAIT_FEED:
- case RTSPSTATE_WAIT_REQUEST:
- /* need to catch errors */
- c->poll_entry = poll_entry;
- poll_entry->fd = fd;
- poll_entry->events = POLLIN;/* Maybe this will work */
- poll_entry++;
- break;
- default:
- c->poll_entry = NULL;
- break;
- }
- c = c->next;
- }
-
- /* wait for an event on one connection. We poll at least every
- second to handle timeouts */
- do {
- ret = poll(poll_table, poll_entry - poll_table, delay);
- if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) &&
- ff_neterrno() != AVERROR(EINTR))
- return -1;
- } while (ret < 0);
-
- cur_time = av_gettime() / 1000;
-
- if (need_to_start_children) {
- need_to_start_children = 0;
- start_children(first_feed);
- }
-
- /* now handle the events */
- for(c = first_http_ctx; c != NULL; c = c_next) {
- c_next = c->next;
- if (handle_connection(c) < 0) {
- /* close and free the connection */
- log_connection(c);
- close_connection(c);
- }
- }
-
- poll_entry = poll_table;
- 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);
- }
- }
-}
-
-/* start waiting for a new HTTP/RTSP request */
-static void start_wait_request(HTTPContext *c, int is_rtsp)
-{
- c->buffer_ptr = c->buffer;
- c->buffer_end = c->buffer + c->buffer_size - 1; /* leave room for '\0' */
-
- if (is_rtsp) {
- c->timeout = cur_time + RTSP_REQUEST_TIMEOUT;
- c->state = RTSPSTATE_WAIT_REQUEST;
- } else {
- c->timeout = cur_time + HTTP_REQUEST_TIMEOUT;
- c->state = HTTPSTATE_WAIT_REQUEST;
- }
-}
-
-static void http_send_too_busy_reply(int fd)
-{
- char buffer[300];
- int len = snprintf(buffer, sizeof(buffer),
- "HTTP/1.0 503 Server too busy\r\n"
- "Content-type: text/html\r\n"
- "\r\n"
- "<html><head><title>Too busy</title></head><body>\r\n"
- "<p>The server is too busy to serve your request at this time.</p>\r\n"
- "<p>The number of current connections is %d, and this exceeds the limit of %d.</p>\r\n"
- "</body></html>\r\n",
- nb_connections, nb_max_connections);
- send(fd, buffer, len, 0);
-}
-
-
-static void new_connection(int server_fd, int is_rtsp)
-{
- struct sockaddr_in from_addr;
- int fd, len;
- HTTPContext *c = NULL;
-
- len = sizeof(from_addr);
- fd = accept(server_fd, (struct sockaddr *)&from_addr,
- &len);
- if (fd < 0) {
- http_log("error during accept %s\n", strerror(errno));
- return;
- }
- ff_socket_nonblock(fd, 1);
-
- if (nb_connections >= nb_max_connections) {
- http_send_too_busy_reply(fd);
- goto fail;
- }
-
- /* add a new connection */
- c = av_mallocz(sizeof(HTTPContext));
- if (!c)
- goto fail;
-
- c->fd = fd;
- c->poll_entry = NULL;
- c->from_addr = from_addr;
- c->buffer_size = IOBUFFER_INIT_SIZE;
- c->buffer = av_malloc(c->buffer_size);
- if (!c->buffer)
- goto fail;
-
- c->next = first_http_ctx;
- first_http_ctx = c;
- nb_connections++;
-
- start_wait_request(c, is_rtsp);
-
- return;
-
- fail:
- if (c) {
- av_free(c->buffer);
- av_free(c);
- }
- closesocket(fd);
-}
-
-static void close_connection(HTTPContext *c)
-{
- HTTPContext **cp, *c1;
- int i, nb_streams;
- AVFormatContext *ctx;
- URLContext *h;
- AVStream *st;
-
- /* remove connection from list */
- cp = &first_http_ctx;
- while ((*cp) != NULL) {
- c1 = *cp;
- if (c1 == c)
- *cp = c->next;
- else
- cp = &c1->next;
- }
-
- /* remove references, if any (XXX: do it faster) */
- for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
- if (c1->rtsp_c == c)
- c1->rtsp_c = NULL;
- }
-
- /* remove connection associated resources */
- if (c->fd >= 0)
- closesocket(c->fd);
- if (c->fmt_in) {
- /* close each frame parser */
- for(i=0;i<c->fmt_in->nb_streams;i++) {
- st = c->fmt_in->streams[i];
- if (st->codec->codec)
- avcodec_close(st->codec);
- }
- av_close_input_file(c->fmt_in);
- }
-
- /* free RTP output streams if any */
- nb_streams = 0;
- if (c->stream)
- nb_streams = c->stream->nb_streams;
-
- for(i=0;i<nb_streams;i++) {
- ctx = c->rtp_ctx[i];
- if (ctx) {
- av_write_trailer(ctx);
- av_dict_free(&ctx->metadata);
- av_free(ctx->streams[0]);
- av_free(ctx);
- }
- h = c->rtp_handles[i];
- if (h)
- url_close(h);
- }
-
- ctx = &c->fmt_ctx;
-
- if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
- if (ctx->oformat) {
- /* prepare header */
- if (avio_open_dyn_buf(&ctx->pb) >= 0) {
- av_write_trailer(ctx);
- av_freep(&c->pb_buffer);
- avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
- }
- }
- }
-
- for(i=0; i<ctx->nb_streams; i++)
- av_free(ctx->streams[i]);
-
- if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
- current_bandwidth -= c->stream->bandwidth;
-
- /* signal that there is no feed if we are the feeder socket */
- if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
- c->stream->feed_opened = 0;
- close(c->feed_fd);
- }
-
- av_freep(&c->pb_buffer);
- av_freep(&c->packet_buffer);
- av_free(c->buffer);
- av_free(c);
- nb_connections--;
-}
-
-static int handle_connection(HTTPContext *c)
-{
- int len, ret;
-
- switch(c->state) {
- case HTTPSTATE_WAIT_REQUEST:
- case RTSPSTATE_WAIT_REQUEST:
- /* timeout ? */
- if ((c->timeout - cur_time) < 0)
- return -1;
- if (c->poll_entry->revents & (POLLERR | POLLHUP))
- return -1;
-
- /* no need to read if no events */
- if (!(c->poll_entry->revents & POLLIN))
- return 0;
- /* read the data */
- read_loop:
- len = recv(c->fd, c->buffer_ptr, 1, 0);
- if (len < 0) {
- if (ff_neterrno() != AVERROR(EAGAIN) &&
- ff_neterrno() != AVERROR(EINTR))
- return -1;
- } else if (len == 0) {
- return -1;
- } else {
- /* search for end of request. */
- uint8_t *ptr;
- c->buffer_ptr += len;
- ptr = c->buffer_ptr;
- if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
- (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
- /* request found : parse it and reply */
- if (c->state == HTTPSTATE_WAIT_REQUEST) {
- ret = http_parse_request(c);
- } else {
- ret = rtsp_parse_request(c);
- }
- if (ret < 0)
- return -1;
- } else if (ptr >= c->buffer_end) {
- /* request too long: cannot do anything */
- return -1;
- } else goto read_loop;
- }
- break;
-
- case HTTPSTATE_SEND_HEADER:
- if (c->poll_entry->revents & (POLLERR | POLLHUP))
- return -1;
-
- /* no need to write if no events */
- if (!(c->poll_entry->revents & POLLOUT))
- return 0;
- len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
- if (len < 0) {
- if (ff_neterrno() != AVERROR(EAGAIN) &&
- ff_neterrno() != AVERROR(EINTR)) {
- /* error : close connection */
- av_freep(&c->pb_buffer);
- return -1;
- }
- } else {
- c->buffer_ptr += len;
- if (c->stream)
- c->stream->bytes_served += len;
- c->data_count += len;
- if (c->buffer_ptr >= c->buffer_end) {
- av_freep(&c->pb_buffer);
- /* if error, exit */
- if (c->http_error)
- return -1;
- /* all the buffer was sent : synchronize to the incoming stream */
- c->state = HTTPSTATE_SEND_DATA_HEADER;
- c->buffer_ptr = c->buffer_end = c->buffer;
- }
- }
- break;
-
- case HTTPSTATE_SEND_DATA:
- case HTTPSTATE_SEND_DATA_HEADER:
- case HTTPSTATE_SEND_DATA_TRAILER:
- /* for packetized output, we consider we can always write (the
- input streams sets the speed). It may be better to verify
- that we do not rely too much on the kernel queues */
- if (!c->is_packetized) {
- if (c->poll_entry->revents & (POLLERR | POLLHUP))
- return -1;
-
- /* no need to read if no events */
- if (!(c->poll_entry->revents & POLLOUT))
- return 0;
- }
- if (http_send_data(c) < 0)
- return -1;
- /* close connection if trailer sent */
- if (c->state == HTTPSTATE_SEND_DATA_TRAILER)
- return -1;
- break;
- case HTTPSTATE_RECEIVE_DATA:
- /* no need to read if no events */
- if (c->poll_entry->revents & (POLLERR | POLLHUP))
- return -1;
- if (!(c->poll_entry->revents & POLLIN))
- return 0;
- if (http_receive_data(c) < 0)
- return -1;
- break;
- case HTTPSTATE_WAIT_FEED:
- /* no need to read if no events */
- if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP))
- return -1;
-
- /* nothing to do, we'll be waken up by incoming feed packets */
- break;
-
- case RTSPSTATE_SEND_REPLY:
- if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
- av_freep(&c->pb_buffer);
- return -1;
- }
- /* no need to write if no events */
- if (!(c->poll_entry->revents & POLLOUT))
- return 0;
- len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
- if (len < 0) {
- if (ff_neterrno() != AVERROR(EAGAIN) &&
- ff_neterrno() != AVERROR(EINTR)) {
- /* error : close connection */
- av_freep(&c->pb_buffer);
- return -1;
- }
- } else {
- c->buffer_ptr += len;
- c->data_count += len;
- if (c->buffer_ptr >= c->buffer_end) {
- /* all the buffer was sent : wait for a new request */
- av_freep(&c->pb_buffer);
- start_wait_request(c, 1);
- }
- }
- break;
- case RTSPSTATE_SEND_PACKET:
- if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
- av_freep(&c->packet_buffer);
- return -1;
- }
- /* no need to write if no events */
- if (!(c->poll_entry->revents & POLLOUT))
- return 0;
- len = send(c->fd, c->packet_buffer_ptr,
- c->packet_buffer_end - c->packet_buffer_ptr, 0);
- if (len < 0) {
- if (ff_neterrno() != AVERROR(EAGAIN) &&
- ff_neterrno() != AVERROR(EINTR)) {
- /* error : close connection */
- av_freep(&c->packet_buffer);
- return -1;
- }
- } else {
- c->packet_buffer_ptr += len;
- if (c->packet_buffer_ptr >= c->packet_buffer_end) {
- /* all the buffer was sent : wait for a new request */
- av_freep(&c->packet_buffer);
- c->state = RTSPSTATE_WAIT_REQUEST;
- }
- }
- break;
- case HTTPSTATE_READY:
- /* nothing to do */
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-static int extract_rates(char *rates, int ratelen, const char *request)
-{
- const char *p;
-
- for (p = request; *p && *p != '\r' && *p != '\n'; ) {
- if (strncasecmp(p, "Pragma:", 7) == 0) {
- const char *q = p + 7;
-
- while (*q && *q != '\n' && isspace(*q))
- q++;
-
- if (strncasecmp(q, "stream-switch-entry=", 20) == 0) {
- int stream_no;
- int rate_no;
-
- q += 20;
-
- memset(rates, 0xff, ratelen);
-
- while (1) {
- while (*q && *q != '\n' && *q != ':')
- q++;
-
- if (sscanf(q, ":%d:%d", &stream_no, &rate_no) != 2)
- break;
-
- stream_no--;
- if (stream_no < ratelen && stream_no >= 0)
- rates[stream_no] = rate_no;
-
- while (*q && *q != '\n' && !isspace(*q))
- q++;
- }
-
- return 1;
- }
- }
- p = strchr(p, '\n');
- if (!p)
- break;
-
- p++;
- }
-
- return 0;
-}
-
-static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_rate)
-{
- int i;
- int best_bitrate = 100000000;
- int best = -1;
-
- for (i = 0; i < feed->nb_streams; i++) {
- AVCodecContext *feed_codec = feed->streams[i]->codec;
-
- if (feed_codec->codec_id != codec->codec_id ||
- feed_codec->sample_rate != codec->sample_rate ||
- feed_codec->width != codec->width ||
- feed_codec->height != codec->height)
- continue;
-
- /* Potential stream */
-
- /* We want the fastest stream less than bit_rate, or the slowest
- * faster than bit_rate
- */
-
- if (feed_codec->bit_rate <= bit_rate) {
- if (best_bitrate > bit_rate || feed_codec->bit_rate > best_bitrate) {
- best_bitrate = feed_codec->bit_rate;
- best = i;
- }
- } else {
- if (feed_codec->bit_rate < best_bitrate) {
- best_bitrate = feed_codec->bit_rate;
- best = i;
- }
- }
- }
-
- return best;
-}
-
-static int modify_current_stream(HTTPContext *c, char *rates)
-{
- int i;
- FFStream *req = c->stream;
- int action_required = 0;
-
- /* Not much we can do for a feed */
- if (!req->feed)
- return 0;
-
- for (i = 0; i < req->nb_streams; i++) {
- AVCodecContext *codec = req->streams[i]->codec;
-
- switch(rates[i]) {
- case 0:
- c->switch_feed_streams[i] = req->feed_streams[i];
- break;
- case 1:
- c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 2);
- break;
- case 2:
- /* Wants off or slow */
- c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 4);
-#ifdef WANTS_OFF
- /* This doesn't work well when it turns off the only stream! */
- c->switch_feed_streams[i] = -2;
- c->feed_streams[i] = -2;
-#endif
- break;
- }
-
- if (c->switch_feed_streams[i] >= 0 && c->switch_feed_streams[i] != c->feed_streams[i])
- action_required = 1;
- }
-
- return action_required;
-}
-
-/* XXX: factorize in utils.c ? */
-/* XXX: take care with different space meaning */
-static void skip_spaces(const char **pp)
-{
- const char *p;
- p = *pp;
- while (*p == ' ' || *p == '\t')
- p++;
- *pp = p;
-}
-
-static void get_word(char *buf, int buf_size, const char **pp)
-{
- const char *p;
- char *q;
-
- p = *pp;
- skip_spaces(&p);
- q = buf;
- while (!isspace(*p) && *p != '\0') {
- if ((q - buf) < buf_size - 1)
- *q++ = *p;
- p++;
- }
- if (buf_size > 0)
- *q = '\0';
- *pp = p;
-}
-
-static void get_arg(char *buf, int buf_size, const char **pp)
-{
- const char *p;
- char *q;
- int quote;
-
- p = *pp;
- while (isspace(*p)) p++;
- q = buf;
- quote = 0;
- if (*p == '\"' || *p == '\'')
- quote = *p++;
- for(;;) {
- if (quote) {
- if (*p == quote)
- break;
- } else {
- if (isspace(*p))
- break;
- }
- if (*p == '\0')
- break;
- if ((q - buf) < buf_size - 1)
- *q++ = *p;
- p++;
- }
- *q = '\0';
- if (quote && *p == quote)
- p++;
- *pp = p;
-}
-
-static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl,
- const char *p, const char *filename, int line_num)
-{
- char arg[1024];
- IPAddressACL acl;
- int errors = 0;
-
- get_arg(arg, sizeof(arg), &p);
- if (strcasecmp(arg, "allow") == 0)
- acl.action = IP_ALLOW;
- else if (strcasecmp(arg, "deny") == 0)
- acl.action = IP_DENY;
- else {
- fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
- filename, line_num, arg);
- errors++;
- }
-
- get_arg(arg, sizeof(arg), &p);
-
- if (resolve_host(&acl.first, arg) != 0) {
- fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
- filename, line_num, arg);
- errors++;
- } else
- acl.last = acl.first;
-
- get_arg(arg, sizeof(arg), &p);
-
- if (arg[0]) {
- if (resolve_host(&acl.last, arg) != 0) {
- fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
- filename, line_num, arg);
- errors++;
- }
- }
-
- if (!errors) {
- IPAddressACL *nacl = av_mallocz(sizeof(*nacl));
- IPAddressACL **naclp = 0;
-
- acl.next = 0;
- *nacl = acl;
-
- if (stream)
- naclp = &stream->acl;
- else if (feed)
- naclp = &feed->acl;
- else if (ext_acl)
- naclp = &ext_acl;
- else {
- fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
- filename, line_num);
- errors++;
- }
-
- if (naclp) {
- while (*naclp)
- naclp = &(*naclp)->next;
-
- *naclp = nacl;
- }
- }
-}
-
-
-static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
-{
- FILE* f;
- char line[1024];
- char cmd[1024];
- IPAddressACL *acl = NULL;
- int line_num = 0;
- const char *p;
-
- f = fopen(stream->dynamic_acl, "r");
- if (!f) {
- perror(stream->dynamic_acl);
- return NULL;
- }
-
- acl = av_mallocz(sizeof(IPAddressACL));
-
- /* Build ACL */
- for(;;) {
- if (fgets(line, sizeof(line), f) == NULL)
- break;
- line_num++;
- p = line;
- while (isspace(*p))
- p++;
- if (*p == '\0' || *p == '#')
- continue;
- get_arg(cmd, sizeof(cmd), &p);
-
- if (!strcasecmp(cmd, "ACL"))
- parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
- }
- fclose(f);
- return acl;
-}
-
-
-static void free_acl_list(IPAddressACL *in_acl)
-{
- IPAddressACL *pacl,*pacl2;
-
- pacl = in_acl;
- while(pacl) {
- pacl2 = pacl;
- pacl = pacl->next;
- av_freep(pacl2);
- }
-}
-
-static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c)
-{
- enum IPAddressAction last_action = IP_DENY;
- IPAddressACL *acl;
- struct in_addr *src = &c->from_addr.sin_addr;
- unsigned long src_addr = src->s_addr;
-
- for (acl = in_acl; acl; acl = acl->next) {
- if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr)
- return (acl->action == IP_ALLOW) ? 1 : 0;
- last_action = acl->action;
- }
-
- /* Nothing matched, so return not the last action */
- return (last_action == IP_DENY) ? 1 : 0;
-}
-
-static int validate_acl(FFStream *stream, HTTPContext *c)
-{
- int ret = 0;
- IPAddressACL *acl;
-
-
- /* if stream->acl is null validate_acl_list will return 1 */
- ret = validate_acl_list(stream->acl, c);
-
- if (stream->dynamic_acl[0]) {
- acl = parse_dynamic_acl(stream, c);
-
- ret = validate_acl_list(acl, c);
-
- free_acl_list(acl);
- }
-
- return ret;
-}
-
-/* compute the real filename of a file by matching it without its
- extensions to all the stream filenames */
-static void compute_real_filename(char *filename, int max_size)
-{
- char file1[1024];
- char file2[1024];
- char *p;
- FFStream *stream;
-
- /* compute filename by matching without the file extensions */
- av_strlcpy(file1, filename, sizeof(file1));
- p = strrchr(file1, '.');
- if (p)
- *p = '\0';
- for(stream = first_stream; stream != NULL; stream = stream->next) {
- av_strlcpy(file2, stream->filename, sizeof(file2));
- p = strrchr(file2, '.');
- if (p)
- *p = '\0';
- if (!strcmp(file1, file2)) {
- av_strlcpy(filename, stream->filename, max_size);
- break;
- }
- }
-}
-
-enum RedirType {
- REDIR_NONE,
- REDIR_ASX,
- REDIR_RAM,
- REDIR_ASF,
- REDIR_RTSP,
- REDIR_SDP,
-};
-
-/* parse http request and prepare header */
-static int http_parse_request(HTTPContext *c)
-{
- char *p;
- enum RedirType redir_type;
- char cmd[32];
- char info[1024], filename[1024];
- char url[1024], *q;
- char protocol[32];
- char msg[1024];
- const char *mime_type;
- FFStream *stream;
- int i;
- char ratebuf[32];
- char *useragent = 0;
-
- p = c->buffer;
- get_word(cmd, sizeof(cmd), (const char **)&p);
- av_strlcpy(c->method, cmd, sizeof(c->method));
-
- if (!strcmp(cmd, "GET"))
- c->post = 0;
- else if (!strcmp(cmd, "POST"))
- c->post = 1;
- else
- return -1;
-
- get_word(url, sizeof(url), (const char **)&p);
- av_strlcpy(c->url, url, sizeof(c->url));
-
- get_word(protocol, sizeof(protocol), (const char **)&p);
- if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1"))
- return -1;
-
- av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
-
- if (ffserver_debug)
- http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url);
-
- /* find the filename and the optional info string in the request */
- p = strchr(url, '?');
- if (p) {
- av_strlcpy(info, p, sizeof(info));
- *p = '\0';
- } else
- info[0] = '\0';
-
- av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
-
- for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
- if (strncasecmp(p, "User-Agent:", 11) == 0) {
- useragent = p + 11;
- if (*useragent && *useragent != '\n' && isspace(*useragent))
- useragent++;
- break;
- }
- p = strchr(p, '\n');
- if (!p)
- break;
-
- p++;
- }
-
- redir_type = REDIR_NONE;
- if (av_match_ext(filename, "asx")) {
- redir_type = REDIR_ASX;
- filename[strlen(filename)-1] = 'f';
- } else if (av_match_ext(filename, "asf") &&
- (!useragent || strncasecmp(useragent, "NSPlayer", 8) != 0)) {
- /* if this isn't WMP or lookalike, return the redirector file */
- redir_type = REDIR_ASF;
- } else if (av_match_ext(filename, "rpm,ram")) {
- redir_type = REDIR_RAM;
- strcpy(filename + strlen(filename)-2, "m");
- } else if (av_match_ext(filename, "rtsp")) {
- redir_type = REDIR_RTSP;
- compute_real_filename(filename, sizeof(filename) - 1);
- } else if (av_match_ext(filename, "sdp")) {
- redir_type = REDIR_SDP;
- compute_real_filename(filename, sizeof(filename) - 1);
- }
-
- // "redirect" / request to index.html
- if (!strlen(filename))
- av_strlcpy(filename, "index.html", sizeof(filename) - 1);
-
- stream = first_stream;
- while (stream != NULL) {
- if (!strcmp(stream->filename, filename) && validate_acl(stream, c))
- break;
- stream = stream->next;
- }
- if (stream == NULL) {
- snprintf(msg, sizeof(msg), "File '%s' not found", url);
- http_log("File '%s' not found\n", url);
- goto send_error;
- }
-
- c->stream = stream;
- memcpy(c->feed_streams, stream->feed_streams, sizeof(c->feed_streams));
- memset(c->switch_feed_streams, -1, sizeof(c->switch_feed_streams));
-
- if (stream->stream_type == STREAM_TYPE_REDIRECT) {
- c->http_error = 301;
- q = c->buffer;
- q += snprintf(q, c->buffer_size,
- "HTTP/1.0 301 Moved\r\n"
- "Location: %s\r\n"
- "Content-type: text/html\r\n"
- "\r\n"
- "<html><head><title>Moved</title></head><body>\r\n"
- "You should be <a href=\"%s\">redirected</a>.\r\n"
- "</body></html>\r\n", stream->feed_filename, stream->feed_filename);
- /* prepare output buffer */
- c->buffer_ptr = c->buffer;
- c->buffer_end = q;
- c->state = HTTPSTATE_SEND_HEADER;
- return 0;
- }
-
- /* If this is WMP, get the rate information */
- if (extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
- if (modify_current_stream(c, ratebuf)) {
- for (i = 0; i < FF_ARRAY_ELEMS(c->feed_streams); i++) {
- if (c->switch_feed_streams[i] >= 0)
- c->switch_feed_streams[i] = -1;
- }
- }
- }
-
- if (c->post == 0 && stream->stream_type == STREAM_TYPE_LIVE)
- current_bandwidth += stream->bandwidth;
-
- /* 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;
- }
-
- if (c->post == 0 && max_bandwidth < current_bandwidth) {
- c->http_error = 503;
- q = c->buffer;
- q += snprintf(q, c->buffer_size,
- "HTTP/1.0 503 Server too busy\r\n"
- "Content-type: text/html\r\n"
- "\r\n"
- "<html><head><title>Too busy</title></head><body>\r\n"
- "<p>The server is too busy to serve your request at this time.</p>\r\n"
- "<p>The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, "
- "and this exceeds the limit of %"PRIu64"kbit/sec.</p>\r\n"
- "</body></html>\r\n", current_bandwidth, max_bandwidth);
- /* prepare output buffer */
- c->buffer_ptr = c->buffer;
- c->buffer_end = q;
- c->state = HTTPSTATE_SEND_HEADER;
- return 0;
- }
-
- if (redir_type != REDIR_NONE) {
- char *hostinfo = 0;
-
- for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
- if (strncasecmp(p, "Host:", 5) == 0) {
- hostinfo = p + 5;
- break;
- }
- p = strchr(p, '\n');
- if (!p)
- break;
-
- p++;
- }
-
- if (hostinfo) {
- char *eoh;
- char hostbuf[260];
-
- while (isspace(*hostinfo))
- hostinfo++;
-
- eoh = strchr(hostinfo, '\n');
- if (eoh) {
- if (eoh[-1] == '\r')
- eoh--;
-
- if (eoh - hostinfo < sizeof(hostbuf) - 1) {
- memcpy(hostbuf, hostinfo, eoh - hostinfo);
- hostbuf[eoh - hostinfo] = 0;
-
- c->http_error = 200;
- q = c->buffer;
- switch(redir_type) {
- case REDIR_ASX:
- q += snprintf(q, c->buffer_size,
- "HTTP/1.0 200 ASX Follows\r\n"
- "Content-type: video/x-ms-asf\r\n"
- "\r\n"
- "<ASX Version=\"3\">\r\n"
- //"<!-- Autogenerated by ffserver -->\r\n"
- "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n"
- "</ASX>\r\n", hostbuf, filename, info);
- break;
- case REDIR_RAM:
- q += snprintf(q, c->buffer_size,
- "HTTP/1.0 200 RAM Follows\r\n"
- "Content-type: audio/x-pn-realaudio\r\n"
- "\r\n"
- "# Autogenerated by ffserver\r\n"
- "http://%s/%s%s\r\n", hostbuf, filename, info);
- break;
- case REDIR_ASF:
- q += snprintf(q, c->buffer_size,
- "HTTP/1.0 200 ASF Redirect follows\r\n"
- "Content-type: video/x-ms-asf\r\n"
- "\r\n"
- "[Reference]\r\n"
- "Ref1=http://%s/%s%s\r\n", hostbuf, filename, info);
- break;
- case REDIR_RTSP:
- {
- char hostname[256], *p;
- /* extract only hostname */
- av_strlcpy(hostname, hostbuf, sizeof(hostname));
- p = strrchr(hostname, ':');
- if (p)
- *p = '\0';
- q += snprintf(q, c->buffer_size,
- "HTTP/1.0 200 RTSP Redirect follows\r\n"
- /* XXX: incorrect mime type ? */
- "Content-type: application/x-rtsp\r\n"
- "\r\n"
- "rtsp://%s:%d/%s\r\n", hostname, ntohs(my_rtsp_addr.sin_port), filename);
- }
- break;
- case REDIR_SDP:
- {
- uint8_t *sdp_data;
- int sdp_data_size, len;
- struct sockaddr_in my_addr;
-
- q += snprintf(q, c->buffer_size,
- "HTTP/1.0 200 OK\r\n"
- "Content-type: application/sdp\r\n"
- "\r\n");
-
- len = sizeof(my_addr);
- getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
-
- /* XXX: should use a dynamic buffer */
- sdp_data_size = prepare_sdp_description(stream,
- &sdp_data,
- my_addr.sin_addr);
- if (sdp_data_size > 0) {
- memcpy(q, sdp_data, sdp_data_size);
- q += sdp_data_size;
- *q = '\0';
- av_free(sdp_data);
- }
- }
- break;
- default:
- abort();
- break;
- }
-
- /* prepare output buffer */
- c->buffer_ptr = c->buffer;
- c->buffer_end = q;
- c->state = HTTPSTATE_SEND_HEADER;
- return 0;
- }
- }
- }
-
- snprintf(msg, sizeof(msg), "ASX/RAM file not handled");
- goto send_error;
- }
-
- stream->conns_served++;
-
- /* XXX: add there authenticate and IP match */
-
- if (c->post) {
- /* if post, it means a feed is being sent */
- if (!stream->is_feed) {
- /* However it might be a status report from WMP! Let us log the
- * data as it might come in handy one day. */
- char *logline = 0;
- int client_id = 0;
-
- for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
- if (strncasecmp(p, "Pragma: log-line=", 17) == 0) {
- logline = p;
- break;
- }
- if (strncasecmp(p, "Pragma: client-id=", 18) == 0)
- client_id = strtol(p + 18, 0, 10);
- p = strchr(p, '\n');
- if (!p)
- break;
-
- p++;
- }
-
- if (logline) {
- char *eol = strchr(logline, '\n');
-
- logline += 17;
-
- if (eol) {
- if (eol[-1] == '\r')
- eol--;
- http_log("%.*s\n", (int) (eol - logline), logline);
- c->suppress_log = 1;
- }
- }
-
-#ifdef DEBUG
- http_log("\nGot request:\n%s\n", c->buffer);
-#endif
-
- if (client_id && extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
- HTTPContext *wmpc;
-
- /* Now we have to find the client_id */
- for (wmpc = first_http_ctx; wmpc; wmpc = wmpc->next) {
- if (wmpc->wmp_client_id == client_id)
- break;
- }
-
- if (wmpc && modify_current_stream(wmpc, ratebuf))
- wmpc->switch_pending = 1;
- }
-
- snprintf(msg, sizeof(msg), "POST command not handled");
- c->stream = 0;
- goto send_error;
- }
- if (http_start_receive_data(c) < 0) {
- snprintf(msg, sizeof(msg), "could not open feed");
- goto send_error;
- }
- c->http_error = 0;
- c->state = HTTPSTATE_RECEIVE_DATA;
- return 0;
- }
-
-#ifdef DEBUG
- if (strcmp(stream->filename + strlen(stream->filename) - 4, ".asf") == 0)
- http_log("\nGot request:\n%s\n", c->buffer);
-#endif
-
- if (c->stream->stream_type == STREAM_TYPE_STATUS)
- goto send_status;
-
- /* open input stream */
- if (open_input_stream(c, info) < 0) {
- snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url);
- goto send_error;
- }
-
- /* prepare http header */
- q = c->buffer;
- q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n");
- mime_type = c->stream->fmt->mime_type;
- if (!mime_type)
- mime_type = "application/x-octet-stream";
- q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Pragma: no-cache\r\n");
-
- /* for asf, we need extra headers */
- if (!strcmp(c->stream->fmt->name,"asf_stream")) {
- /* Need to allocate a client id */
-
- c->wmp_client_id = av_lfg_get(&random_state);
-
- q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id);
- }
- q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-Type: %s\r\n", mime_type);
- q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
-
- /* prepare output buffer */
- c->http_error = 0;
- c->buffer_ptr = c->buffer;
- c->buffer_end = q;
- c->state = HTTPSTATE_SEND_HEADER;
- return 0;
- send_error:
- c->http_error = 404;
- q = c->buffer;
- q += snprintf(q, c->buffer_size,
- "HTTP/1.0 404 Not Found\r\n"
- "Content-type: text/html\r\n"
- "\r\n"
- "<html>\n"
- "<head><title>404 Not Found</title></head>\n"
- "<body>%s</body>\n"
- "</html>\n", msg);
- /* prepare output buffer */
- c->buffer_ptr = c->buffer;
- c->buffer_end = q;
- c->state = HTTPSTATE_SEND_HEADER;
- return 0;
- send_status:
- compute_status(c);
- c->http_error = 200; /* horrible : we use this value to avoid
- going to the send data state */
- c->state = HTTPSTATE_SEND_HEADER;
- return 0;
-}
-
-static void fmt_bytecount(AVIOContext *pb, int64_t count)
-{
- static const char *suffix = " kMGTP";
- const char *s;
-
- for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++);
-
- avio_printf(pb, "%"PRId64"%c", count, *s);
-}
-
-static void compute_status(HTTPContext *c)
-{
- HTTPContext *c1;
- FFStream *stream;
- char *p;
- time_t ti;
- int i, len;
- AVIOContext *pb;
-
- if (avio_open_dyn_buf(&pb) < 0) {
- /* XXX: return an error ? */
- c->buffer_ptr = c->buffer;
- c->buffer_end = c->buffer;
- return;
- }
-
- avio_printf(pb, "HTTP/1.0 200 OK\r\n");
- avio_printf(pb, "Content-type: %s\r\n", "text/html");
- avio_printf(pb, "Pragma: no-cache\r\n");
- avio_printf(pb, "\r\n");
-
- avio_printf(pb, "<html><head><title>%s Status</title>\n", program_name);
- if (c->stream->feed_filename[0])
- avio_printf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);
- avio_printf(pb, "</head>\n<body>");
- avio_printf(pb, "<h1>%s Status</h1>\n", program_name);
- /* format status */
- avio_printf(pb, "<h2>Available Streams</h2>\n");
- avio_printf(pb, "<table cellspacing=0 cellpadding=4>\n");
- avio_printf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<th valign=top>Format<th>Bit rate<br>kbits/s<th align=left>Video<br>kbits/s<th><br>Codec<th align=left>Audio<br>kbits/s<th><br>Codec<th align=left valign=top>Feed\n");
- stream = first_stream;
- while (stream != NULL) {
- char sfilename[1024];
- char *eosf;
-
- if (stream->feed != stream) {
- av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10);
- eosf = sfilename + strlen(sfilename);
- if (eosf - sfilename >= 4) {
- if (strcmp(eosf - 4, ".asf") == 0)
- strcpy(eosf - 4, ".asx");
- else if (strcmp(eosf - 3, ".rm") == 0)
- strcpy(eosf - 3, ".ram");
- else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
- /* generate a sample RTSP director if
- unicast. Generate an SDP redirector if
- multicast */
- eosf = strrchr(sfilename, '.');
- if (!eosf)
- eosf = sfilename + strlen(sfilename);
- if (stream->is_multicast)
- strcpy(eosf, ".sdp");
- else
- strcpy(eosf, ".rtsp");
- }
- }
-
- avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
- sfilename, stream->filename);
- avio_printf(pb, "<td align=right> %d <td align=right> ",
- stream->conns_served);
- fmt_bytecount(pb, stream->bytes_served);
- switch(stream->stream_type) {
- case STREAM_TYPE_LIVE: {
- int audio_bit_rate = 0;
- int video_bit_rate = 0;
- const char *audio_codec_name = "";
- const char *video_codec_name = "";
- const char *audio_codec_name_extra = "";
- const char *video_codec_name_extra = "";
-
- for(i=0;i<stream->nb_streams;i++) {
- AVStream *st = stream->streams[i];
- AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
- switch(st->codec->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- audio_bit_rate += st->codec->bit_rate;
- if (codec) {
- if (*audio_codec_name)
- audio_codec_name_extra = "...";
- audio_codec_name = codec->name;
- }
- break;
- case AVMEDIA_TYPE_VIDEO:
- video_bit_rate += st->codec->bit_rate;
- if (codec) {
- if (*video_codec_name)
- video_codec_name_extra = "...";
- video_codec_name = codec->name;
- }
- break;
- case AVMEDIA_TYPE_DATA:
- video_bit_rate += st->codec->bit_rate;
- break;
- default:
- abort();
- }
- }
- avio_printf(pb, "<td align=center> %s <td align=right> %d <td align=right> %d <td> %s %s <td align=right> %d <td> %s %s",
- stream->fmt->name,
- stream->bandwidth,
- video_bit_rate / 1000, video_codec_name, video_codec_name_extra,
- audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra);
- if (stream->feed)
- avio_printf(pb, "<td>%s", stream->feed->filename);
- else
- avio_printf(pb, "<td>%s", stream->feed_filename);
- avio_printf(pb, "\n");
- }
- break;
- default:
- avio_printf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n");
- break;
- }
- }
- stream = stream->next;
- }
- avio_printf(pb, "</table>\n");
-
- stream = first_stream;
- while (stream != NULL) {
- if (stream->feed == stream) {
- avio_printf(pb, "<h2>Feed %s</h2>", stream->filename);
- if (stream->pid) {
- avio_printf(pb, "Running as pid %d.\n", stream->pid);
-
-#if defined(linux) && !defined(CONFIG_NOCUTILS)
- {
- FILE *pid_stat;
- char ps_cmd[64];
-
- /* This is somewhat linux specific I guess */
- snprintf(ps_cmd, sizeof(ps_cmd),
- "ps -o \"%%cpu,cputime\" --no-headers %d",
- stream->pid);
-
- pid_stat = popen(ps_cmd, "r");
- if (pid_stat) {
- char cpuperc[10];
- char cpuused[64];
-
- if (fscanf(pid_stat, "%10s %64s", cpuperc,
- cpuused) == 2) {
- avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",
- cpuperc, cpuused);
- }
- fclose(pid_stat);
- }
- }
-#endif
-
- avio_printf(pb, "<p>");
- }
- avio_printf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>type<th>kbits/s<th align=left>codec<th align=left>Parameters\n");
-
- for (i = 0; i < stream->nb_streams; i++) {
- AVStream *st = stream->streams[i];
- AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
- const char *type = "unknown";
- char parameters[64];
-
- parameters[0] = 0;
-
- switch(st->codec->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- type = "audio";
- snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate);
- break;
- case AVMEDIA_TYPE_VIDEO:
- type = "video";
- snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height,
- st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num);
- break;
- default:
- abort();
- }
- avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\n",
- i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters);
- }
- avio_printf(pb, "</table>\n");
-
- }
- stream = stream->next;
- }
-
- /* connection status */
- avio_printf(pb, "<h2>Connection Status</h2>\n");
-
- avio_printf(pb, "Number of connections: %d / %d<br>\n",
- nb_connections, nb_max_connections);
-
- avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
- current_bandwidth, max_bandwidth);
-
- avio_printf(pb, "<table>\n");
- avio_printf(pb, "<tr><th>#<th>File<th>IP<th>Proto<th>State<th>Target bits/sec<th>Actual bits/sec<th>Bytes transferred\n");
- c1 = first_http_ctx;
- i = 0;
- while (c1 != NULL) {
- int bitrate;
- int j;
-
- bitrate = 0;
- if (c1->stream) {
- for (j = 0; j < c1->stream->nb_streams; j++) {
- if (!c1->stream->feed)
- bitrate += c1->stream->streams[j]->codec->bit_rate;
- else if (c1->feed_streams[j] >= 0)
- bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate;
- }
- }
-
- i++;
- p = inet_ntoa(c1->from_addr.sin_addr);
- avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td align=right>",
- i,
- c1->stream ? c1->stream->filename : "",
- c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "",
- p,
- c1->protocol,
- http_state[c1->state]);
- fmt_bytecount(pb, bitrate);
- avio_printf(pb, "<td align=right>");
- fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);
- avio_printf(pb, "<td align=right>");
- fmt_bytecount(pb, c1->data_count);
- avio_printf(pb, "\n");
- c1 = c1->next;
- }
- avio_printf(pb, "</table>\n");
-
- /* date */
- ti = time(NULL);
- p = ctime(&ti);
- avio_printf(pb, "<hr size=1 noshade>Generated at %s", p);
- avio_printf(pb, "</body>\n</html>\n");
-
- len = avio_close_dyn_buf(pb, &c->pb_buffer);
- c->buffer_ptr = c->pb_buffer;
- c->buffer_end = c->pb_buffer + len;
-}
-
-/* check if the parser needs to be opened for stream i */
-static void open_parser(AVFormatContext *s, int i)
-{
- AVStream *st = s->streams[i];
- AVCodec *codec;
-
- if (!st->codec->codec) {
- codec = avcodec_find_decoder(st->codec->codec_id);
- if (codec && (codec->capabilities & CODEC_CAP_PARSE_ONLY)) {
- st->codec->parse_only = 1;
- if (avcodec_open2(st->codec, codec, NULL) < 0)
- st->codec->parse_only = 0;
- }
- }
-}
-
-static int open_input_stream(HTTPContext *c, const char *info)
-{
- char buf[128];
- char input_filename[1024];
- AVFormatContext *s = NULL;
- int buf_size, i, ret;
- int64_t stream_pos;
-
- /* find file name */
- if (c->stream->feed) {
- strcpy(input_filename, c->stream->feed->feed_filename);
- buf_size = FFM_PACKET_SIZE;
- /* compute position (absolute time) */
- if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
- if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0)
- return ret;
- } else if (av_find_info_tag(buf, sizeof(buf), "buffer", info)) {
- int prebuffer = strtol(buf, 0, 10);
- stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
- } else
- stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000;
- } else {
- strcpy(input_filename, c->stream->feed_filename);
- buf_size = 0;
- /* compute position (relative time) */
- if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
- if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0)
- return ret;
- } else
- stream_pos = 0;
- }
- if (input_filename[0] == '\0')
- return -1;
-
- /* open stream */
- if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) {
- http_log("could not open %s: %d\n", input_filename, ret);
- return -1;
- }
- s->flags |= AVFMT_FLAG_GENPTS;
- c->fmt_in = s;
- if (strcmp(s->iformat->name, "ffm") && av_find_stream_info(c->fmt_in) < 0) {
- http_log("Could not find stream info '%s'\n", input_filename);
- av_close_input_file(s);
- return -1;
- }
-
- /* open each parser */
- for(i=0;i<s->nb_streams;i++)
- open_parser(s, i);
-
- /* choose stream as clock source (we favorize video stream if
- present) for packet sending */
- c->pts_stream_index = 0;
- for(i=0;i<c->stream->nb_streams;i++) {
- if (c->pts_stream_index == 0 &&
- c->stream->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- c->pts_stream_index = i;
- }
- }
-
- if (c->fmt_in->iformat->read_seek)
- av_seek_frame(c->fmt_in, -1, stream_pos, 0);
- /* set the start time (needed for maxtime and RTP packet timing) */
- c->start_time = cur_time;
- c->first_pts = AV_NOPTS_VALUE;
- return 0;
-}
-
-/* return the server clock (in us) */
-static int64_t get_server_clock(HTTPContext *c)
-{
- /* compute current pts value from system time */
- return (cur_time - c->start_time) * 1000;
-}
-
-/* return the estimated time at which the current packet must be sent
- (in us) */
-static int64_t get_packet_send_clock(HTTPContext *c)
-{
- int bytes_left, bytes_sent, frame_bytes;
-
- frame_bytes = c->cur_frame_bytes;
- if (frame_bytes <= 0)
- return c->cur_pts;
- else {
- bytes_left = c->buffer_end - c->buffer_ptr;
- bytes_sent = frame_bytes - bytes_left;
- return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
- }
-}
-
-
-static int http_prepare_data(HTTPContext *c)
-{
- int i, len, ret;
- AVFormatContext *ctx;
-
- av_freep(&c->pb_buffer);
- switch(c->state) {
- case HTTPSTATE_SEND_DATA_HEADER:
- memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx));
- av_dict_set(&c->fmt_ctx.metadata, "author" , c->stream->author , 0);
- av_dict_set(&c->fmt_ctx.metadata, "comment" , c->stream->comment , 0);
- av_dict_set(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0);
- av_dict_set(&c->fmt_ctx.metadata, "title" , c->stream->title , 0);
-
- c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams);
-
- for(i=0;i<c->stream->nb_streams;i++) {
- AVStream *src;
- c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
- /* if file or feed, then just take streams from FFStream struct */
- if (!c->stream->feed ||
- c->stream->feed == c->stream)
- src = c->stream->streams[i];
- else
- src = c->stream->feed->streams[c->stream->feed_streams[i]];
-
- *(c->fmt_ctx.streams[i]) = *src;
- c->fmt_ctx.streams[i]->priv_data = 0;
- c->fmt_ctx.streams[i]->codec->frame_number = 0; /* XXX: should be done in
- 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 */
- if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
- /* XXX: potential leak */
- return -1;
- }
- c->fmt_ctx.pb->seekable = 0;
-
- /*
- * HACK to avoid mpeg ps muxer to spit many underflow errors
- * Default value from Libav
- * 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);
-
- if (avformat_write_header(&c->fmt_ctx, NULL) < 0) {
- http_log("Error writing output header\n");
- return -1;
- }
- av_dict_free(&c->fmt_ctx.metadata);
-
- len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
- c->buffer_ptr = c->pb_buffer;
- c->buffer_end = c->pb_buffer + len;
-
- c->state = HTTPSTATE_SEND_DATA;
- c->last_packet_sent = 0;
- break;
- case HTTPSTATE_SEND_DATA:
- /* find a new packet */
- /* read a packet from the input stream */
- if (c->stream->feed)
- ffm_set_write_index(c->fmt_in,
- c->stream->feed->feed_write_index,
- c->stream->feed->feed_size);
-
- if (c->stream->max_time &&
- c->stream->max_time + c->start_time - cur_time < 0)
- /* We have timed out */
- c->state = HTTPSTATE_SEND_DATA_TRAILER;
- else {
- AVPacket pkt;
- redo:
- ret = av_read_frame(c->fmt_in, &pkt);
- if (ret < 0) {
- if (c->stream->feed) {
- /* if coming from feed, it means we reached the end of the
- ffm file, so must wait for more data */
- c->state = HTTPSTATE_WAIT_FEED;
- return 1; /* state changed */
- } else if (ret == AVERROR(EAGAIN)) {
- /* input not ready, come back later */
- return 0;
- } else {
- if (c->stream->loop) {
- av_close_input_file(c->fmt_in);
- c->fmt_in = NULL;
- if (open_input_stream(c, "") < 0)
- goto no_loop;
- goto redo;
- } else {
- no_loop:
- /* must send trailer now because eof or error */
- c->state = HTTPSTATE_SEND_DATA_TRAILER;
- }
- }
- } else {
- int source_index = pkt.stream_index;
- /* update first pts if needed */
- if (c->first_pts == AV_NOPTS_VALUE) {
- c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
- c->start_time = cur_time;
- }
- /* send it to the appropriate stream */
- if (c->stream->feed) {
- /* if coming from a feed, select the right stream */
- if (c->switch_pending) {
- c->switch_pending = 0;
- for(i=0;i<c->stream->nb_streams;i++) {
- if (c->switch_feed_streams[i] == pkt.stream_index)
- if (pkt.flags & AV_PKT_FLAG_KEY)
- c->switch_feed_streams[i] = -1;
- if (c->switch_feed_streams[i] >= 0)
- c->switch_pending = 1;
- }
- }
- for(i=0;i<c->stream->nb_streams;i++) {
- if (c->stream->feed_streams[i] == pkt.stream_index) {
- AVStream *st = c->fmt_in->streams[source_index];
- pkt.stream_index = i;
- if (pkt.flags & AV_PKT_FLAG_KEY &&
- (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
- c->stream->nb_streams == 1))
- c->got_key_frame = 1;
- if (!c->stream->send_on_key || c->got_key_frame)
- goto send_it;
- }
- }
- } 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) {
- /* compute send time and duration */
- c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
- c->cur_pts -= c->first_pts;
- c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
- /* find RTP context */
- c->packet_stream_index = pkt.stream_index;
- ctx = c->rtp_ctx[c->packet_stream_index];
- if(!ctx) {
- av_free_packet(&pkt);
- break;
- }
- codec = ctx->streams[0]->codec;
- /* only one stream per RTP connection */
- pkt.stream_index = 0;
- } else {
- ctx = &c->fmt_ctx;
- /* Fudge here */
- codec = ctx->streams[pkt.stream_index]->codec;
- }
-
- if (c->is_packetized) {
- int max_packet_size;
- if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
- max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
- else
- max_packet_size = url_get_max_packet_size(c->rtp_handles[c->packet_stream_index]);
- ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size);
- } else {
- ret = avio_open_dyn_buf(&ctx->pb);
- }
- if (ret < 0) {
- /* XXX: potential leak */
- return -1;
- }
- ost = ctx->streams[pkt.stream_index];
-
- ctx->pb->seekable = 0;
- if (pkt.dts != AV_NOPTS_VALUE)
- 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, 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;
- }
-
- len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
- c->cur_frame_bytes = len;
- c->buffer_ptr = c->pb_buffer;
- c->buffer_end = c->pb_buffer + len;
-
- codec->frame_number++;
- if (len == 0) {
- av_free_packet(&pkt);
- goto redo;
- }
- }
- av_free_packet(&pkt);
- }
- }
- break;
- default:
- case HTTPSTATE_SEND_DATA_TRAILER:
- /* last packet test ? */
- if (c->last_packet_sent || c->is_packetized)
- return -1;
- ctx = &c->fmt_ctx;
- /* prepare header */
- if (avio_open_dyn_buf(&ctx->pb) < 0) {
- /* XXX: potential leak */
- return -1;
- }
- c->fmt_ctx.pb->seekable = 0;
- av_write_trailer(ctx);
- len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
- c->buffer_ptr = c->pb_buffer;
- c->buffer_end = c->pb_buffer + len;
-
- c->last_packet_sent = 1;
- break;
- }
- return 0;
-}
-
-/* should convert the format at the same time */
-/* send data starting at c->buffer_ptr to the output connection
- (either UDP or TCP connection) */
-static int http_send_data(HTTPContext *c)
-{
- int len, ret;
-
- for(;;) {
- if (c->buffer_ptr >= c->buffer_end) {
- ret = http_prepare_data(c);
- if (ret < 0)
- return -1;
- else if (ret != 0)
- /* state change requested */
- break;
- } else {
- if (c->is_packetized) {
- /* RTP data output */
- len = c->buffer_end - c->buffer_ptr;
- if (len < 4) {
- /* fail safe - should never happen */
- fail1:
- c->buffer_ptr = c->buffer_end;
- return 0;
- }
- len = (c->buffer_ptr[0] << 24) |
- (c->buffer_ptr[1] << 16) |
- (c->buffer_ptr[2] << 8) |
- (c->buffer_ptr[3]);
- if (len > (c->buffer_end - c->buffer_ptr))
- goto fail1;
- if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {
- /* nothing to send yet: we can wait */
- return 0;
- }
-
- c->data_count += len;
- update_datarate(&c->datarate, c->data_count);
- if (c->stream)
- c->stream->bytes_served += len;
-
- if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
- /* RTP packets are sent inside the RTSP TCP connection */
- AVIOContext *pb;
- int interleaved_index, size;
- uint8_t header[4];
- HTTPContext *rtsp_c;
-
- rtsp_c = c->rtsp_c;
- /* if no RTSP connection left, error */
- if (!rtsp_c)
- return -1;
- /* if already sending something, then wait. */
- if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)
- break;
- if (avio_open_dyn_buf(&pb) < 0)
- goto fail1;
- interleaved_index = c->packet_stream_index * 2;
- /* RTCP packets are sent at odd indexes */
- if (c->buffer_ptr[1] == 200)
- interleaved_index++;
- /* write RTSP TCP header */
- header[0] = '$';
- header[1] = interleaved_index;
- header[2] = len >> 8;
- header[3] = len;
- avio_write(pb, header, 4);
- /* write RTP packet data */
- c->buffer_ptr += 4;
- avio_write(pb, c->buffer_ptr, len);
- size = avio_close_dyn_buf(pb, &c->packet_buffer);
- /* prepare asynchronous TCP sending */
- rtsp_c->packet_buffer_ptr = c->packet_buffer;
- rtsp_c->packet_buffer_end = c->packet_buffer + size;
- c->buffer_ptr += len;
-
- /* send everything we can NOW */
- len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,
- rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);
- if (len > 0)
- rtsp_c->packet_buffer_ptr += len;
- if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
- /* if we could not send all the data, we will
- send it later, so a new state is needed to
- "lock" the RTSP TCP connection */
- rtsp_c->state = RTSPSTATE_SEND_PACKET;
- break;
- } else
- /* all data has been sent */
- av_freep(&c->packet_buffer);
- } else {
- /* send RTP packet directly in UDP */
- c->buffer_ptr += 4;
- url_write(c->rtp_handles[c->packet_stream_index],
- c->buffer_ptr, len);
- c->buffer_ptr += len;
- /* here we continue as we can send several packets per 10 ms slot */
- }
- } else {
- /* TCP data output */
- len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
- if (len < 0) {
- if (ff_neterrno() != AVERROR(EAGAIN) &&
- ff_neterrno() != AVERROR(EINTR))
- /* error : close connection */
- return -1;
- else
- return 0;
- } else
- c->buffer_ptr += len;
-
- c->data_count += len;
- update_datarate(&c->datarate, c->data_count);
- if (c->stream)
- c->stream->bytes_served += len;
- break;
- }
- }
- } /* for(;;) */
- return 0;
-}
-
-static int http_start_receive_data(HTTPContext *c)
-{
- int fd;
-
- if (c->stream->feed_opened)
- return -1;
-
- /* Don't permit writing to this one */
- if (c->stream->readonly)
- return -1;
-
- /* open feed */
- fd = open(c->stream->feed_filename, O_RDWR);
- if (fd < 0) {
- http_log("Error opening feeder file: %s\n", strerror(errno));
- return -1;
- }
- c->feed_fd = fd;
-
- if (c->stream->truncate) {
- /* truncate feed file */
- ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
- ftruncate(c->feed_fd, FFM_PACKET_SIZE);
- http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
- } else {
- if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) {
- http_log("Error reading write index from feed file: %s\n", strerror(errno));
- return -1;
- }
- }
-
- c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
- c->stream->feed_size = lseek(fd, 0, SEEK_END);
- lseek(fd, 0, SEEK_SET);
-
- /* init buffer input */
- c->buffer_ptr = c->buffer;
- c->buffer_end = c->buffer + FFM_PACKET_SIZE;
- c->stream->feed_opened = 1;
- c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
- return 0;
-}
-
-static int http_receive_data(HTTPContext *c)
-{
- HTTPContext *c1;
- int len, loop_run = 0;
-
- while (c->chunked_encoding && !c->chunk_size &&
- c->buffer_end > c->buffer_ptr) {
- /* read chunk header, if present */
- len = recv(c->fd, c->buffer_ptr, 1, 0);
-
- if (len < 0) {
- if (ff_neterrno() != AVERROR(EAGAIN) &&
- ff_neterrno() != AVERROR(EINTR))
- /* error : close connection */
- goto fail;
- return 0;
- } else if (len == 0) {
- /* end of connection : close it */
- goto fail;
- } else if (c->buffer_ptr - c->buffer >= 2 &&
- !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
- c->chunk_size = strtol(c->buffer, 0, 16);
- if (c->chunk_size == 0) // end of stream
- goto fail;
- c->buffer_ptr = c->buffer;
- break;
- } else if (++loop_run > 10) {
- /* no chunk header, abort */
- goto fail;
- } else {
- c->buffer_ptr++;
- }
- }
-
- if (c->buffer_end > c->buffer_ptr) {
- len = recv(c->fd, c->buffer_ptr,
- FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
- if (len < 0) {
- if (ff_neterrno() != AVERROR(EAGAIN) &&
- ff_neterrno() != AVERROR(EINTR))
- /* error : close connection */
- goto fail;
- } else if (len == 0)
- /* end of connection : close it */
- goto fail;
- else {
- c->chunk_size -= len;
- c->buffer_ptr += len;
- c->data_count += len;
- update_datarate(&c->datarate, c->data_count);
- }
- }
-
- if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
- if (c->buffer[0] != 'f' ||
- c->buffer[1] != 'm') {
- http_log("Feed stream has become desynchronized -- disconnecting\n");
- goto fail;
- }
- }
-
- if (c->buffer_ptr >= c->buffer_end) {
- FFStream *feed = c->stream;
- /* a packet has been received : write it in the store, except
- if header */
- if (c->data_count > FFM_PACKET_SIZE) {
-
- // printf("writing pos=0x%"PRIx64" size=0x%"PRIx64"\n", feed->feed_write_index, feed->feed_size);
- /* XXX: use llseek or url_seek */
- lseek(c->feed_fd, feed->feed_write_index, SEEK_SET);
- if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) {
- http_log("Error writing to feed file: %s\n", strerror(errno));
- goto fail;
- }
-
- feed->feed_write_index += FFM_PACKET_SIZE;
- /* update file size */
- if (feed->feed_write_index > c->stream->feed_size)
- feed->feed_size = feed->feed_write_index;
-
- /* handle wrap around if max file size reached */
- if (c->stream->feed_max_size && feed->feed_write_index >= c->stream->feed_max_size)
- feed->feed_write_index = FFM_PACKET_SIZE;
-
- /* write index */
- if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) {
- http_log("Error writing index to feed file: %s\n", strerror(errno));
- goto fail;
- }
-
- /* wake up any waiting connections */
- for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
- if (c1->state == HTTPSTATE_WAIT_FEED &&
- c1->stream->feed == c->stream->feed)
- c1->state = HTTPSTATE_SEND_DATA;
- }
- } else {
- /* We have a header in our hands that contains useful data */
- AVFormatContext *s = avformat_alloc_context();
- AVIOContext *pb;
- AVInputFormat *fmt_in;
- int i;
-
- if (!s)
- goto fail;
-
- /* use feed output format name to find corresponding input format */
- fmt_in = av_find_input_format(feed->fmt->name);
- if (!fmt_in)
- goto fail;
-
- pb = avio_alloc_context(c->buffer, c->buffer_end - c->buffer,
- 0, NULL, NULL, NULL, NULL);
- pb->seekable = 0;
-
- s->pb = pb;
- if (avformat_open_input(&s, 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_close_input_stream(s);
- av_free(pb);
- http_log("Feed '%s' stream number does not match registered feed\n",
- c->stream->feed_filename);
- goto fail;
- }
-
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *fst = feed->streams[i];
- AVStream *st = s->streams[i];
- avcodec_copy_context(fst->codec, st->codec);
- }
-
- av_close_input_stream(s);
- av_free(pb);
- }
- c->buffer_ptr = c->buffer;
- }
-
- return 0;
- fail:
- c->stream->feed_opened = 0;
- close(c->feed_fd);
- /* wake up any waiting connections to stop waiting for feed */
- for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
- if (c1->state == HTTPSTATE_WAIT_FEED &&
- c1->stream->feed == c->stream->feed)
- c1->state = HTTPSTATE_SEND_DATA_TRAILER;
- }
- return -1;
-}
-
-/********************************************************************/
-/* RTSP handling */
-
-static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
-{
- const char *str;
- time_t ti;
- struct tm *tm;
- char buf2[32];
-
- switch(error_number) {
- case RTSP_STATUS_OK:
- str = "OK";
- break;
- case RTSP_STATUS_METHOD:
- str = "Method Not Allowed";
- break;
- case RTSP_STATUS_BANDWIDTH:
- str = "Not Enough Bandwidth";
- break;
- case RTSP_STATUS_SESSION:
- str = "Session Not Found";
- break;
- case RTSP_STATUS_STATE:
- str = "Method Not Valid in This State";
- break;
- case RTSP_STATUS_AGGREGATE:
- str = "Aggregate operation not allowed";
- break;
- case RTSP_STATUS_ONLY_AGGREGATE:
- str = "Only aggregate operation allowed";
- break;
- case RTSP_STATUS_TRANSPORT:
- str = "Unsupported transport";
- break;
- case RTSP_STATUS_INTERNAL:
- str = "Internal Server Error";
- break;
- case RTSP_STATUS_SERVICE:
- str = "Service Unavailable";
- break;
- case RTSP_STATUS_VERSION:
- str = "RTSP Version not supported";
- break;
- default:
- str = "Unknown Error";
- break;
- }
-
- avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
- avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
-
- /* output GMT time */
- ti = time(NULL);
- tm = gmtime(&ti);
- strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
- avio_printf(c->pb, "Date: %s GMT\r\n", buf2);
-}
-
-static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
-{
- rtsp_reply_header(c, error_number);
- avio_printf(c->pb, "\r\n");
-}
-
-static int rtsp_parse_request(HTTPContext *c)
-{
- const char *p, *p1, *p2;
- char cmd[32];
- char url[1024];
- char protocol[32];
- char line[1024];
- int len;
- RTSPMessageHeader header1, *header = &header1;
-
- c->buffer_ptr[0] = '\0';
- p = c->buffer;
-
- get_word(cmd, sizeof(cmd), &p);
- get_word(url, sizeof(url), &p);
- get_word(protocol, sizeof(protocol), &p);
-
- av_strlcpy(c->method, cmd, sizeof(c->method));
- av_strlcpy(c->url, url, sizeof(c->url));
- av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
-
- if (avio_open_dyn_buf(&c->pb) < 0) {
- /* XXX: cannot do more */
- c->pb = NULL; /* safety */
- return -1;
- }
-
- /* check version name */
- if (strcmp(protocol, "RTSP/1.0") != 0) {
- rtsp_reply_error(c, RTSP_STATUS_VERSION);
- goto the_end;
- }
-
- /* parse each header line */
- memset(header, 0, sizeof(*header));
- /* skip to next line */
- while (*p != '\n' && *p != '\0')
- p++;
- if (*p == '\n')
- p++;
- while (*p != '\0') {
- p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
- if (!p1)
- break;
- p2 = p1;
- if (p2 > p && p2[-1] == '\r')
- p2--;
- /* skip empty line */
- if (p2 == p)
- break;
- len = p2 - p;
- if (len > sizeof(line) - 1)
- len = sizeof(line) - 1;
- memcpy(line, p, len);
- line[len] = '\0';
- ff_rtsp_parse_line(header, line, NULL, NULL);
- p = p1 + 1;
- }
-
- /* handle sequence number */
- c->seq = header->seq;
-
- if (!strcmp(cmd, "DESCRIBE"))
- rtsp_cmd_describe(c, url);
- else if (!strcmp(cmd, "OPTIONS"))
- rtsp_cmd_options(c, url);
- else if (!strcmp(cmd, "SETUP"))
- rtsp_cmd_setup(c, url, header);
- else if (!strcmp(cmd, "PLAY"))
- rtsp_cmd_play(c, url, header);
- else if (!strcmp(cmd, "PAUSE"))
- rtsp_cmd_pause(c, url, header);
- else if (!strcmp(cmd, "TEARDOWN"))
- rtsp_cmd_teardown(c, url, header);
- else
- rtsp_reply_error(c, RTSP_STATUS_METHOD);
-
- the_end:
- len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
- c->pb = NULL; /* safety */
- if (len < 0) {
- /* XXX: cannot do more */
- return -1;
- }
- c->buffer_ptr = c->pb_buffer;
- c->buffer_end = c->pb_buffer + len;
- c->state = RTSPSTATE_SEND_REPLY;
- return 0;
-}
-
-static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
- struct in_addr my_ip)
-{
- AVFormatContext *avc;
- AVStream *avs = NULL;
- int i;
-
- avc = avformat_alloc_context();
- if (avc == NULL) {
- return -1;
- }
- av_dict_set(&avc->metadata, "title",
- stream->title[0] ? stream->title : "No Title", 0);
- avc->nb_streams = stream->nb_streams;
- if (stream->is_multicast) {
- snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
- inet_ntoa(stream->multicast_ip),
- stream->multicast_port, stream->multicast_ttl);
- } else {
- snprintf(avc->filename, 1024, "rtp://0.0.0.0");
- }
-
- if (avc->nb_streams >= INT_MAX/sizeof(*avc->streams) ||
- !(avc->streams = av_malloc(avc->nb_streams * sizeof(*avc->streams))))
- goto sdp_done;
- if (avc->nb_streams >= INT_MAX/sizeof(*avs) ||
- !(avs = av_malloc(avc->nb_streams * sizeof(*avs))))
- goto sdp_done;
-
- for(i = 0; i < stream->nb_streams; i++) {
- avc->streams[i] = &avs[i];
- avc->streams[i]->codec = stream->streams[i]->codec;
- }
- *pbuffer = av_mallocz(2048);
- av_sdp_create(&avc, 1, *pbuffer, 2048);
-
- sdp_done:
- av_free(avc->streams);
- av_dict_free(&avc->metadata);
- av_free(avc);
- av_free(avs);
-
- return strlen(*pbuffer);
-}
-
-static void rtsp_cmd_options(HTTPContext *c, const char *url)
-{
-// rtsp_reply_header(c, RTSP_STATUS_OK);
- avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
- avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
- avio_printf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
- avio_printf(c->pb, "\r\n");
-}
-
-static void rtsp_cmd_describe(HTTPContext *c, const char *url)
-{
- FFStream *stream;
- char path1[1024];
- const char *path;
- uint8_t *content;
- int content_length, len;
- struct sockaddr_in my_addr;
-
- /* find which url is asked */
- av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
- path = path1;
- if (*path == '/')
- path++;
-
- for(stream = first_stream; stream != NULL; stream = stream->next) {
- if (!stream->is_feed &&
- stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
- !strcmp(path, stream->filename)) {
- goto found;
- }
- }
- /* no stream found */
- rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
- return;
-
- found:
- /* prepare the media description in sdp format */
-
- /* get the host IP */
- len = sizeof(my_addr);
- getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
- content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr);
- if (content_length < 0) {
- rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
- return;
- }
- rtsp_reply_header(c, RTSP_STATUS_OK);
- avio_printf(c->pb, "Content-Base: %s/\r\n", url);
- avio_printf(c->pb, "Content-Type: application/sdp\r\n");
- avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
- avio_printf(c->pb, "\r\n");
- avio_write(c->pb, content, content_length);
- av_free(content);
-}
-
-static HTTPContext *find_rtp_session(const char *session_id)
-{
- HTTPContext *c;
-
- if (session_id[0] == '\0')
- return NULL;
-
- for(c = first_http_ctx; c != NULL; c = c->next) {
- if (!strcmp(c->session_id, session_id))
- return c;
- }
- return NULL;
-}
-
-static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport)
-{
- RTSPTransportField *th;
- int i;
-
- for(i=0;i<h->nb_transports;i++) {
- th = &h->transports[i];
- if (th->lower_transport == lower_transport)
- return th;
- }
- return NULL;
-}
-
-static void rtsp_cmd_setup(HTTPContext *c, const char *url,
- RTSPMessageHeader *h)
-{
- FFStream *stream;
- int stream_index, rtp_port, rtcp_port;
- char buf[1024];
- char path1[1024];
- const char *path;
- HTTPContext *rtp_c;
- RTSPTransportField *th;
- struct sockaddr_in dest_addr;
- RTSPActionServerSetup setup;
-
- /* find which url is asked */
- av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
- path = path1;
- if (*path == '/')
- path++;
-
- /* now check each stream */
- for(stream = first_stream; stream != NULL; stream = stream->next) {
- if (!stream->is_feed &&
- stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
- /* accept aggregate filenames only if single stream */
- if (!strcmp(path, stream->filename)) {
- if (stream->nb_streams != 1) {
- rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);
- return;
- }
- stream_index = 0;
- goto found;
- }
-
- for(stream_index = 0; stream_index < stream->nb_streams;
- stream_index++) {
- snprintf(buf, sizeof(buf), "%s/streamid=%d",
- stream->filename, stream_index);
- if (!strcmp(path, buf))
- goto found;
- }
- }
- }
- /* no stream found */
- rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
- return;
- found:
-
- /* generate session id if needed */
- if (h->session_id[0] == '\0')
- snprintf(h->session_id, sizeof(h->session_id), "%08x%08x",
- av_lfg_get(&random_state), av_lfg_get(&random_state));
-
- /* find rtp session, and create it if none found */
- rtp_c = find_rtp_session(h->session_id);
- if (!rtp_c) {
- /* always prefer UDP */
- th = find_transport(h, RTSP_LOWER_TRANSPORT_UDP);
- if (!th) {
- th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP);
- if (!th) {
- rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
- return;
- }
- }
-
- rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,
- th->lower_transport);
- if (!rtp_c) {
- rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);
- return;
- }
-
- /* open input stream */
- if (open_input_stream(rtp_c, "") < 0) {
- rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
- return;
- }
- }
-
- /* test if stream is OK (test needed because several SETUP needs
- to be done for a given file) */
- if (rtp_c->stream != stream) {
- rtsp_reply_error(c, RTSP_STATUS_SERVICE);
- return;
- }
-
- /* test if stream is already set up */
- if (rtp_c->rtp_ctx[stream_index]) {
- rtsp_reply_error(c, RTSP_STATUS_STATE);
- return;
- }
-
- /* check transport */
- th = find_transport(h, rtp_c->rtp_protocol);
- if (!th || (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
- th->client_port_min <= 0)) {
- rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
- return;
- }
-
- /* setup default options */
- setup.transport_option[0] = '\0';
- dest_addr = rtp_c->from_addr;
- dest_addr.sin_port = htons(th->client_port_min);
-
- /* setup stream */
- if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
- rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
- return;
- }
-
- /* now everything is OK, so we can send the connection parameters */
- rtsp_reply_header(c, RTSP_STATUS_OK);
- /* session ID */
- avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
-
- switch(rtp_c->rtp_protocol) {
- case RTSP_LOWER_TRANSPORT_UDP:
- rtp_port = rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
- rtcp_port = rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
- avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
- "client_port=%d-%d;server_port=%d-%d",
- th->client_port_min, th->client_port_max,
- rtp_port, rtcp_port);
- break;
- case RTSP_LOWER_TRANSPORT_TCP:
- avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
- stream_index * 2, stream_index * 2 + 1);
- break;
- default:
- break;
- }
- if (setup.transport_option[0] != '\0')
- avio_printf(c->pb, ";%s", setup.transport_option);
- avio_printf(c->pb, "\r\n");
-
-
- avio_printf(c->pb, "\r\n");
-}
-
-
-/* find an rtp connection by using the session ID. Check consistency
- with filename */
-static HTTPContext *find_rtp_session_with_url(const char *url,
- const char *session_id)
-{
- HTTPContext *rtp_c;
- char path1[1024];
- const char *path;
- char buf[1024];
- int s, len;
-
- rtp_c = find_rtp_session(session_id);
- if (!rtp_c)
- return NULL;
-
- /* find which url is asked */
- av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
- path = path1;
- if (*path == '/')
- path++;
- if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
- for(s=0; s<rtp_c->stream->nb_streams; ++s) {
- snprintf(buf, sizeof(buf), "%s/streamid=%d",
- rtp_c->stream->filename, s);
- if(!strncmp(path, buf, sizeof(buf))) {
- // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
- return rtp_c;
- }
- }
- len = strlen(path);
- if (len > 0 && path[len - 1] == '/' &&
- !strncmp(path, rtp_c->stream->filename, len - 1))
- return rtp_c;
- return NULL;
-}
-
-static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
-{
- HTTPContext *rtp_c;
-
- rtp_c = find_rtp_session_with_url(url, h->session_id);
- if (!rtp_c) {
- rtsp_reply_error(c, RTSP_STATUS_SESSION);
- return;
- }
-
- if (rtp_c->state != HTTPSTATE_SEND_DATA &&
- rtp_c->state != HTTPSTATE_WAIT_FEED &&
- rtp_c->state != HTTPSTATE_READY) {
- rtsp_reply_error(c, RTSP_STATUS_STATE);
- return;
- }
-
- rtp_c->state = HTTPSTATE_SEND_DATA;
-
- /* now everything is OK, so we can send the connection parameters */
- rtsp_reply_header(c, RTSP_STATUS_OK);
- /* session ID */
- avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
- avio_printf(c->pb, "\r\n");
-}
-
-static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h)
-{
- HTTPContext *rtp_c;
-
- rtp_c = find_rtp_session_with_url(url, h->session_id);
- if (!rtp_c) {
- rtsp_reply_error(c, RTSP_STATUS_SESSION);
- return;
- }
-
- if (rtp_c->state != HTTPSTATE_SEND_DATA &&
- rtp_c->state != HTTPSTATE_WAIT_FEED) {
- rtsp_reply_error(c, RTSP_STATUS_STATE);
- return;
- }
-
- rtp_c->state = HTTPSTATE_READY;
- rtp_c->first_pts = AV_NOPTS_VALUE;
- /* now everything is OK, so we can send the connection parameters */
- rtsp_reply_header(c, RTSP_STATUS_OK);
- /* session ID */
- avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
- avio_printf(c->pb, "\r\n");
-}
-
-static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h)
-{
- HTTPContext *rtp_c;
-
- rtp_c = find_rtp_session_with_url(url, h->session_id);
- if (!rtp_c) {
- rtsp_reply_error(c, RTSP_STATUS_SESSION);
- return;
- }
-
- /* now everything is OK, so we can send the connection parameters */
- rtsp_reply_header(c, RTSP_STATUS_OK);
- /* session ID */
- avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
- avio_printf(c->pb, "\r\n");
-
- /* abort the session */
- close_connection(rtp_c);
-}
-
-
-/********************************************************************/
-/* RTP handling */
-
-static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
- FFStream *stream, const char *session_id,
- enum RTSPLowerTransport rtp_protocol)
-{
- HTTPContext *c = NULL;
- const char *proto_str;
-
- /* XXX: should output a warning page when coming
- close to the connection limit */
- if (nb_connections >= nb_max_connections)
- goto fail;
-
- /* add a new connection */
- c = av_mallocz(sizeof(HTTPContext));
- if (!c)
- goto fail;
-
- c->fd = -1;
- c->poll_entry = NULL;
- c->from_addr = *from_addr;
- c->buffer_size = IOBUFFER_INIT_SIZE;
- c->buffer = av_malloc(c->buffer_size);
- if (!c->buffer)
- goto fail;
- nb_connections++;
- c->stream = stream;
- av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
- c->state = HTTPSTATE_READY;
- c->is_packetized = 1;
- c->rtp_protocol = rtp_protocol;
-
- /* protocol is shown in statistics */
- switch(c->rtp_protocol) {
- case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
- proto_str = "MCAST";
- break;
- case RTSP_LOWER_TRANSPORT_UDP:
- proto_str = "UDP";
- break;
- case RTSP_LOWER_TRANSPORT_TCP:
- proto_str = "TCP";
- break;
- default:
- proto_str = "???";
- break;
- }
- av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
- av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
-
- current_bandwidth += stream->bandwidth;
-
- c->next = first_http_ctx;
- first_http_ctx = c;
- return c;
-
- fail:
- if (c) {
- av_free(c->buffer);
- av_free(c);
- }
- return NULL;
-}
-
-/* add a new RTP stream in an RTP connection (used in RTSP SETUP
- command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
- used. */
-static int rtp_new_av_stream(HTTPContext *c,
- int stream_index, struct sockaddr_in *dest_addr,
- HTTPContext *rtsp_c)
-{
- AVFormatContext *ctx;
- AVStream *st;
- char *ipaddr;
- URLContext *h = NULL;
- uint8_t *dummy_buf;
- int max_packet_size;
-
- /* now we can open the relevant output stream */
- ctx = avformat_alloc_context();
- if (!ctx)
- return -1;
- ctx->oformat = av_guess_format("rtp", NULL, NULL);
-
- st = av_mallocz(sizeof(AVStream));
- if (!st)
- goto fail;
- ctx->nb_streams = 1;
- ctx->streams = av_mallocz(sizeof(AVStream *) * ctx->nb_streams);
- if (!ctx->streams)
- goto fail;
- ctx->streams[0] = st;
-
- if (!c->stream->feed ||
- c->stream->feed == c->stream)
- memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
- else
- memcpy(st,
- c->stream->feed->streams[c->stream->feed_streams[stream_index]],
- sizeof(AVStream));
- st->priv_data = NULL;
-
- /* build destination RTP address */
- ipaddr = inet_ntoa(dest_addr->sin_addr);
-
- switch(c->rtp_protocol) {
- case RTSP_LOWER_TRANSPORT_UDP:
- case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
- /* RTP/UDP case */
-
- /* XXX: also pass as parameter to function ? */
- if (c->stream->is_multicast) {
- int ttl;
- ttl = c->stream->multicast_ttl;
- if (!ttl)
- ttl = 16;
- snprintf(ctx->filename, sizeof(ctx->filename),
- "rtp://%s:%d?multicast=1&ttl=%d",
- ipaddr, ntohs(dest_addr->sin_port), ttl);
- } else {
- snprintf(ctx->filename, sizeof(ctx->filename),
- "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
- }
-
- if (url_open(&h, ctx->filename, AVIO_FLAG_WRITE) < 0)
- goto fail;
- c->rtp_handles[stream_index] = h;
- max_packet_size = url_get_max_packet_size(h);
- break;
- case RTSP_LOWER_TRANSPORT_TCP:
- /* RTP/TCP case */
- c->rtsp_c = rtsp_c;
- max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
- break;
- default:
- goto fail;
- }
-
- http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",
- ipaddr, ntohs(dest_addr->sin_port),
- c->stream->filename, stream_index, c->protocol);
-
- /* normally, no packets should be output here, but the packet size may be checked */
- if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
- /* XXX: close stream */
- goto fail;
- }
- if (avformat_write_header(ctx, NULL) < 0) {
- fail:
- if (h)
- url_close(h);
- av_free(ctx);
- return -1;
- }
- avio_close_dyn_buf(ctx->pb, &dummy_buf);
- av_free(dummy_buf);
-
- c->rtp_ctx[stream_index] = ctx;
- return 0;
-}
-
-/********************************************************************/
-/* ffserver initialization */
-
-static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
-{
- AVStream *fst;
-
- fst = av_mallocz(sizeof(AVStream));
- if (!fst)
- return NULL;
- if (copy) {
- fst->codec= avcodec_alloc_context();
- memcpy(fst->codec, codec, sizeof(AVCodecContext));
- if (codec->extradata_size) {
- fst->codec->extradata = av_malloc(codec->extradata_size);
- memcpy(fst->codec->extradata, codec->extradata,
- codec->extradata_size);
- }
- } else {
- /* live streams must use the actual feed's codec since it may be
- * updated later to carry extradata needed by the streams.
- */
- fst->codec = codec;
- }
- fst->priv_data = av_mallocz(sizeof(FeedData));
- fst->index = stream->nb_streams;
- av_set_pts_info(fst, 33, 1, 90000);
- fst->sample_aspect_ratio = codec->sample_aspect_ratio;
- stream->streams[stream->nb_streams++] = fst;
- return fst;
-}
-
-/* return the stream number in the feed */
-static int add_av_stream(FFStream *feed, AVStream *st)
-{
- AVStream *fst;
- AVCodecContext *av, *av1;
- int i;
-
- av = st->codec;
- for(i=0;i<feed->nb_streams;i++) {
- st = feed->streams[i];
- av1 = st->codec;
- if (av1->codec_id == av->codec_id &&
- av1->codec_type == av->codec_type &&
- av1->bit_rate == av->bit_rate) {
-
- switch(av->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- if (av1->channels == av->channels &&
- av1->sample_rate == av->sample_rate)
- goto found;
- break;
- case AVMEDIA_TYPE_VIDEO:
- if (av1->width == av->width &&
- av1->height == av->height &&
- av1->time_base.den == av->time_base.den &&
- av1->time_base.num == av->time_base.num &&
- av1->gop_size == av->gop_size)
- goto found;
- break;
- default:
- abort();
- }
- }
- }
-
- fst = add_av_stream1(feed, av, 0);
- if (!fst)
- return -1;
- return feed->nb_streams - 1;
- found:
- return i;
-}
-
-static void remove_stream(FFStream *stream)
-{
- FFStream **ps;
- ps = &first_stream;
- while (*ps != NULL) {
- if (*ps == stream)
- *ps = (*ps)->next;
- else
- ps = &(*ps)->next;
- }
-}
-
-/* specific mpeg4 handling : we extract the raw parameters */
-static void extract_mpeg4_header(AVFormatContext *infile)
-{
- int mpeg4_count, i, size;
- AVPacket pkt;
- AVStream *st;
- const uint8_t *p;
-
- mpeg4_count = 0;
- for(i=0;i<infile->nb_streams;i++) {
- st = infile->streams[i];
- if (st->codec->codec_id == CODEC_ID_MPEG4 &&
- st->codec->extradata_size == 0) {
- mpeg4_count++;
- }
- }
- if (!mpeg4_count)
- return;
-
- printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
- while (mpeg4_count > 0) {
- if (av_read_packet(infile, &pkt) < 0)
- break;
- st = infile->streams[pkt.stream_index];
- if (st->codec->codec_id == CODEC_ID_MPEG4 &&
- st->codec->extradata_size == 0) {
- av_freep(&st->codec->extradata);
- /* fill extradata with the header */
- /* XXX: we make hard suppositions here ! */
- p = pkt.data;
- while (p < pkt.data + pkt.size - 4) {
- /* stop when vop header is found */
- if (p[0] == 0x00 && p[1] == 0x00 &&
- p[2] == 0x01 && p[3] == 0xb6) {
- size = p - pkt.data;
- // av_hex_dump_log(infile, AV_LOG_DEBUG, pkt.data, size);
- st->codec->extradata = av_malloc(size);
- st->codec->extradata_size = size;
- memcpy(st->codec->extradata, pkt.data, size);
- break;
- }
- p++;
- }
- mpeg4_count--;
- }
- av_free_packet(&pkt);
- }
-}
-
-/* compute the needed AVStream for each file */
-static void build_file_streams(void)
-{
- FFStream *stream, *stream_next;
- int i, ret;
-
- /* gather all streams */
- for(stream = first_stream; stream != NULL; stream = stream_next) {
- AVFormatContext *infile = NULL;
- stream_next = stream->next;
- if (stream->stream_type == STREAM_TYPE_LIVE &&
- !stream->feed) {
- /* the stream comes from a file */
- /* try to open the file */
- /* open stream */
- if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
- /* specific case : if transport stream output to RTP,
- we use a raw transport stream reader */
- av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
- }
-
- http_log("Opening file '%s'\n", stream->feed_filename);
- if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {
- http_log("Could not open '%s': %d\n", stream->feed_filename, ret);
- /* remove stream (no need to spend more time on it) */
- fail:
- remove_stream(stream);
- } else {
- /* find all the AVStreams inside and reference them in
- 'stream' */
- if (av_find_stream_info(infile) < 0) {
- http_log("Could not find codec parameters from '%s'\n",
- stream->feed_filename);
- av_close_input_file(infile);
- goto fail;
- }
- extract_mpeg4_header(infile);
-
- for(i=0;i<infile->nb_streams;i++)
- add_av_stream1(stream, infile->streams[i]->codec, 1);
-
- av_close_input_file(infile);
- }
- }
- }
-}
-
-/* compute the needed AVStream for each feed */
-static void build_feed_streams(void)
-{
- FFStream *stream, *feed;
- int i;
-
- /* gather all streams */
- for(stream = first_stream; stream != NULL; stream = stream->next) {
- feed = stream->feed;
- if (feed) {
- if (!stream->is_feed) {
- /* we handle a stream coming from a feed */
- for(i=0;i<stream->nb_streams;i++)
- stream->feed_streams[i] = add_av_stream(feed, stream->streams[i]);
- }
- }
- }
-
- /* gather all streams */
- for(stream = first_stream; stream != NULL; stream = stream->next) {
- feed = stream->feed;
- if (feed) {
- if (stream->is_feed) {
- for(i=0;i<stream->nb_streams;i++)
- stream->feed_streams[i] = i;
- }
- }
- }
-
- /* create feed files if needed */
- for(feed = first_feed; feed != NULL; feed = feed->next_feed) {
- int fd;
-
- if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) {
- /* See if it matches */
- AVFormatContext *s = NULL;
- int matches = 0;
-
- if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) {
- /* Now see if it matches */
- if (s->nb_streams == feed->nb_streams) {
- matches = 1;
- for(i=0;i<s->nb_streams;i++) {
- AVStream *sf, *ss;
- sf = feed->streams[i];
- ss = s->streams[i];
-
- if (sf->index != ss->index ||
- sf->id != ss->id) {
- http_log("Index & Id do not match for stream %d (%s)\n",
- i, feed->feed_filename);
- matches = 0;
- } else {
- AVCodecContext *ccf, *ccs;
-
- ccf = sf->codec;
- ccs = ss->codec;
-#define CHECK_CODEC(x) (ccf->x != ccs->x)
-
- if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
- http_log("Codecs do not match for stream %d\n", i);
- matches = 0;
- } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
- http_log("Codec bitrates do not match for stream %d\n", i);
- matches = 0;
- } else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (CHECK_CODEC(time_base.den) ||
- CHECK_CODEC(time_base.num) ||
- CHECK_CODEC(width) ||
- CHECK_CODEC(height)) {
- http_log("Codec width, height and framerate do not match for stream %d\n", i);
- matches = 0;
- }
- } else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) {
- if (CHECK_CODEC(sample_rate) ||
- CHECK_CODEC(channels) ||
- CHECK_CODEC(frame_size)) {
- http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i);
- matches = 0;
- }
- } else {
- http_log("Unknown codec type\n");
- matches = 0;
- }
- }
- if (!matches)
- break;
- }
- } else
- 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
- http_log("Deleting feed file '%s' as it appears to be corrupt\n",
- feed->feed_filename);
-
- if (!matches) {
- if (feed->readonly) {
- http_log("Unable to delete feed file '%s' as it is marked readonly\n",
- feed->feed_filename);
- exit(1);
- }
- unlink(feed->feed_filename);
- }
- }
- if (avio_check(feed->feed_filename, AVIO_FLAG_WRITE) <= 0) {
- AVFormatContext s1 = {0}, *s = &s1;
-
- if (feed->readonly) {
- 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 (avio_open(&s->pb, feed->feed_filename, AVIO_FLAG_WRITE) < 0) {
- http_log("Could not open output feed file '%s'\n",
- feed->feed_filename);
- exit(1);
- }
- s->oformat = feed->fmt;
- s->nb_streams = feed->nb_streams;
- s->streams = feed->streams;
- if (avformat_write_header(s, NULL) < 0) {
- http_log("Container doesn't supports the required parameters\n");
- exit(1);
- }
- /* XXX: need better api */
- av_freep(&s->priv_data);
- avio_close(s->pb);
- }
- /* get feed size and write index */
- fd = open(feed->feed_filename, O_RDONLY);
- if (fd < 0) {
- http_log("Could not open output feed file '%s'\n",
- feed->feed_filename);
- exit(1);
- }
-
- feed->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
- feed->feed_size = lseek(fd, 0, SEEK_END);
- /* ensure that we do not wrap before the end of file */
- if (feed->feed_max_size && feed->feed_max_size < feed->feed_size)
- feed->feed_max_size = feed->feed_size;
-
- close(fd);
- }
-}
-
-/* compute the bandwidth used by each stream */
-static void compute_bandwidth(void)
-{
- unsigned bandwidth;
- int i;
- FFStream *stream;
-
- for(stream = first_stream; stream != NULL; stream = stream->next) {
- bandwidth = 0;
- for(i=0;i<stream->nb_streams;i++) {
- AVStream *st = stream->streams[i];
- switch(st->codec->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- case AVMEDIA_TYPE_VIDEO:
- bandwidth += st->codec->bit_rate;
- break;
- default:
- break;
- }
- }
- stream->bandwidth = (bandwidth + 999) / 1000;
- }
-}
-
-/* add a codec and set the default parameters */
-static void add_codec(FFStream *stream, AVCodecContext *av)
-{
- AVStream *st;
-
- /* compute default parameters */
- switch(av->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- if (av->bit_rate == 0)
- av->bit_rate = 64000;
- if (av->sample_rate == 0)
- av->sample_rate = 22050;
- if (av->channels == 0)
- av->channels = 1;
- break;
- case AVMEDIA_TYPE_VIDEO:
- if (av->bit_rate == 0)
- av->bit_rate = 64000;
- if (av->time_base.num == 0){
- av->time_base.den = 5;
- av->time_base.num = 1;
- }
- if (av->width == 0 || av->height == 0) {
- av->width = 160;
- av->height = 128;
- }
- /* Bitrate tolerance is less for streaming */
- if (av->bit_rate_tolerance == 0)
- av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
- (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
- if (av->qmin == 0)
- av->qmin = 3;
- if (av->qmax == 0)
- av->qmax = 31;
- if (av->max_qdiff == 0)
- av->max_qdiff = 3;
- av->qcompress = 0.5;
- av->qblur = 0.5;
-
- if (!av->nsse_weight)
- av->nsse_weight = 8;
-
- av->frame_skip_cmp = FF_CMP_DCTMAX;
- if (!av->me_method)
- av->me_method = ME_EPZS;
- av->rc_buffer_aggressivity = 1.0;
-
- if (!av->rc_eq)
- av->rc_eq = "tex^qComp";
- if (!av->i_quant_factor)
- av->i_quant_factor = -0.8;
- if (!av->b_quant_factor)
- av->b_quant_factor = 1.25;
- if (!av->b_quant_offset)
- av->b_quant_offset = 1.25;
- if (!av->rc_max_rate)
- av->rc_max_rate = av->bit_rate * 2;
-
- if (av->rc_max_rate && !av->rc_buffer_size) {
- av->rc_buffer_size = av->rc_max_rate;
- }
-
-
- break;
- default:
- abort();
- }
-
- st = av_mallocz(sizeof(AVStream));
- if (!st)
- return;
- st->codec = avcodec_alloc_context();
- stream->streams[stream->nb_streams++] = st;
- memcpy(st->codec, av, sizeof(AVCodecContext));
-}
-
-static enum CodecID opt_audio_codec(const char *arg)
-{
- AVCodec *p= avcodec_find_encoder_by_name(arg);
-
- if (p == NULL || p->type != AVMEDIA_TYPE_AUDIO)
- return CODEC_ID_NONE;
-
- return p->id;
-}
-
-static enum CodecID opt_video_codec(const char *arg)
-{
- AVCodec *p= avcodec_find_encoder_by_name(arg);
-
- if (p == NULL || p->type != AVMEDIA_TYPE_VIDEO)
- return CODEC_ID_NONE;
-
- return p->id;
-}
-
-/* simplistic plugin support */
-
-#if HAVE_DLOPEN
-static void load_module(const char *filename)
-{
- void *dll;
- void (*init_func)(void);
- dll = dlopen(filename, RTLD_NOW);
- if (!dll) {
- fprintf(stderr, "Could not load module '%s' - %s\n",
- filename, dlerror());
- return;
- }
-
- init_func = dlsym(dll, "ffserver_module_init");
- if (!init_func) {
- fprintf(stderr,
- "%s: init function 'ffserver_module_init()' not found\n",
- filename);
- dlclose(dll);
- }
-
- init_func();
-}
-#endif
-
-static int ffserver_opt_default(const char *opt, const char *arg,
- AVCodecContext *avctx, int type)
-{
- int ret = 0;
- const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0);
- if(o)
- ret = av_set_string3(avctx, opt, arg, 1, NULL);
- return ret;
-}
-
-static int ffserver_opt_preset(const char *arg,
- AVCodecContext *avctx, int type,
- enum CodecID *audio_id, enum CodecID *video_id)
-{
- FILE *f=NULL;
- char filename[1000], tmp[1000], tmp2[1000], line[1000];
- int ret = 0;
- AVCodec *codec = avcodec_find_encoder(avctx->codec_id);
-
- if (!(f = get_preset_file(filename, sizeof(filename), arg, 0,
- codec ? codec->name : NULL))) {
- fprintf(stderr, "File for preset '%s' not found\n", arg);
- return 1;
- }
-
- while(!feof(f)){
- int e= fscanf(f, "%999[^\n]\n", line) - 1;
- if(line[0] == '#' && !e)
- continue;
- e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
- if(e){
- fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line);
- ret = 1;
- break;
- }
- if(!strcmp(tmp, "acodec")){
- *audio_id = opt_audio_codec(tmp2);
- }else if(!strcmp(tmp, "vcodec")){
- *video_id = opt_video_codec(tmp2);
- }else if(!strcmp(tmp, "scodec")){
- /* opt_subtitle_codec(tmp2); */
- }else if(ffserver_opt_default(tmp, tmp2, avctx, type) < 0){
- fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2);
- ret = 1;
- break;
- }
- }
-
- fclose(f);
-
- return ret;
-}
-
-static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename,
- const char *mime_type)
-{
- AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
-
- if (fmt) {
- AVOutputFormat *stream_fmt;
- char stream_format_name[64];
-
- snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
- stream_fmt = av_guess_format(stream_format_name, NULL, NULL);
-
- if (stream_fmt)
- fmt = stream_fmt;
- }
-
- return fmt;
-}
-
-static void report_config_error(const char *filename, int line_num, int *errors, const char *fmt, ...)
-{
- va_list vl;
- va_start(vl, fmt);
- fprintf(stderr, "%s:%d: ", filename, line_num);
- vfprintf(stderr, fmt, vl);
- va_end(vl);
-
- (*errors)++;
-}
-
-static int parse_ffconfig(const char *filename)
-{
- FILE *f;
- char line[1024];
- char cmd[64];
- char arg[1024];
- const char *p;
- int val, errors, line_num;
- FFStream **last_stream, *stream, *redirect;
- FFStream **last_feed, *feed, *s;
- AVCodecContext audio_enc, video_enc;
- enum CodecID audio_id, video_id;
-
- f = fopen(filename, "r");
- if (!f) {
- perror(filename);
- return -1;
- }
-
- errors = 0;
- line_num = 0;
- first_stream = NULL;
- last_stream = &first_stream;
- first_feed = NULL;
- last_feed = &first_feed;
- stream = NULL;
- feed = NULL;
- redirect = NULL;
- audio_id = CODEC_ID_NONE;
- video_id = CODEC_ID_NONE;
-
-#define ERROR(...) report_config_error(filename, line_num, &errors, __VA_ARGS__)
- for(;;) {
- if (fgets(line, sizeof(line), f) == NULL)
- break;
- line_num++;
- p = line;
- while (isspace(*p))
- p++;
- if (*p == '\0' || *p == '#')
- continue;
-
- get_arg(cmd, sizeof(cmd), &p);
-
- if (!strcasecmp(cmd, "Port")) {
- get_arg(arg, sizeof(arg), &p);
- val = atoi(arg);
- if (val < 1 || val > 65536) {
- ERROR("Invalid_port: %s\n", arg);
- }
- my_http_addr.sin_port = htons(val);
- } else if (!strcasecmp(cmd, "BindAddress")) {
- get_arg(arg, sizeof(arg), &p);
- if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
- ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
- }
- } else if (!strcasecmp(cmd, "NoDaemon")) {
- ffserver_daemon = 0;
- } else if (!strcasecmp(cmd, "RTSPPort")) {
- get_arg(arg, sizeof(arg), &p);
- val = atoi(arg);
- if (val < 1 || val > 65536) {
- ERROR("%s:%d: Invalid port: %s\n", arg);
- }
- my_rtsp_addr.sin_port = htons(atoi(arg));
- } else if (!strcasecmp(cmd, "RTSPBindAddress")) {
- get_arg(arg, sizeof(arg), &p);
- if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
- ERROR("Invalid host/IP address: %s\n", arg);
- }
- } else if (!strcasecmp(cmd, "MaxHTTPConnections")) {
- get_arg(arg, sizeof(arg), &p);
- val = atoi(arg);
- if (val < 1 || val > 65536) {
- ERROR("Invalid MaxHTTPConnections: %s\n", arg);
- }
- nb_max_http_connections = val;
- } else if (!strcasecmp(cmd, "MaxClients")) {
- get_arg(arg, sizeof(arg), &p);
- val = atoi(arg);
- if (val < 1 || val > nb_max_http_connections) {
- ERROR("Invalid MaxClients: %s\n", arg);
- } else {
- nb_max_connections = val;
- }
- } else if (!strcasecmp(cmd, "MaxBandwidth")) {
- int64_t llval;
- get_arg(arg, sizeof(arg), &p);
- llval = atoll(arg);
- if (llval < 10 || llval > 10000000) {
- ERROR("Invalid MaxBandwidth: %s\n", arg);
- } else
- max_bandwidth = llval;
- } else if (!strcasecmp(cmd, "CustomLog")) {
- if (!ffserver_debug)
- get_arg(logfilename, sizeof(logfilename), &p);
- } else if (!strcasecmp(cmd, "<Feed")) {
- /*********************************************/
- /* Feed related options */
- char *q;
- if (stream || feed) {
- ERROR("Already in a tag\n");
- } else {
- feed = av_mallocz(sizeof(FFStream));
- get_arg(feed->filename, sizeof(feed->filename), &p);
- q = strrchr(feed->filename, '>');
- if (*q)
- *q = '\0';
-
- for (s = first_feed; s; s = s->next) {
- if (!strcmp(feed->filename, s->filename)) {
- ERROR("Feed '%s' already registered\n", s->filename);
- }
- }
-
- feed->fmt = av_guess_format("ffm", NULL, NULL);
- /* defaut feed file */
- snprintf(feed->feed_filename, sizeof(feed->feed_filename),
- "/tmp/%s.ffm", feed->filename);
- feed->feed_max_size = 5 * 1024 * 1024;
- feed->is_feed = 1;
- feed->feed = feed; /* self feeding :-) */
-
- /* add in stream list */
- *last_stream = feed;
- last_stream = &feed->next;
- /* add in feed list */
- *last_feed = feed;
- last_feed = &feed->next_feed;
- }
- } else if (!strcasecmp(cmd, "Launch")) {
- if (feed) {
- int i;
-
- feed->child_argv = av_mallocz(64 * sizeof(char *));
-
- for (i = 0; i < 62; i++) {
- get_arg(arg, sizeof(arg), &p);
- if (!arg[0])
- break;
-
- feed->child_argv[i] = av_strdup(arg);
- }
-
- feed->child_argv[i] = av_malloc(30 + strlen(feed->filename));
-
- snprintf(feed->child_argv[i], 30+strlen(feed->filename),
- "http://%s:%d/%s",
- (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);
- }
- } else if (!strcasecmp(cmd, "ReadOnlyFile")) {
- if (feed) {
- get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
- feed->readonly = 1;
- } else if (stream) {
- get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
- }
- } else if (!strcasecmp(cmd, "File")) {
- if (feed) {
- get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
- } else if (stream)
- get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
- } else if (!strcasecmp(cmd, "Truncate")) {
- if (feed) {
- get_arg(arg, sizeof(arg), &p);
- feed->truncate = strtod(arg, NULL);
- }
- } else if (!strcasecmp(cmd, "FileMaxSize")) {
- if (feed) {
- char *p1;
- double fsize;
-
- get_arg(arg, sizeof(arg), &p);
- p1 = arg;
- fsize = strtod(p1, &p1);
- switch(toupper(*p1)) {
- case 'K':
- fsize *= 1024;
- break;
- case 'M':
- fsize *= 1024 * 1024;
- break;
- case 'G':
- fsize *= 1024 * 1024 * 1024;
- break;
- }
- feed->feed_max_size = (int64_t)fsize;
- if (feed->feed_max_size < FFM_PACKET_SIZE*4) {
- ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4);
- }
- }
- } else if (!strcasecmp(cmd, "</Feed>")) {
- if (!feed) {
- ERROR("No corresponding <Feed> for </Feed>\n");
- }
- feed = NULL;
- } else if (!strcasecmp(cmd, "<Stream")) {
- /*********************************************/
- /* Stream related options */
- char *q;
- if (stream || feed) {
- ERROR("Already in a tag\n");
- } else {
- FFStream *s;
- stream = av_mallocz(sizeof(FFStream));
- get_arg(stream->filename, sizeof(stream->filename), &p);
- q = strrchr(stream->filename, '>');
- if (*q)
- *q = '\0';
-
- for (s = first_stream; s; s = s->next) {
- if (!strcmp(stream->filename, s->filename)) {
- ERROR("Stream '%s' already registered\n", s->filename);
- }
- }
-
- stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL);
- avcodec_get_context_defaults2(&video_enc, AVMEDIA_TYPE_VIDEO);
- avcodec_get_context_defaults2(&audio_enc, AVMEDIA_TYPE_AUDIO);
- audio_id = CODEC_ID_NONE;
- video_id = CODEC_ID_NONE;
- if (stream->fmt) {
- audio_id = stream->fmt->audio_codec;
- video_id = stream->fmt->video_codec;
- }
-
- *last_stream = stream;
- last_stream = &stream->next;
- }
- } else if (!strcasecmp(cmd, "Feed")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- FFStream *sfeed;
-
- sfeed = first_feed;
- while (sfeed != NULL) {
- if (!strcmp(sfeed->filename, arg))
- break;
- sfeed = sfeed->next_feed;
- }
- if (!sfeed)
- ERROR("feed '%s' not defined\n", arg);
- else
- stream->feed = sfeed;
- }
- } 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 = ffserver_guess_format(arg, NULL, NULL);
- if (!stream->fmt) {
- ERROR("Unknown Format: %s\n", arg);
- }
- }
- 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);
- if (stream) {
- stream->ifmt = av_find_input_format(arg);
- if (!stream->ifmt) {
- ERROR("Unknown input format: %s\n", arg);
- }
- }
- } else if (!strcasecmp(cmd, "FaviconURL")) {
- if (stream && stream->stream_type == STREAM_TYPE_STATUS) {
- get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
- } else {
- ERROR("FaviconURL only permitted for status streams\n");
- }
- } else if (!strcasecmp(cmd, "Author")) {
- if (stream)
- get_arg(stream->author, sizeof(stream->author), &p);
- } else if (!strcasecmp(cmd, "Comment")) {
- if (stream)
- get_arg(stream->comment, sizeof(stream->comment), &p);
- } else if (!strcasecmp(cmd, "Copyright")) {
- if (stream)
- get_arg(stream->copyright, sizeof(stream->copyright), &p);
- } else if (!strcasecmp(cmd, "Title")) {
- if (stream)
- get_arg(stream->title, sizeof(stream->title), &p);
- } else if (!strcasecmp(cmd, "Preroll")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- stream->prebuffer = atof(arg) * 1000;
- } else if (!strcasecmp(cmd, "StartSendOnKey")) {
- if (stream)
- stream->send_on_key = 1;
- } else if (!strcasecmp(cmd, "AudioCodec")) {
- get_arg(arg, sizeof(arg), &p);
- audio_id = opt_audio_codec(arg);
- if (audio_id == CODEC_ID_NONE) {
- ERROR("Unknown AudioCodec: %s\n", arg);
- }
- } else if (!strcasecmp(cmd, "VideoCodec")) {
- get_arg(arg, sizeof(arg), &p);
- video_id = opt_video_codec(arg);
- if (video_id == CODEC_ID_NONE) {
- ERROR("Unknown VideoCodec: %s\n", arg);
- }
- } else if (!strcasecmp(cmd, "MaxTime")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- stream->max_time = atof(arg) * 1000;
- } else if (!strcasecmp(cmd, "AudioBitRate")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- audio_enc.bit_rate = lrintf(atof(arg) * 1000);
- } else if (!strcasecmp(cmd, "AudioChannels")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- audio_enc.channels = atoi(arg);
- } else if (!strcasecmp(cmd, "AudioSampleRate")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- audio_enc.sample_rate = atoi(arg);
- } else if (!strcasecmp(cmd, "AudioQuality")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
-// audio_enc.quality = atof(arg) * 1000;
- }
- } else if (!strcasecmp(cmd, "VideoBitRateRange")) {
- if (stream) {
- int minrate, maxrate;
-
- get_arg(arg, sizeof(arg), &p);
-
- if (sscanf(arg, "%d-%d", &minrate, &maxrate) == 2) {
- video_enc.rc_min_rate = minrate * 1000;
- video_enc.rc_max_rate = maxrate * 1000;
- } else {
- ERROR("Incorrect format for VideoBitRateRange -- should be <min>-<max>: %s\n", arg);
- }
- }
- } else if (!strcasecmp(cmd, "Debug")) {
- if (stream) {
- get_arg(arg, sizeof(arg), &p);
- video_enc.debug = strtol(arg,0,0);
- }
- } else if (!strcasecmp(cmd, "Strict")) {
- if (stream) {
- get_arg(arg, sizeof(arg), &p);
- video_enc.strict_std_compliance = atoi(arg);
- }
- } else if (!strcasecmp(cmd, "VideoBufferSize")) {
- if (stream) {
- get_arg(arg, sizeof(arg), &p);
- video_enc.rc_buffer_size = atoi(arg) * 8*1024;
- }
- } else if (!strcasecmp(cmd, "VideoBitRateTolerance")) {
- if (stream) {
- get_arg(arg, sizeof(arg), &p);
- video_enc.bit_rate_tolerance = atoi(arg) * 1000;
- }
- } else if (!strcasecmp(cmd, "VideoBitRate")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.bit_rate = atoi(arg) * 1000;
- }
- } else if (!strcasecmp(cmd, "VideoSize")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- av_parse_video_size(&video_enc.width, &video_enc.height, arg);
- if ((video_enc.width % 16) != 0 ||
- (video_enc.height % 16) != 0) {
- ERROR("Image size must be a multiple of 16\n");
- }
- }
- } else if (!strcasecmp(cmd, "VideoFrameRate")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- AVRational frame_rate;
- if (av_parse_video_rate(&frame_rate, arg) < 0) {
- ERROR("Incorrect frame rate: %s\n", arg);
- } else {
- video_enc.time_base.num = frame_rate.den;
- video_enc.time_base.den = frame_rate.num;
- }
- }
- } else if (!strcasecmp(cmd, "VideoGopSize")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- video_enc.gop_size = atoi(arg);
- } else if (!strcasecmp(cmd, "VideoIntraOnly")) {
- if (stream)
- video_enc.gop_size = 1;
- } else if (!strcasecmp(cmd, "VideoHighQuality")) {
- if (stream)
- video_enc.mb_decision = FF_MB_DECISION_BITS;
- } else if (!strcasecmp(cmd, "Video4MotionVector")) {
- if (stream) {
- video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove
- video_enc.flags |= CODEC_FLAG_4MV;
- }
- } else if (!strcasecmp(cmd, "AVOptionVideo") ||
- !strcasecmp(cmd, "AVOptionAudio")) {
- char arg2[1024];
- AVCodecContext *avctx;
- int type;
- get_arg(arg, sizeof(arg), &p);
- get_arg(arg2, sizeof(arg2), &p);
- if (!strcasecmp(cmd, "AVOptionVideo")) {
- avctx = &video_enc;
- type = AV_OPT_FLAG_VIDEO_PARAM;
- } else {
- avctx = &audio_enc;
- type = AV_OPT_FLAG_AUDIO_PARAM;
- }
- if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
- ERROR("AVOption error: %s %s\n", arg, arg2);
- }
- } else if (!strcasecmp(cmd, "AVPresetVideo") ||
- !strcasecmp(cmd, "AVPresetAudio")) {
- AVCodecContext *avctx;
- int type;
- get_arg(arg, sizeof(arg), &p);
- if (!strcasecmp(cmd, "AVPresetVideo")) {
- avctx = &video_enc;
- video_enc.codec_id = video_id;
- type = AV_OPT_FLAG_VIDEO_PARAM;
- } else {
- avctx = &audio_enc;
- audio_enc.codec_id = audio_id;
- type = AV_OPT_FLAG_AUDIO_PARAM;
- }
- if (ffserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
- ERROR("AVPreset error: %s\n", arg);
- }
- } else if (!strcasecmp(cmd, "VideoTag")) {
- get_arg(arg, sizeof(arg), &p);
- if ((strlen(arg) == 4) && stream)
- video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]);
- } else if (!strcasecmp(cmd, "BitExact")) {
- if (stream)
- video_enc.flags |= CODEC_FLAG_BITEXACT;
- } else if (!strcasecmp(cmd, "DctFastint")) {
- if (stream)
- video_enc.dct_algo = FF_DCT_FASTINT;
- } else if (!strcasecmp(cmd, "IdctSimple")) {
- if (stream)
- video_enc.idct_algo = FF_IDCT_SIMPLE;
- } else if (!strcasecmp(cmd, "Qscale")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.flags |= CODEC_FLAG_QSCALE;
- video_enc.global_quality = FF_QP2LAMBDA * atoi(arg);
- }
- } else if (!strcasecmp(cmd, "VideoQDiff")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.max_qdiff = atoi(arg);
- if (video_enc.max_qdiff < 1 || video_enc.max_qdiff > 31) {
- ERROR("VideoQDiff out of range\n");
- }
- }
- } else if (!strcasecmp(cmd, "VideoQMax")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.qmax = atoi(arg);
- if (video_enc.qmax < 1 || video_enc.qmax > 31) {
- ERROR("VideoQMax out of range\n");
- }
- }
- } else if (!strcasecmp(cmd, "VideoQMin")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.qmin = atoi(arg);
- if (video_enc.qmin < 1 || video_enc.qmin > 31) {
- ERROR("VideoQMin out of range\n");
- }
- }
- } else if (!strcasecmp(cmd, "LumaElim")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- video_enc.luma_elim_threshold = atoi(arg);
- } else if (!strcasecmp(cmd, "ChromaElim")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- video_enc.chroma_elim_threshold = atoi(arg);
- } else if (!strcasecmp(cmd, "LumiMask")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- video_enc.lumi_masking = atof(arg);
- } else if (!strcasecmp(cmd, "DarkMask")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- video_enc.dark_masking = atof(arg);
- } else if (!strcasecmp(cmd, "NoVideo")) {
- video_id = CODEC_ID_NONE;
- } else if (!strcasecmp(cmd, "NoAudio")) {
- audio_id = CODEC_ID_NONE;
- } else if (!strcasecmp(cmd, "ACL")) {
- parse_acl_row(stream, feed, NULL, p, filename, line_num);
- } else if (!strcasecmp(cmd, "DynamicACL")) {
- if (stream) {
- get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p);
- }
- } else if (!strcasecmp(cmd, "RTSPOption")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- av_freep(&stream->rtsp_option);
- stream->rtsp_option = av_strdup(arg);
- }
- } else if (!strcasecmp(cmd, "MulticastAddress")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- if (resolve_host(&stream->multicast_ip, arg) != 0) {
- ERROR("Invalid host/IP address: %s\n", arg);
- }
- stream->is_multicast = 1;
- stream->loop = 1; /* default is looping */
- }
- } else if (!strcasecmp(cmd, "MulticastPort")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- stream->multicast_port = atoi(arg);
- } else if (!strcasecmp(cmd, "MulticastTTL")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- stream->multicast_ttl = atoi(arg);
- } else if (!strcasecmp(cmd, "NoLoop")) {
- if (stream)
- stream->loop = 0;
- } else if (!strcasecmp(cmd, "</Stream>")) {
- if (!stream) {
- ERROR("No corresponding <Stream> for </Stream>\n");
- } else {
- if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) {
- if (audio_id != CODEC_ID_NONE) {
- audio_enc.codec_type = AVMEDIA_TYPE_AUDIO;
- audio_enc.codec_id = audio_id;
- add_codec(stream, &audio_enc);
- }
- if (video_id != CODEC_ID_NONE) {
- video_enc.codec_type = AVMEDIA_TYPE_VIDEO;
- video_enc.codec_id = video_id;
- add_codec(stream, &video_enc);
- }
- }
- stream = NULL;
- }
- } else if (!strcasecmp(cmd, "<Redirect")) {
- /*********************************************/
- char *q;
- if (stream || feed || redirect) {
- ERROR("Already in a tag\n");
- } else {
- redirect = av_mallocz(sizeof(FFStream));
- *last_stream = redirect;
- last_stream = &redirect->next;
-
- get_arg(redirect->filename, sizeof(redirect->filename), &p);
- q = strrchr(redirect->filename, '>');
- if (*q)
- *q = '\0';
- redirect->stream_type = STREAM_TYPE_REDIRECT;
- }
- } else if (!strcasecmp(cmd, "URL")) {
- if (redirect)
- get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p);
- } else if (!strcasecmp(cmd, "</Redirect>")) {
- if (!redirect) {
- ERROR("No corresponding <Redirect> for </Redirect>\n");
- } else {
- if (!redirect->feed_filename[0]) {
- ERROR("No URL found for <Redirect>\n");
- }
- redirect = NULL;
- }
- } else if (!strcasecmp(cmd, "LoadModule")) {
- get_arg(arg, sizeof(arg), &p);
-#if HAVE_DLOPEN
- load_module(arg);
-#else
- ERROR("Module support not compiled into this version: '%s'\n", arg);
-#endif
- } else {
- ERROR("Incorrect keyword: '%s'\n", cmd);
- }
- }
-#undef ERROR
-
- fclose(f);
- if (errors)
- return -1;
- else
- return 0;
-}
-
-static void handle_child_exit(int sig)
-{
- pid_t pid;
- int status;
-
- while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
- FFStream *feed;
-
- for (feed = first_feed; feed; feed = feed->next) {
- if (feed->pid == pid) {
- int uptime = time(0) - feed->pid_start;
-
- feed->pid = 0;
- fprintf(stderr, "%s: Pid %d exited with status %d after %d seconds\n", feed->filename, pid, status, uptime);
-
- if (uptime < 30)
- /* Turn off any more restarts */
- feed->child_argv = 0;
- }
- }
- }
-
- need_to_start_children = 1;
-}
-
-static void opt_debug(void)
-{
- ffserver_debug = 1;
- ffserver_daemon = 0;
- logfilename[0] = '-';
-}
-
-static void show_help(void)
-{
- printf("usage: ffserver [options]\n"
- "Hyper fast multi format Audio/Video streaming server\n");
- printf("\n");
- show_help_options(options, "Main options:\n", 0, 0);
-}
-
-static const OptionDef options[] = {
-#include "cmdutils_common_opts.h"
- { "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" },
- { "d", 0, {(void*)opt_debug}, "enable debug mode" },
- { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/ffserver.conf", "configfile" },
- { NULL },
-};
-
-int main(int argc, char **argv)
-{
- struct sigaction sigact;
-
- av_register_all();
-
- show_banner();
-
- my_program_name = argv[0];
- my_program_dir = getcwd(0, 0);
- ffserver_daemon = 1;
-
- parse_options(argc, argv, options, NULL);
-
- unsetenv("http_proxy"); /* Kill the http_proxy */
-
- av_lfg_init(&random_state, av_get_random_seed());
-
- memset(&sigact, 0, sizeof(sigact));
- sigact.sa_handler = handle_child_exit;
- sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART;
- sigaction(SIGCHLD, &sigact, 0);
-
- if (parse_ffconfig(config_filename) < 0) {
- fprintf(stderr, "Incorrect config file - exiting.\n");
- 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();
-
- compute_bandwidth();
-
- /* put the process in background and detach it from its TTY */
- if (ffserver_daemon) {
- int pid;
-
- pid = fork();
- if (pid < 0) {
- perror("fork");
- exit(1);
- } else if (pid > 0) {
- /* parent : exit */
- exit(0);
- } else {
- /* child */
- setsid();
- close(0);
- open("/dev/null", O_RDWR);
- if (strcmp(logfilename, "-") != 0) {
- close(1);
- dup(0);
- }
- close(2);
- dup(0);
- }
- }
-
- /* signal init */
- signal(SIGPIPE, SIG_IGN);
-
- if (ffserver_daemon)
- chdir("/");
-
- if (http_server() < 0) {
- http_log("Could not start server\n");
- exit(1);
- }
-
- return 0;
-}
diff --git a/ffserver.h b/ffserver.h
deleted file mode 100644
index 43bc79c..0000000
--- a/ffserver.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Multiple format streaming server
- * copyright (c) 2002 Fabrice Bellard
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef LIBAV_FFSERVER_H
-#define LIBAV_FFSERVER_H
-
-/* interface between ffserver and modules */
-
-void ffserver_module_init(void);
-
-#endif /* LIBAV_FFSERVER_H */
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index ed83259..83f0a12 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -132,8 +132,8 @@ typedef struct FourXContext{
AVFrame current_picture, last_picture;
GetBitContext pre_gb; ///< ac/dc prefix
GetBitContext gb;
- const uint8_t *bytestream;
- const uint16_t *wordstream;
+ GetByteContext g;
+ GetByteContext g2;
int mv[256];
VLC pre_vlc;
int last_dc;
@@ -277,7 +277,7 @@ static void init_mv(FourXContext *f){
}
#endif
-static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){
+static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, unsigned dc){
int i;
dc*= 0x10001;
@@ -328,7 +328,7 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo
assert(code>=0 && code<=6);
if(code == 0){
- src += f->mv[ *f->bytestream++ ];
+ src += f->mv[bytestream2_get_byte(&f->g)];
if(start > src || src > end){
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
return;
@@ -345,21 +345,21 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo
}else if(code == 3 && f->version<2){
mcdc(dst, src, log2w, h, stride, 1, 0);
}else if(code == 4){
- src += f->mv[ *f->bytestream++ ];
+ src += f->mv[bytestream2_get_byte(&f->g)];
if(start > src || src > end){
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
return;
}
- mcdc(dst, src, log2w, h, stride, 1, av_le2ne16(*f->wordstream++));
+ mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16(&f->g2));
}else if(code == 5){
- mcdc(dst, src, log2w, h, stride, 0, av_le2ne16(*f->wordstream++));
+ mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2));
}else if(code == 6){
if(log2w){
- dst[0] = av_le2ne16(*f->wordstream++);
- dst[1] = av_le2ne16(*f->wordstream++);
+ dst[0] = bytestream2_get_le16(&f->g2);
+ dst[1] = bytestream2_get_le16(&f->g2);
}else{
- dst[0 ] = av_le2ne16(*f->wordstream++);
- dst[stride] = av_le2ne16(*f->wordstream++);
+ dst[0 ] = bytestream2_get_le16(&f->g2);
+ dst[stride] = bytestream2_get_le16(&f->g2);
}
}
}
@@ -371,7 +371,7 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
uint16_t *src= (uint16_t*)f->last_picture.data[0];
uint16_t *dst= (uint16_t*)f->current_picture.data[0];
const int stride= f->current_picture.linesize[0]>>1;
- unsigned int bitstream_size, bytestream_size, wordstream_size, extra;
+ unsigned int bitstream_size, bytestream_size, wordstream_size, extra, bytestream_offset, wordstream_offset;
if(f->version>1){
extra=20;
@@ -399,10 +399,13 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
if (!f->bitstream_buffer)
return AVERROR(ENOMEM);
f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4);
+ memset((uint8_t*)f->bitstream_buffer + bitstream_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size);
- f->wordstream= (const uint16_t*)(buf + extra + bitstream_size);
- f->bytestream= buf + extra + bitstream_size + wordstream_size;
+ wordstream_offset = extra + bitstream_size;
+ bytestream_offset = extra + bitstream_size + wordstream_size;
+ bytestream2_init(&f->g2, buf + wordstream_offset, length - wordstream_offset);
+ bytestream2_init(&f->g, buf + bytestream_offset, length - bytestream_offset);
init_mv(f);
@@ -414,15 +417,6 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
dst += 8*stride;
}
- if( bitstream_size != (get_bits_count(&f->gb)+31)/32*4
- || (((const char*)f->wordstream - (const char*)buf + 2)&~2) != extra + bitstream_size + wordstream_size
- || (((const char*)f->bytestream - (const char*)buf + 3)&~3) != extra + bitstream_size + wordstream_size + bytestream_size)
- av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n",
- bitstream_size - (get_bits_count(&f->gb)+31)/32*4,
- -(((const char*)f->bytestream - (const char*)buf + 3)&~3) + (extra + bitstream_size + wordstream_size + bytestream_size),
- -(((const char*)f->wordstream - (const char*)buf + 2)&~2) + (extra + bitstream_size + wordstream_size)
- );
-
return 0;
}
@@ -601,9 +595,10 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const
len_tab[j]= len;
}
- init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257,
- len_tab , 1, 1,
- bits_tab, 4, 4, 0);
+ if (init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257,
+ len_tab , 1, 1,
+ bits_tab, 4, 4, 0))
+ return NULL;
return ptr;
}
@@ -655,8 +650,6 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){
int x, y;
const int width= f->avctx->width;
const int height= f->avctx->height;
- uint16_t *dst= (uint16_t*)f->current_picture.data[0];
- const int stride= f->current_picture.linesize[0]>>1;
const unsigned int bitstream_size= AV_RL32(buf);
int token_count av_unused;
unsigned int prestream_size;
@@ -688,6 +681,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){
if (!f->bitstream_buffer)
return AVERROR(ENOMEM);
f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream, prestream_size/4);
+ memset((uint8_t*)f->bitstream_buffer + prestream_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size);
f->last_dc= 0*128*8*8;
@@ -699,7 +693,6 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){
idct_put(f, x, y);
}
- dst += 16*stride;
}
if(get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256)
@@ -875,15 +868,14 @@ static av_cold int decode_end(AVCodecContext *avctx){
}
AVCodec ff_fourxm_decoder = {
- "4xm",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_4XM,
- sizeof(FourXContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "4xm",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_4XM,
+ .priv_data_size = sizeof(FourXContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("4X Movie"),
};
diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c
index 055715f..de8dd8e 100644
--- a/libavcodec/8bps.c
+++ b/libavcodec/8bps.c
@@ -221,14 +221,13 @@ static av_cold int decode_end(AVCodecContext *avctx)
AVCodec ff_eightbps_decoder = {
- "8bps",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_8BPS,
- sizeof(EightBpsContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
+ .name = "8bps",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_8BPS,
+ .priv_data_size = sizeof(EightBpsContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
};
diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c
index 5fdea91..4f11b8b 100644
--- a/libavcodec/8svx.c
+++ b/libavcodec/8svx.c
@@ -23,6 +23,7 @@
* @file
* 8svx audio decoder
* @author Jaikrishnan Menon
+ *
* supports: fibonacci delta encoding
* : exponential encoding
*/
@@ -31,46 +32,141 @@
/** decoder context */
typedef struct EightSvxContext {
- int16_t fib_acc;
- const int16_t *table;
+ AVFrame frame;
+ uint8_t fib_acc[2];
+ const int8_t *table;
+
+ /* buffer used to store the whole first packet.
+ data is only sent as one large packet */
+ uint8_t *data[2];
+ int data_size;
+ int data_idx;
} EightSvxContext;
-static const int16_t fibonacci[16] = { -34<<8, -21<<8, -13<<8, -8<<8, -5<<8, -3<<8, -2<<8, -1<<8,
- 0, 1<<8, 2<<8, 3<<8, 5<<8, 8<<8, 13<<8, 21<<8 };
-static const int16_t exponential[16] = { -128<<8, -64<<8, -32<<8, -16<<8, -8<<8, -4<<8, -2<<8, -1<<8,
- 0, 1<<8, 2<<8, 4<<8, 8<<8, 16<<8, 32<<8, 64<<8 };
+static const int8_t fibonacci[16] = { -34, -21, -13, -8, -5, -3, -2, -1,
+ 0, 1, 2, 3, 5, 8, 13, 21 };
+static const int8_t exponential[16] = { -128, -64, -32, -16, -8, -4, -2, -1,
+ 0, 1, 2, 4, 8, 16, 32, 64 };
+
+#define MAX_FRAME_SIZE 32768
+
+/**
+ * Delta decode the compressed values in src, and put the resulting
+ * decoded samples in dst.
+ *
+ * @param[in,out] state starting value. it is saved for use in the next call.
+ */
+static void delta_decode(uint8_t *dst, const uint8_t *src, int src_size,
+ uint8_t *state, const int8_t *table, int channels)
+{
+ uint8_t val = *state;
+
+ while (src_size--) {
+ uint8_t d = *src++;
+ val = av_clip_uint8(val + table[d & 0xF]);
+ *dst = val;
+ dst += channels;
+ val = av_clip_uint8(val + table[d >> 4]);
+ *dst = val;
+ dst += channels;
+ }
+
+ *state = val;
+}
+
+static void raw_decode(uint8_t *dst, const int8_t *src, int src_size,
+ int channels)
+{
+ while (src_size--) {
+ *dst = *src++ + 128;
+ dst += channels;
+ }
+}
/** decode a frame */
-static int eightsvx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
- AVPacket *avpkt)
+static int eightsvx_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
EightSvxContext *esc = avctx->priv_data;
- int16_t *out_data = data;
- int consumed = buf_size;
- const uint8_t *buf_end = buf + buf_size;
+ int buf_size;
+ uint8_t *out_data;
+ int ret;
+ int is_compr = (avctx->codec_id != CODEC_ID_PCM_S8_PLANAR);
+
+ /* for the first packet, copy data to buffer */
+ if (avpkt->data) {
+ int hdr_size = is_compr ? 2 : 0;
+ int chan_size = (avpkt->size - hdr_size * avctx->channels) / avctx->channels;
- if((*data_size >> 2) < buf_size)
- return -1;
+ if (avpkt->size < hdr_size * avctx->channels) {
+ av_log(avctx, AV_LOG_ERROR, "packet size is too small\n");
+ return AVERROR(EINVAL);
+ }
+ if (esc->data[0]) {
+ av_log(avctx, AV_LOG_ERROR, "unexpected data after first packet\n");
+ return AVERROR(EINVAL);
+ }
- if(avctx->frame_number == 0) {
- esc->fib_acc = buf[1] << 8;
- buf_size -= 2;
- buf += 2;
+ if (is_compr) {
+ esc->fib_acc[0] = avpkt->data[1] + 128;
+ if (avctx->channels == 2)
+ esc->fib_acc[1] = avpkt->data[2+chan_size+1] + 128;
+ }
+
+ esc->data_idx = 0;
+ esc->data_size = chan_size;
+ if (!(esc->data[0] = av_malloc(chan_size)))
+ return AVERROR(ENOMEM);
+ if (avctx->channels == 2) {
+ if (!(esc->data[1] = av_malloc(chan_size))) {
+ av_freep(&esc->data[0]);
+ return AVERROR(ENOMEM);
+ }
+ }
+ memcpy(esc->data[0], &avpkt->data[hdr_size], chan_size);
+ if (avctx->channels == 2)
+ memcpy(esc->data[1], &avpkt->data[2*hdr_size+chan_size], chan_size);
+ }
+ if (!esc->data[0]) {
+ av_log(avctx, AV_LOG_ERROR, "unexpected empty packet\n");
+ return AVERROR(EINVAL);
}
- *data_size = buf_size << 2;
+ /* decode next piece of data from the buffer */
+ buf_size = FFMIN(MAX_FRAME_SIZE, esc->data_size - esc->data_idx);
+ if (buf_size <= 0) {
+ *got_frame_ptr = 0;
+ return avpkt->size;
+ }
+
+ /* get output buffer */
+ esc->frame.nb_samples = buf_size * (is_compr + 1);
+ if ((ret = avctx->get_buffer(avctx, &esc->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ out_data = esc->frame.data[0];
- while(buf < buf_end) {
- uint8_t d = *buf++;
- esc->fib_acc += esc->table[d & 0x0f];
- *out_data++ = esc->fib_acc;
- esc->fib_acc += esc->table[d >> 4];
- *out_data++ = esc->fib_acc;
+ if (is_compr) {
+ delta_decode(out_data, &esc->data[0][esc->data_idx], buf_size,
+ &esc->fib_acc[0], esc->table, avctx->channels);
+ if (avctx->channels == 2) {
+ delta_decode(&out_data[1], &esc->data[1][esc->data_idx], buf_size,
+ &esc->fib_acc[1], esc->table, avctx->channels);
}
+ } else {
+ int ch;
+ for (ch = 0; ch < avctx->channels; ch++) {
+ raw_decode((int8_t *)&out_data[ch], &esc->data[ch][esc->data_idx],
+ buf_size, avctx->channels);
+ }
+ }
+ esc->data_idx += buf_size;
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = esc->frame;
- return consumed;
+ return avpkt->size;
}
/** initialize 8svx decoder */
@@ -78,6 +174,11 @@ static av_cold int eightsvx_decode_init(AVCodecContext *avctx)
{
EightSvxContext *esc = avctx->priv_data;
+ if (avctx->channels < 1 || avctx->channels > 2) {
+ av_log(avctx, AV_LOG_ERROR, "8SVX does not support more than 2 channels\n");
+ return AVERROR(EINVAL);
+ }
+
switch(avctx->codec->id) {
case CODEC_ID_8SVX_FIB:
esc->table = fibonacci;
@@ -85,10 +186,26 @@ static av_cold int eightsvx_decode_init(AVCodecContext *avctx)
case CODEC_ID_8SVX_EXP:
esc->table = exponential;
break;
+ case CODEC_ID_PCM_S8_PLANAR:
+ break;
default:
return -1;
}
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ avctx->sample_fmt = AV_SAMPLE_FMT_U8;
+
+ avcodec_get_frame_defaults(&esc->frame);
+ avctx->coded_frame = &esc->frame;
+
+ return 0;
+}
+
+static av_cold int eightsvx_decode_close(AVCodecContext *avctx)
+{
+ EightSvxContext *esc = avctx->priv_data;
+
+ av_freep(&esc->data[0]);
+ av_freep(&esc->data[1]);
+
return 0;
}
@@ -98,7 +215,9 @@ AVCodec ff_eightsvx_fib_decoder = {
.id = CODEC_ID_8SVX_FIB,
.priv_data_size = sizeof (EightSvxContext),
.init = eightsvx_decode_init,
+ .close = eightsvx_decode_close,
.decode = eightsvx_decode_frame,
+ .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
};
@@ -108,6 +227,20 @@ AVCodec ff_eightsvx_exp_decoder = {
.id = CODEC_ID_8SVX_EXP,
.priv_data_size = sizeof (EightSvxContext),
.init = eightsvx_decode_init,
+ .close = eightsvx_decode_close,
.decode = eightsvx_decode_frame,
+ .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"),
};
+
+AVCodec ff_pcm_s8_planar_decoder = {
+ .name = "pcm_s8_planar",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_PCM_S8_PLANAR,
+ .priv_data_size = sizeof(EightSvxContext),
+ .init = eightsvx_decode_init,
+ .close = eightsvx_decode_close,
+ .decode = eightsvx_decode_frame,
+ .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("PCM signed 8-bit planar"),
+};
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 0cfa08c..741df91 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1,9 +1,7 @@
-include $(SUBDIR)../config.mak
-
NAME = avcodec
FFLIBS = avutil
-HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vdpau.h version.h xvmc.h
+HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vda.h vdpau.h version.h xvmc.h
OBJS = allcodecs.o \
audioconvert.o \
@@ -47,6 +45,7 @@ RDFT-OBJS-$(CONFIG_HARDCODED_TABLES) += sin_tables.o
OBJS-$(CONFIG_RDFT) += rdft.o $(RDFT-OBJS-yes)
OBJS-$(CONFIG_SINEWIN) += sinewin.o
OBJS-$(CONFIG_VAAPI) += vaapi.o
+OBJS-$(CONFIG_VDA) += vda.o
OBJS-$(CONFIG_VDPAU) += vdpau.o
# decoders/encoders/hardware accelerators
@@ -91,11 +90,13 @@ OBJS-$(CONFIG_AURA2_DECODER) += aura.o
OBJS-$(CONFIG_AVS_DECODER) += avs.o
OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o
OBJS-$(CONFIG_BFI_DECODER) += bfi.o
-OBJS-$(CONFIG_BINK_DECODER) += bink.o binkidct.o
+OBJS-$(CONFIG_BINK_DECODER) += bink.o binkdsp.o
OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.o wma.o
OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.o wma.o
OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o
OBJS-$(CONFIG_BMP_ENCODER) += bmpenc.o
+OBJS-$(CONFIG_BMV_VIDEO_DECODER) += bmv.o
+OBJS-$(CONFIG_BMV_AUDIO_DECODER) += bmv.o
OBJS-$(CONFIG_C93_DECODER) += c93.o
OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o \
mpeg12data.o mpegvideo.o
@@ -124,9 +125,10 @@ OBJS-$(CONFIG_DVDSUB_ENCODER) += dvdsubenc.o
OBJS-$(CONFIG_DVVIDEO_DECODER) += dv.o dvdata.o
OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o dvdata.o
OBJS-$(CONFIG_DXA_DECODER) += dxa.o
-OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3dec_data.o
+OBJS-$(CONFIG_DXTORY_DECODER) += dxtory.o
+OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3_data.o
OBJS-$(CONFIG_EAC3_ENCODER) += eac3enc.o ac3enc.o ac3enc_float.o \
- ac3tab.o ac3.o kbdwin.o
+ ac3tab.o ac3.o kbdwin.o eac3_data.o
OBJS-$(CONFIG_EACMV_DECODER) += eacmv.o
OBJS-$(CONFIG_EAMAD_DECODER) += eamad.o eaidct.o mpeg12.o \
mpeg12data.o mpegvideo.o \
@@ -148,6 +150,7 @@ OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o
OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o
OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o
OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o
+OBJS-$(CONFIG_FLASHSV2_DECODER) += flashsv.o
OBJS-$(CONFIG_FLIC_DECODER) += flicvideo.o
OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o
OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o
@@ -179,6 +182,7 @@ OBJS-$(CONFIG_H264_DECODER) += h264.o \
mpegvideo.o error_resilience.o
OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o
OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o
+OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o
OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o
OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o
OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o
@@ -187,6 +191,7 @@ OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o
OBJS-$(CONFIG_IMC_DECODER) += imc.o
OBJS-$(CONFIG_INDEO2_DECODER) += indeo2.o
OBJS-$(CONFIG_INDEO3_DECODER) += indeo3.o
+OBJS-$(CONFIG_INDEO4_DECODER) += indeo4.o ivi_common.o ivi_dsp.o
OBJS-$(CONFIG_INDEO5_DECODER) += indeo5.o ivi_common.o ivi_dsp.o
OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER) += dpcm.o
OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o
@@ -246,8 +251,6 @@ OBJS-$(CONFIG_MPC7_DECODER) += mpc7.o mpc.o mpegaudiodec.o \
OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o mpegaudiodec.o \
mpegaudiodecheader.o mpegaudio.o \
mpegaudiodata.o
-OBJS-$(CONFIG_MPEGVIDEO_DECODER) += mpeg12.o mpeg12data.o \
- mpegvideo.o error_resilience.o
OBJS-$(CONFIG_MPEG_XVMC_DECODER) += mpegvideo_xvmc.o
OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12.o mpeg12data.o \
mpegvideo.o error_resilience.o
@@ -296,6 +299,7 @@ OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o
OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o
OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o
OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o
+OBJS-$(CONFIG_PRORES_DECODER) += proresdec.o proresdsp.o
OBJS-$(CONFIG_PTX_DECODER) += ptx.o
OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o celp_math.o \
celp_filters.o acelp_vectors.o \
@@ -324,9 +328,9 @@ OBJS-$(CONFIG_RV10_DECODER) += rv10.o
OBJS-$(CONFIG_RV10_ENCODER) += rv10enc.o
OBJS-$(CONFIG_RV20_DECODER) += rv10.o
OBJS-$(CONFIG_RV20_ENCODER) += rv20enc.o
-OBJS-$(CONFIG_RV30_DECODER) += rv30.o rv34.o rv30dsp.o \
+OBJS-$(CONFIG_RV30_DECODER) += rv30.o rv34.o rv30dsp.o rv34dsp.o \
mpegvideo.o error_resilience.o
-OBJS-$(CONFIG_RV40_DECODER) += rv40.o rv34.o rv40dsp.o \
+OBJS-$(CONFIG_RV40_DECODER) += rv40.o rv34.o rv34dsp.o rv40dsp.o \
mpegvideo.o error_resilience.o
OBJS-$(CONFIG_S302M_DECODER) += s302m.o
OBJS-$(CONFIG_SGI_DECODER) += sgidec.o
@@ -339,12 +343,12 @@ OBJS-$(CONFIG_SIPR_DECODER) += sipr.o acelp_pitch_delay.o \
OBJS-$(CONFIG_SMACKAUD_DECODER) += smacker.o
OBJS-$(CONFIG_SMACKER_DECODER) += smacker.o
OBJS-$(CONFIG_SMC_DECODER) += smc.o
-OBJS-$(CONFIG_SNOW_DECODER) += snow.o rangecoder.o
-OBJS-$(CONFIG_SNOW_ENCODER) += snow.o rangecoder.o motion_est.o \
- ratecontrol.o h263.o \
- mpegvideo.o error_resilience.o \
- ituh263enc.o mpegvideo_enc.o \
- mpeg12data.o
+OBJS-$(CONFIG_SNOW_DECODER) += snowdec.o snow.o rangecoder.o
+OBJS-$(CONFIG_SNOW_ENCODER) += snowenc.o snow.o rangecoder.o \
+ motion_est.o ratecontrol.o \
+ h263.o mpegvideo.o \
+ error_resilience.o ituh263enc.o \
+ mpegvideo_enc.o mpeg12data.o
OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o
OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o mjpegdec.o mjpeg.o
OBJS-$(CONFIG_SRT_DECODER) += srtdec.o ass.o
@@ -378,10 +382,14 @@ OBJS-$(CONFIG_TTA_DECODER) += tta.o
OBJS-$(CONFIG_TWINVQ_DECODER) += twinvq.o celp_math.o
OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o
OBJS-$(CONFIG_ULTI_DECODER) += ulti.o
+OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideo.o
OBJS-$(CONFIG_V210_DECODER) += v210dec.o
OBJS-$(CONFIG_V210_ENCODER) += v210enc.o
+OBJS-$(CONFIG_V410_DECODER) += v410dec.o
+OBJS-$(CONFIG_V410_ENCODER) += v410enc.o
OBJS-$(CONFIG_V210X_DECODER) += v210x.o
OBJS-$(CONFIG_VB_DECODER) += vb.o
+OBJS-$(CONFIG_VBLE_DECODER) += vble.o
OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1.o vc1data.o vc1dsp.o \
msmpeg4.o msmpeg4data.o \
intrax8.o intrax8dsp.o
@@ -452,6 +460,7 @@ 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_S8_PLANAR_DECODER) += 8svx.o
OBJS-$(CONFIG_PCM_S16BE_DECODER) += pcm.o
OBJS-$(CONFIG_PCM_S16BE_ENCODER) += pcm.o
OBJS-$(CONFIG_PCM_S16LE_DECODER) += pcm.o
@@ -482,48 +491,48 @@ 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_G722_DECODER) += g722.o
-OBJS-$(CONFIG_ADPCM_G722_ENCODER) += g722.o
+OBJS-$(CONFIG_ADPCM_4XM_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o adx.o
+OBJS-$(CONFIG_ADPCM_ADX_ENCODER) += adxenc.o adx.o
+OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_EA_MAXIS_XA_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_EA_R1_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_EA_R2_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_EA_R3_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_EA_XAS_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_G722_DECODER) += g722.o g722dec.o
+OBJS-$(CONFIG_ADPCM_G722_ENCODER) += g722.o g722enc.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_ISS_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
+OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER) += adpcmenc.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER) += adpcmenc.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_MS_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_MS_ENCODER) += adpcmenc.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_SBPRO_2_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_SBPRO_3_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_SBPRO_4_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_SWF_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_SWF_ENCODER) += adpcmenc.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o
# libavformat dependencies
OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o
+OBJS-$(CONFIG_ADX_DEMUXER) += adx.o
OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o
OBJS-$(CONFIG_DV_DEMUXER) += dvdata.o
OBJS-$(CONFIG_DV_MUXER) += dvdata.o
@@ -532,12 +541,14 @@ OBJS-$(CONFIG_FLAC_MUXER) += flacdec.o flacdata.o flac.o
OBJS-$(CONFIG_FLV_DEMUXER) += mpeg4audio.o
OBJS-$(CONFIG_GXF_DEMUXER) += mpeg12data.o
OBJS-$(CONFIG_IFF_DEMUXER) += iff.o
+OBJS-$(CONFIG_LATM_MUXER) += mpeg4audio.o
OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o \
flacdec.o flacdata.o flac.o
OBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio.o mpegaudiodata.o
OBJS-$(CONFIG_MATROSKA_MUXER) += xiph.o mpeg4audio.o \
flacdec.o flacdata.o flac.o \
mpegaudiodata.o
+OBJS-$(CONFIG_MP3_MUXER) += mpegaudiodata.o mpegaudiodecheader.o
OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o
OBJS-$(CONFIG_MOV_MUXER) += mpeg4audio.o mpegaudiodata.o
OBJS-$(CONFIG_MPEGTS_MUXER) += mpegvideo.o mpeg4audio.o
@@ -573,6 +584,7 @@ OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \
libschroedinger.o \
libdirac_libschro.o
OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o
+OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o
OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o
OBJS-$(CONFIG_LIBVO_AACENC_ENCODER) += libvo-aacenc.o mpeg4audio.o
OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o
@@ -588,6 +600,7 @@ OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \
aacadtsdec.o mpeg4audio.o
OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o \
aac_ac3_parser.o
+OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o
OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o
OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o
OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o
@@ -616,6 +629,8 @@ 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_RV30_PARSER) += rv34_parser.o
+OBJS-$(CONFIG_RV40_PARSER) += rv34_parser.o
OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o \
msmpeg4.o msmpeg4data.o mpeg4video.o \
h263.o mpegvideo.o error_resilience.o
@@ -641,7 +656,7 @@ OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o
# thread libraries
OBJS-$(HAVE_PTHREADS) += pthread.o
-OBJS-$(HAVE_W32THREADS) += w32thread.o
+OBJS-$(HAVE_W32THREADS) += pthread.o
OBJS-$(CONFIG_MLIB) += mlib/dsputil_mlib.o \
@@ -651,7 +666,7 @@ OBJS-$(CONFIG_MLIB) += mlib/dsputil_mlib.o \
# well.
OBJS-$(!CONFIG_SMALL) += inverse.o
--include $(SUBDIR)$(ARCH)/Makefile
+-include $(SRC_PATH)/$(SUBDIR)$(ARCH)/Makefile
SKIPHEADERS += %_tablegen.h \
%_tables.h \
@@ -663,12 +678,14 @@ SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_LIBDIRAC) += libdirac.h
SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h
SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h
+SKIPHEADERS-$(CONFIG_VDA) += vda.h vda_internal.h
SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h
SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h
+SKIPHEADERS-$(HAVE_W32THREADS) += w32pthreads.h
EXAMPLES = api
-TESTPROGS = cabac dct fft fft-fixed h264 iirfilter rangecoder snow
+TESTPROGS = cabac dct fft fft-fixed h264 iirfilter rangecoder
TESTPROGS-$(HAVE_MMX) += motion
TESTOBJS = dctref.o
@@ -680,8 +697,6 @@ DIRS = alpha arm bfin mlib ppc ps2 sh4 sparc x86
CLEANFILES = *_tables.c *_tables.h *_tablegen$(HOSTEXESUF)
-include $(SUBDIR)../subdir.mak
-
$(SUBDIR)dct-test$(EXESUF): $(SUBDIR)dctref.o
TRIG_TABLES = cos cos_fixed sin
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index 4861ec0..30491fe 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -104,11 +104,11 @@ enum CouplingPoint {
* Output configuration status
*/
enum OCStatus {
- OC_NONE, //< Output unconfigured
- OC_TRIAL_PCE, //< Output configuration under trial specified by an inband PCE
- OC_TRIAL_FRAME, //< Output configuration under trial specified by a frame header
- OC_GLOBAL_HDR, //< Output configuration set in a global header but not yet locked
- OC_LOCKED, //< Output configuration locked in place
+ OC_NONE, ///< Output unconfigured
+ OC_TRIAL_PCE, ///< Output configuration under trial specified by an inband PCE
+ OC_TRIAL_FRAME, ///< Output configuration under trial specified by a frame header
+ OC_GLOBAL_HDR, ///< Output configuration set in a global header but not yet locked
+ OC_LOCKED, ///< Output configuration locked in place
};
/**
@@ -251,6 +251,7 @@ typedef struct {
*/
typedef struct {
AVCodecContext *avctx;
+ AVFrame frame;
MPEG4AudioConfig m4ac;
diff --git a/libavcodec/aac_ac3_parser.h b/libavcodec/aac_ac3_parser.h
index c4ed816..a14fce5 100644
--- a/libavcodec/aac_ac3_parser.h
+++ b/libavcodec/aac_ac3_parser.h
@@ -48,7 +48,7 @@ typedef struct AACAC3ParseContext {
int sample_rate;
int bit_rate;
int samples;
- int64_t channel_layout;
+ uint64_t channel_layout;
int service_type;
int remaining_size;
diff --git a/libavcodec/aac_adtstoasc_bsf.c b/libavcodec/aac_adtstoasc_bsf.c
index d1310c4..55181bb 100644
--- a/libavcodec/aac_adtstoasc_bsf.c
+++ b/libavcodec/aac_adtstoasc_bsf.c
@@ -55,7 +55,7 @@ static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc,
if (show_bits(&gb, 12) != 0xfff)
return 0;
- if (ff_aac_parse_header(&gb, &hdr) < 0) {
+ if (avpriv_aac_parse_header(&gb, &hdr) < 0) {
av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n");
return -1;
}
@@ -78,7 +78,7 @@ static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc,
return -1;
}
init_put_bits(&pb, pce_data, MAX_PCE_SIZE);
- pce_size = ff_copy_pce_data(&pb, &gb)/8;
+ pce_size = avpriv_copy_pce_data(&pb, &gb)/8;
flush_put_bits(&pb);
buf_size -= get_bits_count(&gb)/8;
buf += get_bits_count(&gb)/8;
diff --git a/libavcodec/aac_parser.c b/libavcodec/aac_parser.c
index 1c5546e..f0914e6 100644
--- a/libavcodec/aac_parser.c
+++ b/libavcodec/aac_parser.c
@@ -40,7 +40,7 @@ static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info,
tmp.u64 = av_be2ne64(state);
init_get_bits(&bits, tmp.u8+8-AAC_ADTS_HEADER_SIZE, AAC_ADTS_HEADER_SIZE * 8);
- if ((size = ff_aac_parse_header(&bits, &hdr)) < 0)
+ if ((size = avpriv_aac_parse_header(&bits, &hdr)) < 0)
return 0;
*need_next_header = 0;
*new_frame_start = 1;
@@ -61,9 +61,9 @@ static av_cold int aac_parse_init(AVCodecParserContext *s1)
AVCodecParser ff_aac_parser = {
- { CODEC_ID_AAC },
- sizeof(AACAC3ParseContext),
- aac_parse_init,
- ff_aac_ac3_parse,
- ff_parse_close,
+ .codec_ids = { CODEC_ID_AAC },
+ .priv_data_size = sizeof(AACAC3ParseContext),
+ .parser_init = aac_parse_init,
+ .parser_parse = ff_aac_ac3_parse,
+ .parser_close = ff_parse_close,
};
diff --git a/libavcodec/aacadtsdec.c b/libavcodec/aacadtsdec.c
index a9ff8ef..30f92e0 100644
--- a/libavcodec/aacadtsdec.c
+++ b/libavcodec/aacadtsdec.c
@@ -26,7 +26,7 @@
#include "get_bits.h"
#include "mpeg4audio.h"
-int ff_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr)
+int avpriv_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr)
{
int size, rdb, ch, sr;
int aot, crc_abs;
@@ -39,7 +39,7 @@ int ff_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr)
crc_abs = get_bits1(gbc); /* protection_absent */
aot = get_bits(gbc, 2); /* profile_objecttype */
sr = get_bits(gbc, 4); /* sample_frequency_index */
- if(!ff_mpeg4audio_sample_rates[sr])
+ if(!avpriv_mpeg4audio_sample_rates[sr])
return AAC_AC3_PARSE_ERROR_SAMPLE_RATE;
skip_bits1(gbc); /* private_bit */
ch = get_bits(gbc, 3); /* channel_configuration */
@@ -62,7 +62,7 @@ int ff_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr)
hdr->crc_absent = crc_abs;
hdr->num_aac_frames = rdb + 1;
hdr->sampling_index = sr;
- hdr->sample_rate = ff_mpeg4audio_sample_rates[sr];
+ hdr->sample_rate = avpriv_mpeg4audio_sample_rates[sr];
hdr->samples = (rdb + 1) * 1024;
hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples;
diff --git a/libavcodec/aacadtsdec.h b/libavcodec/aacadtsdec.h
index 2fa1b4b..60fdd22 100644
--- a/libavcodec/aacadtsdec.h
+++ b/libavcodec/aacadtsdec.h
@@ -49,6 +49,6 @@ typedef struct {
* -2 if the version element is invalid, -3 if the sample rate
* element is invalid, or -4 if the bit rate element is invalid.
*/
-int ff_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr);
+int avpriv_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr);
#endif /* AVCODEC_AACADTSDEC_H */
diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index 4d5b98f..f8a8f3d 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -33,6 +33,7 @@
#include "libavutil/libm.h" // brought forward to work around cygwin header breakage
#include <float.h>
+#include "libavutil/mathematics.h"
#include "avcodec.h"
#include "put_bits.h"
#include "aac.h"
@@ -345,7 +346,7 @@ static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce
float cost_stay_here, cost_get_here;
float rd = 0.0f;
for (w = 0; w < group_len; w++) {
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(win+w)*16+swb];
+ FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(win+w)*16+swb];
rd += quantize_band_cost(s, sce->coeffs + start + w*128,
s->scoefs + start + w*128, size,
sce->sf_idx[(win+w)*16+swb], cb,
@@ -432,10 +433,26 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
for (swb = 0; swb < max_sfb; swb++) {
size = sce->ics.swb_sizes[swb];
if (sce->zeroes[win*16 + swb]) {
- for (cb = 0; cb < 12; cb++) {
- path[swb+1][cb].prev_idx = cb;
- path[swb+1][cb].cost = path[swb][cb].cost;
- path[swb+1][cb].run = path[swb][cb].run + 1;
+ float cost_stay_here = path[swb][0].cost;
+ float cost_get_here = next_minrd + run_bits + 4;
+ if ( run_value_bits[sce->ics.num_windows == 8][path[swb][0].run]
+ != run_value_bits[sce->ics.num_windows == 8][path[swb][0].run+1])
+ cost_stay_here += run_bits;
+ if (cost_get_here < cost_stay_here) {
+ path[swb+1][0].prev_idx = next_mincb;
+ path[swb+1][0].cost = cost_get_here;
+ path[swb+1][0].run = 1;
+ } else {
+ path[swb+1][0].prev_idx = 0;
+ path[swb+1][0].cost = cost_stay_here;
+ path[swb+1][0].run = path[swb][0].run + 1;
+ }
+ next_minrd = path[swb+1][0].cost;
+ next_mincb = 0;
+ for (cb = 1; cb < 12; cb++) {
+ path[swb+1][cb].cost = 61450;
+ path[swb+1][cb].prev_idx = -1;
+ path[swb+1][cb].run = 0;
}
} else {
float minrd = next_minrd;
@@ -609,7 +626,7 @@ static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
qmin = INT_MAX;
qmax = 0.0f;
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
+ FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
if (band->energy <= band->threshold || band->threshold == 0.0f) {
sce->zeroes[(w+w2)*16+g] = 1;
continue;
@@ -638,7 +655,7 @@ static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
float dist = 0;
int cb = find_min_book(maxval, sce->sf_idx[w*16+g]);
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
+ FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
dist += quantize_band_cost(s, coefs + w2*128, s->scoefs + start + w2*128, sce->ics.swb_sizes[g],
q + q0, cb, lambda / band->threshold, INFINITY, NULL);
}
@@ -711,7 +728,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
int nz = 0;
float uplim = 0.0f;
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
+ FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
uplim += band->threshold;
if (band->energy <= band->threshold || band->threshold == 0.0f) {
sce->zeroes[(w+w2)*16+g] = 1;
@@ -1011,7 +1028,7 @@ static void search_for_quantizers_fast(AVCodecContext *avctx, AACEncContext *s,
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
for (g = 0; g < sce->ics.num_swb; g++) {
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
+ FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
if (band->energy <= band->threshold) {
sce->sf_idx[(w+w2)*16+g] = 218;
sce->zeroes[(w+w2)*16+g] = 1;
@@ -1049,8 +1066,8 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe,
if (!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]) {
float dist1 = 0.0f, dist2 = 0.0f;
for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) {
- FFPsyBand *band0 = &s->psy.psy_bands[(s->cur_channel+0)*PSY_MAX_BANDS+(w+w2)*16+g];
- FFPsyBand *band1 = &s->psy.psy_bands[(s->cur_channel+1)*PSY_MAX_BANDS+(w+w2)*16+g];
+ FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g];
+ FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g];
float minthr = FFMIN(band0->threshold, band1->threshold);
float maxthr = FFMAX(band0->threshold, band1->threshold);
for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 2958ddb..4d3f1ff 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -98,6 +98,7 @@
#include "aacsbr.h"
#include "mpeg4audio.h"
#include "aacadtsdec.h"
+#include "libavutil/intfloat.h"
#include <assert.h>
#include <errno.h>
@@ -108,11 +109,6 @@
# include "arm/aac.h"
#endif
-union float754 {
- float f;
- uint32_t i;
-};
-
static VLC vlc_scalefactors;
static VLC vlc_spectral[11];
@@ -184,9 +180,11 @@ static av_cold int che_configure(AACContext *ac,
int type, int id, int *channels)
{
if (che_pos[type][id]) {
- if (!ac->che[type][id] && !(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
- return AVERROR(ENOMEM);
- ff_aac_sbr_ctx_init(ac, &ac->che[type][id]->sbr);
+ if (!ac->che[type][id]) {
+ if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
+ return AVERROR(ENOMEM);
+ ff_aac_sbr_ctx_init(ac, &ac->che[type][id]->sbr);
+ }
if (type != TYPE_CCE) {
ac->output_data[(*channels)++] = ac->che[type][id]->ch[0].ret;
if (type == TYPE_CPE ||
@@ -450,15 +448,17 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
* @param ac pointer to AACContext, may be null
* @param avctx pointer to AVCCodecContext, used for logging
* @param m4ac pointer to MPEG4AudioConfig, used for parsing
- * @param data pointer to AVCodecContext extradata
- * @param data_size size of AVCCodecContext extradata
+ * @param data pointer to buffer holding an audio specific config
+ * @param bit_size size of audio specific config or data in bits
+ * @param sync_extension look for an appended sync extension
*
* @return Returns error status or number of consumed bits. <0 - error
*/
static int decode_audio_specific_config(AACContext *ac,
AVCodecContext *avctx,
MPEG4AudioConfig *m4ac,
- const uint8_t *data, int data_size)
+ const uint8_t *data, int bit_size,
+ int sync_extension)
{
GetBitContext gb;
int i;
@@ -468,9 +468,9 @@ static int decode_audio_specific_config(AACContext *ac,
av_dlog(avctx, "%02x ", avctx->extradata[i]);
av_dlog(avctx, "\n");
- init_get_bits(&gb, data, data_size * 8);
+ init_get_bits(&gb, data, bit_size);
- if ((i = ff_mpeg4audio_get_config(m4ac, data, data_size)) < 0)
+ if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size, sync_extension)) < 0)
return -1;
if (m4ac->sampling_index > 12) {
av_log(avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", m4ac->sampling_index);
@@ -530,6 +530,22 @@ static void reset_all_predictors(PredictorState *ps)
reset_predict_state(&ps[i]);
}
+static int sample_rate_idx (int rate)
+{
+ if (92017 <= rate) return 0;
+ else if (75132 <= rate) return 1;
+ else if (55426 <= rate) return 2;
+ else if (46009 <= rate) return 3;
+ else if (37566 <= rate) return 4;
+ else if (27713 <= rate) return 5;
+ else if (23004 <= rate) return 6;
+ else if (18783 <= rate) return 7;
+ else if (13856 <= rate) return 8;
+ else if (11502 <= rate) return 9;
+ else if (9391 <= rate) return 10;
+ else return 11;
+}
+
static void reset_predictor_group(PredictorState *ps, int group_num)
{
int i;
@@ -554,8 +570,33 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
if (avctx->extradata_size > 0) {
if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac,
avctx->extradata,
- avctx->extradata_size) < 0)
+ avctx->extradata_size*8, 1) < 0)
return -1;
+ } else {
+ int sr, i;
+ enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
+
+ sr = sample_rate_idx(avctx->sample_rate);
+ ac->m4ac.sampling_index = sr;
+ ac->m4ac.channels = avctx->channels;
+ ac->m4ac.sbr = -1;
+ ac->m4ac.ps = -1;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++)
+ if (ff_mpeg4audio_channels[i] == avctx->channels)
+ break;
+ if (i == FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) {
+ i = 0;
+ }
+ ac->m4ac.chan_config = i;
+
+ if (ac->m4ac.chan_config) {
+ int ret = set_default_channel_config(avctx, new_che_pos, ac->m4ac.chan_config);
+ if (!ret)
+ output_configure(ac, ac->che_pos, new_che_pos, ac->m4ac.chan_config, OC_GLOBAL_HDR);
+ else if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
}
if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
@@ -603,6 +644,9 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
cbrt_tableinit();
+ avcodec_get_frame_defaults(&ac->frame);
+ avctx->coded_frame = &ac->frame;
+
return 0;
}
@@ -659,16 +703,13 @@ static void decode_ltp(AACContext *ac, LongTermPrediction *ltp,
/**
* Decode Individual Channel Stream info; reference: table 4.6.
- *
- * @param common_window Channels have independent [0], or shared [1], Individual Channel Stream information.
*/
static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
- GetBitContext *gb, int common_window)
+ GetBitContext *gb)
{
if (get_bits1(gb)) {
av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n");
- memset(ics, 0, sizeof(IndividualChannelStream));
- return -1;
+ return AVERROR_INVALIDDATA;
}
ics->window_sequence[1] = ics->window_sequence[0];
ics->window_sequence[0] = get_bits(gb, 2);
@@ -703,13 +744,11 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
if (ics->predictor_present) {
if (ac->m4ac.object_type == AOT_AAC_MAIN) {
if (decode_prediction(ac, ics, gb)) {
- memset(ics, 0, sizeof(IndividualChannelStream));
- return -1;
+ return AVERROR_INVALIDDATA;
}
} else if (ac->m4ac.object_type == AOT_AAC_LC) {
av_log(ac->avctx, AV_LOG_ERROR, "Prediction is not allowed in AAC-LC.\n");
- memset(ics, 0, sizeof(IndividualChannelStream));
- return -1;
+ return AVERROR_INVALIDDATA;
} else {
if ((ics->ltp.present = get_bits(gb, 1)))
decode_ltp(ac, &ics->ltp, gb, ics->max_sfb);
@@ -721,8 +760,7 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
av_log(ac->avctx, AV_LOG_ERROR,
"Number of scalefactor bands in group (%d) exceeds limit (%d).\n",
ics->max_sfb, ics->num_swb);
- memset(ics, 0, sizeof(IndividualChannelStream));
- return -1;
+ return AVERROR_INVALIDDATA;
}
return 0;
@@ -956,7 +994,7 @@ static inline float *VMUL4(float *dst, const float *v, unsigned idx,
static inline float *VMUL2S(float *dst, const float *v, unsigned idx,
unsigned sign, const float *scale)
{
- union float754 s0, s1;
+ union av_intfloat32 s0, s1;
s0.f = s1.f = *scale;
s0.i ^= sign >> 1 << 31;
@@ -974,8 +1012,8 @@ static inline float *VMUL4S(float *dst, const float *v, unsigned idx,
unsigned sign, const float *scale)
{
unsigned nz = idx >> 12;
- union float754 s = { .f = *scale };
- union float754 t;
+ union av_intfloat32 s = { .f = *scale };
+ union av_intfloat32 t;
t.i = s.i ^ (sign & 1U<<31);
*dst++ = v[idx & 3] * t.f;
@@ -1088,7 +1126,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
GET_VLC(code, re, gb, vlc_tab, 8, 2);
cb_idx = cb_vector_idx[code];
nnz = cb_idx >> 8 & 15;
- bits = SHOW_UBITS(re, gb, nnz) << (32-nnz);
+ bits = nnz ? GET_CACHE(re, gb) : 0;
LAST_SKIP_BITS(re, gb, nnz);
cf = VMUL4S(cf, vq, cb_idx, bits, sf + idx);
} while (len -= 4);
@@ -1128,7 +1166,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
GET_VLC(code, re, gb, vlc_tab, 8, 2);
cb_idx = cb_vector_idx[code];
nnz = cb_idx >> 8 & 15;
- sign = SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12);
+ sign = nnz ? SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12) : 0;
LAST_SKIP_BITS(re, gb, nnz);
cf = VMUL2S(cf, vq, cb_idx, sign, sf + idx);
} while (len -= 2);
@@ -1224,7 +1262,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
static av_always_inline float flt16_round(float pf)
{
- union float754 tmp;
+ union av_intfloat32 tmp;
tmp.f = pf;
tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U;
return tmp.f;
@@ -1232,7 +1270,7 @@ static av_always_inline float flt16_round(float pf)
static av_always_inline float flt16_even(float pf)
{
- union float754 tmp;
+ union av_intfloat32 tmp;
tmp.f = pf;
tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U >> 16)) & 0xFFFF0000U;
return tmp.f;
@@ -1240,7 +1278,7 @@ static av_always_inline float flt16_even(float pf)
static av_always_inline float flt16_trunc(float pf)
{
- union float754 pun;
+ union av_intfloat32 pun;
pun.f = pf;
pun.i &= 0xFFFF0000U;
return pun.f;
@@ -1327,8 +1365,8 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce,
global_gain = get_bits(gb, 8);
if (!common_window && !scale_flag) {
- if (decode_ics_info(ac, ics, gb, 0) < 0)
- return -1;
+ if (decode_ics_info(ac, ics, gb) < 0)
+ return AVERROR_INVALIDDATA;
}
if (decode_band_types(ac, sce->band_type, sce->band_type_run_end, gb, ics) < 0)
@@ -1444,8 +1482,8 @@ static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe)
common_window = get_bits1(gb);
if (common_window) {
- if (decode_ics_info(ac, &cpe->ch[0].ics, gb, 1))
- return -1;
+ if (decode_ics_info(ac, &cpe->ch[0].ics, gb))
+ return AVERROR_INVALIDDATA;
i = cpe->ch[1].ics.use_kb_window[0];
cpe->ch[1].ics = cpe->ch[0].ics;
cpe->ch[1].ics.use_kb_window[1] = i;
@@ -2034,26 +2072,28 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
int size;
AACADTSHeaderInfo hdr_info;
- size = ff_aac_parse_header(gb, &hdr_info);
+ size = avpriv_aac_parse_header(gb, &hdr_info);
if (size > 0) {
- if (ac->output_configured != OC_LOCKED && hdr_info.chan_config) {
+ if (hdr_info.chan_config) {
enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
ac->m4ac.chan_config = hdr_info.chan_config;
if (set_default_channel_config(ac->avctx, new_che_pos, hdr_info.chan_config))
return -7;
- if (output_configure(ac, ac->che_pos, new_che_pos, hdr_info.chan_config, OC_TRIAL_FRAME))
+ if (output_configure(ac, ac->che_pos, new_che_pos, hdr_info.chan_config,
+ FFMAX(ac->output_configured, OC_TRIAL_FRAME)))
return -7;
} else if (ac->output_configured != OC_LOCKED) {
+ ac->m4ac.chan_config = 0;
ac->output_configured = OC_NONE;
}
if (ac->output_configured != OC_LOCKED) {
ac->m4ac.sbr = -1;
ac->m4ac.ps = -1;
+ ac->m4ac.sample_rate = hdr_info.sample_rate;
+ ac->m4ac.sampling_index = hdr_info.sampling_index;
+ ac->m4ac.object_type = hdr_info.object_type;
}
- ac->m4ac.sample_rate = hdr_info.sample_rate;
- ac->m4ac.sampling_index = hdr_info.sampling_index;
- ac->m4ac.object_type = hdr_info.object_type;
if (!ac->avctx->sample_rate)
ac->avctx->sample_rate = hdr_info.sample_rate;
if (hdr_info.num_aac_frames == 1) {
@@ -2068,12 +2108,12 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
}
static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
- int *data_size, GetBitContext *gb)
+ int *got_frame_ptr, GetBitContext *gb)
{
AACContext *ac = avctx->priv_data;
ChannelElement *che = NULL, *che_prev = NULL;
enum RawDataBlockType elem_type, elem_type_prev = TYPE_END;
- int err, elem_id, data_size_tmp;
+ int err, elem_id;
int samples = 0, multiplier, audio_found = 0;
if (show_bits(gb, 12) == 0xfff) {
@@ -2177,24 +2217,26 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
avctx->frame_size = samples;
}
- data_size_tmp = samples * avctx->channels *
- (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8);
- if (*data_size < data_size_tmp) {
- av_log(avctx, AV_LOG_ERROR,
- "Output buffer too small (%d) or trying to output too many samples (%d) for this frame.\n",
- *data_size, data_size_tmp);
- return -1;
- }
- *data_size = data_size_tmp;
-
if (samples) {
+ /* get output buffer */
+ ac->frame.nb_samples = samples;
+ if ((err = avctx->get_buffer(avctx, &ac->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return err;
+ }
+
if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT)
- ac->fmt_conv.float_interleave(data, (const float **)ac->output_data,
+ ac->fmt_conv.float_interleave((float *)ac->frame.data[0],
+ (const float **)ac->output_data,
samples, avctx->channels);
else
- ac->fmt_conv.float_to_int16_interleave(data, (const float **)ac->output_data,
+ ac->fmt_conv.float_to_int16_interleave((int16_t *)ac->frame.data[0],
+ (const float **)ac->output_data,
samples, avctx->channels);
+
+ *(AVFrame *)data = ac->frame;
}
+ *got_frame_ptr = !!samples;
if (ac->output_configured && audio_found)
ac->output_configured = OC_LOCKED;
@@ -2203,18 +2245,37 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
}
static int aac_decode_frame(AVCodecContext *avctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame_ptr, AVPacket *avpkt)
{
+ AACContext *ac = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
GetBitContext gb;
int buf_consumed;
int buf_offset;
int err;
+ int new_extradata_size;
+ const uint8_t *new_extradata = av_packet_get_side_data(avpkt,
+ AV_PKT_DATA_NEW_EXTRADATA,
+ &new_extradata_size);
+
+ if (new_extradata) {
+ av_free(avctx->extradata);
+ avctx->extradata = av_mallocz(new_extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!avctx->extradata)
+ return AVERROR(ENOMEM);
+ avctx->extradata_size = new_extradata_size;
+ memcpy(avctx->extradata, new_extradata, new_extradata_size);
+ if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac,
+ avctx->extradata,
+ avctx->extradata_size*8, 1) < 0)
+ return AVERROR_INVALIDDATA;
+ }
init_get_bits(&gb, buf, buf_size * 8);
- if ((err = aac_decode_frame_int(avctx, data, data_size, &gb)) < 0)
+ if ((err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb)) < 0)
return err;
buf_consumed = (get_bits_count(&gb) + 7) >> 3;
@@ -2265,29 +2326,42 @@ static inline uint32_t latm_get_value(GetBitContext *b)
}
static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
- GetBitContext *gb)
+ GetBitContext *gb, int asclen)
{
- AVCodecContext *avctx = latmctx->aac_ctx.avctx;
- MPEG4AudioConfig m4ac;
- int config_start_bit = get_bits_count(gb);
- int bits_consumed, esize;
+ AACContext *ac = &latmctx->aac_ctx;
+ AVCodecContext *avctx = ac->avctx;
+ MPEG4AudioConfig m4ac = {0};
+ int config_start_bit = get_bits_count(gb);
+ int sync_extension = 0;
+ int bits_consumed, esize;
+
+ if (asclen) {
+ sync_extension = 1;
+ asclen = FFMIN(asclen, get_bits_left(gb));
+ } else
+ asclen = get_bits_left(gb);
if (config_start_bit % 8) {
av_log_missing_feature(latmctx->aac_ctx.avctx, "audio specific "
"config not byte aligned.\n", 1);
return AVERROR_INVALIDDATA;
- } else {
- bits_consumed =
- decode_audio_specific_config(NULL, avctx, &m4ac,
+ }
+ bits_consumed = decode_audio_specific_config(NULL, avctx, &m4ac,
gb->buffer + (config_start_bit / 8),
- get_bits_left(gb) / 8);
+ asclen, sync_extension);
- if (bits_consumed < 0)
- return AVERROR_INVALIDDATA;
+ if (bits_consumed < 0)
+ return AVERROR_INVALIDDATA;
+
+ if (ac->m4ac.sample_rate != m4ac.sample_rate ||
+ ac->m4ac.chan_config != m4ac.chan_config) {
+
+ av_log(avctx, AV_LOG_INFO, "audio config changed\n");
+ latmctx->initialized = 0;
esize = (bits_consumed+7) / 8;
- if (avctx->extradata_size <= esize) {
+ if (avctx->extradata_size < esize) {
av_free(avctx->extradata);
avctx->extradata = av_malloc(esize + FF_INPUT_BUFFER_PADDING_SIZE);
if (!avctx->extradata)
@@ -2297,9 +2371,8 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
avctx->extradata_size = esize;
memcpy(avctx->extradata, gb->buffer + (config_start_bit/8), esize);
memset(avctx->extradata+esize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-
- skip_bits_long(gb, bits_consumed);
}
+ skip_bits_long(gb, bits_consumed);
return bits_consumed;
}
@@ -2338,11 +2411,11 @@ static int read_stream_mux_config(struct LATMContext *latmctx,
// for all but first stream: use_same_config = get_bits(gb, 1);
if (!audio_mux_version) {
- if ((ret = latm_decode_audio_specific_config(latmctx, gb)) < 0)
+ if ((ret = latm_decode_audio_specific_config(latmctx, gb, 0)) < 0)
return ret;
} else {
int ascLen = latm_get_value(gb);
- if ((ret = latm_decode_audio_specific_config(latmctx, gb)) < 0)
+ if ((ret = latm_decode_audio_specific_config(latmctx, gb, ascLen)) < 0)
return ret;
ascLen -= ret;
skip_bits_long(gb, ascLen);
@@ -2436,16 +2509,13 @@ static int read_audio_mux_element(struct LATMContext *latmctx,
}
-static int latm_decode_frame(AVCodecContext *avctx, void *out, int *out_size,
- AVPacket *avpkt)
+static int latm_decode_frame(AVCodecContext *avctx, void *out,
+ int *got_frame_ptr, AVPacket *avpkt)
{
struct LATMContext *latmctx = avctx->priv_data;
int muxlength, err;
GetBitContext gb;
- if (avpkt->size == 0)
- return 0;
-
init_get_bits(&gb, avpkt->data, avpkt->size * 8);
// check for LOAS sync word
@@ -2462,11 +2532,12 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, int *out_size,
if (!latmctx->initialized) {
if (!avctx->extradata) {
- *out_size = 0;
+ *got_frame_ptr = 0;
return avpkt->size;
} else {
- aac_decode_close(avctx);
- if ((err = aac_decode_init(avctx)) < 0)
+ if ((err = decode_audio_specific_config(
+ &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.m4ac,
+ avctx->extradata, avctx->extradata_size*8, 1)) < 0)
return err;
latmctx->initialized = 1;
}
@@ -2479,7 +2550,7 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, int *out_size,
return AVERROR_INVALIDDATA;
}
- if ((err = aac_decode_frame_int(avctx, out, out_size, &gb)) < 0)
+ if ((err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb)) < 0)
return err;
return muxlength;
@@ -2488,33 +2559,28 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, int *out_size,
av_cold static int latm_decode_init(AVCodecContext *avctx)
{
struct LATMContext *latmctx = avctx->priv_data;
- int ret;
+ int ret = aac_decode_init(avctx);
- ret = aac_decode_init(avctx);
-
- if (avctx->extradata_size > 0) {
+ if (avctx->extradata_size > 0)
latmctx->initialized = !ret;
- } else {
- latmctx->initialized = 0;
- }
return ret;
}
AVCodec ff_aac_decoder = {
- "aac",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_AAC,
- sizeof(AACContext),
- aac_decode_init,
- NULL,
- aac_decode_close,
- aac_decode_frame,
+ .name = "aac",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AAC,
+ .priv_data_size = sizeof(AACContext),
+ .init = aac_decode_init,
+ .close = aac_decode_close,
+ .decode = aac_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"),
.sample_fmts = (const enum AVSampleFormat[]) {
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
},
+ .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
.channel_layouts = aac_channel_layout,
};
@@ -2535,5 +2601,6 @@ AVCodec ff_aac_latm_decoder = {
.sample_fmts = (const enum AVSampleFormat[]) {
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
},
+ .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
.channel_layouts = aac_channel_layout,
};
diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h
index 23a7868..4f8d84b 100644
--- a/libavcodec/aacdectab.h
+++ b/libavcodec/aacdectab.h
@@ -90,7 +90,7 @@ static const uint8_t aac_channel_layout_map[7][5][2] = {
{ { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, { TYPE_LFE, 0 }, { TYPE_CPE, 2 }, { TYPE_CPE, 1 }, },
};
-static const int64_t aac_channel_layout[8] = {
+static const uint64_t aac_channel_layout[8] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_SURROUND,
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index e8942a1..b112fa8 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -165,12 +165,13 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
AACEncContext *s = avctx->priv_data;
int i;
const uint8_t *sizes[2];
+ uint8_t grouping[AAC_MAX_CHANNELS];
int lengths[2];
avctx->frame_size = 1024;
for (i = 0; i < 16; i++)
- if (avctx->sample_rate == ff_mpeg4audio_sample_rates[i])
+ if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i])
break;
if (i == 16) {
av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n", avctx->sample_rate);
@@ -199,8 +200,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
ff_init_ff_sine_windows(10);
ff_init_ff_sine_windows(7);
+ s->chan_map = aac_chan_configs[avctx->channels-1];
s->samples = av_malloc(2 * 1024 * avctx->channels * sizeof(s->samples[0]));
- s->cpe = av_mallocz(sizeof(ChannelElement) * aac_chan_configs[avctx->channels-1][0]);
+ s->cpe = av_mallocz(sizeof(ChannelElement) * s->chan_map[0]);
avctx->extradata = av_mallocz(5 + FF_INPUT_BUFFER_PADDING_SIZE);
avctx->extradata_size = 5;
put_audio_specific_config(avctx);
@@ -209,7 +211,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
sizes[1] = swb_size_128[i];
lengths[0] = ff_aac_num_swb_1024[i];
lengths[1] = ff_aac_num_swb_128[i];
- ff_psy_init(&s->psy, avctx, 2, sizes, lengths);
+ for (i = 0; i < s->chan_map[0]; i++)
+ grouping[i] = s->chan_map[i + 1] == TYPE_CPE;
+ ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping);
s->psypp = ff_psy_preprocess_init(avctx);
s->coder = &ff_aac_coders[2];
@@ -363,7 +367,7 @@ static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, in
if (msc == 0 || ics0->max_sfb == 0)
cpe->ms_mode = 0;
else
- cpe->ms_mode = msc < ics0->max_sfb ? 1 : 2;
+ cpe->ms_mode = msc < ics0->max_sfb * ics0->num_windows ? 1 : 2;
}
}
@@ -478,7 +482,7 @@ static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s,
put_bits(&s->pb, 8, namelen - 16);
put_bits(&s->pb, 4, 0); //extension type - filler
padbits = 8 - (put_bits_count(&s->pb) & 7);
- align_put_bits(&s->pb);
+ avpriv_align_put_bits(&s->pb);
for (i = 0; i < namelen - 2; i++)
put_bits(&s->pb, 8, name[i]);
put_bits(&s->pb, 12 - padbits, 0);
@@ -491,7 +495,6 @@ static int aac_encode_frame(AVCodecContext *avctx,
int16_t *samples = s->samples, *samples2, *la;
ChannelElement *cpe;
int i, ch, w, g, chans, tag, start_ch;
- const uint8_t *chan_map = aac_chan_configs[avctx->channels-1];
int chan_el_counter[4];
FFPsyWindowInfo windows[AAC_MAX_CHANNELS];
@@ -504,8 +507,8 @@ static int aac_encode_frame(AVCodecContext *avctx,
} else {
start_ch = 0;
samples2 = s->samples + 1024 * avctx->channels;
- for (i = 0; i < chan_map[0]; i++) {
- tag = chan_map[i+1];
+ for (i = 0; i < s->chan_map[0]; i++) {
+ tag = s->chan_map[i+1];
chans = tag == TYPE_CPE ? 2 : 1;
ff_psy_preprocess(s->psypp, (uint16_t*)data + start_ch,
samples2 + start_ch, start_ch, chans);
@@ -520,9 +523,9 @@ static int aac_encode_frame(AVCodecContext *avctx,
}
start_ch = 0;
- for (i = 0; i < chan_map[0]; i++) {
+ for (i = 0; i < s->chan_map[0]; i++) {
FFPsyWindowInfo* wi = windows + start_ch;
- tag = chan_map[i+1];
+ tag = s->chan_map[i+1];
chans = tag == TYPE_CPE ? 2 : 1;
cpe = &s->cpe[i];
for (ch = 0; ch < chans; ch++) {
@@ -537,6 +540,12 @@ static int aac_encode_frame(AVCodecContext *avctx,
wi[ch].window_shape = 0;
wi[ch].num_windows = 1;
wi[ch].grouping[0] = 1;
+
+ /* Only the lowest 12 coefficients are used in a LFE channel.
+ * The expression below results in only the bottom 8 coefficients
+ * being used for 11.025kHz to 16kHz sample rates.
+ */
+ ics->num_swb = s->samplerate_index >= 8 ? 1 : 3;
} else {
wi[ch] = s->psy.model->window(&s->psy, samples2, la, cur_channel,
ics->window_sequence[0]);
@@ -547,7 +556,7 @@ static int aac_encode_frame(AVCodecContext *avctx,
ics->use_kb_window[0] = wi[ch].window_shape;
ics->num_windows = wi[ch].num_windows;
ics->swb_sizes = s->psy.bands [ics->num_windows == 8];
- ics->num_swb = tag == TYPE_LFE ? 12 : s->psy.num_bands[ics->num_windows == 8];
+ ics->num_swb = tag == TYPE_LFE ? ics->num_swb : s->psy.num_bands[ics->num_windows == 8];
for (w = 0; w < ics->num_windows; w++)
ics->group_len[w] = wi[ch].grouping[w];
@@ -562,16 +571,19 @@ static int aac_encode_frame(AVCodecContext *avctx,
put_bitstream_info(avctx, s, LIBAVCODEC_IDENT);
start_ch = 0;
memset(chan_el_counter, 0, sizeof(chan_el_counter));
- for (i = 0; i < chan_map[0]; i++) {
+ for (i = 0; i < s->chan_map[0]; i++) {
FFPsyWindowInfo* wi = windows + start_ch;
- tag = chan_map[i+1];
+ const float *coeffs[2];
+ tag = s->chan_map[i+1];
chans = tag == TYPE_CPE ? 2 : 1;
cpe = &s->cpe[i];
put_bits(&s->pb, 3, tag);
put_bits(&s->pb, 4, chan_el_counter[tag]++);
+ for (ch = 0; ch < chans; ch++)
+ coeffs[ch] = cpe->ch[ch].coeffs;
+ s->psy.model->analyze(&s->psy, start_ch, coeffs, wi);
for (ch = 0; ch < chans; ch++) {
- s->cur_channel = start_ch + ch;
- s->psy.model->analyze(&s->psy, s->cur_channel, cpe->ch[ch].coeffs, &wi[ch]);
+ s->cur_channel = start_ch * 2 + ch;
s->coder->search_for_quantizers(avctx, s, &cpe->ch[ch], s->lambda);
}
cpe->common_window = 0;
@@ -587,7 +599,7 @@ static int aac_encode_frame(AVCodecContext *avctx,
}
}
}
- s->cur_channel = start_ch;
+ s->cur_channel = start_ch * 2;
if (s->options.stereo_mode && cpe->common_window) {
if (s->options.stereo_mode > 0) {
IndividualChannelStream *ics = &cpe->ch[0].ics;
@@ -656,10 +668,10 @@ static av_cold int aac_encode_end(AVCodecContext *avctx)
#define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption aacenc_options[] = {
- {"stereo_mode", "Stereo coding method", offsetof(AACEncContext, options.stereo_mode), FF_OPT_TYPE_INT, {.dbl = 0}, -1, 1, AACENC_FLAGS, "stereo_mode"},
- {"auto", "Selected by the Encoder", 0, FF_OPT_TYPE_CONST, {.dbl = -1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
- {"ms_off", "Disable Mid/Side coding", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
- {"ms_force", "Force Mid/Side for the whole frame if possible", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
+ {"stereo_mode", "Stereo coding method", offsetof(AACEncContext, options.stereo_mode), AV_OPT_TYPE_INT, {.dbl = 0}, -1, 1, AACENC_FLAGS, "stereo_mode"},
+ {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.dbl = -1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
+ {"ms_off", "Disable Mid/Side coding", 0, AV_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
+ {"ms_force", "Force Mid/Side for the whole frame if possible", 0, AV_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
{NULL}
};
@@ -671,13 +683,13 @@ static const AVClass aacenc_class = {
};
AVCodec ff_aac_encoder = {
- "aac",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_AAC,
- sizeof(AACEncContext),
- aac_encode_init,
- aac_encode_frame,
- aac_encode_end,
+ .name = "aac",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AAC,
+ .priv_data_size = sizeof(AACEncContext),
+ .init = aac_encode_init,
+ .encode = aac_encode_frame,
+ .close = aac_encode_end,
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"),
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index 067a9b0..acd185a 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -61,6 +61,7 @@ typedef struct AACEncContext {
int16_t *samples; ///< saved preprocessed input
int samplerate_index; ///< MPEG-4 samplerate index
+ const uint8_t *chan_map; ///< channel configuration map
ChannelElement *cpe; ///< channel elements
FFPsyContext psy;
diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c
index 3f1424b..d7d6ef8 100644
--- a/libavcodec/aacps.c
+++ b/libavcodec/aacps.c
@@ -28,9 +28,9 @@
#include "aacps_tablegen.h"
#include "aacpsdata.c"
-#define PS_BASELINE 0 //< Operate in Baseline PS mode
- //< Baseline implies 10 or 20 stereo bands,
- //< mixing mode A, and no ipd/opd
+#define PS_BASELINE 0 ///< Operate in Baseline PS mode
+ ///< Baseline implies 10 or 20 stereo bands,
+ ///< mixing mode A, and no ipd/opd
#define numQMFSlots 32 //numTimeSlots * RATE
@@ -69,19 +69,19 @@ static const int huff_iid[] = {
static VLC vlc_ps[10];
-/**
- * Read Inter-channel Intensity Difference/Inter-Channel Coherence/
- * Inter-channel Phase Difference/Overall Phase Difference parameters from the
- * bitstream.
- *
- * @param avctx contains the current codec context
- * @param gb pointer to the input bitstream
- * @param ps pointer to the Parametric Stereo context
- * @param par pointer to the parameter to be read
- * @param e envelope to decode
- * @param dt 1: time delta-coded, 0: frequency delta-coded
- */
#define READ_PAR_DATA(PAR, OFFSET, MASK, ERR_CONDITION) \
+/** \
+ * Read Inter-channel Intensity Difference/Inter-Channel Coherence/ \
+ * Inter-channel Phase Difference/Overall Phase Difference parameters from the \
+ * bitstream. \
+ * \
+ * @param avctx contains the current codec context \
+ * @param gb pointer to the input bitstream \
+ * @param ps pointer to the Parametric Stereo context \
+ * @param PAR pointer to the parameter to be read \
+ * @param e envelope to decode \
+ * @param dt 1: time delta-coded, 0: frequency delta-coded \
+ */ \
static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSContext *ps, \
int8_t (*PAR)[PS_MAX_NR_IIDICC], int table_idx, int e, int dt) \
{ \
@@ -654,7 +654,7 @@ static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[3
const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20;
const float peak_decay_factor = 0.76592833836465f;
const float transient_impact = 1.5f;
- const float a_smooth = 0.25f; //< Smoothing coefficient
+ const float a_smooth = 0.25f; ///< Smoothing coefficient
int i, k, m, n;
int n0 = 0, nL = 32;
static const int link_delay[] = { 3, 4, 5 };
diff --git a/libavcodec/aacps.h b/libavcodec/aacps.h
index 59a9bff..124fbee 100644
--- a/libavcodec/aacps.h
+++ b/libavcodec/aacps.h
@@ -52,11 +52,11 @@ typedef struct {
int num_env;
int enable_ipdopd;
int border_position[PS_MAX_NUM_ENV+1];
- int8_t iid_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; //<Inter-channel Intensity Difference Parameters
- int8_t icc_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; //<Inter-Channel Coherence Parameters
+ int8_t iid_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Inter-channel Intensity Difference Parameters
+ int8_t icc_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Inter-Channel Coherence Parameters
/* ipd/opd is iid/icc sized so that the same functions can handle both */
- int8_t ipd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; //<Inter-channel Phase Difference Parameters
- int8_t opd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; //<Overall Phase Difference Parameters
+ int8_t ipd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Inter-channel Phase Difference Parameters
+ int8_t opd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Overall Phase Difference Parameters
int is34bands;
int is34bands_old;
diff --git a/libavcodec/aacps_tablegen.h b/libavcodec/aacps_tablegen.h
index 492cb0c..5041f44 100644
--- a/libavcodec/aacps_tablegen.h
+++ b/libavcodec/aacps_tablegen.h
@@ -139,7 +139,7 @@ static void ps_tableinit(void)
}
for (iid = 0; iid < 46; iid++) {
- float c = iid_par_dequant[iid]; //<Linear Inter-channel Intensity Difference
+ float c = iid_par_dequant[iid]; ///< Linear Inter-channel Intensity Difference
float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c);
float c2 = c * c1;
for (icc = 0; icc < 8; icc++) {
diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c
index 5aea1fa..38d9d9f 100644
--- a/libavcodec/aacpsy.c
+++ b/libavcodec/aacpsy.c
@@ -216,7 +216,7 @@ static const float psy_fir_coeffs[] = {
};
/**
- * calculates the attack threshold for ABR from the above table for the LAME psy model
+ * Calculate the ABR attack threshold from the above LAME psymodel table.
*/
static float lame_calc_attack_threshold(int bitrate)
{
@@ -377,9 +377,10 @@ static const uint8_t window_grouping[9] = {
* Tell encoder which window types to use.
* @see 3GPP TS26.403 5.4.1 "Blockswitching"
*/
-static FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx,
- const int16_t *audio, const int16_t *la,
- int channel, int prev_type)
+static av_unused FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx,
+ const int16_t *audio,
+ const int16_t *la,
+ int channel, int prev_type)
{
int i, j;
int br = ctx->avctx->bit_rate / ctx->avctx->channels;
@@ -556,8 +557,8 @@ static float calc_reduced_thr_3gpp(AacPsyBand *band, float min_snr,
/**
* Calculate band thresholds as suggested in 3GPP TS26.403
*/
-static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
- const float *coefs, const FFPsyWindowInfo *wi)
+static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel,
+ const float *coefs, const FFPsyWindowInfo *wi)
{
AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
AacPsyChannel *pch = &pctx->ch[channel];
@@ -626,7 +627,7 @@ static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
}
/* 5.6.1.3.2 "Calculation of the desired perceptual entropy" */
- ctx->pe[channel] = pe;
+ ctx->ch[channel].entropy = pe;
desired_bits = calc_bit_demand(pctx, pe, ctx->bitres.bits, ctx->bitres.size, wi->num_windows == 8);
desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits);
/* NOTE: PE correction is kept simple. During initial testing it had very
@@ -730,7 +731,7 @@ static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
for (w = 0; w < wi->num_windows*16; w += 16) {
for (g = 0; g < num_bands; g++) {
AacPsyBand *band = &pch->band[w+g];
- FFPsyBand *psy_band = &ctx->psy_bands[channel*PSY_MAX_BANDS+w+g];
+ FFPsyBand *psy_band = &ctx->ch[channel].psy_bands[w+g];
psy_band->threshold = band->thr;
psy_band->energy = band->energy;
@@ -740,6 +741,16 @@ static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
memcpy(pch->prev_band, pch->band, sizeof(pch->band));
}
+static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
+ const float **coeffs, const FFPsyWindowInfo *wi)
+{
+ int ch;
+ FFPsyChannelGroup *group = ff_psy_find_group(ctx, channel);
+
+ for (ch = 0; ch < group->num_ch; ch++)
+ psy_3gpp_analyze_channel(ctx, channel + ch, coeffs[ch], &wi[ch]);
+}
+
static av_cold void psy_3gpp_end(FFPsyContext *apc)
{
AacPsyContext *pctx = (AacPsyContext*) apc->model_priv_data;
diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c
index e80e094..11ea577 100644
--- a/libavcodec/aasc.c
+++ b/libavcodec/aasc.c
@@ -110,14 +110,13 @@ static av_cold int aasc_decode_end(AVCodecContext *avctx)
}
AVCodec ff_aasc_decoder = {
- "aasc",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_AASC,
- sizeof(AascContext),
- aasc_decode_init,
- NULL,
- aasc_decode_end,
- aasc_decode_frame,
- CODEC_CAP_DR1,
+ .name = "aasc",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_AASC,
+ .priv_data_size = sizeof(AascContext),
+ .init = aasc_decode_init,
+ .close = aasc_decode_end,
+ .decode = aasc_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Autodesk RLE"),
};
diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h
index 9adad93..304c86c 100644
--- a/libavcodec/ac3.h
+++ b/libavcodec/ac3.h
@@ -118,7 +118,7 @@ typedef struct {
uint32_t bit_rate;
uint8_t channels;
uint16_t frame_size;
- int64_t channel_layout;
+ uint64_t channel_layout;
/** @} */
} AC3HeaderInfo;
diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c
index 82eeda3..e3c46fd 100644
--- a/libavcodec/ac3_parser.c
+++ b/libavcodec/ac3_parser.c
@@ -35,7 +35,7 @@ static const uint8_t eac3_blocks[4] = {
};
-int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
+int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
{
int frame_size_code;
@@ -141,7 +141,7 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info,
GetBitContext gbc;
init_get_bits(&gbc, tmp.u8+8-AC3_HEADER_SIZE, 54);
- err = ff_ac3_parse_header(&gbc, &hdr);
+ err = avpriv_ac3_parse_header(&gbc, &hdr);
if(err < 0)
return 0;
@@ -174,9 +174,9 @@ static av_cold int ac3_parse_init(AVCodecParserContext *s1)
AVCodecParser ff_ac3_parser = {
- { CODEC_ID_AC3, CODEC_ID_EAC3 },
- sizeof(AACAC3ParseContext),
- ac3_parse_init,
- ff_aac_ac3_parse,
- ff_parse_close,
+ .codec_ids = { CODEC_ID_AC3, CODEC_ID_EAC3 },
+ .priv_data_size = sizeof(AACAC3ParseContext),
+ .parser_init = ac3_parse_init,
+ .parser_parse = ff_aac_ac3_parse,
+ .parser_close = ff_parse_close,
};
diff --git a/libavcodec/ac3_parser.h b/libavcodec/ac3_parser.h
index d62490b..9322550 100644
--- a/libavcodec/ac3_parser.h
+++ b/libavcodec/ac3_parser.h
@@ -36,6 +36,6 @@
* -2 if the bsid (version) element is invalid, -3 if the fscod (sample rate)
* element is invalid, or -4 if the frmsizecod (bit rate) element is invalid.
*/
-int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr);
+int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr);
#endif /* AVCODEC_AC3_PARSER_H */
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index 2966c33..83cfa0a 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -30,6 +30,7 @@
#include <string.h>
#include "libavutil/crc.h"
+#include "libavutil/opt.h"
#include "internal.h"
#include "aac_ac3_parser.h"
#include "ac3_parser.h"
@@ -37,16 +38,12 @@
#include "ac3dec_data.h"
#include "kbdwin.h"
-/** Large enough for maximum possible frame size when the specification limit is ignored */
-#define AC3_FRAME_BUFFER_SIZE 32768
-
/**
* table for ungrouping 3 values in 7 bits.
* used for exponents and bap=2 mantissas
*/
static uint8_t ungroup_3_in_7_bits_tab[128][3];
-
/** tables for ungrouping mantissas */
static int b1_mantissas[32][3];
static int b2_mantissas[128][3];
@@ -126,7 +123,7 @@ static av_cold void ac3_tables_init(void)
/* generate table for ungrouping 3 values in 7 bits
reference: Section 7.1.3 Exponent Decoding */
- for(i=0; i<128; i++) {
+ for (i = 0; i < 128; i++) {
ungroup_3_in_7_bits_tab[i][0] = i / 25;
ungroup_3_in_7_bits_tab[i][1] = (i % 25) / 5;
ungroup_3_in_7_bits_tab[i][2] = (i % 25) % 5;
@@ -134,13 +131,13 @@ static av_cold void ac3_tables_init(void)
/* generate grouped mantissa tables
reference: Section 7.3.5 Ungrouping of Mantissas */
- for(i=0; i<32; i++) {
+ for (i = 0; i < 32; i++) {
/* bap=1 mantissas */
b1_mantissas[i][0] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][0], 3);
b1_mantissas[i][1] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][1], 3);
b1_mantissas[i][2] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][2], 3);
}
- for(i=0; i<128; i++) {
+ for (i = 0; i < 128; i++) {
/* bap=2 mantissas */
b2_mantissas[i][0] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][0], 5);
b2_mantissas[i][1] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][1], 5);
@@ -152,24 +149,23 @@ static av_cold void ac3_tables_init(void)
}
/* generate ungrouped mantissa tables
reference: Tables 7.21 and 7.23 */
- for(i=0; i<7; i++) {
+ for (i = 0; i < 7; i++) {
/* bap=3 mantissas */
b3_mantissas[i] = symmetric_dequant(i, 7);
}
- for(i=0; i<15; i++) {
+ for (i = 0; i < 15; i++) {
/* bap=5 mantissas */
b5_mantissas[i] = symmetric_dequant(i, 15);
}
/* generate dynamic range table
reference: Section 7.7.1 Dynamic Range Control */
- for(i=0; i<256; i++) {
+ for (i = 0; i < 256; i++) {
int v = (i >> 5) - ((i >> 7) << 3) - 5;
dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0x1F) | 0x20);
}
}
-
/**
* AVCodec initialization
*/
@@ -178,6 +174,11 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
AC3DecodeContext *s = avctx->priv_data;
s->avctx = avctx;
+#if FF_API_DRC_SCALE
+ if (avctx->drc_scale)
+ s->drc_scale = avctx->drc_scale;
+#endif
+
ff_ac3_common_init();
ac3_tables_init();
ff_mdct_init(&s->imdct_256, 8, 1, 1.0);
@@ -205,10 +206,8 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
}
s->downmixed = 1;
- /* allocate context input buffer */
- s->input_buffer = av_mallocz(AC3_FRAME_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!s->input_buffer)
- return AVERROR(ENOMEM);
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
return 0;
}
@@ -249,7 +248,7 @@ static int ac3_parse_header(AC3DecodeContext *s)
i = get_bits(gbc, 6);
do {
skip_bits(gbc, 8);
- } while(i--);
+ } while (i--);
}
return 0;
@@ -263,8 +262,8 @@ static int parse_frame_header(AC3DecodeContext *s)
AC3HeaderInfo hdr;
int err;
- err = ff_ac3_parse_header(&s->gbc, &hdr);
- if(err)
+ err = avpriv_ac3_parse_header(&s->gbc, &hdr);
+ if (err)
return err;
/* get decoding parameters from header info */
@@ -286,9 +285,9 @@ static int parse_frame_header(AC3DecodeContext *s)
s->frame_type = hdr.frame_type;
s->substreamid = hdr.substreamid;
- if(s->lfe_on) {
- s->start_freq[s->lfe_ch] = 0;
- s->end_freq[s->lfe_ch] = 7;
+ if (s->lfe_on) {
+ s->start_freq[s->lfe_ch] = 0;
+ s->end_freq[s->lfe_ch] = 7;
s->num_exp_groups[s->lfe_ch] = 2;
s->channel_in_cpl[s->lfe_ch] = 0;
}
@@ -325,38 +324,39 @@ static void set_downmix_coeffs(AC3DecodeContext *s)
float smix = gain_levels[surround_levels[s->surround_mix_level]];
float norm0, norm1;
- for(i=0; i<s->fbw_channels; i++) {
+ for (i = 0; i < s->fbw_channels; i++) {
s->downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]];
s->downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]];
}
- if(s->channel_mode > 1 && s->channel_mode & 1) {
+ if (s->channel_mode > 1 && s->channel_mode & 1) {
s->downmix_coeffs[1][0] = s->downmix_coeffs[1][1] = cmix;
}
- if(s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) {
+ if (s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) {
int nf = s->channel_mode - 2;
s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB;
}
- if(s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) {
+ if (s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) {
int nf = s->channel_mode - 4;
s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf+1][1] = smix;
}
/* renormalize */
norm0 = norm1 = 0.0;
- for(i=0; i<s->fbw_channels; i++) {
+ for (i = 0; i < s->fbw_channels; i++) {
norm0 += s->downmix_coeffs[i][0];
norm1 += s->downmix_coeffs[i][1];
}
norm0 = 1.0f / norm0;
norm1 = 1.0f / norm1;
- for(i=0; i<s->fbw_channels; i++) {
+ for (i = 0; i < s->fbw_channels; i++) {
s->downmix_coeffs[i][0] *= norm0;
s->downmix_coeffs[i][1] *= norm1;
}
- if(s->output_mode == AC3_CHMODE_MONO) {
- for(i=0; i<s->fbw_channels; i++)
- s->downmix_coeffs[i][0] = (s->downmix_coeffs[i][0] + s->downmix_coeffs[i][1]) * LEVEL_MINUS_3DB;
+ if (s->output_mode == AC3_CHMODE_MONO) {
+ for (i = 0; i < s->fbw_channels; i++)
+ s->downmix_coeffs[i][0] = (s->downmix_coeffs[i][0] +
+ s->downmix_coeffs[i][1]) * LEVEL_MINUS_3DB;
}
}
@@ -373,7 +373,7 @@ static int decode_exponents(GetBitContext *gbc, int exp_strategy, int ngrps,
/* unpack groups */
group_size = exp_strategy + (exp_strategy == EXP_D45);
- for(grp=0,i=0; grp<ngrps; grp++) {
+ for (grp = 0, i = 0; grp < ngrps; grp++) {
expacc = get_bits(gbc, 7);
dexp[i++] = ungroup_3_in_7_bits_tab[expacc][0];
dexp[i++] = ungroup_3_in_7_bits_tab[expacc][1];
@@ -382,15 +382,15 @@ static int decode_exponents(GetBitContext *gbc, int exp_strategy, int ngrps,
/* convert to absolute exps and expand groups */
prevexp = absexp;
- for(i=0,j=0; i<ngrps*3; i++) {
+ for (i = 0, j = 0; i < ngrps * 3; i++) {
prevexp += dexp[i] - 2;
if (prevexp > 24U)
return -1;
switch (group_size) {
- case 4: dexps[j++] = prevexp;
- dexps[j++] = prevexp;
- case 2: dexps[j++] = prevexp;
- case 1: dexps[j++] = prevexp;
+ case 4: dexps[j++] = prevexp;
+ dexps[j++] = prevexp;
+ case 2: dexps[j++] = prevexp;
+ case 1: dexps[j++] = prevexp;
}
}
return 0;
@@ -413,7 +413,8 @@ static void calc_transform_coeffs_cpl(AC3DecodeContext *s)
if (s->channel_in_cpl[ch]) {
int cpl_coord = s->cpl_coords[ch][band] << 5;
for (bin = band_start; bin < band_end; bin++) {
- s->fixed_coeffs[ch][bin] = MULH(s->fixed_coeffs[CPL_CH][bin] << 4, cpl_coord);
+ s->fixed_coeffs[ch][bin] =
+ MULH(s->fixed_coeffs[CPL_CH][bin] << 4, cpl_coord);
}
if (ch == 2 && s->phase_flags[band]) {
for (bin = band_start; bin < band_end; bin++)
@@ -444,73 +445,70 @@ typedef struct {
static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, mant_groups *m)
{
int start_freq = s->start_freq[ch_index];
- int end_freq = s->end_freq[ch_index];
- uint8_t *baps = s->bap[ch_index];
- int8_t *exps = s->dexps[ch_index];
- int *coeffs = s->fixed_coeffs[ch_index];
- int dither = (ch_index == CPL_CH) || s->dither_flag[ch_index];
+ int end_freq = s->end_freq[ch_index];
+ uint8_t *baps = s->bap[ch_index];
+ int8_t *exps = s->dexps[ch_index];
+ int *coeffs = s->fixed_coeffs[ch_index];
+ int dither = (ch_index == CPL_CH) || s->dither_flag[ch_index];
GetBitContext *gbc = &s->gbc;
int freq;
- for(freq = start_freq; freq < end_freq; freq++){
+ for (freq = start_freq; freq < end_freq; freq++) {
int bap = baps[freq];
int mantissa;
- switch(bap){
- case 0:
- if (dither)
- mantissa = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000;
- else
- mantissa = 0;
- break;
- case 1:
- if(m->b1){
- m->b1--;
- mantissa = m->b1_mant[m->b1];
- }
- else{
- int bits = get_bits(gbc, 5);
- mantissa = b1_mantissas[bits][0];
- m->b1_mant[1] = b1_mantissas[bits][1];
- m->b1_mant[0] = b1_mantissas[bits][2];
- m->b1 = 2;
- }
- break;
- case 2:
- if(m->b2){
- m->b2--;
- mantissa = m->b2_mant[m->b2];
- }
- else{
- int bits = get_bits(gbc, 7);
- mantissa = b2_mantissas[bits][0];
- m->b2_mant[1] = b2_mantissas[bits][1];
- m->b2_mant[0] = b2_mantissas[bits][2];
- m->b2 = 2;
- }
- break;
- case 3:
- mantissa = b3_mantissas[get_bits(gbc, 3)];
- break;
- case 4:
- if(m->b4){
- m->b4 = 0;
- mantissa = m->b4_mant;
- }
- else{
- int bits = get_bits(gbc, 7);
- mantissa = b4_mantissas[bits][0];
- m->b4_mant = b4_mantissas[bits][1];
- m->b4 = 1;
- }
- break;
- case 5:
- mantissa = b5_mantissas[get_bits(gbc, 4)];
- break;
- default: /* 6 to 15 */
- mantissa = get_bits(gbc, quantization_tab[bap]);
- /* Shift mantissa and sign-extend it. */
- mantissa = (mantissa << (32-quantization_tab[bap]))>>8;
- break;
+ switch (bap) {
+ case 0:
+ if (dither)
+ mantissa = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000;
+ else
+ mantissa = 0;
+ break;
+ case 1:
+ if (m->b1) {
+ m->b1--;
+ mantissa = m->b1_mant[m->b1];
+ } else {
+ int bits = get_bits(gbc, 5);
+ mantissa = b1_mantissas[bits][0];
+ m->b1_mant[1] = b1_mantissas[bits][1];
+ m->b1_mant[0] = b1_mantissas[bits][2];
+ m->b1 = 2;
+ }
+ break;
+ case 2:
+ if (m->b2) {
+ m->b2--;
+ mantissa = m->b2_mant[m->b2];
+ } else {
+ int bits = get_bits(gbc, 7);
+ mantissa = b2_mantissas[bits][0];
+ m->b2_mant[1] = b2_mantissas[bits][1];
+ m->b2_mant[0] = b2_mantissas[bits][2];
+ m->b2 = 2;
+ }
+ break;
+ case 3:
+ mantissa = b3_mantissas[get_bits(gbc, 3)];
+ break;
+ case 4:
+ if (m->b4) {
+ m->b4 = 0;
+ mantissa = m->b4_mant;
+ } else {
+ int bits = get_bits(gbc, 7);
+ mantissa = b4_mantissas[bits][0];
+ m->b4_mant = b4_mantissas[bits][1];
+ m->b4 = 1;
+ }
+ break;
+ case 5:
+ mantissa = b5_mantissas[get_bits(gbc, 4)];
+ break;
+ default: /* 6 to 15 */
+ /* Shift mantissa and sign-extend it. */
+ mantissa = get_sbits(gbc, quantization_tab[bap]);
+ mantissa <<= 24 - quantization_tab[bap];
+ break;
}
coeffs[freq] = mantissa >> exps[freq];
}
@@ -524,10 +522,10 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma
static void remove_dithering(AC3DecodeContext *s) {
int ch, i;
- for(ch=1; ch<=s->fbw_channels; ch++) {
- if(!s->dither_flag[ch] && s->channel_in_cpl[ch]) {
- for(i = s->start_freq[CPL_CH]; i<s->end_freq[CPL_CH]; i++) {
- if(!s->bap[CPL_CH][i])
+ for (ch = 1; ch <= s->fbw_channels; ch++) {
+ if (!s->dither_flag[ch] && s->channel_in_cpl[ch]) {
+ for (i = s->start_freq[CPL_CH]; i < s->end_freq[CPL_CH]; i++) {
+ if (!s->bap[CPL_CH][i])
s->fixed_coeffs[ch][i] = 0;
}
}
@@ -535,7 +533,7 @@ static void remove_dithering(AC3DecodeContext *s) {
}
static void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk, int ch,
- mant_groups *m)
+ mant_groups *m)
{
if (!s->channel_uses_aht[ch]) {
ac3_decode_transform_coeffs_ch(s, ch, m);
@@ -579,7 +577,7 @@ static void decode_transform_coeffs(AC3DecodeContext *s, int blk)
}
do
s->fixed_coeffs[ch][end] = 0;
- while(++end < 256);
+ while (++end < 256);
}
/* zero the dithered coefficients for appropriate channels */
@@ -597,10 +595,10 @@ static void do_rematrixing(AC3DecodeContext *s)
end = FFMIN(s->end_freq[1], s->end_freq[2]);
- for(bnd=0; bnd<s->num_rematrixing_bands; bnd++) {
- if(s->rematrixing_flags[bnd]) {
- bndend = FFMIN(end, ff_ac3_rematrix_band_tab[bnd+1]);
- for(i=ff_ac3_rematrix_band_tab[bnd]; i<bndend; i++) {
+ for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) {
+ if (s->rematrixing_flags[bnd]) {
+ bndend = FFMIN(end, ff_ac3_rematrix_band_tab[bnd + 1]);
+ for (i = ff_ac3_rematrix_band_tab[bnd]; i < bndend; i++) {
int tmp0 = s->fixed_coeffs[1][i];
s->fixed_coeffs[1][i] += s->fixed_coeffs[2][i];
s->fixed_coeffs[2][i] = tmp0 - s->fixed_coeffs[2][i];
@@ -618,21 +616,23 @@ static inline void do_imdct(AC3DecodeContext *s, int channels)
{
int ch;
- for (ch=1; ch<=channels; ch++) {
+ for (ch = 1; ch <= channels; ch++) {
if (s->block_switch[ch]) {
int i;
- float *x = s->tmp_output+128;
- for(i=0; i<128; i++)
- x[i] = s->transform_coeffs[ch][2*i];
+ float *x = s->tmp_output + 128;
+ for (i = 0; i < 128; i++)
+ x[i] = s->transform_coeffs[ch][2 * i];
s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x);
- s->dsp.vector_fmul_window(s->output[ch-1], s->delay[ch-1], s->tmp_output, s->window, 128);
- for(i=0; i<128; i++)
- x[i] = s->transform_coeffs[ch][2*i+1];
- s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch-1], x);
+ s->dsp.vector_fmul_window(s->output[ch - 1], s->delay[ch - 1],
+ s->tmp_output, s->window, 128);
+ for (i = 0; i < 128; i++)
+ x[i] = s->transform_coeffs[ch][2 * i + 1];
+ s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1], x);
} else {
s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]);
- s->dsp.vector_fmul_window(s->output[ch-1], s->delay[ch-1], s->tmp_output, s->window, 128);
- memcpy(s->delay[ch-1], s->tmp_output+128, 128*sizeof(float));
+ s->dsp.vector_fmul_window(s->output[ch - 1], s->delay[ch - 1],
+ s->tmp_output, s->window, 128);
+ memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(float));
}
}
}
@@ -640,24 +640,25 @@ static inline void do_imdct(AC3DecodeContext *s, int channels)
/**
* Downmix the output to mono or stereo.
*/
-void ff_ac3_downmix_c(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len)
+void ff_ac3_downmix_c(float (*samples)[256], float (*matrix)[2],
+ int out_ch, int in_ch, int len)
{
int i, j;
float v0, v1;
- if(out_ch == 2) {
- for(i=0; i<len; i++) {
+ if (out_ch == 2) {
+ for (i = 0; i < len; i++) {
v0 = v1 = 0.0f;
- for(j=0; j<in_ch; j++) {
+ for (j = 0; j < in_ch; j++) {
v0 += samples[j][i] * matrix[j][0];
v1 += samples[j][i] * matrix[j][1];
}
samples[0][i] = v0;
samples[1][i] = v1;
}
- } else if(out_ch == 1) {
- for(i=0; i<len; i++) {
+ } else if (out_ch == 1) {
+ for (i = 0; i < len; i++) {
v0 = 0.0f;
- for(j=0; j<in_ch; j++)
+ for (j = 0; j < in_ch; j++)
v0 += samples[j][i] * matrix[j][0];
samples[0][i] = v0;
}
@@ -670,25 +671,25 @@ void ff_ac3_downmix_c(float (*samples)[256], float (*matrix)[2], int out_ch, int
static void ac3_upmix_delay(AC3DecodeContext *s)
{
int channel_data_size = sizeof(s->delay[0]);
- switch(s->channel_mode) {
- case AC3_CHMODE_DUALMONO:
- case AC3_CHMODE_STEREO:
- /* upmix mono to stereo */
- memcpy(s->delay[1], s->delay[0], channel_data_size);
- break;
- case AC3_CHMODE_2F2R:
- memset(s->delay[3], 0, channel_data_size);
- case AC3_CHMODE_2F1R:
- memset(s->delay[2], 0, channel_data_size);
- break;
- case AC3_CHMODE_3F2R:
- memset(s->delay[4], 0, channel_data_size);
- case AC3_CHMODE_3F1R:
- memset(s->delay[3], 0, channel_data_size);
- case AC3_CHMODE_3F:
- memcpy(s->delay[2], s->delay[1], channel_data_size);
- memset(s->delay[1], 0, channel_data_size);
- break;
+ switch (s->channel_mode) {
+ case AC3_CHMODE_DUALMONO:
+ case AC3_CHMODE_STEREO:
+ /* upmix mono to stereo */
+ memcpy(s->delay[1], s->delay[0], channel_data_size);
+ break;
+ case AC3_CHMODE_2F2R:
+ memset(s->delay[3], 0, channel_data_size);
+ case AC3_CHMODE_2F1R:
+ memset(s->delay[2], 0, channel_data_size);
+ break;
+ case AC3_CHMODE_3F2R:
+ memset(s->delay[4], 0, channel_data_size);
+ case AC3_CHMODE_3F1R:
+ memset(s->delay[3], 0, channel_data_size);
+ case AC3_CHMODE_3F:
+ memcpy(s->delay[2], s->delay[1], channel_data_size);
+ memset(s->delay[1], 0, channel_data_size);
+ break;
}
}
@@ -741,7 +742,7 @@ static void decode_band_structure(GetBitContext *gbc, int blk, int eac3,
bnd_sz[0] = ecpl ? 6 : 12;
for (bnd = 0, subbnd = 1; subbnd < n_subbands; subbnd++) {
int subbnd_size = (ecpl && subbnd < 4) ? 6 : 12;
- if (band_struct[subbnd-1]) {
+ if (band_struct[subbnd - 1]) {
n_bands--;
bnd_sz[bnd] += subbnd_size;
} else {
@@ -778,7 +779,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
if (s->block_switch_syntax) {
for (ch = 1; ch <= fbw_channels; ch++) {
s->block_switch[ch] = get_bits1(gbc);
- if(ch > 1 && s->block_switch[ch] != s->block_switch[1])
+ if (ch > 1 && s->block_switch[ch] != s->block_switch[1])
different_transforms = 1;
}
}
@@ -793,13 +794,13 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
/* dynamic range */
i = !(s->channel_mode);
do {
- if(get_bits1(gbc)) {
- s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)]-1.0) *
- s->avctx->drc_scale)+1.0;
- } else if(blk == 0) {
+ if (get_bits1(gbc)) {
+ s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)] - 1.0) *
+ s->drc_scale) + 1.0;
+ } else if (blk == 0) {
s->dynamic_range[i] = 1.0f;
}
- } while(i--);
+ } while (i--);
/* spectral extension strategy */
if (s->eac3 && (!blk || get_bits1(gbc))) {
@@ -880,7 +881,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
bandsize = s->spx_band_sizes[bnd];
nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend;
nratio = av_clipf(nratio, 0.0f, 1.0f);
- nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3) to give unity variance
+ nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3)
+ // to give unity variance
sblend = sqrtf(1.0f - nratio);
bin += bandsize;
@@ -890,7 +892,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
if (spx_coord_exp == 15) spx_coord_mant <<= 1;
else spx_coord_mant += 4;
spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord);
- spx_coord = spx_coord_mant * (1.0f/(1<<23));
+ spx_coord = spx_coord_mant * (1.0f / (1 << 23));
/* multiply noise and signal blending factors by spx coordinate */
s->spx_noise_blend [ch][bnd] = nblend * spx_coord;
@@ -963,8 +965,9 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
s->phase_flags_in_use = 0;
}
} else if (!s->eac3) {
- if(!blk) {
- av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must be present in block 0\n");
+ if (!blk) {
+ av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must "
+ "be present in block 0\n");
return -1;
} else {
s->cpl_in_use[blk] = s->cpl_in_use[blk-1];
@@ -993,7 +996,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord);
}
} else if (!blk) {
- av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must be present in block 0\n");
+ av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must "
+ "be present in block 0\n");
return -1;
}
} else {
@@ -1018,10 +1022,11 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
} else if (s->spx_in_use && s->spx_src_start_freq <= 61) {
s->num_rematrixing_bands--;
}
- for(bnd=0; bnd<s->num_rematrixing_bands; bnd++)
+ for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++)
s->rematrixing_flags[bnd] = get_bits1(gbc);
} else if (!blk) {
- av_log(s->avctx, AV_LOG_WARNING, "Warning: new rematrixing strategy not present in block 0\n");
+ av_log(s->avctx, AV_LOG_WARNING, "Warning: "
+ "new rematrixing strategy not present in block 0\n");
s->num_rematrixing_bands = 0;
}
}
@@ -1030,7 +1035,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
for (ch = !cpl_in_use; ch <= s->channels; ch++) {
if (!s->eac3)
s->exp_strategy[blk][ch] = get_bits(gbc, 2 - (ch == s->lfe_ch));
- if(s->exp_strategy[blk][ch] != EXP_REUSE)
+ if (s->exp_strategy[blk][ch] != EXP_REUSE)
bit_alloc_stages[ch] = 3;
}
@@ -1053,8 +1058,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
s->end_freq[ch] = bandwidth_code * 3 + 73;
}
group_size = 3 << (s->exp_strategy[blk][ch] - 1);
- s->num_exp_groups[ch] = (s->end_freq[ch]+group_size-4) / group_size;
- if(blk > 0 && s->end_freq[ch] != prev)
+ s->num_exp_groups[ch] = (s->end_freq[ch] + group_size-4) / group_size;
+ if (blk > 0 && s->end_freq[ch] != prev)
memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);
}
}
@@ -1073,7 +1078,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
av_log(s->avctx, AV_LOG_ERROR, "exponent out-of-range\n");
return -1;
}
- if(ch != CPL_CH && ch != s->lfe_ch)
+ if (ch != CPL_CH && ch != s->lfe_ch)
skip_bits(gbc, 2); /* skip gainrng */
}
}
@@ -1086,17 +1091,18 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
s->bit_alloc_params.slow_gain = ff_ac3_slow_gain_tab[get_bits(gbc, 2)];
s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[get_bits(gbc, 2)];
s->bit_alloc_params.floor = ff_ac3_floor_tab[get_bits(gbc, 3)];
- for(ch=!cpl_in_use; ch<=s->channels; ch++)
+ for (ch = !cpl_in_use; ch <= s->channels; ch++)
bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
} else if (!blk) {
- av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must be present in block 0\n");
+ av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must "
+ "be present in block 0\n");
return -1;
}
}
/* signal-to-noise ratio offsets and fast gains (signal-to-mask ratios) */
- if(!s->eac3 || !blk){
- if(s->snr_offset_strategy && get_bits1(gbc)) {
+ if (!s->eac3 || !blk) {
+ if (s->snr_offset_strategy && get_bits1(gbc)) {
int snr = 0;
int csnr;
csnr = (get_bits(gbc, 6) - 15) << 4;
@@ -1105,7 +1111,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
if (ch == i || s->snr_offset_strategy == 2)
snr = (csnr + get_bits(gbc, 4)) << 2;
/* run at least last bit allocation stage if snr offset changes */
- if(blk && s->snr_offset[ch] != snr) {
+ if (blk && s->snr_offset[ch] != snr) {
bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 1);
}
s->snr_offset[ch] = snr;
@@ -1115,7 +1121,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
int prev = s->fast_gain[ch];
s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)];
/* run last 2 bit allocation stages if fast gain changes */
- if(blk && prev != s->fast_gain[ch])
+ if (blk && prev != s->fast_gain[ch])
bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
}
}
@@ -1131,7 +1137,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
int prev = s->fast_gain[ch];
s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)];
/* run last 2 bit allocation stages if fast gain changes */
- if(blk && prev != s->fast_gain[ch])
+ if (blk && prev != s->fast_gain[ch])
bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
}
} else if (s->eac3 && !blk) {
@@ -1151,14 +1157,15 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
int sl = get_bits(gbc, 3);
/* run last 2 bit allocation stages for coupling channel if
coupling leak changes */
- if(blk && (fl != s->bit_alloc_params.cpl_fast_leak ||
- sl != s->bit_alloc_params.cpl_slow_leak)) {
+ if (blk && (fl != s->bit_alloc_params.cpl_fast_leak ||
+ sl != s->bit_alloc_params.cpl_slow_leak)) {
bit_alloc_stages[CPL_CH] = FFMAX(bit_alloc_stages[CPL_CH], 2);
}
s->bit_alloc_params.cpl_fast_leak = fl;
s->bit_alloc_params.cpl_slow_leak = sl;
} else if (!s->eac3 && !blk) {
- av_log(s->avctx, AV_LOG_ERROR, "new coupling leak info must be present in block 0\n");
+ av_log(s->avctx, AV_LOG_ERROR, "new coupling leak info must "
+ "be present in block 0\n");
return -1;
}
s->first_cpl_leak = 0;
@@ -1182,40 +1189,40 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
for (seg = 0; seg < s->dba_nsegs[ch]; seg++) {
s->dba_offsets[ch][seg] = get_bits(gbc, 5);
s->dba_lengths[ch][seg] = get_bits(gbc, 4);
- s->dba_values[ch][seg] = get_bits(gbc, 3);
+ s->dba_values[ch][seg] = get_bits(gbc, 3);
}
/* run last 2 bit allocation stages if new dba values */
bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
}
}
- } else if(blk == 0) {
- for(ch=0; ch<=s->channels; ch++) {
+ } else if (blk == 0) {
+ for (ch = 0; ch <= s->channels; ch++) {
s->dba_mode[ch] = DBA_NONE;
}
}
/* Bit allocation */
- for(ch=!cpl_in_use; ch<=s->channels; ch++) {
- if(bit_alloc_stages[ch] > 2) {
+ for (ch = !cpl_in_use; ch <= s->channels; ch++) {
+ if (bit_alloc_stages[ch] > 2) {
/* Exponent mapping into PSD and PSD integration */
ff_ac3_bit_alloc_calc_psd(s->dexps[ch],
s->start_freq[ch], s->end_freq[ch],
s->psd[ch], s->band_psd[ch]);
}
- if(bit_alloc_stages[ch] > 1) {
+ if (bit_alloc_stages[ch] > 1) {
/* Compute excitation function, Compute masking curve, and
Apply delta bit allocation */
if (ff_ac3_bit_alloc_calc_mask(&s->bit_alloc_params, s->band_psd[ch],
- s->start_freq[ch], s->end_freq[ch],
- s->fast_gain[ch], (ch == s->lfe_ch),
- s->dba_mode[ch], s->dba_nsegs[ch],
+ s->start_freq[ch], s->end_freq[ch],
+ s->fast_gain[ch], (ch == s->lfe_ch),
+ s->dba_mode[ch], s->dba_nsegs[ch],
s->dba_offsets[ch], s->dba_lengths[ch],
- s->dba_values[ch], s->mask[ch])) {
+ s->dba_values[ch], s->mask[ch])) {
av_log(s->avctx, AV_LOG_ERROR, "error in bit allocation\n");
return -1;
}
}
- if(bit_alloc_stages[ch] > 0) {
+ if (bit_alloc_stages[ch] > 0) {
/* Compute bit allocation */
const uint8_t *bap_tab = s->channel_uses_aht[ch] ?
ff_eac3_hebap_tab : ff_ac3_bap_tab;
@@ -1230,7 +1237,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
/* unused dummy data */
if (s->skip_syntax && get_bits1(gbc)) {
int skipl = get_bits(gbc, 9);
- while(skipl--)
+ while (skipl--)
skip_bits(gbc, 8);
}
@@ -1241,18 +1248,19 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
/* TODO: generate enhanced coupling coordinates and uncouple */
/* recover coefficients if rematrixing is in use */
- if(s->channel_mode == AC3_CHMODE_STEREO)
+ if (s->channel_mode == AC3_CHMODE_STEREO)
do_rematrixing(s);
/* apply scaling to coefficients (headroom, dynrng) */
- for(ch=1; ch<=s->channels; ch++) {
+ for (ch = 1; ch <= s->channels; ch++) {
float gain = s->mul_bias / 4194304.0f;
- if(s->channel_mode == AC3_CHMODE_DUALMONO) {
- gain *= s->dynamic_range[2-ch];
+ if (s->channel_mode == AC3_CHMODE_DUALMONO) {
+ gain *= s->dynamic_range[2 - ch];
} else {
gain *= s->dynamic_range[0];
}
- s->fmt_conv.int32_to_float_fmul_scalar(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256);
+ s->fmt_conv.int32_to_float_fmul_scalar(s->transform_coeffs[ch],
+ s->fixed_coeffs[ch], gain, 256);
}
/* apply spectral extension to high frequency bins */
@@ -1266,27 +1274,30 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
downmix_output = s->channels != s->out_channels &&
!((s->output_mode & AC3_OUTPUT_LFEON) &&
s->fbw_channels == s->out_channels);
- if(different_transforms) {
+ if (different_transforms) {
/* the delay samples have already been downmixed, so we upmix the delay
samples in order to reconstruct all channels before downmixing. */
- if(s->downmixed) {
+ if (s->downmixed) {
s->downmixed = 0;
ac3_upmix_delay(s);
}
do_imdct(s, s->channels);
- if(downmix_output) {
- s->dsp.ac3_downmix(s->output, s->downmix_coeffs, s->out_channels, s->fbw_channels, 256);
+ if (downmix_output) {
+ s->dsp.ac3_downmix(s->output, s->downmix_coeffs,
+ s->out_channels, s->fbw_channels, 256);
}
} else {
- if(downmix_output) {
- s->dsp.ac3_downmix(s->transform_coeffs+1, s->downmix_coeffs, s->out_channels, s->fbw_channels, 256);
+ if (downmix_output) {
+ s->dsp.ac3_downmix(s->transform_coeffs + 1, s->downmix_coeffs,
+ s->out_channels, s->fbw_channels, 256);
}
- if(downmix_output && !s->downmixed) {
+ if (downmix_output && !s->downmixed) {
s->downmixed = 1;
- s->dsp.ac3_downmix(s->delay, s->downmix_coeffs, s->out_channels, s->fbw_channels, 128);
+ s->dsp.ac3_downmix(s->delay, s->downmix_coeffs, s->out_channels,
+ s->fbw_channels, 128);
}
do_imdct(s, s->out_channels);
@@ -1298,15 +1309,15 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
/**
* Decode a single AC-3 frame.
*/
-static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
- AVPacket *avpkt)
+static int ac3_decode_frame(AVCodecContext * avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
AC3DecodeContext *s = avctx->priv_data;
- float *out_samples_flt = data;
- int16_t *out_samples_s16 = data;
- int blk, ch, err;
+ float *out_samples_flt;
+ int16_t *out_samples_s16;
+ int blk, ch, err, ret;
const uint8_t *channel_map;
const float *output[AC3_MAX_CHANNELS];
@@ -1323,45 +1334,47 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
init_get_bits(&s->gbc, buf, buf_size * 8);
/* parse the syncinfo */
- *data_size = 0;
err = parse_frame_header(s);
if (err) {
- switch(err) {
- case AAC_AC3_PARSE_ERROR_SYNC:
- av_log(avctx, AV_LOG_ERROR, "frame sync error\n");
- return -1;
- case AAC_AC3_PARSE_ERROR_BSID:
- av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n");
- break;
- case AAC_AC3_PARSE_ERROR_SAMPLE_RATE:
- av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");
- break;
- case AAC_AC3_PARSE_ERROR_FRAME_SIZE:
- av_log(avctx, AV_LOG_ERROR, "invalid frame size\n");
- break;
- case AAC_AC3_PARSE_ERROR_FRAME_TYPE:
- /* skip frame if CRC is ok. otherwise use error concealment. */
- /* TODO: add support for substreams and dependent frames */
- if(s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) {
- av_log(avctx, AV_LOG_ERROR, "unsupported frame type : skipping frame\n");
- return s->frame_size;
- } else {
- av_log(avctx, AV_LOG_ERROR, "invalid frame type\n");
- }
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "invalid header\n");
- break;
+ switch (err) {
+ case AAC_AC3_PARSE_ERROR_SYNC:
+ av_log(avctx, AV_LOG_ERROR, "frame sync error\n");
+ return -1;
+ case AAC_AC3_PARSE_ERROR_BSID:
+ av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n");
+ break;
+ case AAC_AC3_PARSE_ERROR_SAMPLE_RATE:
+ av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");
+ break;
+ case AAC_AC3_PARSE_ERROR_FRAME_SIZE:
+ av_log(avctx, AV_LOG_ERROR, "invalid frame size\n");
+ break;
+ case AAC_AC3_PARSE_ERROR_FRAME_TYPE:
+ /* skip frame if CRC is ok. otherwise use error concealment. */
+ /* TODO: add support for substreams and dependent frames */
+ if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) {
+ av_log(avctx, AV_LOG_ERROR, "unsupported frame type : "
+ "skipping frame\n");
+ *got_frame_ptr = 0;
+ return s->frame_size;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "invalid frame type\n");
+ }
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "invalid header\n");
+ break;
}
} else {
/* check that reported frame size fits in input buffer */
if (s->frame_size > buf_size) {
av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
err = AAC_AC3_PARSE_ERROR_FRAME_SIZE;
- } else if (avctx->error_recognition >= FF_ER_CAREFUL) {
+ } else if (avctx->err_recognition & AV_EF_CRCCHECK) {
/* check for crc mismatch */
- if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size-2)) {
+ if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2],
+ s->frame_size - 2)) {
av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n");
err = AAC_AC3_PARSE_ERROR_CRC;
}
@@ -1371,12 +1384,12 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
/* if frame is ok, set audio parameters */
if (!err) {
avctx->sample_rate = s->sample_rate;
- avctx->bit_rate = s->bit_rate;
+ avctx->bit_rate = s->bit_rate;
/* channel config */
s->out_channels = s->channels;
- s->output_mode = s->channel_mode;
- if(s->lfe_on)
+ s->output_mode = s->channel_mode;
+ if (s->lfe_on)
s->output_mode |= AC3_OUTPUT_LFEON;
if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
avctx->request_channels < s->channels) {
@@ -1384,17 +1397,17 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;
s->channel_layout = ff_ac3_channel_layout_tab[s->output_mode];
}
- avctx->channels = s->out_channels;
+ avctx->channels = s->out_channels;
avctx->channel_layout = s->channel_layout;
/* set downmixing coefficients if needed */
- if(s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
+ if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
s->fbw_channels == s->out_channels)) {
set_downmix_coeffs(s);
}
} else if (!s->out_channels) {
s->out_channels = avctx->channels;
- if(s->out_channels < s->channels)
+ if (s->out_channels < s->channels)
s->output_mode = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;
}
/* set audio service type based on bitstream mode for AC-3 */
@@ -1402,6 +1415,15 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
if (s->bitstream_mode == 0x7 && s->channels > 1)
avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
+ /* get output buffer */
+ s->frame.nb_samples = s->num_blocks * 256;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ out_samples_flt = (float *)s->frame.data[0];
+ out_samples_s16 = (int16_t *)s->frame.data[0];
+
/* decode the audio blocks */
channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];
for (ch = 0; ch < s->out_channels; ch++)
@@ -1421,8 +1443,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
out_samples_s16 += 256 * s->out_channels;
}
}
- *data_size = s->num_blocks * 256 * avctx->channels *
- (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8);
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return FFMIN(buf_size, s->frame_size);
}
@@ -1435,37 +1459,60 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx)
ff_mdct_end(&s->imdct_512);
ff_mdct_end(&s->imdct_256);
- av_freep(&s->input_buffer);
-
return 0;
}
+#define OFFSET(x) offsetof(AC3DecodeContext, x)
+#define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM)
+static const AVOption options[] = {
+ { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {1.0}, 0.0, 1.0, PAR },
+ { NULL},
+};
+
+static const AVClass ac3_decoder_class = {
+ .class_name = "AC3 decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_ac3_decoder = {
- .name = "ac3",
- .type = AVMEDIA_TYPE_AUDIO,
- .id = CODEC_ID_AC3,
+ .name = "ac3",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AC3,
.priv_data_size = sizeof (AC3DecodeContext),
- .init = ac3_decode_init,
- .close = ac3_decode_end,
- .decode = ac3_decode_frame,
- .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
- .sample_fmts = (const enum AVSampleFormat[]) {
- AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
- },
+ .init = ac3_decode_init,
+ .close = ac3_decode_end,
+ .decode = ac3_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
+ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+ .priv_class = &ac3_decoder_class,
};
#if CONFIG_EAC3_DECODER
+static const AVClass eac3_decoder_class = {
+ .class_name = "E-AC3 decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_eac3_decoder = {
- .name = "eac3",
- .type = AVMEDIA_TYPE_AUDIO,
- .id = CODEC_ID_EAC3,
+ .name = "eac3",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_EAC3,
.priv_data_size = sizeof (AC3DecodeContext),
- .init = ac3_decode_init,
- .close = ac3_decode_end,
- .decode = ac3_decode_frame,
- .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
- .sample_fmts = (const enum AVSampleFormat[]) {
- AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
- },
+ .init = ac3_decode_init,
+ .close = ac3_decode_end,
+ .decode = ac3_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
+ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+ .priv_class = &eac3_decoder_class,
};
#endif
diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
index aed8743..56c6553 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -62,10 +62,14 @@
#define SPX_MAX_BANDS 17
+/** Large enough for maximum possible frame size when the specification limit is ignored */
+#define AC3_FRAME_BUFFER_SIZE 32768
+
typedef struct {
+ AVClass *class; ///< class for AVOptions
AVCodecContext *avctx; ///< parent context
+ AVFrame frame; ///< AVFrame for decoded output
GetBitContext gbc; ///< bitstream reader
- uint8_t *input_buffer; ///< temp buffer to prevent overread
///@name Bit stream information
///@{
@@ -141,6 +145,7 @@ typedef struct {
///@name Dynamic range
float dynamic_range[2]; ///< dynamic range
+ float drc_scale; ///< percentage of dynamic range compression to be applied
///@}
///@name Bandwidth
@@ -200,6 +205,7 @@ typedef struct {
DECLARE_ALIGNED(32, float, window)[AC3_BLOCK_SIZE]; ///< window coefficients
DECLARE_ALIGNED(32, float, tmp_output)[AC3_BLOCK_SIZE]; ///< temporary storage for output before windowing
DECLARE_ALIGNED(32, float, output)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing
+ DECLARE_ALIGNED(32, uint8_t, input_buffer)[AC3_FRAME_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; ///< temp buffer to prevent overread
///@}
} AC3DecodeContext;
diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c
index 8ce5f8d..98c7357 100644
--- a/libavcodec/ac3dsp.c
+++ b/libavcodec/ac3dsp.c
@@ -164,21 +164,8 @@ static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs)
int i;
for (i = 0; i < nb_coefs; i++) {
- int e;
int v = abs(coef[i]);
- if (v == 0)
- e = 24;
- else {
- e = 23 - av_log2(v);
- if (e >= 24) {
- e = 24;
- coef[i] = 0;
- } else if (e < 0) {
- e = 0;
- coef[i] = av_clip(coef[i], -16777215, 16777215);
- }
- }
- exp[i] = e;
+ exp[i] = v ? 23 - av_log2(v) : 24;
}
}
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index 3426bd2..b8e23e4 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -46,7 +46,7 @@
#include "eac3enc.h"
typedef struct AC3Mant {
- uint16_t *qmant1_ptr, *qmant2_ptr, *qmant4_ptr; ///< mantissa pointers for bap=1,2,4
+ int16_t *qmant1_ptr, *qmant2_ptr, *qmant4_ptr; ///< mantissa pointers for bap=1,2,4
int mant1_cnt, mant2_cnt, mant4_cnt; ///< mantissa counts for bap=1,2,4
} AC3Mant;
@@ -77,7 +77,7 @@ static uint8_t exponent_group_tab[2][3][256];
/**
* List of supported channel layouts.
*/
-const int64_t ff_ac3_channel_layouts[19] = {
+const uint64_t ff_ac3_channel_layouts[19] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_2_1,
@@ -176,8 +176,10 @@ static const int8_t ac3_coupling_start_tab[6][3][19] = {
/**
* Adjust the frame size to make the average bit rate match the target bit rate.
* This is only needed for 11025, 22050, and 44100 sample rates or any E-AC-3.
+ *
+ * @param s AC-3 encoder private context
*/
-static void adjust_frame_size(AC3EncodeContext *s)
+void ff_ac3_adjust_frame_size(AC3EncodeContext *s)
{
while (s->bits_written >= s->bit_rate && s->samples_written >= s->sample_rate) {
s->bits_written -= s->bit_rate;
@@ -186,18 +188,24 @@ static void adjust_frame_size(AC3EncodeContext *s)
s->frame_size = s->frame_size_min +
2 * (s->bits_written * s->sample_rate < s->samples_written * s->bit_rate);
s->bits_written += s->frame_size * 8;
- s->samples_written += AC3_FRAME_SIZE;
+ s->samples_written += AC3_BLOCK_SIZE * s->num_blocks;
}
-static void compute_coupling_strategy(AC3EncodeContext *s)
+/**
+ * Set the initial coupling strategy parameters prior to coupling analysis.
+ *
+ * @param s AC-3 encoder private context
+ */
+void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s)
{
int blk, ch;
int got_cpl_snr;
+ int num_cpl_blocks;
/* set coupling use flags for each block/channel */
/* TODO: turn coupling on/off and adjust start band based on bit usage */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
for (ch = 1; ch <= s->fbw_channels; ch++)
block->channel_in_cpl[ch] = s->cpl_on;
@@ -206,12 +214,14 @@ static void compute_coupling_strategy(AC3EncodeContext *s)
/* enable coupling for each block if at least 2 channels have coupling
enabled for that block */
got_cpl_snr = 0;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ num_cpl_blocks = 0;
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
block->num_cpl_channels = 0;
for (ch = 1; ch <= s->fbw_channels; ch++)
block->num_cpl_channels += block->channel_in_cpl[ch];
block->cpl_in_use = block->num_cpl_channels > 1;
+ num_cpl_blocks += block->cpl_in_use;
if (!block->cpl_in_use) {
block->num_cpl_channels = 0;
for (ch = 1; ch <= s->fbw_channels; ch++)
@@ -237,9 +247,11 @@ static void compute_coupling_strategy(AC3EncodeContext *s)
block->new_snr_offsets = 0;
}
}
+ if (!num_cpl_blocks)
+ s->cpl_on = 0;
/* set bandwidth for each channel */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch])
@@ -253,8 +265,10 @@ static void compute_coupling_strategy(AC3EncodeContext *s)
/**
* Apply stereo rematrixing to coefficients based on rematrixing flags.
+ *
+ * @param s AC-3 encoder private context
*/
-static void apply_rematrixing(AC3EncodeContext *s)
+void ff_ac3_apply_rematrixing(AC3EncodeContext *s)
{
int nb_coefs;
int blk, bnd, i;
@@ -264,7 +278,7 @@ static void apply_rematrixing(AC3EncodeContext *s)
if (!s->rematrixing_enabled)
return;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
if (block->new_rematrixing_strategy)
flags = block->rematrixing_flags;
@@ -285,7 +299,7 @@ static void apply_rematrixing(AC3EncodeContext *s)
}
-/**
+/*
* Initialize exponent tables.
*/
static av_cold void exponent_init(AC3EncodeContext *s)
@@ -301,18 +315,19 @@ static av_cold void exponent_init(AC3EncodeContext *s)
}
/* LFE */
exponent_group_tab[0][0][7] = 2;
+
+ if (CONFIG_EAC3_ENCODER && s->eac3)
+ ff_eac3_exponent_init();
}
-/**
+/*
* Extract exponents from the MDCT coefficients.
- * This takes into account the normalization that was done to the input samples
- * by adjusting the exponents by the exponent shift values.
*/
static void extract_exponents(AC3EncodeContext *s)
{
int ch = !s->cpl_on;
- int chan_size = AC3_MAX_COEFS * AC3_MAX_BLOCKS * (s->channels - ch + 1);
+ int chan_size = AC3_MAX_COEFS * s->num_blocks * (s->channels - ch + 1);
AC3Block *block = &s->blocks[0];
s->ac3dsp.extract_exponents(block->exp[ch], block->fixed_coef[ch], chan_size);
@@ -325,8 +340,17 @@ static void extract_exponents(AC3EncodeContext *s)
*/
#define EXP_DIFF_THRESHOLD 500
-
/**
+ * Table used to select exponent strategy based on exponent reuse block interval.
+ */
+static const uint8_t exp_strategy_reuse_tab[4][6] = {
+ { EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15 },
+ { EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15 },
+ { EXP_D25, EXP_D25, EXP_D15, EXP_D15, EXP_D15, EXP_D15 },
+ { EXP_D45, EXP_D25, EXP_D25, EXP_D15, EXP_D15, EXP_D15 }
+};
+
+/*
* Calculate exponent strategies for all channels.
* Array arrangement is reversed to simplify the per-channel calculation.
*/
@@ -343,9 +367,16 @@ static void compute_exp_strategy(AC3EncodeContext *s)
reused in the next frame */
exp_strategy[0] = EXP_NEW;
exp += AC3_MAX_COEFS;
- for (blk = 1; blk < AC3_MAX_BLOCKS; blk++, exp += AC3_MAX_COEFS) {
- if ((ch == CPL_CH && (!s->blocks[blk].cpl_in_use || !s->blocks[blk-1].cpl_in_use)) ||
- (ch > CPL_CH && (s->blocks[blk].channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]))) {
+ for (blk = 1; blk < s->num_blocks; blk++, exp += AC3_MAX_COEFS) {
+ if (ch == CPL_CH) {
+ if (!s->blocks[blk-1].cpl_in_use) {
+ exp_strategy[blk] = EXP_NEW;
+ continue;
+ } else if (!s->blocks[blk].cpl_in_use) {
+ exp_strategy[blk] = EXP_REUSE;
+ continue;
+ }
+ } else if (s->blocks[blk].channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]) {
exp_strategy[blk] = EXP_NEW;
continue;
}
@@ -360,30 +391,34 @@ static void compute_exp_strategy(AC3EncodeContext *s)
/* now select the encoding strategy type : if exponents are often
recoded, we use a coarse encoding */
blk = 0;
- while (blk < AC3_MAX_BLOCKS) {
+ while (blk < s->num_blocks) {
blk1 = blk + 1;
- while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE)
+ while (blk1 < s->num_blocks && exp_strategy[blk1] == EXP_REUSE)
blk1++;
- switch (blk1 - blk) {
- case 1: exp_strategy[blk] = EXP_D45; break;
- case 2:
- case 3: exp_strategy[blk] = EXP_D25; break;
- default: exp_strategy[blk] = EXP_D15; break;
- }
+ exp_strategy[blk] = exp_strategy_reuse_tab[s->num_blks_code][blk1-blk-1];
blk = blk1;
}
}
if (s->lfe_on) {
ch = s->lfe_channel;
s->exp_strategy[ch][0] = EXP_D15;
- for (blk = 1; blk < AC3_MAX_BLOCKS; blk++)
+ for (blk = 1; blk < s->num_blocks; blk++)
s->exp_strategy[ch][blk] = EXP_REUSE;
}
+
+ /* for E-AC-3, determine frame exponent strategy */
+ if (CONFIG_EAC3_ENCODER && s->eac3)
+ ff_eac3_get_frame_exp_strategy(s);
}
/**
* Update the exponents so that they are the ones the decoder will decode.
+ *
+ * @param[in,out] exp array of exponents for 1 block in 1 channel
+ * @param nb_exps number of exponents in active bandwidth
+ * @param exp_strategy exponent strategy for the block
+ * @param cpl indicates if the block is in the coupling channel
*/
static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy,
int cpl)
@@ -452,7 +487,7 @@ static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy,
}
-/**
+/*
* Encode exponents from original extracted form to what the decoder will see.
* This copies and groups exponents based on exponent strategy and reduces
* deltas between adjacent exponent groups so that they can be differentially
@@ -470,7 +505,7 @@ static void encode_exponents(AC3EncodeContext *s)
cpl = (ch == CPL_CH);
blk = 0;
- while (blk < AC3_MAX_BLOCKS) {
+ while (blk < s->num_blocks) {
AC3Block *block = &s->blocks[blk];
if (cpl && !block->cpl_in_use) {
exp += AC3_MAX_COEFS;
@@ -483,7 +518,7 @@ static void encode_exponents(AC3EncodeContext *s)
/* count the number of EXP_REUSE blocks after the current block
and set exponent reference block numbers */
s->exp_ref_block[ch][blk] = blk;
- while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE) {
+ while (blk1 < s->num_blocks && exp_strategy[blk1] == EXP_REUSE) {
s->exp_ref_block[ch][blk1] = blk;
blk1++;
}
@@ -505,21 +540,50 @@ static void encode_exponents(AC3EncodeContext *s)
}
+/*
+ * Count exponent bits based on bandwidth, coupling, and exponent strategies.
+ */
+static int count_exponent_bits(AC3EncodeContext *s)
+{
+ int blk, ch;
+ int nb_groups, bit_count;
+
+ bit_count = 0;
+ for (blk = 0; blk < s->num_blocks; blk++) {
+ AC3Block *block = &s->blocks[blk];
+ for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
+ int exp_strategy = s->exp_strategy[ch][blk];
+ int cpl = (ch == CPL_CH);
+ int nb_coefs = block->end_freq[ch] - s->start_freq[ch];
+
+ if (exp_strategy == EXP_REUSE)
+ continue;
+
+ nb_groups = exponent_group_tab[cpl][exp_strategy-1][nb_coefs];
+ bit_count += 4 + (nb_groups * 7);
+ }
+ }
+
+ return bit_count;
+}
+
+
/**
* Group exponents.
* 3 delta-encoded exponents are in each 7-bit group. The number of groups
* varies depending on exponent strategy and bandwidth.
+ *
+ * @param s AC-3 encoder private context
*/
-static void group_exponents(AC3EncodeContext *s)
+void ff_ac3_group_exponents(AC3EncodeContext *s)
{
int blk, ch, i, cpl;
- int group_size, nb_groups, bit_count;
+ int group_size, nb_groups;
uint8_t *p;
int delta0, delta1, delta2;
int exp0, exp1;
- bit_count = 0;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
int exp_strategy = s->exp_strategy[ch][blk];
@@ -528,7 +592,6 @@ static void group_exponents(AC3EncodeContext *s)
cpl = (ch == CPL_CH);
group_size = exp_strategy + (exp_strategy == EXP_D45);
nb_groups = exponent_group_tab[cpl][exp_strategy-1][block->end_freq[ch]-s->start_freq[ch]];
- bit_count += 4 + (nb_groups * 7);
p = block->exp[ch] + s->start_freq[ch] - cpl;
/* DC exponent */
@@ -560,8 +623,6 @@ static void group_exponents(AC3EncodeContext *s)
}
}
}
-
- s->exponent_bits = bit_count;
}
@@ -569,8 +630,10 @@ static void group_exponents(AC3EncodeContext *s)
* Calculate final exponents from the supplied MDCT coefficients and exponent shift.
* Extract exponents from MDCT coefficients, calculate exponent strategies,
* and encode final exponents.
+ *
+ * @param s AC-3 encoder private context
*/
-static void process_exponents(AC3EncodeContext *s)
+void ff_ac3_process_exponents(AC3EncodeContext *s)
{
extract_exponents(s);
@@ -578,13 +641,11 @@ static void process_exponents(AC3EncodeContext *s)
encode_exponents(s);
- group_exponents(s);
-
emms_c();
}
-/**
+/*
* Count frame bits that are based solely on fixed parameters.
* This only has to be run once when the encoder is initialized.
*/
@@ -608,26 +669,38 @@ static void count_frame_bits_fixed(AC3EncodeContext *s)
if (s->eac3) {
/* bitstream info header */
frame_bits += 35;
- frame_bits += 1 + 1 + 1;
+ frame_bits += 1 + 1;
+ if (s->num_blocks != 0x6)
+ frame_bits++;
+ frame_bits++;
/* audio frame header */
- frame_bits += 2;
+ if (s->num_blocks == 6)
+ frame_bits += 2;
frame_bits += 10;
/* exponent strategy */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
- frame_bits += 2 * s->fbw_channels + s->lfe_on;
+ if (s->use_frame_exp_strategy)
+ frame_bits += 5 * s->fbw_channels;
+ else
+ frame_bits += s->num_blocks * 2 * s->fbw_channels;
+ if (s->lfe_on)
+ frame_bits += s->num_blocks;
/* converter exponent strategy */
- frame_bits += s->fbw_channels * 5;
+ if (s->num_blks_code != 0x3)
+ frame_bits++;
+ else
+ frame_bits += s->fbw_channels * 5;
/* snr offsets */
frame_bits += 10;
/* block start info */
- frame_bits++;
+ if (s->num_blocks != 1)
+ frame_bits++;
} else {
frame_bits += 49;
frame_bits += frame_bits_inc[s->channel_mode];
}
/* audio blocks */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
if (!s->eac3) {
/* block switch flags */
frame_bits += s->fbw_channels;
@@ -678,7 +751,7 @@ static void count_frame_bits_fixed(AC3EncodeContext *s)
}
-/**
+/*
* Initialize bit allocation.
* Set default parameter codes and calculate parameter values.
*/
@@ -713,7 +786,7 @@ static void bit_alloc_init(AC3EncodeContext *s)
}
-/**
+/*
* Count the bits used to encode the frame, minus exponents and mantissas.
* Bits based on fixed parameters have already been counted, so now we just
* have to add the bits based on parameters that change during encoding.
@@ -726,10 +799,34 @@ static void count_frame_bits(AC3EncodeContext *s)
/* header */
if (s->eac3) {
+ if (opt->eac3_mixing_metadata) {
+ if (s->channel_mode > AC3_CHMODE_STEREO)
+ frame_bits += 2;
+ if (s->has_center)
+ frame_bits += 6;
+ if (s->has_surround)
+ frame_bits += 6;
+ frame_bits += s->lfe_on;
+ frame_bits += 1 + 1 + 2;
+ if (s->channel_mode < AC3_CHMODE_STEREO)
+ frame_bits++;
+ frame_bits++;
+ }
+ if (opt->eac3_info_metadata) {
+ frame_bits += 3 + 1 + 1;
+ if (s->channel_mode == AC3_CHMODE_STEREO)
+ frame_bits += 2 + 2;
+ if (s->channel_mode >= AC3_CHMODE_2F2R)
+ frame_bits += 2;
+ frame_bits++;
+ if (opt->audio_production_info)
+ frame_bits += 5 + 2 + 1;
+ frame_bits++;
+ }
/* coupling */
if (s->channel_mode > AC3_CHMODE_MONO) {
frame_bits++;
- for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 1; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
frame_bits++;
if (block->new_cpl_strategy)
@@ -737,8 +834,14 @@ static void count_frame_bits(AC3EncodeContext *s)
}
}
/* coupling exponent strategy */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
- frame_bits += 2 * s->blocks[blk].cpl_in_use;
+ if (s->cpl_on) {
+ if (s->use_frame_exp_strategy) {
+ frame_bits += 5 * s->cpl_on;
+ } else {
+ for (blk = 0; blk < s->num_blocks; blk++)
+ frame_bits += 2 * s->blocks[blk].cpl_in_use;
+ }
+ }
} else {
if (opt->audio_production_info)
frame_bits += 7;
@@ -751,7 +854,7 @@ static void count_frame_bits(AC3EncodeContext *s)
}
/* audio blocks */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
/* coupling strategy */
@@ -779,9 +882,9 @@ static void count_frame_bits(AC3EncodeContext *s)
if (block->cpl_in_use) {
for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch]) {
- if (!s->eac3 || block->new_cpl_coords != 2)
+ if (!s->eac3 || block->new_cpl_coords[ch] != 2)
frame_bits++;
- if (block->new_cpl_coords) {
+ if (block->new_cpl_coords[ch]) {
frame_bits += 2;
frame_bits += (4 + 4) * s->num_cpl_bands;
}
@@ -830,7 +933,7 @@ static void count_frame_bits(AC3EncodeContext *s)
}
-/**
+/*
* Calculate masking curve based on the final exponents.
* Also calculate the power spectral densities to use in future calculations.
*/
@@ -838,7 +941,7 @@ static void bit_alloc_masking(AC3EncodeContext *s)
{
int blk, ch;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
/* We only need psd and mask for calculating bap.
@@ -860,7 +963,7 @@ static void bit_alloc_masking(AC3EncodeContext *s)
}
-/**
+/*
* Ensure that bap for each block and channel point to the current bap_buffer.
* They may have been switched during the bit allocation search.
*/
@@ -874,9 +977,9 @@ static void reset_block_bap(AC3EncodeContext *s)
ref_bap = s->bap_buffer;
for (ch = 0; ch <= s->channels; ch++) {
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
+ for (blk = 0; blk < s->num_blocks; blk++)
s->ref_bap[ch][blk] = ref_bap + AC3_MAX_COEFS * s->exp_ref_block[ch][blk];
- ref_bap += AC3_MAX_COEFS * AC3_MAX_BLOCKS;
+ ref_bap += AC3_MAX_COEFS * s->num_blocks;
}
s->ref_bap_set = 1;
}
@@ -886,6 +989,8 @@ static void reset_block_bap(AC3EncodeContext *s)
* Initialize mantissa counts.
* These are set so that they are padded to the next whole group size when bits
* are counted in compute_mantissa_size.
+ *
+ * @param[in,out] mant_cnt running counts for each bap value for each block
*/
static void count_mantissa_bits_init(uint16_t mant_cnt[AC3_MAX_BLOCKS][16])
{
@@ -902,6 +1007,12 @@ static void count_mantissa_bits_init(uint16_t mant_cnt[AC3_MAX_BLOCKS][16])
/**
* Update mantissa bit counts for all blocks in 1 channel in a given bandwidth
* range.
+ *
+ * @param s AC-3 encoder private context
+ * @param ch channel index
+ * @param[in,out] mant_cnt running counts for each bap value for each block
+ * @param start starting coefficient bin
+ * @param end ending coefficient bin
*/
static void count_mantissa_bits_update_ch(AC3EncodeContext *s, int ch,
uint16_t mant_cnt[AC3_MAX_BLOCKS][16],
@@ -909,7 +1020,7 @@ static void count_mantissa_bits_update_ch(AC3EncodeContext *s, int ch,
{
int blk;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
if (ch == CPL_CH && !block->cpl_in_use)
continue;
@@ -920,7 +1031,7 @@ static void count_mantissa_bits_update_ch(AC3EncodeContext *s, int ch,
}
-/**
+/*
* Count the number of mantissa bits in the frame based on the bap values.
*/
static int count_mantissa_bits(AC3EncodeContext *s)
@@ -943,6 +1054,9 @@ static int count_mantissa_bits(AC3EncodeContext *s)
* Run the bit allocation with a given SNR offset.
* This calculates the bit allocation pointers that will be used to determine
* the quantization of each mantissa.
+ *
+ * @param s AC-3 encoder private context
+ * @param snr_offset SNR offset, 0 to 1023
* @return the number of bits needed for mantissas if the given SNR offset is
* is used.
*/
@@ -953,7 +1067,7 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset)
snr_offset = (snr_offset - 240) << 2;
reset_block_bap(s);
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
@@ -973,7 +1087,7 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset)
}
-/**
+/*
* Constant bitrate bit allocation search.
* Find the largest SNR offset that will allow data to fit in the frame.
*/
@@ -1022,93 +1136,31 @@ static int cbr_bit_allocation(AC3EncodeContext *s)
}
-/**
- * Downgrade exponent strategies to reduce the bits used by the exponents.
- * This is a fallback for when bit allocation fails with the normal exponent
- * strategies. Each time this function is run it only downgrades the
- * strategy in 1 channel of 1 block.
- * @return non-zero if downgrade was unsuccessful
- */
-static int downgrade_exponents(AC3EncodeContext *s)
-{
- int ch, blk;
-
- for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) {
- for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) {
- if (s->exp_strategy[ch][blk] == EXP_D15) {
- s->exp_strategy[ch][blk] = EXP_D25;
- return 0;
- }
- }
- }
- for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) {
- for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) {
- if (s->exp_strategy[ch][blk] == EXP_D25) {
- s->exp_strategy[ch][blk] = EXP_D45;
- return 0;
- }
- }
- }
- /* block 0 cannot reuse exponents, so only downgrade D45 to REUSE if
- the block number > 0 */
- for (blk = AC3_MAX_BLOCKS-1; blk > 0; blk--) {
- for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) {
- if (s->exp_strategy[ch][blk] > EXP_REUSE) {
- s->exp_strategy[ch][blk] = EXP_REUSE;
- return 0;
- }
- }
- }
- return -1;
-}
-
-
-/**
+/*
* Perform bit allocation search.
* Finds the SNR offset value that maximizes quality and fits in the specified
* frame size. Output is the SNR offset and a set of bit allocation pointers
* used to quantize the mantissas.
*/
-static int compute_bit_allocation(AC3EncodeContext *s)
+int ff_ac3_compute_bit_allocation(AC3EncodeContext *s)
{
- int ret;
-
count_frame_bits(s);
- bit_alloc_masking(s);
+ s->exponent_bits = count_exponent_bits(s);
- ret = cbr_bit_allocation(s);
- while (ret) {
- /* fallback 1: disable channel coupling */
- if (s->cpl_on) {
- s->cpl_on = 0;
- compute_coupling_strategy(s);
- s->compute_rematrixing_strategy(s);
- apply_rematrixing(s);
- process_exponents(s);
- ret = compute_bit_allocation(s);
- continue;
- }
-
- /* fallback 2: downgrade exponents */
- if (!downgrade_exponents(s)) {
- extract_exponents(s);
- encode_exponents(s);
- group_exponents(s);
- ret = compute_bit_allocation(s);
- continue;
- }
-
- /* fallbacks were not enough... */
- break;
- }
+ bit_alloc_masking(s);
- return ret;
+ return cbr_bit_allocation(s);
}
/**
* Symmetric quantization on 'levels' levels.
+ *
+ * @param c unquantized coefficient
+ * @param e exponent
+ * @param levels number of quantization levels
+ * @return quantized coefficient
*/
static inline int sym_quant(int c, int e, int levels)
{
@@ -1120,32 +1172,39 @@ static inline int sym_quant(int c, int e, int levels)
/**
* Asymmetric quantization on 2^qbits levels.
+ *
+ * @param c unquantized coefficient
+ * @param e exponent
+ * @param qbits number of quantization bits
+ * @return quantized coefficient
*/
static inline int asym_quant(int c, int e, int qbits)
{
- int lshift, m, v;
+ int m;
- lshift = e + qbits - 24;
- if (lshift >= 0)
- v = c << lshift;
- else
- v = c >> (-lshift);
- /* rounding */
- v = (v + 1) >> 1;
+ c = (((c << e) >> (24 - qbits)) + 1) >> 1;
m = (1 << (qbits-1));
- if (v >= m)
- v = m - 1;
- av_assert2(v >= -m);
- return v & ((1 << qbits)-1);
+ if (c >= m)
+ c = m - 1;
+ av_assert2(c >= -m);
+ return c;
}
/**
* Quantize a set of mantissas for a single channel in a single block.
+ *
+ * @param s Mantissa count context
+ * @param fixed_coef unquantized fixed-point coefficients
+ * @param exp exponents
+ * @param bap bit allocation pointer indices
+ * @param[out] qmant quantized coefficients
+ * @param start_freq starting coefficient bin
+ * @param end_freq ending coefficient bin
*/
static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef,
uint8_t *exp, uint8_t *bap,
- uint16_t *qmant, int start_freq,
+ int16_t *qmant, int start_freq,
int end_freq)
{
int i;
@@ -1237,12 +1296,14 @@ static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef,
/**
* Quantize mantissas using coefficients, exponents, and bit allocation pointers.
+ *
+ * @param s AC-3 encoder private context
*/
-static void quantize_mantissas(AC3EncodeContext *s)
+void ff_ac3_quantize_mantissas(AC3EncodeContext *s)
{
int blk, ch, ch0=0, got_cpl;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
AC3Mant m = { 0 };
@@ -1264,7 +1325,7 @@ static void quantize_mantissas(AC3EncodeContext *s)
}
-/**
+/*
* Write the AC-3 frame header to the output bitstream.
*/
static void ac3_output_frame_header(AC3EncodeContext *s)
@@ -1320,7 +1381,7 @@ static void ac3_output_frame_header(AC3EncodeContext *s)
}
-/**
+/*
* Write one audio block to the output bitstream.
*/
static void output_audio_block(AC3EncodeContext *s, int blk)
@@ -1382,9 +1443,9 @@ static void output_audio_block(AC3EncodeContext *s, int blk)
if (block->cpl_in_use) {
for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch]) {
- if (!s->eac3 || block->new_cpl_coords != 2)
- put_bits(&s->pb, 1, block->new_cpl_coords);
- if (block->new_cpl_coords) {
+ if (!s->eac3 || block->new_cpl_coords[ch] != 2)
+ put_bits(&s->pb, 1, block->new_cpl_coords[ch]);
+ if (block->new_cpl_coords[ch]) {
put_bits(&s->pb, 2, block->cpl_master_exp[ch]);
for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]);
@@ -1497,14 +1558,14 @@ static void output_audio_block(AC3EncodeContext *s, int blk)
q = block->qmant[ch][i];
b = s->ref_bap[ch][blk][i];
switch (b) {
- case 0: break;
- case 1: if (q != 128) put_bits(&s->pb, 5, q); break;
- case 2: if (q != 128) put_bits(&s->pb, 7, q); break;
- case 3: put_bits(&s->pb, 3, q); break;
- case 4: if (q != 128) put_bits(&s->pb, 7, q); break;
- case 14: put_bits(&s->pb, 14, q); break;
- case 15: put_bits(&s->pb, 16, q); break;
- default: put_bits(&s->pb, b-1, q); break;
+ case 0: break;
+ case 1: if (q != 128) put_bits (&s->pb, 5, q); break;
+ case 2: if (q != 128) put_bits (&s->pb, 7, q); break;
+ case 3: put_sbits(&s->pb, 3, q); break;
+ case 4: if (q != 128) put_bits (&s->pb, 7, q); break;
+ case 14: put_sbits(&s->pb, 14, q); break;
+ case 15: put_sbits(&s->pb, 16, q); break;
+ default: put_sbits(&s->pb, b-1, q); break;
}
}
if (ch == CPL_CH)
@@ -1548,7 +1609,7 @@ static unsigned int pow_poly(unsigned int a, unsigned int n, unsigned int poly)
}
-/**
+/*
* Fill the end of the frame with 0's and compute the two CRCs.
*/
static void output_frame_end(AC3EncodeContext *s)
@@ -1596,8 +1657,11 @@ static void output_frame_end(AC3EncodeContext *s)
/**
* Write the frame to the output bitstream.
+ *
+ * @param s AC-3 encoder private context
+ * @param frame output data buffer
*/
-static void output_frame(AC3EncodeContext *s, unsigned char *frame)
+void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame)
{
int blk;
@@ -1605,17 +1669,17 @@ static void output_frame(AC3EncodeContext *s, unsigned char *frame)
s->output_frame_header(s);
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
+ for (blk = 0; blk < s->num_blocks; blk++)
output_audio_block(s, blk);
output_frame_end(s);
}
-static void dprint_options(AVCodecContext *avctx)
+static void dprint_options(AC3EncodeContext *s)
{
#ifdef DEBUG
- AC3EncodeContext *s = avctx->priv_data;
+ AVCodecContext *avctx = s->avctx;
AC3EncOptions *opt = &s->options;
char strbuf[32];
@@ -1633,6 +1697,7 @@ static void dprint_options(AVCodecContext *avctx)
av_dlog(avctx, "channel_layout: %s\n", strbuf);
av_dlog(avctx, "sample_rate: %d\n", s->sample_rate);
av_dlog(avctx, "bit_rate: %d\n", s->bit_rate);
+ av_dlog(avctx, "blocks/frame: %d (code=%d)\n", s->num_blocks, s->num_blks_code);
if (s->cutoff)
av_dlog(avctx, "cutoff: %d\n", s->cutoff);
@@ -1651,9 +1716,9 @@ static void dprint_options(AVCodecContext *avctx)
if (opt->audio_production_info) {
av_dlog(avctx, "mixing_level: %ddB\n", opt->mixing_level);
switch (opt->room_type) {
- case 0: av_strlcpy(strbuf, "notindicated", 32); break;
- case 1: av_strlcpy(strbuf, "large", 32); break;
- case 2: av_strlcpy(strbuf, "small", 32); break;
+ case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break;
+ case AC3ENC_OPT_LARGE_ROOM: av_strlcpy(strbuf, "large", 32); break;
+ case AC3ENC_OPT_SMALL_ROOM: av_strlcpy(strbuf, "small", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->room_type);
}
av_dlog(avctx, "room_type: %s\n", strbuf);
@@ -1665,9 +1730,9 @@ static void dprint_options(AVCodecContext *avctx)
av_dlog(avctx, "dialnorm: %ddB\n", opt->dialogue_level);
if (s->channel_mode == AC3_CHMODE_STEREO) {
switch (opt->dolby_surround_mode) {
- case 0: av_strlcpy(strbuf, "notindicated", 32); break;
- case 1: av_strlcpy(strbuf, "on", 32); break;
- case 2: av_strlcpy(strbuf, "off", 32); break;
+ case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break;
+ case AC3ENC_OPT_MODE_ON: av_strlcpy(strbuf, "on", 32); break;
+ case AC3ENC_OPT_MODE_OFF: av_strlcpy(strbuf, "off", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->dolby_surround_mode);
}
av_dlog(avctx, "dsur_mode: %s\n", strbuf);
@@ -1679,9 +1744,9 @@ static void dprint_options(AVCodecContext *avctx)
if (s->bitstream_id == 6) {
if (opt->extended_bsi_1) {
switch (opt->preferred_stereo_downmix) {
- case 0: av_strlcpy(strbuf, "notindicated", 32); break;
- case 1: av_strlcpy(strbuf, "ltrt", 32); break;
- case 2: av_strlcpy(strbuf, "loro", 32); break;
+ case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break;
+ case AC3ENC_OPT_DOWNMIX_LTRT: av_strlcpy(strbuf, "ltrt", 32); break;
+ case AC3ENC_OPT_DOWNMIX_LORO: av_strlcpy(strbuf, "loro", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->preferred_stereo_downmix);
}
av_dlog(avctx, "dmix_mode: %s\n", strbuf);
@@ -1698,23 +1763,23 @@ static void dprint_options(AVCodecContext *avctx)
}
if (opt->extended_bsi_2) {
switch (opt->dolby_surround_ex_mode) {
- case 0: av_strlcpy(strbuf, "notindicated", 32); break;
- case 1: av_strlcpy(strbuf, "on", 32); break;
- case 2: av_strlcpy(strbuf, "off", 32); break;
+ case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break;
+ case AC3ENC_OPT_MODE_ON: av_strlcpy(strbuf, "on", 32); break;
+ case AC3ENC_OPT_MODE_OFF: av_strlcpy(strbuf, "off", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->dolby_surround_ex_mode);
}
av_dlog(avctx, "dsurex_mode: %s\n", strbuf);
switch (opt->dolby_headphone_mode) {
- case 0: av_strlcpy(strbuf, "notindicated", 32); break;
- case 1: av_strlcpy(strbuf, "on", 32); break;
- case 2: av_strlcpy(strbuf, "off", 32); break;
+ case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break;
+ case AC3ENC_OPT_MODE_ON: av_strlcpy(strbuf, "on", 32); break;
+ case AC3ENC_OPT_MODE_OFF: av_strlcpy(strbuf, "off", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->dolby_headphone_mode);
}
av_dlog(avctx, "dheadphone_mode: %s\n", strbuf);
switch (opt->ad_converter_type) {
- case 0: av_strlcpy(strbuf, "standard", 32); break;
- case 1: av_strlcpy(strbuf, "hdcd", 32); break;
+ case AC3ENC_OPT_ADCONV_STANDARD: av_strlcpy(strbuf, "standard", 32); break;
+ case AC3ENC_OPT_ADCONV_HDCD: av_strlcpy(strbuf, "hdcd", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->ad_converter_type);
}
av_dlog(avctx, "ad_conv_type: %s\n", strbuf);
@@ -1765,27 +1830,155 @@ static void validate_mix_level(void *log_ctx, const char *opt_name,
/**
* Validate metadata options as set by AVOption system.
* These values can optionally be changed per-frame.
+ *
+ * @param s AC-3 encoder private context
*/
-static int validate_metadata(AVCodecContext *avctx)
+int ff_ac3_validate_metadata(AC3EncodeContext *s)
{
- AC3EncodeContext *s = avctx->priv_data;
+ AVCodecContext *avctx = s->avctx;
AC3EncOptions *opt = &s->options;
- /* validate mixing levels */
- if (s->has_center) {
- validate_mix_level(avctx, "center_mix_level", &opt->center_mix_level,
- cmixlev_options, CMIXLEV_NUM_OPTIONS, 1, 0,
- &s->center_mix_level);
+ opt->audio_production_info = 0;
+ opt->extended_bsi_1 = 0;
+ opt->extended_bsi_2 = 0;
+ opt->eac3_mixing_metadata = 0;
+ opt->eac3_info_metadata = 0;
+
+ /* determine mixing metadata / xbsi1 use */
+ if (s->channel_mode > AC3_CHMODE_STEREO && opt->preferred_stereo_downmix != AC3ENC_OPT_NONE) {
+ opt->extended_bsi_1 = 1;
+ opt->eac3_mixing_metadata = 1;
+ }
+ if (s->has_center &&
+ (opt->ltrt_center_mix_level >= 0 || opt->loro_center_mix_level >= 0)) {
+ opt->extended_bsi_1 = 1;
+ opt->eac3_mixing_metadata = 1;
+ }
+ if (s->has_surround &&
+ (opt->ltrt_surround_mix_level >= 0 || opt->loro_surround_mix_level >= 0)) {
+ opt->extended_bsi_1 = 1;
+ opt->eac3_mixing_metadata = 1;
+ }
+
+ if (s->eac3) {
+ /* determine info metadata use */
+ if (avctx->audio_service_type != AV_AUDIO_SERVICE_TYPE_MAIN)
+ opt->eac3_info_metadata = 1;
+ if (opt->copyright != AC3ENC_OPT_NONE || opt->original != AC3ENC_OPT_NONE)
+ opt->eac3_info_metadata = 1;
+ if (s->channel_mode == AC3_CHMODE_STEREO &&
+ (opt->dolby_headphone_mode != AC3ENC_OPT_NONE || opt->dolby_surround_mode != AC3ENC_OPT_NONE))
+ opt->eac3_info_metadata = 1;
+ if (s->channel_mode >= AC3_CHMODE_2F2R && opt->dolby_surround_ex_mode != AC3ENC_OPT_NONE)
+ opt->eac3_info_metadata = 1;
+ if (opt->mixing_level != AC3ENC_OPT_NONE || opt->room_type != AC3ENC_OPT_NONE ||
+ opt->ad_converter_type != AC3ENC_OPT_NONE) {
+ opt->audio_production_info = 1;
+ opt->eac3_info_metadata = 1;
+ }
+ } else {
+ /* determine audio production info use */
+ if (opt->mixing_level != AC3ENC_OPT_NONE || opt->room_type != AC3ENC_OPT_NONE)
+ opt->audio_production_info = 1;
+
+ /* determine xbsi2 use */
+ if (s->channel_mode >= AC3_CHMODE_2F2R && opt->dolby_surround_ex_mode != AC3ENC_OPT_NONE)
+ opt->extended_bsi_2 = 1;
+ if (s->channel_mode == AC3_CHMODE_STEREO && opt->dolby_headphone_mode != AC3ENC_OPT_NONE)
+ opt->extended_bsi_2 = 1;
+ if (opt->ad_converter_type != AC3ENC_OPT_NONE)
+ opt->extended_bsi_2 = 1;
}
- if (s->has_surround) {
- validate_mix_level(avctx, "surround_mix_level", &opt->surround_mix_level,
- surmixlev_options, SURMIXLEV_NUM_OPTIONS, 1, 0,
- &s->surround_mix_level);
+
+ /* validate AC-3 mixing levels */
+ if (!s->eac3) {
+ if (s->has_center) {
+ validate_mix_level(avctx, "center_mix_level", &opt->center_mix_level,
+ cmixlev_options, CMIXLEV_NUM_OPTIONS, 1, 0,
+ &s->center_mix_level);
+ }
+ if (s->has_surround) {
+ validate_mix_level(avctx, "surround_mix_level", &opt->surround_mix_level,
+ surmixlev_options, SURMIXLEV_NUM_OPTIONS, 1, 0,
+ &s->surround_mix_level);
+ }
}
- /* set audio production info flag */
- if (opt->mixing_level >= 0 || opt->room_type >= 0) {
- if (opt->mixing_level < 0) {
+ /* validate extended bsi 1 / mixing metadata */
+ if (opt->extended_bsi_1 || opt->eac3_mixing_metadata) {
+ /* default preferred stereo downmix */
+ if (opt->preferred_stereo_downmix == AC3ENC_OPT_NONE)
+ opt->preferred_stereo_downmix = AC3ENC_OPT_NOT_INDICATED;
+ if (!s->eac3 || s->has_center) {
+ /* validate Lt/Rt center mix level */
+ validate_mix_level(avctx, "ltrt_center_mix_level",
+ &opt->ltrt_center_mix_level, extmixlev_options,
+ EXTMIXLEV_NUM_OPTIONS, 5, 0,
+ &s->ltrt_center_mix_level);
+ /* validate Lo/Ro center mix level */
+ validate_mix_level(avctx, "loro_center_mix_level",
+ &opt->loro_center_mix_level, extmixlev_options,
+ EXTMIXLEV_NUM_OPTIONS, 5, 0,
+ &s->loro_center_mix_level);
+ }
+ if (!s->eac3 || s->has_surround) {
+ /* validate Lt/Rt surround mix level */
+ validate_mix_level(avctx, "ltrt_surround_mix_level",
+ &opt->ltrt_surround_mix_level, extmixlev_options,
+ EXTMIXLEV_NUM_OPTIONS, 6, 3,
+ &s->ltrt_surround_mix_level);
+ /* validate Lo/Ro surround mix level */
+ validate_mix_level(avctx, "loro_surround_mix_level",
+ &opt->loro_surround_mix_level, extmixlev_options,
+ EXTMIXLEV_NUM_OPTIONS, 6, 3,
+ &s->loro_surround_mix_level);
+ }
+ }
+
+ /* validate audio service type / channels combination */
+ if ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_KARAOKE &&
+ avctx->channels == 1) ||
+ ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_COMMENTARY ||
+ avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_EMERGENCY ||
+ avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_VOICE_OVER)
+ && avctx->channels > 1)) {
+ av_log(avctx, AV_LOG_ERROR, "invalid audio service type for the "
+ "specified number of channels\n");
+ return AVERROR(EINVAL);
+ }
+
+ /* validate extended bsi 2 / info metadata */
+ if (opt->extended_bsi_2 || opt->eac3_info_metadata) {
+ /* default dolby headphone mode */
+ if (opt->dolby_headphone_mode == AC3ENC_OPT_NONE)
+ opt->dolby_headphone_mode = AC3ENC_OPT_NOT_INDICATED;
+ /* default dolby surround ex mode */
+ if (opt->dolby_surround_ex_mode == AC3ENC_OPT_NONE)
+ opt->dolby_surround_ex_mode = AC3ENC_OPT_NOT_INDICATED;
+ /* default A/D converter type */
+ if (opt->ad_converter_type == AC3ENC_OPT_NONE)
+ opt->ad_converter_type = AC3ENC_OPT_ADCONV_STANDARD;
+ }
+
+ /* copyright & original defaults */
+ if (!s->eac3 || opt->eac3_info_metadata) {
+ /* default copyright */
+ if (opt->copyright == AC3ENC_OPT_NONE)
+ opt->copyright = AC3ENC_OPT_OFF;
+ /* default original */
+ if (opt->original == AC3ENC_OPT_NONE)
+ opt->original = AC3ENC_OPT_ON;
+ }
+
+ /* dolby surround mode default */
+ if (!s->eac3 || opt->eac3_info_metadata) {
+ if (opt->dolby_surround_mode == AC3ENC_OPT_NONE)
+ opt->dolby_surround_mode = AC3ENC_OPT_NOT_INDICATED;
+ }
+
+ /* validate audio production info */
+ if (opt->audio_production_info) {
+ if (opt->mixing_level == AC3ENC_OPT_NONE) {
av_log(avctx, AV_LOG_ERROR, "mixing_level must be set if "
"room_type is set\n");
return AVERROR(EINVAL);
@@ -1796,68 +1989,12 @@ static int validate_metadata(AVCodecContext *avctx)
return AVERROR(EINVAL);
}
/* default room type */
- if (opt->room_type < 0)
- opt->room_type = 0;
- opt->audio_production_info = 1;
- } else {
- opt->audio_production_info = 0;
- }
-
- /* set extended bsi 1 flag */
- if ((s->has_center || s->has_surround) &&
- (opt->preferred_stereo_downmix >= 0 ||
- opt->ltrt_center_mix_level >= 0 ||
- opt->ltrt_surround_mix_level >= 0 ||
- opt->loro_center_mix_level >= 0 ||
- opt->loro_surround_mix_level >= 0)) {
- /* default preferred stereo downmix */
- if (opt->preferred_stereo_downmix < 0)
- opt->preferred_stereo_downmix = 0;
- /* validate Lt/Rt center mix level */
- validate_mix_level(avctx, "ltrt_center_mix_level",
- &opt->ltrt_center_mix_level, extmixlev_options,
- EXTMIXLEV_NUM_OPTIONS, 5, 0,
- &s->ltrt_center_mix_level);
- /* validate Lt/Rt surround mix level */
- validate_mix_level(avctx, "ltrt_surround_mix_level",
- &opt->ltrt_surround_mix_level, extmixlev_options,
- EXTMIXLEV_NUM_OPTIONS, 6, 3,
- &s->ltrt_surround_mix_level);
- /* validate Lo/Ro center mix level */
- validate_mix_level(avctx, "loro_center_mix_level",
- &opt->loro_center_mix_level, extmixlev_options,
- EXTMIXLEV_NUM_OPTIONS, 5, 0,
- &s->loro_center_mix_level);
- /* validate Lo/Ro surround mix level */
- validate_mix_level(avctx, "loro_surround_mix_level",
- &opt->loro_surround_mix_level, extmixlev_options,
- EXTMIXLEV_NUM_OPTIONS, 6, 3,
- &s->loro_surround_mix_level);
- opt->extended_bsi_1 = 1;
- } else {
- opt->extended_bsi_1 = 0;
- }
-
- /* set extended bsi 2 flag */
- if (opt->dolby_surround_ex_mode >= 0 ||
- opt->dolby_headphone_mode >= 0 ||
- opt->ad_converter_type >= 0) {
- /* default dolby surround ex mode */
- if (opt->dolby_surround_ex_mode < 0)
- opt->dolby_surround_ex_mode = 0;
- /* default dolby headphone mode */
- if (opt->dolby_headphone_mode < 0)
- opt->dolby_headphone_mode = 0;
- /* default A/D converter type */
- if (opt->ad_converter_type < 0)
- opt->ad_converter_type = 0;
- opt->extended_bsi_2 = 1;
- } else {
- opt->extended_bsi_2 = 0;
+ if (opt->room_type == AC3ENC_OPT_NONE)
+ opt->room_type = AC3ENC_OPT_NOT_INDICATED;
}
/* set bitstream id for alternate bitstream syntax */
- if (opt->extended_bsi_1 || opt->extended_bsi_2) {
+ if (!s->eac3 && (opt->extended_bsi_1 || opt->extended_bsi_2)) {
if (s->bitstream_id > 8 && s->bitstream_id < 11) {
static int warn_once = 1;
if (warn_once) {
@@ -1876,58 +2013,9 @@ static int validate_metadata(AVCodecContext *avctx)
/**
- * Encode a single AC-3 frame.
- */
-int ff_ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame,
- int buf_size, void *data)
-{
- AC3EncodeContext *s = avctx->priv_data;
- const SampleType *samples = data;
- int ret;
-
- if (!s->eac3 && s->options.allow_per_frame_metadata) {
- ret = validate_metadata(avctx);
- if (ret)
- return ret;
- }
-
- if (s->bit_alloc.sr_code == 1 || s->eac3)
- adjust_frame_size(s);
-
- s->deinterleave_input_samples(s, samples);
-
- s->apply_mdct(s);
-
- s->scale_coefficients(s);
-
- s->cpl_on = s->cpl_enabled;
- compute_coupling_strategy(s);
-
- if (s->cpl_on)
- s->apply_channel_coupling(s);
-
- s->compute_rematrixing_strategy(s);
-
- apply_rematrixing(s);
-
- process_exponents(s);
-
- ret = compute_bit_allocation(s);
- if (ret) {
- av_log(avctx, AV_LOG_ERROR, "Bit allocation failed. Try increasing the bitrate.\n");
- return ret;
- }
-
- quantize_mantissas(s);
-
- output_frame(s, frame);
-
- return s->frame_size;
-}
-
-
-/**
* Finalize encoding and free any memory allocated by the encoder.
+ *
+ * @param avctx Codec context
*/
av_cold int ff_ac3_encode_close(AVCodecContext *avctx)
{
@@ -1948,7 +2036,9 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx)
av_freep(&s->band_psd_buffer);
av_freep(&s->mask_buffer);
av_freep(&s->qmant_buffer);
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ av_freep(&s->cpl_coord_exp_buffer);
+ av_freep(&s->cpl_coord_mant_buffer);
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
av_freep(&block->mdct_coef);
av_freep(&block->fixed_coef);
@@ -1958,27 +2048,28 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx)
av_freep(&block->band_psd);
av_freep(&block->mask);
av_freep(&block->qmant);
+ av_freep(&block->cpl_coord_exp);
+ av_freep(&block->cpl_coord_mant);
}
- s->mdct_end(s->mdct);
- av_freep(&s->mdct);
+ s->mdct_end(s);
av_freep(&avctx->coded_frame);
return 0;
}
-/**
+/*
* Set channel information during initialization.
*/
static av_cold int set_channel_info(AC3EncodeContext *s, int channels,
- int64_t *channel_layout)
+ uint64_t *channel_layout)
{
int ch_layout;
if (channels < 1 || channels > AC3_MAX_CHANNELS)
return AVERROR(EINVAL);
- if ((uint64_t)*channel_layout > 0x7FF)
+ if (*channel_layout > 0x7FF)
return AVERROR(EINVAL);
ch_layout = *channel_layout;
if (!ch_layout)
@@ -2016,8 +2107,9 @@ static av_cold int set_channel_info(AC3EncodeContext *s, int channels,
}
-static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s)
+static av_cold int validate_options(AC3EncodeContext *s)
{
+ AVCodecContext *avctx = s->avctx;
int i, ret, max_sr;
/* validate channel layout */
@@ -2053,18 +2145,30 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s)
/* validate bit rate */
if (s->eac3) {
int max_br, min_br, wpf, min_br_dist, min_br_code;
+ int num_blks_code, num_blocks, frame_samples;
/* calculate min/max bitrate */
- max_br = 2048 * s->sample_rate / AC3_FRAME_SIZE * 16;
- min_br = ((s->sample_rate + (AC3_FRAME_SIZE-1)) / AC3_FRAME_SIZE) * 16;
+ /* TODO: More testing with 3 and 2 blocks. All E-AC-3 samples I've
+ found use either 6 blocks or 1 block, even though 2 or 3 blocks
+ would work as far as the bit rate is concerned. */
+ for (num_blks_code = 3; num_blks_code >= 0; num_blks_code--) {
+ num_blocks = ((int[]){ 1, 2, 3, 6 })[num_blks_code];
+ frame_samples = AC3_BLOCK_SIZE * num_blocks;
+ max_br = 2048 * s->sample_rate / frame_samples * 16;
+ min_br = ((s->sample_rate + (frame_samples-1)) / frame_samples) * 16;
+ if (avctx->bit_rate <= max_br)
+ break;
+ }
if (avctx->bit_rate < min_br || avctx->bit_rate > max_br) {
av_log(avctx, AV_LOG_ERROR, "invalid bit rate. must be %d to %d "
"for this sample rate\n", min_br, max_br);
return AVERROR(EINVAL);
}
+ s->num_blks_code = num_blks_code;
+ s->num_blocks = num_blocks;
/* calculate words-per-frame for the selected bitrate */
- wpf = (avctx->bit_rate / 16) * AC3_FRAME_SIZE / s->sample_rate;
+ wpf = (avctx->bit_rate / 16) * frame_samples / s->sample_rate;
av_assert1(wpf > 0 && wpf <= 2048);
/* find the closest AC-3 bitrate code to the selected bitrate.
@@ -2096,6 +2200,8 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s)
}
s->frame_size_code = i << 1;
s->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code];
+ s->num_blks_code = 0x3;
+ s->num_blocks = 6;
}
s->bit_rate = avctx->bit_rate;
s->frame_size = s->frame_size_min;
@@ -2109,35 +2215,21 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s)
if (s->cutoff > (s->sample_rate >> 1))
s->cutoff = s->sample_rate >> 1;
- /* validate audio service type / channels combination */
- if ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_KARAOKE &&
- avctx->channels == 1) ||
- ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_COMMENTARY ||
- avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_EMERGENCY ||
- avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_VOICE_OVER)
- && avctx->channels > 1)) {
- av_log(avctx, AV_LOG_ERROR, "invalid audio service type for the "
- "specified number of channels\n");
- return AVERROR(EINVAL);
- }
-
- if (!s->eac3) {
- ret = validate_metadata(avctx);
- if (ret)
- return ret;
- }
+ ret = ff_ac3_validate_metadata(s);
+ if (ret)
+ return ret;
s->rematrixing_enabled = s->options.stereo_rematrixing &&
(s->channel_mode == AC3_CHMODE_STEREO);
s->cpl_enabled = s->options.channel_coupling &&
- s->channel_mode >= AC3_CHMODE_STEREO && !s->fixed_point;
+ s->channel_mode >= AC3_CHMODE_STEREO;
return 0;
}
-/**
+/*
* Set bandwidth for all channels.
* The user can optionally supply a cutoff frequency. Otherwise an appropriate
* default value will be used.
@@ -2160,24 +2252,28 @@ static av_cold void set_bandwidth(AC3EncodeContext *s)
/* set number of coefficients for each channel */
for (ch = 1; ch <= s->fbw_channels; ch++) {
s->start_freq[ch] = 0;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
+ for (blk = 0; blk < s->num_blocks; blk++)
s->blocks[blk].end_freq[ch] = s->bandwidth_code * 3 + 73;
}
/* LFE channel always has 7 coefs */
if (s->lfe_on) {
s->start_freq[s->lfe_channel] = 0;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
+ for (blk = 0; blk < s->num_blocks; blk++)
s->blocks[blk].end_freq[ch] = 7;
}
/* initialize coupling strategy */
if (s->cpl_enabled) {
- if (s->options.cpl_start >= 0) {
+ if (s->options.cpl_start != AC3ENC_OPT_AUTO) {
cpl_start = s->options.cpl_start;
} else {
cpl_start = ac3_coupling_start_tab[s->channel_mode-2][s->bit_alloc.sr_code][s->frame_size_code/2];
- if (cpl_start < 0)
- s->cpl_enabled = 0;
+ if (cpl_start < 0) {
+ if (s->options.channel_coupling == AC3ENC_OPT_AUTO)
+ s->cpl_enabled = 0;
+ else
+ cpl_start = 15;
+ }
}
}
if (s->cpl_enabled) {
@@ -2203,46 +2299,48 @@ static av_cold void set_bandwidth(AC3EncodeContext *s)
s->start_freq[CPL_CH] = cpl_start_band * 12 + 37;
s->cpl_end_freq = cpl_end_band * 12 + 37;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
+ for (blk = 0; blk < s->num_blocks; blk++)
s->blocks[blk].end_freq[CPL_CH] = s->cpl_end_freq;
}
}
-static av_cold int allocate_buffers(AVCodecContext *avctx)
+static av_cold int allocate_buffers(AC3EncodeContext *s)
{
+ AVCodecContext *avctx = s->avctx;
int blk, ch;
- AC3EncodeContext *s = avctx->priv_data;
int channels = s->channels + 1; /* includes coupling channel */
+ int channel_blocks = channels * s->num_blocks;
+ int total_coefs = AC3_MAX_COEFS * channel_blocks;
if (s->allocate_sample_buffers(s))
goto alloc_fail;
- FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, AC3_MAX_BLOCKS * channels *
- AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail);
- FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * channels *
- AC3_MAX_COEFS * sizeof(*s->bap1_buffer), alloc_fail);
- FF_ALLOCZ_OR_GOTO(avctx, s->mdct_coef_buffer, AC3_MAX_BLOCKS * channels *
- AC3_MAX_COEFS * sizeof(*s->mdct_coef_buffer), alloc_fail);
- FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, AC3_MAX_BLOCKS * channels *
- AC3_MAX_COEFS * sizeof(*s->exp_buffer), alloc_fail);
- FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, AC3_MAX_BLOCKS * channels *
- 128 * sizeof(*s->grouped_exp_buffer), alloc_fail);
- FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, AC3_MAX_BLOCKS * channels *
- AC3_MAX_COEFS * sizeof(*s->psd_buffer), alloc_fail);
- FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, AC3_MAX_BLOCKS * channels *
- 64 * sizeof(*s->band_psd_buffer), alloc_fail);
- FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, AC3_MAX_BLOCKS * channels *
- 64 * sizeof(*s->mask_buffer), alloc_fail);
- FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, AC3_MAX_BLOCKS * channels *
- AC3_MAX_COEFS * sizeof(*s->qmant_buffer), alloc_fail);
+ FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, total_coefs *
+ sizeof(*s->bap_buffer), alloc_fail);
+ FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, total_coefs *
+ sizeof(*s->bap1_buffer), alloc_fail);
+ FF_ALLOCZ_OR_GOTO(avctx, s->mdct_coef_buffer, total_coefs *
+ sizeof(*s->mdct_coef_buffer), alloc_fail);
+ FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, total_coefs *
+ sizeof(*s->exp_buffer), alloc_fail);
+ FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, channel_blocks * 128 *
+ sizeof(*s->grouped_exp_buffer), alloc_fail);
+ FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, total_coefs *
+ sizeof(*s->psd_buffer), alloc_fail);
+ FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, channel_blocks * 64 *
+ sizeof(*s->band_psd_buffer), alloc_fail);
+ FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, channel_blocks * 64 *
+ sizeof(*s->mask_buffer), alloc_fail);
+ FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, total_coefs *
+ sizeof(*s->qmant_buffer), alloc_fail);
if (s->cpl_enabled) {
- FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_exp_buffer, AC3_MAX_BLOCKS * channels *
- 16 * sizeof(*s->cpl_coord_exp_buffer), alloc_fail);
- FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_mant_buffer, AC3_MAX_BLOCKS * channels *
- 16 * sizeof(*s->cpl_coord_mant_buffer), alloc_fail);
+ FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_exp_buffer, channel_blocks * 16 *
+ sizeof(*s->cpl_coord_exp_buffer), alloc_fail);
+ FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_mant_buffer, channel_blocks * 16 *
+ sizeof(*s->cpl_coord_mant_buffer), alloc_fail);
}
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
FF_ALLOCZ_OR_GOTO(avctx, block->mdct_coef, channels * sizeof(*block->mdct_coef),
alloc_fail);
@@ -2278,23 +2376,23 @@ static av_cold int allocate_buffers(AVCodecContext *avctx)
}
/* arrangement: channel, block, coeff */
- block->exp[ch] = &s->exp_buffer [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)];
- block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)];
+ block->exp[ch] = &s->exp_buffer [AC3_MAX_COEFS * (s->num_blocks * ch + blk)];
+ block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (s->num_blocks * ch + blk)];
}
}
if (!s->fixed_point) {
- FF_ALLOCZ_OR_GOTO(avctx, s->fixed_coef_buffer, AC3_MAX_BLOCKS * channels *
- AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail);
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ FF_ALLOCZ_OR_GOTO(avctx, s->fixed_coef_buffer, total_coefs *
+ sizeof(*s->fixed_coef_buffer), alloc_fail);
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels *
sizeof(*block->fixed_coef), alloc_fail);
for (ch = 0; ch < channels; ch++)
- block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)];
+ block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (s->num_blocks * ch + blk)];
}
} else {
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels *
sizeof(*block->fixed_coef), alloc_fail);
@@ -2309,9 +2407,6 @@ alloc_fail:
}
-/**
- * Initialize the encoder.
- */
av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
{
AC3EncodeContext *s = avctx->priv_data;
@@ -2321,14 +2416,14 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
s->eac3 = avctx->codec_id == CODEC_ID_EAC3;
- avctx->frame_size = AC3_FRAME_SIZE;
-
ff_ac3_common_init();
- ret = validate_options(avctx, s);
+ ret = validate_options(s);
if (ret)
return ret;
+ avctx->frame_size = AC3_BLOCK_SIZE * s->num_blocks;
+
s->bitstream_mode = avctx->audio_service_type;
if (s->bitstream_mode == AV_AUDIO_SERVICE_TYPE_KARAOKE)
s->bitstream_mode = 0x7;
@@ -2348,24 +2443,11 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
if (CONFIG_AC3_FIXED_ENCODER && s->fixed_point) {
s->mdct_end = ff_ac3_fixed_mdct_end;
s->mdct_init = ff_ac3_fixed_mdct_init;
- s->apply_window = ff_ac3_fixed_apply_window;
- s->normalize_samples = ff_ac3_fixed_normalize_samples;
- s->scale_coefficients = ff_ac3_fixed_scale_coefficients;
s->allocate_sample_buffers = ff_ac3_fixed_allocate_sample_buffers;
- s->deinterleave_input_samples = ff_ac3_fixed_deinterleave_input_samples;
- s->apply_mdct = ff_ac3_fixed_apply_mdct;
- s->apply_channel_coupling = ff_ac3_fixed_apply_channel_coupling;
- s->compute_rematrixing_strategy = ff_ac3_fixed_compute_rematrixing_strategy;
} else if (CONFIG_AC3_ENCODER || CONFIG_EAC3_ENCODER) {
s->mdct_end = ff_ac3_float_mdct_end;
s->mdct_init = ff_ac3_float_mdct_init;
- s->apply_window = ff_ac3_float_apply_window;
- s->scale_coefficients = ff_ac3_float_scale_coefficients;
s->allocate_sample_buffers = ff_ac3_float_allocate_sample_buffers;
- s->deinterleave_input_samples = ff_ac3_float_deinterleave_input_samples;
- s->apply_mdct = ff_ac3_float_apply_mdct;
- s->apply_channel_coupling = ff_ac3_float_apply_channel_coupling;
- s->compute_rematrixing_strategy = ff_ac3_float_compute_rematrixing_strategy;
}
if (CONFIG_EAC3_ENCODER && s->eac3)
s->output_frame_header = ff_eac3_output_frame_header;
@@ -2378,12 +2460,11 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
bit_alloc_init(s);
- FF_ALLOCZ_OR_GOTO(avctx, s->mdct, sizeof(AC3MDCTContext), init_fail);
- ret = s->mdct_init(avctx, s->mdct, 9);
+ ret = s->mdct_init(s);
if (ret)
goto init_fail;
- ret = allocate_buffers(avctx);
+ ret = allocate_buffers(s);
if (ret)
goto init_fail;
@@ -2392,7 +2473,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
dsputil_init(&s->dsp, avctx);
ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
- dprint_options(avctx);
+ dprint_options(s);
return 0;
init_fail:
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index bf25298..6ef1a53 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -50,22 +50,40 @@
#if CONFIG_AC3ENC_FLOAT
#define AC3_NAME(x) ff_ac3_float_ ## x
#define MAC_COEF(d,a,b) ((d)+=(a)*(b))
+#define COEF_MIN (-16777215.0/16777216.0)
+#define COEF_MAX ( 16777215.0/16777216.0)
+#define NEW_CPL_COORD_THRESHOLD 0.03
typedef float SampleType;
typedef float CoefType;
typedef float CoefSumType;
#else
#define AC3_NAME(x) ff_ac3_fixed_ ## x
#define MAC_COEF(d,a,b) MAC64(d,a,b)
+#define COEF_MIN -16777215
+#define COEF_MAX 16777215
+#define NEW_CPL_COORD_THRESHOLD 503317
typedef int16_t SampleType;
typedef int32_t CoefType;
typedef int64_t CoefSumType;
#endif
+/* common option values */
+#define AC3ENC_OPT_NONE -1
+#define AC3ENC_OPT_AUTO -1
+#define AC3ENC_OPT_OFF 0
+#define AC3ENC_OPT_ON 1
+#define AC3ENC_OPT_NOT_INDICATED 0
+#define AC3ENC_OPT_MODE_ON 2
+#define AC3ENC_OPT_MODE_OFF 1
+
+/* specific option values */
+#define AC3ENC_OPT_LARGE_ROOM 1
+#define AC3ENC_OPT_SMALL_ROOM 2
+#define AC3ENC_OPT_DOWNMIX_LTRT 1
+#define AC3ENC_OPT_DOWNMIX_LORO 2
+#define AC3ENC_OPT_ADCONV_STANDARD 0
+#define AC3ENC_OPT_ADCONV_HDCD 1
-typedef struct AC3MDCTContext {
- const SampleType *window; ///< MDCT window function
- FFTContext fft; ///< FFT context for MDCT calculation
-} AC3MDCTContext;
/**
* Encoding Options used by AVOption.
@@ -92,6 +110,8 @@ typedef struct AC3EncOptions {
int dolby_surround_ex_mode;
int dolby_headphone_mode;
int ad_converter_type;
+ int eac3_mixing_metadata;
+ int eac3_info_metadata;
/* other encoding options */
int allow_per_frame_metadata;
@@ -122,7 +142,7 @@ typedef struct AC3Block {
int cpl_in_use; ///< coupling in use for this block (cplinu)
uint8_t channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl)
int num_cpl_channels; ///< number of channels in coupling
- uint8_t new_cpl_coords; ///< send new coupling coordinates (cplcoe)
+ uint8_t new_cpl_coords[AC3_MAX_CHANNELS]; ///< send new coupling coordinates (cplcoe)
uint8_t cpl_master_exp[AC3_MAX_CHANNELS]; ///< coupling coord master exponents (mstrcplco)
int new_snr_offsets; ///< send new SNR offsets
int new_cpl_leak; ///< send new coupling leak info
@@ -139,7 +159,8 @@ typedef struct AC3EncodeContext {
PutBitContext pb; ///< bitstream writer context
DSPContext dsp;
AC3DSPContext ac3dsp; ///< AC-3 optimized functions
- AC3MDCTContext *mdct; ///< MDCT context
+ FFTContext mdct; ///< FFT context for MDCT calculation
+ const SampleType *mdct_window; ///< MDCT window function array
AC3Block blocks[AC3_MAX_BLOCKS]; ///< per-block info
@@ -151,6 +172,8 @@ typedef struct AC3EncodeContext {
int bit_rate; ///< target bit rate, in bits-per-second
int sample_rate; ///< sampling frequency, in Hz
+ int num_blks_code; ///< number of blocks code (numblkscod)
+ int num_blocks; ///< number of blocks per frame
int frame_size_min; ///< minimum frame size in case rounding is necessary
int frame_size; ///< current frame size in bytes
int frame_size_code; ///< frame size code (frmsizecod)
@@ -212,87 +235,71 @@ typedef struct AC3EncodeContext {
int16_t *psd_buffer;
int16_t *band_psd_buffer;
int16_t *mask_buffer;
- uint16_t *qmant_buffer;
+ int16_t *qmant_buffer;
uint8_t *cpl_coord_exp_buffer;
uint8_t *cpl_coord_mant_buffer;
uint8_t exp_strategy[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< exponent strategies
+ uint8_t frame_exp_strategy[AC3_MAX_CHANNELS]; ///< frame exp strategy index
+ int use_frame_exp_strategy; ///< indicates use of frame exp strategy
uint8_t exp_ref_block[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< reference blocks for EXP_REUSE
uint8_t *ref_bap [AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< bit allocation pointers (bap)
int ref_bap_set; ///< indicates if ref_bap pointers have been set
/* fixed vs. float function pointers */
- void (*mdct_end)(AC3MDCTContext *mdct);
- int (*mdct_init)(AVCodecContext *avctx, AC3MDCTContext *mdct, int nbits);
- void (*apply_window)(DSPContext *dsp, SampleType *output,
- const SampleType *input, const SampleType *window,
- unsigned int len);
- int (*normalize_samples)(struct AC3EncodeContext *s);
- void (*scale_coefficients)(struct AC3EncodeContext *s);
+ void (*mdct_end)(struct AC3EncodeContext *s);
+ int (*mdct_init)(struct AC3EncodeContext *s);
/* fixed vs. float templated function pointers */
int (*allocate_sample_buffers)(struct AC3EncodeContext *s);
- void (*deinterleave_input_samples)(struct AC3EncodeContext *s,
- const SampleType *samples);
- void (*apply_mdct)(struct AC3EncodeContext *s);
- void (*apply_channel_coupling)(struct AC3EncodeContext *s);
- void (*compute_rematrixing_strategy)(struct AC3EncodeContext *s);
/* AC-3 vs. E-AC-3 function pointers */
void (*output_frame_header)(struct AC3EncodeContext *s);
} AC3EncodeContext;
-extern const int64_t ff_ac3_channel_layouts[19];
+extern const uint64_t ff_ac3_channel_layouts[19];
int ff_ac3_encode_init(AVCodecContext *avctx);
-int ff_ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame,
- int buf_size, void *data);
-
int ff_ac3_encode_close(AVCodecContext *avctx);
+int ff_ac3_validate_metadata(AC3EncodeContext *s);
-/* prototypes for functions in ac3enc_fixed.c and ac3enc_float.c */
+void ff_ac3_adjust_frame_size(AC3EncodeContext *s);
-void ff_ac3_fixed_mdct_end(AC3MDCTContext *mdct);
-void ff_ac3_float_mdct_end(AC3MDCTContext *mdct);
+void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s);
-int ff_ac3_fixed_mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct,
- int nbits);
-int ff_ac3_float_mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct,
- int nbits);
+void ff_ac3_apply_rematrixing(AC3EncodeContext *s);
-void ff_ac3_fixed_apply_window(DSPContext *dsp, SampleType *output,
- const SampleType *input,
- const SampleType *window, unsigned int len);
-void ff_ac3_float_apply_window(DSPContext *dsp, SampleType *output,
- const SampleType *input,
- const SampleType *window, unsigned int len);
+void ff_ac3_process_exponents(AC3EncodeContext *s);
-int ff_ac3_fixed_normalize_samples(AC3EncodeContext *s);
+int ff_ac3_compute_bit_allocation(AC3EncodeContext *s);
-void ff_ac3_fixed_scale_coefficients(AC3EncodeContext *s);
-void ff_ac3_float_scale_coefficients(AC3EncodeContext *s);
+void ff_ac3_group_exponents(AC3EncodeContext *s);
+void ff_ac3_quantize_mantissas(AC3EncodeContext *s);
-/* prototypes for functions in ac3enc_template.c */
+void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame);
-int ff_ac3_fixed_allocate_sample_buffers(AC3EncodeContext *s);
-int ff_ac3_float_allocate_sample_buffers(AC3EncodeContext *s);
-void ff_ac3_fixed_deinterleave_input_samples(AC3EncodeContext *s,
- const SampleType *samples);
-void ff_ac3_float_deinterleave_input_samples(AC3EncodeContext *s,
- const SampleType *samples);
+/* prototypes for functions in ac3enc_fixed.c and ac3enc_float.c */
-void ff_ac3_fixed_apply_mdct(AC3EncodeContext *s);
-void ff_ac3_float_apply_mdct(AC3EncodeContext *s);
+void ff_ac3_fixed_mdct_end(AC3EncodeContext *s);
+void ff_ac3_float_mdct_end(AC3EncodeContext *s);
-void ff_ac3_fixed_apply_channel_coupling(AC3EncodeContext *s);
-void ff_ac3_float_apply_channel_coupling(AC3EncodeContext *s);
+int ff_ac3_fixed_mdct_init(AC3EncodeContext *s);
+int ff_ac3_float_mdct_init(AC3EncodeContext *s);
+
+
+/* prototypes for functions in ac3enc_template.c */
+
+int ff_ac3_fixed_allocate_sample_buffers(AC3EncodeContext *s);
+int ff_ac3_float_allocate_sample_buffers(AC3EncodeContext *s);
-void ff_ac3_fixed_compute_rematrixing_strategy(AC3EncodeContext *s);
-void ff_ac3_float_compute_rematrixing_strategy(AC3EncodeContext *s);
+int ff_ac3_fixed_encode_frame(AVCodecContext *avctx, unsigned char *frame,
+ int buf_size, void *data);
+int ff_ac3_float_encode_frame(AVCodecContext *avctx, unsigned char *frame,
+ int buf_size, void *data);
#endif /* AVCODEC_AC3ENC_H */
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index 0620a6a..202dfb8 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -29,70 +29,59 @@
#define CONFIG_FFT_FLOAT 0
#undef CONFIG_AC3ENC_FLOAT
#include "ac3enc.h"
+#include "eac3enc.h"
#define AC3ENC_TYPE AC3ENC_TYPE_AC3_FIXED
#include "ac3enc_opts_template.c"
-static AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name,
- ac3fixed_options, LIBAVUTIL_VERSION_INT };
+static const AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name,
+ ac3fixed_options, LIBAVUTIL_VERSION_INT };
#include "ac3enc_template.c"
/**
* Finalize MDCT and free allocated memory.
+ *
+ * @param s AC-3 encoder private context
*/
-av_cold void AC3_NAME(mdct_end)(AC3MDCTContext *mdct)
+av_cold void AC3_NAME(mdct_end)(AC3EncodeContext *s)
{
- ff_mdct_end(&mdct->fft);
+ ff_mdct_end(&s->mdct);
}
/**
* Initialize MDCT tables.
- * @param nbits log2(MDCT size)
+ *
+ * @param s AC-3 encoder private context
+ * @return 0 on success, negative error code on failure
*/
-av_cold int AC3_NAME(mdct_init)(AVCodecContext *avctx, AC3MDCTContext *mdct,
- int nbits)
+av_cold int AC3_NAME(mdct_init)(AC3EncodeContext *s)
{
- int ret = ff_mdct_init(&mdct->fft, nbits, 0, -1.0);
- mdct->window = ff_ac3_window;
+ int ret = ff_mdct_init(&s->mdct, 9, 0, -1.0);
+ s->mdct_window = ff_ac3_window;
return ret;
}
-/**
+/*
* Apply KBD window to input samples prior to MDCT.
*/
-void AC3_NAME(apply_window)(DSPContext *dsp, int16_t *output,
- const int16_t *input, const int16_t *window,
- unsigned int len)
+static void apply_window(DSPContext *dsp, int16_t *output, const int16_t *input,
+ const int16_t *window, unsigned int len)
{
dsp->apply_window_int16(output, input, window, len);
}
-/**
- * Calculate the log2() of the maximum absolute value in an array.
- * @param tab input array
- * @param n number of values in the array
- * @return log2(max(abs(tab[])))
- */
-static int log2_tab(AC3EncodeContext *s, int16_t *src, int len)
-{
- int v = s->ac3dsp.ac3_max_msb_abs_int16(src, len);
- return av_log2(v);
-}
-
-
-/**
+/*
* Normalize the input samples to use the maximum available precision.
* This assumes signed 16-bit input samples.
- *
- * @return exponent shift
*/
-int AC3_NAME(normalize_samples)(AC3EncodeContext *s)
+static int normalize_samples(AC3EncodeContext *s)
{
- int v = 14 - log2_tab(s, s->windowed_samples, AC3_WINDOW_SIZE);
+ int v = s->ac3dsp.ac3_max_msb_abs_int16(s->windowed_samples, AC3_WINDOW_SIZE);
+ v = 14 - av_log2(v);
if (v > 0)
s->ac3dsp.ac3_lshift_int16(s->windowed_samples, AC3_WINDOW_SIZE, v);
/* +6 to right-shift from 31-bit to 25-bit */
@@ -100,14 +89,14 @@ int AC3_NAME(normalize_samples)(AC3EncodeContext *s)
}
-/**
+/*
* Scale MDCT coefficients to 25-bit signed fixed-point.
*/
-void AC3_NAME(scale_coefficients)(AC3EncodeContext *s)
+static void scale_coefficients(AC3EncodeContext *s)
{
int blk, ch;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
for (ch = 1; ch <= s->channels; ch++) {
s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS,
@@ -117,6 +106,31 @@ void AC3_NAME(scale_coefficients)(AC3EncodeContext *s)
}
+/*
+ * Clip MDCT coefficients to allowable range.
+ */
+static void clip_coefficients(DSPContext *dsp, int32_t *coef, unsigned int len)
+{
+ dsp->vector_clip_int32(coef, coef, COEF_MIN, COEF_MAX, len);
+}
+
+
+/*
+ * Calculate a single coupling coordinate.
+ */
+static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl)
+{
+ if (energy_cpl <= COEF_MAX) {
+ return 1048576;
+ } else {
+ uint64_t coord = energy_ch / (energy_cpl >> 24);
+ uint32_t coord32 = FFMIN(coord, 1073741824);
+ coord32 = ff_sqrt(coord32) << 9;
+ return FFMIN(coord32, COEF_MAX);
+ }
+}
+
+
static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx)
{
AC3EncodeContext *s = avctx->priv_data;
@@ -126,14 +140,13 @@ static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx)
AVCodec ff_ac3_fixed_encoder = {
- "ac3_fixed",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_AC3,
- sizeof(AC3EncodeContext),
- ac3_fixed_encode_init,
- ff_ac3_encode_frame,
- ff_ac3_encode_close,
- NULL,
+ .name = "ac3_fixed",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AC3,
+ .priv_data_size = sizeof(AC3EncodeContext),
+ .init = ac3_fixed_encode_init,
+ .encode = ff_ac3_fixed_encode_frame,
+ .close = ff_ac3_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
.priv_class = &ac3enc_class,
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index 43fbb95..a4abd89 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -35,8 +35,8 @@
#if CONFIG_AC3_ENCODER
#define AC3ENC_TYPE AC3ENC_TYPE_AC3
#include "ac3enc_opts_template.c"
-static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
- ac3_options, LIBAVUTIL_VERSION_INT };
+static const AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
+ ac3_options, LIBAVUTIL_VERSION_INT };
#endif
#include "ac3enc_template.c"
@@ -44,74 +44,107 @@ static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
/**
* Finalize MDCT and free allocated memory.
+ *
+ * @param s AC-3 encoder private context
*/
-av_cold void ff_ac3_float_mdct_end(AC3MDCTContext *mdct)
+av_cold void ff_ac3_float_mdct_end(AC3EncodeContext *s)
{
- ff_mdct_end(&mdct->fft);
- av_freep(&mdct->window);
+ ff_mdct_end(&s->mdct);
+ av_freep(&s->mdct_window);
}
/**
* Initialize MDCT tables.
- * @param nbits log2(MDCT size)
+ *
+ * @param s AC-3 encoder private context
+ * @return 0 on success, negative error code on failure
*/
-av_cold int ff_ac3_float_mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct,
- int nbits)
+av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s)
{
float *window;
int i, n, n2;
- n = 1 << nbits;
+ n = 1 << 9;
n2 = n >> 1;
window = av_malloc(n * sizeof(*window));
if (!window) {
- av_log(avctx, AV_LOG_ERROR, "Cannot allocate memory.\n");
+ av_log(s->avctx, AV_LOG_ERROR, "Cannot allocate memory.\n");
return AVERROR(ENOMEM);
}
ff_kbd_window_init(window, 5.0, n2);
for (i = 0; i < n2; i++)
window[n-1-i] = window[i];
- mdct->window = window;
+ s->mdct_window = window;
- return ff_mdct_init(&mdct->fft, nbits, 0, -2.0 / n);
+ return ff_mdct_init(&s->mdct, 9, 0, -2.0 / n);
}
-/**
+/*
* Apply KBD window to input samples prior to MDCT.
*/
-void ff_ac3_float_apply_window(DSPContext *dsp, float *output,
- const float *input, const float *window,
- unsigned int len)
+static void apply_window(DSPContext *dsp, float *output, const float *input,
+ const float *window, unsigned int len)
{
dsp->vector_fmul(output, input, window, len);
}
-/**
+/*
+ * Normalize the input samples.
+ * Not needed for the floating-point encoder.
+ */
+static int normalize_samples(AC3EncodeContext *s)
+{
+ return 0;
+}
+
+
+/*
* Scale MDCT coefficients from float to 24-bit fixed-point.
*/
-void ff_ac3_float_scale_coefficients(AC3EncodeContext *s)
+static void scale_coefficients(AC3EncodeContext *s)
+{
+ int chan_size = AC3_MAX_COEFS * s->num_blocks;
+ int cpl = s->cpl_on;
+ s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + (chan_size * !cpl),
+ s->mdct_coef_buffer + (chan_size * !cpl),
+ chan_size * (s->channels + cpl));
+}
+
+
+/*
+ * Clip MDCT coefficients to allowable range.
+ */
+static void clip_coefficients(DSPContext *dsp, float *coef, unsigned int len)
+{
+ dsp->vector_clipf(coef, coef, COEF_MIN, COEF_MAX, len);
+}
+
+
+/*
+ * Calculate a single coupling coordinate.
+ */
+static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl)
{
- int chan_size = AC3_MAX_COEFS * AC3_MAX_BLOCKS;
- s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + chan_size,
- s->mdct_coef_buffer + chan_size,
- chan_size * s->channels);
+ float coord = 0.125;
+ if (energy_cpl > 0)
+ coord *= sqrtf(energy_ch / energy_cpl);
+ return FFMIN(coord, COEF_MAX);
}
#if CONFIG_AC3_ENCODER
AVCodec ff_ac3_encoder = {
- "ac3",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_AC3,
- sizeof(AC3EncodeContext),
- ff_ac3_encode_init,
- ff_ac3_encode_frame,
- ff_ac3_encode_close,
- NULL,
+ .name = "ac3",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AC3,
+ .priv_data_size = sizeof(AC3EncodeContext),
+ .init = ff_ac3_encode_init,
+ .encode = ff_ac3_float_encode_frame,
+ .close = ff_ac3_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
.priv_class = &ac3enc_class,
diff --git a/libavcodec/ac3enc_opts_template.c b/libavcodec/ac3enc_opts_template.c
index 39138a1..a5f848e 100644
--- a/libavcodec/ac3enc_opts_template.c
+++ b/libavcodec/ac3enc_opts_template.c
@@ -29,56 +29,52 @@ static const AVOption ac3_options[] = {
#else /* AC3ENC_TYPE_EAC3 */
static const AVOption eac3_options[] = {
#endif
-#if AC3ENC_TYPE != AC3ENC_TYPE_EAC3
/* Metadata Options */
-{"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, 1, AC3ENC_PARAM},
-/* downmix levels */
-{"center_mixlev", "Center Mix Level", OFFSET(center_mix_level), FF_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_4POINT5DB }, 0.0, 1.0, AC3ENC_PARAM},
-{"surround_mixlev", "Surround Mix Level", OFFSET(surround_mix_level), FF_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_6DB }, 0.0, 1.0, AC3ENC_PARAM},
+{"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, 1, AC3ENC_PARAM},
+#if AC3ENC_TYPE != AC3ENC_TYPE_EAC3
+/* AC-3 downmix levels */
+{"center_mixlev", "Center Mix Level", OFFSET(center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_4POINT5DB }, 0.0, 1.0, AC3ENC_PARAM},
+{"surround_mixlev", "Surround Mix Level", OFFSET(surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_6DB }, 0.0, 1.0, AC3ENC_PARAM},
+#endif
/* audio production information */
-{"mixing_level", "Mixing Level", OFFSET(mixing_level), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 111, AC3ENC_PARAM},
-{"room_type", "Room Type", OFFSET(room_type), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 2, AC3ENC_PARAM, "room_type"},
- {"notindicated", "Not Indicated (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
- {"large", "Large Room", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
- {"small", "Small Room", 0, FF_OPT_TYPE_CONST, {.dbl = 2 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
+{"mixing_level", "Mixing Level", OFFSET(mixing_level), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 111, AC3ENC_PARAM},
+{"room_type", "Room Type", OFFSET(room_type), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_SMALL_ROOM, AC3ENC_PARAM, "room_type"},
+ {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
+ {"large", "Large Room", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_LARGE_ROOM }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
+ {"small", "Small Room", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_SMALL_ROOM }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
/* other metadata options */
-{"copyright", "Copyright Bit", OFFSET(copyright), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, 1, AC3ENC_PARAM},
-#endif
-{"dialnorm", "Dialogue Level (dB)", OFFSET(dialogue_level), FF_OPT_TYPE_INT, {.dbl = -31 }, -31, -1, AC3ENC_PARAM},
-#if AC3ENC_TYPE != AC3ENC_TYPE_EAC3
-{"dsur_mode", "Dolby Surround Mode", OFFSET(dolby_surround_mode), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, 2, AC3ENC_PARAM, "dsur_mode"},
- {"notindicated", "Not Indicated (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
- {"on", "Dolby Surround Encoded", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
- {"off", "Not Dolby Surround Encoded", 0, FF_OPT_TYPE_CONST, {.dbl = 2 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
-{"original", "Original Bit Stream", OFFSET(original), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 1, AC3ENC_PARAM},
+{"copyright", "Copyright Bit", OFFSET(copyright), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM},
+{"dialnorm", "Dialogue Level (dB)", OFFSET(dialogue_level), AV_OPT_TYPE_INT, {.dbl = -31 }, -31, -1, AC3ENC_PARAM},
+{"dsur_mode", "Dolby Surround Mode", OFFSET(dolby_surround_mode), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dsur_mode"},
+ {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
+ {"on", "Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
+ {"off", "Not Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
+{"original", "Original Bit Stream", OFFSET(original), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM},
/* extended bitstream information */
-{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 2, AC3ENC_PARAM, "dmix_mode"},
- {"notindicated", "Not Indicated (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
- {"ltrt", "Lt/Rt Downmix Preferred", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
- {"loro", "Lo/Ro Downmix Preferred", 0, FF_OPT_TYPE_CONST, {.dbl = 2 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
-{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), FF_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
-{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), FF_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
-{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), FF_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
-{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), FF_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
-{"dsurex_mode", "Dolby Surround EX Mode", OFFSET(dolby_surround_ex_mode), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 2, AC3ENC_PARAM, "dsurex_mode"},
- {"notindicated", "Not Indicated (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
- {"on", "Dolby Surround EX Encoded", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
- {"off", "Not Dolby Surround EX Encoded", 0, FF_OPT_TYPE_CONST, {.dbl = 2 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
-{"dheadphone_mode", "Dolby Headphone Mode", OFFSET(dolby_headphone_mode), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 2, AC3ENC_PARAM, "dheadphone_mode"},
- {"notindicated", "Not Indicated (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
- {"on", "Dolby Headphone Encoded", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
- {"off", "Not Dolby Headphone Encoded", 0, FF_OPT_TYPE_CONST, {.dbl = 2 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
-{"ad_conv_type", "A/D Converter Type", OFFSET(ad_converter_type), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 1, AC3ENC_PARAM, "ad_conv_type"},
- {"standard", "Standard (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
- {"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
-#endif
+{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DOWNMIX_LORO, AC3ENC_PARAM, "dmix_mode"},
+ {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
+ {"ltrt", "Lt/Rt Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_DOWNMIX_LTRT }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
+ {"loro", "Lo/Ro Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_DOWNMIX_LORO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
+{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
+{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
+{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
+{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
+{"dsurex_mode", "Dolby Surround EX Mode", OFFSET(dolby_surround_ex_mode), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dsurex_mode"},
+ {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
+ {"on", "Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
+ {"off", "Not Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
+{"dheadphone_mode", "Dolby Headphone Mode", OFFSET(dolby_headphone_mode), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dheadphone_mode"},
+ {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
+ {"on", "Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
+ {"off", "Not Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
+{"ad_conv_type", "A/D Converter Type", OFFSET(ad_converter_type), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_ADCONV_HDCD, AC3ENC_PARAM, "ad_conv_type"},
+ {"standard", "Standard (default)", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_ADCONV_STANDARD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
+ {"hdcd", "HDCD", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_ADCONV_HDCD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
/* Other Encoding Options */
-{"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 1, AC3ENC_PARAM},
-#if AC3ENC_TYPE != AC3ENC_TYPE_AC3_FIXED
-{"channel_coupling", "Channel Coupling", OFFSET(channel_coupling), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 1, AC3ENC_PARAM, "channel_coupling"},
- {"auto", "Selected by the Encoder", 0, FF_OPT_TYPE_CONST, {.dbl = -1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "channel_coupling"},
-{"cpl_start_band", "Coupling Start Band", OFFSET(cpl_start), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 15, AC3ENC_PARAM, "cpl_start_band"},
- {"auto", "Selected by the Encoder", 0, FF_OPT_TYPE_CONST, {.dbl = -1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "cpl_start_band"},
-#endif
+{"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_ON }, AC3ENC_OPT_OFF, AC3ENC_OPT_ON, AC3ENC_PARAM},
+{"channel_coupling", "Channel Coupling", OFFSET(channel_coupling), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, AC3ENC_OPT_ON, AC3ENC_PARAM, "channel_coupling"},
+ {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "channel_coupling"},
+{"cpl_start_band", "Coupling Start Band", OFFSET(cpl_start), AV_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, 15, AC3ENC_PARAM, "cpl_start_band"},
+ {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "cpl_start_band"},
{NULL}
};
diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c
index f6248a8..3396ed1 100644
--- a/libavcodec/ac3enc_template.c
+++ b/libavcodec/ac3enc_template.c
@@ -28,7 +28,20 @@
#include <stdint.h>
-#include "ac3enc.h"
+
+/* prototypes for static functions in ac3enc_fixed.c and ac3enc_float.c */
+
+static void scale_coefficients(AC3EncodeContext *s);
+
+static void apply_window(DSPContext *dsp, SampleType *output,
+ const SampleType *input, const SampleType *window,
+ unsigned int len);
+
+static int normalize_samples(AC3EncodeContext *s);
+
+static void clip_coefficients(DSPContext *dsp, CoefType *coef, unsigned int len);
+
+static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl);
int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s)
@@ -51,12 +64,12 @@ alloc_fail:
}
-/**
+/*
* Deinterleave input samples.
* Channels are reordered from Libav's default order to AC-3 order.
*/
-void AC3_NAME(deinterleave_input_samples)(AC3EncodeContext *s,
- const SampleType *samples)
+static void deinterleave_input_samples(AC3EncodeContext *s,
+ const SampleType *samples)
{
int ch, i;
@@ -66,13 +79,13 @@ void AC3_NAME(deinterleave_input_samples)(AC3EncodeContext *s,
int sinc;
/* copy last 256 samples of previous frame to the start of the current frame */
- memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_FRAME_SIZE],
+ memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_BLOCK_SIZE * s->num_blocks],
AC3_BLOCK_SIZE * sizeof(s->planar_samples[0][0]));
/* deinterleave */
sinc = s->channels;
sptr = samples + s->channel_map[ch];
- for (i = AC3_BLOCK_SIZE; i < AC3_FRAME_SIZE+AC3_BLOCK_SIZE; i++) {
+ for (i = AC3_BLOCK_SIZE; i < AC3_BLOCK_SIZE * (s->num_blocks + 1); i++) {
s->planar_samples[ch][i] = *sptr;
sptr += sinc;
}
@@ -80,64 +93,52 @@ void AC3_NAME(deinterleave_input_samples)(AC3EncodeContext *s,
}
-/**
+/*
* Apply the MDCT to input samples to generate frequency coefficients.
* This applies the KBD window and normalizes the input to reduce precision
* loss due to fixed-point calculations.
*/
-void AC3_NAME(apply_mdct)(AC3EncodeContext *s)
+static void apply_mdct(AC3EncodeContext *s)
{
int blk, ch;
for (ch = 0; ch < s->channels; ch++) {
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
- s->apply_window(&s->dsp, s->windowed_samples, input_samples,
- s->mdct->window, AC3_WINDOW_SIZE);
+ apply_window(&s->dsp, s->windowed_samples, input_samples,
+ s->mdct_window, AC3_WINDOW_SIZE);
if (s->fixed_point)
- block->coeff_shift[ch+1] = s->normalize_samples(s);
+ block->coeff_shift[ch+1] = normalize_samples(s);
- s->mdct->fft.mdct_calcw(&s->mdct->fft, block->mdct_coef[ch+1],
- s->windowed_samples);
+ s->mdct.mdct_calcw(&s->mdct, block->mdct_coef[ch+1],
+ s->windowed_samples);
}
}
}
-/**
- * Calculate a single coupling coordinate.
- */
-static inline float calc_cpl_coord(float energy_ch, float energy_cpl)
-{
- float coord = 0.125;
- if (energy_cpl > 0)
- coord *= sqrtf(energy_ch / energy_cpl);
- return coord;
-}
-
-
-/**
+/*
* Calculate coupling channel and coupling coordinates.
- * TODO: Currently this is only used for the floating-point encoder. I was
- * able to make it work for the fixed-point encoder, but quality was
- * generally lower in most cases than not using coupling. If a more
- * adaptive coupling strategy were to be implemented it might be useful
- * at that time to use coupling for the fixed-point encoder as well.
*/
-void AC3_NAME(apply_channel_coupling)(AC3EncodeContext *s)
+static void apply_channel_coupling(AC3EncodeContext *s)
{
+ LOCAL_ALIGNED_16(CoefType, cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]);
#if CONFIG_AC3ENC_FLOAT
- LOCAL_ALIGNED_16(float, cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]);
LOCAL_ALIGNED_16(int32_t, fixed_cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]);
+#else
+ int32_t (*fixed_cpl_coords)[AC3_MAX_CHANNELS][16] = cpl_coords;
+#endif
int blk, ch, bnd, i, j;
CoefSumType energy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16] = {{{0}}};
int cpl_start, num_cpl_coefs;
memset(cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords));
- memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*fixed_cpl_coords));
+#if CONFIG_AC3ENC_FLOAT
+ memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords));
+#endif
/* align start to 16-byte boundary. align length to multiple of 32.
note: coupling start bin % 4 will always be 1 */
@@ -146,7 +147,7 @@ void AC3_NAME(apply_channel_coupling)(AC3EncodeContext *s)
cpl_start = FFMIN(256, cpl_start + num_cpl_coefs) - num_cpl_coefs;
/* calculate coupling channel from fbw channels */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
CoefType *cpl_coef = &block->mdct_coef[CPL_CH][cpl_start];
if (!block->cpl_in_use)
@@ -160,12 +161,8 @@ void AC3_NAME(apply_channel_coupling)(AC3EncodeContext *s)
cpl_coef[i] += ch_coef[i];
}
- /* coefficients must be clipped to +/- 1.0 in order to be encoded */
- s->dsp.vector_clipf(cpl_coef, cpl_coef, -1.0f, 1.0f, num_cpl_coefs);
-
- /* scale coupling coefficients from float to 24-bit fixed-point */
- s->ac3dsp.float_to_fixed24(&block->fixed_coef[CPL_CH][cpl_start],
- cpl_coef, num_cpl_coefs);
+ /* coefficients must be clipped in order to be encoded */
+ clip_coefficients(&s->dsp, cpl_coef, num_cpl_coefs);
}
/* calculate energy in each band in coupling channel and each fbw channel */
@@ -175,7 +172,7 @@ void AC3_NAME(apply_channel_coupling)(AC3EncodeContext *s)
while (i < s->cpl_end_freq) {
int band_size = s->cpl_band_sizes[bnd];
for (ch = CPL_CH; ch <= s->fbw_channels; ch++) {
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch]))
continue;
@@ -189,68 +186,64 @@ void AC3_NAME(apply_channel_coupling)(AC3EncodeContext *s)
bnd++;
}
+ /* calculate coupling coordinates for all blocks for all channels */
+ for (blk = 0; blk < s->num_blocks; blk++) {
+ AC3Block *block = &s->blocks[blk];
+ if (!block->cpl_in_use)
+ continue;
+ for (ch = 1; ch <= s->fbw_channels; ch++) {
+ if (!block->channel_in_cpl[ch])
+ continue;
+ for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
+ cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy[blk][ch][bnd],
+ energy[blk][CPL_CH][bnd]);
+ }
+ }
+ }
+
/* determine which blocks to send new coupling coordinates for */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL;
- int new_coords = 0;
- CoefSumType coord_diff[AC3_MAX_CHANNELS] = {0,};
- if (block->cpl_in_use) {
- /* calculate coupling coordinates for all blocks and calculate the
- average difference between coordinates in successive blocks */
- for (ch = 1; ch <= s->fbw_channels; ch++) {
- if (!block->channel_in_cpl[ch])
- continue;
-
- for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
- cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy[blk][ch][bnd],
- energy[blk][CPL_CH][bnd]);
- if (blk > 0 && block0->cpl_in_use &&
- block0->channel_in_cpl[ch]) {
- coord_diff[ch] += fabs(cpl_coords[blk-1][ch][bnd] -
- cpl_coords[blk ][ch][bnd]);
- }
- }
- coord_diff[ch] /= s->num_cpl_bands;
- }
+ memset(block->new_cpl_coords, 0, sizeof(block->new_cpl_coords));
+ if (block->cpl_in_use) {
/* send new coordinates if this is the first block, if previous
* block did not use coupling but this block does, the channels
* using coupling has changed from the previous block, or the
* coordinate difference from the last block for any channel is
* greater than a threshold value. */
- if (blk == 0) {
- new_coords = 1;
- } else if (!block0->cpl_in_use) {
- new_coords = 1;
+ if (blk == 0 || !block0->cpl_in_use) {
+ for (ch = 1; ch <= s->fbw_channels; ch++)
+ block->new_cpl_coords[ch] = 1;
} else {
for (ch = 1; ch <= s->fbw_channels; ch++) {
- if (block->channel_in_cpl[ch] && !block0->channel_in_cpl[ch]) {
- new_coords = 1;
- break;
- }
- }
- if (!new_coords) {
- for (ch = 1; ch <= s->fbw_channels; ch++) {
- if (block->channel_in_cpl[ch] && coord_diff[ch] > 0.04) {
- new_coords = 1;
- break;
+ if (!block->channel_in_cpl[ch])
+ continue;
+ if (!block0->channel_in_cpl[ch]) {
+ block->new_cpl_coords[ch] = 1;
+ } else {
+ CoefSumType coord_diff = 0;
+ for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
+ coord_diff += FFABS(cpl_coords[blk-1][ch][bnd] -
+ cpl_coords[blk ][ch][bnd]);
}
+ coord_diff /= s->num_cpl_bands;
+ if (coord_diff > NEW_CPL_COORD_THRESHOLD)
+ block->new_cpl_coords[ch] = 1;
}
}
}
}
- block->new_cpl_coords = new_coords;
}
/* calculate final coupling coordinates, taking into account reusing of
coordinates in successive blocks */
for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
blk = 0;
- while (blk < AC3_MAX_BLOCKS) {
- int blk1;
- CoefSumType energy_cpl;
+ while (blk < s->num_blocks) {
+ int av_uninit(blk1);
AC3Block *block = &s->blocks[blk];
if (!block->cpl_in_use) {
@@ -258,23 +251,18 @@ void AC3_NAME(apply_channel_coupling)(AC3EncodeContext *s)
continue;
}
- energy_cpl = energy[blk][CPL_CH][bnd];
- blk1 = blk+1;
- while (!s->blocks[blk1].new_cpl_coords && blk1 < AC3_MAX_BLOCKS) {
- if (s->blocks[blk1].cpl_in_use)
- energy_cpl += energy[blk1][CPL_CH][bnd];
- blk1++;
- }
-
for (ch = 1; ch <= s->fbw_channels; ch++) {
- CoefType energy_ch;
+ CoefSumType energy_ch, energy_cpl;
if (!block->channel_in_cpl[ch])
continue;
+ energy_cpl = energy[blk][CPL_CH][bnd];
energy_ch = energy[blk][ch][bnd];
blk1 = blk+1;
- while (!s->blocks[blk1].new_cpl_coords && blk1 < AC3_MAX_BLOCKS) {
- if (s->blocks[blk1].cpl_in_use)
+ while (!s->blocks[blk1].new_cpl_coords[ch] && blk1 < s->num_blocks) {
+ if (s->blocks[blk1].cpl_in_use) {
+ energy_cpl += energy[blk1][CPL_CH][bnd];
energy_ch += energy[blk1][ch][bnd];
+ }
blk1++;
}
cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl);
@@ -284,14 +272,16 @@ void AC3_NAME(apply_channel_coupling)(AC3EncodeContext *s)
}
/* calculate exponents/mantissas for coupling coordinates */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
- if (!block->cpl_in_use || !block->new_cpl_coords)
+ if (!block->cpl_in_use)
continue;
+#if CONFIG_AC3ENC_FLOAT
s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1],
cpl_coords[blk][1],
s->fbw_channels * 16);
+#endif
s->ac3dsp.extract_exponents(block->cpl_coord_exp[1],
fixed_cpl_coords[blk][1],
s->fbw_channels * 16);
@@ -299,6 +289,9 @@ void AC3_NAME(apply_channel_coupling)(AC3EncodeContext *s)
for (ch = 1; ch <= s->fbw_channels; ch++) {
int bnd, min_exp, max_exp, master_exp;
+ if (!block->new_cpl_coords[ch])
+ continue;
+
/* determine master exponent */
min_exp = max_exp = block->cpl_coord_exp[ch][0];
for (bnd = 1; bnd < s->num_cpl_bands; bnd++) {
@@ -332,14 +325,13 @@ void AC3_NAME(apply_channel_coupling)(AC3EncodeContext *s)
if (CONFIG_EAC3_ENCODER && s->eac3)
ff_eac3_set_cpl_states(s);
-#endif /* CONFIG_AC3ENC_FLOAT */
}
-/**
+/*
* Determine rematrixing flags for each block and band.
*/
-void AC3_NAME(compute_rematrixing_strategy)(AC3EncodeContext *s)
+static void compute_rematrixing_strategy(AC3EncodeContext *s)
{
int nb_coefs;
int blk, bnd, i;
@@ -348,15 +340,10 @@ void AC3_NAME(compute_rematrixing_strategy)(AC3EncodeContext *s)
if (s->channel_mode != AC3_CHMODE_STEREO)
return;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
block = &s->blocks[blk];
block->new_rematrixing_strategy = !blk;
- if (!s->rematrixing_enabled) {
- block0 = block;
- continue;
- }
-
block->num_rematrixing_bands = 4;
if (block->cpl_in_use) {
block->num_rematrixing_bands -= (s->start_freq[CPL_CH] <= 61);
@@ -366,6 +353,11 @@ void AC3_NAME(compute_rematrixing_strategy)(AC3EncodeContext *s)
}
nb_coefs = FFMIN(block->end_freq[1], block->end_freq[2]);
+ if (!s->rematrixing_enabled) {
+ block0 = block;
+ continue;
+ }
+
for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) {
/* calculate calculate sum of squared coeffs for one band in one block */
int start = ff_ac3_rematrix_band_tab[bnd];
@@ -397,3 +389,60 @@ void AC3_NAME(compute_rematrixing_strategy)(AC3EncodeContext *s)
block0 = block;
}
}
+
+
+int AC3_NAME(encode_frame)(AVCodecContext *avctx, unsigned char *frame,
+ int buf_size, void *data)
+{
+ AC3EncodeContext *s = avctx->priv_data;
+ const SampleType *samples = data;
+ int ret;
+
+ if (s->options.allow_per_frame_metadata) {
+ ret = ff_ac3_validate_metadata(s);
+ if (ret)
+ return ret;
+ }
+
+ if (s->bit_alloc.sr_code == 1 || s->eac3)
+ ff_ac3_adjust_frame_size(s);
+
+ deinterleave_input_samples(s, samples);
+
+ apply_mdct(s);
+
+ if (s->fixed_point)
+ scale_coefficients(s);
+
+ clip_coefficients(&s->dsp, s->blocks[0].mdct_coef[1],
+ AC3_MAX_COEFS * s->num_blocks * s->channels);
+
+ s->cpl_on = s->cpl_enabled;
+ ff_ac3_compute_coupling_strategy(s);
+
+ if (s->cpl_on)
+ apply_channel_coupling(s);
+
+ compute_rematrixing_strategy(s);
+
+ if (!s->fixed_point)
+ scale_coefficients(s);
+
+ ff_ac3_apply_rematrixing(s);
+
+ ff_ac3_process_exponents(s);
+
+ ret = ff_ac3_compute_bit_allocation(s);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR, "Bit allocation failed. Try increasing the bitrate.\n");
+ return ret;
+ }
+
+ ff_ac3_group_exponents(s);
+
+ ff_ac3_quantize_mantissas(s);
+
+ ff_ac3_output_frame(s, frame);
+
+ return s->frame_size;
+}
diff --git a/libavcodec/acelp_pitch_delay.c b/libavcodec/acelp_pitch_delay.c
index 4e44bc9..395247d 100644
--- a/libavcodec/acelp_pitch_delay.c
+++ b/libavcodec/acelp_pitch_delay.c
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/mathematics.h"
#include "avcodec.h"
#include "dsputil.h"
#include "acelp_pitch_delay.h"
@@ -104,20 +105,9 @@ int16_t ff_acelp_decode_gain_code(
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(dsp->scalarproduct_int16(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(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size, 0));
return mr_energy >> 12;
-#endif
}
float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy,
diff --git a/libavcodec/acelp_pitch_delay.h b/libavcodec/acelp_pitch_delay.h
index 6d182bb..e5410bb 100644
--- a/libavcodec/acelp_pitch_delay.h
+++ b/libavcodec/acelp_pitch_delay.h
@@ -30,11 +30,11 @@
#define PITCH_DELAY_MAX 143
/**
- * \brief Decode pitch delay of the first subframe encoded by 8 bits with 1/3
+ * @brief Decode pitch delay of the first subframe encoded by 8 bits with 1/3
* resolution.
- * \param ac_index adaptive codebook index (8 bits)
+ * @param ac_index adaptive codebook index (8 bits)
*
- * \return pitch delay in 1/3 units
+ * @return pitch delay in 1/3 units
*
* Pitch delay is coded:
* with 1/3 resolution, 19 < pitch_delay < 85
@@ -43,18 +43,18 @@
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
+ * @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
+ * @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
+ * @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,
+ * @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(
@@ -62,19 +62,19 @@ int ff_acelp_decode_5_6_bit_to_2nd_delay3(
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
+ * @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
+ * @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,
+ * @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(
@@ -82,44 +82,44 @@ int ff_acelp_decode_4bit_to_2nd_delay3(
int pitch_delay_min);
/**
- * \brief Decode pitch delay of the first subframe encoded by 9 bits
+ * @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 ac_index adaptive codebook index (9 bits)
*
- * \return pitch delay in 1/6 units
+ * @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.
+ * @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
+ * @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
+ * @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
+ * @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.
+ * @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[in,out] quant_energy 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
+ * @brief Update past quantized energies
+ * @param[in,out] quant_energy 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:
@@ -128,7 +128,7 @@ int ff_acelp_decode_6bit_to_2nd_delay6(
* 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).
+ * @remark The routine is used in G.729 and AMR (all modes).
*/
void ff_acelp_update_past_gain(
int16_t* quant_energy,
@@ -137,16 +137,16 @@ void ff_acelp_update_past_gain(
int erasure);
/**
- * \brief Decode the adaptive codebook gain and add
+ * @brief Decode the adaptive codebook gain and add
* correction (4.1.5 and 3.9.1 of G.729).
- * \param dsp initialized dsputil context
- * \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[in,out] quant_energy past quantized energies (5.10)
- * \param subframe_size length of subframe
+ * @param dsp initialized dsputil context
+ * @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[in,out] quant_energy past quantized energies (5.10)
+ * @param subframe_size length of subframe
*
- * \return quantized fixed-codebook gain (14.1)
+ * @return quantized fixed-codebook gain (14.1)
*
* The routine implements equations 69, 66 and 71 of the G.729 specification (3.9.1)
*
@@ -205,7 +205,7 @@ void ff_acelp_update_past_gain(
*
* mr_energy = Em + 10log(N) + 10log(2^26)
*
- * \remark The routine is used in G.729 and AMR (all modes).
+ * @remark The routine is used in G.729 and AMR (all modes).
*/
int16_t ff_acelp_decode_gain_code(
DSPContext *dsp,
diff --git a/libavcodec/acelp_vectors.c b/libavcodec/acelp_vectors.c
index 25a6ff2..b7c05e7 100644
--- a/libavcodec/acelp_vectors.c
+++ b/libavcodec/acelp_vectors.c
@@ -48,26 +48,6 @@ const uint8_t ff_fc_2pulses_9bits_track1_gray[16] =
28, 26,
};
-const uint8_t ff_fc_2pulses_9bits_track2_gray[32] =
-{
- 0, 2,
- 5, 4,
- 12, 10,
- 7, 9,
- 25, 24,
- 20, 22,
- 14, 15,
- 19, 17,
- 36, 31,
- 21, 26,
- 1, 6,
- 16, 11,
- 27, 29,
- 32, 30,
- 39, 37,
- 34, 35,
-};
-
const uint8_t ff_fc_4pulses_8bits_tracks_13[16] =
{
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
diff --git a/libavcodec/acelp_vectors.h b/libavcodec/acelp_vectors.h
index 07d1000..2c5d319 100644
--- a/libavcodec/acelp_vectors.h
+++ b/libavcodec/acelp_vectors.h
@@ -82,37 +82,6 @@ extern const uint8_t ff_fc_2pulses_9bits_track1[16];
extern const uint8_t ff_fc_2pulses_9bits_track1_gray[16];
/**
- * Track|Pulse| Positions
- * -----------------------------------------
- * 2 | 1 | 0, 7, 14, 20, 27, 34, 1, 21
- * | | 2, 9, 15, 22, 29, 35, 6, 26
- * | | 4,10, 17, 24, 30, 37, 11, 31
- * | | 5,12, 19, 25, 32, 39, 16, 36
- * -----------------------------------------
- *
- * @remark Track in the table should be read top-to-bottom, left-to-right.
- *
- * @note (EE.1) This table (from the reference code) does not comply with
- * the specification.
- * The specification contains the following table:
- *
- * Track|Pulse| Positions
- * -----------------------------------------
- * 2 | 1 | 0, 5, 10, 15, 20, 25, 30, 35
- * | | 1, 6, 11, 16, 21, 26, 31, 36
- * | | 2, 7, 12, 17, 22, 27, 32, 37
- * | | 4, 9, 14, 19, 24, 29, 34, 39
- *
- * -----------------------------------------
- *
- * @note (EE.2) 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)
- */
-extern const uint8_t ff_fc_2pulses_9bits_track2_gray[32];
-
-/**
* b60 hamming windowed sinc function coefficients
*/
extern const float ff_b60_sinc[61];
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 70a5360..2081ef6 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -1,5 +1,4 @@
/*
- * ADPCM codecs
* Copyright (c) 2001-2003 The ffmpeg Project
*
* This file is part of Libav.
@@ -22,10 +21,12 @@
#include "get_bits.h"
#include "put_bits.h"
#include "bytestream.h"
+#include "adpcm.h"
+#include "adpcm_data.h"
/**
* @file
- * ADPCM codecs.
+ * ADPCM decoders
* First version by Francois Revol (revol at free.fr)
* Fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
* by Mike Melanson (melanson at pcisys.net)
@@ -41,73 +42,35 @@
* Features and limitations:
*
* Reference documents:
- * http://www.pcisys.net/~melanson/codecs/simpleaudio.html
- * http://www.geocities.com/SiliconValley/8682/aud3.txt
- * http://openquicktime.sourceforge.net/plugins.htm
- * XAnim sources (xa_codec.c) http://www.rasnaimaging.com/people/lapus/download.html
- * http://www.cs.ucla.edu/~leec/mediabench/applications.html
- * SoX source code http://home.sprynet.com/~cbagwell/sox.html
+ * http://wiki.multimedia.cx/index.php?title=Category:ADPCM_Audio_Codecs
+ * http://www.pcisys.net/~melanson/codecs/simpleaudio.html [dead]
+ * http://www.geocities.com/SiliconValley/8682/aud3.txt [dead]
+ * http://openquicktime.sourceforge.net/
+ * XAnim sources (xa_codec.c) http://xanim.polter.net/
+ * http://www.cs.ucla.edu/~leec/mediabench/applications.html [dead]
+ * SoX source code http://sox.sourceforge.net/
*
* CD-ROM XA:
- * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html
- * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html
+ * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html [dead]
+ * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html [dead]
* readstr http://www.geocities.co.jp/Playtown/2004/
*/
-#define BLKSIZE 1024
-
-/* step_table[] and index_table[] are from the ADPCM reference source */
-/* This is the index table: */
-static const int index_table[16] = {
- -1, -1, -1, -1, 2, 4, 6, 8,
- -1, -1, -1, -1, 2, 4, 6, 8,
-};
-
-/**
- * This is the step table. Note that many programs use slight deviations from
- * this table, but such deviations are negligible:
- */
-static const int step_table[89] = {
- 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
-};
-
-/* These are for MS-ADPCM */
-/* AdaptationTable[], AdaptCoeff1[], and AdaptCoeff2[] are from libsndfile */
-static const int AdaptationTable[] = {
- 230, 230, 230, 230, 307, 409, 512, 614,
- 768, 614, 512, 409, 307, 230, 230, 230
-};
-
-/** Divided by 4 to fit in 8-bit integers */
-static const uint8_t AdaptCoeff1[] = {
- 64, 128, 0, 48, 60, 115, 98
-};
-
-/** Divided by 4 to fit in 8-bit integers */
-static const int8_t AdaptCoeff2[] = {
- 0, -64, 0, 16, 0, -52, -58
-};
-
/* These are for CD-ROM XA ADPCM */
static const int xa_adpcm_table[5][2] = {
- { 0, 0 },
- { 60, 0 },
- { 115, -52 },
- { 98, -55 },
- { 122, -60 }
+ { 0, 0 },
+ { 60, 0 },
+ { 115, -52 },
+ { 98, -55 },
+ { 122, -60 }
};
static const int ea_adpcm_table[] = {
- 0, 240, 460, 392, 0, 0, -208, -220, 0, 1,
- 3, 4, 7, 8, 10, 11, 0, -1, -3, -4
+ 0, 240, 460, 392,
+ 0, 0, -208, -220,
+ 0, 1, 3, 4,
+ 7, 8, 10, 11,
+ 0, -1, -3, -4
};
// padded to zero where table size is less then 16
@@ -118,643 +81,29 @@ static const int swf_index_tables[4][16] = {
/*5*/ { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 }
};
-static const int yamaha_indexscale[] = {
- 230, 230, 230, 230, 307, 409, 512, 614,
- 230, 230, 230, 230, 307, 409, 512, 614
-};
-
-static const int yamaha_difflookup[] = {
- 1, 3, 5, 7, 9, 11, 13, 15,
- -1, -3, -5, -7, -9, -11, -13, -15
-};
-
/* end of tables */
-typedef struct ADPCMChannelStatus {
- int predictor;
- short int step_index;
- int step;
- /* for encoding */
- int prev_sample;
-
- /* MS version */
- short sample1;
- short sample2;
- int coeff1;
- int coeff2;
- int idelta;
-} ADPCMChannelStatus;
-
-typedef struct TrellisPath {
- int nibble;
- int prev;
-} TrellisPath;
-
-typedef struct TrellisNode {
- uint32_t ssd;
- int path;
- int sample1;
- int sample2;
- int step;
-} TrellisNode;
-
-typedef struct ADPCMContext {
+typedef struct ADPCMDecodeContext {
+ AVFrame frame;
ADPCMChannelStatus status[6];
- TrellisPath *paths;
- TrellisNode *node_buf;
- TrellisNode **nodep_buf;
- uint8_t *trellis_hash;
-} ADPCMContext;
-
-#define FREEZE_INTERVAL 128
-
-/* XXX: implement encoding */
-
-#if CONFIG_ENCODERS
-static av_cold int adpcm_encode_init(AVCodecContext *avctx)
-{
- ADPCMContext *s = avctx->priv_data;
- uint8_t *extradata;
- int i;
- if (avctx->channels > 2)
- return -1; /* only stereo or mono =) */
-
- if(avctx->trellis && (unsigned)avctx->trellis > 16U){
- av_log(avctx, AV_LOG_ERROR, "invalid trellis size\n");
- return -1;
- }
-
- if (avctx->trellis) {
- int frontier = 1 << avctx->trellis;
- int max_paths = frontier * FREEZE_INTERVAL;
- FF_ALLOC_OR_GOTO(avctx, s->paths, max_paths * sizeof(*s->paths), error);
- FF_ALLOC_OR_GOTO(avctx, s->node_buf, 2 * frontier * sizeof(*s->node_buf), error);
- FF_ALLOC_OR_GOTO(avctx, s->nodep_buf, 2 * frontier * sizeof(*s->nodep_buf), error);
- FF_ALLOC_OR_GOTO(avctx, s->trellis_hash, 65536 * sizeof(*s->trellis_hash), error);
- }
-
- switch(avctx->codec->id) {
- case CODEC_ID_ADPCM_IMA_WAV:
- avctx->frame_size = (BLKSIZE - 4 * avctx->channels) * 8 / (4 * avctx->channels) + 1; /* each 16 bits sample gives one nibble */
- /* and we have 4 bytes per channel overhead */
- avctx->block_align = BLKSIZE;
- /* seems frame_size isn't taken into account... have to buffer the samples :-( */
- break;
- case CODEC_ID_ADPCM_IMA_QT:
- avctx->frame_size = 64;
- avctx->block_align = 34 * avctx->channels;
- break;
- case CODEC_ID_ADPCM_MS:
- avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 / avctx->channels + 2; /* each 16 bits sample gives one nibble */
- /* and we have 7 bytes per channel overhead */
- avctx->block_align = BLKSIZE;
- avctx->extradata_size = 32;
- extradata = avctx->extradata = av_malloc(avctx->extradata_size);
- if (!extradata)
- return AVERROR(ENOMEM);
- bytestream_put_le16(&extradata, avctx->frame_size);
- bytestream_put_le16(&extradata, 7); /* wNumCoef */
- for (i = 0; i < 7; i++) {
- bytestream_put_le16(&extradata, AdaptCoeff1[i] * 4);
- bytestream_put_le16(&extradata, AdaptCoeff2[i] * 4);
- }
- break;
- case CODEC_ID_ADPCM_YAMAHA:
- avctx->frame_size = BLKSIZE * avctx->channels;
- avctx->block_align = BLKSIZE;
- break;
- case CODEC_ID_ADPCM_SWF:
- if (avctx->sample_rate != 11025 &&
- avctx->sample_rate != 22050 &&
- avctx->sample_rate != 44100) {
- av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, 22050 or 44100\n");
- goto error;
- }
- avctx->frame_size = 512 * (avctx->sample_rate / 11025);
- break;
- default:
- goto error;
- }
-
- avctx->coded_frame= avcodec_alloc_frame();
- avctx->coded_frame->key_frame= 1;
-
- return 0;
-error:
- av_freep(&s->paths);
- av_freep(&s->node_buf);
- av_freep(&s->nodep_buf);
- av_freep(&s->trellis_hash);
- return -1;
-}
-
-static av_cold int adpcm_encode_close(AVCodecContext *avctx)
-{
- ADPCMContext *s = avctx->priv_data;
- av_freep(&avctx->coded_frame);
- av_freep(&s->paths);
- av_freep(&s->node_buf);
- av_freep(&s->nodep_buf);
- av_freep(&s->trellis_hash);
-
- return 0;
-}
-
-
-static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c, short sample)
-{
- int delta = sample - c->prev_sample;
- int nibble = FFMIN(7, abs(delta)*4/step_table[c->step_index]) + (delta<0)*8;
- c->prev_sample += ((step_table[c->step_index] * yamaha_difflookup[nibble]) / 8);
- c->prev_sample = av_clip_int16(c->prev_sample);
- c->step_index = av_clip(c->step_index + index_table[nibble], 0, 88);
- return nibble;
-}
-
-static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c, short sample)
-{
- int predictor, nibble, bias;
-
- predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 64;
-
- nibble= sample - predictor;
- if(nibble>=0) bias= c->idelta/2;
- else bias=-c->idelta/2;
-
- nibble= (nibble + bias) / c->idelta;
- nibble= av_clip(nibble, -8, 7)&0x0F;
-
- predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta;
-
- c->sample2 = c->sample1;
- c->sample1 = av_clip_int16(predictor);
-
- c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8;
- if (c->idelta < 16) c->idelta = 16;
-
- return nibble;
-}
-
-static inline unsigned char adpcm_yamaha_compress_sample(ADPCMChannelStatus *c, short sample)
-{
- int nibble, delta;
-
- if(!c->step) {
- c->predictor = 0;
- c->step = 127;
- }
-
- delta = sample - c->predictor;
-
- nibble = FFMIN(7, abs(delta)*4/c->step) + (delta<0)*8;
-
- c->predictor += ((c->step * yamaha_difflookup[nibble]) / 8);
- c->predictor = av_clip_int16(c->predictor);
- c->step = (c->step * yamaha_indexscale[nibble]) >> 8;
- c->step = av_clip(c->step, 127, 24567);
-
- return nibble;
-}
-
-static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples,
- uint8_t *dst, ADPCMChannelStatus *c, int n)
-{
- //FIXME 6% faster if frontier is a compile-time constant
- ADPCMContext *s = avctx->priv_data;
- const int frontier = 1 << avctx->trellis;
- const int stride = avctx->channels;
- const int version = avctx->codec->id;
- TrellisPath *paths = s->paths, *p;
- TrellisNode *node_buf = s->node_buf;
- TrellisNode **nodep_buf = s->nodep_buf;
- TrellisNode **nodes = nodep_buf; // nodes[] is always sorted by .ssd
- TrellisNode **nodes_next = nodep_buf + frontier;
- int pathn = 0, froze = -1, i, j, k, generation = 0;
- uint8_t *hash = s->trellis_hash;
- memset(hash, 0xff, 65536 * sizeof(*hash));
-
- memset(nodep_buf, 0, 2 * frontier * sizeof(*nodep_buf));
- nodes[0] = node_buf + frontier;
- nodes[0]->ssd = 0;
- nodes[0]->path = 0;
- nodes[0]->step = c->step_index;
- nodes[0]->sample1 = c->sample1;
- nodes[0]->sample2 = c->sample2;
- if((version == CODEC_ID_ADPCM_IMA_WAV) || (version == CODEC_ID_ADPCM_IMA_QT) || (version == CODEC_ID_ADPCM_SWF))
- nodes[0]->sample1 = c->prev_sample;
- if(version == CODEC_ID_ADPCM_MS)
- nodes[0]->step = c->idelta;
- if(version == CODEC_ID_ADPCM_YAMAHA) {
- if(c->step == 0) {
- nodes[0]->step = 127;
- nodes[0]->sample1 = 0;
- } else {
- nodes[0]->step = c->step;
- nodes[0]->sample1 = c->predictor;
- }
- }
-
- for(i=0; i<n; i++) {
- TrellisNode *t = node_buf + frontier*(i&1);
- TrellisNode **u;
- int sample = samples[i*stride];
- int heap_pos = 0;
- memset(nodes_next, 0, frontier*sizeof(TrellisNode*));
- for(j=0; j<frontier && nodes[j]; j++) {
- // higher j have higher ssd already, so they're likely to yield a suboptimal next sample too
- const int range = (j < frontier/2) ? 1 : 0;
- 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)) / 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);
- for(nidx=nmin; nidx<=nmax; nidx++) {
- const int nibble = nidx & 0xf;
- int dec_sample = predictor + nidx * step;
-#define STORE_NODE(NAME, STEP_INDEX)\
- int d;\
- uint32_t ssd;\
- int pos;\
- TrellisNode *u;\
- uint8_t *h;\
- dec_sample = av_clip_int16(dec_sample);\
- d = sample - dec_sample;\
- ssd = nodes[j]->ssd + d*d;\
- /* Check for wraparound, skip such samples completely. \
- * Note, changing ssd to a 64 bit variable would be \
- * simpler, avoiding this check, but it's slower on \
- * x86 32 bit at the moment. */\
- if (ssd < nodes[j]->ssd)\
- goto next_##NAME;\
- /* Collapse any two states with the same previous sample value. \
- * One could also distinguish states by step and by 2nd to last
- * sample, but the effects of that are negligible.
- * Since nodes in the previous generation are iterated
- * through a heap, they're roughly ordered from better to
- * worse, but not strictly ordered. Therefore, an earlier
- * node with the same sample value is better in most cases
- * (and thus the current is skipped), but not strictly
- * in all cases. Only skipping samples where ssd >=
- * ssd of the earlier node with the same sample gives
- * slightly worse quality, though, for some reason. */ \
- h = &hash[(uint16_t) dec_sample];\
- if (*h == generation)\
- goto next_##NAME;\
- if (heap_pos < frontier) {\
- pos = heap_pos++;\
- } else {\
- /* Try to replace one of the leaf nodes with the new \
- * one, but try a different slot each time. */\
- pos = (frontier >> 1) + (heap_pos & ((frontier >> 1) - 1));\
- if (ssd > nodes_next[pos]->ssd)\
- goto next_##NAME;\
- heap_pos++;\
- }\
- *h = generation;\
- u = nodes_next[pos];\
- if(!u) {\
- assert(pathn < FREEZE_INTERVAL<<avctx->trellis);\
- u = t++;\
- nodes_next[pos] = u;\
- u->path = pathn++;\
- }\
- u->ssd = ssd;\
- u->step = STEP_INDEX;\
- u->sample2 = nodes[j]->sample1;\
- u->sample1 = dec_sample;\
- paths[u->path].nibble = nibble;\
- paths[u->path].prev = nodes[j]->path;\
- /* Sift the newly inserted node up in the heap to \
- * restore the heap property. */\
- while (pos > 0) {\
- int parent = (pos - 1) >> 1;\
- if (nodes_next[parent]->ssd <= ssd)\
- break;\
- FFSWAP(TrellisNode*, nodes_next[parent], nodes_next[pos]);\
- pos = parent;\
- }\
- next_##NAME:;
- STORE_NODE(ms, FFMAX(16, (AdaptationTable[nibble] * step) >> 8));
- }
- } else if((version == CODEC_ID_ADPCM_IMA_WAV)|| (version == CODEC_ID_ADPCM_IMA_QT)|| (version == CODEC_ID_ADPCM_SWF)) {
-#define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\
- const int predictor = nodes[j]->sample1;\
- const int div = (sample - predictor) * 4 / STEP_TABLE;\
- int nmin = av_clip(div-range, -7, 6);\
- int nmax = av_clip(div+range, -6, 7);\
- if(nmin<=0) nmin--; /* distinguish -0 from +0 */\
- if(nmax<0) nmax--;\
- for(nidx=nmin; nidx<=nmax; nidx++) {\
- const int nibble = nidx<0 ? 7-nidx : nidx;\
- int dec_sample = predictor + (STEP_TABLE * yamaha_difflookup[nibble]) / 8;\
- STORE_NODE(NAME, STEP_INDEX);\
- }
- LOOP_NODES(ima, step_table[step], av_clip(step + index_table[nibble], 0, 88));
- } else { //CODEC_ID_ADPCM_YAMAHA
- LOOP_NODES(yamaha, step, av_clip((step * yamaha_indexscale[nibble]) >> 8, 127, 24567));
-#undef LOOP_NODES
-#undef STORE_NODE
- }
- }
-
- u = nodes;
- nodes = nodes_next;
- nodes_next = u;
-
- generation++;
- if (generation == 255) {
- memset(hash, 0xff, 65536 * sizeof(*hash));
- generation = 0;
- }
-
- // prevent overflow
- if(nodes[0]->ssd > (1<<28)) {
- for(j=1; j<frontier && nodes[j]; j++)
- nodes[j]->ssd -= nodes[0]->ssd;
- nodes[0]->ssd = 0;
- }
-
- // merge old paths to save memory
- if(i == froze + FREEZE_INTERVAL) {
- p = &paths[nodes[0]->path];
- for(k=i; k>froze; k--) {
- dst[k] = p->nibble;
- p = &paths[p->prev];
- }
- froze = i;
- pathn = 0;
- // other nodes might use paths that don't coincide with the frozen one.
- // checking which nodes do so is too slow, so just kill them all.
- // this also slightly improves quality, but I don't know why.
- memset(nodes+1, 0, (frontier-1)*sizeof(TrellisNode*));
- }
- }
-
- p = &paths[nodes[0]->path];
- for(i=n-1; i>froze; i--) {
- dst[i] = p->nibble;
- p = &paths[p->prev];
- }
-
- c->predictor = nodes[0]->sample1;
- c->sample1 = nodes[0]->sample1;
- c->sample2 = nodes[0]->sample2;
- c->step_index = nodes[0]->step;
- c->step = nodes[0]->step;
- c->idelta = nodes[0]->step;
-}
-
-static int adpcm_encode_frame(AVCodecContext *avctx,
- unsigned char *frame, int buf_size, void *data)
-{
- int n, i, st;
- short *samples;
- unsigned char *dst;
- ADPCMContext *c = avctx->priv_data;
- uint8_t *buf;
-
- dst = frame;
- samples = (short *)data;
- st= avctx->channels == 2;
-/* n = (BLKSIZE - 4 * avctx->channels) / (2 * 8 * avctx->channels); */
-
- switch(avctx->codec->id) {
- case CODEC_ID_ADPCM_IMA_WAV:
- n = avctx->frame_size / 8;
- c->status[0].prev_sample = (signed short)samples[0]; /* XXX */
-/* c->status[0].step_index = 0; *//* XXX: not sure how to init the state machine */
- bytestream_put_le16(&dst, c->status[0].prev_sample);
- *dst++ = (unsigned char)c->status[0].step_index;
- *dst++ = 0; /* unknown */
- samples++;
- if (avctx->channels == 2) {
- c->status[1].prev_sample = (signed short)samples[0];
-/* c->status[1].step_index = 0; */
- bytestream_put_le16(&dst, c->status[1].prev_sample);
- *dst++ = (unsigned char)c->status[1].step_index;
- *dst++ = 0;
- samples++;
- }
-
- /* stereo: 4 bytes (8 samples) for left, 4 bytes for right, 4 bytes left, ... */
- if(avctx->trellis > 0) {
- FF_ALLOC_OR_GOTO(avctx, buf, 2*n*8, error);
- adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n*8);
- if(avctx->channels == 2)
- adpcm_compress_trellis(avctx, samples+1, buf + n*8, &c->status[1], n*8);
- for(i=0; i<n; i++) {
- *dst++ = buf[8*i+0] | (buf[8*i+1] << 4);
- *dst++ = buf[8*i+2] | (buf[8*i+3] << 4);
- *dst++ = buf[8*i+4] | (buf[8*i+5] << 4);
- *dst++ = buf[8*i+6] | (buf[8*i+7] << 4);
- if (avctx->channels == 2) {
- uint8_t *buf1 = buf + n*8;
- *dst++ = buf1[8*i+0] | (buf1[8*i+1] << 4);
- *dst++ = buf1[8*i+2] | (buf1[8*i+3] << 4);
- *dst++ = buf1[8*i+4] | (buf1[8*i+5] << 4);
- *dst++ = buf1[8*i+6] | (buf1[8*i+7] << 4);
- }
- }
- av_free(buf);
- } else
- for (; n>0; n--) {
- *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]);
- *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels]) << 4;
- dst++;
- *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]);
- *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4;
- dst++;
- *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]);
- *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4;
- dst++;
- *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]);
- *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4;
- dst++;
- /* right channel */
- if (avctx->channels == 2) {
- *dst = adpcm_ima_compress_sample(&c->status[1], samples[1]);
- *dst |= adpcm_ima_compress_sample(&c->status[1], samples[3]) << 4;
- dst++;
- *dst = adpcm_ima_compress_sample(&c->status[1], samples[5]);
- *dst |= adpcm_ima_compress_sample(&c->status[1], samples[7]) << 4;
- dst++;
- *dst = adpcm_ima_compress_sample(&c->status[1], samples[9]);
- *dst |= adpcm_ima_compress_sample(&c->status[1], samples[11]) << 4;
- dst++;
- *dst = adpcm_ima_compress_sample(&c->status[1], samples[13]);
- *dst |= adpcm_ima_compress_sample(&c->status[1], samples[15]) << 4;
- dst++;
- }
- samples += 8 * avctx->channels;
- }
- break;
- case CODEC_ID_ADPCM_IMA_QT:
- {
- int ch, i;
- PutBitContext pb;
- init_put_bits(&pb, dst, buf_size*8);
-
- for(ch=0; ch<avctx->channels; ch++){
- put_bits(&pb, 9, (c->status[ch].prev_sample + 0x10000) >> 7);
- put_bits(&pb, 7, c->status[ch].step_index);
- if(avctx->trellis > 0) {
- uint8_t buf[64];
- adpcm_compress_trellis(avctx, samples+ch, buf, &c->status[ch], 64);
- for(i=0; i<64; i++)
- put_bits(&pb, 4, buf[i^1]);
- c->status[ch].prev_sample = c->status[ch].predictor & ~0x7F;
- } else {
- for (i=0; i<64; i+=2){
- int t1, t2;
- t1 = adpcm_ima_compress_sample(&c->status[ch], samples[avctx->channels*(i+0)+ch]);
- t2 = adpcm_ima_compress_sample(&c->status[ch], samples[avctx->channels*(i+1)+ch]);
- put_bits(&pb, 4, t2);
- put_bits(&pb, 4, t1);
- }
- c->status[ch].prev_sample &= ~0x7F;
- }
- }
-
- flush_put_bits(&pb);
- dst += put_bits_count(&pb)>>3;
- break;
- }
- case CODEC_ID_ADPCM_SWF:
- {
- int i;
- PutBitContext pb;
- init_put_bits(&pb, dst, buf_size*8);
-
- n = avctx->frame_size-1;
-
- //Store AdpcmCodeSize
- put_bits(&pb, 2, 2); //Set 4bits flash adpcm format
-
- //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_sbits(&pb, 16, samples[i]);
- put_bits(&pb, 6, c->status[i].step_index);
- c->status[i].prev_sample = (signed short)samples[i];
- }
-
- if(avctx->trellis > 0) {
- FF_ALLOC_OR_GOTO(avctx, buf, 2*n, error);
- adpcm_compress_trellis(avctx, samples+2, buf, &c->status[0], n);
- if (avctx->channels == 2)
- adpcm_compress_trellis(avctx, samples+3, buf+n, &c->status[1], n);
- for(i=0; i<n; i++) {
- put_bits(&pb, 4, buf[i]);
- if (avctx->channels == 2)
- put_bits(&pb, 4, buf[n+i]);
- }
- av_free(buf);
- } else {
- for (i=1; i<avctx->frame_size; i++) {
- put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels*i]));
- if (avctx->channels == 2)
- put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1], samples[2*i+1]));
- }
- }
- flush_put_bits(&pb);
- dst += put_bits_count(&pb)>>3;
- break;
- }
- case CODEC_ID_ADPCM_MS:
- for(i=0; i<avctx->channels; i++){
- int predictor=0;
-
- *dst++ = predictor;
- c->status[i].coeff1 = AdaptCoeff1[predictor];
- c->status[i].coeff2 = AdaptCoeff2[predictor];
- }
- for(i=0; i<avctx->channels; i++){
- if (c->status[i].idelta < 16)
- c->status[i].idelta = 16;
-
- 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++)
- bytestream_put_le16(&dst, c->status[i].sample2);
-
- if(avctx->trellis > 0) {
- int n = avctx->block_align - 7*avctx->channels;
- FF_ALLOC_OR_GOTO(avctx, buf, 2*n, error);
- if(avctx->channels == 1) {
- adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
- for(i=0; i<n; i+=2)
- *dst++ = (buf[i] << 4) | buf[i+1];
- } else {
- adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
- adpcm_compress_trellis(avctx, samples+1, buf+n, &c->status[1], n);
- for(i=0; i<n; i++)
- *dst++ = (buf[i] << 4) | buf[n+i];
- }
- av_free(buf);
- } else
- for(i=7*avctx->channels; i<avctx->block_align; i++) {
- int nibble;
- nibble = adpcm_ms_compress_sample(&c->status[ 0], *samples++)<<4;
- nibble|= adpcm_ms_compress_sample(&c->status[st], *samples++);
- *dst++ = nibble;
- }
- break;
- case CODEC_ID_ADPCM_YAMAHA:
- n = avctx->frame_size / 2;
- if(avctx->trellis > 0) {
- FF_ALLOC_OR_GOTO(avctx, buf, 2*n*2, error);
- n *= 2;
- if(avctx->channels == 1) {
- adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
- for(i=0; i<n; i+=2)
- *dst++ = buf[i] | (buf[i+1] << 4);
- } else {
- adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
- adpcm_compress_trellis(avctx, samples+1, buf+n, &c->status[1], n);
- for(i=0; i<n; i++)
- *dst++ = buf[i] | (buf[n+i] << 4);
- }
- av_free(buf);
- } else
- for (n *= avctx->channels; n>0; n--) {
- int nibble;
- nibble = adpcm_yamaha_compress_sample(&c->status[ 0], *samples++);
- nibble |= adpcm_yamaha_compress_sample(&c->status[st], *samples++) << 4;
- *dst++ = nibble;
- }
- break;
- default:
- error:
- return -1;
- }
- return dst - frame;
-}
-#endif //CONFIG_ENCODERS
+} ADPCMDecodeContext;
static av_cold int adpcm_decode_init(AVCodecContext * avctx)
{
- ADPCMContext *c = avctx->priv_data;
+ ADPCMDecodeContext *c = avctx->priv_data;
unsigned int max_channels = 2;
switch(avctx->codec->id) {
case CODEC_ID_ADPCM_EA_R1:
case CODEC_ID_ADPCM_EA_R2:
case CODEC_ID_ADPCM_EA_R3:
+ case CODEC_ID_ADPCM_EA_XAS:
max_channels = 6;
break;
}
- if(avctx->channels > max_channels){
- return -1;
+ if (avctx->channels <= 0 || avctx->channels > max_channels) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
+ return AVERROR(EINVAL);
}
switch(avctx->codec->id) {
@@ -777,6 +126,10 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
break;
}
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ avcodec_get_frame_defaults(&c->frame);
+ avctx->coded_frame = &c->frame;
+
return 0;
}
@@ -786,8 +139,8 @@ static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble,
int predictor;
int sign, delta, diff, step;
- step = step_table[c->step_index];
- step_index = c->step_index + index_table[(unsigned)nibble];
+ step = ff_adpcm_step_table[c->step_index];
+ step_index = c->step_index + ff_adpcm_index_table[(unsigned)nibble];
if (step_index < 0) step_index = 0;
else if (step_index > 88) step_index = 88;
@@ -807,6 +160,32 @@ static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble,
return (short)c->predictor;
}
+static inline int adpcm_ima_qt_expand_nibble(ADPCMChannelStatus *c, int nibble, int shift)
+{
+ int step_index;
+ int predictor;
+ int diff, step;
+
+ step = ff_adpcm_step_table[c->step_index];
+ step_index = c->step_index + ff_adpcm_index_table[nibble];
+ step_index = av_clip(step_index, 0, 88);
+
+ diff = step >> 3;
+ if (nibble & 4) diff += step;
+ if (nibble & 2) diff += step >> 1;
+ if (nibble & 1) diff += step >> 2;
+
+ if (nibble & 8)
+ predictor = c->predictor - diff;
+ else
+ predictor = c->predictor + diff;
+
+ c->predictor = av_clip_int16(predictor);
+ c->step_index = step_index;
+
+ return c->predictor;
+}
+
static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble)
{
int predictor;
@@ -816,7 +195,7 @@ static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble)
c->sample2 = c->sample1;
c->sample1 = av_clip_int16(predictor);
- c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8;
+ c->idelta = (ff_adpcm_AdaptationTable[(int)nibble] * c->idelta) >> 8;
if (c->idelta < 16) c->idelta = 16;
return c->sample1;
@@ -837,7 +216,7 @@ static inline short adpcm_ct_expand_nibble(ADPCMChannelStatus *c, char nibble)
c->predictor = ((c->predictor * 254) >> 8) + (sign ? -diff : diff);
c->predictor = av_clip_int16(c->predictor);
/* calculate new step and clamp it to range 511..32767 */
- new_step = (AdaptationTable[nibble & 7] * c->step) >> 8;
+ new_step = (ff_adpcm_AdaptationTable[nibble & 7] * c->step) >> 8;
c->step = av_clip(new_step, 511, 32767);
return (short)c->predictor;
@@ -870,9 +249,9 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c
c->step = 127;
}
- c->predictor += (c->step * yamaha_difflookup[nibble]) / 8;
+ c->predictor += (c->step * ff_adpcm_yamaha_difflookup[nibble]) / 8;
c->predictor = av_clip_int16(c->predictor);
- c->step = (c->step * yamaha_indexscale[nibble]) >> 8;
+ c->step = (c->step * ff_adpcm_yamaha_indexscale[nibble]) >> 8;
c->step = av_clip(c->step, 127, 24567);
return c->predictor;
}
@@ -942,6 +321,173 @@ static void xa_decode(short *out, const unsigned char *in,
}
}
+/**
+ * Get the number of samples that will be decoded from the packet.
+ * In one case, this is actually the maximum number of samples possible to
+ * decode with the given buf_size.
+ *
+ * @param[out] coded_samples set to the number of samples as coded in the
+ * packet, or 0 if the codec does not encode the
+ * number of samples in each frame.
+ */
+static int get_nb_samples(AVCodecContext *avctx, const uint8_t *buf,
+ int buf_size, int *coded_samples)
+{
+ ADPCMDecodeContext *s = avctx->priv_data;
+ int nb_samples = 0;
+ int ch = avctx->channels;
+ int has_coded_samples = 0;
+ int header_size;
+
+ *coded_samples = 0;
+
+ switch (avctx->codec->id) {
+ /* constant, only check buf_size */
+ case CODEC_ID_ADPCM_EA_XAS:
+ if (buf_size < 76 * ch)
+ return 0;
+ nb_samples = 128;
+ break;
+ case CODEC_ID_ADPCM_IMA_QT:
+ if (buf_size < 34 * ch)
+ return 0;
+ nb_samples = 64;
+ break;
+ /* simple 4-bit adpcm */
+ case CODEC_ID_ADPCM_CT:
+ case CODEC_ID_ADPCM_IMA_EA_SEAD:
+ case CODEC_ID_ADPCM_IMA_WS:
+ case CODEC_ID_ADPCM_YAMAHA:
+ nb_samples = buf_size * 2 / ch;
+ break;
+ }
+ if (nb_samples)
+ return nb_samples;
+
+ /* simple 4-bit adpcm, with header */
+ header_size = 0;
+ switch (avctx->codec->id) {
+ case CODEC_ID_ADPCM_4XM:
+ case CODEC_ID_ADPCM_IMA_ISS: header_size = 4 * ch; break;
+ case CODEC_ID_ADPCM_IMA_AMV: header_size = 8; break;
+ case CODEC_ID_ADPCM_IMA_SMJPEG: header_size = 4; break;
+ }
+ if (header_size > 0)
+ return (buf_size - header_size) * 2 / ch;
+
+ /* more complex formats */
+ switch (avctx->codec->id) {
+ case CODEC_ID_ADPCM_EA:
+ has_coded_samples = 1;
+ if (buf_size < 4)
+ return 0;
+ *coded_samples = AV_RL32(buf);
+ *coded_samples -= *coded_samples % 28;
+ nb_samples = (buf_size - 12) / 30 * 28;
+ break;
+ case CODEC_ID_ADPCM_IMA_EA_EACS:
+ has_coded_samples = 1;
+ if (buf_size < 4)
+ return 0;
+ *coded_samples = AV_RL32(buf);
+ nb_samples = (buf_size - (4 + 8 * ch)) * 2 / ch;
+ break;
+ case CODEC_ID_ADPCM_EA_MAXIS_XA:
+ nb_samples = ((buf_size - ch) / (2 * ch)) * 2 * ch;
+ break;
+ case CODEC_ID_ADPCM_EA_R1:
+ case CODEC_ID_ADPCM_EA_R2:
+ case CODEC_ID_ADPCM_EA_R3:
+ /* maximum number of samples */
+ /* has internal offsets and a per-frame switch to signal raw 16-bit */
+ has_coded_samples = 1;
+ if (buf_size < 4)
+ return 0;
+ switch (avctx->codec->id) {
+ case CODEC_ID_ADPCM_EA_R1:
+ header_size = 4 + 9 * ch;
+ *coded_samples = AV_RL32(buf);
+ break;
+ case CODEC_ID_ADPCM_EA_R2:
+ header_size = 4 + 5 * ch;
+ *coded_samples = AV_RL32(buf);
+ break;
+ case CODEC_ID_ADPCM_EA_R3:
+ header_size = 4 + 5 * ch;
+ *coded_samples = AV_RB32(buf);
+ break;
+ }
+ *coded_samples -= *coded_samples % 28;
+ nb_samples = (buf_size - header_size) * 2 / ch;
+ nb_samples -= nb_samples % 28;
+ break;
+ case CODEC_ID_ADPCM_IMA_DK3:
+ if (avctx->block_align > 0)
+ buf_size = FFMIN(buf_size, avctx->block_align);
+ nb_samples = ((buf_size - 16) * 8 / 3) / ch;
+ break;
+ case CODEC_ID_ADPCM_IMA_DK4:
+ nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch;
+ break;
+ case CODEC_ID_ADPCM_IMA_WAV:
+ if (avctx->block_align > 0)
+ buf_size = FFMIN(buf_size, avctx->block_align);
+ nb_samples = 1 + (buf_size - 4 * ch) / (4 * ch) * 8;
+ break;
+ case CODEC_ID_ADPCM_MS:
+ if (avctx->block_align > 0)
+ buf_size = FFMIN(buf_size, avctx->block_align);
+ nb_samples = 2 + (buf_size - 7 * ch) * 2 / ch;
+ break;
+ case CODEC_ID_ADPCM_SBPRO_2:
+ case CODEC_ID_ADPCM_SBPRO_3:
+ case CODEC_ID_ADPCM_SBPRO_4:
+ {
+ int samples_per_byte;
+ switch (avctx->codec->id) {
+ case CODEC_ID_ADPCM_SBPRO_2: samples_per_byte = 4; break;
+ case CODEC_ID_ADPCM_SBPRO_3: samples_per_byte = 3; break;
+ case CODEC_ID_ADPCM_SBPRO_4: samples_per_byte = 2; break;
+ }
+ if (!s->status[0].step_index) {
+ nb_samples++;
+ buf_size -= ch;
+ }
+ nb_samples += buf_size * samples_per_byte / ch;
+ break;
+ }
+ case CODEC_ID_ADPCM_SWF:
+ {
+ int buf_bits = buf_size * 8 - 2;
+ int nbits = (buf[0] >> 6) + 2;
+ int block_hdr_size = 22 * ch;
+ int block_size = block_hdr_size + nbits * ch * 4095;
+ int nblocks = buf_bits / block_size;
+ int bits_left = buf_bits - nblocks * block_size;
+ nb_samples = nblocks * 4096;
+ if (bits_left >= block_hdr_size)
+ nb_samples += 1 + (bits_left - block_hdr_size) / (nbits * ch);
+ break;
+ }
+ case CODEC_ID_ADPCM_THP:
+ has_coded_samples = 1;
+ if (buf_size < 8)
+ return 0;
+ *coded_samples = AV_RB32(&buf[4]);
+ *coded_samples -= *coded_samples % 14;
+ nb_samples = (buf_size - 80) / (8 * ch) * 14;
+ break;
+ case CODEC_ID_ADPCM_XA:
+ nb_samples = (buf_size / 128) * 224 / ch;
+ break;
+ }
+
+ /* validate coded sample count */
+ if (has_coded_samples && (*coded_samples <= 0 || *coded_samples > nb_samples))
+ return AVERROR_INVALIDDATA;
+
+ return nb_samples;
+}
/* DK3 ADPCM support macro */
#define DK3_GET_NEXT_NIBBLE() \
@@ -952,105 +498,104 @@ static void xa_decode(short *out, const unsigned char *in,
} \
else \
{ \
+ if (end_of_packet) \
+ break; \
last_byte = *src++; \
- if (src >= buf + buf_size) break; \
+ if (src >= buf + buf_size) \
+ end_of_packet = 1; \
nibble = last_byte & 0x0F; \
decode_top_nibble_next = 1; \
}
-static int adpcm_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- ADPCMContext *c = avctx->priv_data;
+ ADPCMDecodeContext *c = avctx->priv_data;
ADPCMChannelStatus *cs;
int n, m, channel, i;
- int block_predictor[2];
short *samples;
- short *samples_end;
const uint8_t *src;
int st; /* stereo */
-
- /* DK3 ADPCM accounting variables */
- unsigned char last_byte = 0;
- unsigned char nibble;
- int decode_top_nibble_next = 0;
- int diff_channel;
-
- /* EA ADPCM state variables */
- uint32_t samples_in_chunk;
- int32_t previous_left_sample, previous_right_sample;
- int32_t current_left_sample, current_right_sample;
- int32_t next_left_sample, next_right_sample;
- int32_t coeff1l, coeff2l, coeff1r, coeff2r;
- uint8_t shift_left, shift_right;
int count1, count2;
- int coeff[2][2], shift[2];//used in EA MAXIS ADPCM
+ int nb_samples, coded_samples, ret;
- if (!buf_size)
- return 0;
+ nb_samples = get_nb_samples(avctx, buf, buf_size, &coded_samples);
+ if (nb_samples <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "invalid number of samples in packet\n");
+ return AVERROR_INVALIDDATA;
+ }
- //should protect all 4bit ADPCM variants
- //8 is needed for CODEC_ID_ADPCM_IMA_WAV with 2 channels
- //
- if(*data_size/4 < buf_size + 8)
- return -1;
+ /* get output buffer */
+ c->frame.nb_samples = nb_samples;
+ if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (short *)c->frame.data[0];
+
+ /* use coded_samples when applicable */
+ /* it is always <= nb_samples, so the output buffer will be large enough */
+ if (coded_samples) {
+ if (coded_samples != nb_samples)
+ av_log(avctx, AV_LOG_WARNING, "mismatch in coded sample count\n");
+ c->frame.nb_samples = nb_samples = coded_samples;
+ }
- samples = data;
- samples_end= samples + *data_size/2;
- *data_size= 0;
src = buf;
st = avctx->channels == 2 ? 1 : 0;
switch(avctx->codec->id) {
case CODEC_ID_ADPCM_IMA_QT:
- n = buf_size - 2*avctx->channels;
+ /* In QuickTime, IMA is encoded by chunks of 34 bytes (=64 samples).
+ Channel data is interleaved per-chunk. */
for (channel = 0; channel < avctx->channels; channel++) {
+ int16_t predictor;
+ int step_index;
cs = &(c->status[channel]);
/* (pppppp) (piiiiiii) */
/* Bits 15-7 are the _top_ 9 bits of the 16-bit initial predictor value */
- cs->predictor = (*src++) << 8;
- cs->predictor |= (*src & 0x80);
- cs->predictor &= 0xFF80;
-
- /* sign extension */
- if(cs->predictor & 0x8000)
- cs->predictor -= 0x10000;
-
- cs->predictor = av_clip_int16(cs->predictor);
-
- cs->step_index = (*src++) & 0x7F;
+ predictor = AV_RB16(src);
+ step_index = predictor & 0x7F;
+ predictor &= 0xFF80;
+
+ src += 2;
+
+ if (cs->step_index == step_index) {
+ int diff = (int)predictor - cs->predictor;
+ if (diff < 0)
+ diff = - diff;
+ if (diff > 0x7f)
+ goto update;
+ } else {
+ update:
+ cs->step_index = step_index;
+ cs->predictor = predictor;
+ }
if (cs->step_index > 88){
av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", cs->step_index);
cs->step_index = 88;
}
- cs->step = step_table[cs->step_index];
+ samples = (short *)c->frame.data[0] + channel;
- samples = (short*)data + channel;
-
- for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded by chuncks of 34 bytes (=64 samples) */
- *samples = adpcm_ima_expand_nibble(cs, src[0] & 0x0F, 3);
+ for (m = 0; m < 32; m++) {
+ *samples = adpcm_ima_qt_expand_nibble(cs, src[0] & 0x0F, 3);
samples += avctx->channels;
- *samples = adpcm_ima_expand_nibble(cs, src[0] >> 4 , 3);
+ *samples = adpcm_ima_qt_expand_nibble(cs, src[0] >> 4 , 3);
samples += avctx->channels;
src ++;
}
}
- if (st)
- samples--;
break;
case CODEC_ID_ADPCM_IMA_WAV:
if (avctx->block_align != 0 && buf_size > avctx->block_align)
buf_size = avctx->block_align;
-// samples_per_block= (block_align-4*chanels)*8 / (bits_per_sample * chanels) + 1;
-
for(i=0; i<avctx->channels; i++){
cs = &(c->status[i]);
cs->predictor = *samples++ = (int16_t)bytestream_get_le16(&src);
@@ -1063,61 +608,61 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
if (*src++) av_log(avctx, AV_LOG_ERROR, "unused byte should be null but is %d!!\n", src[-1]); /* unused */
}
- while(src < buf + buf_size){
- for(m=0; m<4; m++){
- for(i=0; i<=st; i++)
- *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] & 0x0F, 3);
- for(i=0; i<=st; i++)
- *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] >> 4 , 3);
- src++;
+ for (n = (nb_samples - 1) / 8; n > 0; n--) {
+ for (i = 0; i < avctx->channels; i++) {
+ cs = &c->status[i];
+ for (m = 0; m < 4; m++) {
+ uint8_t v = *src++;
+ *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 3);
+ samples += avctx->channels;
+ *samples = adpcm_ima_expand_nibble(cs, v >> 4 , 3);
+ samples += avctx->channels;
+ }
+ samples -= 8 * avctx->channels - 1;
}
- src += 4*st;
+ samples += 7 * avctx->channels;
}
break;
case CODEC_ID_ADPCM_4XM:
- cs = &(c->status[0]);
- c->status[0].predictor= (int16_t)bytestream_get_le16(&src);
- if(st){
- c->status[1].predictor= (int16_t)bytestream_get_le16(&src);
- }
- c->status[0].step_index= (int16_t)bytestream_get_le16(&src);
- if(st){
- 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;
+ for (i = 0; i < avctx->channels; i++)
+ c->status[i].predictor= (int16_t)bytestream_get_le16(&src);
- m= (buf_size - (src - buf))>>st;
- for(i=0; i<m; i++) {
- *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] & 0x0F, 4);
- if (st)
- *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] & 0x0F, 4);
- *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] >> 4, 4);
- if (st)
- *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] >> 4, 4);
+ for (i = 0; i < avctx->channels; i++) {
+ c->status[i].step_index= (int16_t)bytestream_get_le16(&src);
+ c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88);
}
- src += m<<st;
-
+ for (i = 0; i < avctx->channels; i++) {
+ samples = (short *)c->frame.data[0] + i;
+ cs = &c->status[i];
+ for (n = nb_samples >> 1; n > 0; n--, src++) {
+ uint8_t v = *src;
+ *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 4);
+ samples += avctx->channels;
+ *samples = adpcm_ima_expand_nibble(cs, v >> 4 , 4);
+ samples += avctx->channels;
+ }
+ }
break;
case CODEC_ID_ADPCM_MS:
+ {
+ int block_predictor;
+
if (avctx->block_align != 0 && buf_size > avctx->block_align)
buf_size = avctx->block_align;
- n = buf_size - 7 * avctx->channels;
- if (n < 0)
- return -1;
- block_predictor[0] = av_clip(*src++, 0, 6);
- block_predictor[1] = 0;
- if (st)
- block_predictor[1] = av_clip(*src++, 0, 6);
+
+ block_predictor = av_clip(*src++, 0, 6);
+ c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor];
+ c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor];
+ if (st) {
+ block_predictor = av_clip(*src++, 0, 6);
+ c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor];
+ c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor];
+ }
c->status[0].idelta = (int16_t)bytestream_get_le16(&src);
if (st){
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 = bytestream_get_le16(&src);
if (st) c->status[1].sample1 = bytestream_get_le16(&src);
@@ -1128,51 +673,40 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
if (st) *samples++ = c->status[1].sample2;
*samples++ = c->status[0].sample1;
if (st) *samples++ = c->status[1].sample1;
- for(;n>0;n--) {
+ for(n = (nb_samples - 2) >> (1 - st); n > 0; n--, src++) {
*samples++ = adpcm_ms_expand_nibble(&c->status[0 ], src[0] >> 4 );
*samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] & 0x0F);
- src ++;
}
break;
+ }
case CODEC_ID_ADPCM_IMA_DK4:
if (avctx->block_align != 0 && buf_size > avctx->block_align)
buf_size = avctx->block_align;
- 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)bytestream_get_le16(&src);
- c->status[1].step_index = *src++;
+ for (channel = 0; channel < avctx->channels; channel++) {
+ cs = &c->status[channel];
+ cs->predictor = (int16_t)bytestream_get_le16(&src);
+ cs->step_index = *src++;
src++;
- *samples++ = c->status[1].predictor;
+ *samples++ = cs->predictor;
}
- while (src < buf + buf_size) {
-
- /* take care of the top nibble (always left or mono channel) */
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
- src[0] >> 4, 3);
-
- /* take care of the bottom nibble, which is right sample for
- * stereo, or another mono sample */
- if (st)
- *samples++ = adpcm_ima_expand_nibble(&c->status[1],
- src[0] & 0x0F, 3);
- else
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
- src[0] & 0x0F, 3);
-
- src++;
+ for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
+ uint8_t v = *src;
+ *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4 , 3);
+ *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);
}
break;
case CODEC_ID_ADPCM_IMA_DK3:
+ {
+ unsigned char last_byte = 0;
+ unsigned char nibble;
+ int decode_top_nibble_next = 0;
+ int end_of_packet = 0;
+ int diff_channel;
+
if (avctx->block_align != 0 && buf_size > avctx->block_align)
buf_size = avctx->block_align;
- if(buf_size + 16 > (samples_end - samples)*3/8)
- return -1;
-
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];
@@ -1211,50 +745,35 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
*samples++ = c->status[0].predictor - c->status[1].predictor;
}
break;
+ }
case CODEC_ID_ADPCM_IMA_ISS:
- c->status[0].predictor = (int16_t)AV_RL16(src + 0);
- c->status[0].step_index = src[2];
- src += 4;
- if(st) {
- c->status[1].predictor = (int16_t)AV_RL16(src + 0);
- c->status[1].step_index = src[2];
- src += 4;
+ for (channel = 0; channel < avctx->channels; channel++) {
+ cs = &c->status[channel];
+ cs->predictor = (int16_t)bytestream_get_le16(&src);
+ cs->step_index = *src++;
+ src++;
}
- while (src < buf + buf_size) {
-
+ for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
+ uint8_t v1, v2;
+ uint8_t v = *src;
+ /* nibbles are swapped for mono */
if (st) {
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
- src[0] >> 4 , 3);
- *samples++ = adpcm_ima_expand_nibble(&c->status[1],
- src[0] & 0x0F, 3);
+ v1 = v >> 4;
+ v2 = v & 0x0F;
} else {
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
- src[0] & 0x0F, 3);
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
- src[0] >> 4 , 3);
+ v2 = v >> 4;
+ v1 = v & 0x0F;
}
-
- src++;
+ *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v1, 3);
+ *samples++ = adpcm_ima_expand_nibble(&c->status[st], v2, 3);
}
break;
case CODEC_ID_ADPCM_IMA_WS:
- /* no per-block initialization; just start decoding the data */
while (src < buf + buf_size) {
-
- if (st) {
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
- src[0] >> 4 , 3);
- *samples++ = adpcm_ima_expand_nibble(&c->status[1],
- src[0] & 0x0F, 3);
- } else {
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
- src[0] >> 4 , 3);
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
- src[0] & 0x0F, 3);
- }
-
- src++;
+ uint8_t v = *src++;
+ *samples++ = adpcm_ima_expand_nibble(&c->status[0], v >> 4 , 3);
+ *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);
}
break;
case CODEC_ID_ADPCM_XA:
@@ -1267,55 +786,56 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
}
break;
case CODEC_ID_ADPCM_IMA_EA_EACS:
- samples_in_chunk = bytestream_get_le32(&src) >> (1-st);
-
- if (samples_in_chunk > buf_size-4-(8<<st)) {
- src += buf_size - 4;
- break;
- }
+ src += 4; // skip sample count (already read)
for (i=0; i<=st; i++)
c->status[i].step_index = bytestream_get_le32(&src);
for (i=0; i<=st; i++)
c->status[i].predictor = bytestream_get_le32(&src);
- for (; samples_in_chunk; samples_in_chunk--, src++) {
+ for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
*samples++ = adpcm_ima_expand_nibble(&c->status[0], *src>>4, 3);
*samples++ = adpcm_ima_expand_nibble(&c->status[st], *src&0x0F, 3);
}
break;
case CODEC_ID_ADPCM_IMA_EA_SEAD:
- for (; src < buf+buf_size; src++) {
+ for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
*samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] >> 4, 6);
*samples++ = adpcm_ima_expand_nibble(&c->status[st],src[0]&0x0F, 6);
}
break;
case CODEC_ID_ADPCM_EA:
- if (buf_size < 4 || AV_RL32(src) >= ((buf_size - 12) * 2)) {
- src += buf_size;
- break;
- }
- samples_in_chunk = AV_RL32(src);
- src += 4;
+ {
+ int32_t previous_left_sample, previous_right_sample;
+ int32_t current_left_sample, current_right_sample;
+ int32_t next_left_sample, next_right_sample;
+ int32_t coeff1l, coeff2l, coeff1r, coeff2r;
+ uint8_t shift_left, shift_right;
+
+ /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces,
+ each coding 28 stereo samples. */
+
+ src += 4; // skip sample count (already read)
+
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++) {
+ for (count1 = 0; count1 < nb_samples / 28; count1++) {
coeff1l = ea_adpcm_table[ *src >> 4 ];
coeff2l = ea_adpcm_table[(*src >> 4 ) + 4];
coeff1r = ea_adpcm_table[*src & 0x0F];
coeff2r = ea_adpcm_table[(*src & 0x0F) + 4];
src++;
- shift_left = (*src >> 4 ) + 8;
- shift_right = (*src & 0x0F) + 8;
+ shift_left = 20 - (*src >> 4);
+ shift_right = 20 - (*src & 0x0F);
src++;
for (count2 = 0; count2 < 28; count2++) {
- next_left_sample = (int32_t)((*src & 0xF0) << 24) >> shift_left;
- next_right_sample = (int32_t)((*src & 0x0F) << 28) >> shift_right;
+ next_left_sample = sign_extend(*src >> 4, 4) << shift_left;
+ next_right_sample = sign_extend(*src, 4) << shift_right;
src++;
next_left_sample = (next_left_sample +
@@ -1338,17 +858,21 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
src += 2; // Skip terminating 0x0000
break;
+ }
case CODEC_ID_ADPCM_EA_MAXIS_XA:
+ {
+ int coeff[2][2], shift[2];
+
for(channel = 0; channel < avctx->channels; channel++) {
for (i=0; i<2; i++)
coeff[channel][i] = ea_adpcm_table[(*src >> 4) + 4*i];
- shift[channel] = (*src & 0x0F) + 8;
+ shift[channel] = 20 - (*src & 0x0F);
src++;
}
- for (count1 = 0; count1 < (buf_size - avctx->channels) / avctx->channels; count1++) {
+ for (count1 = 0; count1 < nb_samples / 2; count1++) {
for(i = 4; i >= 0; i-=4) { /* Pairwise samples LL RR (st) or LL LL (mono) */
for(channel = 0; channel < avctx->channels; channel++) {
- int32_t sample = (int32_t)(((*(src+channel) >> i) & 0x0F) << 0x1C) >> shift[channel];
+ int32_t sample = sign_extend(src[channel] >> i, 4) << shift[channel];
sample = (sample +
c->status[channel].sample1 * coeff[channel][0] +
c->status[channel].sample2 * coeff[channel][1] + 0x80) >> 8;
@@ -1359,7 +883,10 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
}
src+=avctx->channels;
}
+ /* consume whole packet */
+ src = buf + buf_size;
break;
+ }
case CODEC_ID_ADPCM_EA_R1:
case CODEC_ID_ADPCM_EA_R2:
case CODEC_ID_ADPCM_EA_R3: {
@@ -1375,14 +902,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
uint16_t *samplesC;
const uint8_t *srcC;
const uint8_t *src_end = buf + buf_size;
+ int count = 0;
- samples_in_chunk = (big_endian ? bytestream_get_be32(&src)
- : bytestream_get_le32(&src)) / 28;
- if (samples_in_chunk > UINT32_MAX/(28*avctx->channels) ||
- 28*samples_in_chunk*avctx->channels > samples_end-samples) {
- src += buf_size - 4;
- break;
- }
+ src += 4; // skip sample count (already read)
for (channel=0; channel<avctx->channels; channel++) {
int32_t offset = (big_endian ? bytestream_get_be32(&src)
@@ -1401,7 +923,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
previous_sample = c->status[channel].prev_sample;
}
- for (count1=0; count1<samples_in_chunk; count1++) {
+ for (count1 = 0; count1 < nb_samples / 28; count1++) {
if (*srcC == 0xEE) { /* only seen in R2 and R3 */
srcC++;
if (srcC > src_end - 30*2) break;
@@ -1415,14 +937,14 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
} else {
coeff1 = ea_adpcm_table[ *srcC>>4 ];
coeff2 = ea_adpcm_table[(*srcC>>4) + 4];
- shift = (*srcC++ & 0x0F) + 8;
+ shift = 20 - (*srcC++ & 0x0F);
if (srcC > src_end - 14) break;
for (count2=0; count2<28; count2++) {
if (count2 & 1)
- next_sample = (int32_t)((*srcC++ & 0x0F) << 28) >> shift;
+ next_sample = sign_extend(*srcC++, 4) << shift;
else
- next_sample = (int32_t)((*srcC & 0xF0) << 24) >> shift;
+ next_sample = sign_extend(*srcC >> 4, 4) << shift;
next_sample += (current_sample * coeff1) +
(previous_sample * coeff2);
@@ -1435,6 +957,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
}
}
}
+ if (!count) {
+ count = count1;
+ } else if (count != count1) {
+ av_log(avctx, AV_LOG_WARNING, "per-channel sample count mismatch\n");
+ count = FFMAX(count, count1);
+ }
if (avctx->codec->id != CODEC_ID_ADPCM_EA_R1) {
c->status[channel].predictor = current_sample;
@@ -1442,23 +970,18 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
}
}
- src = src + buf_size - (4 + 4*avctx->channels);
- samples += 28 * samples_in_chunk * avctx->channels;
+ c->frame.nb_samples = count * 28;
+ src = src_end;
break;
}
case CODEC_ID_ADPCM_EA_XAS:
- if (samples_end-samples < 32*4*avctx->channels
- || buf_size < (4+15)*4*avctx->channels) {
- src += buf_size;
- break;
- }
for (channel=0; channel<avctx->channels; channel++) {
int coeff[2][4], shift[4];
short *s2, *s = &samples[channel];
for (n=0; n<4; n++, s+=32*avctx->channels) {
for (i=0; i<2; i++)
coeff[i][n] = ea_adpcm_table[(src[0]&0x0F)+4*i];
- shift[n] = (src[2]&0x0F) + 8;
+ shift[n] = 20 - (src[2] & 0x0F);
for (s2=s, i=0; i<2; i++, src+=2, s2+=avctx->channels)
s2[0] = (src[0]&0xF0) + (src[1]<<8);
}
@@ -1467,7 +990,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
s = &samples[m*avctx->channels + channel];
for (n=0; n<4; n++, src++, s+=32*avctx->channels) {
for (s2=s, i=0; i<8; i+=4, s2+=avctx->channels) {
- int level = (int32_t)((*src & (0xF0>>i)) << (24+i)) >> shift[n];
+ int level = sign_extend(*src >> (4 - i), 4) << shift[n];
int pred = s2[-1*avctx->channels] * coeff[0][n]
+ s2[-2*avctx->channels] * coeff[1][n];
s2[0] = av_clip_int16((level + pred + 0x80) >> 8);
@@ -1475,17 +998,20 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
}
}
}
- samples += 32*4*avctx->channels;
break;
case CODEC_ID_ADPCM_IMA_AMV:
case CODEC_ID_ADPCM_IMA_SMJPEG:
- c->status[0].predictor = (int16_t)bytestream_get_le16(&src);
- c->status[0].step_index = bytestream_get_le16(&src);
-
- if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV)
- src+=4;
+ if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV) {
+ c->status[0].predictor = sign_extend(bytestream_get_le16(&src), 16);
+ c->status[0].step_index = bytestream_get_le16(&src);
+ src += 4;
+ } else {
+ c->status[0].predictor = sign_extend(bytestream_get_be16(&src), 16);
+ c->status[0].step_index = bytestream_get_byte(&src);
+ src += 1;
+ }
- while (src < buf + buf_size) {
+ for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
char hi, lo;
lo = *src & 0x0F;
hi = *src >> 4;
@@ -1497,23 +1023,13 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
lo, 3);
*samples++ = adpcm_ima_expand_nibble(&c->status[0],
hi, 3);
- src++;
}
break;
case CODEC_ID_ADPCM_CT:
- while (src < buf + buf_size) {
- if (st) {
- *samples++ = adpcm_ct_expand_nibble(&c->status[0],
- src[0] >> 4);
- *samples++ = adpcm_ct_expand_nibble(&c->status[1],
- src[0] & 0x0F);
- } else {
- *samples++ = adpcm_ct_expand_nibble(&c->status[0],
- src[0] >> 4);
- *samples++ = adpcm_ct_expand_nibble(&c->status[0],
- src[0] & 0x0F);
- }
- src++;
+ for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
+ uint8_t v = *src;
+ *samples++ = adpcm_ct_expand_nibble(&c->status[0 ], v >> 4 );
+ *samples++ = adpcm_ct_expand_nibble(&c->status[st], v & 0x0F);
}
break;
case CODEC_ID_ADPCM_SBPRO_4:
@@ -1525,27 +1041,26 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
if (st)
*samples++ = 128 * (*src++ - 0x80);
c->status[0].step_index = 1;
+ nb_samples--;
}
if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_4) {
- while (src < buf + buf_size) {
+ for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
src[0] >> 4, 4, 0);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[st],
src[0] & 0x0F, 4, 0);
- src++;
}
} else if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_3) {
- while (src < buf + buf_size && samples + 2 < samples_end) {
+ for (n = nb_samples / 3; n > 0; n--, src++) {
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
src[0] >> 5 , 3, 0);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
(src[0] >> 2) & 0x07, 3, 0);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
src[0] & 0x03, 2, 0);
- src++;
}
} else {
- while (src < buf + buf_size && samples + 3 < samples_end) {
+ for (n = nb_samples >> (2 - st); n > 0; n--, src++) {
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
src[0] >> 6 , 2, 2);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[st],
@@ -1554,7 +1069,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
(src[0] >> 2) & 0x03, 2, 2);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[st],
src[0] & 0x03, 2, 2);
- src++;
}
}
break;
@@ -1586,7 +1100,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
for (i = 0; i < avctx->channels; i++) {
// similar to IMA adpcm
int delta = get_bits(&gb, nb_bits);
- int step = step_table[c->status[i].step_index];
+ int step = ff_adpcm_step_table[c->status[i].step_index];
long vpdiff = 0; // vpdiff = (delta+0.5)*step/4
int k = k0;
@@ -1609,10 +1123,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
c->status[i].predictor = av_clip_int16(c->status[i].predictor);
*samples++ = c->status[i].predictor;
- if (samples >= samples_end) {
- av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n");
- return -1;
- }
}
}
}
@@ -1620,35 +1130,20 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
break;
}
case CODEC_ID_ADPCM_YAMAHA:
- while (src < buf + buf_size) {
- if (st) {
- *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
- src[0] & 0x0F);
- *samples++ = adpcm_yamaha_expand_nibble(&c->status[1],
- src[0] >> 4 );
- } else {
- *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
- src[0] & 0x0F);
- *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
- src[0] >> 4 );
- }
- src++;
+ for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
+ uint8_t v = *src;
+ *samples++ = adpcm_yamaha_expand_nibble(&c->status[0 ], v & 0x0F);
+ *samples++ = adpcm_yamaha_expand_nibble(&c->status[st], v >> 4 );
}
break;
case CODEC_ID_ADPCM_THP:
{
int table[2][16];
- unsigned int samplecnt;
int prev[2][2];
int ch;
- if (buf_size < 80) {
- av_log(avctx, AV_LOG_ERROR, "frame too small\n");
- return -1;
- }
-
- src+=4;
- samplecnt = bytestream_get_be32(&src);
+ src += 4; // skip channel size
+ src += 4; // skip number of samples (already read)
for (i = 0; i < 32; i++)
table[0][i] = (int16_t)bytestream_get_be16(&src);
@@ -1657,29 +1152,24 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
for (i = 0; i < 4; i++)
prev[0][i] = (int16_t)bytestream_get_be16(&src);
- if (samplecnt >= (samples_end - samples) / (st + 1)) {
- av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n");
- return -1;
- }
-
for (ch = 0; ch <= st; ch++) {
- samples = (unsigned short *) data + ch;
+ samples = (short *)c->frame.data[0] + ch;
/* Read in every sample for this channel. */
- for (i = 0; i < samplecnt / 14; i++) {
+ for (i = 0; i < nb_samples / 14; i++) {
int index = (*src >> 4) & 7;
- unsigned int exp = 28 - (*src++ & 15);
+ unsigned int exp = *src++ & 15;
int factor1 = table[ch][index * 2];
int factor2 = table[ch][index * 2 + 1];
/* Decode 14 samples. */
for (n = 0; n < 14; n++) {
int32_t sampledat;
- if(n&1) sampledat= *src++ <<28;
- else sampledat= (*src&0xF0)<<24;
+ if(n&1) sampledat = sign_extend(*src++, 4);
+ else sampledat = sign_extend(*src >> 4, 4);
sampledat = ((prev[ch][0]*factor1
- + prev[ch][1]*factor2) >> 11) + (sampledat>>exp);
+ + prev[ch][1]*factor2) >> 11) + (sampledat << exp);
*samples = av_clip_int16(sampledat);
prev[ch][1] = prev[ch][0];
prev[ch][0] = *samples++;
@@ -1690,59 +1180,31 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
}
}
}
-
- /* In the previous loop, in case stereo is used, samples is
- increased exactly one time too often. */
- samples -= st;
break;
}
default:
return -1;
}
- *data_size = (uint8_t *)samples - (uint8_t *)data;
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = c->frame;
+
return src - buf;
}
-
-#if CONFIG_ENCODERS
-#define ADPCM_ENCODER(id,name,long_name_) \
-AVCodec ff_ ## name ## _encoder = { \
- #name, \
- AVMEDIA_TYPE_AUDIO, \
- id, \
- sizeof(ADPCMContext), \
- adpcm_encode_init, \
- adpcm_encode_frame, \
- adpcm_encode_close, \
- NULL, \
- .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, \
- .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+#define ADPCM_DECODER(id_, name_, long_name_) \
+AVCodec ff_ ## name_ ## _decoder = { \
+ .name = #name_, \
+ .type = AVMEDIA_TYPE_AUDIO, \
+ .id = id_, \
+ .priv_data_size = sizeof(ADPCMDecodeContext), \
+ .init = adpcm_decode_init, \
+ .decode = adpcm_decode_frame, \
+ .capabilities = CODEC_CAP_DR1, \
+ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
}
-#else
-#define ADPCM_ENCODER(id,name,long_name_)
-#endif
-
-#if CONFIG_DECODERS
-#define ADPCM_DECODER(id,name,long_name_) \
-AVCodec ff_ ## name ## _decoder = { \
- #name, \
- AVMEDIA_TYPE_AUDIO, \
- id, \
- sizeof(ADPCMContext), \
- adpcm_decode_init, \
- NULL, \
- NULL, \
- adpcm_decode_frame, \
- .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
-}
-#else
-#define ADPCM_DECODER(id,name,long_name_)
-#endif
-
-#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, "ADPCM 4X Movie");
@@ -1759,15 +1221,15 @@ ADPCM_DECODER(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4, "ADPCM IMA Duck DK4");
ADPCM_DECODER(CODEC_ID_ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs, "ADPCM IMA Electronic Arts EACS");
ADPCM_DECODER(CODEC_ID_ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead, "ADPCM IMA Electronic Arts SEAD");
ADPCM_DECODER(CODEC_ID_ADPCM_IMA_ISS, adpcm_ima_iss, "ADPCM IMA Funcom ISS");
-ADPCM_CODEC (CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, "ADPCM IMA QuickTime");
+ADPCM_DECODER(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, "ADPCM IMA QuickTime");
ADPCM_DECODER(CODEC_ID_ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG");
-ADPCM_CODEC (CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, "ADPCM IMA WAV");
+ADPCM_DECODER(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, "ADPCM IMA WAV");
ADPCM_DECODER(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws, "ADPCM IMA Westwood");
-ADPCM_CODEC (CODEC_ID_ADPCM_MS, adpcm_ms, "ADPCM Microsoft");
+ADPCM_DECODER(CODEC_ID_ADPCM_MS, adpcm_ms, "ADPCM Microsoft");
ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2, "ADPCM Sound Blaster Pro 2-bit");
ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3, "ADPCM Sound Blaster Pro 2.6-bit");
ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4, "ADPCM Sound Blaster Pro 4-bit");
-ADPCM_CODEC (CODEC_ID_ADPCM_SWF, adpcm_swf, "ADPCM Shockwave Flash");
+ADPCM_DECODER(CODEC_ID_ADPCM_SWF, adpcm_swf, "ADPCM Shockwave Flash");
ADPCM_DECODER(CODEC_ID_ADPCM_THP, adpcm_thp, "ADPCM Nintendo Gamecube THP");
ADPCM_DECODER(CODEC_ID_ADPCM_XA, adpcm_xa, "ADPCM CDROM XA");
-ADPCM_CODEC (CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, "ADPCM Yamaha");
+ADPCM_DECODER(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, "ADPCM Yamaha");
diff --git a/libavcodec/adpcm.h b/libavcodec/adpcm.h
new file mode 100644
index 0000000..aed5048
--- /dev/null
+++ b/libavcodec/adpcm.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2001-2003 The ffmpeg Project
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * ADPCM encoder/decoder common header.
+ */
+
+#ifndef AVCODEC_ADPCM_H
+#define AVCODEC_ADPCM_H
+
+#define BLKSIZE 1024
+
+typedef struct ADPCMChannelStatus {
+ int predictor;
+ short int step_index;
+ int step;
+ /* for encoding */
+ int prev_sample;
+
+ /* MS version */
+ short sample1;
+ short sample2;
+ int coeff1;
+ int coeff2;
+ int idelta;
+} ADPCMChannelStatus;
+
+#endif /* AVCODEC_ADPCM_H */
diff --git a/libavcodec/adpcm_data.c b/libavcodec/adpcm_data.c
new file mode 100644
index 0000000..3bc5de2
--- /dev/null
+++ b/libavcodec/adpcm_data.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2003 The ffmpeg Project
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * ADPCM tables
+ */
+
+#include <stdint.h>
+
+/* ff_adpcm_step_table[] and ff_adpcm_index_table[] are from the ADPCM
+ reference source */
+/* This is the index table: */
+const int8_t ff_adpcm_index_table[16] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8,
+};
+
+/**
+ * This is the step table. Note that many programs use slight deviations from
+ * this table, but such deviations are negligible:
+ */
+const int16_t ff_adpcm_step_table[89] = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
+/* These are for MS-ADPCM */
+/* ff_adpcm_AdaptationTable[], ff_adpcm_AdaptCoeff1[], and
+ ff_adpcm_AdaptCoeff2[] are from libsndfile */
+const int16_t ff_adpcm_AdaptationTable[] = {
+ 230, 230, 230, 230, 307, 409, 512, 614,
+ 768, 614, 512, 409, 307, 230, 230, 230
+};
+
+/** Divided by 4 to fit in 8-bit integers */
+const uint8_t ff_adpcm_AdaptCoeff1[] = {
+ 64, 128, 0, 48, 60, 115, 98
+};
+
+/** Divided by 4 to fit in 8-bit integers */
+const int8_t ff_adpcm_AdaptCoeff2[] = {
+ 0, -64, 0, 16, 0, -52, -58
+};
+
+const int16_t ff_adpcm_yamaha_indexscale[] = {
+ 230, 230, 230, 230, 307, 409, 512, 614,
+ 230, 230, 230, 230, 307, 409, 512, 614
+};
+
+const int8_t ff_adpcm_yamaha_difflookup[] = {
+ 1, 3, 5, 7, 9, 11, 13, 15,
+ -1, -3, -5, -7, -9, -11, -13, -15
+};
diff --git a/libavcodec/adpcm_data.h b/libavcodec/adpcm_data.h
new file mode 100644
index 0000000..a46cb5b
--- /dev/null
+++ b/libavcodec/adpcm_data.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2001-2003 The ffmpeg Project
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * ADPCM tables
+ */
+
+#ifndef AVCODEC_ADPCM_DATA_H
+#define AVCODEC_ADPCM_DATA_H
+
+#include <stdint.h>
+
+extern const int8_t ff_adpcm_index_table[16];
+extern const int16_t ff_adpcm_step_table[89];
+extern const int16_t ff_adpcm_AdaptationTable[];
+extern const uint8_t ff_adpcm_AdaptCoeff1[];
+extern const int8_t ff_adpcm_AdaptCoeff2[];
+extern const int16_t ff_adpcm_yamaha_indexscale[];
+extern const int8_t ff_adpcm_yamaha_difflookup[];
+
+#endif /* AVCODEC_ADPCM_DATA_H */
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c
new file mode 100644
index 0000000..9697f82
--- /dev/null
+++ b/libavcodec/adpcmenc.c
@@ -0,0 +1,716 @@
+/*
+ * Copyright (c) 2001-2003 The ffmpeg Project
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "put_bits.h"
+#include "bytestream.h"
+#include "adpcm.h"
+#include "adpcm_data.h"
+
+/**
+ * @file
+ * ADPCM encoders
+ * First version by Francois Revol (revol at free.fr)
+ * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
+ * by Mike Melanson (melanson at pcisys.net)
+ *
+ * See ADPCM decoder reference documents for codec information.
+ */
+
+typedef struct TrellisPath {
+ int nibble;
+ int prev;
+} TrellisPath;
+
+typedef struct TrellisNode {
+ uint32_t ssd;
+ int path;
+ int sample1;
+ int sample2;
+ int step;
+} TrellisNode;
+
+typedef struct ADPCMEncodeContext {
+ ADPCMChannelStatus status[6];
+ TrellisPath *paths;
+ TrellisNode *node_buf;
+ TrellisNode **nodep_buf;
+ uint8_t *trellis_hash;
+} ADPCMEncodeContext;
+
+#define FREEZE_INTERVAL 128
+
+static av_cold int adpcm_encode_init(AVCodecContext *avctx)
+{
+ ADPCMEncodeContext *s = avctx->priv_data;
+ uint8_t *extradata;
+ int i;
+ if (avctx->channels > 2)
+ return -1; /* only stereo or mono =) */
+
+ if (avctx->trellis && (unsigned)avctx->trellis > 16U) {
+ av_log(avctx, AV_LOG_ERROR, "invalid trellis size\n");
+ return -1;
+ }
+
+ if (avctx->trellis) {
+ int frontier = 1 << avctx->trellis;
+ int max_paths = frontier * FREEZE_INTERVAL;
+ FF_ALLOC_OR_GOTO(avctx, s->paths,
+ max_paths * sizeof(*s->paths), error);
+ FF_ALLOC_OR_GOTO(avctx, s->node_buf,
+ 2 * frontier * sizeof(*s->node_buf), error);
+ FF_ALLOC_OR_GOTO(avctx, s->nodep_buf,
+ 2 * frontier * sizeof(*s->nodep_buf), error);
+ FF_ALLOC_OR_GOTO(avctx, s->trellis_hash,
+ 65536 * sizeof(*s->trellis_hash), error);
+ }
+
+ avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id);
+
+ switch (avctx->codec->id) {
+ case CODEC_ID_ADPCM_IMA_WAV:
+ /* each 16 bits sample gives one nibble
+ and we have 4 bytes per channel overhead */
+ avctx->frame_size = (BLKSIZE - 4 * avctx->channels) * 8 /
+ (4 * avctx->channels) + 1;
+ /* seems frame_size isn't taken into account...
+ have to buffer the samples :-( */
+ avctx->block_align = BLKSIZE;
+ break;
+ case CODEC_ID_ADPCM_IMA_QT:
+ avctx->frame_size = 64;
+ avctx->block_align = 34 * avctx->channels;
+ break;
+ case CODEC_ID_ADPCM_MS:
+ /* each 16 bits sample gives one nibble
+ and we have 7 bytes per channel overhead */
+ avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 /
+ avctx->channels + 2;
+ avctx->block_align = BLKSIZE;
+ avctx->extradata_size = 32;
+ extradata = avctx->extradata = av_malloc(avctx->extradata_size);
+ if (!extradata)
+ return AVERROR(ENOMEM);
+ bytestream_put_le16(&extradata, avctx->frame_size);
+ bytestream_put_le16(&extradata, 7); /* wNumCoef */
+ for (i = 0; i < 7; i++) {
+ bytestream_put_le16(&extradata, ff_adpcm_AdaptCoeff1[i] * 4);
+ bytestream_put_le16(&extradata, ff_adpcm_AdaptCoeff2[i] * 4);
+ }
+ break;
+ case CODEC_ID_ADPCM_YAMAHA:
+ avctx->frame_size = BLKSIZE * avctx->channels;
+ avctx->block_align = BLKSIZE;
+ break;
+ case CODEC_ID_ADPCM_SWF:
+ if (avctx->sample_rate != 11025 &&
+ avctx->sample_rate != 22050 &&
+ avctx->sample_rate != 44100) {
+ av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, "
+ "22050 or 44100\n");
+ goto error;
+ }
+ avctx->frame_size = 512 * (avctx->sample_rate / 11025);
+ break;
+ default:
+ goto error;
+ }
+
+ avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame->key_frame= 1;
+
+ return 0;
+error:
+ av_freep(&s->paths);
+ av_freep(&s->node_buf);
+ av_freep(&s->nodep_buf);
+ av_freep(&s->trellis_hash);
+ return -1;
+}
+
+static av_cold int adpcm_encode_close(AVCodecContext *avctx)
+{
+ ADPCMEncodeContext *s = avctx->priv_data;
+ av_freep(&avctx->coded_frame);
+ av_freep(&s->paths);
+ av_freep(&s->node_buf);
+ av_freep(&s->nodep_buf);
+ av_freep(&s->trellis_hash);
+
+ return 0;
+}
+
+
+static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c,
+ short sample)
+{
+ int delta = sample - c->prev_sample;
+ int nibble = FFMIN(7, abs(delta) * 4 /
+ ff_adpcm_step_table[c->step_index]) + (delta < 0) * 8;
+ c->prev_sample += ((ff_adpcm_step_table[c->step_index] *
+ ff_adpcm_yamaha_difflookup[nibble]) / 8);
+ c->prev_sample = av_clip_int16(c->prev_sample);
+ c->step_index = av_clip(c->step_index + ff_adpcm_index_table[nibble], 0, 88);
+ return nibble;
+}
+
+static inline unsigned char adpcm_ima_qt_compress_sample(ADPCMChannelStatus *c,
+ short sample)
+{
+ int delta = sample - c->prev_sample;
+ int mask, step = ff_adpcm_step_table[c->step_index];
+ int diff = step >> 3;
+ int nibble = 0;
+
+ if (delta < 0) {
+ nibble = 8;
+ delta = -delta;
+ }
+
+ for (mask = 4; mask;) {
+ if (delta >= step) {
+ nibble |= mask;
+ delta -= step;
+ diff += step;
+ }
+ step >>= 1;
+ mask >>= 1;
+ }
+
+ if (nibble & 8)
+ c->prev_sample -= diff;
+ else
+ c->prev_sample += diff;
+
+ c->prev_sample = av_clip_int16(c->prev_sample);
+ c->step_index = av_clip(c->step_index + ff_adpcm_index_table[nibble], 0, 88);
+
+ return nibble;
+}
+
+static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c,
+ short sample)
+{
+ int predictor, nibble, bias;
+
+ predictor = (((c->sample1) * (c->coeff1)) +
+ (( c->sample2) * (c->coeff2))) / 64;
+
+ nibble = sample - predictor;
+ if (nibble >= 0)
+ bias = c->idelta / 2;
+ else
+ bias = -c->idelta / 2;
+
+ nibble = (nibble + bias) / c->idelta;
+ nibble = av_clip(nibble, -8, 7) & 0x0F;
+
+ predictor += (signed)((nibble & 0x08) ? (nibble - 0x10) : nibble) * c->idelta;
+
+ c->sample2 = c->sample1;
+ c->sample1 = av_clip_int16(predictor);
+
+ c->idelta = (ff_adpcm_AdaptationTable[(int)nibble] * c->idelta) >> 8;
+ if (c->idelta < 16)
+ c->idelta = 16;
+
+ return nibble;
+}
+
+static inline unsigned char adpcm_yamaha_compress_sample(ADPCMChannelStatus *c,
+ short sample)
+{
+ int nibble, delta;
+
+ if (!c->step) {
+ c->predictor = 0;
+ c->step = 127;
+ }
+
+ delta = sample - c->predictor;
+
+ nibble = FFMIN(7, abs(delta) * 4 / c->step) + (delta < 0) * 8;
+
+ c->predictor += ((c->step * ff_adpcm_yamaha_difflookup[nibble]) / 8);
+ c->predictor = av_clip_int16(c->predictor);
+ c->step = (c->step * ff_adpcm_yamaha_indexscale[nibble]) >> 8;
+ c->step = av_clip(c->step, 127, 24567);
+
+ return nibble;
+}
+
+static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples,
+ uint8_t *dst, ADPCMChannelStatus *c, int n)
+{
+ //FIXME 6% faster if frontier is a compile-time constant
+ ADPCMEncodeContext *s = avctx->priv_data;
+ const int frontier = 1 << avctx->trellis;
+ const int stride = avctx->channels;
+ const int version = avctx->codec->id;
+ TrellisPath *paths = s->paths, *p;
+ TrellisNode *node_buf = s->node_buf;
+ TrellisNode **nodep_buf = s->nodep_buf;
+ TrellisNode **nodes = nodep_buf; // nodes[] is always sorted by .ssd
+ TrellisNode **nodes_next = nodep_buf + frontier;
+ int pathn = 0, froze = -1, i, j, k, generation = 0;
+ uint8_t *hash = s->trellis_hash;
+ memset(hash, 0xff, 65536 * sizeof(*hash));
+
+ memset(nodep_buf, 0, 2 * frontier * sizeof(*nodep_buf));
+ nodes[0] = node_buf + frontier;
+ nodes[0]->ssd = 0;
+ nodes[0]->path = 0;
+ nodes[0]->step = c->step_index;
+ nodes[0]->sample1 = c->sample1;
+ nodes[0]->sample2 = c->sample2;
+ if (version == CODEC_ID_ADPCM_IMA_WAV ||
+ version == CODEC_ID_ADPCM_IMA_QT ||
+ version == CODEC_ID_ADPCM_SWF)
+ nodes[0]->sample1 = c->prev_sample;
+ if (version == CODEC_ID_ADPCM_MS)
+ nodes[0]->step = c->idelta;
+ if (version == CODEC_ID_ADPCM_YAMAHA) {
+ if (c->step == 0) {
+ nodes[0]->step = 127;
+ nodes[0]->sample1 = 0;
+ } else {
+ nodes[0]->step = c->step;
+ nodes[0]->sample1 = c->predictor;
+ }
+ }
+
+ for (i = 0; i < n; i++) {
+ TrellisNode *t = node_buf + frontier*(i&1);
+ TrellisNode **u;
+ int sample = samples[i * stride];
+ int heap_pos = 0;
+ memset(nodes_next, 0, frontier * sizeof(TrellisNode*));
+ for (j = 0; j < frontier && nodes[j]; j++) {
+ // higher j have higher ssd already, so they're likely
+ // to yield a suboptimal next sample too
+ const int range = (j < frontier / 2) ? 1 : 0;
+ 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)) / 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);
+ for (nidx = nmin; nidx <= nmax; nidx++) {
+ const int nibble = nidx & 0xf;
+ int dec_sample = predictor + nidx * step;
+#define STORE_NODE(NAME, STEP_INDEX)\
+ int d;\
+ uint32_t ssd;\
+ int pos;\
+ TrellisNode *u;\
+ uint8_t *h;\
+ dec_sample = av_clip_int16(dec_sample);\
+ d = sample - dec_sample;\
+ ssd = nodes[j]->ssd + d*d;\
+ /* Check for wraparound, skip such samples completely. \
+ * Note, changing ssd to a 64 bit variable would be \
+ * simpler, avoiding this check, but it's slower on \
+ * x86 32 bit at the moment. */\
+ if (ssd < nodes[j]->ssd)\
+ goto next_##NAME;\
+ /* Collapse any two states with the same previous sample value. \
+ * One could also distinguish states by step and by 2nd to last
+ * sample, but the effects of that are negligible.
+ * Since nodes in the previous generation are iterated
+ * through a heap, they're roughly ordered from better to
+ * worse, but not strictly ordered. Therefore, an earlier
+ * node with the same sample value is better in most cases
+ * (and thus the current is skipped), but not strictly
+ * in all cases. Only skipping samples where ssd >=
+ * ssd of the earlier node with the same sample gives
+ * slightly worse quality, though, for some reason. */ \
+ h = &hash[(uint16_t) dec_sample];\
+ if (*h == generation)\
+ goto next_##NAME;\
+ if (heap_pos < frontier) {\
+ pos = heap_pos++;\
+ } else {\
+ /* Try to replace one of the leaf nodes with the new \
+ * one, but try a different slot each time. */\
+ pos = (frontier >> 1) +\
+ (heap_pos & ((frontier >> 1) - 1));\
+ if (ssd > nodes_next[pos]->ssd)\
+ goto next_##NAME;\
+ heap_pos++;\
+ }\
+ *h = generation;\
+ u = nodes_next[pos];\
+ if (!u) {\
+ assert(pathn < FREEZE_INTERVAL << avctx->trellis);\
+ u = t++;\
+ nodes_next[pos] = u;\
+ u->path = pathn++;\
+ }\
+ u->ssd = ssd;\
+ u->step = STEP_INDEX;\
+ u->sample2 = nodes[j]->sample1;\
+ u->sample1 = dec_sample;\
+ paths[u->path].nibble = nibble;\
+ paths[u->path].prev = nodes[j]->path;\
+ /* Sift the newly inserted node up in the heap to \
+ * restore the heap property. */\
+ while (pos > 0) {\
+ int parent = (pos - 1) >> 1;\
+ if (nodes_next[parent]->ssd <= ssd)\
+ break;\
+ FFSWAP(TrellisNode*, nodes_next[parent], nodes_next[pos]);\
+ pos = parent;\
+ }\
+ next_##NAME:;
+ STORE_NODE(ms, FFMAX(16,
+ (ff_adpcm_AdaptationTable[nibble] * step) >> 8));
+ }
+ } else if (version == CODEC_ID_ADPCM_IMA_WAV ||
+ version == CODEC_ID_ADPCM_IMA_QT ||
+ version == CODEC_ID_ADPCM_SWF) {
+#define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\
+ const int predictor = nodes[j]->sample1;\
+ const int div = (sample - predictor) * 4 / STEP_TABLE;\
+ int nmin = av_clip(div - range, -7, 6);\
+ int nmax = av_clip(div + range, -6, 7);\
+ if (nmin <= 0)\
+ nmin--; /* distinguish -0 from +0 */\
+ if (nmax < 0)\
+ nmax--;\
+ for (nidx = nmin; nidx <= nmax; nidx++) {\
+ const int nibble = nidx < 0 ? 7 - nidx : nidx;\
+ int dec_sample = predictor +\
+ (STEP_TABLE *\
+ ff_adpcm_yamaha_difflookup[nibble]) / 8;\
+ STORE_NODE(NAME, STEP_INDEX);\
+ }
+ LOOP_NODES(ima, ff_adpcm_step_table[step],
+ av_clip(step + ff_adpcm_index_table[nibble], 0, 88));
+ } else { //CODEC_ID_ADPCM_YAMAHA
+ LOOP_NODES(yamaha, step,
+ av_clip((step * ff_adpcm_yamaha_indexscale[nibble]) >> 8,
+ 127, 24567));
+#undef LOOP_NODES
+#undef STORE_NODE
+ }
+ }
+
+ u = nodes;
+ nodes = nodes_next;
+ nodes_next = u;
+
+ generation++;
+ if (generation == 255) {
+ memset(hash, 0xff, 65536 * sizeof(*hash));
+ generation = 0;
+ }
+
+ // prevent overflow
+ if (nodes[0]->ssd > (1 << 28)) {
+ for (j = 1; j < frontier && nodes[j]; j++)
+ nodes[j]->ssd -= nodes[0]->ssd;
+ nodes[0]->ssd = 0;
+ }
+
+ // merge old paths to save memory
+ if (i == froze + FREEZE_INTERVAL) {
+ p = &paths[nodes[0]->path];
+ for (k = i; k > froze; k--) {
+ dst[k] = p->nibble;
+ p = &paths[p->prev];
+ }
+ froze = i;
+ pathn = 0;
+ // other nodes might use paths that don't coincide with the frozen one.
+ // checking which nodes do so is too slow, so just kill them all.
+ // this also slightly improves quality, but I don't know why.
+ memset(nodes + 1, 0, (frontier - 1) * sizeof(TrellisNode*));
+ }
+ }
+
+ p = &paths[nodes[0]->path];
+ for (i = n - 1; i > froze; i--) {
+ dst[i] = p->nibble;
+ p = &paths[p->prev];
+ }
+
+ c->predictor = nodes[0]->sample1;
+ c->sample1 = nodes[0]->sample1;
+ c->sample2 = nodes[0]->sample2;
+ c->step_index = nodes[0]->step;
+ c->step = nodes[0]->step;
+ c->idelta = nodes[0]->step;
+}
+
+static int adpcm_encode_frame(AVCodecContext *avctx,
+ unsigned char *frame, int buf_size, void *data)
+{
+ int n, i, st;
+ short *samples;
+ unsigned char *dst;
+ ADPCMEncodeContext *c = avctx->priv_data;
+ uint8_t *buf;
+
+ dst = frame;
+ samples = (short *)data;
+ st = avctx->channels == 2;
+ /* n = (BLKSIZE - 4 * avctx->channels) / (2 * 8 * avctx->channels); */
+
+ switch(avctx->codec->id) {
+ case CODEC_ID_ADPCM_IMA_WAV:
+ n = avctx->frame_size / 8;
+ c->status[0].prev_sample = (signed short)samples[0]; /* XXX */
+ /* c->status[0].step_index = 0;
+ XXX: not sure how to init the state machine */
+ bytestream_put_le16(&dst, c->status[0].prev_sample);
+ *dst++ = (unsigned char)c->status[0].step_index;
+ *dst++ = 0; /* unknown */
+ samples++;
+ if (avctx->channels == 2) {
+ c->status[1].prev_sample = (signed short)samples[0];
+ /* c->status[1].step_index = 0; */
+ bytestream_put_le16(&dst, c->status[1].prev_sample);
+ *dst++ = (unsigned char)c->status[1].step_index;
+ *dst++ = 0;
+ samples++;
+ }
+
+ /* stereo: 4 bytes (8 samples) for left,
+ 4 bytes for right, 4 bytes left, ... */
+ if (avctx->trellis > 0) {
+ FF_ALLOC_OR_GOTO(avctx, buf, 2 * n * 8, error);
+ adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n * 8);
+ if (avctx->channels == 2)
+ adpcm_compress_trellis(avctx, samples + 1, buf + n * 8,
+ &c->status[1], n * 8);
+ for (i = 0; i < n; i++) {
+ *dst++ = buf[8 * i + 0] | (buf[8 * i + 1] << 4);
+ *dst++ = buf[8 * i + 2] | (buf[8 * i + 3] << 4);
+ *dst++ = buf[8 * i + 4] | (buf[8 * i + 5] << 4);
+ *dst++ = buf[8 * i + 6] | (buf[8 * i + 7] << 4);
+ if (avctx->channels == 2) {
+ uint8_t *buf1 = buf + n * 8;
+ *dst++ = buf1[8 * i + 0] | (buf1[8 * i + 1] << 4);
+ *dst++ = buf1[8 * i + 2] | (buf1[8 * i + 3] << 4);
+ *dst++ = buf1[8 * i + 4] | (buf1[8 * i + 5] << 4);
+ *dst++ = buf1[8 * i + 6] | (buf1[8 * i + 7] << 4);
+ }
+ }
+ av_free(buf);
+ } else {
+ for (; n > 0; n--) {
+ *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]);
+ *dst++ |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels ]) << 4;
+ *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]);
+ *dst++ |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4;
+ *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]);
+ *dst++ |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4;
+ *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]);
+ *dst++ |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4;
+ /* right channel */
+ if (avctx->channels == 2) {
+ *dst = adpcm_ima_compress_sample(&c->status[1], samples[1 ]);
+ *dst++ |= adpcm_ima_compress_sample(&c->status[1], samples[3 ]) << 4;
+ *dst = adpcm_ima_compress_sample(&c->status[1], samples[5 ]);
+ *dst++ |= adpcm_ima_compress_sample(&c->status[1], samples[7 ]) << 4;
+ *dst = adpcm_ima_compress_sample(&c->status[1], samples[9 ]);
+ *dst++ |= adpcm_ima_compress_sample(&c->status[1], samples[11]) << 4;
+ *dst = adpcm_ima_compress_sample(&c->status[1], samples[13]);
+ *dst++ |= adpcm_ima_compress_sample(&c->status[1], samples[15]) << 4;
+ }
+ samples += 8 * avctx->channels;
+ }
+ }
+ break;
+ case CODEC_ID_ADPCM_IMA_QT:
+ {
+ int ch, i;
+ PutBitContext pb;
+ init_put_bits(&pb, dst, buf_size * 8);
+
+ for (ch = 0; ch < avctx->channels; ch++) {
+ put_bits(&pb, 9, (c->status[ch].prev_sample + 0x10000) >> 7);
+ put_bits(&pb, 7, c->status[ch].step_index);
+ if (avctx->trellis > 0) {
+ uint8_t buf[64];
+ adpcm_compress_trellis(avctx, samples+ch, buf, &c->status[ch], 64);
+ for (i = 0; i < 64; i++)
+ put_bits(&pb, 4, buf[i ^ 1]);
+ } else {
+ for (i = 0; i < 64; i += 2) {
+ int t1, t2;
+ t1 = adpcm_ima_qt_compress_sample(&c->status[ch],
+ samples[avctx->channels * (i + 0) + ch]);
+ t2 = adpcm_ima_qt_compress_sample(&c->status[ch],
+ samples[avctx->channels * (i + 1) + ch]);
+ put_bits(&pb, 4, t2);
+ put_bits(&pb, 4, t1);
+ }
+ }
+ }
+
+ flush_put_bits(&pb);
+ dst += put_bits_count(&pb) >> 3;
+ break;
+ }
+ case CODEC_ID_ADPCM_SWF:
+ {
+ int i;
+ PutBitContext pb;
+ init_put_bits(&pb, dst, buf_size * 8);
+
+ n = avctx->frame_size - 1;
+
+ // store AdpcmCodeSize
+ put_bits(&pb, 2, 2); // set 4-bit flash adpcm format
+
+ // init the encoder state
+ for (i = 0; i < avctx->channels; i++) {
+ // clip step so it fits 6 bits
+ c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63);
+ put_sbits(&pb, 16, samples[i]);
+ put_bits(&pb, 6, c->status[i].step_index);
+ c->status[i].prev_sample = (signed short)samples[i];
+ }
+
+ if (avctx->trellis > 0) {
+ FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error);
+ adpcm_compress_trellis(avctx, samples + 2, buf, &c->status[0], n);
+ if (avctx->channels == 2)
+ adpcm_compress_trellis(avctx, samples + 3, buf + n,
+ &c->status[1], n);
+ for (i = 0; i < n; i++) {
+ put_bits(&pb, 4, buf[i]);
+ if (avctx->channels == 2)
+ put_bits(&pb, 4, buf[n + i]);
+ }
+ av_free(buf);
+ } else {
+ for (i = 1; i < avctx->frame_size; i++) {
+ put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0],
+ samples[avctx->channels * i]));
+ if (avctx->channels == 2)
+ put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1],
+ samples[2 * i + 1]));
+ }
+ }
+ flush_put_bits(&pb);
+ dst += put_bits_count(&pb) >> 3;
+ break;
+ }
+ case CODEC_ID_ADPCM_MS:
+ for (i = 0; i < avctx->channels; i++) {
+ int predictor = 0;
+ *dst++ = predictor;
+ c->status[i].coeff1 = ff_adpcm_AdaptCoeff1[predictor];
+ c->status[i].coeff2 = ff_adpcm_AdaptCoeff2[predictor];
+ }
+ for (i = 0; i < avctx->channels; i++) {
+ if (c->status[i].idelta < 16)
+ c->status[i].idelta = 16;
+ 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++)
+ bytestream_put_le16(&dst, c->status[i].sample2);
+
+ if (avctx->trellis > 0) {
+ int n = avctx->block_align - 7 * avctx->channels;
+ FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error);
+ if (avctx->channels == 1) {
+ adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
+ for (i = 0; i < n; i += 2)
+ *dst++ = (buf[i] << 4) | buf[i + 1];
+ } else {
+ adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
+ adpcm_compress_trellis(avctx, samples + 1, buf + n, &c->status[1], n);
+ for (i = 0; i < n; i++)
+ *dst++ = (buf[i] << 4) | buf[n + i];
+ }
+ av_free(buf);
+ } else {
+ for (i = 7 * avctx->channels; i < avctx->block_align; i++) {
+ int nibble;
+ nibble = adpcm_ms_compress_sample(&c->status[ 0], *samples++) << 4;
+ nibble |= adpcm_ms_compress_sample(&c->status[st], *samples++);
+ *dst++ = nibble;
+ }
+ }
+ break;
+ case CODEC_ID_ADPCM_YAMAHA:
+ n = avctx->frame_size / 2;
+ if (avctx->trellis > 0) {
+ FF_ALLOC_OR_GOTO(avctx, buf, 2 * n * 2, error);
+ n *= 2;
+ if (avctx->channels == 1) {
+ adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
+ for (i = 0; i < n; i += 2)
+ *dst++ = buf[i] | (buf[i + 1] << 4);
+ } else {
+ adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
+ adpcm_compress_trellis(avctx, samples + 1, buf + n, &c->status[1], n);
+ for (i = 0; i < n; i++)
+ *dst++ = buf[i] | (buf[n + i] << 4);
+ }
+ av_free(buf);
+ } else
+ for (n *= avctx->channels; n > 0; n--) {
+ int nibble;
+ nibble = adpcm_yamaha_compress_sample(&c->status[ 0], *samples++);
+ nibble |= adpcm_yamaha_compress_sample(&c->status[st], *samples++) << 4;
+ *dst++ = nibble;
+ }
+ break;
+ default:
+ error:
+ return -1;
+ }
+ return dst - frame;
+}
+
+
+#define ADPCM_ENCODER(id_, name_, long_name_) \
+AVCodec ff_ ## name_ ## _encoder = { \
+ .name = #name_, \
+ .type = AVMEDIA_TYPE_AUDIO, \
+ .id = id_, \
+ .priv_data_size = sizeof(ADPCMEncodeContext), \
+ .init = adpcm_encode_init, \
+ .encode = adpcm_encode_frame, \
+ .close = adpcm_encode_close, \
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, \
+ AV_SAMPLE_FMT_NONE}, \
+ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+}
+
+ADPCM_ENCODER(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, "ADPCM IMA QuickTime");
+ADPCM_ENCODER(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, "ADPCM IMA WAV");
+ADPCM_ENCODER(CODEC_ID_ADPCM_MS, adpcm_ms, "ADPCM Microsoft");
+ADPCM_ENCODER(CODEC_ID_ADPCM_SWF, adpcm_swf, "ADPCM Shockwave Flash");
+ADPCM_ENCODER(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, "ADPCM Yamaha");
diff --git a/libavcodec/adx.c b/libavcodec/adx.c
new file mode 100644
index 0000000..aa90fd8
--- /dev/null
+++ b/libavcodec/adx.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011 Justin Ruggles
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
+#include "adx.h"
+
+void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff)
+{
+ double a, b, c;
+
+ a = M_SQRT2 - cos(2.0 * M_PI * cutoff / sample_rate);
+ b = M_SQRT2 - 1.0;
+ c = (a - sqrt((a + b) * (a - b))) / b;
+
+ coeff[0] = lrintf(c * 2.0 * (1 << bits));
+ coeff[1] = lrintf(-(c * c) * (1 << bits));
+}
+
+int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,
+ int bufsize, int *header_size, int *coeff)
+{
+ int offset, cutoff;
+
+ if (bufsize < 24)
+ return AVERROR_INVALIDDATA;
+
+ if (AV_RB16(buf) != 0x8000)
+ return AVERROR_INVALIDDATA;
+ offset = AV_RB16(buf + 2) + 4;
+
+ /* if copyright string is within the provided data, validate it */
+ if (bufsize >= offset && memcmp(buf + offset - 6, "(c)CRI", 6))
+ return AVERROR_INVALIDDATA;
+
+ /* check for encoding=3 block_size=18, sample_size=4 */
+ if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) {
+ av_log_ask_for_sample(avctx, "unsupported ADX format\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ /* channels */
+ avctx->channels = buf[7];
+ if (avctx->channels > 2)
+ return AVERROR_INVALIDDATA;
+
+ /* sample rate */
+ avctx->sample_rate = AV_RB32(buf + 8);
+ if (avctx->sample_rate < 1 ||
+ avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8))
+ return AVERROR_INVALIDDATA;
+
+ /* bit rate */
+ avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES;
+
+ /* LPC coefficients */
+ if (coeff) {
+ cutoff = AV_RB16(buf + 16);
+ ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, coeff);
+ }
+
+ *header_size = offset;
+ return 0;
+}
diff --git a/libavcodec/adx.h b/libavcodec/adx.h
index c420696..92abe5f 100644
--- a/libavcodec/adx.h
+++ b/libavcodec/adx.h
@@ -31,19 +31,51 @@
#ifndef AVCODEC_ADX_H
#define AVCODEC_ADX_H
+#include <stdint.h>
+
+#include "avcodec.h"
+
typedef struct {
int s1,s2;
-} PREV;
+} ADXChannelState;
typedef struct {
- PREV prev[2];
+ AVFrame frame;
+ int channels;
+ ADXChannelState prev[2];
int header_parsed;
- unsigned char dec_temp[18*2];
- int in_temp;
+ int eof;
+ int cutoff;
+ int coeff[2];
} ADXContext;
-#define BASEVOL 0x4000
-#define SCALE1 0x7298
-#define SCALE2 0x3350
+#define COEFF_BITS 12
+
+#define BLOCK_SIZE 18
+#define BLOCK_SAMPLES 32
+
+/**
+ * Calculate LPC coefficients based on cutoff frequency and sample rate.
+ *
+ * @param cutoff cutoff frequency
+ * @param sample_rate sample rate
+ * @param bits number of bits used to quantize coefficients
+ * @param[out] coeff 2 quantized LPC coefficients
+ */
+void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff);
+
+/**
+ * Decode ADX stream header.
+ * Sets avctx->channels and avctx->sample_rate.
+ *
+ * @param avctx codec context
+ * @param buf header data
+ * @param bufsize data size, should be at least 24 bytes
+ * @param[out] header_size size of ADX header
+ * @param[out] coeff 2 LPC coefficients, can be NULL
+ * @return data offset or negative error code if header is invalid
+ */
+int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,
+ int bufsize, int *header_size, int *coeff);
#endif /* AVCODEC_ADX_H */
diff --git a/libavcodec/adx_parser.c b/libavcodec/adx_parser.c
new file mode 100644
index 0000000..ebcb137
--- /dev/null
+++ b/libavcodec/adx_parser.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011 Justin Ruggles
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * ADX audio parser
+ *
+ * Reads header to extradata and splits packets into individual blocks.
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "parser.h"
+#include "adx.h"
+
+typedef struct ADXParseContext {
+ ParseContext pc;
+ int header_size;
+ int block_size;
+ int buf_pos;
+} ADXParseContext;
+
+#define MIN_HEADER_SIZE 24
+
+static int adx_parse(AVCodecParserContext *s1,
+ AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ ADXParseContext *s = s1->priv_data;
+ ParseContext *pc = &s->pc;
+ int next = END_NOT_FOUND;
+
+ if (!avctx->extradata_size) {
+ int ret;
+
+ ff_combine_frame(pc, END_NOT_FOUND, &buf, &buf_size);
+
+ if (!s->header_size && pc->index >= MIN_HEADER_SIZE) {
+ if (ret = avpriv_adx_decode_header(avctx, pc->buffer, pc->index,
+ &s->header_size, NULL))
+ return AVERROR_INVALIDDATA;
+ s->block_size = BLOCK_SIZE * avctx->channels;
+ }
+ if (s->header_size && s->header_size <= pc->index) {
+ avctx->extradata = av_mallocz(s->header_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!avctx->extradata)
+ return AVERROR(ENOMEM);
+ avctx->extradata_size = s->header_size;
+ memcpy(avctx->extradata, pc->buffer, s->header_size);
+ memmove(pc->buffer, pc->buffer + s->header_size, s->header_size);
+ pc->index -= s->header_size;
+ }
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+
+ if (pc->index - s->buf_pos >= s->block_size) {
+ *poutbuf = &pc->buffer[s->buf_pos];
+ *poutbuf_size = s->block_size;
+ s->buf_pos += s->block_size;
+ return 0;
+ }
+ if (pc->index && s->buf_pos) {
+ memmove(pc->buffer, &pc->buffer[s->buf_pos], pc->index - s->buf_pos);
+ pc->index -= s->buf_pos;
+ s->buf_pos = 0;
+ }
+ if (buf_size + pc->index >= s->block_size)
+ next = s->block_size - pc->index;
+
+ if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+ *poutbuf = buf;
+ *poutbuf_size = buf_size;
+ return next;
+}
+
+AVCodecParser ff_adx_parser = {
+ .codec_ids = { CODEC_ID_ADPCM_ADX },
+ .priv_data_size = sizeof(ADXParseContext),
+ .parser_parse = adx_parse,
+ .parser_close = ff_parse_close,
+};
diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c
index 48acc65..e910413 100644
--- a/libavcodec/adxdec.c
+++ b/libavcodec/adxdec.c
@@ -22,6 +22,7 @@
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "adx.h"
+#include "get_bits.h"
/**
* @file
@@ -34,147 +35,126 @@
static av_cold int adx_decode_init(AVCodecContext *avctx)
{
+ ADXContext *c = avctx->priv_data;
+ int ret, header_size;
+
+ if (avctx->extradata_size < 24)
+ return AVERROR_INVALIDDATA;
+
+ if ((ret = avpriv_adx_decode_header(avctx, avctx->extradata,
+ avctx->extradata_size, &header_size,
+ c->coeff)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
+ return AVERROR_INVALIDDATA;
+ }
+ c->channels = avctx->channels;
+
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ avcodec_get_frame_defaults(&c->frame);
+ avctx->coded_frame = &c->frame;
+
return 0;
}
-/* 18 bytes <-> 32 samples */
-
-static void adx_decode(short *out,const unsigned char *in,PREV *prev)
+/**
+ * Decode 32 samples from 18 bytes.
+ *
+ * A 16-bit scalar value is applied to 32 residuals, which then have a
+ * 2nd-order LPC filter applied to it to form the output signal for a single
+ * channel.
+ */
+static int adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch)
{
+ ADXChannelState *prev = &c->prev[ch];
+ GetBitContext gb;
int scale = AV_RB16(in);
int i;
- int s0,s1,s2,d;
+ int s0, s1, s2, d;
-// printf("%x ",scale);
+ /* check if this is an EOF packet */
+ if (scale & 0x8000)
+ return -1;
- in+=2;
+ init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8);
s1 = prev->s1;
s2 = prev->s2;
- for(i=0;i<16;i++) {
- d = in[i];
- // d>>=4; if (d&8) d-=16;
- d = ((signed char)d >> 4);
- s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14;
- s2 = s1;
- s1 = av_clip_int16(s0);
- *out++=s1;
-
- d = in[i];
- //d&=15; if (d&8) d-=16;
- d = ((signed char)(d<<4) >> 4);
- s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14;
+ for (i = 0; i < BLOCK_SAMPLES; i++) {
+ d = get_sbits(&gb, 4);
+ s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS;
s2 = s1;
s1 = av_clip_int16(s0);
- *out++=s1;
+ *out = s1;
+ out += c->channels;
}
prev->s1 = s1;
prev->s2 = s2;
+ return 0;
}
-static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev)
+static int adx_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
- short tmp[32*2];
- int i;
-
- adx_decode(tmp ,in ,prev);
- adx_decode(tmp+32,in+18,prev+1);
- for(i=0;i<32;i++) {
- out[i*2] = tmp[i];
- out[i*2+1] = tmp[i+32];
+ int buf_size = avpkt->size;
+ ADXContext *c = avctx->priv_data;
+ int16_t *samples;
+ const uint8_t *buf = avpkt->data;
+ int num_blocks, ch, ret;
+
+ if (c->eof) {
+ *got_frame_ptr = 0;
+ return buf_size;
}
-}
-
-/* return data offset or 0 */
-static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize)
-{
- int offset;
- if (buf[0]!=0x80) return 0;
- offset = (AV_RB32(buf)^0x80000000)+4;
- if (bufsize<offset || memcmp(buf+offset-6,"(c)CRI",6)) return 0;
+ /* calculate number of blocks in the packet */
+ num_blocks = buf_size / (BLOCK_SIZE * c->channels);
- avctx->channels = buf[7];
- avctx->sample_rate = AV_RB32(buf+8);
- avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32;
-
- return offset;
-}
-
-static int adx_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
-{
- const uint8_t *buf0 = avpkt->data;
- int buf_size = avpkt->size;
- ADXContext *c = avctx->priv_data;
- short *samples = data;
- const uint8_t *buf = buf0;
- int rest = buf_size;
-
- if (!c->header_parsed) {
- int hdrsize = adx_decode_header(avctx,buf,rest);
- if (hdrsize==0) return -1;
- c->header_parsed = 1;
- buf += hdrsize;
- rest -= hdrsize;
+ /* if the packet is not an even multiple of BLOCK_SIZE, check for an EOF
+ packet */
+ if (!num_blocks || buf_size % (BLOCK_SIZE * avctx->channels)) {
+ if (buf_size >= 4 && (AV_RB16(buf) & 0x8000)) {
+ c->eof = 1;
+ *got_frame_ptr = 0;
+ return avpkt->size;
+ }
+ return AVERROR_INVALIDDATA;
}
- /* 18 bytes of data are expanded into 32*2 bytes of audio,
- so guard against buffer overflows */
- if(rest/18 > *data_size/64)
- rest = (*data_size/64) * 18;
-
- if (c->in_temp) {
- int copysize = 18*avctx->channels - c->in_temp;
- memcpy(c->dec_temp+c->in_temp,buf,copysize);
- rest -= copysize;
- buf += copysize;
- if (avctx->channels==1) {
- adx_decode(samples,c->dec_temp,c->prev);
- samples += 32;
- } else {
- adx_decode_stereo(samples,c->dec_temp,c->prev);
- samples += 32*2;
- }
+ /* get output buffer */
+ c->frame.nb_samples = num_blocks * BLOCK_SAMPLES;
+ if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
- //
- if (avctx->channels==1) {
- while(rest>=18) {
- adx_decode(samples,buf,c->prev);
- rest-=18;
- buf+=18;
- samples+=32;
- }
- } else {
- while(rest>=18*2) {
- adx_decode_stereo(samples,buf,c->prev);
- rest-=18*2;
- buf+=18*2;
- samples+=32*2;
+ samples = (int16_t *)c->frame.data[0];
+
+ while (num_blocks--) {
+ for (ch = 0; ch < c->channels; ch++) {
+ if (adx_decode(c, samples + ch, buf, ch)) {
+ c->eof = 1;
+ buf = avpkt->data + avpkt->size;
+ break;
+ }
+ buf_size -= BLOCK_SIZE;
+ buf += BLOCK_SIZE;
}
+ samples += BLOCK_SAMPLES * c->channels;
}
- //
- c->in_temp = rest;
- if (rest) {
- memcpy(c->dec_temp,buf,rest);
- buf+=rest;
- }
- *data_size = (uint8_t*)samples - (uint8_t*)data;
-// printf("%d:%d ",buf-buf0,*data_size); fflush(stdout);
- return buf-buf0;
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = c->frame;
+
+ return buf - avpkt->data;
}
AVCodec ff_adpcm_adx_decoder = {
- "adpcm_adx",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_ADPCM_ADX,
- sizeof(ADXContext),
- adx_decode_init,
- NULL,
- NULL,
- adx_decode_frame,
- .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
+ .name = "adpcm_adx",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ADPCM_ADX,
+ .priv_data_size = sizeof(ADXContext),
+ .init = adx_decode_init,
+ .decode = adx_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
};
-
diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c
index b0847f4..ae4b9f7 100644
--- a/libavcodec/adxenc.c
+++ b/libavcodec/adxenc.c
@@ -22,6 +22,7 @@
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "adx.h"
+#include "put_bits.h"
/**
* @file
@@ -34,8 +35,10 @@
/* 18 bytes <-> 32 samples */
-static void adx_encode(unsigned char *adx,const short *wav,PREV *prev)
+static void adx_encode(ADXContext *c, unsigned char *adx, const short *wav,
+ ADXChannelState *prev)
{
+ PutBitContext pb;
int scale;
int i;
int s0,s1,s2,d;
@@ -47,7 +50,7 @@ static void adx_encode(unsigned char *adx,const short *wav,PREV *prev)
s2 = prev->s2;
for(i=0;i<32;i++) {
s0 = wav[i];
- d = ((s0<<14) - SCALE1*s1 + SCALE2*s2)/BASEVOL;
+ d = ((s0 << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS;
data[i]=d;
if (max<d) max=d;
if (min>d) min=d;
@@ -71,9 +74,10 @@ static void adx_encode(unsigned char *adx,const short *wav,PREV *prev)
AV_WB16(adx, scale);
- for(i=0;i<16;i++) {
- adx[i+2] = ((data[i*2]/scale)<<4) | ((data[i*2+1]/scale)&0xf);
- }
+ init_put_bits(&pb, adx + 2, 16);
+ for (i = 0; i < 32; i++)
+ put_sbits(&pb, 4, av_clip(data[i]/scale, -8, 7));
+ flush_put_bits(&pb);
}
static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize)
@@ -101,19 +105,24 @@ static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t buf
} adxhdr; /* big endian */
/* offset-6 "(c)CRI" */
#endif
+ ADXContext *c = avctx->priv_data;
+
AV_WB32(buf+0x00,0x80000000|0x20);
AV_WB32(buf+0x04,0x03120400|avctx->channels);
AV_WB32(buf+0x08,avctx->sample_rate);
AV_WB32(buf+0x0c,0); /* FIXME: set after */
- AV_WB32(buf+0x10,0x01040300);
- AV_WB32(buf+0x14,0x00000000);
- AV_WB32(buf+0x18,0x00000000);
- memcpy(buf+0x1c,"\0\0(c)CRI",8);
+ AV_WB16(buf + 0x10, c->cutoff);
+ AV_WB32(buf + 0x12, 0x03000000);
+ AV_WB32(buf + 0x16, 0x00000000);
+ AV_WB32(buf + 0x1a, 0x00000000);
+ memcpy (buf + 0x1e, "(c)CRI", 6);
return 0x20+4;
}
static av_cold int adx_encode_init(AVCodecContext *avctx)
{
+ ADXContext *c = avctx->priv_data;
+
if (avctx->channels > 2)
return -1; /* only stereo or mono =) */
avctx->frame_size = 32;
@@ -123,6 +132,10 @@ static av_cold int adx_encode_init(AVCodecContext *avctx)
// avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32;
+ /* the cutoff can be adjusted, but this seems to work pretty well */
+ c->cutoff = 500;
+ ff_adx_calculate_coeffs(c->cutoff, avctx->sample_rate, COEFF_BITS, c->coeff);
+
av_log(avctx, AV_LOG_DEBUG, "adx encode init\n");
return 0;
@@ -145,7 +158,7 @@ static int adx_encode_frame(AVCodecContext *avctx,
/*
input data size =
- ffmpeg.c: do_audio_out()
+ avconv.c:do_audio_out()
frame_bytes = enc->frame_size * 2 * enc->channels;
*/
@@ -158,7 +171,7 @@ static int adx_encode_frame(AVCodecContext *avctx,
if (avctx->channels==1) {
while(rest>=32) {
- adx_encode(dst,samples,c->prev);
+ adx_encode(c, dst, samples, c->prev);
dst+=18;
samples+=32;
rest-=32;
@@ -173,8 +186,8 @@ static int adx_encode_frame(AVCodecContext *avctx,
tmpbuf[i+32] = samples[i*2+1];
}
- adx_encode(dst,tmpbuf,c->prev);
- adx_encode(dst+18,tmpbuf+32,c->prev+1);
+ adx_encode(c, dst, tmpbuf, c->prev);
+ adx_encode(c, dst + 18, tmpbuf + 32, c->prev + 1);
dst+=18*2;
samples+=32*2;
rest-=32*2;
@@ -184,14 +197,13 @@ static int adx_encode_frame(AVCodecContext *avctx,
}
AVCodec ff_adpcm_adx_encoder = {
- "adpcm_adx",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_ADPCM_ADX,
- sizeof(ADXContext),
- adx_encode_init,
- adx_encode_frame,
- adx_encode_close,
- NULL,
+ .name = "adpcm_adx",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ADPCM_ADX,
+ .priv_data_size = sizeof(ADXContext),
+ .init = adx_encode_init,
+ .encode = adx_encode_frame,
+ .close = adx_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
};
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index 4ea3f7e..47234ec 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -23,9 +23,7 @@
* @file
* ALAC (Apple Lossless Audio Codec) decoder
* @author 2005 David Hammerton
- *
- * For more information on the ALAC format, visit:
- * http://crazney.net/programs/itunes/alac.html
+ * @see http://crazney.net/programs/itunes/alac.html
*
* Note: This decoder expects a 36- (0x24-)byte QuickTime atom to be
* passed through the extradata[_size] fields. This atom is tacked onto
@@ -64,17 +62,17 @@
typedef struct {
AVCodecContext *avctx;
+ AVFrame frame;
GetBitContext gb;
int numchannels;
- int bytespersample;
/* buffers */
int32_t *predicterror_buffer[MAX_CHANNELS];
int32_t *outputsamples_buffer[MAX_CHANNELS];
- int32_t *wasted_bits_buffer[MAX_CHANNELS];
+ int32_t *extra_bits_buffer[MAX_CHANNELS];
/* stuff from setinfo */
uint32_t setinfo_max_samples_per_frame; /* 0x1000 = 4096 */ /* max samples per frame? */
@@ -84,58 +82,9 @@ typedef struct {
uint8_t setinfo_rice_kmodifier; /* 0x0e */
/* end setinfo stuff */
- int wasted_bits;
+ int extra_bits; /**< number of extra bits beyond 16-bit */
} ALACContext;
-static void allocate_buffers(ALACContext *alac)
-{
- int chan;
- for (chan = 0; chan < MAX_CHANNELS; chan++) {
- alac->predicterror_buffer[chan] =
- av_malloc(alac->setinfo_max_samples_per_frame * 4);
-
- alac->outputsamples_buffer[chan] =
- av_malloc(alac->setinfo_max_samples_per_frame * 4);
-
- alac->wasted_bits_buffer[chan] = av_malloc(alac->setinfo_max_samples_per_frame * 4);
- }
-}
-
-static int alac_set_info(ALACContext *alac)
-{
- const unsigned char *ptr = alac->avctx->extradata;
-
- ptr += 4; /* size */
- ptr += 4; /* alac */
- ptr += 4; /* 0 ? */
-
- if(AV_RB32(ptr) >= UINT_MAX/4){
- av_log(alac->avctx, AV_LOG_ERROR, "setinfo_max_samples_per_frame too large\n");
- return -1;
- }
-
- /* buffer size / 2 ? */
- alac->setinfo_max_samples_per_frame = bytestream_get_be32(&ptr);
- ptr++; /* ??? */
- alac->setinfo_sample_size = *ptr++;
- if (alac->setinfo_sample_size > 32) {
- av_log(alac->avctx, AV_LOG_ERROR, "setinfo_sample_size too large\n");
- return -1;
- }
- alac->setinfo_rice_historymult = *ptr++;
- alac->setinfo_rice_initialhistory = *ptr++;
- alac->setinfo_rice_kmodifier = *ptr++;
- ptr++; /* channels? */
- bytestream_get_be16(&ptr); /* ??? */
- bytestream_get_be32(&ptr); /* max coded frame size */
- bytestream_get_be32(&ptr); /* bitrate ? */
- bytestream_get_be32(&ptr); /* samplerate */
-
- allocate_buffers(alac);
-
- return 0;
-}
-
static inline int decode_scalar(GetBitContext *gb, int k, int limit, int readsamplesize){
/* read x - number of 1s before 0 represent the rice */
int x = get_unary_0_9(gb);
@@ -286,20 +235,9 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer,
buffer_out[i+1] = val;
}
-#if 0
/* 4 and 8 are very common cases (the only ones i've seen). these
* should be unrolled and optimized
*/
- if (predictor_coef_num == 4) {
- /* FIXME: optimized general case */
- return;
- }
-
- if (predictor_coef_table == 8) {
- /* FIXME: optimized general case */
- return;
- }
-#endif
/* general case */
if (predictor_coef_num > 0) {
@@ -360,99 +298,61 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer,
}
}
-static void reconstruct_stereo_16(int32_t *buffer[MAX_CHANNELS],
- int16_t *buffer_out,
- int numchannels, int numsamples,
- uint8_t interlacing_shift,
- uint8_t interlacing_leftweight)
+static void decorrelate_stereo(int32_t *buffer[MAX_CHANNELS],
+ int numsamples, uint8_t interlacing_shift,
+ uint8_t interlacing_leftweight)
{
int i;
- if (numsamples <= 0)
- return;
- /* weighted interlacing */
- if (interlacing_leftweight) {
- for (i = 0; i < numsamples; i++) {
- int32_t a, b;
+ for (i = 0; i < numsamples; i++) {
+ int32_t a, b;
- a = buffer[0][i];
- b = buffer[1][i];
+ a = buffer[0][i];
+ b = buffer[1][i];
- a -= (b * interlacing_leftweight) >> interlacing_shift;
- b += a;
+ a -= (b * interlacing_leftweight) >> interlacing_shift;
+ b += a;
- buffer_out[i*numchannels] = b;
- buffer_out[i*numchannels + 1] = a;
- }
-
- return;
+ buffer[0][i] = b;
+ buffer[1][i] = a;
}
+}
- /* otherwise basic interlacing took place */
- for (i = 0; i < numsamples; i++) {
- int16_t left, right;
-
- left = buffer[0][i];
- right = buffer[1][i];
+static void append_extra_bits(int32_t *buffer[MAX_CHANNELS],
+ int32_t *extra_bits_buffer[MAX_CHANNELS],
+ int extra_bits, int numchannels, int numsamples)
+{
+ int i, ch;
- buffer_out[i*numchannels] = left;
- buffer_out[i*numchannels + 1] = right;
- }
+ for (ch = 0; ch < numchannels; ch++)
+ for (i = 0; i < numsamples; i++)
+ buffer[ch][i] = (buffer[ch][i] << extra_bits) | extra_bits_buffer[ch][i];
}
-static void decorrelate_stereo_24(int32_t *buffer[MAX_CHANNELS],
- int32_t *buffer_out,
- int32_t *wasted_bits_buffer[MAX_CHANNELS],
- int wasted_bits,
- int numchannels, int numsamples,
- uint8_t interlacing_shift,
- uint8_t interlacing_leftweight)
+static void interleave_stereo_16(int32_t *buffer[MAX_CHANNELS],
+ int16_t *buffer_out, int numsamples)
{
int i;
- if (numsamples <= 0)
- return;
-
- /* weighted interlacing */
- if (interlacing_leftweight) {
- for (i = 0; i < numsamples; i++) {
- int32_t a, b;
-
- a = buffer[0][i];
- b = buffer[1][i];
-
- a -= (b * interlacing_leftweight) >> interlacing_shift;
- b += a;
-
- if (wasted_bits) {
- b = (b << wasted_bits) | wasted_bits_buffer[0][i];
- a = (a << wasted_bits) | wasted_bits_buffer[1][i];
- }
-
- buffer_out[i * numchannels] = b << 8;
- buffer_out[i * numchannels + 1] = a << 8;
- }
- } else {
- for (i = 0; i < numsamples; i++) {
- int32_t left, right;
-
- left = buffer[0][i];
- right = buffer[1][i];
+ for (i = 0; i < numsamples; i++) {
+ *buffer_out++ = buffer[0][i];
+ *buffer_out++ = buffer[1][i];
+ }
+}
- if (wasted_bits) {
- left = (left << wasted_bits) | wasted_bits_buffer[0][i];
- right = (right << wasted_bits) | wasted_bits_buffer[1][i];
- }
+static void interleave_stereo_24(int32_t *buffer[MAX_CHANNELS],
+ int32_t *buffer_out, int numsamples)
+{
+ int i;
- buffer_out[i * numchannels] = left << 8;
- buffer_out[i * numchannels + 1] = right << 8;
- }
+ for (i = 0; i < numsamples; i++) {
+ *buffer_out++ = buffer[0][i] << 8;
+ *buffer_out++ = buffer[1][i] << 8;
}
}
-static int alac_decode_frame(AVCodecContext *avctx,
- void *outbuffer, int *outputsize,
- AVPacket *avpkt)
+static int alac_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *inbuffer = avpkt->data;
int input_buffer_size = avpkt->size;
@@ -465,18 +365,14 @@ static int alac_decode_frame(AVCodecContext *avctx,
int isnotcompressed;
uint8_t interlacing_shift;
uint8_t interlacing_leftweight;
-
- /* short-circuit null buffers */
- if (!inbuffer || !input_buffer_size)
- return -1;
+ int i, ch, ret;
init_get_bits(&alac->gb, inbuffer, input_buffer_size * 8);
channels = get_bits(&alac->gb, 3) + 1;
- if (channels > MAX_CHANNELS) {
- av_log(avctx, AV_LOG_ERROR, "channels > %d not supported\n",
- MAX_CHANNELS);
- return -1;
+ if (channels != avctx->channels) {
+ av_log(avctx, AV_LOG_ERROR, "frame header channel count mismatch\n");
+ return AVERROR_INVALIDDATA;
}
/* 2^result = something to do with output waiting.
@@ -489,7 +385,7 @@ static int alac_decode_frame(AVCodecContext *avctx,
/* the output sample size is stored soon */
hassize = get_bits1(&alac->gb);
- alac->wasted_bits = get_bits(&alac->gb, 2) << 3;
+ alac->extra_bits = get_bits(&alac->gb, 2) << 3;
/* whether the frame is compressed */
isnotcompressed = get_bits1(&alac->gb);
@@ -504,25 +400,18 @@ static int alac_decode_frame(AVCodecContext *avctx,
} else
outputsamples = alac->setinfo_max_samples_per_frame;
- switch (alac->setinfo_sample_size) {
- case 16: avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- alac->bytespersample = channels << 1;
- break;
- case 24: avctx->sample_fmt = AV_SAMPLE_FMT_S32;
- alac->bytespersample = channels << 2;
- break;
- default: av_log(avctx, AV_LOG_ERROR, "Sample depth %d is not supported.\n",
- alac->setinfo_sample_size);
- return -1;
+ /* get output buffer */
+ if (outputsamples > INT32_MAX) {
+ av_log(avctx, AV_LOG_ERROR, "unsupported block size: %u\n", outputsamples);
+ return AVERROR_INVALIDDATA;
}
-
- if(outputsamples > *outputsize / alac->bytespersample){
- av_log(avctx, AV_LOG_ERROR, "sample buffer too small\n");
- return -1;
+ alac->frame.nb_samples = outputsamples;
+ if ((ret = avctx->get_buffer(avctx, &alac->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
- *outputsize = outputsamples * alac->bytespersample;
- readsamplesize = alac->setinfo_sample_size - (alac->wasted_bits) + channels - 1;
+ readsamplesize = alac->setinfo_sample_size - alac->extra_bits + channels - 1;
if (readsamplesize > MIN_CACHE_BITS) {
av_log(avctx, AV_LOG_ERROR, "readsamplesize too big (%d)\n", readsamplesize);
return -1;
@@ -535,51 +424,49 @@ static int alac_decode_frame(AVCodecContext *avctx,
int prediction_type[MAX_CHANNELS];
int prediction_quantitization[MAX_CHANNELS];
int ricemodifier[MAX_CHANNELS];
- int i, chan;
interlacing_shift = get_bits(&alac->gb, 8);
interlacing_leftweight = get_bits(&alac->gb, 8);
- for (chan = 0; chan < channels; chan++) {
- prediction_type[chan] = get_bits(&alac->gb, 4);
- prediction_quantitization[chan] = get_bits(&alac->gb, 4);
+ for (ch = 0; ch < channels; ch++) {
+ prediction_type[ch] = get_bits(&alac->gb, 4);
+ prediction_quantitization[ch] = get_bits(&alac->gb, 4);
- ricemodifier[chan] = get_bits(&alac->gb, 3);
- predictor_coef_num[chan] = get_bits(&alac->gb, 5);
+ ricemodifier[ch] = get_bits(&alac->gb, 3);
+ predictor_coef_num[ch] = get_bits(&alac->gb, 5);
/* read the predictor table */
- for (i = 0; i < predictor_coef_num[chan]; i++)
- predictor_coef_table[chan][i] = (int16_t)get_bits(&alac->gb, 16);
+ for (i = 0; i < predictor_coef_num[ch]; i++)
+ predictor_coef_table[ch][i] = (int16_t)get_bits(&alac->gb, 16);
}
- if (alac->wasted_bits) {
- int i, ch;
+ if (alac->extra_bits) {
for (i = 0; i < outputsamples; i++) {
for (ch = 0; ch < channels; ch++)
- alac->wasted_bits_buffer[ch][i] = get_bits(&alac->gb, alac->wasted_bits);
+ alac->extra_bits_buffer[ch][i] = get_bits(&alac->gb, alac->extra_bits);
}
}
- for (chan = 0; chan < channels; chan++) {
+ for (ch = 0; ch < channels; ch++) {
bastardized_rice_decompress(alac,
- alac->predicterror_buffer[chan],
+ alac->predicterror_buffer[ch],
outputsamples,
readsamplesize,
alac->setinfo_rice_initialhistory,
alac->setinfo_rice_kmodifier,
- ricemodifier[chan] * alac->setinfo_rice_historymult / 4,
+ ricemodifier[ch] * alac->setinfo_rice_historymult / 4,
(1 << alac->setinfo_rice_kmodifier) - 1);
- if (prediction_type[chan] == 0) {
+ if (prediction_type[ch] == 0) {
/* adaptive fir */
- predictor_decompress_fir_adapt(alac->predicterror_buffer[chan],
- alac->outputsamples_buffer[chan],
+ predictor_decompress_fir_adapt(alac->predicterror_buffer[ch],
+ alac->outputsamples_buffer[ch],
outputsamples,
readsamplesize,
- predictor_coef_table[chan],
- predictor_coef_num[chan],
- prediction_quantitization[chan]);
+ predictor_coef_table[ch],
+ predictor_coef_num[ch],
+ prediction_quantitization[ch]);
} else {
- av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type[chan]);
+ av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type[ch]);
/* I think the only other prediction type (or perhaps this is
* just a boolean?) runs adaptive fir twice.. like:
* predictor_decompress_fir_adapt(predictor_error, tempout, ...)
@@ -590,63 +477,49 @@ static int alac_decode_frame(AVCodecContext *avctx,
}
} else {
/* not compressed, easy case */
- int i, chan;
- if (alac->setinfo_sample_size <= 16) {
- for (i = 0; i < outputsamples; i++)
- for (chan = 0; chan < channels; chan++) {
- int32_t audiobits;
-
- audiobits = get_sbits_long(&alac->gb, alac->setinfo_sample_size);
-
- alac->outputsamples_buffer[chan][i] = audiobits;
- }
- } else {
- for (i = 0; i < outputsamples; i++) {
- for (chan = 0; chan < channels; chan++) {
- alac->outputsamples_buffer[chan][i] = get_bits(&alac->gb,
- alac->setinfo_sample_size);
- alac->outputsamples_buffer[chan][i] = sign_extend(alac->outputsamples_buffer[chan][i],
- alac->setinfo_sample_size);
- }
+ for (i = 0; i < outputsamples; i++) {
+ for (ch = 0; ch < channels; ch++) {
+ alac->outputsamples_buffer[ch][i] = get_sbits_long(&alac->gb,
+ alac->setinfo_sample_size);
}
}
- alac->wasted_bits = 0;
+ alac->extra_bits = 0;
interlacing_shift = 0;
interlacing_leftweight = 0;
}
if (get_bits(&alac->gb, 3) != 7)
av_log(avctx, AV_LOG_ERROR, "Error : Wrong End Of Frame\n");
+ if (channels == 2 && interlacing_leftweight) {
+ decorrelate_stereo(alac->outputsamples_buffer, outputsamples,
+ interlacing_shift, interlacing_leftweight);
+ }
+
+ if (alac->extra_bits) {
+ append_extra_bits(alac->outputsamples_buffer, alac->extra_bits_buffer,
+ alac->extra_bits, alac->numchannels, outputsamples);
+ }
+
switch(alac->setinfo_sample_size) {
case 16:
if (channels == 2) {
- reconstruct_stereo_16(alac->outputsamples_buffer,
- (int16_t*)outbuffer,
- alac->numchannels,
- outputsamples,
- interlacing_shift,
- interlacing_leftweight);
+ interleave_stereo_16(alac->outputsamples_buffer,
+ (int16_t *)alac->frame.data[0], outputsamples);
} else {
- int i;
+ int16_t *outbuffer = (int16_t *)alac->frame.data[0];
for (i = 0; i < outputsamples; i++) {
- ((int16_t*)outbuffer)[i] = alac->outputsamples_buffer[0][i];
+ outbuffer[i] = alac->outputsamples_buffer[0][i];
}
}
break;
case 24:
if (channels == 2) {
- decorrelate_stereo_24(alac->outputsamples_buffer,
- outbuffer,
- alac->wasted_bits_buffer,
- alac->wasted_bits,
- alac->numchannels,
- outputsamples,
- interlacing_shift,
- interlacing_leftweight);
+ interleave_stereo_24(alac->outputsamples_buffer,
+ (int32_t *)alac->frame.data[0], outputsamples);
} else {
- int i;
+ int32_t *outbuffer = (int32_t *)alac->frame.data[0];
for (i = 0; i < outputsamples; i++)
- ((int32_t *)outbuffer)[i] = alac->outputsamples_buffer[0][i] << 8;
+ outbuffer[i] = alac->outputsamples_buffer[0][i] << 8;
}
break;
}
@@ -654,14 +527,81 @@ static int alac_decode_frame(AVCodecContext *avctx,
if (input_buffer_size * 8 - get_bits_count(&alac->gb) > 8)
av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n", input_buffer_size * 8 - get_bits_count(&alac->gb));
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = alac->frame;
+
return input_buffer_size;
}
+static av_cold int alac_decode_close(AVCodecContext *avctx)
+{
+ ALACContext *alac = avctx->priv_data;
+
+ int ch;
+ for (ch = 0; ch < alac->numchannels; ch++) {
+ av_freep(&alac->predicterror_buffer[ch]);
+ av_freep(&alac->outputsamples_buffer[ch]);
+ av_freep(&alac->extra_bits_buffer[ch]);
+ }
+
+ return 0;
+}
+
+static int allocate_buffers(ALACContext *alac)
+{
+ int ch;
+ for (ch = 0; ch < alac->numchannels; ch++) {
+ int buf_size = alac->setinfo_max_samples_per_frame * sizeof(int32_t);
+
+ FF_ALLOC_OR_GOTO(alac->avctx, alac->predicterror_buffer[ch],
+ buf_size, buf_alloc_fail);
+
+ FF_ALLOC_OR_GOTO(alac->avctx, alac->outputsamples_buffer[ch],
+ buf_size, buf_alloc_fail);
+
+ FF_ALLOC_OR_GOTO(alac->avctx, alac->extra_bits_buffer[ch],
+ buf_size, buf_alloc_fail);
+ }
+ return 0;
+buf_alloc_fail:
+ alac_decode_close(alac->avctx);
+ return AVERROR(ENOMEM);
+}
+
+static int alac_set_info(ALACContext *alac)
+{
+ const unsigned char *ptr = alac->avctx->extradata;
+
+ ptr += 4; /* size */
+ ptr += 4; /* alac */
+ ptr += 4; /* 0 ? */
+
+ if(AV_RB32(ptr) >= UINT_MAX/4){
+ av_log(alac->avctx, AV_LOG_ERROR, "setinfo_max_samples_per_frame too large\n");
+ return -1;
+ }
+
+ /* buffer size / 2 ? */
+ alac->setinfo_max_samples_per_frame = bytestream_get_be32(&ptr);
+ ptr++; /* ??? */
+ alac->setinfo_sample_size = *ptr++;
+ alac->setinfo_rice_historymult = *ptr++;
+ alac->setinfo_rice_initialhistory = *ptr++;
+ alac->setinfo_rice_kmodifier = *ptr++;
+ alac->numchannels = *ptr++;
+ bytestream_get_be16(&ptr); /* ??? */
+ bytestream_get_be32(&ptr); /* max coded frame size */
+ bytestream_get_be32(&ptr); /* bitrate ? */
+ bytestream_get_be32(&ptr); /* samplerate */
+
+ return 0;
+}
+
static av_cold int alac_decode_init(AVCodecContext * avctx)
{
+ int ret;
ALACContext *alac = avctx->priv_data;
alac->avctx = avctx;
- alac->numchannels = alac->avctx->channels;
/* initialize from the extradata */
if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) {
@@ -674,31 +614,50 @@ static av_cold int alac_decode_init(AVCodecContext * avctx)
return -1;
}
- return 0;
-}
+ switch (alac->setinfo_sample_size) {
+ case 16: avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ break;
+ case 24: avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+ break;
+ default: av_log_ask_for_sample(avctx, "Sample depth %d is not supported.\n",
+ alac->setinfo_sample_size);
+ return AVERROR_PATCHWELCOME;
+ }
-static av_cold int alac_decode_close(AVCodecContext *avctx)
-{
- ALACContext *alac = avctx->priv_data;
+ if (alac->numchannels < 1) {
+ av_log(avctx, AV_LOG_WARNING, "Invalid channel count\n");
+ alac->numchannels = avctx->channels;
+ } else {
+ if (alac->numchannels > MAX_CHANNELS)
+ alac->numchannels = avctx->channels;
+ else
+ avctx->channels = alac->numchannels;
+ }
+ if (avctx->channels > MAX_CHANNELS) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported channel count: %d\n",
+ avctx->channels);
+ return AVERROR_PATCHWELCOME;
+ }
- int chan;
- for (chan = 0; chan < MAX_CHANNELS; chan++) {
- av_freep(&alac->predicterror_buffer[chan]);
- av_freep(&alac->outputsamples_buffer[chan]);
- av_freep(&alac->wasted_bits_buffer[chan]);
+ if ((ret = allocate_buffers(alac)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error allocating buffers\n");
+ return ret;
}
+ avcodec_get_frame_defaults(&alac->frame);
+ avctx->coded_frame = &alac->frame;
+
return 0;
}
AVCodec ff_alac_decoder = {
- "alac",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_ALAC,
- sizeof(ALACContext),
- alac_decode_init,
- NULL,
- alac_decode_close,
- alac_decode_frame,
+ .name = "alac",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ALAC,
+ .priv_data_size = sizeof(ALACContext),
+ .init = alac_decode_init,
+ .close = alac_decode_close,
+ .decode = alac_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
};
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index acaa545..7e29a24 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -75,20 +75,22 @@ typedef struct AlacEncodeContext {
} AlacEncodeContext;
-static void init_sample_buffers(AlacEncodeContext *s, const int16_t *input_samples)
+static void init_sample_buffers(AlacEncodeContext *s,
+ const int16_t *input_samples)
{
int ch, i;
- for(ch=0;ch<s->avctx->channels;ch++) {
+ for (ch = 0; ch < s->avctx->channels; ch++) {
const int16_t *sptr = input_samples + ch;
- for(i=0;i<s->avctx->frame_size;i++) {
+ for (i = 0; i < s->avctx->frame_size; i++) {
s->sample_buf[ch][i] = *sptr;
sptr += s->avctx->channels;
}
}
}
-static void encode_scalar(AlacEncodeContext *s, int x, int k, int write_sample_size)
+static void encode_scalar(AlacEncodeContext *s, int x,
+ int k, int write_sample_size)
{
int divisor, q, r;
@@ -97,17 +99,17 @@ static void encode_scalar(AlacEncodeContext *s, int x, int k, int write_sample_s
q = x / divisor;
r = x % divisor;
- if(q > 8) {
+ if (q > 8) {
// write escape code and sample value directly
put_bits(&s->pbctx, 9, ALAC_ESCAPE_CODE);
put_bits(&s->pbctx, write_sample_size, x);
} else {
- if(q)
+ if (q)
put_bits(&s->pbctx, q, (1<<q) - 1);
put_bits(&s->pbctx, 1, 0);
- if(k != 1) {
- if(r > 0)
+ if (k != 1) {
+ if (r > 0)
put_bits(&s->pbctx, k, r+1);
else
put_bits(&s->pbctx, k-1, 0);
@@ -164,7 +166,7 @@ static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n)
/* calculate sum of 2nd order residual for each channel */
sum[0] = sum[1] = sum[2] = sum[3] = 0;
- for(i=2; i<n; i++) {
+ for (i = 2; i < n; i++) {
lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2];
rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2];
sum[2] += FFABS((lt + rt) >> 1);
@@ -181,8 +183,8 @@ static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n)
/* return mode with lowest score */
best = 0;
- for(i=1; i<4; i++) {
- if(score[i] < score[best]) {
+ for (i = 1; i < 4; i++) {
+ if (score[i] < score[best]) {
best = i;
}
}
@@ -205,7 +207,7 @@ static void alac_stereo_decorrelation(AlacEncodeContext *s)
break;
case ALAC_CHMODE_LEFT_SIDE:
- for(i=0; i<n; i++) {
+ for (i = 0; i < n; i++) {
right[i] = left[i] - right[i];
}
s->interlacing_leftweight = 1;
@@ -213,7 +215,7 @@ static void alac_stereo_decorrelation(AlacEncodeContext *s)
break;
case ALAC_CHMODE_RIGHT_SIDE:
- for(i=0; i<n; i++) {
+ for (i = 0; i < n; i++) {
tmp = right[i];
right[i] = left[i] - right[i];
left[i] = tmp + (right[i] >> 31);
@@ -223,7 +225,7 @@ static void alac_stereo_decorrelation(AlacEncodeContext *s)
break;
default:
- for(i=0; i<n; i++) {
+ for (i = 0; i < n; i++) {
tmp = left[i];
left[i] = (tmp + right[i]) >> 1;
right[i] = tmp - right[i];
@@ -239,10 +241,10 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch)
int i;
AlacLPCContext lpc = s->lpc[ch];
- if(lpc.lpc_order == 31) {
+ if (lpc.lpc_order == 31) {
s->predictor_buf[0] = s->sample_buf[ch][0];
- for(i=1; i<s->avctx->frame_size; i++)
+ for (i = 1; i < s->avctx->frame_size; i++)
s->predictor_buf[i] = s->sample_buf[ch][i] - s->sample_buf[ch][i-1];
return;
@@ -250,17 +252,17 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch)
// generalised linear predictor
- if(lpc.lpc_order > 0) {
+ if (lpc.lpc_order > 0) {
int32_t *samples = s->sample_buf[ch];
int32_t *residual = s->predictor_buf;
// generate warm-up samples
residual[0] = samples[0];
- for(i=1;i<=lpc.lpc_order;i++)
+ for (i = 1; i <= lpc.lpc_order; i++)
residual[i] = samples[i] - samples[i-1];
// perform lpc on remaining samples
- for(i = lpc.lpc_order + 1; i < s->avctx->frame_size; i++) {
+ for (i = lpc.lpc_order + 1; i < s->avctx->frame_size; i++) {
int sum = 1 << (lpc.lpc_quant - 1), res_val, j;
for (j = 0; j < lpc.lpc_order; j++) {
@@ -303,7 +305,7 @@ static void alac_entropy_coder(AlacEncodeContext *s)
int sign_modifier = 0, i, k;
int32_t *samples = s->predictor_buf;
- for(i=0;i < s->avctx->frame_size;) {
+ for (i = 0; i < s->avctx->frame_size;) {
int x;
k = av_log2((history >> 9) + 3);
@@ -320,15 +322,15 @@ static void alac_entropy_coder(AlacEncodeContext *s)
- ((history * s->rc.history_mult) >> 9);
sign_modifier = 0;
- if(x > 0xFFFF)
+ if (x > 0xFFFF)
history = 0xFFFF;
- if((history < 128) && (i < s->avctx->frame_size)) {
+ if (history < 128 && i < s->avctx->frame_size) {
unsigned int block_size = 0;
k = 7 - av_log2(history) + ((history + 16) >> 6);
- while((*samples == 0) && (i < s->avctx->frame_size)) {
+ while (*samples == 0 && i < s->avctx->frame_size) {
samples++;
i++;
block_size++;
@@ -347,12 +349,12 @@ static void write_compressed_frame(AlacEncodeContext *s)
{
int i, j;
- if(s->avctx->channels == 2)
+ if (s->avctx->channels == 2)
alac_stereo_decorrelation(s);
put_bits(&s->pbctx, 8, s->interlacing_shift);
put_bits(&s->pbctx, 8, s->interlacing_leftweight);
- for(i=0;i<s->avctx->channels;i++) {
+ for (i = 0; i < s->avctx->channels; i++) {
calc_predictor_params(s, i);
@@ -362,14 +364,14 @@ static void write_compressed_frame(AlacEncodeContext *s)
put_bits(&s->pbctx, 3, s->rc.rice_modifier);
put_bits(&s->pbctx, 5, s->lpc[i].lpc_order);
// predictor coeff. table
- for(j=0;j<s->lpc[i].lpc_order;j++) {
+ for (j = 0; j < s->lpc[i].lpc_order; j++) {
put_sbits(&s->pbctx, 16, s->lpc[i].lpc_coeff[j]);
}
}
// apply lpc and entropy coding to audio samples
- for(i=0;i<s->avctx->channels;i++) {
+ for (i = 0; i < s->avctx->channels; i++) {
alac_linear_predictor(s, i);
alac_entropy_coder(s);
}
@@ -384,13 +386,13 @@ static av_cold int alac_encode_init(AVCodecContext *avctx)
avctx->frame_size = DEFAULT_FRAME_SIZE;
avctx->bits_per_coded_sample = DEFAULT_SAMPLE_SIZE;
- if(avctx->sample_fmt != AV_SAMPLE_FMT_S16) {
+ if (avctx->sample_fmt != AV_SAMPLE_FMT_S16) {
av_log(avctx, AV_LOG_ERROR, "only pcm_s16 input samples are supported\n");
return -1;
}
// Set default compression level
- if(avctx->compression_level == FF_COMPRESSION_DEFAULT)
+ if (avctx->compression_level == FF_COMPRESSION_DEFAULT)
s->compression_level = 2;
else
s->compression_level = av_clip(avctx->compression_level, 0, 2);
@@ -411,21 +413,23 @@ static av_cold int alac_encode_init(AVCodecContext *avctx)
AV_WB8 (alac_extradata+17, avctx->bits_per_coded_sample);
AV_WB8 (alac_extradata+21, avctx->channels);
AV_WB32(alac_extradata+24, s->max_coded_frame_size);
- AV_WB32(alac_extradata+28, avctx->sample_rate*avctx->channels*avctx->bits_per_coded_sample); // average bitrate
+ AV_WB32(alac_extradata+28,
+ avctx->sample_rate * avctx->channels * avctx->bits_per_coded_sample); // average bitrate
AV_WB32(alac_extradata+32, avctx->sample_rate);
// Set relevant extradata fields
- if(s->compression_level > 0) {
+ if (s->compression_level > 0) {
AV_WB8(alac_extradata+18, s->rc.history_mult);
AV_WB8(alac_extradata+19, s->rc.initial_history);
AV_WB8(alac_extradata+20, s->rc.k_modifier);
}
s->min_prediction_order = DEFAULT_MIN_PRED_ORDER;
- if(avctx->min_prediction_order >= 0) {
- if(avctx->min_prediction_order < MIN_LPC_ORDER ||
+ if (avctx->min_prediction_order >= 0) {
+ if (avctx->min_prediction_order < MIN_LPC_ORDER ||
avctx->min_prediction_order > ALAC_MAX_LPC_ORDER) {
- av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n", avctx->min_prediction_order);
+ av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",
+ avctx->min_prediction_order);
return -1;
}
@@ -433,18 +437,20 @@ static av_cold int alac_encode_init(AVCodecContext *avctx)
}
s->max_prediction_order = DEFAULT_MAX_PRED_ORDER;
- if(avctx->max_prediction_order >= 0) {
- if(avctx->max_prediction_order < MIN_LPC_ORDER ||
- avctx->max_prediction_order > ALAC_MAX_LPC_ORDER) {
- av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n", avctx->max_prediction_order);
+ if (avctx->max_prediction_order >= 0) {
+ if (avctx->max_prediction_order < MIN_LPC_ORDER ||
+ avctx->max_prediction_order > ALAC_MAX_LPC_ORDER) {
+ av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",
+ avctx->max_prediction_order);
return -1;
}
s->max_prediction_order = avctx->max_prediction_order;
}
- if(s->max_prediction_order < s->min_prediction_order) {
- av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n",
+ if (s->max_prediction_order < s->min_prediction_order) {
+ av_log(avctx, AV_LOG_ERROR,
+ "invalid prediction orders: min=%d max=%d\n",
s->min_prediction_order, s->max_prediction_order);
return -1;
}
@@ -469,12 +475,12 @@ static int alac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
PutBitContext *pb = &s->pbctx;
int i, out_bytes, verbatim_flag = 0;
- if(avctx->frame_size > DEFAULT_FRAME_SIZE) {
+ if (avctx->frame_size > DEFAULT_FRAME_SIZE) {
av_log(avctx, AV_LOG_ERROR, "input frame size exceeded\n");
return -1;
}
- if(buf_size < 2*s->max_coded_frame_size) {
+ if (buf_size < 2 * s->max_coded_frame_size) {
av_log(avctx, AV_LOG_ERROR, "buffer size is too small\n");
return -1;
}
@@ -482,11 +488,11 @@ static int alac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
verbatim:
init_put_bits(pb, frame, buf_size);
- if((s->compression_level == 0) || verbatim_flag) {
+ if (s->compression_level == 0 || verbatim_flag) {
// Verbatim mode
const int16_t *samples = data;
write_frame_header(s, 1);
- for(i=0; i<avctx->frame_size*avctx->channels; i++) {
+ for (i = 0; i < avctx->frame_size * avctx->channels; i++) {
put_sbits(pb, 16, *samples++);
}
} else {
@@ -499,9 +505,9 @@ verbatim:
flush_put_bits(pb);
out_bytes = put_bits_count(pb) >> 3;
- if(out_bytes > s->max_coded_frame_size) {
+ if (out_bytes > s->max_coded_frame_size) {
/* frame too large. use verbatim mode */
- if(verbatim_flag || (s->compression_level == 0)) {
+ if (verbatim_flag || s->compression_level == 0) {
/* still too large. must be an error. */
av_log(avctx, AV_LOG_ERROR, "error encoding frame\n");
return -1;
@@ -524,14 +530,15 @@ static av_cold int alac_encode_close(AVCodecContext *avctx)
}
AVCodec ff_alac_encoder = {
- "alac",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_ALAC,
- sizeof(AlacEncodeContext),
- alac_encode_init,
- alac_encode_frame,
- alac_encode_close,
+ .name = "alac",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ALAC,
+ .priv_data_size = sizeof(AlacEncodeContext),
+ .init = alac_encode_init,
+ .encode = alac_encode_frame,
+ .close = alac_encode_close,
.capabilities = CODEC_CAP_SMALL_LAST_FRAME,
- .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE},
+ .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
};
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 71b6094..3980982 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -57,6 +57,7 @@ void avcodec_register_all(void)
REGISTER_HWACCEL (H263_VAAPI, h263_vaapi);
REGISTER_HWACCEL (H264_DXVA2, h264_dxva2);
REGISTER_HWACCEL (H264_VAAPI, h264_vaapi);
+ REGISTER_HWACCEL (H264_VDA, h264_vda);
REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2);
REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi);
REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi);
@@ -81,11 +82,12 @@ void avcodec_register_all(void)
REGISTER_DECODER (BFI, bfi);
REGISTER_DECODER (BINK, bink);
REGISTER_ENCDEC (BMP, bmp);
+ REGISTER_DECODER (BMV_VIDEO, bmv_video);
REGISTER_DECODER (C93, c93);
REGISTER_DECODER (CAVS, cavs);
REGISTER_DECODER (CDGRAPHICS, cdgraphics);
REGISTER_DECODER (CINEPAK, cinepak);
- REGISTER_DECODER (CLJR, cljr);
+ REGISTER_ENCDEC (CLJR, cljr);
REGISTER_DECODER (CSCD, cscd);
REGISTER_DECODER (CYUV, cyuv);
REGISTER_DECODER (DFA, dfa);
@@ -94,6 +96,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (DSICINVIDEO, dsicinvideo);
REGISTER_ENCDEC (DVVIDEO, dvvideo);
REGISTER_DECODER (DXA, dxa);
+ REGISTER_DECODER (DXTORY, dxtory);
REGISTER_DECODER (EACMV, eacmv);
REGISTER_DECODER (EAMAD, eamad);
REGISTER_DECODER (EATGQ, eatgq);
@@ -106,6 +109,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (FFV1, ffv1);
REGISTER_ENCDEC (FFVHUFF, ffvhuff);
REGISTER_ENCDEC (FLASHSV, flashsv);
+ REGISTER_DECODER (FLASHSV2, flashsv2);
REGISTER_DECODER (FLIC, flic);
REGISTER_ENCDEC (FLV, flv);
REGISTER_DECODER (FOURXM, fourxm);
@@ -124,6 +128,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (IFF_ILBM, iff_ilbm);
REGISTER_DECODER (INDEO2, indeo2);
REGISTER_DECODER (INDEO3, indeo3);
+ REGISTER_DECODER (INDEO4, indeo4);
REGISTER_DECODER (INDEO5, indeo5);
REGISTER_DECODER (INTERPLAY_VIDEO, interplay_video);
REGISTER_ENCDEC (JPEGLS, jpegls);
@@ -144,7 +149,6 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video);
REGISTER_ENCDEC (MPEG4, mpeg4);
REGISTER_DECODER (MPEG4_VDPAU, mpeg4_vdpau);
- REGISTER_DECODER (MPEGVIDEO, mpegvideo);
REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau);
REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau);
REGISTER_DECODER (MSMPEG4V1, msmpeg4v1);
@@ -163,6 +167,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (PICTOR, pictor);
REGISTER_ENCDEC (PNG, png);
REGISTER_ENCDEC (PPM, ppm);
+ REGISTER_DECODER (PRORES, prores);
REGISTER_DECODER (PTX, ptx);
REGISTER_DECODER (QDRAW, qdraw);
REGISTER_DECODER (QPEG, qpeg);
@@ -197,11 +202,15 @@ void avcodec_register_all(void)
REGISTER_DECODER (TSCC, tscc);
REGISTER_DECODER (TXD, txd);
REGISTER_DECODER (ULTI, ulti);
+ REGISTER_DECODER (UTVIDEO, utvideo);
REGISTER_ENCDEC (V210, v210);
REGISTER_DECODER (V210X, v210x);
+ REGISTER_ENCDEC (V410, v410);
REGISTER_DECODER (VB, vb);
+ REGISTER_DECODER (VBLE, vble);
REGISTER_DECODER (VC1, vc1);
REGISTER_DECODER (VC1_VDPAU, vc1_vdpau);
+ REGISTER_DECODER (VC1IMAGE, vc1image);
REGISTER_DECODER (VCR1, vcr1);
REGISTER_DECODER (VMDVIDEO, vmdvideo);
REGISTER_DECODER (VMNC, vmnc);
@@ -216,6 +225,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (WMV2, wmv2);
REGISTER_DECODER (WMV3, wmv3);
REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau);
+ REGISTER_DECODER (WMV3IMAGE, wmv3image);
REGISTER_DECODER (WNV1, wnv1);
REGISTER_DECODER (XAN_WC3, xan_wc3);
REGISTER_DECODER (XAN_WC4, xan_wc4);
@@ -238,6 +248,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (ATRAC3, atrac3);
REGISTER_DECODER (BINKAUDIO_DCT, binkaudio_dct);
REGISTER_DECODER (BINKAUDIO_RDFT, binkaudio_rdft);
+ REGISTER_DECODER (BMV_AUDIO, bmv_audio);
REGISTER_DECODER (COOK, cook);
REGISTER_DECODER (DCA, dca);
REGISTER_DECODER (DSICINAUDIO, dsicinaudio);
@@ -293,6 +304,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (PCM_LXF, pcm_lxf);
REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw);
REGISTER_ENCDEC (PCM_S8, pcm_s8);
+ REGISTER_DECODER (PCM_S8_PLANAR, pcm_s8_planar);
REGISTER_ENCDEC (PCM_S16BE, pcm_s16be);
REGISTER_ENCDEC (PCM_S16LE, pcm_s16le);
REGISTER_DECODER (PCM_S16LE_PLANAR, pcm_s16le_planar);
@@ -308,7 +320,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (PCM_U24LE, pcm_u24le);
REGISTER_ENCDEC (PCM_U32BE, pcm_u32be);
REGISTER_ENCDEC (PCM_U32LE, pcm_u32le);
- REGISTER_ENCDEC (PCM_ZORK , pcm_zork);
+ REGISTER_DECODER (PCM_ZORK , pcm_zork);
/* DPCM codecs */
REGISTER_DECODER (INTERPLAY_DPCM, interplay_dpcm);
@@ -365,7 +377,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb);
REGISTER_DECODER (LIBOPENJPEG, libopenjpeg);
REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger);
- REGISTER_DECODER (LIBSPEEX, libspeex);
+ REGISTER_ENCDEC (LIBSPEEX, libspeex);
REGISTER_ENCODER (LIBTHEORA, libtheora);
REGISTER_ENCODER (LIBVO_AACENC, libvo_aacenc);
REGISTER_ENCODER (LIBVO_AMRWBENC, libvo_amrwbenc);
@@ -379,6 +391,7 @@ void avcodec_register_all(void)
REGISTER_PARSER (AAC, aac);
REGISTER_PARSER (AAC_LATM, aac_latm);
REGISTER_PARSER (AC3, ac3);
+ REGISTER_PARSER (ADX, adx);
REGISTER_PARSER (CAVSVIDEO, cavsvideo);
REGISTER_PARSER (DCA, dca);
REGISTER_PARSER (DIRAC, dirac);
@@ -395,6 +408,8 @@ void avcodec_register_all(void)
REGISTER_PARSER (MPEGAUDIO, mpegaudio);
REGISTER_PARSER (MPEGVIDEO, mpegvideo);
REGISTER_PARSER (PNM, pnm);
+ REGISTER_PARSER (RV30, rv30);
+ REGISTER_PARSER (RV40, rv40);
REGISTER_PARSER (VC1, vc1);
REGISTER_PARSER (VP3, vp3);
REGISTER_PARSER (VP8, vp8);
diff --git a/libavcodec/alpha/dsputil_alpha.c b/libavcodec/alpha/dsputil_alpha.c
index 32bb0fc..acd8e03 100644
--- a/libavcodec/alpha/dsputil_alpha.c
+++ b/libavcodec/alpha/dsputil_alpha.c
@@ -270,7 +270,7 @@ static void put_pixels16_axp_asm(uint8_t *block, const uint8_t *pixels,
void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx)
{
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
if (!high_bit_depth) {
c->put_pixels_tab[0][0] = put_pixels16_axp_asm;
@@ -321,7 +321,8 @@ void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx)
c->put_pixels_clamped = put_pixels_clamped_mvi_asm;
c->add_pixels_clamped = add_pixels_clamped_mvi_asm;
- c->get_pixels = get_pixels_mvi;
+ if (!high_bit_depth)
+ c->get_pixels = get_pixels_mvi;
c->diff_pixels = diff_pixels_mvi;
c->sad[0] = pix_abs16x16_mvi_asm;
c->sad[1] = pix_abs8x8_mvi;
@@ -335,7 +336,7 @@ void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx)
put_pixels_clamped_axp_p = c->put_pixels_clamped;
add_pixels_clamped_axp_p = c->add_pixels_clamped;
- if (!avctx->lowres &&
+ if (!avctx->lowres && avctx->bits_per_raw_sample <= 8 &&
(avctx->idct_algo == FF_IDCT_AUTO ||
avctx->idct_algo == FF_IDCT_SIMPLEALPHA)) {
c->idct_put = ff_simple_idct_put_axp;
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index 17c5490..dc4961c 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -191,6 +191,7 @@ typedef struct {
typedef struct {
AVCodecContext *avctx;
+ AVFrame frame;
ALSSpecificConfig sconf;
GetBitContext gb;
DSPContext dsp;
@@ -289,8 +290,8 @@ static av_cold int read_specific_config(ALSDecContext *ctx)
init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
- config_offset = ff_mpeg4audio_get_config(&m4ac, avctx->extradata,
- avctx->extradata_size);
+ config_offset = avpriv_mpeg4audio_get_config(&m4ac, avctx->extradata,
+ avctx->extradata_size * 8, 1);
if (config_offset < 0)
return -1;
@@ -393,7 +394,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx)
if (get_bits_left(&gb) < 32)
return -1;
- if (avctx->error_recognition >= FF_ER_CAREFUL) {
+ if (avctx->err_recognition & AV_EF_CRCCHECK) {
ctx->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
ctx->crc = 0xFFFFFFFF;
ctx->crc_org = ~get_bits_long(&gb, 32);
@@ -1415,15 +1416,14 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame)
/** Decode an ALS frame.
*/
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
AVPacket *avpkt)
{
ALSDecContext *ctx = avctx->priv_data;
ALSSpecificConfig *sconf = &ctx->sconf;
const uint8_t *buffer = avpkt->data;
int buffer_size = avpkt->size;
- int invalid_frame, size;
+ int invalid_frame, ret;
unsigned int c, sample, ra_frame, bytes_read, shift;
init_get_bits(&ctx->gb, buffer, buffer_size * 8);
@@ -1448,21 +1448,17 @@ static int decode_frame(AVCodecContext *avctx,
ctx->frame_id++;
- // check for size of decoded data
- size = ctx->cur_frame_length * avctx->channels *
- (av_get_bits_per_sample_fmt(avctx->sample_fmt) >> 3);
-
- if (size > *data_size) {
- av_log(avctx, AV_LOG_ERROR, "Decoded data exceeds buffer size.\n");
- return -1;
+ /* get output buffer */
+ ctx->frame.nb_samples = ctx->cur_frame_length;
+ if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
- *data_size = size;
-
// transform decoded frame into output format
#define INTERLEAVE_OUTPUT(bps) \
{ \
- int##bps##_t *dest = (int##bps##_t*) data; \
+ int##bps##_t *dest = (int##bps##_t*)ctx->frame.data[0]; \
shift = bps - ctx->avctx->bits_per_raw_sample; \
for (sample = 0; sample < ctx->cur_frame_length; sample++) \
for (c = 0; c < avctx->channels; c++) \
@@ -1476,11 +1472,11 @@ static int decode_frame(AVCodecContext *avctx,
}
// update CRC
- if (sconf->crc_enabled && avctx->error_recognition >= FF_ER_CAREFUL) {
+ if (sconf->crc_enabled && (avctx->err_recognition & AV_EF_CRCCHECK)) {
int swap = HAVE_BIGENDIAN != sconf->msb_first;
if (ctx->avctx->bits_per_raw_sample == 24) {
- int32_t *src = data;
+ int32_t *src = (int32_t *)ctx->frame.data[0];
for (sample = 0;
sample < ctx->cur_frame_length * avctx->channels;
@@ -1501,22 +1497,25 @@ static int decode_frame(AVCodecContext *avctx,
if (swap) {
if (ctx->avctx->bits_per_raw_sample <= 16) {
- int16_t *src = (int16_t*) data;
+ int16_t *src = (int16_t*) ctx->frame.data[0];
int16_t *dest = (int16_t*) ctx->crc_buffer;
for (sample = 0;
sample < ctx->cur_frame_length * avctx->channels;
sample++)
*dest++ = av_bswap16(src[sample]);
} else {
- ctx->dsp.bswap_buf((uint32_t*)ctx->crc_buffer, data,
+ ctx->dsp.bswap_buf((uint32_t*)ctx->crc_buffer,
+ (uint32_t *)ctx->frame.data[0],
ctx->cur_frame_length * avctx->channels);
}
crc_source = ctx->crc_buffer;
} else {
- crc_source = data;
+ crc_source = ctx->frame.data[0];
}
- ctx->crc = av_crc(ctx->crc_table, ctx->crc, crc_source, size);
+ ctx->crc = av_crc(ctx->crc_table, ctx->crc, crc_source,
+ ctx->cur_frame_length * avctx->channels *
+ av_get_bytes_per_sample(avctx->sample_fmt));
}
@@ -1527,6 +1526,9 @@ static int decode_frame(AVCodecContext *avctx,
}
}
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = ctx->frame;
+
bytes_read = invalid_frame ? buffer_size :
(get_bits_count(&ctx->gb) + 7) >> 3;
@@ -1710,11 +1712,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
// allocate crc buffer
if (HAVE_BIGENDIAN != sconf->msb_first && sconf->crc_enabled &&
- avctx->error_recognition >= FF_ER_CAREFUL) {
+ (avctx->err_recognition & AV_EF_CRCCHECK)) {
ctx->crc_buffer = av_malloc(sizeof(*ctx->crc_buffer) *
ctx->cur_frame_length *
avctx->channels *
- (av_get_bits_per_sample_fmt(avctx->sample_fmt) >> 3));
+ av_get_bytes_per_sample(avctx->sample_fmt));
if (!ctx->crc_buffer) {
av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
decode_end(avctx);
@@ -1724,6 +1726,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
dsputil_init(&ctx->dsp, avctx);
+ avcodec_get_frame_defaults(&ctx->frame);
+ avctx->coded_frame = &ctx->frame;
+
return 0;
}
@@ -1739,16 +1744,15 @@ static av_cold void flush(AVCodecContext *avctx)
AVCodec ff_als_decoder = {
- "als",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP4ALS,
- sizeof(ALSDecContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
+ .name = "als",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP4ALS,
+ .priv_data_size = sizeof(ALSDecContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
.flush = flush,
- .capabilities = CODEC_CAP_SUBFRAMES,
+ .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"),
};
diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c
index 1c90aad..926014f 100644
--- a/libavcodec/amrnbdec.c
+++ b/libavcodec/amrnbdec.c
@@ -83,7 +83,7 @@
/** Maximum sharpening factor
*
* The specification says 0.8, which should be 13107, but the reference C code
- * uses 13017 instead. (Amusingly the same applies to SHARP_MAX in g729dec.c.)
+ * uses 13017 instead. (Amusingly the same applies to SHARP_MAX in bitexact G.729.)
*/
#define SHARP_MAX 0.79449462890625
@@ -95,6 +95,7 @@
#define AMR_AGC_ALPHA 0.9
typedef struct AMRContext {
+ AVFrame avframe; ///< AVFrame for decoded samples
AMRNBFrame frame; ///< decoded AMR parameters (lsf coefficients, codebook indexes, etc)
uint8_t bad_frame_indicator; ///< bad frame ? 1 : 0
enum Mode cur_frame_mode;
@@ -167,6 +168,9 @@ static av_cold int amrnb_decode_init(AVCodecContext *avctx)
for (i = 0; i < 4; i++)
p->prediction_error[i] = MIN_ENERGY;
+ avcodec_get_frame_defaults(&p->avframe);
+ avctx->coded_frame = &p->avframe;
+
return 0;
}
@@ -649,7 +653,7 @@ static void decode_gains(AMRContext *p, const AMRNBSubframe *amr_subframe,
static void apply_ir_filter(float *out, const AMRFixed *in,
const float *filter)
{
- float filter1[AMR_SUBFRAME_SIZE], //!< filters at pitch lag*1 and *2
+ float filter1[AMR_SUBFRAME_SIZE], ///< filters at pitch lag*1 and *2
filter2[AMR_SUBFRAME_SIZE];
int lag = in->pitch_lag;
float fac = in->pitch_fac;
@@ -919,21 +923,29 @@ static void postfilter(AMRContext *p, float *lpc, float *buf_out)
/// @}
-static int amrnb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
- AVPacket *avpkt)
+static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
AMRContext *p = avctx->priv_data; // pointer to private data
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- float *buf_out = data; // pointer to the output data buffer
- int i, subframe;
+ float *buf_out; // pointer to the output data buffer
+ int i, subframe, ret;
float fixed_gain_factor;
AMRFixed fixed_sparse = {0}; // fixed vector up to anti-sparseness processing
float spare_vector[AMR_SUBFRAME_SIZE]; // extra stack space to hold result from anti-sparseness processing
float synth_fixed_gain; // the fixed gain that synthesis should use
const float *synth_fixed_vector; // pointer to the fixed vector that synthesis should use
+ /* get output buffer */
+ p->avframe.nb_samples = AMR_BLOCK_SIZE;
+ if ((ret = avctx->get_buffer(avctx, &p->avframe)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ buf_out = (float *)p->avframe.data[0];
+
p->cur_frame_mode = unpack_bitstream(p, buf, buf_size);
if (p->cur_frame_mode == MODE_DTX) {
av_log_missing_feature(avctx, "dtx mode", 1);
@@ -1028,8 +1040,8 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
ff_weighted_vector_sumf(p->lsf_avg, p->lsf_avg, p->lsf_q[3],
0.84, 0.16, LP_FILTER_ORDER);
- /* report how many samples we got */
- *data_size = AMR_BLOCK_SIZE * sizeof(float);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = p->avframe;
/* return the amount of bytes consumed if everything was OK */
return frame_sizes_nb[p->cur_frame_mode] + 1; // +7 for rounding and +8 for TOC
@@ -1043,6 +1055,7 @@ AVCodec ff_amrnb_decoder = {
.priv_data_size = sizeof(AMRContext),
.init = amrnb_decode_init,
.decode = amrnb_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Adaptive Multi-Rate NarrowBand"),
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE},
};
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index d4bb776..6ea5d22 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -41,6 +41,7 @@
#include "amrwbdata.h"
typedef struct {
+ AVFrame avframe; ///< AVFrame for decoded samples
AMRWBFrame frame; ///< AMRWB parameters decoded from bitstream
enum Mode fr_cur_mode; ///< mode index of current frame
uint8_t fr_quality; ///< frame quality index (FQI)
@@ -102,12 +103,15 @@ static av_cold int amrwb_decode_init(AVCodecContext *avctx)
for (i = 0; i < 4; i++)
ctx->prediction_error[i] = MIN_ENERGY;
+ avcodec_get_frame_defaults(&ctx->avframe);
+ avctx->coded_frame = &ctx->avframe;
+
return 0;
}
/**
* Decode the frame header in the "MIME/storage" format. This format
- * is simpler and does not carry the auxiliary information of the frame
+ * is simpler and does not carry the auxiliary frame information.
*
* @param[in] ctx The Context
* @param[in] buf Pointer to the input buffer
@@ -129,7 +133,7 @@ static int decode_mime_header(AMRWBContext *ctx, const uint8_t *buf)
}
/**
- * Decodes quantized ISF vectors using 36-bit indexes (6K60 mode only)
+ * Decode quantized ISF vectors using 36-bit indexes (6K60 mode only).
*
* @param[in] ind Array of 5 indexes
* @param[out] isf_q Buffer for isf_q[LP_ORDER]
@@ -156,7 +160,7 @@ static void decode_isf_indices_36b(uint16_t *ind, float *isf_q)
}
/**
- * Decodes quantized ISF vectors using 46-bit indexes (except 6K60 mode)
+ * Decode quantized ISF vectors using 46-bit indexes (except 6K60 mode).
*
* @param[in] ind Array of 7 indexes
* @param[out] isf_q Buffer for isf_q[LP_ORDER]
@@ -189,8 +193,8 @@ static void decode_isf_indices_46b(uint16_t *ind, float *isf_q)
}
/**
- * Apply mean and past ISF values using the prediction factor
- * Updates past ISF vector
+ * Apply mean and past ISF values using the prediction factor.
+ * Updates past ISF vector.
*
* @param[in,out] isf_q Current quantized ISF
* @param[in,out] isf_past Past quantized ISF
@@ -211,7 +215,7 @@ static void isf_add_mean_and_past(float *isf_q, float *isf_past)
/**
* Interpolate the fourth ISP vector from current and past frames
- * to obtain a ISP vector for each subframe
+ * to obtain an ISP vector for each subframe.
*
* @param[in,out] isp_q ISPs for each subframe
* @param[in] isp4_past Past ISP for subframe 4
@@ -228,9 +232,9 @@ static void interpolate_isp(double isp_q[4][LP_ORDER], const double *isp4_past)
}
/**
- * Decode an adaptive codebook index into pitch lag (except 6k60, 8k85 modes)
- * Calculate integer lag and fractional lag always using 1/4 resolution
- * In 1st and 3rd subframes the index is relative to last subframe integer lag
+ * Decode an adaptive codebook index into pitch lag (except 6k60, 8k85 modes).
+ * Calculate integer lag and fractional lag always using 1/4 resolution.
+ * In 1st and 3rd subframes the index is relative to last subframe integer lag.
*
* @param[out] lag_int Decoded integer pitch lag
* @param[out] lag_frac Decoded fractional pitch lag
@@ -267,9 +271,9 @@ static void decode_pitch_lag_high(int *lag_int, int *lag_frac, int pitch_index,
}
/**
- * Decode a adaptive codebook index into pitch lag for 8k85 and 6k60 modes
- * Description is analogous to decode_pitch_lag_high, but in 6k60 relative
- * index is used for all subframes except the first
+ * Decode an adaptive codebook index into pitch lag for 8k85 and 6k60 modes.
+ * The description is analogous to decode_pitch_lag_high, but in 6k60 the
+ * relative index is used for all subframes except the first.
*/
static void decode_pitch_lag_low(int *lag_int, int *lag_frac, int pitch_index,
uint8_t *base_lag_int, int subframe, enum Mode mode)
@@ -294,7 +298,7 @@ static void decode_pitch_lag_low(int *lag_int, int *lag_frac, int pitch_index,
/**
* Find the pitch vector by interpolating the past excitation at the
- * pitch delay, which is obtained in this function
+ * pitch delay, which is obtained in this function.
*
* @param[in,out] ctx The context
* @param[in] amr_subframe Current subframe data
@@ -347,10 +351,10 @@ static void decode_pitch_vector(AMRWBContext *ctx,
/**
* The next six functions decode_[i]p_track decode exactly i pulses
* positions and amplitudes (-1 or 1) in a subframe track using
- * an encoded pulse indexing (TS 26.190 section 5.8.2)
+ * an encoded pulse indexing (TS 26.190 section 5.8.2).
*
* The results are given in out[], in which a negative number means
- * amplitude -1 and vice versa (i.e., ampl(x) = x / abs(x) )
+ * amplitude -1 and vice versa (i.e., ampl(x) = x / abs(x) ).
*
* @param[out] out Output buffer (writes i elements)
* @param[in] code Pulse index (no. of bits varies, see below)
@@ -466,7 +470,7 @@ static void decode_6p_track(int *out, int code, int m, int off) ///code: 6m-2 bi
/**
* Decode the algebraic codebook index to pulse positions and signs,
- * then construct the algebraic codebook vector
+ * then construct the algebraic codebook vector.
*
* @param[out] fixed_vector Buffer for the fixed codebook excitation
* @param[in] pulse_hi MSBs part of the pulse index array (higher modes only)
@@ -537,7 +541,7 @@ static void decode_fixed_vector(float *fixed_vector, const uint16_t *pulse_hi,
}
/**
- * Decode pitch gain and fixed gain correction factor
+ * Decode pitch gain and fixed gain correction factor.
*
* @param[in] vq_gain Vector-quantized index for gains
* @param[in] mode Mode of the current frame
@@ -555,7 +559,7 @@ static void decode_gains(const uint8_t vq_gain, const enum Mode mode,
}
/**
- * Apply pitch sharpening filters to the fixed codebook vector
+ * Apply pitch sharpening filters to the fixed codebook vector.
*
* @param[in] ctx The context
* @param[in,out] fixed_vector Fixed codebook excitation
@@ -576,7 +580,7 @@ static void pitch_sharpening(AMRWBContext *ctx, float *fixed_vector)
}
/**
- * Calculate the voicing factor (-1.0 = unvoiced to 1.0 = voiced)
+ * Calculate the voicing factor (-1.0 = unvoiced to 1.0 = voiced).
*
* @param[in] p_vector, f_vector Pitch and fixed excitation vectors
* @param[in] p_gain, f_gain Pitch and fixed gains
@@ -595,8 +599,8 @@ static float voice_factor(float *p_vector, float p_gain,
}
/**
- * Reduce fixed vector sparseness by smoothing with one of three IR filters
- * Also known as "adaptive phase dispersion"
+ * Reduce fixed vector sparseness by smoothing with one of three IR filters,
+ * also known as "adaptive phase dispersion".
*
* @param[in] ctx The context
* @param[in,out] fixed_vector Unfiltered fixed vector
@@ -666,7 +670,7 @@ static float *anti_sparseness(AMRWBContext *ctx,
/**
* Calculate a stability factor {teta} based on distance between
- * current and past isf. A value of 1 shows maximum signal stability
+ * current and past isf. A value of 1 shows maximum signal stability.
*/
static float stability_factor(const float *isf, const float *isf_past)
{
@@ -683,7 +687,7 @@ static float stability_factor(const float *isf, const float *isf_past)
/**
* Apply a non-linear fixed gain smoothing in order to reduce
- * fluctuation in the energy of excitation
+ * fluctuation in the energy of excitation.
*
* @param[in] fixed_gain Unsmoothed fixed gain
* @param[in,out] prev_tr_gain Previous threshold gain (updated)
@@ -714,7 +718,7 @@ static float noise_enhancer(float fixed_gain, float *prev_tr_gain,
}
/**
- * Filter the fixed_vector to emphasize the higher frequencies
+ * Filter the fixed_vector to emphasize the higher frequencies.
*
* @param[in,out] fixed_vector Fixed codebook vector
* @param[in] voice_fac Frame voicing factor
@@ -738,7 +742,7 @@ static void pitch_enhancer(float *fixed_vector, float voice_fac)
}
/**
- * Conduct 16th order linear predictive coding synthesis from excitation
+ * Conduct 16th order linear predictive coding synthesis from excitation.
*
* @param[in] ctx Pointer to the AMRWBContext
* @param[in] lpc Pointer to the LPC coefficients
@@ -798,7 +802,7 @@ static void de_emphasis(float *out, float *in, float m, float mem[1])
/**
* Upsample a signal by 5/4 ratio (from 12.8kHz to 16kHz) using
- * a FIR interpolation filter. Uses past data from before *in address
+ * a FIR interpolation filter. Uses past data from before *in address.
*
* @param[out] out Buffer for interpolated signal
* @param[in] in Current signal data (length 0.8*o_size)
@@ -828,7 +832,7 @@ static void upsample_5_4(float *out, const float *in, int o_size)
/**
* Calculate the high-band gain based on encoded index (23k85 mode) or
- * on the low-band speech signal and the Voice Activity Detection flag
+ * on the low-band speech signal and the Voice Activity Detection flag.
*
* @param[in] ctx The context
* @param[in] synth LB speech synthesis at 12.8k
@@ -853,7 +857,7 @@ static float find_hb_gain(AMRWBContext *ctx, const float *synth,
/**
* Generate the high-band excitation with the same energy from the lower
- * one and scaled by the given gain
+ * one and scaled by the given gain.
*
* @param[in] ctx The context
* @param[out] hb_exc Buffer for the excitation
@@ -876,7 +880,7 @@ static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc,
}
/**
- * Calculate the auto-correlation for the ISF difference vector
+ * Calculate the auto-correlation for the ISF difference vector.
*/
static float auto_correlation(float *diff_isf, float mean, int lag)
{
@@ -892,7 +896,7 @@ static float auto_correlation(float *diff_isf, float mean, int lag)
/**
* Extrapolate a ISF vector to the 16kHz range (20th order LP)
- * used at mode 6k60 LP filter for the high frequency band
+ * used at mode 6k60 LP filter for the high frequency band.
*
* @param[out] out Buffer for extrapolated isf
* @param[in] isf Input isf vector
@@ -977,7 +981,7 @@ static void lpc_weighting(float *out, const float *lpc, float gamma, int size)
/**
* Conduct 20th order linear predictive coding synthesis for the high
- * frequency band excitation at 16kHz
+ * frequency band excitation at 16kHz.
*
* @param[in] ctx The context
* @param[in] subframe Current subframe index (0 to 3)
@@ -1015,8 +1019,8 @@ static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples,
}
/**
- * Apply to high-band samples a 15th order filter
- * The filter characteristic depends on the given coefficients
+ * Apply a 15th order filter to high-band samples.
+ * The filter characteristic depends on the given coefficients.
*
* @param[out] out Buffer for filtered output
* @param[in] fir_coef Filter coefficients
@@ -1044,7 +1048,7 @@ static void hb_fir_filter(float *out, const float fir_coef[HB_FIR_SIZE + 1],
}
/**
- * Update context state before the next subframe
+ * Update context state before the next subframe.
*/
static void update_sub_state(AMRWBContext *ctx)
{
@@ -1062,15 +1066,15 @@ static void update_sub_state(AMRWBContext *ctx)
LP_ORDER_16k * sizeof(float));
}
-static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
- AVPacket *avpkt)
+static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
AMRWBContext *ctx = avctx->priv_data;
AMRWBFrame *cf = &ctx->frame;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
int expected_fr_size, header_size;
- float *buf_out = data;
+ float *buf_out;
float spare_vector[AMRWB_SFR_SIZE]; // extra stack space to hold result from anti-sparseness processing
float fixed_gain_factor; // fixed gain correction factor (gamma)
float *synth_fixed_vector; // pointer to the fixed vector that synthesis should use
@@ -1080,7 +1084,15 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
float hb_exc[AMRWB_SFR_SIZE_16k]; // excitation for the high frequency band
float hb_samples[AMRWB_SFR_SIZE_16k]; // filtered high-band samples from synthesis
float hb_gain;
- int sub, i;
+ int sub, i, ret;
+
+ /* get output buffer */
+ ctx->avframe.nb_samples = 4 * AMRWB_SFR_SIZE_16k;
+ if ((ret = avctx->get_buffer(avctx, &ctx->avframe)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ buf_out = (float *)ctx->avframe.data[0];
header_size = decode_mime_header(ctx, buf);
expected_fr_size = ((cf_sizes_wb[ctx->fr_cur_mode] + 7) >> 3) + 1;
@@ -1088,7 +1100,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
if (buf_size < expected_fr_size) {
av_log(avctx, AV_LOG_ERROR,
"Frame too small (%d bytes). Truncated file?\n", buf_size);
- *data_size = 0;
+ *got_frame_ptr = 0;
return buf_size;
}
@@ -1219,8 +1231,8 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(ctx->isp[3][0]));
memcpy(ctx->isf_past_final, ctx->isf_cur, LP_ORDER * sizeof(float));
- /* report how many samples we got */
- *data_size = 4 * AMRWB_SFR_SIZE_16k * sizeof(float);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = ctx->avframe;
return expected_fr_size;
}
@@ -1232,6 +1244,7 @@ AVCodec ff_amrwb_decoder = {
.priv_data_size = sizeof(AMRWBContext),
.init = amrwb_decode_init,
.decode = amrwb_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Adaptive Multi-Rate WideBand"),
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE},
};
diff --git a/libavcodec/anm.c b/libavcodec/anm.c
index ef037f2..59de984 100644
--- a/libavcodec/anm.c
+++ b/libavcodec/anm.c
@@ -81,6 +81,8 @@ static inline int op(uint8_t **dst, const uint8_t *dst_end,
int striplen = FFMIN(count, remaining);
if (buf) {
striplen = FFMIN(striplen, buf_end - *buf);
+ if (*buf >= buf_end)
+ goto exhausted;
memcpy(*dst, *buf, striplen);
*buf += striplen;
} else if (pixel >= 0)
@@ -184,14 +186,13 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_anm_decoder = {
- "anm",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ANM,
- sizeof(AnmContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "anm",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ANM,
+ .priv_data_size = sizeof(AnmContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
};
diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c
index e46879d..32c7ce4 100644
--- a/libavcodec/ansi.c
+++ b/libavcodec/ansi.c
@@ -153,7 +153,7 @@ static void draw_char(AVCodecContext *avctx, int c)
/**
* Execute ANSI escape code
- * @param <0 error
+ * @return 0 on success, negative on error
*/
static int execute_code(AVCodecContext * avctx, int c)
{
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index f92b375..fa50d61 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -20,12 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "dsputil.h"
#include "get_bits.h"
#include "bytestream.h"
#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
/**
* @file
@@ -128,6 +129,7 @@ typedef struct APEPredictor {
/** Decoder context */
typedef struct APEContext {
AVCodecContext *avctx;
+ AVFrame frame;
DSPContext dsp;
int channels;
int samples; ///< samples left to decode in current frame
@@ -139,8 +141,6 @@ typedef struct APEContext {
uint32_t CRC; ///< frame CRC
int frameflags; ///< frame flags
- int currentframeblocks; ///< samples (per channel) in current frame
- int blocksdecoded; ///< count of decoded samples in current frame
APEPredictor predictor; ///< predictor used for final reconstruction
int32_t decoded0[BLOCKS_PER_LOOP]; ///< decoded data for the first channel
@@ -156,29 +156,40 @@ typedef struct APEContext {
uint8_t *data; ///< current frame data
uint8_t *data_end; ///< frame data end
const uint8_t *ptr; ///< current position in frame data
- const uint8_t *last_ptr; ///< position where last 4608-sample block ended
int error;
} APEContext;
// TODO: dsputilize
-static av_cold int ape_decode_init(AVCodecContext * avctx)
+static av_cold int ape_decode_close(AVCodecContext *avctx)
+{
+ APEContext *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < APE_FILTER_LEVELS; i++)
+ av_freep(&s->filterbuf[i]);
+
+ av_freep(&s->data);
+ return 0;
+}
+
+static av_cold int ape_decode_init(AVCodecContext *avctx)
{
APEContext *s = avctx->priv_data;
int i;
if (avctx->extradata_size != 6) {
av_log(avctx, AV_LOG_ERROR, "Incorrect extradata\n");
- return -1;
+ return AVERROR(EINVAL);
}
if (avctx->bits_per_coded_sample != 16) {
av_log(avctx, AV_LOG_ERROR, "Only 16-bit samples are supported\n");
- return -1;
+ return AVERROR(EINVAL);
}
if (avctx->channels > 2) {
av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n");
- return -1;
+ return AVERROR(EINVAL);
}
s->avctx = avctx;
s->channels = avctx->channels;
@@ -186,34 +197,33 @@ static av_cold int ape_decode_init(AVCodecContext * avctx)
s->compression_level = AV_RL16(avctx->extradata + 2);
s->flags = AV_RL16(avctx->extradata + 4);
- av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n", s->compression_level, s->flags);
+ av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n",
+ s->compression_level, s->flags);
if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE) {
- av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n", s->compression_level);
- return -1;
+ av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n",
+ s->compression_level);
+ return AVERROR_INVALIDDATA;
}
s->fset = s->compression_level / 1000 - 1;
for (i = 0; i < APE_FILTER_LEVELS; i++) {
if (!ape_filter_orders[s->fset][i])
break;
- s->filterbuf[i] = av_malloc((ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4);
+ FF_ALLOC_OR_GOTO(avctx, s->filterbuf[i],
+ (ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4,
+ filter_alloc_fail);
}
dsputil_init(&s->dsp, avctx);
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
- return 0;
-}
-static av_cold int ape_decode_close(AVCodecContext * avctx)
-{
- APEContext *s = avctx->priv_data;
- int i;
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
- for (i = 0; i < APE_FILTER_LEVELS; i++)
- av_freep(&s->filterbuf[i]);
-
- av_freep(&s->data);
return 0;
+filter_alloc_fail:
+ ape_decode_close(avctx);
+ return AVERROR(ENOMEM);
}
/**
@@ -228,7 +238,7 @@ static av_cold int ape_decode_close(AVCodecContext * avctx)
#define BOTTOM_VALUE (TOP_VALUE >> 8)
/** Start the decoder */
-static inline void range_start_decoding(APEContext * ctx)
+static inline void range_start_decoding(APEContext *ctx)
{
ctx->rc.buffer = bytestream_get_byte(&ctx->ptr);
ctx->rc.low = ctx->rc.buffer >> (8 - EXTRA_BITS);
@@ -236,13 +246,16 @@ static inline void range_start_decoding(APEContext * ctx)
}
/** Perform normalization */
-static inline void range_dec_normalize(APEContext * ctx)
+static inline void range_dec_normalize(APEContext *ctx)
{
while (ctx->rc.range <= BOTTOM_VALUE) {
ctx->rc.buffer <<= 8;
- if(ctx->ptr < ctx->data_end)
+ if(ctx->ptr < ctx->data_end) {
ctx->rc.buffer += *ctx->ptr;
- ctx->ptr++;
+ ctx->ptr++;
+ } else {
+ ctx->error = 1;
+ }
ctx->rc.low = (ctx->rc.low << 8) | ((ctx->rc.buffer >> 1) & 0xFF);
ctx->rc.range <<= 8;
}
@@ -254,7 +267,7 @@ static inline void range_dec_normalize(APEContext * ctx)
* @param tot_f is the total frequency or (code_value)1<<shift
* @return the culmulative frequency
*/
-static inline int range_decode_culfreq(APEContext * ctx, int tot_f)
+static inline int range_decode_culfreq(APEContext *ctx, int tot_f)
{
range_dec_normalize(ctx);
ctx->rc.help = ctx->rc.range / tot_f;
@@ -266,7 +279,7 @@ static inline int range_decode_culfreq(APEContext * ctx, int tot_f)
* @param ctx decoder context
* @param shift number of bits to decode
*/
-static inline int range_decode_culshift(APEContext * ctx, int shift)
+static inline int range_decode_culshift(APEContext *ctx, int shift)
{
range_dec_normalize(ctx);
ctx->rc.help = ctx->rc.range >> shift;
@@ -280,14 +293,14 @@ static inline int range_decode_culshift(APEContext * ctx, int shift)
* @param sy_f the interval length (frequency of the symbol)
* @param lt_f the lower end (frequency sum of < symbols)
*/
-static inline void range_decode_update(APEContext * ctx, int sy_f, int lt_f)
+static inline void range_decode_update(APEContext *ctx, int sy_f, int lt_f)
{
ctx->rc.low -= ctx->rc.help * lt_f;
ctx->rc.range = ctx->rc.help * sy_f;
}
/** Decode n bits (n <= 16) without modelling */
-static inline int range_decode_bits(APEContext * ctx, int n)
+static inline int range_decode_bits(APEContext *ctx, int n)
{
int sym = range_decode_culshift(ctx, n);
range_decode_update(ctx, 1, sym);
@@ -339,7 +352,7 @@ static const uint16_t counts_diff_3980[21] = {
* @param counts probability range start position
* @param counts_diff probability range widths
*/
-static inline int range_get_symbol(APEContext * ctx,
+static inline int range_get_symbol(APEContext *ctx,
const uint16_t counts[],
const uint16_t counts_diff[])
{
@@ -374,7 +387,7 @@ static inline void update_rice(APERice *rice, int x)
rice->k++;
}
-static inline int ape_decode_value(APEContext * ctx, APERice *rice)
+static inline int ape_decode_value(APEContext *ctx, APERice *rice)
{
int x, overflow;
@@ -441,13 +454,11 @@ static inline int ape_decode_value(APEContext * ctx, APERice *rice)
return -(x >> 1);
}
-static void entropy_decode(APEContext * ctx, int blockstodecode, int stereo)
+static void entropy_decode(APEContext *ctx, int blockstodecode, int stereo)
{
int32_t *decoded0 = ctx->decoded0;
int32_t *decoded1 = ctx->decoded1;
- ctx->blocksdecoded = blockstodecode;
-
if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
/* We are pure silence, just memset the output buffer. */
memset(decoded0, 0, blockstodecode * sizeof(int32_t));
@@ -459,14 +470,13 @@ static void entropy_decode(APEContext * ctx, int blockstodecode, int stereo)
*decoded1++ = ape_decode_value(ctx, &ctx->riceX);
}
}
-
- if (ctx->blocksdecoded == ctx->currentframeblocks)
- range_dec_normalize(ctx); /* normalize to use up all bytes */
}
-static void init_entropy_decoder(APEContext * ctx)
+static int init_entropy_decoder(APEContext *ctx)
{
/* Read the CRC */
+ if (ctx->data_end - ctx->ptr < 6)
+ return AVERROR_INVALIDDATA;
ctx->CRC = bytestream_get_be32(&ctx->ptr);
/* Read the frame flags if they exist */
@@ -474,12 +484,11 @@ static void init_entropy_decoder(APEContext * ctx)
if ((ctx->fileversion > 3820) && (ctx->CRC & 0x80000000)) {
ctx->CRC &= ~0x80000000;
+ if (ctx->data_end - ctx->ptr < 6)
+ return AVERROR_INVALIDDATA;
ctx->frameflags = bytestream_get_be32(&ctx->ptr);
}
- /* Keep a count of the blocks decoded in this frame */
- ctx->blocksdecoded = 0;
-
/* Initialize the rice structs */
ctx->riceX.k = 10;
ctx->riceX.ksum = (1 << ctx->riceX.k) * 16;
@@ -490,13 +499,15 @@ static void init_entropy_decoder(APEContext * ctx)
ctx->ptr++;
range_start_decoding(ctx);
+
+ return 0;
}
static const int32_t initial_coeffs[4] = {
360, 317, -109, 98
};
-static void init_predictor_decoder(APEContext * ctx)
+static void init_predictor_decoder(APEContext *ctx)
{
APEPredictor *p = &ctx->predictor;
@@ -519,7 +530,10 @@ static inline int APESIGN(int32_t x) {
return (x < 0) - (x > 0);
}
-static av_always_inline int predictor_update_filter(APEPredictor *p, const int decoded, const int filter, const int delayA, const int delayB, const int adaptA, const int adaptB)
+static av_always_inline int predictor_update_filter(APEPredictor *p,
+ const int decoded, const int filter,
+ const int delayA, const int delayB,
+ const int adaptA, const int adaptB)
{
int32_t predictionA, predictionB, sign;
@@ -563,7 +577,7 @@ static av_always_inline int predictor_update_filter(APEPredictor *p, const int d
return p->filterA[filter];
}
-static void predictor_decode_stereo(APEContext * ctx, int count)
+static void predictor_decode_stereo(APEContext *ctx, int count)
{
APEPredictor *p = &ctx->predictor;
int32_t *decoded0 = ctx->decoded0;
@@ -571,9 +585,11 @@ static void predictor_decode_stereo(APEContext * ctx, int count)
while (count--) {
/* Predictor Y */
- *decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, YADAPTCOEFFSA, YADAPTCOEFFSB);
+ *decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB,
+ YADAPTCOEFFSA, YADAPTCOEFFSB);
decoded0++;
- *decoded1 = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, XADAPTCOEFFSA, XADAPTCOEFFSB);
+ *decoded1 = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB,
+ XADAPTCOEFFSA, XADAPTCOEFFSB);
decoded1++;
/* Combined */
@@ -587,7 +603,7 @@ static void predictor_decode_stereo(APEContext * ctx, int count)
}
}
-static void predictor_decode_mono(APEContext * ctx, int count)
+static void predictor_decode_mono(APEContext *ctx, int count)
{
APEPredictor *p = &ctx->predictor;
int32_t *decoded0 = ctx->decoded0;
@@ -632,7 +648,7 @@ static void predictor_decode_mono(APEContext * ctx, int count)
p->lastA[0] = currentA;
}
-static void do_init_filter(APEFilter *f, int16_t * buf, int order)
+static void do_init_filter(APEFilter *f, int16_t *buf, int order)
{
f->coeffs = buf;
f->historybuffer = buf + order;
@@ -644,20 +660,23 @@ static void do_init_filter(APEFilter *f, int16_t * buf, int order)
f->avg = 0;
}
-static void init_filter(APEContext * ctx, APEFilter *f, int16_t * buf, int order)
+static void init_filter(APEContext *ctx, APEFilter *f, int16_t *buf, int order)
{
do_init_filter(&f[0], buf, order);
do_init_filter(&f[1], buf + order * 3 + HISTORY_SIZE, order);
}
-static void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t *data, int count, int order, int fracbits)
+static 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 = ctx->dsp.scalarproduct_and_madd_int16(f->coeffs, f->delay - order, f->adaptcoeffs - order, order, APESIGN(*data));
+ res = ctx->dsp.scalarproduct_and_madd_int16(f->coeffs, f->delay - order,
+ f->adaptcoeffs - order,
+ order, APESIGN(*data));
res = (res + (1 << (fracbits - 1))) >> fracbits;
res += *data;
*data++ = res;
@@ -676,7 +695,8 @@ static void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t
/* Update the adaption coefficients */
absres = FFABS(res);
if (absres)
- *f->adaptcoeffs = ((res & (1<<31)) - (1<<30)) >> (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3));
+ *f->adaptcoeffs = ((res & (-1<<31)) ^ (-1<<30)) >>
+ (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3));
else
*f->adaptcoeffs = 0;
@@ -699,8 +719,8 @@ static void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t
}
}
-static void apply_filter(APEContext * ctx, APEFilter *f,
- int32_t * data0, int32_t * data1,
+static void apply_filter(APEContext *ctx, APEFilter *f,
+ int32_t *data0, int32_t *data1,
int count, int order, int fracbits)
{
do_apply_filter(ctx, ctx->fileversion, &f[0], data0, count, order, fracbits);
@@ -708,34 +728,38 @@ static void apply_filter(APEContext * ctx, APEFilter *f,
do_apply_filter(ctx, ctx->fileversion, &f[1], data1, count, order, fracbits);
}
-static void ape_apply_filters(APEContext * ctx, int32_t * decoded0,
- int32_t * decoded1, int count)
+static void ape_apply_filters(APEContext *ctx, int32_t *decoded0,
+ int32_t *decoded1, int count)
{
int i;
for (i = 0; i < APE_FILTER_LEVELS; i++) {
if (!ape_filter_orders[ctx->fset][i])
break;
- apply_filter(ctx, ctx->filters[i], decoded0, decoded1, count, ape_filter_orders[ctx->fset][i], ape_filter_fracbits[ctx->fset][i]);
+ apply_filter(ctx, ctx->filters[i], decoded0, decoded1, count,
+ ape_filter_orders[ctx->fset][i],
+ ape_filter_fracbits[ctx->fset][i]);
}
}
-static void init_frame_decoder(APEContext * ctx)
+static int init_frame_decoder(APEContext *ctx)
{
- int i;
- init_entropy_decoder(ctx);
+ int i, ret;
+ if ((ret = init_entropy_decoder(ctx)) < 0)
+ return ret;
init_predictor_decoder(ctx);
for (i = 0; i < APE_FILTER_LEVELS; i++) {
if (!ape_filter_orders[ctx->fset][i])
break;
- init_filter(ctx, ctx->filters[i], ctx->filterbuf[i], ape_filter_orders[ctx->fset][i]);
+ init_filter(ctx, ctx->filters[i], ctx->filterbuf[i],
+ ape_filter_orders[ctx->fset][i]);
}
+ return 0;
}
-static void ape_unpack_mono(APEContext * ctx, int count)
+static void ape_unpack_mono(APEContext *ctx, int count)
{
- int32_t left;
int32_t *decoded0 = ctx->decoded0;
int32_t *decoded1 = ctx->decoded1;
@@ -754,14 +778,11 @@ static void ape_unpack_mono(APEContext * ctx, int count)
/* Pseudo-stereo - just copy left channel to right channel */
if (ctx->channels == 2) {
- while (count--) {
- left = *decoded0;
- *(decoded1++) = *(decoded0++) = left;
- }
+ memcpy(decoded1, decoded0, count * sizeof(*decoded1));
}
}
-static void ape_unpack_stereo(APEContext * ctx, int count)
+static void ape_unpack_stereo(APEContext *ctx, int count)
{
int32_t left, right;
int32_t *decoded0 = ctx->decoded0;
@@ -789,66 +810,87 @@ static void ape_unpack_stereo(APEContext * ctx, int count)
}
}
-static int ape_decode_frame(AVCodecContext * avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int ape_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
APEContext *s = avctx->priv_data;
- int16_t *samples = data;
- int nblocks;
- int i, n;
+ int16_t *samples;
+ int i, ret;
int blockstodecode;
- int bytes_used;
+ int bytes_used = 0;
- if (buf_size == 0 && !s->samples) {
- *data_size = 0;
- return 0;
- }
-
- /* should not happen but who knows */
- if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) {
- av_log (avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc! (max is %d where you have %d)\n", *data_size, s->samples * 2 * avctx->channels);
- return -1;
- }
+ /* this should never be negative, but bad things will happen if it is, so
+ check it just to make sure. */
+ av_assert0(s->samples >= 0);
if(!s->samples){
- s->data = av_realloc(s->data, (buf_size + 3) & ~3);
+ uint32_t nblocks, offset;
+ void *tmp_data;
+
+ if (!buf_size) {
+ *got_frame_ptr = 0;
+ return 0;
+ }
+ if (buf_size < 8) {
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ tmp_data = av_realloc(s->data, FFALIGN(buf_size, 4));
+ if (!tmp_data)
+ return AVERROR(ENOMEM);
+ s->data = tmp_data;
s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2);
- s->ptr = s->last_ptr = s->data;
+ s->ptr = s->data;
s->data_end = s->data + buf_size;
- nblocks = s->samples = bytestream_get_be32(&s->ptr);
- n = bytestream_get_be32(&s->ptr);
- if(n < 0 || n > 3){
+ nblocks = bytestream_get_be32(&s->ptr);
+ offset = bytestream_get_be32(&s->ptr);
+ if (offset > 3) {
av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n");
s->data = NULL;
- return -1;
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->data_end - s->ptr < offset) {
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+ return AVERROR_INVALIDDATA;
}
- s->ptr += n;
+ s->ptr += offset;
- s->currentframeblocks = nblocks;
- buf += 4;
- if (s->samples <= 0) {
- *data_size = 0;
- return buf_size;
+ if (!nblocks || nblocks > INT_MAX) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks);
+ return AVERROR_INVALIDDATA;
}
+ s->samples = nblocks;
memset(s->decoded0, 0, sizeof(s->decoded0));
memset(s->decoded1, 0, sizeof(s->decoded1));
/* Initialize the frame decoder */
- init_frame_decoder(s);
+ if (init_frame_decoder(s) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error reading frame header\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ bytes_used = buf_size;
}
if (!s->data) {
- *data_size = 0;
+ *got_frame_ptr = 0;
return buf_size;
}
- nblocks = s->samples;
- blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks);
+ blockstodecode = FFMIN(BLOCKS_PER_LOOP, s->samples);
+
+ /* get output buffer */
+ s->frame.nb_samples = blockstodecode;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (int16_t *)s->frame.data[0];
s->error=0;
@@ -858,10 +900,10 @@ static int ape_decode_frame(AVCodecContext * avctx,
ape_unpack_stereo(s, blockstodecode);
emms_c();
- if(s->error || s->ptr > s->data_end){
+ if (s->error) {
s->samples=0;
av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
for (i = 0; i < blockstodecode; i++) {
@@ -872,9 +914,9 @@ static int ape_decode_frame(AVCodecContext * avctx,
s->samples -= blockstodecode;
- *data_size = blockstodecode * 2 * s->channels;
- bytes_used = s->samples ? s->ptr - s->last_ptr : buf_size;
- s->last_ptr = s->ptr;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return bytes_used;
}
@@ -885,15 +927,14 @@ static void ape_flush(AVCodecContext *avctx)
}
AVCodec ff_ape_decoder = {
- "ape",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_APE,
- sizeof(APEContext),
- ape_decode_init,
- NULL,
- ape_decode_close,
- ape_decode_frame,
- .capabilities = CODEC_CAP_SUBFRAMES,
+ .name = "ape",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_APE,
+ .priv_data_size = sizeof(APEContext),
+ .init = ape_decode_init,
+ .close = ape_decode_close,
+ .decode = ape_decode_frame,
+ .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DELAY | CODEC_CAP_DR1,
.flush = ape_flush,
.long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
};
diff --git a/libavcodec/api-example.c b/libavcodec/api-example.c
index 0221a30..970a90e 100644
--- a/libavcodec/api-example.c
+++ b/libavcodec/api-example.c
@@ -20,8 +20,9 @@
/**
* @file
- * avcodec API use example.
+ * libavcodec API use example.
*
+ * @example libavcodec/api-example.c
* Note that this library only handles codecs (mpeg, mpeg4, etc...),
* not file formats (avi, vob, etc...). See library 'libavformat' for the
* format handling
@@ -37,6 +38,7 @@
#include "libavcodec/avcodec.h"
#include "libavutil/mathematics.h"
+#include "libavutil/samplefmt.h"
#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
@@ -64,7 +66,7 @@ static void audio_encode_example(const char *filename)
exit(1);
}
- c= avcodec_alloc_context();
+ c = avcodec_alloc_context3(codec);
/* put sample parameters */
c->bit_rate = 64000;
@@ -117,11 +119,11 @@ static void audio_decode_example(const char *outfilename, const char *filename)
{
AVCodec *codec;
AVCodecContext *c= NULL;
- int out_size, len;
+ int len;
FILE *f, *outfile;
- uint8_t *outbuf;
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;
+ AVFrame *decoded_frame = NULL;
av_init_packet(&avpkt);
@@ -134,7 +136,7 @@ static void audio_decode_example(const char *outfilename, const char *filename)
exit(1);
}
- c= avcodec_alloc_context();
+ c = avcodec_alloc_context3(codec);
/* open it */
if (avcodec_open(c, codec) < 0) {
@@ -142,8 +144,6 @@ static void audio_decode_example(const char *outfilename, const char *filename)
exit(1);
}
- outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
-
f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "could not open %s\n", filename);
@@ -160,15 +160,27 @@ static void audio_decode_example(const char *outfilename, const char *filename)
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
while (avpkt.size > 0) {
- out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
- len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);
+ int got_frame = 0;
+
+ if (!decoded_frame) {
+ if (!(decoded_frame = avcodec_alloc_frame())) {
+ fprintf(stderr, "out of memory\n");
+ exit(1);
+ }
+ } else
+ avcodec_get_frame_defaults(decoded_frame);
+
+ len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
if (len < 0) {
fprintf(stderr, "Error while decoding\n");
exit(1);
}
- if (out_size > 0) {
+ if (got_frame) {
/* if a frame has been decoded, output it */
- fwrite(outbuf, 1, out_size, outfile);
+ int data_size = av_samples_get_buffer_size(NULL, c->channels,
+ decoded_frame->nb_samples,
+ c->sample_fmt, 1);
+ fwrite(decoded_frame->data[0], 1, data_size, outfile);
}
avpkt.size -= len;
avpkt.data += len;
@@ -188,10 +200,10 @@ static void audio_decode_example(const char *outfilename, const char *filename)
fclose(outfile);
fclose(f);
- free(outbuf);
avcodec_close(c);
av_free(c);
+ av_free(decoded_frame);
}
/*
@@ -215,7 +227,7 @@ static void video_encode_example(const char *filename)
exit(1);
}
- c= avcodec_alloc_context();
+ c = avcodec_alloc_context3(codec);
picture= avcodec_alloc_frame();
/* put sample parameters */
@@ -346,7 +358,7 @@ static void video_decode_example(const char *outfilename, const char *filename)
exit(1);
}
- c= avcodec_alloc_context();
+ c = avcodec_alloc_context3(codec);
picture= avcodec_alloc_frame();
if(codec->capabilities&CODEC_CAP_TRUNCATED)
diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile
index 3374f0e..fc17113 100644
--- a/libavcodec/arm/Makefile
+++ b/libavcodec/arm/Makefile
@@ -54,6 +54,7 @@ NEON-OBJS-$(CONFIG_RDFT) += arm/rdft_neon.o \
NEON-OBJS-$(CONFIG_H264DSP) += arm/h264dsp_neon.o \
arm/h264idct_neon.o \
+ arm/h264cmc_neon.o \
NEON-OBJS-$(CONFIG_H264PRED) += arm/h264pred_neon.o \
@@ -62,6 +63,15 @@ NEON-OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_neon.o
NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_neon.o \
arm/synth_filter_neon.o \
+NEON-OBJS-$(CONFIG_RV30_DECODER) += arm/rv34dsp_init_neon.o \
+ arm/rv34dsp_neon.o \
+
+NEON-OBJS-$(CONFIG_RV40_DECODER) += arm/rv34dsp_init_neon.o \
+ arm/rv34dsp_neon.o \
+ arm/rv40dsp_init_neon.o \
+ arm/rv40dsp_neon.o \
+ arm/h264cmc_neon.o \
+
NEON-OBJS-$(CONFIG_VP3_DECODER) += arm/vp3dsp_neon.o
NEON-OBJS-$(CONFIG_VP5_DECODER) += arm/vp56dsp_neon.o \
diff --git a/libavcodec/arm/aac.h b/libavcodec/arm/aac.h
index 6d5df49..83b5aef 100644
--- a/libavcodec/arm/aac.h
+++ b/libavcodec/arm/aac.h
@@ -114,12 +114,15 @@ static inline float *VMUL4S(float *dst, const float *v, unsigned idx,
"vmov d1, %2, %3 \n\t"
"lsls %6, %6, #1 \n\t"
"and %0, %5, #1<<31 \n\t"
+ "it cs \n\t"
"lslcs %5, %5, #1 \n\t"
"lsls %6, %6, #1 \n\t"
"and %1, %5, #1<<31 \n\t"
+ "it cs \n\t"
"lslcs %5, %5, #1 \n\t"
"lsls %6, %6, #1 \n\t"
"and %2, %5, #1<<31 \n\t"
+ "it cs \n\t"
"lslcs %5, %5, #1 \n\t"
"vmov d4, %0, %1 \n\t"
"and %3, %5, #1<<31 \n\t"
diff --git a/libavcodec/arm/ac3dsp_arm.S b/libavcodec/arm/ac3dsp_arm.S
index 545714c..9a7d20e 100644
--- a/libavcodec/arm/ac3dsp_arm.S
+++ b/libavcodec/arm/ac3dsp_arm.S
@@ -27,6 +27,7 @@ function ff_ac3_update_bap_counts_arm, export=1
lsl r3, lr, #1
ldrh r12, [r0, r3]
subs r2, r2, #1
+ it gt
ldrbgt lr, [r1], #1
add r12, r12, #1
strh r12, [r0, r3]
diff --git a/libavcodec/arm/ac3dsp_armv6.S b/libavcodec/arm/ac3dsp_armv6.S
index 8026cb7..b6aee86 100644
--- a/libavcodec/arm/ac3dsp_armv6.S
+++ b/libavcodec/arm/ac3dsp_armv6.S
@@ -37,14 +37,16 @@ function ff_ac3_bit_alloc_calc_bap_armv6, export=1
ldrb r10, [r4], #1
1:
ldrsh r9, [r0], #2 @ mask[band]
- movw r8, #0x1fe0
+ mov r8, #0xff0
sub r9, r9, r12 @ - snr_offset
mov r11, r10
ldrb r10, [r4], #1 @ band_start_tab[band++]
subs r9, r9, r5 @ - floor
+ it lt
movlt r9, #0
cmp r10, r3 @ - end
- and r9, r9, r8 @ & 0x1fe0
+ and r9, r9, r8, lsl #1 @ & 0x1fe0
+ ite gt
subgt r8, r3, r11
suble r8, r10, r11
add r9, r9, r5 @ + floor => m
diff --git a/libavcodec/arm/ac3dsp_neon.S b/libavcodec/arm/ac3dsp_neon.S
index 946b39f..e97197c 100644
--- a/libavcodec/arm/ac3dsp_neon.S
+++ b/libavcodec/arm/ac3dsp_neon.S
@@ -41,6 +41,7 @@ endfunc
function ff_ac3_exponent_min_neon, export=1
cmp r1, #0
+ it eq
bxeq lr
push {lr}
mov r12, #256
@@ -94,19 +95,14 @@ function ff_float_to_fixed24_neon, export=1
endfunc
function ff_ac3_extract_exponents_neon, export=1
- vmov.i32 q14, #24
vmov.i32 q15, #8
1:
- vld1.32 {q0}, [r1,:128]
+ vld1.32 {q0}, [r1,:128]!
vabs.s32 q1, q0
vclz.i32 q3, q1
vsub.i32 q3, q3, q15
- vcge.s32 q2, q3, q14
- vbit q3, q14, q2
- vbic q0, q0, q2
vmovn.i32 d6, q3
vmovn.i16 d6, q3
- vst1.32 {q0}, [r1,:128]!
vst1.32 {d6[0]}, [r0,:32]!
subs r2, r2, #4
bgt 1b
diff --git a/libavcodec/arm/asm-offsets.h b/libavcodec/arm/asm-offsets.h
index 110d33d..8999456 100644
--- a/libavcodec/arm/asm-offsets.h
+++ b/libavcodec/arm/asm-offsets.h
@@ -29,11 +29,11 @@
#endif
/* MpegEncContext */
-#define Y_DC_SCALE 0xb4
-#define C_DC_SCALE 0xb8
-#define AC_PRED 0xbc
-#define BLOCK_LAST_INDEX 0xc0
-#define H263_AIC 0xf0
-#define INTER_SCANTAB_RASTER_END 0x138
+#define Y_DC_SCALE 0xa8
+#define C_DC_SCALE 0xac
+#define AC_PRED 0xb0
+#define BLOCK_LAST_INDEX 0xb4
+#define H263_AIC 0xe4
+#define INTER_SCANTAB_RASTER_END 0x12c
#endif /* AVCODEC_ARM_ASM_OFFSETS_H */
diff --git a/libavcodec/arm/asm.S b/libavcodec/arm/asm.S
index 8d7fe98..aaf497e 100644
--- a/libavcodec/arm/asm.S
+++ b/libavcodec/arm/asm.S
@@ -26,7 +26,32 @@
# define ELF @
#endif
+#if CONFIG_THUMB
+# define A @
+# define T
+#else
+# define A
+# define T @
+#endif
+
+#if HAVE_NEON
+ .arch armv7-a
+#elif HAVE_ARMV6T2
+ .arch armv6t2
+#elif HAVE_ARMV6
+ .arch armv6
+#elif HAVE_ARMV5TE
+ .arch armv5te
+#endif
+
+#if HAVE_NEON
+ .fpu neon
+#elif HAVE_ARMVFP
+ .fpu vfp
+#endif
+
.syntax unified
+T .thumb
.macro require8 val=1
ELF .eabi_attribute 24, \val
@@ -82,6 +107,96 @@ ELF .size \name, . - \name
#endif
.endm
+.macro ldr_pre rt, rn, rm:vararg
+A ldr \rt, [\rn, \rm]!
+T add \rn, \rn, \rm
+T ldr \rt, [\rn]
+.endm
+
+.macro ldr_dpre rt, rn, rm:vararg
+A ldr \rt, [\rn, -\rm]!
+T sub \rn, \rn, \rm
+T ldr \rt, [\rn]
+.endm
+
+.macro ldr_post rt, rn, rm:vararg
+A ldr \rt, [\rn], \rm
+T ldr \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro ldrd_reg rt, rt2, rn, rm
+A ldrd \rt, \rt2, [\rn, \rm]
+T add \rt, \rn, \rm
+T ldrd \rt, \rt2, [\rt]
+.endm
+
+.macro ldrd_post rt, rt2, rn, rm
+A ldrd \rt, \rt2, [\rn], \rm
+T ldrd \rt, \rt2, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro ldrh_pre rt, rn, rm
+A ldrh \rt, [\rn, \rm]!
+T add \rn, \rn, \rm
+T ldrh \rt, [\rn]
+.endm
+
+.macro ldrh_dpre rt, rn, rm
+A ldrh \rt, [\rn, -\rm]!
+T sub \rn, \rn, \rm
+T ldrh \rt, [\rn]
+.endm
+
+.macro ldrh_post rt, rn, rm
+A ldrh \rt, [\rn], \rm
+T ldrh \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro str_post rt, rn, rm:vararg
+A str \rt, [\rn], \rm
+T str \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro strb_post rt, rn, rm:vararg
+A strb \rt, [\rn], \rm
+T strb \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro strd_post rt, rt2, rn, rm
+A strd \rt, \rt2, [\rn], \rm
+T strd \rt, \rt2, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro strh_pre rt, rn, rm
+A strh \rt, [\rn, \rm]!
+T add \rn, \rn, \rm
+T strh \rt, [\rn]
+.endm
+
+.macro strh_dpre rt, rn, rm
+A strh \rt, [\rn, -\rm]!
+T sub \rn, \rn, \rm
+T strh \rt, [\rn]
+.endm
+
+.macro strh_post rt, rn, rm
+A strh \rt, [\rn], \rm
+T strh \rt, [\rn]
+T add \rn, \rn, \rm
+.endm
+
+.macro strh_dpost rt, rn, rm
+A strh \rt, [\rn], -\rm
+T strh \rt, [\rn]
+T sub \rn, \rn, \rm
+.endm
+
#if HAVE_VFP_ARGS
.eabi_attribute 28, 1
# define VFP
diff --git a/libavcodec/arm/dca.h b/libavcodec/arm/dca.h
new file mode 100644
index 0000000..9b0efc0
--- /dev/null
+++ b/libavcodec/arm/dca.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011 Mans Rullgard <mans at mansr.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_ARM_DCA_H
+#define AVCODEC_ARM_DCA_H
+
+#include <stdint.h>
+#include "config.h"
+#include "libavutil/intmath.h"
+
+#if HAVE_ARMV6 && HAVE_INLINE_ASM && AV_GCC_VERSION_AT_LEAST(4,4)
+
+#define decode_blockcodes decode_blockcodes
+static inline int decode_blockcodes(int code1, int code2, int levels,
+ int *values)
+{
+ int v0, v1, v2, v3, v4, v5;
+
+ __asm__ ("smmul %8, %14, %18 \n"
+ "smmul %11, %15, %18 \n"
+ "smlabb %14, %8, %17, %14 \n"
+ "smlabb %15, %11, %17, %15 \n"
+ "smmul %9, %8, %18 \n"
+ "smmul %12, %11, %18 \n"
+ "sub %14, %14, %16, lsr #1 \n"
+ "sub %15, %15, %16, lsr #1 \n"
+ "smlabb %8, %9, %17, %8 \n"
+ "smlabb %11, %12, %17, %11 \n"
+ "smmul %10, %9, %18 \n"
+ "smmul %13, %12, %18 \n"
+ "str %14, %0 \n"
+ "str %15, %4 \n"
+ "sub %8, %8, %16, lsr #1 \n"
+ "sub %11, %11, %16, lsr #1 \n"
+ "smlabb %9, %10, %17, %9 \n"
+ "smlabb %12, %13, %17, %12 \n"
+ "smmul %14, %10, %18 \n"
+ "smmul %15, %13, %18 \n"
+ "str %8, %1 \n"
+ "str %11, %5 \n"
+ "sub %9, %9, %16, lsr #1 \n"
+ "sub %12, %12, %16, lsr #1 \n"
+ "smlabb %10, %14, %17, %10 \n"
+ "smlabb %13, %15, %17, %13 \n"
+ "str %9, %2 \n"
+ "str %12, %6 \n"
+ "sub %10, %10, %16, lsr #1 \n"
+ "sub %13, %13, %16, lsr #1 \n"
+ "str %10, %3 \n"
+ "str %13, %7 \n"
+ : "=m"(values[0]), "=m"(values[1]),
+ "=m"(values[2]), "=m"(values[3]),
+ "=m"(values[4]), "=m"(values[5]),
+ "=m"(values[6]), "=m"(values[7]),
+ "=&r"(v0), "=&r"(v1), "=&r"(v2),
+ "=&r"(v3), "=&r"(v4), "=&r"(v5),
+ "+&r"(code1), "+&r"(code2)
+ : "r"(levels - 1), "r"(-levels), "r"(ff_inverse[levels]));
+
+ return code1 | code2;
+}
+
+#endif
+
+#if HAVE_NEON && HAVE_INLINE_ASM && HAVE_ASM_MOD_Y
+
+#define int8x8_fmul_int32 int8x8_fmul_int32
+static inline void int8x8_fmul_int32(float *dst, const int8_t *src, int scale)
+{
+ __asm__ ("vcvt.f32.s32 %2, %2, #4 \n"
+ "vld1.8 {d0}, [%1,:64] \n"
+ "vmovl.s8 q0, d0 \n"
+ "vmovl.s16 q1, d1 \n"
+ "vmovl.s16 q0, d0 \n"
+ "vcvt.f32.s32 q0, q0 \n"
+ "vcvt.f32.s32 q1, q1 \n"
+ "vmul.f32 q0, q0, %y2 \n"
+ "vmul.f32 q1, q1, %y2 \n"
+ "vst1.32 {q0-q1}, [%m0,:128] \n"
+ : "=Um"(*(float (*)[8])dst)
+ : "r"(src), "x"(scale)
+ : "d0", "d1", "d2", "d3");
+}
+
+#endif
+
+#endif /* AVCODEC_ARM_DCA_H */
diff --git a/libavcodec/arm/dcadsp_neon.S b/libavcodec/arm/dcadsp_neon.S
index 6120836..71f5dd8 100644
--- a/libavcodec/arm/dcadsp_neon.S
+++ b/libavcodec/arm/dcadsp_neon.S
@@ -27,6 +27,7 @@ function ff_dca_lfe_fir_neon, export=1
add r5, r2, #256*4-16 @ cf1
sub r1, r1, #12
cmp r3, #32
+ ite eq
moveq r6, #256/32
movne r6, #256/64
NOVFP vldr s0, [sp, #16] @ scale
diff --git a/libavcodec/arm/dsputil_arm.S b/libavcodec/arm/dsputil_arm.S
index 2117628..136551f 100644
--- a/libavcodec/arm/dsputil_arm.S
+++ b/libavcodec/arm/dsputil_arm.S
@@ -24,11 +24,6 @@
preserve8
-#if !HAVE_PLD
-.macro pld reg
-.endm
-#endif
-
#if HAVE_ARMV5TE
function ff_prefetch_arm, export=1
subs r2, r2, #1
@@ -37,6 +32,8 @@ function ff_prefetch_arm, export=1
bne ff_prefetch_arm
bx lr
endfunc
+#else
+#define pld @
#endif
.macro ALIGN_QWORD_D shift, Rd0, Rd1, Rd2, Rd3, Rn0, Rn1, Rn2, Rn3, Rn4
@@ -554,10 +551,12 @@ endfunc
and r9, r5, r14
and r10, r6, r14
and r11, r7, r14
+ it eq
andeq r14, r14, r14, \rnd #1
add r8, r8, r10
add r9, r9, r11
ldr r12, =0xfcfcfcfc >> 2
+ itt eq
addeq r8, r8, r14
addeq r9, r9, r14
and r4, r12, r4, lsr #2
@@ -638,8 +637,10 @@ function ff_add_pixels_clamped_arm, export=1
mvn r5, r5
mvn r7, r7
tst r6, #0x100
+ it ne
movne r6, r5, lsr #24
tst r8, #0x100
+ it ne
movne r8, r7, lsr #24
mov r9, r6
ldrsh r5, [r0, #4] /* moved form [A] */
@@ -654,8 +655,10 @@ function ff_add_pixels_clamped_arm, export=1
mvn r5, r5
mvn r7, r7
tst r6, #0x100
+ it ne
movne r6, r5, lsr #24
tst r8, #0x100
+ it ne
movne r8, r7, lsr #24
orr r9, r9, r6, lsl #16
ldr r4, [r1, #4] /* moved form [B] */
@@ -676,8 +679,10 @@ function ff_add_pixels_clamped_arm, export=1
mvn r5, r5
mvn r7, r7
tst r6, #0x100
+ it ne
movne r6, r5, lsr #24
tst r8, #0x100
+ it ne
movne r8, r7, lsr #24
mov r9, r6
ldrsh r5, [r0, #12] /* moved from [D] */
@@ -692,8 +697,10 @@ function ff_add_pixels_clamped_arm, export=1
mvn r5, r5
mvn r7, r7
tst r6, #0x100
+ it ne
movne r6, r5, lsr #24
tst r8, #0x100
+ it ne
movne r8, r7, lsr #24
orr r9, r9, r6, lsl #16
add r0, r0, #16 /* moved from [E] */
diff --git a/libavcodec/arm/dsputil_armv6.S b/libavcodec/arm/dsputil_armv6.S
index 8acb96d..becf851 100644
--- a/libavcodec/arm/dsputil_armv6.S
+++ b/libavcodec/arm/dsputil_armv6.S
@@ -22,8 +22,6 @@
preserve8
- .text
-
.macro call_2x_pixels type, subp
function ff_\type\()_pixels16\subp\()_armv6, export=1
push {r0-r3, lr}
@@ -47,16 +45,16 @@ function ff_put_pixels16_armv6, export=1
ldr r5, [r1, #4]
ldr r6, [r1, #8]
ldr r7, [r1, #12]
- ldr r4, [r1], r2
+ ldr_post r4, r1, r2
strd r6, r7, [r0, #8]
ldr r9, [r1, #4]
- strd r4, r5, [r0], r2
+ strd_post r4, r5, r0, r2
ldr r10, [r1, #8]
ldr r11, [r1, #12]
- ldr r8, [r1], r2
+ ldr_post r8, r1, r2
strd r10, r11, [r0, #8]
subs r3, r3, #2
- strd r8, r9, [r0], r2
+ strd_post r8, r9, r0, r2
bne 1b
pop {r4-r11}
@@ -67,12 +65,12 @@ function ff_put_pixels8_armv6, export=1
push {r4-r7}
1:
ldr r5, [r1, #4]
- ldr r4, [r1], r2
+ ldr_post r4, r1, r2
ldr r7, [r1, #4]
- strd r4, r5, [r0], r2
- ldr r6, [r1], r2
+ strd_post r4, r5, r0, r2
+ ldr_post r6, r1, r2
subs r3, r3, #2
- strd r6, r7, [r0], r2
+ strd_post r6, r7, r0, r2
bne 1b
pop {r4-r7}
@@ -90,7 +88,7 @@ function ff_put_pixels8_x2_armv6, export=1
ldr r5, [r1, #4]
ldr r7, [r1, #5]
lsr r6, r4, #8
- ldr r8, [r1, r2]!
+ ldr_pre r8, r1, r2
orr r6, r6, r5, lsl #24
ldr r9, [r1, #4]
ldr r11, [r1, #5]
@@ -112,9 +110,9 @@ function ff_put_pixels8_x2_armv6, export=1
uhadd8 r9, r9, r11
and r6, r6, r12
uadd8 r8, r8, r14
- strd r4, r5, [r0], r2
+ strd_post r4, r5, r0, r2
uadd8 r9, r9, r6
- strd r8, r9, [r0], r2
+ strd_post r8, r9, r0, r2
bne 1b
pop {r4-r11, pc}
@@ -127,7 +125,7 @@ function ff_put_pixels8_y2_armv6, export=1
orr r12, r12, r12, lsl #16
ldr r4, [r1]
ldr r5, [r1, #4]
- ldr r6, [r1, r2]!
+ ldr_pre r6, r1, r2
ldr r7, [r1, #4]
1:
subs r3, r3, #2
@@ -136,7 +134,7 @@ function ff_put_pixels8_y2_armv6, export=1
uhadd8 r9, r5, r7
eor r11, r5, r7
and r10, r10, r12
- ldr r4, [r1, r2]!
+ ldr_pre r4, r1, r2
uadd8 r8, r8, r10
and r11, r11, r12
uadd8 r9, r9, r11
@@ -148,11 +146,11 @@ function ff_put_pixels8_y2_armv6, export=1
eor r7, r5, r7
uadd8 r10, r10, r6
and r7, r7, r12
- ldr r6, [r1, r2]!
+ ldr_pre r6, r1, r2
uadd8 r11, r11, r7
- strd r8, r9, [r0], r2
+ strd_post r8, r9, r0, r2
ldr r7, [r1, #4]
- strd r10, r11, [r0], r2
+ strd_post r10, r11, r0, r2
bne 1b
pop {r4-r11}
@@ -166,7 +164,7 @@ function ff_put_pixels8_x2_no_rnd_armv6, export=1
ldr r4, [r1]
ldr r5, [r1, #4]
ldr r7, [r1, #5]
- ldr r8, [r1, r2]!
+ ldr_pre r8, r1, r2
ldr r9, [r1, #4]
ldr r14, [r1, #5]
add r1, r1, r2
@@ -191,16 +189,16 @@ function ff_put_pixels8_y2_no_rnd_armv6, export=1
push {r4-r9, lr}
ldr r4, [r1]
ldr r5, [r1, #4]
- ldr r6, [r1, r2]!
+ ldr_pre r6, r1, r2
ldr r7, [r1, #4]
1:
subs r3, r3, #2
uhadd8 r8, r4, r6
- ldr r4, [r1, r2]!
+ ldr_pre r4, r1, r2
uhadd8 r9, r5, r7
ldr r5, [r1, #4]
uhadd8 r12, r4, r6
- ldr r6, [r1, r2]!
+ ldr_pre r6, r1, r2
uhadd8 r14, r5, r7
ldr r7, [r1, #4]
stm r0, {r8,r9}
@@ -220,44 +218,44 @@ function ff_avg_pixels8_armv6, export=1
orr lr, lr, lr, lsl #16
ldrd r4, r5, [r0]
ldr r10, [r1, #4]
- ldr r9, [r1], r2
+ ldr_post r9, r1, r2
subs r3, r3, #2
1:
pld [r1, r2]
eor r8, r4, r9
uhadd8 r4, r4, r9
eor r12, r5, r10
- ldrd r6, r7, [r0, r2]
+ ldrd_reg r6, r7, r0, r2
uhadd8 r5, r5, r10
and r8, r8, lr
ldr r10, [r1, #4]
and r12, r12, lr
uadd8 r4, r4, r8
- ldr r9, [r1], r2
+ ldr_post r9, r1, r2
eor r8, r6, r9
uadd8 r5, r5, r12
pld [r1, r2, lsl #1]
eor r12, r7, r10
uhadd8 r6, r6, r9
- strd r4, r5, [r0], r2
+ strd_post r4, r5, r0, r2
uhadd8 r7, r7, r10
beq 2f
and r8, r8, lr
- ldrd r4, r5, [r0, r2]
+ ldrd_reg r4, r5, r0, r2
uadd8 r6, r6, r8
ldr r10, [r1, #4]
and r12, r12, lr
subs r3, r3, #2
uadd8 r7, r7, r12
- ldr r9, [r1], r2
- strd r6, r7, [r0], r2
+ ldr_post r9, r1, r2
+ strd_post r6, r7, r0, r2
b 1b
2:
and r8, r8, lr
and r12, r12, lr
uadd8 r6, r6, r8
uadd8 r7, r7, r12
- strd r6, r7, [r0], r2
+ strd_post r6, r7, r0, r2
pop {r4-r10, pc}
endfunc
@@ -284,7 +282,7 @@ function ff_add_pixels_clamped_armv6, export=1
orr r6, r8, r5, lsl #8
orr r7, r4, lr, lsl #8
subs r3, r3, #1
- strd r6, r7, [r1], r2
+ strd_post r6, r7, r1, r2
bgt 1b
pop {r4-r8,pc}
endfunc
@@ -294,7 +292,7 @@ function ff_get_pixels_armv6, export=1
push {r4-r8, lr}
mov lr, #8
1:
- ldrd r4, r5, [r1], r2
+ ldrd_post r4, r5, r1, r2
subs lr, lr, #1
uxtb16 r6, r4
uxtb16 r4, r4, ror #8
@@ -317,8 +315,8 @@ function ff_diff_pixels_armv6, export=1
push {r4-r9, lr}
mov lr, #8
1:
- ldrd r4, r5, [r1], r3
- ldrd r6, r7, [r2], r3
+ ldrd_post r4, r5, r1, r3
+ ldrd_post r6, r7, r2, r3
uxtb16 r8, r4
uxtb16 r4, r4, ror #8
uxtb16 r9, r6
@@ -492,19 +490,19 @@ function ff_pix_abs8_armv6, export=1
push {r4-r9, lr}
mov r0, #0
mov lr, #0
- ldrd r4, r5, [r1], r3
+ ldrd_post r4, r5, r1, r3
1:
subs r12, r12, #2
ldr r7, [r2, #4]
- ldr r6, [r2], r3
- ldrd r8, r9, [r1], r3
+ ldr_post r6, r2, r3
+ ldrd_post r8, r9, r1, r3
usada8 r0, r4, r6, r0
pld [r2, r3]
usada8 lr, r5, r7, lr
ldr r7, [r2, #4]
- ldr r6, [r2], r3
+ ldr_post r6, r2, r3
beq 2f
- ldrd r4, r5, [r1], r3
+ ldrd_post r4, r5, r1, r3
usada8 r0, r8, r6, r0
pld [r2, r3]
usada8 lr, r9, r7, lr
@@ -613,7 +611,7 @@ function ff_pix_sum_armv6, export=1
ldr r7, [r0, #12]
usada8 r2, r6, lr, r2
beq 2f
- ldr r4, [r0, r1]!
+ ldr_pre r4, r0, r1
usada8 r3, r7, lr, r3
bgt 1b
2:
diff --git a/libavcodec/arm/dsputil_init_arm.c b/libavcodec/arm/dsputil_init_arm.c
index 777a2f9..743be1a 100644
--- a/libavcodec/arm/dsputil_init_arm.c
+++ b/libavcodec/arm/dsputil_init_arm.c
@@ -75,12 +75,12 @@ static void simple_idct_arm_add(uint8_t *dest, int line_size, DCTELEM *block)
void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx)
{
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
ff_put_pixels_clamped = c->put_pixels_clamped;
ff_add_pixels_clamped = c->add_pixels_clamped;
- if (!avctx->lowres) {
+ if (!avctx->lowres && avctx->bits_per_raw_sample <= 8) {
if(avctx->idct_algo == FF_IDCT_AUTO ||
avctx->idct_algo == FF_IDCT_ARM){
c->idct_put = j_rev_dct_arm_put;
diff --git a/libavcodec/arm/dsputil_init_armv5te.c b/libavcodec/arm/dsputil_init_armv5te.c
index 572e06c..e0224da 100644
--- a/libavcodec/arm/dsputil_init_armv5te.c
+++ b/libavcodec/arm/dsputil_init_armv5te.c
@@ -29,8 +29,9 @@ void ff_prefetch_arm(void *mem, int stride, int h);
void av_cold ff_dsputil_init_armv5te(DSPContext* c, AVCodecContext *avctx)
{
- if (!avctx->lowres && (avctx->idct_algo == FF_IDCT_AUTO ||
- avctx->idct_algo == FF_IDCT_SIMPLEARMV5TE)) {
+ if (!avctx->lowres && avctx->bits_per_raw_sample <= 8 &&
+ (avctx->idct_algo == FF_IDCT_AUTO ||
+ avctx->idct_algo == FF_IDCT_SIMPLEARMV5TE)) {
c->idct_put = ff_simple_idct_put_armv5te;
c->idct_add = ff_simple_idct_add_armv5te;
c->idct = ff_simple_idct_armv5te;
diff --git a/libavcodec/arm/dsputil_init_armv6.c b/libavcodec/arm/dsputil_init_armv6.c
index 7584aee..eff4ee3 100644
--- a/libavcodec/arm/dsputil_init_armv6.c
+++ b/libavcodec/arm/dsputil_init_armv6.c
@@ -72,10 +72,11 @@ int ff_pix_sum_armv6(uint8_t *pix, int line_size);
void av_cold ff_dsputil_init_armv6(DSPContext* c, AVCodecContext *avctx)
{
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
- if (!avctx->lowres && (avctx->idct_algo == FF_IDCT_AUTO ||
- avctx->idct_algo == FF_IDCT_SIMPLEARMV6)) {
+ if (!avctx->lowres && avctx->bits_per_raw_sample <= 8 &&
+ (avctx->idct_algo == FF_IDCT_AUTO ||
+ avctx->idct_algo == FF_IDCT_SIMPLEARMV6)) {
c->idct_put = ff_simple_idct_put_armv6;
c->idct_add = ff_simple_idct_add_armv6;
c->idct = ff_simple_idct_armv6;
@@ -105,8 +106,9 @@ void av_cold ff_dsputil_init_armv6(DSPContext* c, AVCodecContext *avctx)
c->avg_pixels_tab[1][0] = ff_avg_pixels8_armv6;
}
+ if (!high_bit_depth)
+ c->get_pixels = ff_get_pixels_armv6;
c->add_pixels_clamped = ff_add_pixels_clamped_armv6;
- c->get_pixels = ff_get_pixels_armv6;
c->diff_pixels = ff_diff_pixels_armv6;
c->pix_abs[0][0] = ff_pix_abs16_armv6;
diff --git a/libavcodec/arm/dsputil_init_neon.c b/libavcodec/arm/dsputil_init_neon.c
index 3bc053c..68e5b3e 100644
--- a/libavcodec/arm/dsputil_init_neon.c
+++ b/libavcodec/arm/dsputil_init_neon.c
@@ -53,7 +53,19 @@ void ff_put_pixels8_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
void ff_put_pixels8_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
void ff_avg_pixels16_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels16_x2_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels16_y2_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels16_xy2_neon(uint8_t *, const uint8_t *, int, int);
void ff_avg_pixels8_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels8_x2_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels8_y2_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels8_xy2_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels8_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels8_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
+void ff_avg_pixels8_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
void ff_add_pixels_clamped_neon(const DCTELEM *, uint8_t *, int);
void ff_put_pixels_clamped_neon(const DCTELEM *, uint8_t *, int);
@@ -143,14 +155,8 @@ void ff_vector_fmul_window_neon(float *dst, const float *src0,
const float *src1, const float *win, int len);
void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul,
int len);
-void ff_vector_fmul_sv_scalar_2_neon(float *dst, const float *src,
- const float **vp, float mul, int len);
-void ff_vector_fmul_sv_scalar_4_neon(float *dst, const float *src,
- const float **vp, float mul, int len);
-void ff_sv_fmul_scalar_2_neon(float *dst, const float **vp, float mul,
- int len);
-void ff_sv_fmul_scalar_4_neon(float *dst, const float **vp, float mul,
- int len);
+void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul,
+ int len);
void ff_butterflies_float_neon(float *v1, float *v2, int len);
float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
@@ -160,6 +166,8 @@ void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1,
void ff_vector_clipf_neon(float *dst, const float *src, float min, float max,
int len);
+void ff_vector_clip_int32_neon(int32_t *dst, const int32_t *src, int32_t min,
+ int32_t max, unsigned int len);
void ff_vorbis_inverse_coupling_neon(float *mag, float *ang, int blocksize);
@@ -173,9 +181,9 @@ void ff_apply_window_int16_neon(int16_t *dst, const int16_t *src,
void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
{
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
- if (!avctx->lowres) {
+ if (!avctx->lowres && avctx->bits_per_raw_sample <= 8) {
if (avctx->idct_algo == FF_IDCT_AUTO ||
avctx->idct_algo == FF_IDCT_SIMPLENEON) {
c->idct_put = ff_simple_idct_put_neon;
@@ -193,37 +201,51 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
}
if (!high_bit_depth) {
- c->clear_block = ff_clear_block_neon;
- c->clear_blocks = ff_clear_blocks_neon;
-
- c->put_pixels_tab[0][0] = ff_put_pixels16_neon;
- c->put_pixels_tab[0][1] = ff_put_pixels16_x2_neon;
- c->put_pixels_tab[0][2] = ff_put_pixels16_y2_neon;
- c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_neon;
- c->put_pixels_tab[1][0] = ff_put_pixels8_neon;
- c->put_pixels_tab[1][1] = ff_put_pixels8_x2_neon;
- c->put_pixels_tab[1][2] = ff_put_pixels8_y2_neon;
- c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_neon;
-
- c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_neon;
- c->put_no_rnd_pixels_tab[0][1] = ff_put_pixels16_x2_no_rnd_neon;
- c->put_no_rnd_pixels_tab[0][2] = ff_put_pixels16_y2_no_rnd_neon;
- c->put_no_rnd_pixels_tab[0][3] = ff_put_pixels16_xy2_no_rnd_neon;
- c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_neon;
- c->put_no_rnd_pixels_tab[1][1] = ff_put_pixels8_x2_no_rnd_neon;
- c->put_no_rnd_pixels_tab[1][2] = ff_put_pixels8_y2_no_rnd_neon;
- c->put_no_rnd_pixels_tab[1][3] = ff_put_pixels8_xy2_no_rnd_neon;
-
- c->avg_pixels_tab[0][0] = ff_avg_pixels16_neon;
- c->avg_pixels_tab[1][0] = ff_avg_pixels8_neon;
+ c->clear_block = ff_clear_block_neon;
+ c->clear_blocks = ff_clear_blocks_neon;
+
+ c->put_pixels_tab[0][0] = ff_put_pixels16_neon;
+ c->put_pixels_tab[0][1] = ff_put_pixels16_x2_neon;
+ c->put_pixels_tab[0][2] = ff_put_pixels16_y2_neon;
+ c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_neon;
+ c->put_pixels_tab[1][0] = ff_put_pixels8_neon;
+ c->put_pixels_tab[1][1] = ff_put_pixels8_x2_neon;
+ c->put_pixels_tab[1][2] = ff_put_pixels8_y2_neon;
+ c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_neon;
+
+ c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_neon;
+ c->put_no_rnd_pixels_tab[0][1] = ff_put_pixels16_x2_no_rnd_neon;
+ c->put_no_rnd_pixels_tab[0][2] = ff_put_pixels16_y2_no_rnd_neon;
+ c->put_no_rnd_pixels_tab[0][3] = ff_put_pixels16_xy2_no_rnd_neon;
+ c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_neon;
+ c->put_no_rnd_pixels_tab[1][1] = ff_put_pixels8_x2_no_rnd_neon;
+ c->put_no_rnd_pixels_tab[1][2] = ff_put_pixels8_y2_no_rnd_neon;
+ c->put_no_rnd_pixels_tab[1][3] = ff_put_pixels8_xy2_no_rnd_neon;
+
+ c->avg_pixels_tab[0][0] = ff_avg_pixels16_neon;
+ c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_neon;
+ c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_neon;
+ c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_neon;
+ c->avg_pixels_tab[1][0] = ff_avg_pixels8_neon;
+ c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_neon;
+ c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_neon;
+ c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_neon;
+
+ c->avg_no_rnd_pixels_tab[0][0] = ff_avg_pixels16_neon;
+ c->avg_no_rnd_pixels_tab[0][1] = ff_avg_pixels16_x2_no_rnd_neon;
+ c->avg_no_rnd_pixels_tab[0][2] = ff_avg_pixels16_y2_no_rnd_neon;
+ c->avg_no_rnd_pixels_tab[0][3] = ff_avg_pixels16_xy2_no_rnd_neon;
+ c->avg_no_rnd_pixels_tab[1][0] = ff_avg_pixels8_neon;
+ c->avg_no_rnd_pixels_tab[1][1] = ff_avg_pixels8_x2_no_rnd_neon;
+ c->avg_no_rnd_pixels_tab[1][2] = ff_avg_pixels8_y2_no_rnd_neon;
+ c->avg_no_rnd_pixels_tab[1][3] = ff_avg_pixels8_xy2_no_rnd_neon;
}
c->add_pixels_clamped = ff_add_pixels_clamped_neon;
c->put_pixels_clamped = ff_put_pixels_clamped_neon;
c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_neon;
- if (CONFIG_H264_DECODER) {
- if (!high_bit_depth) {
+ if (CONFIG_H264_DECODER && !high_bit_depth) {
c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_neon;
c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_neon;
c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_neon;
@@ -299,7 +321,6 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_neon;
c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_neon;
c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_neon;
- }
}
if (CONFIG_VP3_DECODER) {
@@ -311,17 +332,13 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
c->vector_fmul = ff_vector_fmul_neon;
c->vector_fmul_window = ff_vector_fmul_window_neon;
c->vector_fmul_scalar = ff_vector_fmul_scalar_neon;
+ c->vector_fmac_scalar = ff_vector_fmac_scalar_neon;
c->butterflies_float = ff_butterflies_float_neon;
c->scalarproduct_float = ff_scalarproduct_float_neon;
c->vector_fmul_reverse = ff_vector_fmul_reverse_neon;
c->vector_fmul_add = ff_vector_fmul_add_neon;
c->vector_clipf = ff_vector_clipf_neon;
-
- c->vector_fmul_sv_scalar[0] = ff_vector_fmul_sv_scalar_2_neon;
- c->vector_fmul_sv_scalar[1] = ff_vector_fmul_sv_scalar_4_neon;
-
- c->sv_fmul_scalar[0] = ff_sv_fmul_scalar_2_neon;
- c->sv_fmul_scalar[1] = ff_sv_fmul_scalar_4_neon;
+ c->vector_clip_int32 = ff_vector_clip_int32_neon;
if (CONFIG_VORBIS_DECODER)
c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_neon;
diff --git a/libavcodec/arm/dsputil_iwmmxt.c b/libavcodec/arm/dsputil_iwmmxt.c
index 86f8fdd..dec5d77 100644
--- a/libavcodec/arm/dsputil_iwmmxt.c
+++ b/libavcodec/arm/dsputil_iwmmxt.c
@@ -155,7 +155,7 @@ static void nop(uint8_t *block, const uint8_t *pixels, int line_size, int h)
void ff_dsputil_init_iwmmxt(DSPContext* c, AVCodecContext *avctx)
{
int mm_flags = AV_CPU_FLAG_IWMMXT; /* multimedia extension flags */
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
if (avctx->dsp_mask) {
if (avctx->dsp_mask & AV_CPU_FLAG_FORCE)
diff --git a/libavcodec/arm/dsputil_neon.S b/libavcodec/arm/dsputil_neon.S
index 5b80e40..d49aedd 100644
--- a/libavcodec/arm/dsputil_neon.S
+++ b/libavcodec/arm/dsputil_neon.S
@@ -23,7 +23,6 @@
#include "asm.S"
preserve8
- .text
function ff_clear_block_neon, export=1
vmov.i16 q0, #0
@@ -41,75 +40,89 @@ function ff_clear_blocks_neon, export=1
bx lr
endfunc
- .macro pixels16 avg=0
-.if \avg
- mov ip, r0
-.endif
-1: vld1.64 {d0, d1}, [r1], r2
- vld1.64 {d2, d3}, [r1], r2
- vld1.64 {d4, d5}, [r1], r2
+.macro pixels16 rnd=1, avg=0
+ .if \avg
+ mov r12, r0
+ .endif
+1: vld1.64 {q0}, [r1], r2
+ vld1.64 {q1}, [r1], r2
+ vld1.64 {q2}, [r1], r2
pld [r1, r2, lsl #2]
- vld1.64 {d6, d7}, [r1], r2
+ vld1.64 {q3}, [r1], r2
pld [r1]
pld [r1, r2]
pld [r1, r2, lsl #1]
-.if \avg
- vld1.64 {d16,d17}, [ip,:128], r2
+ .if \avg
+ vld1.64 {q8}, [r12,:128], r2
vrhadd.u8 q0, q0, q8
- vld1.64 {d18,d19}, [ip,:128], r2
+ vld1.64 {q9}, [r12,:128], r2
vrhadd.u8 q1, q1, q9
- vld1.64 {d20,d21}, [ip,:128], r2
+ vld1.64 {q10}, [r12,:128], r2
vrhadd.u8 q2, q2, q10
- vld1.64 {d22,d23}, [ip,:128], r2
+ vld1.64 {q11}, [r12,:128], r2
vrhadd.u8 q3, q3, q11
-.endif
+ .endif
subs r3, r3, #4
- vst1.64 {d0, d1}, [r0,:128], r2
- vst1.64 {d2, d3}, [r0,:128], r2
- vst1.64 {d4, d5}, [r0,:128], r2
- vst1.64 {d6, d7}, [r0,:128], r2
+ vst1.64 {q0}, [r0,:128], r2
+ vst1.64 {q1}, [r0,:128], r2
+ vst1.64 {q2}, [r0,:128], r2
+ vst1.64 {q3}, [r0,:128], r2
bne 1b
bx lr
- .endm
+.endm
- .macro pixels16_x2 vhadd=vrhadd.u8
-1: vld1.64 {d0-d2}, [r1], r2
- vld1.64 {d4-d6}, [r1], r2
+.macro pixels16_x2 rnd=1, avg=0
+1: vld1.64 {d0-d2}, [r1], r2
+ vld1.64 {d4-d6}, [r1], r2
pld [r1]
pld [r1, r2]
subs r3, r3, #2
vext.8 q1, q0, q1, #1
- \vhadd q0, q0, q1
+ avg q0, q0, q1
vext.8 q3, q2, q3, #1
- \vhadd q2, q2, q3
- vst1.64 {d0, d1}, [r0,:128], r2
- vst1.64 {d4, d5}, [r0,:128], r2
+ avg q2, q2, q3
+ .if \avg
+ vld1.8 {q1}, [r0,:128], r2
+ vld1.8 {q3}, [r0,:128]
+ vrhadd.u8 q0, q0, q1
+ vrhadd.u8 q2, q2, q3
+ sub r0, r0, r2
+ .endif
+ vst1.64 {q0}, [r0,:128], r2
+ vst1.64 {q2}, [r0,:128], r2
bne 1b
bx lr
- .endm
+.endm
- .macro pixels16_y2 vhadd=vrhadd.u8
- vld1.64 {d0, d1}, [r1], r2
- vld1.64 {d2, d3}, [r1], r2
+.macro pixels16_y2 rnd=1, avg=0
+ vld1.64 {q0}, [r1], r2
+ vld1.64 {q1}, [r1], r2
1: subs r3, r3, #2
- \vhadd q2, q0, q1
- vld1.64 {d0, d1}, [r1], r2
- \vhadd q3, q0, q1
- vld1.64 {d2, d3}, [r1], r2
+ avg q2, q0, q1
+ vld1.64 {q0}, [r1], r2
+ avg q3, q0, q1
+ vld1.64 {q1}, [r1], r2
pld [r1]
pld [r1, r2]
- vst1.64 {d4, d5}, [r0,:128], r2
- vst1.64 {d6, d7}, [r0,:128], r2
+ .if \avg
+ vld1.8 {q8}, [r0,:128], r2
+ vld1.8 {q9}, [r0,:128]
+ vrhadd.u8 q2, q2, q8
+ vrhadd.u8 q3, q3, q9
+ sub r0, r0, r2
+ .endif
+ vst1.64 {q2}, [r0,:128], r2
+ vst1.64 {q3}, [r0,:128], r2
bne 1b
bx lr
- .endm
+.endm
- .macro pixels16_xy2 vshrn=vrshrn.u16 no_rnd=0
- vld1.64 {d0-d2}, [r1], r2
- vld1.64 {d4-d6}, [r1], r2
-.if \no_rnd
+.macro pixels16_xy2 rnd=1, avg=0
+ vld1.64 {d0-d2}, [r1], r2
+ vld1.64 {d4-d6}, [r1], r2
+ .ifeq \rnd
vmov.i16 q13, #1
-.endif
+ .endif
pld [r1]
pld [r1, r2]
vext.8 q1, q0, q1, #1
@@ -119,109 +132,129 @@ endfunc
vaddl.u8 q9, d4, d6
vaddl.u8 q11, d5, d7
1: subs r3, r3, #2
- vld1.64 {d0-d2}, [r1], r2
+ vld1.64 {d0-d2}, [r1], r2
vadd.u16 q12, q8, q9
pld [r1]
-.if \no_rnd
+ .ifeq \rnd
vadd.u16 q12, q12, q13
-.endif
+ .endif
vext.8 q15, q0, q1, #1
vadd.u16 q1 , q10, q11
- \vshrn d28, q12, #2
-.if \no_rnd
+ shrn d28, q12, #2
+ .ifeq \rnd
vadd.u16 q1, q1, q13
-.endif
- \vshrn d29, q1, #2
+ .endif
+ shrn d29, q1, #2
+ .if \avg
+ vld1.8 {q8}, [r0,:128]
+ vrhadd.u8 q14, q14, q8
+ .endif
vaddl.u8 q8, d0, d30
- vld1.64 {d2-d4}, [r1], r2
+ vld1.64 {d2-d4}, [r1], r2
vaddl.u8 q10, d1, d31
- vst1.64 {d28,d29}, [r0,:128], r2
+ vst1.64 {q14}, [r0,:128], r2
vadd.u16 q12, q8, q9
pld [r1, r2]
-.if \no_rnd
+ .ifeq \rnd
vadd.u16 q12, q12, q13
-.endif
+ .endif
vext.8 q2, q1, q2, #1
vadd.u16 q0, q10, q11
- \vshrn d30, q12, #2
-.if \no_rnd
+ shrn d30, q12, #2
+ .ifeq \rnd
vadd.u16 q0, q0, q13
-.endif
- \vshrn d31, q0, #2
+ .endif
+ shrn d31, q0, #2
+ .if \avg
+ vld1.8 {q9}, [r0,:128]
+ vrhadd.u8 q15, q15, q9
+ .endif
vaddl.u8 q9, d2, d4
vaddl.u8 q11, d3, d5
- vst1.64 {d30,d31}, [r0,:128], r2
+ vst1.64 {q15}, [r0,:128], r2
bgt 1b
bx lr
- .endm
+.endm
- .macro pixels8 avg=0
-1: vld1.64 {d0}, [r1], r2
- vld1.64 {d1}, [r1], r2
- vld1.64 {d2}, [r1], r2
+.macro pixels8 rnd=1, avg=0
+1: vld1.64 {d0}, [r1], r2
+ vld1.64 {d1}, [r1], r2
+ vld1.64 {d2}, [r1], r2
pld [r1, r2, lsl #2]
- vld1.64 {d3}, [r1], r2
+ vld1.64 {d3}, [r1], r2
pld [r1]
pld [r1, r2]
pld [r1, r2, lsl #1]
-.if \avg
- vld1.64 {d4}, [r0,:64], r2
+ .if \avg
+ vld1.64 {d4}, [r0,:64], r2
vrhadd.u8 d0, d0, d4
- vld1.64 {d5}, [r0,:64], r2
+ vld1.64 {d5}, [r0,:64], r2
vrhadd.u8 d1, d1, d5
- vld1.64 {d6}, [r0,:64], r2
+ vld1.64 {d6}, [r0,:64], r2
vrhadd.u8 d2, d2, d6
- vld1.64 {d7}, [r0,:64], r2
+ vld1.64 {d7}, [r0,:64], r2
vrhadd.u8 d3, d3, d7
sub r0, r0, r2, lsl #2
-.endif
+ .endif
subs r3, r3, #4
- vst1.64 {d0}, [r0,:64], r2
- vst1.64 {d1}, [r0,:64], r2
- vst1.64 {d2}, [r0,:64], r2
- vst1.64 {d3}, [r0,:64], r2
+ vst1.64 {d0}, [r0,:64], r2
+ vst1.64 {d1}, [r0,:64], r2
+ vst1.64 {d2}, [r0,:64], r2
+ vst1.64 {d3}, [r0,:64], r2
bne 1b
bx lr
- .endm
+.endm
- .macro pixels8_x2 vhadd=vrhadd.u8
-1: vld1.64 {d0, d1}, [r1], r2
+.macro pixels8_x2 rnd=1, avg=0
+1: vld1.64 {q0}, [r1], r2
vext.8 d1, d0, d1, #1
- vld1.64 {d2, d3}, [r1], r2
+ vld1.64 {q1}, [r1], r2
vext.8 d3, d2, d3, #1
pld [r1]
pld [r1, r2]
subs r3, r3, #2
vswp d1, d2
- \vhadd q0, q0, q1
- vst1.64 {d0}, [r0,:64], r2
- vst1.64 {d1}, [r0,:64], r2
+ avg q0, q0, q1
+ .if \avg
+ vld1.8 {d4}, [r0,:64], r2
+ vld1.8 {d5}, [r0,:64]
+ vrhadd.u8 q0, q0, q2
+ sub r0, r0, r2
+ .endif
+ vst1.64 {d0}, [r0,:64], r2
+ vst1.64 {d1}, [r0,:64], r2
bne 1b
bx lr
- .endm
+.endm
- .macro pixels8_y2 vhadd=vrhadd.u8
- vld1.64 {d0}, [r1], r2
- vld1.64 {d1}, [r1], r2
+.macro pixels8_y2 rnd=1, avg=0
+ vld1.64 {d0}, [r1], r2
+ vld1.64 {d1}, [r1], r2
1: subs r3, r3, #2
- \vhadd d4, d0, d1
- vld1.64 {d0}, [r1], r2
- \vhadd d5, d0, d1
- vld1.64 {d1}, [r1], r2
+ avg d4, d0, d1
+ vld1.64 {d0}, [r1], r2
+ avg d5, d0, d1
+ vld1.64 {d1}, [r1], r2
pld [r1]
pld [r1, r2]
- vst1.64 {d4}, [r0,:64], r2
- vst1.64 {d5}, [r0,:64], r2
+ .if \avg
+ vld1.8 {d2}, [r0,:64], r2
+ vld1.8 {d3}, [r0,:64]
+ vrhadd.u8 q2, q2, q1
+ sub r0, r0, r2
+ .endif
+ vst1.64 {d4}, [r0,:64], r2
+ vst1.64 {d5}, [r0,:64], r2
bne 1b
bx lr
- .endm
+.endm
- .macro pixels8_xy2 vshrn=vrshrn.u16 no_rnd=0
- vld1.64 {d0, d1}, [r1], r2
- vld1.64 {d2, d3}, [r1], r2
-.if \no_rnd
+.macro pixels8_xy2 rnd=1, avg=0
+ vld1.64 {q0}, [r1], r2
+ vld1.64 {q1}, [r1], r2
+ .ifeq \rnd
vmov.i16 q11, #1
-.endif
+ .endif
pld [r1]
pld [r1, r2]
vext.8 d4, d0, d1, #1
@@ -229,70 +262,101 @@ endfunc
vaddl.u8 q8, d0, d4
vaddl.u8 q9, d2, d6
1: subs r3, r3, #2
- vld1.64 {d0, d1}, [r1], r2
+ vld1.64 {q0}, [r1], r2
pld [r1]
vadd.u16 q10, q8, q9
vext.8 d4, d0, d1, #1
-.if \no_rnd
+ .ifeq \rnd
vadd.u16 q10, q10, q11
-.endif
+ .endif
vaddl.u8 q8, d0, d4
- \vshrn d5, q10, #2
- vld1.64 {d2, d3}, [r1], r2
+ shrn d5, q10, #2
+ vld1.64 {q1}, [r1], r2
vadd.u16 q10, q8, q9
pld [r1, r2]
-.if \no_rnd
+ .if \avg
+ vld1.8 {d7}, [r0,:64]
+ vrhadd.u8 d5, d5, d7
+ .endif
+ .ifeq \rnd
vadd.u16 q10, q10, q11
-.endif
- vst1.64 {d5}, [r0,:64], r2
- \vshrn d7, q10, #2
+ .endif
+ vst1.64 {d5}, [r0,:64], r2
+ shrn d7, q10, #2
+ .if \avg
+ vld1.8 {d5}, [r0,:64]
+ vrhadd.u8 d7, d7, d5
+ .endif
vext.8 d6, d2, d3, #1
vaddl.u8 q9, d2, d6
- vst1.64 {d7}, [r0,:64], r2
+ vst1.64 {d7}, [r0,:64], r2
bgt 1b
bx lr
- .endm
-
- .macro pixfunc pfx name suf rnd_op args:vararg
+.endm
+
+.macro pixfunc pfx, name, suf, rnd=1, avg=0
+ .if \rnd
+ .macro avg rd, rn, rm
+ vrhadd.u8 \rd, \rn, \rm
+ .endm
+ .macro shrn rd, rn, rm
+ vrshrn.u16 \rd, \rn, \rm
+ .endm
+ .else
+ .macro avg rd, rn, rm
+ vhadd.u8 \rd, \rn, \rm
+ .endm
+ .macro shrn rd, rn, rm
+ vshrn.u16 \rd, \rn, \rm
+ .endm
+ .endif
function ff_\pfx\name\suf\()_neon, export=1
- \name \rnd_op \args
+ \name \rnd, \avg
endfunc
- .endm
+ .purgem avg
+ .purgem shrn
+.endm
- .macro pixfunc2 pfx name args:vararg
- pixfunc \pfx \name
- pixfunc \pfx \name \args
- .endm
+.macro pixfunc2 pfx, name, avg=0
+ pixfunc \pfx, \name, rnd=1, avg=\avg
+ pixfunc \pfx, \name, _no_rnd, rnd=0, avg=\avg
+.endm
function ff_put_h264_qpel16_mc00_neon, export=1
mov r3, #16
endfunc
- pixfunc put_ pixels16
- pixfunc2 put_ pixels16_x2, _no_rnd, vhadd.u8
- pixfunc2 put_ pixels16_y2, _no_rnd, vhadd.u8
- pixfunc2 put_ pixels16_xy2, _no_rnd, vshrn.u16, 1
+ pixfunc put_, pixels16, avg=0
+ pixfunc2 put_, pixels16_x2, avg=0
+ pixfunc2 put_, pixels16_y2, avg=0
+ pixfunc2 put_, pixels16_xy2, avg=0
function ff_avg_h264_qpel16_mc00_neon, export=1
mov r3, #16
endfunc
- pixfunc avg_ pixels16,, 1
+ pixfunc avg_, pixels16, avg=1
+ pixfunc2 avg_, pixels16_x2, avg=1
+ pixfunc2 avg_, pixels16_y2, avg=1
+ pixfunc2 avg_, pixels16_xy2, avg=1
function ff_put_h264_qpel8_mc00_neon, export=1
mov r3, #8
endfunc
- pixfunc put_ pixels8
- pixfunc2 put_ pixels8_x2, _no_rnd, vhadd.u8
- pixfunc2 put_ pixels8_y2, _no_rnd, vhadd.u8
- pixfunc2 put_ pixels8_xy2, _no_rnd, vshrn.u16, 1
+ pixfunc put_, pixels8, avg=0
+ pixfunc2 put_, pixels8_x2, avg=0
+ pixfunc2 put_, pixels8_y2, avg=0
+ pixfunc2 put_, pixels8_xy2, avg=0
function ff_avg_h264_qpel8_mc00_neon, export=1
mov r3, #8
endfunc
- pixfunc avg_ pixels8,, 1
+ pixfunc avg_, pixels8, avg=1
+ pixfunc2 avg_, pixels8_x2, avg=1
+ pixfunc2 avg_, pixels8_y2, avg=1
+ pixfunc2 avg_, pixels8_xy2, avg=1
function ff_put_pixels_clamped_neon, export=1
vld1.64 {d16-d19}, [r0,:128]!
@@ -531,6 +595,7 @@ function ff_vorbis_inverse_coupling_neon, export=1
2: vst1.32 {d2-d3}, [r3, :128]!
vst1.32 {d0-d1}, [r12,:128]!
+ it lt
bxlt lr
3: vld1.32 {d2-d3}, [r1,:128]
@@ -575,6 +640,7 @@ NOVFP vdup.32 q8, r2
2: vst1.32 {q2},[r0,:128]!
vst1.32 {q3},[r0,:128]!
ands len, len, #15
+ it eq
bxeq lr
3: vld1.32 {q0},[r1,:128]!
vmul.f32 q0, q0, q8
@@ -585,105 +651,50 @@ NOVFP vdup.32 q8, r2
.unreq len
endfunc
-function ff_vector_fmul_sv_scalar_2_neon, export=1
-VFP vdup.32 d16, d0[0]
-NOVFP vdup.32 d16, r3
-NOVFP ldr r3, [sp]
- vld1.32 {d0},[r1,:64]!
- vld1.32 {d1},[r1,:64]!
-1: subs r3, r3, #4
- vmul.f32 d4, d0, d16
- vmul.f32 d5, d1, d16
- ldr r12, [r2], #4
- vld1.32 {d2},[r12,:64]
- ldr r12, [r2], #4
- vld1.32 {d3},[r12,:64]
- vmul.f32 d4, d4, d2
- vmul.f32 d5, d5, d3
- beq 2f
- vld1.32 {d0},[r1,:64]!
- vld1.32 {d1},[r1,:64]!
- vst1.32 {d4},[r0,:64]!
- vst1.32 {d5},[r0,:64]!
- b 1b
-2: vst1.32 {d4},[r0,:64]!
- vst1.32 {d5},[r0,:64]!
- bx lr
-endfunc
-
-function ff_vector_fmul_sv_scalar_4_neon, export=1
-VFP vdup.32 q10, d0[0]
-NOVFP vdup.32 q10, r3
-NOVFP ldr r3, [sp]
- push {lr}
- bics lr, r3, #7
- beq 3f
- vld1.32 {q0},[r1,:128]!
- vld1.32 {q2},[r1,:128]!
-1: ldr r12, [r2], #4
- vld1.32 {q1},[r12,:128]
- ldr r12, [r2], #4
- vld1.32 {q3},[r12,:128]
- vmul.f32 q8, q0, q10
- vmul.f32 q8, q8, q1
- vmul.f32 q9, q2, q10
- vmul.f32 q9, q9, q3
- subs lr, lr, #8
- beq 2f
- vld1.32 {q0},[r1,:128]!
- vld1.32 {q2},[r1,:128]!
- vst1.32 {q8},[r0,:128]!
- vst1.32 {q9},[r0,:128]!
- b 1b
-2: vst1.32 {q8},[r0,:128]!
- vst1.32 {q9},[r0,:128]!
- ands r3, r3, #7
- popeq {pc}
-3: vld1.32 {q0},[r1,:128]!
- ldr r12, [r2], #4
- vld1.32 {q1},[r12,:128]
- vmul.f32 q0, q0, q10
- vmul.f32 q0, q0, q1
- vst1.32 {q0},[r0,:128]!
- subs r3, r3, #4
- bgt 3b
- pop {pc}
-endfunc
-
-function ff_sv_fmul_scalar_2_neon, export=1
+function ff_vector_fmac_scalar_neon, export=1
VFP len .req r2
+VFP acc .req r3
NOVFP len .req r3
-VFP vdup.32 q8, d0[0]
-NOVFP vdup.32 q8, r2
- ldr r12, [r1], #4
- vld1.32 {d0},[r12,:64]
- ldr r12, [r1], #4
- vld1.32 {d1},[r12,:64]
-1: vmul.f32 q1, q0, q8
- subs len, len, #4
+NOVFP acc .req r2
+VFP vdup.32 q15, d0[0]
+NOVFP vdup.32 q15, r2
+ bics r12, len, #15
+ mov acc, r0
+ beq 3f
+ vld1.32 {q0}, [r1,:128]!
+ vld1.32 {q8}, [acc,:128]!
+ vld1.32 {q1}, [r1,:128]!
+ vld1.32 {q9}, [acc,:128]!
+1: vmla.f32 q8, q0, q15
+ vld1.32 {q2}, [r1,:128]!
+ vld1.32 {q10}, [acc,:128]!
+ vmla.f32 q9, q1, q15
+ vld1.32 {q3}, [r1,:128]!
+ vld1.32 {q11}, [acc,:128]!
+ vmla.f32 q10, q2, q15
+ vst1.32 {q8}, [r0,:128]!
+ vmla.f32 q11, q3, q15
+ vst1.32 {q9}, [r0,:128]!
+ subs r12, r12, #16
beq 2f
- ldr r12, [r1], #4
- vld1.32 {d0},[r12,:64]
- ldr r12, [r1], #4
- vld1.32 {d1},[r12,:64]
- vst1.32 {q1},[r0,:128]!
+ vld1.32 {q0}, [r1,:128]!
+ vld1.32 {q8}, [acc,:128]!
+ vst1.32 {q10}, [r0,:128]!
+ vld1.32 {q1}, [r1,:128]!
+ vld1.32 {q9}, [acc,:128]!
+ vst1.32 {q11}, [r0,:128]!
b 1b
-2: vst1.32 {q1},[r0,:128]!
- bx lr
- .unreq len
-endfunc
-
-function ff_sv_fmul_scalar_4_neon, export=1
-VFP len .req r2
-NOVFP len .req r3
-VFP vdup.32 q8, d0[0]
-NOVFP vdup.32 q8, r2
-1: ldr r12, [r1], #4
- vld1.32 {q0},[r12,:128]
- vmul.f32 q0, q0, q8
- vst1.32 {q0},[r0,:128]!
+2: vst1.32 {q10}, [r0,:128]!
+ vst1.32 {q11}, [r0,:128]!
+ ands len, len, #15
+ it eq
+ bxeq lr
+3: vld1.32 {q0}, [r1,:128]!
+ vld1.32 {q8}, [acc,:128]!
+ vmla.f32 q8, q0, q15
+ vst1.32 {q8}, [r0,:128]!
subs len, len, #4
- bgt 1b
+ bgt 3b
bx lr
.unreq len
endfunc
@@ -812,3 +823,19 @@ function ff_apply_window_int16_neon, export=1
pop {r4,pc}
endfunc
+
+function ff_vector_clip_int32_neon, export=1
+ vdup.32 q0, r2
+ vdup.32 q1, r3
+ ldr r2, [sp]
+1:
+ vld1.32 {q2-q3}, [r1,:128]!
+ vmin.s32 q2, q2, q1
+ vmin.s32 q3, q3, q1
+ vmax.s32 q2, q2, q0
+ vmax.s32 q3, q3, q0
+ vst1.32 {q2-q3}, [r0,:128]!
+ subs r2, r2, #8
+ bgt 1b
+ bx lr
+endfunc
diff --git a/libavcodec/arm/dsputil_vfp.S b/libavcodec/arm/dsputil_vfp.S
index 16ea25a..cbc4bd6 100644
--- a/libavcodec/arm/dsputil_vfp.S
+++ b/libavcodec/arm/dsputil_vfp.S
@@ -55,18 +55,23 @@ function ff_vector_fmul_vfp, export=1
1:
subs r3, r3, #16
vmul.f32 s12, s4, s12
+ itttt ge
vldmiage r1!, {s16-s19}
vldmiage r2!, {s24-s27}
vldmiage r1!, {s20-s23}
vldmiage r2!, {s28-s31}
+ it ge
vmulge.f32 s24, s16, s24
vstmia r0!, {s8-s11}
vstmia r0!, {s12-s15}
+ it ge
vmulge.f32 s28, s20, s28
+ itttt gt
vldmiagt r1!, {s0-s3}
vldmiagt r2!, {s8-s11}
vldmiagt r1!, {s4-s7}
vldmiagt r2!, {s12-s15}
+ ittt ge
vmulge.f32 s8, s0, s8
vstmiage r0!, {s24-s27}
vstmiage r0!, {s28-s31}
@@ -97,33 +102,49 @@ function ff_vector_fmul_reverse_vfp, export=1
vmul.f32 s11, s0, s11
1:
subs r3, r3, #16
+ it ge
vldmdbge r2!, {s16-s19}
vmul.f32 s12, s7, s12
+ it ge
vldmiage r1!, {s24-s27}
vmul.f32 s13, s6, s13
+ it ge
vldmdbge r2!, {s20-s23}
vmul.f32 s14, s5, s14
+ it ge
vldmiage r1!, {s28-s31}
vmul.f32 s15, s4, s15
+ it ge
vmulge.f32 s24, s19, s24
+ it gt
vldmdbgt r2!, {s0-s3}
+ it ge
vmulge.f32 s25, s18, s25
vstmia r0!, {s8-s13}
+ it ge
vmulge.f32 s26, s17, s26
+ it gt
vldmiagt r1!, {s8-s11}
+ itt ge
vmulge.f32 s27, s16, s27
vmulge.f32 s28, s23, s28
+ it gt
vldmdbgt r2!, {s4-s7}
+ it ge
vmulge.f32 s29, s22, s29
vstmia r0!, {s14-s15}
+ ittt ge
vmulge.f32 s30, s21, s30
vmulge.f32 s31, s20, s31
vmulge.f32 s8, s3, s8
+ it gt
vldmiagt r1!, {s12-s15}
+ itttt ge
vmulge.f32 s9, s2, s9
vmulge.f32 s10, s1, s10
vstmiage r0!, {s24-s27}
vmulge.f32 s11, s0, s11
+ it ge
vstmiage r0!, {s28-s31}
bgt 1b
diff --git a/libavcodec/arm/fft_fixed_neon.S b/libavcodec/arm/fft_fixed_neon.S
index 63d8159..0508088 100644
--- a/libavcodec/arm/fft_fixed_neon.S
+++ b/libavcodec/arm/fft_fixed_neon.S
@@ -75,9 +75,9 @@
.endm
function fft4_neon
- vld1.16 {d0-d1}, [r0,:128]
+ vld1.16 {d0-d1}, [r0]
fft4 d0, d1, d2, d3
- vst1.16 {d0-d1}, [r0,:128]
+ vst1.16 {d0-d1}, [r0]
bx lr
endfunc
diff --git a/libavcodec/arm/fft_neon.S b/libavcodec/arm/fft_neon.S
index 8876218..a458985 100644
--- a/libavcodec/arm/fft_neon.S
+++ b/libavcodec/arm/fft_neon.S
@@ -28,7 +28,6 @@
#define M_SQRT1_2 0.70710678118654752440
- .text
function fft4_neon
vld1.32 {d0-d3}, [r0,:128]
@@ -349,9 +348,7 @@ function ff_fft_permute_neon, export=1
pop {r4,pc}
endfunc
- .section .rodata
- .align 4
-fft_tab_neon:
+const fft_tab_neon
.word fft4_neon
.word fft8_neon
.word fft16_neon
@@ -367,8 +364,12 @@ fft_tab_neon:
.word fft16384_neon
.word fft32768_neon
.word fft65536_neon
-ELF .size fft_tab_neon, . - fft_tab_neon
+endconst
- .align 4
-pmmp: .float +1.0, -1.0, -1.0, +1.0
-mppm: .float -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2
+const pmmp, align=4
+ .float +1.0, -1.0, -1.0, +1.0
+endconst
+
+const mppm, align=4
+ .float -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2
+endconst
diff --git a/libavcodec/arm/fmtconvert_neon.S b/libavcodec/arm/fmtconvert_neon.S
index 4b0e9a2..ad1c15d 100644
--- a/libavcodec/arm/fmtconvert_neon.S
+++ b/libavcodec/arm/fmtconvert_neon.S
@@ -23,7 +23,6 @@
#include "asm.S"
preserve8
- .text
function ff_float_to_int16_neon, export=1
subs r2, r2, #8
@@ -71,6 +70,7 @@ endfunc
function ff_float_to_int16_interleave_neon, export=1
cmp r3, #2
+ itt lt
ldrlt r1, [r1]
blt ff_float_to_int16_neon
bne 4f
@@ -196,6 +196,7 @@ function ff_float_to_int16_interleave_neon, export=1
vst1.64 {d3}, [r8], ip
vst1.64 {d7}, [r8], ip
subs r3, r3, #4
+ it eq
popeq {r4-r8,pc}
cmp r3, #4
add r0, r0, #8
@@ -305,6 +306,7 @@ function ff_float_to_int16_interleave_neon, export=1
vst1.32 {d23[1]}, [r8], ip
8: subs r3, r3, #2
add r0, r0, #4
+ it eq
popeq {r4-r8,pc}
@ 1 channel
@@ -354,6 +356,7 @@ function ff_float_to_int16_interleave_neon, export=1
vst1.16 {d2[3]}, [r5,:16], ip
vst1.16 {d3[1]}, [r5,:16], ip
vst1.16 {d3[3]}, [r5,:16], ip
+ it eq
popeq {r4-r8,pc}
vld1.64 {d0-d1}, [r4,:128]!
vcvt.s32.f32 q0, q0, #16
diff --git a/libavcodec/arm/fmtconvert_vfp.S b/libavcodec/arm/fmtconvert_vfp.S
index 1bb7f49..f7b0e3d 100644
--- a/libavcodec/arm/fmtconvert_vfp.S
+++ b/libavcodec/arm/fmtconvert_vfp.S
@@ -46,6 +46,7 @@ function ff_float_to_int16_vfp, export=1
vmov r5, r6, s2, s3
vmov r7, r8, s4, s5
vmov ip, lr, s6, s7
+ it gt
vldmiagt r1!, {s16-s23}
ssat r4, #16, r4
ssat r3, #16, r3
@@ -53,10 +54,12 @@ function ff_float_to_int16_vfp, export=1
ssat r5, #16, r5
pkhbt r3, r3, r4, lsl #16
pkhbt r4, r5, r6, lsl #16
+ itttt gt
vcvtgt.s32.f32 s0, s16
vcvtgt.s32.f32 s1, s17
vcvtgt.s32.f32 s2, s18
vcvtgt.s32.f32 s3, s19
+ itttt gt
vcvtgt.s32.f32 s4, s20
vcvtgt.s32.f32 s5, s21
vcvtgt.s32.f32 s6, s22
diff --git a/libavcodec/arm/h264cmc_neon.S b/libavcodec/arm/h264cmc_neon.S
new file mode 100644
index 0000000..a6feadd
--- /dev/null
+++ b/libavcodec/arm/h264cmc_neon.S
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "asm.S"
+
+/* chroma_mc8(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */
+.macro h264_chroma_mc8 type, codec=h264
+function ff_\type\()_\codec\()_chroma_mc8_neon, export=1
+ push {r4-r7, lr}
+ ldrd r4, [sp, #20]
+ .ifc \type,avg
+ mov lr, r0
+ .endif
+ pld [r1]
+ pld [r1, r2]
+
+ .ifc \codec,rv40
+ movrel r6, rv40bias
+ lsr r7, r5, #1
+ add r6, r6, r7, lsl #3
+ lsr r7, r4, #1
+ add r6, r6, r7, lsl #1
+ vld1.16 {d22[],d23[]}, [r6,:16]
+ .endif
+
+A muls r7, r4, r5
+T mul r7, r4, r5
+T cmp r7, #0
+ rsb r6, r7, r5, lsl #3
+ rsb r12, r7, r4, lsl #3
+ sub r4, r7, r4, lsl #3
+ sub r4, r4, r5, lsl #3
+ add r4, r4, #64
+
+ beq 2f
+
+ add r5, r1, r2
+
+ vdup.8 d0, r4
+ lsl r4, r2, #1
+ vdup.8 d1, r12
+ vld1.8 {d4, d5}, [r1], r4
+ vdup.8 d2, r6
+ vld1.8 {d6, d7}, [r5], r4
+ vdup.8 d3, r7
+
+ vext.8 d5, d4, d5, #1
+ vext.8 d7, d6, d7, #1
+
+1: pld [r5]
+ vmull.u8 q8, d4, d0
+ vmlal.u8 q8, d5, d1
+ vld1.8 {d4, d5}, [r1], r4
+ vmlal.u8 q8, d6, d2
+ vext.8 d5, d4, d5, #1
+ vmlal.u8 q8, d7, d3
+ vmull.u8 q9, d6, d0
+ subs r3, r3, #2
+ vmlal.u8 q9, d7, d1
+ vmlal.u8 q9, d4, d2
+ vmlal.u8 q9, d5, d3
+ vld1.8 {d6, d7}, [r5], r4
+ pld [r1]
+ .ifc \codec,h264
+ vrshrn.u16 d16, q8, #6
+ vrshrn.u16 d17, q9, #6
+ .else
+ vadd.u16 q8, q8, q11
+ vadd.u16 q9, q9, q11
+ vshrn.u16 d16, q8, #6
+ vshrn.u16 d17, q9, #6
+ .endif
+ .ifc \type,avg
+ vld1.8 {d20}, [lr,:64], r2
+ vld1.8 {d21}, [lr,:64], r2
+ vrhadd.u8 q8, q8, q10
+ .endif
+ vext.8 d7, d6, d7, #1
+ vst1.8 {d16}, [r0,:64], r2
+ vst1.8 {d17}, [r0,:64], r2
+ bgt 1b
+
+ pop {r4-r7, pc}
+
+2: tst r6, r6
+ add r12, r12, r6
+ vdup.8 d0, r4
+ vdup.8 d1, r12
+
+ beq 4f
+
+ add r5, r1, r2
+ lsl r4, r2, #1
+ vld1.8 {d4}, [r1], r4
+ vld1.8 {d6}, [r5], r4
+
+3: pld [r5]
+ vmull.u8 q8, d4, d0
+ vmlal.u8 q8, d6, d1
+ vld1.8 {d4}, [r1], r4
+ vmull.u8 q9, d6, d0
+ vmlal.u8 q9, d4, d1
+ vld1.8 {d6}, [r5], r4
+ .ifc \codec,h264
+ vrshrn.u16 d16, q8, #6
+ vrshrn.u16 d17, q9, #6
+ .else
+ vadd.u16 q8, q8, q11
+ vadd.u16 q9, q9, q11
+ vshrn.u16 d16, q8, #6
+ vshrn.u16 d17, q9, #6
+ .endif
+ .ifc \type,avg
+ vld1.8 {d20}, [lr,:64], r2
+ vld1.8 {d21}, [lr,:64], r2
+ vrhadd.u8 q8, q8, q10
+ .endif
+ subs r3, r3, #2
+ pld [r1]
+ vst1.8 {d16}, [r0,:64], r2
+ vst1.8 {d17}, [r0,:64], r2
+ bgt 3b
+
+ pop {r4-r7, pc}
+
+4: vld1.8 {d4, d5}, [r1], r2
+ vld1.8 {d6, d7}, [r1], r2
+ vext.8 d5, d4, d5, #1
+ vext.8 d7, d6, d7, #1
+
+5: pld [r1]
+ subs r3, r3, #2
+ vmull.u8 q8, d4, d0
+ vmlal.u8 q8, d5, d1
+ vld1.8 {d4, d5}, [r1], r2
+ vmull.u8 q9, d6, d0
+ vmlal.u8 q9, d7, d1
+ pld [r1]
+ vext.8 d5, d4, d5, #1
+ .ifc \codec,h264
+ vrshrn.u16 d16, q8, #6
+ vrshrn.u16 d17, q9, #6
+ .else
+ vadd.u16 q8, q8, q11
+ vadd.u16 q9, q9, q11
+ vshrn.u16 d16, q8, #6
+ vshrn.u16 d17, q9, #6
+ .endif
+ .ifc \type,avg
+ vld1.8 {d20}, [lr,:64], r2
+ vld1.8 {d21}, [lr,:64], r2
+ vrhadd.u8 q8, q8, q10
+ .endif
+ vld1.8 {d6, d7}, [r1], r2
+ vext.8 d7, d6, d7, #1
+ vst1.8 {d16}, [r0,:64], r2
+ vst1.8 {d17}, [r0,:64], r2
+ bgt 5b
+
+ pop {r4-r7, pc}
+endfunc
+.endm
+
+/* chroma_mc4(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */
+.macro h264_chroma_mc4 type, codec=h264
+function ff_\type\()_\codec\()_chroma_mc4_neon, export=1
+ push {r4-r7, lr}
+ ldrd r4, [sp, #20]
+ .ifc \type,avg
+ mov lr, r0
+ .endif
+ pld [r1]
+ pld [r1, r2]
+
+ .ifc \codec,rv40
+ movrel r6, rv40bias
+ lsr r7, r5, #1
+ add r6, r6, r7, lsl #3
+ lsr r7, r4, #1
+ add r6, r6, r7, lsl #1
+ vld1.16 {d22[],d23[]}, [r6,:16]
+ .endif
+
+A muls r7, r4, r5
+T mul r7, r4, r5
+T cmp r7, #0
+ rsb r6, r7, r5, lsl #3
+ rsb r12, r7, r4, lsl #3
+ sub r4, r7, r4, lsl #3
+ sub r4, r4, r5, lsl #3
+ add r4, r4, #64
+
+ beq 2f
+
+ add r5, r1, r2
+
+ vdup.8 d0, r4
+ lsl r4, r2, #1
+ vdup.8 d1, r12
+ vld1.8 {d4}, [r1], r4
+ vdup.8 d2, r6
+ vld1.8 {d6}, [r5], r4
+ vdup.8 d3, r7
+
+ vext.8 d5, d4, d5, #1
+ vext.8 d7, d6, d7, #1
+ vtrn.32 d4, d5
+ vtrn.32 d6, d7
+
+ vtrn.32 d0, d1
+ vtrn.32 d2, d3
+
+1: pld [r5]
+ vmull.u8 q8, d4, d0
+ vmlal.u8 q8, d6, d2
+ vld1.8 {d4}, [r1], r4
+ vext.8 d5, d4, d5, #1
+ vtrn.32 d4, d5
+ vmull.u8 q9, d6, d0
+ vmlal.u8 q9, d4, d2
+ vld1.8 {d6}, [r5], r4
+ vadd.i16 d16, d16, d17
+ vadd.i16 d17, d18, d19
+ .ifc \codec,h264
+ vrshrn.u16 d16, q8, #6
+ .else
+ vadd.u16 q8, q8, q11
+ vshrn.u16 d16, q8, #6
+ .endif
+ subs r3, r3, #2
+ pld [r1]
+ .ifc \type,avg
+ vld1.32 {d20[0]}, [lr,:32], r2
+ vld1.32 {d20[1]}, [lr,:32], r2
+ vrhadd.u8 d16, d16, d20
+ .endif
+ vext.8 d7, d6, d7, #1
+ vtrn.32 d6, d7
+ vst1.32 {d16[0]}, [r0,:32], r2
+ vst1.32 {d16[1]}, [r0,:32], r2
+ bgt 1b
+
+ pop {r4-r7, pc}
+
+2: tst r6, r6
+ add r12, r12, r6
+ vdup.8 d0, r4
+ vdup.8 d1, r12
+ vtrn.32 d0, d1
+
+ beq 4f
+
+ vext.32 d1, d0, d1, #1
+ add r5, r1, r2
+ lsl r4, r2, #1
+ vld1.32 {d4[0]}, [r1], r4
+ vld1.32 {d4[1]}, [r5], r4
+
+3: pld [r5]
+ vmull.u8 q8, d4, d0
+ vld1.32 {d4[0]}, [r1], r4
+ vmull.u8 q9, d4, d1
+ vld1.32 {d4[1]}, [r5], r4
+ vadd.i16 d16, d16, d17
+ vadd.i16 d17, d18, d19
+ .ifc \codec,h264
+ vrshrn.u16 d16, q8, #6
+ .else
+ vadd.u16 q8, q8, q11
+ vshrn.u16 d16, q8, #6
+ .endif
+ .ifc \type,avg
+ vld1.32 {d20[0]}, [lr,:32], r2
+ vld1.32 {d20[1]}, [lr,:32], r2
+ vrhadd.u8 d16, d16, d20
+ .endif
+ subs r3, r3, #2
+ pld [r1]
+ vst1.32 {d16[0]}, [r0,:32], r2
+ vst1.32 {d16[1]}, [r0,:32], r2
+ bgt 3b
+
+ pop {r4-r7, pc}
+
+4: vld1.8 {d4}, [r1], r2
+ vld1.8 {d6}, [r1], r2
+ vext.8 d5, d4, d5, #1
+ vext.8 d7, d6, d7, #1
+ vtrn.32 d4, d5
+ vtrn.32 d6, d7
+
+5: vmull.u8 q8, d4, d0
+ vmull.u8 q9, d6, d0
+ subs r3, r3, #2
+ vld1.8 {d4}, [r1], r2
+ vext.8 d5, d4, d5, #1
+ vtrn.32 d4, d5
+ vadd.i16 d16, d16, d17
+ vadd.i16 d17, d18, d19
+ pld [r1]
+ .ifc \codec,h264
+ vrshrn.u16 d16, q8, #6
+ .else
+ vadd.u16 q8, q8, q11
+ vshrn.u16 d16, q8, #6
+ .endif
+ .ifc \type,avg
+ vld1.32 {d20[0]}, [lr,:32], r2
+ vld1.32 {d20[1]}, [lr,:32], r2
+ vrhadd.u8 d16, d16, d20
+ .endif
+ vld1.8 {d6}, [r1], r2
+ vext.8 d7, d6, d7, #1
+ vtrn.32 d6, d7
+ pld [r1]
+ vst1.32 {d16[0]}, [r0,:32], r2
+ vst1.32 {d16[1]}, [r0,:32], r2
+ bgt 5b
+
+ pop {r4-r7, pc}
+endfunc
+.endm
+
+.macro h264_chroma_mc2 type
+function ff_\type\()_h264_chroma_mc2_neon, export=1
+ push {r4-r6, lr}
+ ldr r4, [sp, #16]
+ ldr lr, [sp, #20]
+ pld [r1]
+ pld [r1, r2]
+ orrs r5, r4, lr
+ beq 2f
+
+ mul r5, r4, lr
+ rsb r6, r5, lr, lsl #3
+ rsb r12, r5, r4, lsl #3
+ sub r4, r5, r4, lsl #3
+ sub r4, r4, lr, lsl #3
+ add r4, r4, #64
+ vdup.8 d0, r4
+ vdup.8 d2, r12
+ vdup.8 d1, r6
+ vdup.8 d3, r5
+ vtrn.16 q0, q1
+1:
+ vld1.32 {d4[0]}, [r1], r2
+ vld1.32 {d4[1]}, [r1], r2
+ vrev64.32 d5, d4
+ vld1.32 {d5[1]}, [r1]
+ vext.8 q3, q2, q2, #1
+ vtrn.16 q2, q3
+ vmull.u8 q8, d4, d0
+ vmlal.u8 q8, d5, d1
+ .ifc \type,avg
+ vld1.16 {d18[0]}, [r0,:16], r2
+ vld1.16 {d18[1]}, [r0,:16]
+ sub r0, r0, r2
+ .endif
+ vtrn.32 d16, d17
+ vadd.i16 d16, d16, d17
+ vrshrn.u16 d16, q8, #6
+ .ifc \type,avg
+ vrhadd.u8 d16, d16, d18
+ .endif
+ vst1.16 {d16[0]}, [r0,:16], r2
+ vst1.16 {d16[1]}, [r0,:16], r2
+ subs r3, r3, #2
+ bgt 1b
+ pop {r4-r6, pc}
+2:
+ .ifc \type,put
+ ldrh_post r5, r1, r2
+ strh_post r5, r0, r2
+ ldrh_post r6, r1, r2
+ strh_post r6, r0, r2
+ .else
+ vld1.16 {d16[0]}, [r1], r2
+ vld1.16 {d16[1]}, [r1], r2
+ vld1.16 {d18[0]}, [r0,:16], r2
+ vld1.16 {d18[1]}, [r0,:16]
+ sub r0, r0, r2
+ vrhadd.u8 d16, d16, d18
+ vst1.16 {d16[0]}, [r0,:16], r2
+ vst1.16 {d16[1]}, [r0,:16], r2
+ .endif
+ subs r3, r3, #2
+ bgt 2b
+ pop {r4-r6, pc}
+endfunc
+.endm
+
+#if CONFIG_H264_DECODER
+ h264_chroma_mc8 put
+ h264_chroma_mc8 avg
+ h264_chroma_mc4 put
+ h264_chroma_mc4 avg
+ h264_chroma_mc2 put
+ h264_chroma_mc2 avg
+#endif
+
+#if CONFIG_RV40_DECODER
+const rv40bias
+ .short 0, 16, 32, 16
+ .short 32, 28, 32, 28
+ .short 0, 32, 16, 32
+ .short 32, 28, 32, 28
+endconst
+
+ h264_chroma_mc8 put, rv40
+ h264_chroma_mc8 avg, rv40
+ h264_chroma_mc4 put, rv40
+ h264_chroma_mc4 avg, rv40
+#endif
diff --git a/libavcodec/arm/h264dsp_init_arm.c b/libavcodec/arm/h264dsp_init_arm.c
index c2399e5..1c331a4 100644
--- a/libavcodec/arm/h264dsp_init_arm.c
+++ b/libavcodec/arm/h264dsp_init_arm.c
@@ -32,47 +32,22 @@ void ff_h264_v_loop_filter_chroma_neon(uint8_t *pix, int stride, int alpha,
void ff_h264_h_loop_filter_chroma_neon(uint8_t *pix, int stride, int alpha,
int beta, int8_t *tc0);
-void ff_weight_h264_pixels_16x16_neon(uint8_t *ds, int stride, int log2_den,
- int weight, int offset);
-void ff_weight_h264_pixels_16x8_neon(uint8_t *ds, int stride, int log2_den,
- int weight, int offset);
-void ff_weight_h264_pixels_8x16_neon(uint8_t *ds, int stride, int log2_den,
- int weight, int offset);
-void ff_weight_h264_pixels_8x8_neon(uint8_t *ds, int stride, int log2_den,
- int weight, int offset);
-void ff_weight_h264_pixels_8x4_neon(uint8_t *ds, int stride, int log2_den,
- int weight, int offset);
-void ff_weight_h264_pixels_4x8_neon(uint8_t *ds, int stride, int log2_den,
- int weight, int offset);
-void ff_weight_h264_pixels_4x4_neon(uint8_t *ds, int stride, int log2_den,
- int weight, int offset);
-void ff_weight_h264_pixels_4x2_neon(uint8_t *ds, int stride, int log2_den,
- int weight, int offset);
+void ff_weight_h264_pixels_16_neon(uint8_t *dst, int stride, int height,
+ int log2_den, int weight, int offset);
+void ff_weight_h264_pixels_8_neon(uint8_t *dst, int stride, int height,
+ int log2_den, int weight, int offset);
+void ff_weight_h264_pixels_4_neon(uint8_t *dst, int stride, int height,
+ int log2_den, int weight, int offset);
-void ff_biweight_h264_pixels_16x16_neon(uint8_t *dst, uint8_t *src, int stride,
- int log2_den, int weightd, int weights,
- int offset);
-void ff_biweight_h264_pixels_16x8_neon(uint8_t *dst, uint8_t *src, int stride,
- int log2_den, int weightd, int weights,
- int offset);
-void ff_biweight_h264_pixels_8x16_neon(uint8_t *dst, uint8_t *src, int stride,
- int log2_den, int weightd, int weights,
- int offset);
-void ff_biweight_h264_pixels_8x8_neon(uint8_t *dst, uint8_t *src, int stride,
- int log2_den, int weightd, int weights,
- int offset);
-void ff_biweight_h264_pixels_8x4_neon(uint8_t *dst, uint8_t *src, int stride,
- int log2_den, int weightd, int weights,
- int offset);
-void ff_biweight_h264_pixels_4x8_neon(uint8_t *dst, uint8_t *src, int stride,
- int log2_den, int weightd, int weights,
- int offset);
-void ff_biweight_h264_pixels_4x4_neon(uint8_t *dst, uint8_t *src, int stride,
- int log2_den, int weightd, int weights,
- int offset);
-void ff_biweight_h264_pixels_4x2_neon(uint8_t *dst, uint8_t *src, int stride,
- int log2_den, int weightd, int weights,
- int offset);
+void ff_biweight_h264_pixels_16_neon(uint8_t *dst, uint8_t *src, int stride,
+ int height, int log2_den, int weightd,
+ int weights, int offset);
+void ff_biweight_h264_pixels_8_neon(uint8_t *dst, uint8_t *src, int stride,
+ int height, int log2_den, int weightd,
+ int weights, int offset);
+void ff_biweight_h264_pixels_4_neon(uint8_t *dst, uint8_t *src, int stride,
+ int height, int log2_den, int weightd,
+ int weights, int offset);
void ff_h264_idct_add_neon(uint8_t *dst, DCTELEM *block, int stride);
void ff_h264_idct_dc_add_neon(uint8_t *dst, DCTELEM *block, int stride);
@@ -92,7 +67,7 @@ void ff_h264_idct8_add4_neon(uint8_t *dst, const int *block_offset,
DCTELEM *block, int stride,
const uint8_t nnzc[6*8]);
-static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth)
+static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
{
if (bit_depth == 8) {
c->h264_v_loop_filter_luma = ff_h264_v_loop_filter_luma_neon;
@@ -100,36 +75,27 @@ static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth)
c->h264_v_loop_filter_chroma = ff_h264_v_loop_filter_chroma_neon;
c->h264_h_loop_filter_chroma = ff_h264_h_loop_filter_chroma_neon;
- c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels_16x16_neon;
- c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels_16x8_neon;
- c->weight_h264_pixels_tab[2] = ff_weight_h264_pixels_8x16_neon;
- c->weight_h264_pixels_tab[3] = ff_weight_h264_pixels_8x8_neon;
- c->weight_h264_pixels_tab[4] = ff_weight_h264_pixels_8x4_neon;
- c->weight_h264_pixels_tab[5] = ff_weight_h264_pixels_4x8_neon;
- c->weight_h264_pixels_tab[6] = ff_weight_h264_pixels_4x4_neon;
- c->weight_h264_pixels_tab[7] = ff_weight_h264_pixels_4x2_neon;
+ c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels_16_neon;
+ c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels_8_neon;
+ c->weight_h264_pixels_tab[2] = ff_weight_h264_pixels_4_neon;
- c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels_16x16_neon;
- c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels_16x8_neon;
- c->biweight_h264_pixels_tab[2] = ff_biweight_h264_pixels_8x16_neon;
- c->biweight_h264_pixels_tab[3] = ff_biweight_h264_pixels_8x8_neon;
- c->biweight_h264_pixels_tab[4] = ff_biweight_h264_pixels_8x4_neon;
- c->biweight_h264_pixels_tab[5] = ff_biweight_h264_pixels_4x8_neon;
- c->biweight_h264_pixels_tab[6] = ff_biweight_h264_pixels_4x4_neon;
- c->biweight_h264_pixels_tab[7] = ff_biweight_h264_pixels_4x2_neon;
+ c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels_16_neon;
+ c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels_8_neon;
+ c->biweight_h264_pixels_tab[2] = ff_biweight_h264_pixels_4_neon;
c->h264_idct_add = ff_h264_idct_add_neon;
c->h264_idct_dc_add = ff_h264_idct_dc_add_neon;
c->h264_idct_add16 = ff_h264_idct_add16_neon;
c->h264_idct_add16intra = ff_h264_idct_add16intra_neon;
- c->h264_idct_add8 = ff_h264_idct_add8_neon;
+ if (chroma_format_idc == 1)
+ c->h264_idct_add8 = ff_h264_idct_add8_neon;
c->h264_idct8_add = ff_h264_idct8_add_neon;
c->h264_idct8_dc_add = ff_h264_idct8_dc_add_neon;
c->h264_idct8_add4 = ff_h264_idct8_add4_neon;
}
}
-void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth)
+void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
{
- if (HAVE_NEON) ff_h264dsp_init_neon(c, bit_depth);
+ if (HAVE_NEON) ff_h264dsp_init_neon(c, bit_depth, chroma_format_idc);
}
diff --git a/libavcodec/arm/h264dsp_neon.S b/libavcodec/arm/h264dsp_neon.S
index b76e447..a4abf66 100644
--- a/libavcodec/arm/h264dsp_neon.S
+++ b/libavcodec/arm/h264dsp_neon.S
@@ -19,414 +19,26 @@
*/
#include "asm.S"
-
- .macro transpose_8x8 r0 r1 r2 r3 r4 r5 r6 r7
- vtrn.32 \r0, \r4
- vtrn.32 \r1, \r5
- vtrn.32 \r2, \r6
- vtrn.32 \r3, \r7
- vtrn.16 \r0, \r2
- vtrn.16 \r1, \r3
- vtrn.16 \r4, \r6
- vtrn.16 \r5, \r7
- vtrn.8 \r0, \r1
- vtrn.8 \r2, \r3
- vtrn.8 \r4, \r5
- vtrn.8 \r6, \r7
- .endm
-
- .macro transpose_4x4 r0 r1 r2 r3
- vtrn.16 \r0, \r2
- vtrn.16 \r1, \r3
- vtrn.8 \r0, \r1
- vtrn.8 \r2, \r3
- .endm
-
- .macro swap4 r0 r1 r2 r3 r4 r5 r6 r7
- vswp \r0, \r4
- vswp \r1, \r5
- vswp \r2, \r6
- vswp \r3, \r7
- .endm
-
- .macro transpose16_4x4 r0 r1 r2 r3 r4 r5 r6 r7
- vtrn.32 \r0, \r2
- vtrn.32 \r1, \r3
- vtrn.32 \r4, \r6
- vtrn.32 \r5, \r7
- vtrn.16 \r0, \r1
- vtrn.16 \r2, \r3
- vtrn.16 \r4, \r5
- vtrn.16 \r6, \r7
- .endm
-
-/* chroma_mc8(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */
- .macro h264_chroma_mc8 type
-function ff_\type\()_h264_chroma_mc8_neon, export=1
- push {r4-r7, lr}
- ldrd r4, [sp, #20]
-.ifc \type,avg
- mov lr, r0
-.endif
- pld [r1]
- pld [r1, r2]
-
- muls r7, r4, r5
- rsb r6, r7, r5, lsl #3
- rsb ip, r7, r4, lsl #3
- sub r4, r7, r4, lsl #3
- sub r4, r4, r5, lsl #3
- add r4, r4, #64
-
- beq 2f
-
- add r5, r1, r2
-
- vdup.8 d0, r4
- lsl r4, r2, #1
- vdup.8 d1, ip
- vld1.64 {d4, d5}, [r1], r4
- vdup.8 d2, r6
- vld1.64 {d6, d7}, [r5], r4
- vdup.8 d3, r7
-
- vext.8 d5, d4, d5, #1
- vext.8 d7, d6, d7, #1
-
-1: pld [r5]
- vmull.u8 q8, d4, d0
- vmlal.u8 q8, d5, d1
- vld1.64 {d4, d5}, [r1], r4
- vmlal.u8 q8, d6, d2
- vext.8 d5, d4, d5, #1
- vmlal.u8 q8, d7, d3
- vmull.u8 q9, d6, d0
- subs r3, r3, #2
- vmlal.u8 q9, d7, d1
- vmlal.u8 q9, d4, d2
- vmlal.u8 q9, d5, d3
- vrshrn.u16 d16, q8, #6
- vld1.64 {d6, d7}, [r5], r4
- pld [r1]
- vrshrn.u16 d17, q9, #6
-.ifc \type,avg
- vld1.64 {d20}, [lr,:64], r2
- vld1.64 {d21}, [lr,:64], r2
- vrhadd.u8 q8, q8, q10
-.endif
- vext.8 d7, d6, d7, #1
- vst1.64 {d16}, [r0,:64], r2
- vst1.64 {d17}, [r0,:64], r2
- bgt 1b
-
- pop {r4-r7, pc}
-
-2: tst r6, r6
- add ip, ip, r6
- vdup.8 d0, r4
- vdup.8 d1, ip
-
- beq 4f
-
- add r5, r1, r2
- lsl r4, r2, #1
- vld1.64 {d4}, [r1], r4
- vld1.64 {d6}, [r5], r4
-
-3: pld [r5]
- vmull.u8 q8, d4, d0
- vmlal.u8 q8, d6, d1
- vld1.64 {d4}, [r1], r4
- vmull.u8 q9, d6, d0
- vmlal.u8 q9, d4, d1
- vld1.64 {d6}, [r5], r4
- vrshrn.u16 d16, q8, #6
- vrshrn.u16 d17, q9, #6
-.ifc \type,avg
- vld1.64 {d20}, [lr,:64], r2
- vld1.64 {d21}, [lr,:64], r2
- vrhadd.u8 q8, q8, q10
-.endif
- subs r3, r3, #2
- pld [r1]
- vst1.64 {d16}, [r0,:64], r2
- vst1.64 {d17}, [r0,:64], r2
- bgt 3b
-
- pop {r4-r7, pc}
-
-4: vld1.64 {d4, d5}, [r1], r2
- vld1.64 {d6, d7}, [r1], r2
- vext.8 d5, d4, d5, #1
- vext.8 d7, d6, d7, #1
-
-5: pld [r1]
- subs r3, r3, #2
- vmull.u8 q8, d4, d0
- vmlal.u8 q8, d5, d1
- vld1.64 {d4, d5}, [r1], r2
- vmull.u8 q9, d6, d0
- vmlal.u8 q9, d7, d1
- pld [r1]
- vext.8 d5, d4, d5, #1
- vrshrn.u16 d16, q8, #6
- vrshrn.u16 d17, q9, #6
-.ifc \type,avg
- vld1.64 {d20}, [lr,:64], r2
- vld1.64 {d21}, [lr,:64], r2
- vrhadd.u8 q8, q8, q10
-.endif
- vld1.64 {d6, d7}, [r1], r2
- vext.8 d7, d6, d7, #1
- vst1.64 {d16}, [r0,:64], r2
- vst1.64 {d17}, [r0,:64], r2
- bgt 5b
-
- pop {r4-r7, pc}
-endfunc
- .endm
-
-/* chroma_mc4(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */
- .macro h264_chroma_mc4 type
-function ff_\type\()_h264_chroma_mc4_neon, export=1
- push {r4-r7, lr}
- ldrd r4, [sp, #20]
-.ifc \type,avg
- mov lr, r0
-.endif
- pld [r1]
- pld [r1, r2]
-
- muls r7, r4, r5
- rsb r6, r7, r5, lsl #3
- rsb ip, r7, r4, lsl #3
- sub r4, r7, r4, lsl #3
- sub r4, r4, r5, lsl #3
- add r4, r4, #64
-
- beq 2f
-
- add r5, r1, r2
-
- vdup.8 d0, r4
- lsl r4, r2, #1
- vdup.8 d1, ip
- vld1.64 {d4}, [r1], r4
- vdup.8 d2, r6
- vld1.64 {d6}, [r5], r4
- vdup.8 d3, r7
-
- vext.8 d5, d4, d5, #1
- vext.8 d7, d6, d7, #1
- vtrn.32 d4, d5
- vtrn.32 d6, d7
-
- vtrn.32 d0, d1
- vtrn.32 d2, d3
-
-1: pld [r5]
- vmull.u8 q8, d4, d0
- vmlal.u8 q8, d6, d2
- vld1.64 {d4}, [r1], r4
- vext.8 d5, d4, d5, #1
- vtrn.32 d4, d5
- vmull.u8 q9, d6, d0
- vmlal.u8 q9, d4, d2
- vld1.64 {d6}, [r5], r4
- vadd.i16 d16, d16, d17
- vadd.i16 d17, d18, d19
- vrshrn.u16 d16, q8, #6
- subs r3, r3, #2
- pld [r1]
-.ifc \type,avg
- vld1.32 {d20[0]}, [lr,:32], r2
- vld1.32 {d20[1]}, [lr,:32], r2
- vrhadd.u8 d16, d16, d20
-.endif
- vext.8 d7, d6, d7, #1
- vtrn.32 d6, d7
- vst1.32 {d16[0]}, [r0,:32], r2
- vst1.32 {d16[1]}, [r0,:32], r2
- bgt 1b
-
- pop {r4-r7, pc}
-
-2: tst r6, r6
- add ip, ip, r6
- vdup.8 d0, r4
- vdup.8 d1, ip
- vtrn.32 d0, d1
-
- beq 4f
-
- vext.32 d1, d0, d1, #1
- add r5, r1, r2
- lsl r4, r2, #1
- vld1.32 {d4[0]}, [r1], r4
- vld1.32 {d4[1]}, [r5], r4
-
-3: pld [r5]
- vmull.u8 q8, d4, d0
- vld1.32 {d4[0]}, [r1], r4
- vmull.u8 q9, d4, d1
- vld1.32 {d4[1]}, [r5], r4
- vadd.i16 d16, d16, d17
- vadd.i16 d17, d18, d19
- vrshrn.u16 d16, q8, #6
-.ifc \type,avg
- vld1.32 {d20[0]}, [lr,:32], r2
- vld1.32 {d20[1]}, [lr,:32], r2
- vrhadd.u8 d16, d16, d20
-.endif
- subs r3, r3, #2
- pld [r1]
- vst1.32 {d16[0]}, [r0,:32], r2
- vst1.32 {d16[1]}, [r0,:32], r2
- bgt 3b
-
- pop {r4-r7, pc}
-
-4: vld1.64 {d4}, [r1], r2
- vld1.64 {d6}, [r1], r2
- vext.8 d5, d4, d5, #1
- vext.8 d7, d6, d7, #1
- vtrn.32 d4, d5
- vtrn.32 d6, d7
-
-5: vmull.u8 q8, d4, d0
- vmull.u8 q9, d6, d0
- subs r3, r3, #2
- vld1.64 {d4}, [r1], r2
- vext.8 d5, d4, d5, #1
- vtrn.32 d4, d5
- vadd.i16 d16, d16, d17
- vadd.i16 d17, d18, d19
- pld [r1]
- vrshrn.u16 d16, q8, #6
-.ifc \type,avg
- vld1.32 {d20[0]}, [lr,:32], r2
- vld1.32 {d20[1]}, [lr,:32], r2
- vrhadd.u8 d16, d16, d20
-.endif
- vld1.64 {d6}, [r1], r2
- vext.8 d7, d6, d7, #1
- vtrn.32 d6, d7
- pld [r1]
- vst1.32 {d16[0]}, [r0,:32], r2
- vst1.32 {d16[1]}, [r0,:32], r2
- bgt 5b
-
- pop {r4-r7, pc}
-endfunc
- .endm
-
- .macro h264_chroma_mc2 type
-function ff_\type\()_h264_chroma_mc2_neon, export=1
- push {r4-r6, lr}
- ldr r4, [sp, #16]
- ldr lr, [sp, #20]
- pld [r1]
- pld [r1, r2]
- orrs r5, r4, lr
- beq 2f
-
- mul r5, r4, lr
- rsb r6, r5, lr, lsl #3
- rsb r12, r5, r4, lsl #3
- sub r4, r5, r4, lsl #3
- sub r4, r4, lr, lsl #3
- add r4, r4, #64
- vdup.8 d0, r4
- vdup.8 d2, r12
- vdup.8 d1, r6
- vdup.8 d3, r5
- vtrn.16 q0, q1
-1:
- vld1.32 {d4[0]}, [r1], r2
- vld1.32 {d4[1]}, [r1], r2
- vrev64.32 d5, d4
- vld1.32 {d5[1]}, [r1]
- vext.8 q3, q2, q2, #1
- vtrn.16 q2, q3
- vmull.u8 q8, d4, d0
- vmlal.u8 q8, d5, d1
-.ifc \type,avg
- vld1.16 {d18[0]}, [r0,:16], r2
- vld1.16 {d18[1]}, [r0,:16]
- sub r0, r0, r2
-.endif
- vtrn.32 d16, d17
- vadd.i16 d16, d16, d17
- vrshrn.u16 d16, q8, #6
-.ifc \type,avg
- vrhadd.u8 d16, d16, d18
-.endif
- vst1.16 {d16[0]}, [r0,:16], r2
- vst1.16 {d16[1]}, [r0,:16], r2
- subs r3, r3, #2
- bgt 1b
- pop {r4-r6, pc}
-2:
-.ifc \type,put
- ldrh r5, [r1], r2
- strh r5, [r0], r2
- ldrh r6, [r1], r2
- strh r6, [r0], r2
-.else
- vld1.16 {d16[0]}, [r1], r2
- vld1.16 {d16[1]}, [r1], r2
- vld1.16 {d18[0]}, [r0,:16], r2
- vld1.16 {d18[1]}, [r0,:16]
- sub r0, r0, r2
- vrhadd.u8 d16, d16, d18
- vst1.16 {d16[0]}, [r0,:16], r2
- vst1.16 {d16[1]}, [r0,:16], r2
-.endif
- subs r3, r3, #2
- bgt 2b
- pop {r4-r6, pc}
-endfunc
-.endm
-
- .text
- .align
-
- h264_chroma_mc8 put
- h264_chroma_mc8 avg
- h264_chroma_mc4 put
- h264_chroma_mc4 avg
- h264_chroma_mc2 put
- h264_chroma_mc2 avg
+#include "neon.S"
/* H.264 loop filter */
- .macro h264_loop_filter_start
- ldr ip, [sp]
+.macro h264_loop_filter_start
+ ldr r12, [sp]
tst r2, r2
- ldr ip, [ip]
+ ldr r12, [r12]
+ it ne
tstne r3, r3
- vmov.32 d24[0], ip
- and ip, ip, ip, lsl #16
+ vmov.32 d24[0], r12
+ and r12, r12, r12, lsl #16
+ it eq
bxeq lr
- ands ip, ip, ip, lsl #8
+ ands r12, r12, r12, lsl #8
+ it lt
bxlt lr
- .endm
-
- .macro align_push_regs
- and ip, sp, #15
- add ip, ip, #32
- sub sp, sp, ip
- vst1.64 {d12-d15}, [sp,:128]
- sub sp, sp, #32
- vst1.64 {d8-d11}, [sp,:128]
- .endm
-
- .macro align_pop_regs
- vld1.64 {d8-d11}, [sp,:128]!
- vld1.64 {d12-d15}, [sp,:128], ip
- .endm
-
- .macro h264_loop_filter_luma
+.endm
+
+.macro h264_loop_filter_luma
vdup.8 q11, r2 @ alpha
vmovl.u8 q12, d24
vabd.u8 q6, q8, q0 @ abs(p0 - q0)
@@ -492,31 +104,31 @@ endfunc
vqmovun.s16 d17, q6
vqmovun.s16 d0, q11
vqmovun.s16 d1, q12
- .endm
+.endm
function ff_h264_v_loop_filter_luma_neon, export=1
h264_loop_filter_start
- vld1.64 {d0, d1}, [r0,:128], r1
- vld1.64 {d2, d3}, [r0,:128], r1
- vld1.64 {d4, d5}, [r0,:128], r1
+ vld1.8 {d0, d1}, [r0,:128], r1
+ vld1.8 {d2, d3}, [r0,:128], r1
+ vld1.8 {d4, d5}, [r0,:128], r1
sub r0, r0, r1, lsl #2
sub r0, r0, r1, lsl #1
- vld1.64 {d20,d21}, [r0,:128], r1
- vld1.64 {d18,d19}, [r0,:128], r1
- vld1.64 {d16,d17}, [r0,:128], r1
+ vld1.8 {d20,d21}, [r0,:128], r1
+ vld1.8 {d18,d19}, [r0,:128], r1
+ vld1.8 {d16,d17}, [r0,:128], r1
- align_push_regs
+ vpush {d8-d15}
h264_loop_filter_luma
sub r0, r0, r1, lsl #1
- vst1.64 {d8, d9}, [r0,:128], r1
- vst1.64 {d16,d17}, [r0,:128], r1
- vst1.64 {d0, d1}, [r0,:128], r1
- vst1.64 {d10,d11}, [r0,:128]
+ vst1.8 {d8, d9}, [r0,:128], r1
+ vst1.8 {d16,d17}, [r0,:128], r1
+ vst1.8 {d0, d1}, [r0,:128], r1
+ vst1.8 {d10,d11}, [r0,:128]
- align_pop_regs
+ vpop {d8-d15}
bx lr
endfunc
@@ -524,26 +136,26 @@ function ff_h264_h_loop_filter_luma_neon, export=1
h264_loop_filter_start
sub r0, r0, #4
- vld1.64 {d6}, [r0], r1
- vld1.64 {d20}, [r0], r1
- vld1.64 {d18}, [r0], r1
- vld1.64 {d16}, [r0], r1
- vld1.64 {d0}, [r0], r1
- vld1.64 {d2}, [r0], r1
- vld1.64 {d4}, [r0], r1
- vld1.64 {d26}, [r0], r1
- vld1.64 {d7}, [r0], r1
- vld1.64 {d21}, [r0], r1
- vld1.64 {d19}, [r0], r1
- vld1.64 {d17}, [r0], r1
- vld1.64 {d1}, [r0], r1
- vld1.64 {d3}, [r0], r1
- vld1.64 {d5}, [r0], r1
- vld1.64 {d27}, [r0], r1
+ vld1.8 {d6}, [r0], r1
+ vld1.8 {d20}, [r0], r1
+ vld1.8 {d18}, [r0], r1
+ vld1.8 {d16}, [r0], r1
+ vld1.8 {d0}, [r0], r1
+ vld1.8 {d2}, [r0], r1
+ vld1.8 {d4}, [r0], r1
+ vld1.8 {d26}, [r0], r1
+ vld1.8 {d7}, [r0], r1
+ vld1.8 {d21}, [r0], r1
+ vld1.8 {d19}, [r0], r1
+ vld1.8 {d17}, [r0], r1
+ vld1.8 {d1}, [r0], r1
+ vld1.8 {d3}, [r0], r1
+ vld1.8 {d5}, [r0], r1
+ vld1.8 {d27}, [r0], r1
transpose_8x8 q3, q10, q9, q8, q0, q1, q2, q13
- align_push_regs
+ vpush {d8-d15}
h264_loop_filter_luma
@@ -568,11 +180,11 @@ function ff_h264_h_loop_filter_luma_neon, export=1
vst1.32 {d1[1]}, [r0], r1
vst1.32 {d11[1]}, [r0], r1
- align_pop_regs
+ vpop {d8-d15}
bx lr
endfunc
- .macro h264_loop_filter_chroma
+.macro h264_loop_filter_chroma
vdup.8 d22, r2 @ alpha
vmovl.u8 q12, d24
vabd.u8 d26, d16, d0 @ abs(p0 - q0)
@@ -601,22 +213,22 @@ endfunc
vsubw.s8 q11, q11, d4
vqmovun.s16 d16, q14
vqmovun.s16 d0, q11
- .endm
+.endm
function ff_h264_v_loop_filter_chroma_neon, export=1
h264_loop_filter_start
sub r0, r0, r1, lsl #1
- vld1.64 {d18}, [r0,:64], r1
- vld1.64 {d16}, [r0,:64], r1
- vld1.64 {d0}, [r0,:64], r1
- vld1.64 {d2}, [r0,:64]
+ vld1.8 {d18}, [r0,:64], r1
+ vld1.8 {d16}, [r0,:64], r1
+ vld1.8 {d0}, [r0,:64], r1
+ vld1.8 {d2}, [r0,:64]
h264_loop_filter_chroma
sub r0, r0, r1, lsl #1
- vst1.64 {d16}, [r0,:64], r1
- vst1.64 {d0}, [r0,:64], r1
+ vst1.8 {d16}, [r0,:64], r1
+ vst1.8 {d0}, [r0,:64], r1
bx lr
endfunc
@@ -661,20 +273,20 @@ endfunc
/* H.264 qpel MC */
- .macro lowpass_const r
+.macro lowpass_const r
movw \r, #5
movt \r, #20
vmov.32 d6[0], \r
- .endm
+.endm
- .macro lowpass_8 r0, r1, r2, r3, d0, d1, narrow=1
-.if \narrow
+.macro lowpass_8 r0, r1, r2, r3, d0, d1, narrow=1
+ .if \narrow
t0 .req q0
t1 .req q8
-.else
+ .else
t0 .req \d0
t1 .req \d1
-.endif
+ .endif
vext.8 d2, \r0, \r1, #2
vext.8 d3, \r0, \r1, #3
vaddl.u8 q1, d2, d3
@@ -695,20 +307,20 @@ endfunc
vaddl.u8 t1, \r2, d31
vmla.i16 t1, q9, d6[1]
vmls.i16 t1, q10, d6[0]
-.if \narrow
+ .if \narrow
vqrshrun.s16 \d0, t0, #5
vqrshrun.s16 \d1, t1, #5
-.endif
+ .endif
.unreq t0
.unreq t1
- .endm
+.endm
- .macro lowpass_8_1 r0, r1, d0, narrow=1
-.if \narrow
+.macro lowpass_8_1 r0, r1, d0, narrow=1
+ .if \narrow
t0 .req q0
-.else
+ .else
t0 .req \d0
-.endif
+ .endif
vext.8 d2, \r0, \r1, #2
vext.8 d3, \r0, \r1, #3
vaddl.u8 q1, d2, d3
@@ -719,13 +331,13 @@ endfunc
vaddl.u8 t0, \r0, d30
vmla.i16 t0, q1, d6[1]
vmls.i16 t0, q2, d6[0]
-.if \narrow
+ .if \narrow
vqrshrun.s16 \d0, t0, #5
-.endif
+ .endif
.unreq t0
- .endm
+.endm
- .macro lowpass_8.16 r0, r1, l0, h0, l1, h1, d
+.macro lowpass_8.16 r0, r1, l0, h0, l1, h1, d
vext.16 q1, \r0, \r1, #2
vext.16 q0, \r0, \r1, #3
vaddl.s16 q9, d2, d0
@@ -760,59 +372,59 @@ endfunc
vrshrn.s32 d19, q1, #10
vqmovun.s16 \d, q9
- .endm
+.endm
function put_h264_qpel16_h_lowpass_neon_packed
mov r4, lr
- mov ip, #16
+ mov r12, #16
mov r3, #8
bl put_h264_qpel8_h_lowpass_neon
sub r1, r1, r2, lsl #4
add r1, r1, #8
- mov ip, #16
+ mov r12, #16
mov lr, r4
b put_h264_qpel8_h_lowpass_neon
endfunc
- .macro h264_qpel_h_lowpass type
+.macro h264_qpel_h_lowpass type
function \type\()_h264_qpel16_h_lowpass_neon
push {lr}
- mov ip, #16
+ mov r12, #16
bl \type\()_h264_qpel8_h_lowpass_neon
sub r0, r0, r3, lsl #4
sub r1, r1, r2, lsl #4
add r0, r0, #8
add r1, r1, #8
- mov ip, #16
+ mov r12, #16
pop {lr}
endfunc
function \type\()_h264_qpel8_h_lowpass_neon
-1: vld1.64 {d0, d1}, [r1], r2
- vld1.64 {d16,d17}, [r1], r2
- subs ip, ip, #2
+1: vld1.8 {d0, d1}, [r1], r2
+ vld1.8 {d16,d17}, [r1], r2
+ subs r12, r12, #2
lowpass_8 d0, d1, d16, d17, d0, d16
-.ifc \type,avg
+ .ifc \type,avg
vld1.8 {d2}, [r0,:64], r3
vrhadd.u8 d0, d0, d2
vld1.8 {d3}, [r0,:64]
vrhadd.u8 d16, d16, d3
sub r0, r0, r3
-.endif
- vst1.64 {d0}, [r0,:64], r3
- vst1.64 {d16}, [r0,:64], r3
+ .endif
+ vst1.8 {d0}, [r0,:64], r3
+ vst1.8 {d16}, [r0,:64], r3
bne 1b
bx lr
endfunc
- .endm
+.endm
h264_qpel_h_lowpass put
h264_qpel_h_lowpass avg
- .macro h264_qpel_h_lowpass_l2 type
+.macro h264_qpel_h_lowpass_l2 type
function \type\()_h264_qpel16_h_lowpass_l2_neon
push {lr}
- mov ip, #16
+ mov r12, #16
bl \type\()_h264_qpel8_h_lowpass_l2_neon
sub r0, r0, r2, lsl #4
sub r1, r1, r2, lsl #4
@@ -820,31 +432,31 @@ function \type\()_h264_qpel16_h_lowpass_l2_neon
add r0, r0, #8
add r1, r1, #8
add r3, r3, #8
- mov ip, #16
+ mov r12, #16
pop {lr}
endfunc
function \type\()_h264_qpel8_h_lowpass_l2_neon
-1: vld1.64 {d0, d1}, [r1], r2
- vld1.64 {d16,d17}, [r1], r2
- vld1.64 {d28}, [r3], r2
- vld1.64 {d29}, [r3], r2
- subs ip, ip, #2
+1: vld1.8 {d0, d1}, [r1], r2
+ vld1.8 {d16,d17}, [r1], r2
+ vld1.8 {d28}, [r3], r2
+ vld1.8 {d29}, [r3], r2
+ subs r12, r12, #2
lowpass_8 d0, d1, d16, d17, d0, d1
vrhadd.u8 q0, q0, q14
-.ifc \type,avg
+ .ifc \type,avg
vld1.8 {d2}, [r0,:64], r2
vrhadd.u8 d0, d0, d2
vld1.8 {d3}, [r0,:64]
vrhadd.u8 d1, d1, d3
sub r0, r0, r2
-.endif
- vst1.64 {d0}, [r0,:64], r2
- vst1.64 {d1}, [r0,:64], r2
+ .endif
+ vst1.8 {d0}, [r0,:64], r2
+ vst1.8 {d1}, [r0,:64], r2
bne 1b
bx lr
endfunc
- .endm
+.endm
h264_qpel_h_lowpass_l2 put
h264_qpel_h_lowpass_l2 avg
@@ -864,7 +476,7 @@ function put_h264_qpel16_v_lowpass_neon_packed
b put_h264_qpel8_v_lowpass_neon
endfunc
- .macro h264_qpel_v_lowpass type
+.macro h264_qpel_v_lowpass type
function \type\()_h264_qpel16_v_lowpass_neon
mov r4, lr
bl \type\()_h264_qpel8_v_lowpass_neon
@@ -881,19 +493,19 @@ function \type\()_h264_qpel16_v_lowpass_neon
endfunc
function \type\()_h264_qpel8_v_lowpass_neon
- vld1.64 {d8}, [r1], r3
- vld1.64 {d10}, [r1], r3
- vld1.64 {d12}, [r1], r3
- vld1.64 {d14}, [r1], r3
- vld1.64 {d22}, [r1], r3
- vld1.64 {d24}, [r1], r3
- vld1.64 {d26}, [r1], r3
- vld1.64 {d28}, [r1], r3
- vld1.64 {d9}, [r1], r3
- vld1.64 {d11}, [r1], r3
- vld1.64 {d13}, [r1], r3
- vld1.64 {d15}, [r1], r3
- vld1.64 {d23}, [r1]
+ vld1.8 {d8}, [r1], r3
+ vld1.8 {d10}, [r1], r3
+ vld1.8 {d12}, [r1], r3
+ vld1.8 {d14}, [r1], r3
+ vld1.8 {d22}, [r1], r3
+ vld1.8 {d24}, [r1], r3
+ vld1.8 {d26}, [r1], r3
+ vld1.8 {d28}, [r1], r3
+ vld1.8 {d9}, [r1], r3
+ vld1.8 {d11}, [r1], r3
+ vld1.8 {d13}, [r1], r3
+ vld1.8 {d15}, [r1], r3
+ vld1.8 {d23}, [r1]
transpose_8x8 q4, q5, q6, q7, q11, q12, q13, q14
lowpass_8 d8, d9, d10, d11, d8, d10
@@ -902,7 +514,7 @@ function \type\()_h264_qpel8_v_lowpass_neon
lowpass_8 d26, d27, d28, d29, d26, d28
transpose_8x8 d8, d10, d12, d14, d22, d24, d26, d28
-.ifc \type,avg
+ .ifc \type,avg
vld1.8 {d9}, [r0,:64], r2
vrhadd.u8 d8, d8, d9
vld1.8 {d11}, [r0,:64], r2
@@ -920,34 +532,34 @@ function \type\()_h264_qpel8_v_lowpass_neon
vld1.8 {d29}, [r0,:64], r2
vrhadd.u8 d28, d28, d29
sub r0, r0, r2, lsl #3
-.endif
+ .endif
- vst1.64 {d8}, [r0,:64], r2
- vst1.64 {d10}, [r0,:64], r2
- vst1.64 {d12}, [r0,:64], r2
- vst1.64 {d14}, [r0,:64], r2
- vst1.64 {d22}, [r0,:64], r2
- vst1.64 {d24}, [r0,:64], r2
- vst1.64 {d26}, [r0,:64], r2
- vst1.64 {d28}, [r0,:64], r2
+ vst1.8 {d8}, [r0,:64], r2
+ vst1.8 {d10}, [r0,:64], r2
+ vst1.8 {d12}, [r0,:64], r2
+ vst1.8 {d14}, [r0,:64], r2
+ vst1.8 {d22}, [r0,:64], r2
+ vst1.8 {d24}, [r0,:64], r2
+ vst1.8 {d26}, [r0,:64], r2
+ vst1.8 {d28}, [r0,:64], r2
bx lr
endfunc
- .endm
+.endm
h264_qpel_v_lowpass put
h264_qpel_v_lowpass avg
- .macro h264_qpel_v_lowpass_l2 type
+.macro h264_qpel_v_lowpass_l2 type
function \type\()_h264_qpel16_v_lowpass_l2_neon
mov r4, lr
bl \type\()_h264_qpel8_v_lowpass_l2_neon
sub r1, r1, r3, lsl #2
bl \type\()_h264_qpel8_v_lowpass_l2_neon
sub r0, r0, r3, lsl #4
- sub ip, ip, r2, lsl #4
+ sub r12, r12, r2, lsl #4
add r0, r0, #8
- add ip, ip, #8
+ add r12, r12, #8
sub r1, r1, r3, lsl #4
sub r1, r1, r3, lsl #2
add r1, r1, #8
@@ -957,19 +569,19 @@ function \type\()_h264_qpel16_v_lowpass_l2_neon
endfunc
function \type\()_h264_qpel8_v_lowpass_l2_neon
- vld1.64 {d8}, [r1], r3
- vld1.64 {d10}, [r1], r3
- vld1.64 {d12}, [r1], r3
- vld1.64 {d14}, [r1], r3
- vld1.64 {d22}, [r1], r3
- vld1.64 {d24}, [r1], r3
- vld1.64 {d26}, [r1], r3
- vld1.64 {d28}, [r1], r3
- vld1.64 {d9}, [r1], r3
- vld1.64 {d11}, [r1], r3
- vld1.64 {d13}, [r1], r3
- vld1.64 {d15}, [r1], r3
- vld1.64 {d23}, [r1]
+ vld1.8 {d8}, [r1], r3
+ vld1.8 {d10}, [r1], r3
+ vld1.8 {d12}, [r1], r3
+ vld1.8 {d14}, [r1], r3
+ vld1.8 {d22}, [r1], r3
+ vld1.8 {d24}, [r1], r3
+ vld1.8 {d26}, [r1], r3
+ vld1.8 {d28}, [r1], r3
+ vld1.8 {d9}, [r1], r3
+ vld1.8 {d11}, [r1], r3
+ vld1.8 {d13}, [r1], r3
+ vld1.8 {d15}, [r1], r3
+ vld1.8 {d23}, [r1]
transpose_8x8 q4, q5, q6, q7, q11, q12, q13, q14
lowpass_8 d8, d9, d10, d11, d8, d9
@@ -978,20 +590,20 @@ function \type\()_h264_qpel8_v_lowpass_l2_neon
lowpass_8 d26, d27, d28, d29, d26, d27
transpose_8x8 d8, d9, d12, d13, d22, d23, d26, d27
- vld1.64 {d0}, [ip], r2
- vld1.64 {d1}, [ip], r2
- vld1.64 {d2}, [ip], r2
- vld1.64 {d3}, [ip], r2
- vld1.64 {d4}, [ip], r2
+ vld1.8 {d0}, [r12], r2
+ vld1.8 {d1}, [r12], r2
+ vld1.8 {d2}, [r12], r2
+ vld1.8 {d3}, [r12], r2
+ vld1.8 {d4}, [r12], r2
vrhadd.u8 q0, q0, q4
- vld1.64 {d5}, [ip], r2
+ vld1.8 {d5}, [r12], r2
vrhadd.u8 q1, q1, q6
- vld1.64 {d10}, [ip], r2
+ vld1.8 {d10}, [r12], r2
vrhadd.u8 q2, q2, q11
- vld1.64 {d11}, [ip], r2
+ vld1.8 {d11}, [r12], r2
vrhadd.u8 q5, q5, q13
-.ifc \type,avg
+ .ifc \type,avg
vld1.8 {d16}, [r0,:64], r3
vrhadd.u8 d0, d0, d16
vld1.8 {d17}, [r0,:64], r3
@@ -1009,51 +621,51 @@ function \type\()_h264_qpel8_v_lowpass_l2_neon
vld1.8 {d17}, [r0,:64], r3
vrhadd.u8 d11, d11, d17
sub r0, r0, r3, lsl #3
-.endif
+ .endif
- vst1.64 {d0}, [r0,:64], r3
- vst1.64 {d1}, [r0,:64], r3
- vst1.64 {d2}, [r0,:64], r3
- vst1.64 {d3}, [r0,:64], r3
- vst1.64 {d4}, [r0,:64], r3
- vst1.64 {d5}, [r0,:64], r3
- vst1.64 {d10}, [r0,:64], r3
- vst1.64 {d11}, [r0,:64], r3
+ vst1.8 {d0}, [r0,:64], r3
+ vst1.8 {d1}, [r0,:64], r3
+ vst1.8 {d2}, [r0,:64], r3
+ vst1.8 {d3}, [r0,:64], r3
+ vst1.8 {d4}, [r0,:64], r3
+ vst1.8 {d5}, [r0,:64], r3
+ vst1.8 {d10}, [r0,:64], r3
+ vst1.8 {d11}, [r0,:64], r3
bx lr
endfunc
- .endm
+.endm
h264_qpel_v_lowpass_l2 put
h264_qpel_v_lowpass_l2 avg
function put_h264_qpel8_hv_lowpass_neon_top
- lowpass_const ip
- mov ip, #12
-1: vld1.64 {d0, d1}, [r1], r3
- vld1.64 {d16,d17}, [r1], r3
- subs ip, ip, #2
+ lowpass_const r12
+ mov r12, #12
+1: vld1.8 {d0, d1}, [r1], r3
+ vld1.8 {d16,d17}, [r1], r3
+ subs r12, r12, #2
lowpass_8 d0, d1, d16, d17, q11, q12, narrow=0
- vst1.64 {d22-d25}, [r4,:128]!
+ vst1.8 {d22-d25}, [r4,:128]!
bne 1b
- vld1.64 {d0, d1}, [r1]
+ vld1.8 {d0, d1}, [r1]
lowpass_8_1 d0, d1, q12, narrow=0
- mov ip, #-16
- add r4, r4, ip
- vld1.64 {d30,d31}, [r4,:128], ip
- vld1.64 {d20,d21}, [r4,:128], ip
- vld1.64 {d18,d19}, [r4,:128], ip
- vld1.64 {d16,d17}, [r4,:128], ip
- vld1.64 {d14,d15}, [r4,:128], ip
- vld1.64 {d12,d13}, [r4,:128], ip
- vld1.64 {d10,d11}, [r4,:128], ip
- vld1.64 {d8, d9}, [r4,:128], ip
- vld1.64 {d6, d7}, [r4,:128], ip
- vld1.64 {d4, d5}, [r4,:128], ip
- vld1.64 {d2, d3}, [r4,:128], ip
- vld1.64 {d0, d1}, [r4,:128]
+ mov r12, #-16
+ add r4, r4, r12
+ vld1.8 {d30,d31}, [r4,:128], r12
+ vld1.8 {d20,d21}, [r4,:128], r12
+ vld1.8 {d18,d19}, [r4,:128], r12
+ vld1.8 {d16,d17}, [r4,:128], r12
+ vld1.8 {d14,d15}, [r4,:128], r12
+ vld1.8 {d12,d13}, [r4,:128], r12
+ vld1.8 {d10,d11}, [r4,:128], r12
+ vld1.8 {d8, d9}, [r4,:128], r12
+ vld1.8 {d6, d7}, [r4,:128], r12
+ vld1.8 {d4, d5}, [r4,:128], r12
+ vld1.8 {d2, d3}, [r4,:128], r12
+ vld1.8 {d0, d1}, [r4,:128]
swap4 d1, d3, d5, d7, d8, d10, d12, d14
transpose16_4x4 q0, q1, q2, q3, q4, q5, q6, q7
@@ -1061,31 +673,31 @@ function put_h264_qpel8_hv_lowpass_neon_top
swap4 d17, d19, d21, d31, d24, d26, d28, d22
transpose16_4x4 q8, q9, q10, q15, q12, q13, q14, q11
- vst1.64 {d30,d31}, [r4,:128]!
- vst1.64 {d6, d7}, [r4,:128]!
- vst1.64 {d20,d21}, [r4,:128]!
- vst1.64 {d4, d5}, [r4,:128]!
- vst1.64 {d18,d19}, [r4,:128]!
- vst1.64 {d2, d3}, [r4,:128]!
- vst1.64 {d16,d17}, [r4,:128]!
- vst1.64 {d0, d1}, [r4,:128]
+ vst1.8 {d30,d31}, [r4,:128]!
+ vst1.8 {d6, d7}, [r4,:128]!
+ vst1.8 {d20,d21}, [r4,:128]!
+ vst1.8 {d4, d5}, [r4,:128]!
+ vst1.8 {d18,d19}, [r4,:128]!
+ vst1.8 {d2, d3}, [r4,:128]!
+ vst1.8 {d16,d17}, [r4,:128]!
+ vst1.8 {d0, d1}, [r4,:128]
lowpass_8.16 q4, q12, d8, d9, d24, d25, d8
lowpass_8.16 q5, q13, d10, d11, d26, d27, d9
lowpass_8.16 q6, q14, d12, d13, d28, d29, d10
lowpass_8.16 q7, q11, d14, d15, d22, d23, d11
- vld1.64 {d16,d17}, [r4,:128], ip
- vld1.64 {d30,d31}, [r4,:128], ip
+ vld1.8 {d16,d17}, [r4,:128], r12
+ vld1.8 {d30,d31}, [r4,:128], r12
lowpass_8.16 q8, q15, d16, d17, d30, d31, d12
- vld1.64 {d16,d17}, [r4,:128], ip
- vld1.64 {d30,d31}, [r4,:128], ip
+ vld1.8 {d16,d17}, [r4,:128], r12
+ vld1.8 {d30,d31}, [r4,:128], r12
lowpass_8.16 q8, q15, d16, d17, d30, d31, d13
- vld1.64 {d16,d17}, [r4,:128], ip
- vld1.64 {d30,d31}, [r4,:128], ip
+ vld1.8 {d16,d17}, [r4,:128], r12
+ vld1.8 {d30,d31}, [r4,:128], r12
lowpass_8.16 q8, q15, d16, d17, d30, d31, d14
- vld1.64 {d16,d17}, [r4,:128], ip
- vld1.64 {d30,d31}, [r4,:128]
+ vld1.8 {d16,d17}, [r4,:128], r12
+ vld1.8 {d30,d31}, [r4,:128]
lowpass_8.16 q8, q15, d16, d17, d30, d31, d15
transpose_8x8 d12, d13, d14, d15, d8, d9, d10, d11
@@ -1093,11 +705,11 @@ function put_h264_qpel8_hv_lowpass_neon_top
bx lr
endfunc
- .macro h264_qpel8_hv_lowpass type
+.macro h264_qpel8_hv_lowpass type
function \type\()_h264_qpel8_hv_lowpass_neon
mov r10, lr
bl put_h264_qpel8_hv_lowpass_neon_top
-.ifc \type,avg
+ .ifc \type,avg
vld1.8 {d0}, [r0,:64], r2
vrhadd.u8 d12, d12, d0
vld1.8 {d1}, [r0,:64], r2
@@ -1115,38 +727,39 @@ function \type\()_h264_qpel8_hv_lowpass_neon
vld1.8 {d7}, [r0,:64], r2
vrhadd.u8 d11, d11, d7
sub r0, r0, r2, lsl #3
-.endif
- vst1.64 {d12}, [r0,:64], r2
- vst1.64 {d13}, [r0,:64], r2
- vst1.64 {d14}, [r0,:64], r2
- vst1.64 {d15}, [r0,:64], r2
- vst1.64 {d8}, [r0,:64], r2
- vst1.64 {d9}, [r0,:64], r2
- vst1.64 {d10}, [r0,:64], r2
- vst1.64 {d11}, [r0,:64], r2
+ .endif
+
+ vst1.8 {d12}, [r0,:64], r2
+ vst1.8 {d13}, [r0,:64], r2
+ vst1.8 {d14}, [r0,:64], r2
+ vst1.8 {d15}, [r0,:64], r2
+ vst1.8 {d8}, [r0,:64], r2
+ vst1.8 {d9}, [r0,:64], r2
+ vst1.8 {d10}, [r0,:64], r2
+ vst1.8 {d11}, [r0,:64], r2
mov lr, r10
bx lr
endfunc
- .endm
+.endm
h264_qpel8_hv_lowpass put
h264_qpel8_hv_lowpass avg
- .macro h264_qpel8_hv_lowpass_l2 type
+.macro h264_qpel8_hv_lowpass_l2 type
function \type\()_h264_qpel8_hv_lowpass_l2_neon
mov r10, lr
bl put_h264_qpel8_hv_lowpass_neon_top
- vld1.64 {d0, d1}, [r2,:128]!
- vld1.64 {d2, d3}, [r2,:128]!
+ vld1.8 {d0, d1}, [r2,:128]!
+ vld1.8 {d2, d3}, [r2,:128]!
vrhadd.u8 q0, q0, q6
- vld1.64 {d4, d5}, [r2,:128]!
+ vld1.8 {d4, d5}, [r2,:128]!
vrhadd.u8 q1, q1, q7
- vld1.64 {d6, d7}, [r2,:128]!
+ vld1.8 {d6, d7}, [r2,:128]!
vrhadd.u8 q2, q2, q4
vrhadd.u8 q3, q3, q5
-.ifc \type,avg
+ .ifc \type,avg
vld1.8 {d16}, [r0,:64], r3
vrhadd.u8 d0, d0, d16
vld1.8 {d17}, [r0,:64], r3
@@ -1164,25 +777,25 @@ function \type\()_h264_qpel8_hv_lowpass_l2_neon
vld1.8 {d23}, [r0,:64], r3
vrhadd.u8 d7, d7, d23
sub r0, r0, r3, lsl #3
-.endif
- vst1.64 {d0}, [r0,:64], r3
- vst1.64 {d1}, [r0,:64], r3
- vst1.64 {d2}, [r0,:64], r3
- vst1.64 {d3}, [r0,:64], r3
- vst1.64 {d4}, [r0,:64], r3
- vst1.64 {d5}, [r0,:64], r3
- vst1.64 {d6}, [r0,:64], r3
- vst1.64 {d7}, [r0,:64], r3
+ .endif
+ vst1.8 {d0}, [r0,:64], r3
+ vst1.8 {d1}, [r0,:64], r3
+ vst1.8 {d2}, [r0,:64], r3
+ vst1.8 {d3}, [r0,:64], r3
+ vst1.8 {d4}, [r0,:64], r3
+ vst1.8 {d5}, [r0,:64], r3
+ vst1.8 {d6}, [r0,:64], r3
+ vst1.8 {d7}, [r0,:64], r3
mov lr, r10
bx lr
endfunc
- .endm
+.endm
h264_qpel8_hv_lowpass_l2 put
h264_qpel8_hv_lowpass_l2 avg
- .macro h264_qpel16_hv type
+.macro h264_qpel16_hv type
function \type\()_h264_qpel16_hv_lowpass_neon
mov r9, lr
bl \type\()_h264_qpel8_hv_lowpass_neon
@@ -1215,17 +828,17 @@ function \type\()_h264_qpel16_hv_lowpass_l2_neon
mov lr, r9
b \type\()_h264_qpel8_hv_lowpass_l2_neon
endfunc
- .endm
+.endm
h264_qpel16_hv put
h264_qpel16_hv avg
- .macro h264_qpel8 type
+.macro h264_qpel8 type
function ff_\type\()_h264_qpel8_mc10_neon, export=1
lowpass_const r3
mov r3, r1
sub r1, r1, #2
- mov ip, #8
+ mov r12, #8
b \type\()_h264_qpel8_h_lowpass_l2_neon
endfunc
@@ -1233,7 +846,7 @@ function ff_\type\()_h264_qpel8_mc20_neon, export=1
lowpass_const r3
sub r1, r1, #2
mov r3, r2
- mov ip, #8
+ mov r12, #8
b \type\()_h264_qpel8_h_lowpass_neon
endfunc
@@ -1241,13 +854,13 @@ function ff_\type\()_h264_qpel8_mc30_neon, export=1
lowpass_const r3
add r3, r1, #1
sub r1, r1, #2
- mov ip, #8
+ mov r12, #8
b \type\()_h264_qpel8_h_lowpass_l2_neon
endfunc
function ff_\type\()_h264_qpel8_mc01_neon, export=1
push {lr}
- mov ip, r1
+ mov r12, r1
\type\()_h264_qpel8_mc01:
lowpass_const r3
mov r3, r2
@@ -1263,22 +876,24 @@ function ff_\type\()_h264_qpel8_mc11_neon, export=1
\type\()_h264_qpel8_mc11:
lowpass_const r3
mov r11, sp
- bic sp, sp, #15
+A bic sp, sp, #15
+T bic r0, r11, #15
+T mov sp, r0
sub sp, sp, #64
mov r0, sp
sub r1, r1, #2
mov r3, #8
- mov ip, #8
+ mov r12, #8
vpush {d8-d15}
bl put_h264_qpel8_h_lowpass_neon
- ldrd r0, [r11]
+ ldrd r0, [r11], #8
mov r3, r2
- add ip, sp, #64
+ add r12, sp, #64
sub r1, r1, r2, lsl #1
mov r2, #8
bl \type\()_h264_qpel8_v_lowpass_l2_neon
vpop {d8-d15}
- add sp, r11, #8
+ mov sp, r11
pop {r11, pc}
endfunc
@@ -1287,23 +902,25 @@ function ff_\type\()_h264_qpel8_mc21_neon, export=1
\type\()_h264_qpel8_mc21:
lowpass_const r3
mov r11, sp
- bic sp, sp, #15
+A bic sp, sp, #15
+T bic r0, r11, #15
+T mov sp, r0
sub sp, sp, #(8*8+16*12)
sub r1, r1, #2
mov r3, #8
mov r0, sp
- mov ip, #8
+ mov r12, #8
vpush {d8-d15}
bl put_h264_qpel8_h_lowpass_neon
mov r4, r0
- ldrd r0, [r11]
+ ldrd r0, [r11], #8
sub r1, r1, r2, lsl #1
sub r1, r1, #2
mov r3, r2
sub r2, r4, #64
bl \type\()_h264_qpel8_hv_lowpass_l2_neon
vpop {d8-d15}
- add sp, r11, #8
+ mov sp, r11
pop {r4, r10, r11, pc}
endfunc
@@ -1330,7 +947,9 @@ function ff_\type\()_h264_qpel8_mc12_neon, export=1
\type\()_h264_qpel8_mc12:
lowpass_const r3
mov r11, sp
- bic sp, sp, #15
+A bic sp, sp, #15
+T bic r0, r11, #15
+T mov sp, r0
sub sp, sp, #(8*8+16*12)
sub r1, r1, r2, lsl #1
mov r3, r2
@@ -1339,20 +958,22 @@ function ff_\type\()_h264_qpel8_mc12_neon, export=1
vpush {d8-d15}
bl put_h264_qpel8_v_lowpass_neon
mov r4, r0
- ldrd r0, [r11]
+ ldrd r0, [r11], #8
sub r1, r1, r3, lsl #1
sub r1, r1, #2
sub r2, r4, #64
bl \type\()_h264_qpel8_hv_lowpass_l2_neon
vpop {d8-d15}
- add sp, r11, #8
+ mov sp, r11
pop {r4, r10, r11, pc}
endfunc
function ff_\type\()_h264_qpel8_mc22_neon, export=1
push {r4, r10, r11, lr}
mov r11, sp
- bic sp, sp, #15
+A bic sp, sp, #15
+T bic r4, r11, #15
+T mov sp, r4
sub r1, r1, r2, lsl #1
sub r1, r1, #2
mov r3, r2
@@ -1373,7 +994,7 @@ endfunc
function ff_\type\()_h264_qpel8_mc03_neon, export=1
push {lr}
- add ip, r1, r2
+ add r12, r1, r2
b \type\()_h264_qpel8_mc01
endfunc
@@ -1396,12 +1017,12 @@ function ff_\type\()_h264_qpel8_mc33_neon, export=1
sub r1, r1, #1
b \type\()_h264_qpel8_mc11
endfunc
- .endm
+.endm
h264_qpel8 put
h264_qpel8 avg
- .macro h264_qpel16 type
+.macro h264_qpel16 type
function ff_\type\()_h264_qpel16_mc10_neon, export=1
lowpass_const r3
mov r3, r1
@@ -1425,7 +1046,7 @@ endfunc
function ff_\type\()_h264_qpel16_mc01_neon, export=1
push {r4, lr}
- mov ip, r1
+ mov r12, r1
\type\()_h264_qpel16_mc01:
lowpass_const r3
mov r3, r2
@@ -1441,21 +1062,23 @@ function ff_\type\()_h264_qpel16_mc11_neon, export=1
\type\()_h264_qpel16_mc11:
lowpass_const r3
mov r11, sp
- bic sp, sp, #15
+A bic sp, sp, #15
+T bic r0, r11, #15
+T mov sp, r0
sub sp, sp, #256
mov r0, sp
sub r1, r1, #2
mov r3, #16
vpush {d8-d15}
bl put_h264_qpel16_h_lowpass_neon
- ldrd r0, [r11]
+ ldrd r0, [r11], #8
mov r3, r2
- add ip, sp, #64
+ add r12, sp, #64
sub r1, r1, r2, lsl #1
mov r2, #16
bl \type\()_h264_qpel16_v_lowpass_l2_neon
vpop {d8-d15}
- add sp, r11, #8
+ mov sp, r11
pop {r4, r11, pc}
endfunc
@@ -1464,20 +1087,22 @@ function ff_\type\()_h264_qpel16_mc21_neon, export=1
\type\()_h264_qpel16_mc21:
lowpass_const r3
mov r11, sp
- bic sp, sp, #15
+A bic sp, sp, #15
+T bic r0, r11, #15
+T mov sp, r0
sub sp, sp, #(16*16+16*12)
sub r1, r1, #2
mov r0, sp
vpush {d8-d15}
bl put_h264_qpel16_h_lowpass_neon_packed
mov r4, r0
- ldrd r0, [r11]
+ ldrd r0, [r11], #8
sub r1, r1, r2, lsl #1
sub r1, r1, #2
mov r3, r2
bl \type\()_h264_qpel16_hv_lowpass_l2_neon
vpop {d8-d15}
- add sp, r11, #8
+ mov sp, r11
pop {r4-r5, r9-r11, pc}
endfunc
@@ -1504,7 +1129,9 @@ function ff_\type\()_h264_qpel16_mc12_neon, export=1
\type\()_h264_qpel16_mc12:
lowpass_const r3
mov r11, sp
- bic sp, sp, #15
+A bic sp, sp, #15
+T bic r0, r11, #15
+T mov sp, r0
sub sp, sp, #(16*16+16*12)
sub r1, r1, r2, lsl #1
mov r0, sp
@@ -1512,13 +1139,13 @@ function ff_\type\()_h264_qpel16_mc12_neon, export=1
vpush {d8-d15}
bl put_h264_qpel16_v_lowpass_neon_packed
mov r4, r0
- ldrd r0, [r11]
+ ldrd r0, [r11], #8
sub r1, r1, r3, lsl #1
sub r1, r1, #2
mov r2, r3
bl \type\()_h264_qpel16_hv_lowpass_l2_neon
vpop {d8-d15}
- add sp, r11, #8
+ mov sp, r11
pop {r4-r5, r9-r11, pc}
endfunc
@@ -1526,7 +1153,9 @@ function ff_\type\()_h264_qpel16_mc22_neon, export=1
push {r4, r9-r11, lr}
lowpass_const r3
mov r11, sp
- bic sp, sp, #15
+A bic sp, sp, #15
+T bic r4, r11, #15
+T mov sp, r4
sub r1, r1, r2, lsl #1
sub r1, r1, #2
mov r3, r2
@@ -1547,7 +1176,7 @@ endfunc
function ff_\type\()_h264_qpel16_mc03_neon, export=1
push {r4, lr}
- add ip, r1, r2
+ add r12, r1, r2
b \type\()_h264_qpel16_mc01
endfunc
@@ -1570,19 +1199,19 @@ function ff_\type\()_h264_qpel16_mc33_neon, export=1
sub r1, r1, #1
b \type\()_h264_qpel16_mc11
endfunc
- .endm
+.endm
h264_qpel16 put
h264_qpel16 avg
@ Biweighted prediction
- .macro biweight_16 macs, macd
+.macro biweight_16 macs, macd
vdup.8 d0, r4
vdup.8 d1, r5
vmov q2, q8
vmov q3, q8
-1: subs ip, ip, #2
+1: subs r3, r3, #2
vld1.8 {d20-d21},[r0,:128], r2
\macd q2, d0, d20
pld [r0]
@@ -1615,14 +1244,14 @@ endfunc
vst1.8 {d24-d25},[r6,:128], r2
bne 1b
pop {r4-r6, pc}
- .endm
+.endm
- .macro biweight_8 macs, macd
+.macro biweight_8 macs, macd
vdup.8 d0, r4
vdup.8 d1, r5
vmov q1, q8
vmov q10, q8
-1: subs ip, ip, #2
+1: subs r3, r3, #2
vld1.8 {d4},[r0,:64], r2
\macd q1, d0, d4
pld [r0]
@@ -1645,14 +1274,14 @@ endfunc
vst1.8 {d4},[r6,:64], r2
bne 1b
pop {r4-r6, pc}
- .endm
+.endm
- .macro biweight_4 macs, macd
+.macro biweight_4 macs, macd
vdup.8 d0, r4
vdup.8 d1, r5
vmov q1, q8
vmov q10, q8
-1: subs ip, ip, #4
+1: subs r3, r3, #4
vld1.32 {d4[0]},[r0,:32], r2
vld1.32 {d4[1]},[r0,:32], r2
\macd q1, d0, d4
@@ -1687,19 +1316,20 @@ endfunc
vst1.32 {d2[0]},[r6,:32], r2
vst1.32 {d2[1]},[r6,:32], r2
pop {r4-r6, pc}
- .endm
+.endm
- .macro biweight_func w
-function biweight_h264_pixels_\w\()_neon
+.macro biweight_func w
+function ff_biweight_h264_pixels_\w\()_neon, export=1
push {r4-r6, lr}
- add r4, sp, #16
+ ldr r12, [sp, #16]
+ add r4, sp, #20
ldm r4, {r4-r6}
lsr lr, r4, #31
add r6, r6, #1
eors lr, lr, r5, lsr #30
orr r6, r6, #1
- vdup.16 q9, r3
- lsl r6, r6, r3
+ vdup.16 q9, r12
+ lsl r6, r6, r12
vmvn q9, q9
vdup.16 q8, r6
mov r6, r0
@@ -1718,36 +1348,17 @@ function biweight_h264_pixels_\w\()_neon
40: rsb r5, r5, #0
biweight_\w vmlsl.u8, vmlal.u8
endfunc
- .endm
-
- .macro biweight_entry w, h, b=1
-function ff_biweight_h264_pixels_\w\()x\h\()_neon, export=1
- mov ip, #\h
-.if \b
- b biweight_h264_pixels_\w\()_neon
-.endif
-endfunc
- .endm
+.endm
- biweight_entry 16, 8
- biweight_entry 16, 16, b=0
biweight_func 16
-
- biweight_entry 8, 16
- biweight_entry 8, 4
- biweight_entry 8, 8, b=0
biweight_func 8
-
- biweight_entry 4, 8
- biweight_entry 4, 2
- biweight_entry 4, 4, b=0
biweight_func 4
@ Weighted prediction
- .macro weight_16 add
- vdup.8 d0, r3
-1: subs ip, ip, #2
+.macro weight_16 add
+ vdup.8 d0, r12
+1: subs r2, r2, #2
vld1.8 {d20-d21},[r0,:128], r1
vmull.u8 q2, d0, d20
pld [r0]
@@ -1772,11 +1383,11 @@ endfunc
vst1.8 {d24-d25},[r4,:128], r1
bne 1b
pop {r4, pc}
- .endm
+.endm
- .macro weight_8 add
- vdup.8 d0, r3
-1: subs ip, ip, #2
+.macro weight_8 add
+ vdup.8 d0, r12
+1: subs r2, r2, #2
vld1.8 {d4},[r0,:64], r1
vmull.u8 q1, d0, d4
pld [r0]
@@ -1793,13 +1404,13 @@ endfunc
vst1.8 {d4},[r4,:64], r1
bne 1b
pop {r4, pc}
- .endm
+.endm
- .macro weight_4 add
- vdup.8 d0, r3
+.macro weight_4 add
+ vdup.8 d0, r12
vmov q1, q8
vmov q10, q8
-1: subs ip, ip, #4
+1: subs r2, r2, #4
vld1.32 {d4[0]},[r0,:32], r1
vld1.32 {d4[1]},[r0,:32], r1
vmull.u8 q1, d0, d4
@@ -1829,53 +1440,35 @@ endfunc
vst1.32 {d2[0]},[r4,:32], r1
vst1.32 {d2[1]},[r4,:32], r1
pop {r4, pc}
- .endm
+.endm
- .macro weight_func w
-function weight_h264_pixels_\w\()_neon
+.macro weight_func w
+function ff_weight_h264_pixels_\w\()_neon, export=1
push {r4, lr}
- ldr r4, [sp, #8]
- cmp r2, #1
- lsl r4, r4, r2
+ ldr r12, [sp, #8]
+ ldr r4, [sp, #12]
+ cmp r3, #1
+ lsl r4, r4, r3
vdup.16 q8, r4
mov r4, r0
ble 20f
- rsb lr, r2, #1
+ rsb lr, r3, #1
vdup.16 q9, lr
- cmp r3, #0
+ cmp r12, #0
blt 10f
weight_\w vhadd.s16
-10: rsb r3, r3, #0
+10: rsb r12, r12, #0
weight_\w vhsub.s16
-20: rsb lr, r2, #0
+20: rsb lr, r3, #0
vdup.16 q9, lr
- cmp r3, #0
+ cmp r12, #0
blt 10f
weight_\w vadd.s16
-10: rsb r3, r3, #0
+10: rsb r12, r12, #0
weight_\w vsub.s16
endfunc
- .endm
-
- .macro weight_entry w, h, b=1
-function ff_weight_h264_pixels_\w\()x\h\()_neon, export=1
- mov ip, #\h
-.if \b
- b weight_h264_pixels_\w\()_neon
-.endif
-endfunc
- .endm
+.endm
- weight_entry 16, 8
- weight_entry 16, 16, b=0
weight_func 16
-
- weight_entry 8, 16
- weight_entry 8, 4
- weight_entry 8, 8, b=0
weight_func 8
-
- weight_entry 4, 8
- weight_entry 4, 2
- weight_entry 4, 4, b=0
weight_func 4
diff --git a/libavcodec/arm/h264idct_neon.S b/libavcodec/arm/h264idct_neon.S
index 3c743e1..edb2ae5 100644
--- a/libavcodec/arm/h264idct_neon.S
+++ b/libavcodec/arm/h264idct_neon.S
@@ -21,7 +21,6 @@
#include "asm.S"
preserve8
- .text
function ff_h264_idct_add_neon, export=1
vld1.64 {d0-d3}, [r1,:128]
@@ -106,10 +105,12 @@ function ff_h264_idct_add16_neon, export=1
blt 2f
ldrsh lr, [r1]
add r0, r0, r4
+ it ne
movne lr, #0
cmp lr, #0
- adrne lr, ff_h264_idct_dc_add_neon
- adreq lr, ff_h264_idct_add_neon
+ ite ne
+ adrne lr, ff_h264_idct_dc_add_neon + CONFIG_THUMB
+ adreq lr, ff_h264_idct_add_neon + CONFIG_THUMB
blx lr
2: subs ip, ip, #1
add r1, r1, #32
@@ -132,8 +133,9 @@ function ff_h264_idct_add16intra_neon, export=1
add r0, r0, r4
cmp r8, #0
ldrsh r8, [r1]
- adrne lr, ff_h264_idct_add_neon
- adreq lr, ff_h264_idct_dc_add_neon
+ iteet ne
+ adrne lr, ff_h264_idct_add_neon + CONFIG_THUMB
+ adreq lr, ff_h264_idct_dc_add_neon + CONFIG_THUMB
cmpeq r8, #0
blxne lr
subs ip, ip, #1
@@ -159,12 +161,14 @@ function ff_h264_idct_add8_neon, export=1
add r1, r3, r12, lsl #5
cmp r8, #0
ldrsh r8, [r1]
- adrne lr, ff_h264_idct_add_neon
- adreq lr, ff_h264_idct_dc_add_neon
+ iteet ne
+ adrne lr, ff_h264_idct_add_neon + CONFIG_THUMB
+ adreq lr, ff_h264_idct_dc_add_neon + CONFIG_THUMB
cmpeq r8, #0
blxne lr
add r12, r12, #1
cmp r12, #4
+ itt eq
moveq r12, #16
moveq r4, r9
cmp r12, #20
@@ -365,10 +369,12 @@ function ff_h264_idct8_add4_neon, export=1
blt 2f
ldrsh lr, [r1]
add r0, r0, r4
+ it ne
movne lr, #0
cmp lr, #0
- adrne lr, ff_h264_idct8_dc_add_neon
- adreq lr, ff_h264_idct8_add_neon
+ ite ne
+ adrne lr, ff_h264_idct8_dc_add_neon + CONFIG_THUMB
+ adreq lr, ff_h264_idct8_add_neon + CONFIG_THUMB
blx lr
2: subs r12, r12, #4
add r1, r1, #128
@@ -376,8 +382,8 @@ function ff_h264_idct8_add4_neon, export=1
pop {r4-r8,pc}
endfunc
- .section .rodata
-scan8: .byte 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8
+const scan8
+ .byte 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8
.byte 6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8
.byte 4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8
.byte 6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8
@@ -389,3 +395,4 @@ scan8: .byte 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8
.byte 6+11*8, 7+11*8, 6+12*8, 7+12*8
.byte 4+13*8, 5+13*8, 4+14*8, 5+14*8
.byte 6+13*8, 7+13*8, 6+14*8, 7+14*8
+endconst
diff --git a/libavcodec/arm/h264pred_init_arm.c b/libavcodec/arm/h264pred_init_arm.c
index e96f339..5fc07bc 100644
--- a/libavcodec/arm/h264pred_init_arm.c
+++ b/libavcodec/arm/h264pred_init_arm.c
@@ -42,7 +42,7 @@ void ff_pred8x8_0lt_dc_neon(uint8_t *src, int stride);
void ff_pred8x8_l00_dc_neon(uint8_t *src, int stride);
void ff_pred8x8_0l0_dc_neon(uint8_t *src, int stride);
-static void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, const int bit_depth)
+static void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc)
{
const int high_depth = bit_depth > 8;
@@ -74,7 +74,7 @@ static void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, const int b
h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_neon;
}
-void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, int bit_depth)
+void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, int bit_depth, const int chroma_format_idc)
{
- if (HAVE_NEON) ff_h264_pred_init_neon(h, codec_id, bit_depth);
+ if (HAVE_NEON) ff_h264_pred_init_neon(h, codec_id, bit_depth, chroma_format_idc);
}
diff --git a/libavcodec/arm/h264pred_neon.S b/libavcodec/arm/h264pred_neon.S
index fe8a369..815b67b 100644
--- a/libavcodec/arm/h264pred_neon.S
+++ b/libavcodec/arm/h264pred_neon.S
@@ -166,12 +166,9 @@ function ff_pred16x16_plane_neon, export=1
bx lr
endfunc
- .section .rodata
- .align 4
-p16weight:
+const p16weight, align=4
.short 1,2,3,4,5,6,7,8
-
- .text
+endconst
function ff_pred8x8_hor_neon, export=1
sub r2, r0, #1
diff --git a/libavcodec/arm/int_neon.S b/libavcodec/arm/int_neon.S
index 5a14991..8bb58af 100644
--- a/libavcodec/arm/int_neon.S
+++ b/libavcodec/arm/int_neon.S
@@ -23,7 +23,6 @@
preserve8
.fpu neon
- .text
function ff_scalarproduct_int16_neon, export=1
vmov.i16 q0, #0
diff --git a/libavcodec/arm/mathops.h b/libavcodec/arm/mathops.h
index b27b18f..3803fcd 100644
--- a/libavcodec/arm/mathops.h
+++ b/libavcodec/arm/mathops.h
@@ -64,11 +64,14 @@ static inline av_const int mid_pred(int a, int b, int c)
__asm__ (
"mov %0, %2 \n\t"
"cmp %1, %2 \n\t"
+ "itt gt \n\t"
"movgt %0, %1 \n\t"
"movgt %1, %2 \n\t"
"cmp %1, %3 \n\t"
+ "it le \n\t"
"movle %1, %3 \n\t"
"cmp %0, %1 \n\t"
+ "it gt \n\t"
"movgt %0, %1 \n\t"
: "=&r"(m), "+r"(a)
: "r"(b), "r"(c)
diff --git a/libavcodec/arm/mdct_neon.S b/libavcodec/arm/mdct_neon.S
index c375f4c..5669075 100644
--- a/libavcodec/arm/mdct_neon.S
+++ b/libavcodec/arm/mdct_neon.S
@@ -23,8 +23,6 @@
preserve8
- .text
-
#define ff_fft_calc_neon X(ff_fft_calc_neon)
function ff_imdct_half_neon, export=1
@@ -191,7 +189,9 @@ function ff_mdct_calc_neon, export=1
vadd.f32 d17, d17, d3 @ in2u+in1d -I
1:
vmul.f32 d7, d0, d21 @ I*s
- ldr r10, [r3, lr, lsr #1]
+A ldr r10, [r3, lr, lsr #1]
+T lsr r10, lr, #1
+T ldr r10, [r3, r10]
vmul.f32 d6, d1, d20 @ -R*c
ldr r6, [r3, #4]!
vmul.f32 d4, d1, d21 @ -R*s
diff --git a/libavcodec/arm/mpegaudiodsp_fixed_armv6.S b/libavcodec/arm/mpegaudiodsp_fixed_armv6.S
index 9ec7314..b517b97 100644
--- a/libavcodec/arm/mpegaudiodsp_fixed_armv6.S
+++ b/libavcodec/arm/mpegaudiodsp_fixed_armv6.S
@@ -75,7 +75,7 @@ function ff_mpadsp_apply_window_fixed_armv6, export=1
sum8 r8, r9, r1, r0, r10, r11, r12, lr
sum8 r8, r9, r1, r2, r10, r11, r12, lr, rsb, 32
round r10, r8, r9
- strh r10, [r3], r4
+ strh_post r10, r3, r4
mov lr, #15
1:
@@ -127,10 +127,10 @@ function ff_mpadsp_apply_window_fixed_armv6, export=1
round r10, r8, r9
adds r8, r8, r4
adc r9, r9, r7
- strh r10, [r3], r12
+ strh_post r10, r3, r12
round r11, r8, r9
subs lr, lr, #1
- strh r11, [r5], -r12
+ strh_dpost r11, r5, r12
bgt 1b
sum8 r8, r9, r1, r0, r10, r11, r12, lr, rsb, 33
diff --git a/libavcodec/arm/mpegvideo_armv5te_s.S b/libavcodec/arm/mpegvideo_armv5te_s.S
index e346160..952c8d7 100644
--- a/libavcodec/arm/mpegvideo_armv5te_s.S
+++ b/libavcodec/arm/mpegvideo_armv5te_s.S
@@ -38,15 +38,21 @@
.macro dequant_t dst, src, mul, add, tmp
rsbs \tmp, ip, \src, asr #16
+ it gt
addgt \tmp, \add, #0
+ it lt
rsblt \tmp, \add, #0
+ it ne
smlatbne \dst, \src, \mul, \tmp
.endm
.macro dequant_b dst, src, mul, add, tmp
rsbs \tmp, ip, \src, lsl #16
+ it gt
addgt \tmp, \add, #0
+ it lt
rsblt \tmp, \add, #0
+ it ne
smlabbne \dst, \src, \mul, \tmp
.endm
@@ -80,21 +86,27 @@ function ff_dct_unquantize_h263_armv5te, export=1
strh lr, [r0], #2
subs r3, r3, #8
+ it gt
ldrdgt r4, [r0, #0] /* load data early to avoid load/use pipeline stall */
bgt 1b
adds r3, r3, #2
+ it le
pople {r4-r9,pc}
2:
ldrsh r9, [r0, #0]
ldrsh lr, [r0, #2]
mov r8, r2
cmp r9, #0
+ it lt
rsblt r8, r2, #0
+ it ne
smlabbne r9, r9, r1, r8
mov r8, r2
cmp lr, #0
+ it lt
rsblt r8, r2, #0
+ it ne
smlabbne lr, lr, r1, r8
strh r9, [r0], #2
strh lr, [r0], #2
diff --git a/libavcodec/arm/mpegvideo_iwmmxt.c b/libavcodec/arm/mpegvideo_iwmmxt.c
index 4d5edd8..6edc4c2 100644
--- a/libavcodec/arm/mpegvideo_iwmmxt.c
+++ b/libavcodec/arm/mpegvideo_iwmmxt.c
@@ -93,29 +93,9 @@ static void dct_unquantize_h263_intra_iwmmxt(MpegEncContext *s,
block_orig[0] = level;
}
-#if 0
-static void dct_unquantize_h263_inter_iwmmxt(MpegEncContext *s,
- DCTELEM *block, int n, int qscale)
-{
- int nCoeffs;
-
- assert(s->block_last_index[n]>=0);
-
- if(s->ac_pred)
- nCoeffs=63;
- else
- nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
-
- ippiQuantInvInter_Compact_H263_16s_I(block, nCoeffs+1, qscale);
-}
-#endif
-
void MPV_common_init_iwmmxt(MpegEncContext *s)
{
if (!(mm_flags & AV_CPU_FLAG_IWMMXT)) return;
s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_iwmmxt;
-#if 0
- s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_iwmmxt;
-#endif
}
diff --git a/libavcodec/arm/mpegvideo_neon.S b/libavcodec/arm/mpegvideo_neon.S
index 365dcf6..206a71a 100644
--- a/libavcodec/arm/mpegvideo_neon.S
+++ b/libavcodec/arm/mpegvideo_neon.S
@@ -57,6 +57,7 @@ function ff_dct_unquantize_h263_neon, export=1
subs r3, r3, #16
vst1.16 {q0}, [r1,:128]!
vst1.16 {q8}, [r1,:128]!
+ it le
bxle lr
cmp r3, #8
bgt 1b
@@ -78,6 +79,7 @@ function ff_dct_unquantize_h263_intra_neon, export=1
ldr r6, [r0, #AC_PRED]
add lr, r0, #INTER_SCANTAB_RASTER_END
cmp r6, #0
+ it ne
movne r12, #63
bne 1f
ldr r12, [r12, r2, lsl #2]
@@ -86,9 +88,11 @@ function ff_dct_unquantize_h263_intra_neon, export=1
ldrsh r4, [r1]
cmp r5, #0
mov r5, r1
+ it ne
movne r2, #0
bne 2f
cmp r2, #4
+ it ge
addge r0, r0, #4
sub r2, r3, #1
ldr r6, [r0, #Y_DC_SCALE]
diff --git a/libavcodec/arm/neon.S b/libavcodec/arm/neon.S
new file mode 100644
index 0000000..716a607
--- /dev/null
+++ b/libavcodec/arm/neon.S
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+.macro transpose_8x8 r0, r1, r2, r3, r4, r5, r6, r7
+ vtrn.32 \r0, \r4
+ vtrn.32 \r1, \r5
+ vtrn.32 \r2, \r6
+ vtrn.32 \r3, \r7
+ vtrn.16 \r0, \r2
+ vtrn.16 \r1, \r3
+ vtrn.16 \r4, \r6
+ vtrn.16 \r5, \r7
+ vtrn.8 \r0, \r1
+ vtrn.8 \r2, \r3
+ vtrn.8 \r4, \r5
+ vtrn.8 \r6, \r7
+.endm
+
+.macro transpose_4x4 r0, r1, r2, r3
+ vtrn.16 \r0, \r2
+ vtrn.16 \r1, \r3
+ vtrn.8 \r0, \r1
+ vtrn.8 \r2, \r3
+.endm
+
+.macro swap4 r0, r1, r2, r3, r4, r5, r6, r7
+ vswp \r0, \r4
+ vswp \r1, \r5
+ vswp \r2, \r6
+ vswp \r3, \r7
+.endm
+
+.macro transpose16_4x4 r0, r1, r2, r3, r4, r5, r6, r7
+ vtrn.32 \r0, \r2
+ vtrn.32 \r1, \r3
+ vtrn.32 \r4, \r6
+ vtrn.32 \r5, \r7
+ vtrn.16 \r0, \r1
+ vtrn.16 \r2, \r3
+ vtrn.16 \r4, \r5
+ vtrn.16 \r6, \r7
+.endm
diff --git a/libavcodec/arm/rdft_neon.S b/libavcodec/arm/rdft_neon.S
index 8aafdc9..fba275e 100644
--- a/libavcodec/arm/rdft_neon.S
+++ b/libavcodec/arm/rdft_neon.S
@@ -137,6 +137,7 @@ function ff_rdft_calc_neon, export=1
vst1.32 {d22}, [r5,:64]
cmp r6, #0
+ it eq
popeq {r4-r8,pc}
vmul.f32 d22, d22, d18
diff --git a/libavcodec/arm/rv34dsp_init_neon.c b/libavcodec/arm/rv34dsp_init_neon.c
new file mode 100644
index 0000000..acf2a7d
--- /dev/null
+++ b/libavcodec/arm/rv34dsp_init_neon.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011 Janne Grunau <janne-libav at jannau.net>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavcodec/avcodec.h"
+#include "libavcodec/rv34dsp.h"
+
+void ff_rv34_inv_transform_neon(DCTELEM *block);
+void ff_rv34_inv_transform_noround_neon(DCTELEM *block);
+void ff_rv34_dequant4x4_neon(DCTELEM *block, int Qdc, int Q);
+
+void ff_rv34dsp_init_neon(RV34DSPContext *c, DSPContext* dsp)
+{
+ c->rv34_inv_transform_tab[0] = ff_rv34_inv_transform_neon;
+ c->rv34_inv_transform_tab[1] = ff_rv34_inv_transform_noround_neon;
+
+ c->rv34_dequant4x4 = ff_rv34_dequant4x4_neon;
+}
diff --git a/libavcodec/arm/rv34dsp_neon.S b/libavcodec/arm/rv34dsp_neon.S
new file mode 100644
index 0000000..423b537
--- /dev/null
+++ b/libavcodec/arm/rv34dsp_neon.S
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2011 Janne Grunau <janne-libav at jannau.net>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "asm.S"
+
+.macro rv34_inv_transform
+ mov r1, #16
+ vld1.16 {d28}, [r0,:64], r1 @ block[i+8*0]
+ vld1.16 {d29}, [r0,:64], r1 @ block[i+8*1]
+ vld1.16 {d30}, [r0,:64], r1 @ block[i+8*2]
+ vld1.16 {d31}, [r0,:64], r1 @ block[i+8*3]
+ vmov.s16 d0, #13
+ vshll.s16 q12, d29, #3
+ vshll.s16 q13, d29, #4
+ vshll.s16 q9, d31, #3
+ vshll.s16 q1, d31, #4
+ vmull.s16 q10, d28, d0
+ vmlal.s16 q10, d30, d0
+ vmull.s16 q11, d28, d0
+ vmlsl.s16 q11, d30, d0
+ vsubw.s16 q12, q12, d29 @ z2 = block[i+8*1]*7
+ vaddw.s16 q13, q13, d29 @ z3 = block[i+8*1]*17
+ vsubw.s16 q9, q9, d31
+ vaddw.s16 q1, q1, d31
+ vadd.s32 q13, q13, q9 @ z3 = 17*block[i+8*1] + 7*block[i+8*3]
+ vsub.s32 q12, q12, q1 @ z2 = 7*block[i+8*1] - 17*block[i+8*3]
+ vadd.s32 q1, q10, q13 @ z0 + z3
+ vadd.s32 q2, q11, q12 @ z1 + z2
+ vsub.s32 q8, q10, q13 @ z0 - z3
+ vsub.s32 q3, q11, q12 @ z1 - z2
+ vtrn.32 q1, q2
+ vtrn.32 q3, q8
+ vswp d3, d6
+ vswp d5, d16
+ vmov.s32 d0, #13
+ vadd.s32 q10, q1, q3
+ vsub.s32 q11, q1, q3
+ vshl.s32 q12, q2, #3
+ vshl.s32 q9, q2, #4
+ vmul.s32 q13, q11, d0[0]
+ vshl.s32 q11, q8, #4
+ vadd.s32 q9, q9, q2
+ vshl.s32 q15, q8, #3
+ vsub.s32 q12, q12, q2
+ vadd.s32 q11, q11, q8
+ vmul.s32 q14, q10, d0[0]
+ vsub.s32 q8, q15, q8
+ vsub.s32 q12, q12, q11
+ vadd.s32 q9, q9, q8
+ vadd.s32 q2, q13, q12 @ z1 + z2
+ vadd.s32 q1, q14, q9 @ z0 + z3
+ vsub.s32 q3, q13, q12 @ z1 - z2
+ vsub.s32 q15, q14, q9 @ z0 - z3
+.endm
+
+/* void ff_rv34_inv_transform_neon(DCTELEM *block); */
+function ff_rv34_inv_transform_neon, export=1
+ mov r2, r0
+ rv34_inv_transform
+ vrshrn.s32 d1, q2, #10 @ (z1 + z2) >> 10
+ vrshrn.s32 d0, q1, #10 @ (z0 + z3) >> 10
+ vrshrn.s32 d2, q3, #10 @ (z1 - z2) >> 10
+ vrshrn.s32 d3, q15, #10 @ (z0 - z3) >> 10
+ vst4.16 {d0[0], d1[0], d2[0], d3[0]}, [r2,:64], r1
+ vst4.16 {d0[1], d1[1], d2[1], d3[1]}, [r2,:64], r1
+ vst4.16 {d0[2], d1[2], d2[2], d3[2]}, [r2,:64], r1
+ vst4.16 {d0[3], d1[3], d2[3], d3[3]}, [r2,:64], r1
+ bx lr
+endfunc
+
+/* void rv34_inv_transform_noround_neon(DCTELEM *block); */
+function ff_rv34_inv_transform_noround_neon, export=1
+ mov r2, r0
+ rv34_inv_transform
+ vshl.s32 q11, q2, #1
+ vshl.s32 q10, q1, #1
+ vshl.s32 q12, q3, #1
+ vshl.s32 q13, q15, #1
+ vadd.s32 q11, q11, q2
+ vadd.s32 q10, q10, q1
+ vadd.s32 q12, q12, q3
+ vadd.s32 q13, q13, q15
+ vshrn.s32 d0, q10, #11 @ (z0 + z3)*3 >> 11
+ vshrn.s32 d1, q11, #11 @ (z1 + z2)*3 >> 11
+ vshrn.s32 d2, q12, #11 @ (z1 - z2)*3 >> 11
+ vshrn.s32 d3, q13, #11 @ (z0 - z3)*3 >> 11
+ vst4.16 {d0[0], d1[0], d2[0], d3[0]}, [r2,:64], r1
+ vst4.16 {d0[1], d1[1], d2[1], d3[1]}, [r2,:64], r1
+ vst4.16 {d0[2], d1[2], d2[2], d3[2]}, [r2,:64], r1
+ vst4.16 {d0[3], d1[3], d2[3], d3[3]}, [r2,:64], r1
+ bx lr
+endfunc
+
+function ff_rv34_dequant4x4_neon, export=1
+ mov r3, r0
+ mov r12, #16
+ vdup.16 q0, r2
+ vmov.16 d0[0], r1
+ vld1.16 {d2}, [r0,:64], r12
+ vld1.16 {d4}, [r0,:64], r12
+ vld1.16 {d6}, [r0,:64], r12
+ vld1.16 {d16}, [r0,:64], r12
+ vmull.s16 q1, d2, d0
+ vmull.s16 q2, d4, d1
+ vmull.s16 q3, d6, d1
+ vmull.s16 q8, d16, d1
+ vqrshrn.s32 d2, q1, #4
+ vqrshrn.s32 d4, q2, #4
+ vqrshrn.s32 d6, q3, #4
+ vqrshrn.s32 d16, q8, #4
+ vst1.16 {d2}, [r3,:64], r12
+ vst1.16 {d4}, [r3,:64], r12
+ vst1.16 {d6}, [r3,:64], r12
+ vst1.16 {d16}, [r3,:64], r12
+ bx lr
+endfunc
diff --git a/libavcodec/arm/rv40dsp_init_neon.c b/libavcodec/arm/rv40dsp_init_neon.c
new file mode 100644
index 0000000..898b841
--- /dev/null
+++ b/libavcodec/arm/rv40dsp_init_neon.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2011 Janne Grunau <janne-libav at jannau.net>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavcodec/avcodec.h"
+#include "libavcodec/rv34dsp.h"
+
+#define DECL_QPEL3(type, w, pos) \
+ void ff_##type##_rv40_qpel##w##_mc##pos##_neon(uint8_t *dst, uint8_t *src,\
+ int stride)
+#define DECL_QPEL2(w, pos) \
+ DECL_QPEL3(put, w, pos); \
+ DECL_QPEL3(avg, w, pos)
+
+#define DECL_QPEL_XY(x, y) \
+ DECL_QPEL2(16, x ## y); \
+ DECL_QPEL2(8, x ## y)
+
+#define DECL_QPEL_Y(y) \
+ DECL_QPEL_XY(0, y); \
+ DECL_QPEL_XY(1, y); \
+ DECL_QPEL_XY(2, y); \
+ DECL_QPEL_XY(3, y); \
+
+DECL_QPEL_Y(0);
+DECL_QPEL_Y(1);
+DECL_QPEL_Y(2);
+DECL_QPEL_Y(3);
+
+void ff_put_rv40_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_put_rv40_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
+
+void ff_avg_rv40_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_avg_rv40_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
+
+void ff_rv40_weight_func_16_neon(uint8_t *, uint8_t *, uint8_t *, int, int, int);
+void ff_rv40_weight_func_8_neon(uint8_t *, uint8_t *, uint8_t *, int, int, int);
+
+int ff_rv40_h_loop_filter_strength_neon(uint8_t *src, int stride,
+ int beta, int beta2, int edge,
+ int *p1, int *q1);
+int ff_rv40_v_loop_filter_strength_neon(uint8_t *src, int stride,
+ int beta, int beta2, int edge,
+ int *p1, int *q1);
+
+void ff_rv40_h_weak_loop_filter_neon(uint8_t *src, int stride, int filter_p1,
+ int filter_q1, int alpha, int beta,
+ int lim_p0q0, int lim_q1, int lim_p1);
+void ff_rv40_v_weak_loop_filter_neon(uint8_t *src, int stride, int filter_p1,
+ int filter_q1, int alpha, int beta,
+ int lim_p0q0, int lim_q1, int lim_p1);
+
+void ff_rv40dsp_init_neon(RV34DSPContext *c, DSPContext* dsp)
+{
+ c->put_pixels_tab[0][ 1] = ff_put_rv40_qpel16_mc10_neon;
+ c->put_pixels_tab[0][ 3] = ff_put_rv40_qpel16_mc30_neon;
+ c->put_pixels_tab[0][ 4] = ff_put_rv40_qpel16_mc01_neon;
+ c->put_pixels_tab[0][ 5] = ff_put_rv40_qpel16_mc11_neon;
+ c->put_pixels_tab[0][ 6] = ff_put_rv40_qpel16_mc21_neon;
+ c->put_pixels_tab[0][ 7] = ff_put_rv40_qpel16_mc31_neon;
+ c->put_pixels_tab[0][ 9] = ff_put_rv40_qpel16_mc12_neon;
+ c->put_pixels_tab[0][10] = ff_put_rv40_qpel16_mc22_neon;
+ c->put_pixels_tab[0][11] = ff_put_rv40_qpel16_mc32_neon;
+ c->put_pixels_tab[0][12] = ff_put_rv40_qpel16_mc03_neon;
+ c->put_pixels_tab[0][13] = ff_put_rv40_qpel16_mc13_neon;
+ c->put_pixels_tab[0][14] = ff_put_rv40_qpel16_mc23_neon;
+ c->put_pixels_tab[0][15] = ff_put_rv40_qpel16_mc33_neon;
+ c->avg_pixels_tab[0][ 1] = ff_avg_rv40_qpel16_mc10_neon;
+ c->avg_pixels_tab[0][ 3] = ff_avg_rv40_qpel16_mc30_neon;
+ c->avg_pixels_tab[0][ 4] = ff_avg_rv40_qpel16_mc01_neon;
+ c->avg_pixels_tab[0][ 5] = ff_avg_rv40_qpel16_mc11_neon;
+ c->avg_pixels_tab[0][ 6] = ff_avg_rv40_qpel16_mc21_neon;
+ c->avg_pixels_tab[0][ 7] = ff_avg_rv40_qpel16_mc31_neon;
+ c->avg_pixels_tab[0][ 9] = ff_avg_rv40_qpel16_mc12_neon;
+ c->avg_pixels_tab[0][10] = ff_avg_rv40_qpel16_mc22_neon;
+ c->avg_pixels_tab[0][11] = ff_avg_rv40_qpel16_mc32_neon;
+ c->avg_pixels_tab[0][12] = ff_avg_rv40_qpel16_mc03_neon;
+ c->avg_pixels_tab[0][13] = ff_avg_rv40_qpel16_mc13_neon;
+ c->avg_pixels_tab[0][14] = ff_avg_rv40_qpel16_mc23_neon;
+ c->avg_pixels_tab[0][15] = ff_avg_rv40_qpel16_mc33_neon;
+ c->put_pixels_tab[1][ 1] = ff_put_rv40_qpel8_mc10_neon;
+ c->put_pixels_tab[1][ 3] = ff_put_rv40_qpel8_mc30_neon;
+ c->put_pixels_tab[1][ 4] = ff_put_rv40_qpel8_mc01_neon;
+ c->put_pixels_tab[1][ 5] = ff_put_rv40_qpel8_mc11_neon;
+ c->put_pixels_tab[1][ 6] = ff_put_rv40_qpel8_mc21_neon;
+ c->put_pixels_tab[1][ 7] = ff_put_rv40_qpel8_mc31_neon;
+ c->put_pixels_tab[1][ 9] = ff_put_rv40_qpel8_mc12_neon;
+ c->put_pixels_tab[1][10] = ff_put_rv40_qpel8_mc22_neon;
+ c->put_pixels_tab[1][11] = ff_put_rv40_qpel8_mc32_neon;
+ c->put_pixels_tab[1][12] = ff_put_rv40_qpel8_mc03_neon;
+ c->put_pixels_tab[1][13] = ff_put_rv40_qpel8_mc13_neon;
+ c->put_pixels_tab[1][14] = ff_put_rv40_qpel8_mc23_neon;
+ c->put_pixels_tab[1][15] = ff_put_rv40_qpel8_mc33_neon;
+ c->avg_pixels_tab[1][ 1] = ff_avg_rv40_qpel8_mc10_neon;
+ c->avg_pixels_tab[1][ 3] = ff_avg_rv40_qpel8_mc30_neon;
+ c->avg_pixels_tab[1][ 4] = ff_avg_rv40_qpel8_mc01_neon;
+ c->avg_pixels_tab[1][ 5] = ff_avg_rv40_qpel8_mc11_neon;
+ c->avg_pixels_tab[1][ 6] = ff_avg_rv40_qpel8_mc21_neon;
+ c->avg_pixels_tab[1][ 7] = ff_avg_rv40_qpel8_mc31_neon;
+ c->avg_pixels_tab[1][ 9] = ff_avg_rv40_qpel8_mc12_neon;
+ c->avg_pixels_tab[1][10] = ff_avg_rv40_qpel8_mc22_neon;
+ c->avg_pixels_tab[1][11] = ff_avg_rv40_qpel8_mc32_neon;
+ c->avg_pixels_tab[1][12] = ff_avg_rv40_qpel8_mc03_neon;
+ c->avg_pixels_tab[1][13] = ff_avg_rv40_qpel8_mc13_neon;
+ c->avg_pixels_tab[1][14] = ff_avg_rv40_qpel8_mc23_neon;
+ c->avg_pixels_tab[1][15] = ff_avg_rv40_qpel8_mc33_neon;
+
+ c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_neon;
+ c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_neon;
+ c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_neon;
+ c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_neon;
+
+ c->rv40_weight_pixels_tab[0] = ff_rv40_weight_func_16_neon;
+ c->rv40_weight_pixels_tab[1] = ff_rv40_weight_func_8_neon;
+
+ c->rv40_loop_filter_strength[0] = ff_rv40_h_loop_filter_strength_neon;
+ c->rv40_loop_filter_strength[1] = ff_rv40_v_loop_filter_strength_neon;
+ c->rv40_weak_loop_filter[0] = ff_rv40_h_weak_loop_filter_neon;
+ c->rv40_weak_loop_filter[1] = ff_rv40_v_weak_loop_filter_neon;
+}
diff --git a/libavcodec/arm/rv40dsp_neon.S b/libavcodec/arm/rv40dsp_neon.S
new file mode 100644
index 0000000..f68f382
--- /dev/null
+++ b/libavcodec/arm/rv40dsp_neon.S
@@ -0,0 +1,920 @@
+/*
+ * Copyright (c) 2011 Janne Grunau <janne-libav at jannau.net>
+ * Copyright (c) 2011 Mans Rullgard <mans at mansr.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "asm.S"
+#include "neon.S"
+
+.macro qpel_lowpass r0, r1, rc1, rc2, shift
+ vext.8 d25, \r0, \r1, #1 @ src[-1]
+ vext.8 d26, \r0, \r1, #4 @ src[ 2]
+ vext.8 d24, \r0, \r1, #5 @ src[ 3]
+ vaddl.u8 q9, d25, d26
+ vaddl.u8 q8, \r0, d24
+ vext.8 d27, \r0, \r1, #2 @ src[ 0]
+ vshl.s16 q12, q9, #2
+ vsub.s16 q8, q8, q9
+ vext.8 d28, \r0, \r1, #3 @ src[ 1]
+ vsub.s16 q8, q8, q12
+ vmlal.u8 q8, d27, \rc1
+ vmlal.u8 q8, d28, \rc2
+ vqrshrun.s16 \r0, q8, #\shift
+.endm
+
+.macro qpel_lowpass_x2 r0, r1, r2, r3, rc1, rc2, shift
+ vext.8 d25, \r0, \r1, #1 @ src[-1]
+ vext.8 d26, \r0, \r1, #4 @ src[ 2]
+ vext.8 d24, \r0, \r1, #5 @ src[ 3]
+ vaddl.u8 q9, d25, d26
+ vaddl.u8 q8, \r0, d24
+ vext.8 d29, \r0, \r1, #2 @ src[ 0]
+ vext.8 d28, \r0, \r1, #3 @ src[ 1]
+ vshl.s16 q10, q9, #2
+ vext.8 \r1, \r2, \r3, #1 @ src[-1]
+ vsub.s16 q8, q8, q9
+ vext.8 d22, \r2, \r3, #4 @ src[ 2]
+ vext.8 \r0, \r2, \r3, #5 @ src[ 3]
+ vaddl.u8 q13, \r1, d22
+ vaddl.u8 q12, \r2, \r0
+ vsub.s16 q8, q8, q10
+ vshl.s16 q9, q13, #2
+ vsub.s16 q12, q12, q13
+ vmlal.u8 q8, d29, \rc1
+ vmlal.u8 q8, d28, \rc2
+ vsub.s16 q12, q12, q9
+ vext.8 d26, \r2, \r3, #2 @ src[ 0]
+ vext.8 d27, \r2, \r3, #3 @ src[ 1]
+ vmlal.u8 q12, d26, \rc1
+ vmlal.u8 q12, d27, \rc2
+ vqrshrun.s16 \r0, q8, #\shift
+ vqrshrun.s16 \r2, q12, #\shift
+.endm
+
+.macro rv40_qpel8_h shift
+function put_rv40_qpel8_h_lp_packed_s\shift\()_neon
+1:
+ vld1.8 {q2}, [r1], r2
+ vld1.8 {q3}, [r1], r2
+ qpel_lowpass_x2 d4, d5, d6, d7, d0, d1, \shift
+ vst1.8 {d4}, [r12,:64]!
+ vst1.8 {d6}, [r12,:64]!
+ subs r3, r3, #2
+ bgt 1b
+ vld1.8 {q2}, [r1]
+ qpel_lowpass d4, d5, d0, d1, \shift
+ vst1.8 {d4}, [r12,:64]!
+ bx lr
+endfunc
+.endm
+
+.macro rv40_qpel8_v shift, type
+function \type\()_rv40_qpel8_v_lp_packed_s\shift\()_neon
+ vld1.64 {d2}, [r1,:64]!
+ vld1.64 {d3}, [r1,:64]!
+ vld1.64 {d4}, [r1,:64]!
+ vld1.64 {d5}, [r1,:64]!
+ vld1.64 {d6}, [r1,:64]!
+ vld1.64 {d7}, [r1,:64]!
+ vld1.64 {d8}, [r1,:64]!
+ vld1.64 {d9}, [r1,:64]!
+ vld1.64 {d10}, [r1,:64]!
+ vld1.64 {d11}, [r1,:64]!
+ vld1.64 {d12}, [r1,:64]!
+ vld1.64 {d13}, [r1,:64]!
+ vld1.64 {d14}, [r1,:64]!
+ transpose_8x8 d2, d3, d4, d5, d6, d7, d8, d9
+ transpose_8x8 d10, d11, d12, d13, d14, d15, d30, d31
+ qpel_lowpass_x2 d2, d10, d3, d11, d0, d1, \shift
+ qpel_lowpass_x2 d4, d12, d5, d13, d0, d1, \shift
+ qpel_lowpass_x2 d6, d14, d7, d15, d0, d1, \shift
+ qpel_lowpass_x2 d8, d30, d9, d31, d0, d1, \shift
+ transpose_8x8 d2, d3, d4, d5, d6, d7, d8, d9
+ .ifc \type,avg
+ vld1.64 d12, [r0,:64], r2
+ vld1.64 d13, [r0,:64], r2
+ vld1.64 d14, [r0,:64], r2
+ vld1.64 d15, [r0,:64], r2
+ vld1.64 d16, [r0,:64], r2
+ vld1.64 d17, [r0,:64], r2
+ vld1.64 d18, [r0,:64], r2
+ vld1.64 d19, [r0,:64], r2
+ sub r0, r0, r2, lsl #3
+ vrhadd.u8 q1, q1, q6
+ vrhadd.u8 q2, q2, q7
+ vrhadd.u8 q3, q3, q8
+ vrhadd.u8 q4, q4, q9
+ .endif
+ vst1.64 d2, [r0,:64], r2
+ vst1.64 d3, [r0,:64], r2
+ vst1.64 d4, [r0,:64], r2
+ vst1.64 d5, [r0,:64], r2
+ vst1.64 d6, [r0,:64], r2
+ vst1.64 d7, [r0,:64], r2
+ vst1.64 d8, [r0,:64], r2
+ vst1.64 d9, [r0,:64], r2
+ bx lr
+endfunc
+.endm
+
+ rv40_qpel8_h 5
+ rv40_qpel8_h 6
+
+.macro rv40_qpel type
+function \type\()_rv40_qpel8_h_lowpass_neon
+ .ifc \type,avg
+ mov r12, r0
+ .endif
+1:
+ vld1.8 {q2}, [r1], r2
+ vld1.8 {q3}, [r1], r2
+ qpel_lowpass_x2 d4, d5, d6, d7, d0, d1, 6
+ .ifc \type,avg
+ vld1.8 {d3}, [r12,:64], r2
+ vld1.8 {d16}, [r12,:64], r2
+ vrhadd.u8 d4, d4, d3
+ vrhadd.u8 d6, d6, d16
+ .endif
+ vst1.8 {d4}, [r0,:64], r2
+ vst1.8 {d6}, [r0,:64], r2
+ subs r3, r3, #2
+ bgt 1b
+ bx lr
+endfunc
+
+function \type\()_rv40_qpel8_v_lowpass_neon
+ vld1.64 {d2}, [r1], r2
+ vld1.64 {d3}, [r1], r2
+ vld1.64 {d4}, [r1], r2
+ vld1.64 {d5}, [r1], r2
+ vld1.64 {d6}, [r1], r2
+ vld1.64 {d7}, [r1], r2
+ vld1.64 {d8}, [r1], r2
+ vld1.64 {d9}, [r1], r2
+ vld1.64 {d10}, [r1], r2
+ vld1.64 {d11}, [r1], r2
+ vld1.64 {d12}, [r1], r2
+ vld1.64 {d13}, [r1], r2
+ vld1.64 {d14}, [r1]
+ transpose_8x8 d2, d3, d4, d5, d6, d7, d8, d9
+ transpose_8x8 d10, d11, d12, d13, d14, d15, d30, d31
+ qpel_lowpass_x2 d2, d10, d3, d11, d0, d1, 6
+ qpel_lowpass_x2 d4, d12, d5, d13, d0, d1, 6
+ qpel_lowpass_x2 d6, d14, d7, d15, d0, d1, 6
+ qpel_lowpass_x2 d8, d30, d9, d31, d0, d1, 6
+ transpose_8x8 d2, d3, d4, d5, d6, d7, d8, d9
+ .ifc \type,avg
+ vld1.64 d12, [r0,:64], r2
+ vld1.64 d13, [r0,:64], r2
+ vld1.64 d14, [r0,:64], r2
+ vld1.64 d15, [r0,:64], r2
+ vld1.64 d16, [r0,:64], r2
+ vld1.64 d17, [r0,:64], r2
+ vld1.64 d18, [r0,:64], r2
+ vld1.64 d19, [r0,:64], r2
+ sub r0, r0, r2, lsl #3
+ vrhadd.u8 q1, q1, q6
+ vrhadd.u8 q2, q2, q7
+ vrhadd.u8 q3, q3, q8
+ vrhadd.u8 q4, q4, q9
+ .endif
+ vst1.64 d2, [r0,:64], r2
+ vst1.64 d3, [r0,:64], r2
+ vst1.64 d4, [r0,:64], r2
+ vst1.64 d5, [r0,:64], r2
+ vst1.64 d6, [r0,:64], r2
+ vst1.64 d7, [r0,:64], r2
+ vst1.64 d8, [r0,:64], r2
+ vst1.64 d9, [r0,:64], r2
+ bx lr
+endfunc
+
+ rv40_qpel8_v 5, \type
+ rv40_qpel8_v 6, \type
+
+function ff_\type\()_rv40_qpel8_mc10_neon, export=1
+ sub r1, r1, #2
+ mov r3, #8
+ vmov.i8 d0, #52
+ vmov.i8 d1, #20
+ b \type\()_rv40_qpel8_h_lowpass_neon
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc30_neon, export=1
+ sub r1, r1, #2
+ mov r3, #8
+ vmov.i8 d0, #20
+ vmov.i8 d1, #52
+ b \type\()_rv40_qpel8_h_lowpass_neon
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc01_neon, export=1
+ push {r4, lr}
+ vpush {d8-d15}
+ sub r1, r1, r2, lsl #1
+ vmov.i8 d0, #52
+ vmov.i8 d1, #20
+ bl \type\()_rv40_qpel8_v_lowpass_neon
+ vpop {d8-d15}
+ pop {r4, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc11_neon, export=1
+ push {r4, lr}
+ vpush {d8-d15}
+ sub sp, sp, #14*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ mov r3, #12
+ vmov.i8 d0, #52
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ add r1, sp, #7
+ bic r1, r1, #7
+ bl \type\()_rv40_qpel8_v_lp_packed_s6_neon
+ add sp, sp, #14*8
+ vpop {d8-d15}
+ pop {r4, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc21_neon, export=1
+ push {r4, lr}
+ vpush {d8-d15}
+ sub sp, sp, #14*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ mov r3, #12
+ vmov.i8 d0, #20
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s5_neon
+ add r1, sp, #7
+ bic r1, r1, #7
+ vmov.i8 d0, #52
+ bl \type\()_rv40_qpel8_v_lp_packed_s6_neon
+ add sp, sp, #14*8
+ vpop {d8-d15}
+ pop {r4, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc31_neon, export=1
+ push {r4, lr}
+ vpush {d8-d15}
+ sub sp, sp, #14*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ mov r3, #12
+ vmov.i8 d0, #20
+ vmov.i8 d1, #52
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ add r1, sp, #7
+ bic r1, r1, #7
+ vswp d0, d1
+ bl \type\()_rv40_qpel8_v_lp_packed_s6_neon
+ add sp, sp, #14*8
+ vpop {d8-d15}
+ pop {r4, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc12_neon, export=1
+ push {r4, lr}
+ vpush {d8-d15}
+ sub sp, sp, #14*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ mov r3, #12
+ vmov.i8 d0, #52
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ add r1, sp, #7
+ bic r1, r1, #7
+ vmov.i8 d0, #20
+ bl \type\()_rv40_qpel8_v_lp_packed_s5_neon
+ add sp, sp, #14*8
+ vpop {d8-d15}
+ pop {r4, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc22_neon, export=1
+ push {r4, lr}
+ vpush {d8-d15}
+ sub sp, sp, #14*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ mov r3, #12
+ vmov.i8 d0, #20
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s5_neon
+ add r1, sp, #7
+ bic r1, r1, #7
+ bl \type\()_rv40_qpel8_v_lp_packed_s5_neon
+ add sp, sp, #14*8
+ vpop {d8-d15}
+ pop {r4, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc32_neon, export=1
+ push {r4, lr}
+ vpush {d8-d15}
+ sub sp, sp, #14*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ mov r3, #12
+ vmov.i8 d0, #20
+ vmov.i8 d1, #52
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ add r1, sp, #7
+ bic r1, r1, #7
+ vmov.i8 d1, #20
+ bl \type\()_rv40_qpel8_v_lp_packed_s5_neon
+ add sp, sp, #14*8
+ vpop {d8-d15}
+ pop {r4, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc03_neon, export=1
+ push {r4, lr}
+ vpush {d8-d15}
+ sub r1, r1, r2, lsl #1
+ vmov.i8 d0, #20
+ vmov.i8 d1, #52
+ bl \type\()_rv40_qpel8_v_lowpass_neon
+ vpop {d8-d15}
+ pop {r4, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc33_neon, export=1
+ mov r3, #8
+ b X(ff_\type\()_pixels8_xy2_neon)
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc13_neon, export=1
+ push {r4, lr}
+ vpush {d8-d15}
+ sub sp, sp, #14*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ mov r3, #12
+ vmov.i8 d0, #52
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ add r1, sp, #7
+ bic r1, r1, #7
+ vswp d0, d1
+ bl \type\()_rv40_qpel8_v_lp_packed_s6_neon
+ add sp, sp, #14*8
+ vpop {d8-d15}
+ pop {r4, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel8_mc23_neon, export=1
+ push {r4, lr}
+ vpush {d8-d15}
+ sub sp, sp, #14*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ mov r3, #12
+ vmov.i8 d0, #20
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s5_neon
+ add r1, sp, #7
+ bic r1, r1, #7
+ vmov.i8 d1, #52
+ bl \type\()_rv40_qpel8_v_lp_packed_s6_neon
+ add sp, sp, #14*8
+ vpop {d8-d15}
+ pop {r4, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc10_neon, export=1
+ vmov.i8 d0, #52
+ vmov.i8 d1, #20
+.L\type\()_rv40_qpel16_h:
+ push {r1, lr}
+ sub r1, r1, #2
+ mov r3, #16
+ bl \type\()_rv40_qpel8_h_lowpass_neon
+ pop {r1, lr}
+ sub r0, r0, r2, lsl #4
+ add r0, r0, #8
+ add r1, r1, #6
+ mov r3, #16
+ b \type\()_rv40_qpel8_h_lowpass_neon
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc30_neon, export=1
+ vmov.i8 d0, #20
+ vmov.i8 d1, #52
+ b .L\type\()_rv40_qpel16_h
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc01_neon, export=1
+ vmov.i8 d0, #52
+ vmov.i8 d1, #20
+.L\type\()_rv40_qpel16_v:
+ sub r1, r1, r2, lsl #1
+ push {r1, lr}
+ vpush {d8-d15}
+ bl \type\()_rv40_qpel8_v_lowpass_neon
+ sub r1, r1, r2, lsl #2
+ bl \type\()_rv40_qpel8_v_lowpass_neon
+ ldr r1, [sp, #64]
+ sub r0, r0, r2, lsl #4
+ add r0, r0, #8
+ add r1, r1, #8
+ bl \type\()_rv40_qpel8_v_lowpass_neon
+ sub r1, r1, r2, lsl #2
+ bl \type\()_rv40_qpel8_v_lowpass_neon
+ vpop {d8-d15}
+ pop {r1, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc11_neon, export=1
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ push {r1, lr}
+ vpush {d8-d15}
+ sub sp, sp, #44*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ mov r3, #20
+ vmov.i8 d0, #52
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ ldr r1, [sp, #416]
+ add r1, r1, #8
+ mov r3, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+.L\type\()_rv40_qpel16_v_s6:
+ add r1, sp, #7
+ bic r1, r1, #7
+ bl \type\()_rv40_qpel8_v_lp_packed_s6_neon
+ sub r1, r1, #40
+ bl \type\()_rv40_qpel8_v_lp_packed_s6_neon
+ sub r0, r0, r2, lsl #4
+ add r0, r0, #8
+ bl \type\()_rv40_qpel8_v_lp_packed_s6_neon
+ sub r1, r1, #40
+ bl \type\()_rv40_qpel8_v_lp_packed_s6_neon
+ add sp, sp, #44*8
+ vpop {d8-d15}
+ pop {r1, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc21_neon, export=1
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ push {r1, lr}
+ vpush {d8-d15}
+ sub sp, sp, #44*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ mov r3, #20
+ vmov.i8 d0, #20
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s5_neon
+ ldr r1, [sp, #416]
+ add r1, r1, #8
+ mov r3, #20
+ bl put_rv40_qpel8_h_lp_packed_s5_neon
+ vmov.i8 d0, #52
+ b .L\type\()_rv40_qpel16_v_s6
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc31_neon, export=1
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ push {r1, lr}
+ vpush {d8-d15}
+ sub sp, sp, #44*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ mov r3, #20
+ vmov.i8 d0, #20
+ vmov.i8 d1, #52
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ ldr r1, [sp, #416]
+ add r1, r1, #8
+ mov r3, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ vswp d0, d1
+ b .L\type\()_rv40_qpel16_v_s6
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc12_neon, export=1
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ push {r1, lr}
+ vpush {d8-d15}
+ sub sp, sp, #44*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ mov r3, #20
+ vmov.i8 d0, #52
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ ldr r1, [sp, #416]
+ add r1, r1, #8
+ mov r3, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ vmov.i8 d0, #20
+.L\type\()_rv40_qpel16_v_s5:
+ add r1, sp, #7
+ bic r1, r1, #7
+ bl \type\()_rv40_qpel8_v_lp_packed_s5_neon
+ sub r1, r1, #40
+ bl \type\()_rv40_qpel8_v_lp_packed_s5_neon
+ sub r0, r0, r2, lsl #4
+ add r0, r0, #8
+ bl \type\()_rv40_qpel8_v_lp_packed_s5_neon
+ sub r1, r1, #40
+ bl \type\()_rv40_qpel8_v_lp_packed_s5_neon
+ add sp, sp, #44*8
+ vpop {d8-d15}
+ pop {r1, pc}
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc22_neon, export=1
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ push {r1, lr}
+ vpush {d8-d15}
+ sub sp, sp, #44*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ mov r3, #20
+ vmov.i8 d0, #20
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s5_neon
+ ldr r1, [sp, #416]
+ add r1, r1, #8
+ mov r3, #20
+ bl put_rv40_qpel8_h_lp_packed_s5_neon
+ b .L\type\()_rv40_qpel16_v_s5
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc32_neon, export=1
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ push {r1, lr}
+ vpush {d8-d15}
+ sub sp, sp, #44*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ mov r3, #20
+ vmov.i8 d0, #20
+ vmov.i8 d1, #52
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ ldr r1, [sp, #416]
+ add r1, r1, #8
+ mov r3, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ vmov.i8 d1, #20
+ b .L\type\()_rv40_qpel16_v_s5
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc03_neon, export=1
+ vmov.i8 d0, #20
+ vmov.i8 d1, #52
+ b .L\type\()_rv40_qpel16_v
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc13_neon, export=1
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ push {r1, lr}
+ vpush {d8-d15}
+ sub sp, sp, #44*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ mov r3, #20
+ vmov.i8 d0, #52
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ ldr r1, [sp, #416]
+ add r1, r1, #8
+ mov r3, #20
+ bl put_rv40_qpel8_h_lp_packed_s6_neon
+ vswp d0, d1
+ b .L\type\()_rv40_qpel16_v_s6
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc23_neon, export=1
+ sub r1, r1, r2, lsl #1
+ sub r1, r1, #2
+ push {r1, lr}
+ vpush {d8-d15}
+ sub sp, sp, #44*8
+ add r12, sp, #7
+ bic r12, r12, #7
+ mov r3, #20
+ vmov.i8 d0, #20
+ vmov.i8 d1, #20
+ bl put_rv40_qpel8_h_lp_packed_s5_neon
+ ldr r1, [sp, #416]
+ add r1, r1, #8
+ mov r3, #20
+ bl put_rv40_qpel8_h_lp_packed_s5_neon
+ vmov.i8 d1, #52
+ b .L\type\()_rv40_qpel16_v_s6
+endfunc
+
+function ff_\type\()_rv40_qpel16_mc33_neon, export=1
+ mov r3, #16
+ b X(ff_\type\()_pixels16_xy2_neon)
+endfunc
+.endm
+
+ rv40_qpel put
+ rv40_qpel avg
+
+.macro rv40_weight
+ vmovl.u8 q8, d2
+ vmovl.u8 q9, d3
+ vmovl.u8 q10, d4
+ vmovl.u8 q11, d5
+ vmull.u16 q2, d16, d0[2]
+ vmull.u16 q3, d17, d0[2]
+ vmull.u16 q8, d18, d0[2]
+ vmull.u16 q9, d19, d0[2]
+ vmull.u16 q12, d20, d0[0]
+ vmull.u16 q13, d21, d0[0]
+ vmull.u16 q14, d22, d0[0]
+ vmull.u16 q15, d23, d0[0]
+ vshrn.i32 d4, q2, #9
+ vshrn.i32 d5, q3, #9
+ vshrn.i32 d6, q8, #9
+ vshrn.i32 d7, q9, #9
+ vshrn.i32 d16, q12, #9
+ vshrn.i32 d17, q13, #9
+ vshrn.i32 d18, q14, #9
+ vshrn.i32 d19, q15, #9
+ vadd.u16 q2, q2, q8
+ vadd.u16 q3, q3, q9
+ vrshrn.i16 d2, q2, #5
+ vrshrn.i16 d3, q3, #5
+.endm
+
+/* void ff_rv40_weight_func_16_neon(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+ int w1, int w2, int stride) */
+function ff_rv40_weight_func_16_neon, export=1
+ ldr r12, [sp]
+ vmov d0, r3, r12
+ ldr r12, [sp, #4]
+ mov r3, #16
+1:
+ vld1.8 {q1}, [r1,:128], r12
+ vld1.8 {q2}, [r2,:128], r12
+ rv40_weight
+ vst1.8 {q1}, [r0,:128], r12
+ subs r3, r3, #1
+ bne 1b
+ bx lr
+endfunc
+
+/* void ff_rv40_weight_func_8_neon(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+ int w1, int w2, int stride) */
+function ff_rv40_weight_func_8_neon, export=1
+ ldr r12, [sp]
+ vmov d0, r3, r12
+ ldr r12, [sp, #4]
+ mov r3, #8
+1:
+ vld1.8 {d2}, [r1,:64], r12
+ vld1.8 {d3}, [r1,:64], r12
+ vld1.8 {d4}, [r2,:64], r12
+ vld1.8 {d5}, [r2,:64], r12
+ rv40_weight
+ vst1.8 {d2}, [r0,:64], r12
+ vst1.8 {d3}, [r0,:64], r12
+ subs r3, r3, #2
+ bne 1b
+ bx lr
+endfunc
+
+function ff_rv40_h_loop_filter_strength_neon, export=1
+ pkhbt r2, r3, r2, lsl #18
+
+ ldr r3, [r0]
+ ldr_dpre r12, r0, r1
+ teq r3, r12
+ beq 1f
+
+ sub r0, r0, r1, lsl #1
+
+ vld1.32 {d4[]}, [r0,:32], r1 @ -3
+ vld1.32 {d0[]}, [r0,:32], r1 @ -2
+ vld1.32 {d4[1]}, [r0,:32], r1 @ -1
+ vld1.32 {d5[]}, [r0,:32], r1 @ 0
+ vld1.32 {d1[]}, [r0,:32], r1 @ 1
+ vld1.32 {d5[0]}, [r0,:32], r1 @ 2
+
+ vpaddl.u8 q8, q0 @ -2, -2, -2, -2, 1, 1, 1, 1
+ vpaddl.u8 q9, q2 @ -3, -3, -1, -1, 2, 2, 0, 0
+ vdup.32 d30, r2 @ beta2, beta << 2
+ vpadd.u16 d16, d16, d17 @ -2, -2, 1, 1
+ vpadd.u16 d18, d18, d19 @ -3, -1, 2, 0
+ vabd.u16 d16, d18, d16
+ vclt.u16 d16, d16, d30
+
+ ldrd r2, r3, [sp, #4]
+ vmovl.u16 q12, d16
+ vtrn.16 d16, d17
+ vshr.u32 q12, q12, #15
+ ldr r0, [sp]
+ vst1.32 {d24[1]}, [r2,:32]
+ vst1.32 {d25[1]}, [r3,:32]
+
+ cmp r0, #0
+ it eq
+ bxeq lr
+
+ vand d18, d16, d17
+ vtrn.32 d18, d19
+ vand d18, d18, d19
+ vmov.u16 r0, d18[0]
+ bx lr
+1:
+ ldrd r2, r3, [sp, #4]
+ mov r0, #0
+ str r0, [r2]
+ str r0, [r3]
+ bx lr
+endfunc
+
+function ff_rv40_v_loop_filter_strength_neon, export=1
+ sub r0, r0, #3
+ pkhbt r2, r3, r2, lsl #18
+
+ vld1.8 {d0}, [r0], r1
+ vld1.8 {d1}, [r0], r1
+ vld1.8 {d2}, [r0], r1
+ vld1.8 {d3}, [r0], r1
+
+ vaddl.u8 q0, d0, d1
+ vaddl.u8 q1, d2, d3
+ vdup.32 q15, r2
+ vadd.u16 q0, q0, q1 @ -3, -2, -1, 0, 1, 2
+ vext.16 q1, q0, q0, #1 @ -2, -1, 0, 1, 2
+ vabd.u16 q0, q1, q0
+ vclt.u16 q0, q0, q15
+
+ ldrd r2, r3, [sp, #4]
+ vmovl.u16 q1, d0
+ vext.16 d1, d0, d1, #3
+ vshr.u32 q1, q1, #15
+ ldr r0, [sp]
+ vst1.32 {d2[1]}, [r2,:32]
+ vst1.32 {d3[1]}, [r3,:32]
+
+ cmp r0, #0
+ it eq
+ bxeq lr
+
+ vand d0, d0, d1
+ vtrn.16 d0, d1
+ vand d0, d0, d1
+ vmov.u16 r0, d0[0]
+ bx lr
+endfunc
+
+.macro rv40_weak_loop_filter
+ vdup.16 d30, r2 @ filter_p1
+ vdup.16 d31, r3 @ filter_q1
+ ldrd r2, r3, [sp]
+ vdup.16 d28, r2 @ alpha
+ vdup.16 d29, r3 @ beta
+ ldr r12, [sp, #8]
+ vdup.16 d25, r12 @ lim_p0q0
+ ldrd r2, r3, [sp, #12]
+ vsubl.u8 q9, d5, d4 @ x, t
+ vabdl.u8 q8, d5, d4 @ x, abs(t)
+ vneg.s16 q15, q15
+ vceq.i16 d16, d19, #0 @ !t
+ vshl.s16 d19, d19, #2 @ t << 2
+ vmul.u16 d18, d17, d28 @ alpha * abs(t)
+ vand d24, d30, d31 @ filter_p1 & filter_q1
+ vsubl.u8 q1, d0, d4 @ p1p2, p1p0
+ vsubl.u8 q3, d1, d5 @ q1q2, q1q0
+ vmov.i16 d22, #3
+ vshr.u16 d18, d18, #7
+ vadd.i16 d22, d22, d24 @ 3 - (filter_p1 & filter_q1)
+ vsubl.u8 q10, d0, d1 @ src[-2] - src[1]
+ vcle.u16 d18, d18, d22
+ vand d20, d20, d24
+ vneg.s16 d23, d25 @ -lim_p0q0
+ vadd.s16 d19, d19, d20
+ vbic d16, d18, d16 @ t && u <= 3 - (fp1 & fq1)
+ vtrn.32 d4, d5 @ -3, 2, -1, 0
+ vrshr.s16 d19, d19, #3
+ vmov d28, d29 @ beta
+ vswp d3, d6 @ q1q2, p1p0
+ vmin.s16 d19, d19, d25
+ vand d30, d30, d16
+ vand d31, d31, d16
+ vadd.s16 q10, q1, q3 @ p1p2 + p1p0, q1q2 + q1q0
+ vmax.s16 d19, d19, d23 @ diff
+ vabs.s16 q1, q1 @ abs(p1p2), abs(q1q2)
+ vand d18, d19, d16 @ diff
+ vcle.u16 q1, q1, q14
+ vneg.s16 d19, d18 @ -diff
+ vdup.16 d26, r3 @ lim_p1
+ vaddw.u8 q2, q9, d5 @ src[-1]+diff, src[0]-diff
+ vhsub.s16 q11, q10, q9
+ vand q1, q1, q15
+ vqmovun.s16 d4, q2 @ -1, 0
+ vand q9, q11, q1
+ vdup.16 d27, r2 @ lim_q1
+ vneg.s16 q9, q9
+ vneg.s16 q14, q13
+ vmin.s16 q9, q9, q13
+ vtrn.32 d0, d1 @ -2, 1, -2, 1
+ vmax.s16 q9, q9, q14
+ vaddw.u8 q3, q9, d0
+ vqmovun.s16 d5, q3 @ -2, 1
+.endm
+
+function ff_rv40_h_weak_loop_filter_neon, export=1
+ sub r0, r0, r1, lsl #1
+ sub r0, r0, r1
+
+ vld1.32 {d4[]}, [r0,:32], r1
+ vld1.32 {d0[]}, [r0,:32], r1
+ vld1.32 {d4[1]}, [r0,:32], r1
+ vld1.32 {d5[]}, [r0,:32], r1
+ vld1.32 {d1[]}, [r0,:32], r1
+ vld1.32 {d5[0]}, [r0,:32]
+
+ sub r0, r0, r1, lsl #2
+
+ rv40_weak_loop_filter
+
+ vst1.32 {d5[0]}, [r0,:32], r1
+ vst1.32 {d4[0]}, [r0,:32], r1
+ vst1.32 {d4[1]}, [r0,:32], r1
+ vst1.32 {d5[1]}, [r0,:32], r1
+
+ bx lr
+endfunc
+
+function ff_rv40_v_weak_loop_filter_neon, export=1
+ sub r12, r0, #3
+ sub r0, r0, #2
+
+ vld1.8 {d4}, [r12], r1
+ vld1.8 {d5}, [r12], r1
+ vld1.8 {d2}, [r12], r1
+ vld1.8 {d3}, [r12], r1
+
+ vtrn.16 q2, q1
+ vtrn.8 d4, d5
+ vtrn.8 d2, d3
+
+ vrev64.32 d5, d5
+ vtrn.32 q2, q1
+ vdup.32 d0, d3[0]
+ vdup.32 d1, d2[0]
+
+ rv40_weak_loop_filter
+
+ vtrn.32 q2, q3
+ vswp d4, d5
+
+ vst4.8 {d4[0],d5[0],d6[0],d7[0]}, [r0], r1
+ vst4.8 {d4[1],d5[1],d6[1],d7[1]}, [r0], r1
+ vst4.8 {d4[2],d5[2],d6[2],d7[2]}, [r0], r1
+ vst4.8 {d4[3],d5[3],d6[3],d7[3]}, [r0], r1
+
+ bx lr
+endfunc
diff --git a/libavcodec/arm/simple_idct_arm.S b/libavcodec/arm/simple_idct_arm.S
index 4e6dfa4..1490f53 100644
--- a/libavcodec/arm/simple_idct_arm.S
+++ b/libavcodec/arm/simple_idct_arm.S
@@ -1,5 +1,4 @@
/*
- * simple_idct_arm.S
* Copyright (C) 2002 Frederic 'dilb' Boulay
*
* Author: Frederic Boulay <dilb at handhelds.org>
@@ -54,8 +53,6 @@
#define COL_SHIFTED_1 524288 /* 1<< (COL_SHIFT-1) */
- .text
-
function ff_simple_idct_arm, export=1
@@ void simple_idct_arm(int16_t *block)
@@ save stack for reg needed (take all of them),
@@ -121,11 +118,13 @@ __b_evaluation:
ldr r11, [r12, #offW7] @ R11=W7
mul r5, r10, r7 @ R5=W5*ROWr16[1]=b2 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
mul r7, r11, r7 @ R7=W7*ROWr16[1]=b3 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
- teq r2, #0 @ if null avoid muls
- mlane r0, r9, r2, r0 @ R0+=W3*ROWr16[3]=b0 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+ teq r2, #0 @ if null avoid muls
+ itttt ne
+ mlane r0, r9, r2, r0 @ R0+=W3*ROWr16[3]=b0 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
rsbne r2, r2, #0 @ R2=-ROWr16[3]
mlane r1, r11, r2, r1 @ R1-=W7*ROWr16[3]=b1 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
mlane r5, r8, r2, r5 @ R5-=W1*ROWr16[3]=b2 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+ it ne
mlane r7, r10, r2, r7 @ R7-=W5*ROWr16[3]=b3 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
@@ at this point, R0=b0, R1=b1, R2 (free), R3=ROWr32[2], R4=ROWr32[3],
@@ -148,19 +147,23 @@ __b_evaluation:
@@ MAC16(b3, -W1, row[7]);
@@ MAC16(b1, -W5, row[7]);
mov r3, r3, asr #16 @ R3=ROWr16[5]
- teq r3, #0 @ if null avoid muls
+ teq r3, #0 @ if null avoid muls
+ it ne
mlane r0, r10, r3, r0 @ R0+=W5*ROWr16[5]=b0
mov r4, r4, asr #16 @ R4=ROWr16[7]
+ itttt ne
mlane r5, r11, r3, r5 @ R5+=W7*ROWr16[5]=b2
mlane r7, r9, r3, r7 @ R7+=W3*ROWr16[5]=b3
rsbne r3, r3, #0 @ R3=-ROWr16[5]
mlane r1, r8, r3, r1 @ R7-=W1*ROWr16[5]=b1
@@ R3 is free now
- teq r4, #0 @ if null avoid muls
+ teq r4, #0 @ if null avoid muls
+ itttt ne
mlane r0, r11, r4, r0 @ R0+=W7*ROWr16[7]=b0
mlane r5, r9, r4, r5 @ R5+=W3*ROWr16[7]=b2
rsbne r4, r4, #0 @ R4=-ROWr16[7]
mlane r7, r8, r4, r7 @ R7-=W1*ROWr16[7]=b3
+ it ne
mlane r1, r10, r4, r1 @ R1-=W5*ROWr16[7]=b1
@@ R4 is free now
__end_b_evaluation:
@@ -204,16 +207,19 @@ __a_evaluation:
@@ a2 -= W4*row[4]
@@ a3 += W4*row[4]
ldrsh r11, [r14, #8] @ R11=ROWr16[4]
- teq r11, #0 @ if null avoid muls
+ teq r11, #0 @ if null avoid muls
+ it ne
mulne r11, r9, r11 @ R11=W4*ROWr16[4]
@@ R9 is free now
ldrsh r9, [r14, #12] @ R9=ROWr16[6]
+ itttt ne
addne r6, r6, r11 @ R6+=W4*ROWr16[4] (a0)
subne r2, r2, r11 @ R2-=W4*ROWr16[4] (a1)
subne r3, r3, r11 @ R3-=W4*ROWr16[4] (a2)
addne r4, r4, r11 @ R4+=W4*ROWr16[4] (a3)
@@ W6 alone is no more useful, save W2*ROWr16[6] in it instead
- teq r9, #0 @ if null avoid muls
+ teq r9, #0 @ if null avoid muls
+ itttt ne
mulne r11, r10, r9 @ R11=W6*ROWr16[6]
addne r6, r6, r11 @ R6+=W6*ROWr16[6] (a0)
mulne r10, r8, r9 @ R10=W2*ROWr16[6]
@@ -222,6 +228,7 @@ __a_evaluation:
@@ a1 -= W2*row[6];
@@ a2 += W2*row[6];
subne r4, r4, r11 @ R4-=W6*ROWr16[6] (a3)
+ itt ne
subne r2, r2, r10 @ R2-=W2*ROWr16[6] (a1)
addne r3, r3, r10 @ R3+=W2*ROWr16[6] (a2)
@@ -323,10 +330,12 @@ __b_evaluation2:
ldrsh r2, [r14, #48]
mul r7, r11, r7 @ R7=W7*ROWr16[1]=b3 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle)
teq r2, #0 @ if 0, then avoid muls
+ itttt ne
mlane r0, r9, r2, r0 @ R0+=W3*ROWr16[3]=b0 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
rsbne r2, r2, #0 @ R2=-ROWr16[3]
mlane r1, r11, r2, r1 @ R1-=W7*ROWr16[3]=b1 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
mlane r5, r8, r2, r5 @ R5-=W1*ROWr16[3]=b2 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
+ it ne
mlane r7, r10, r2, r7 @ R7-=W5*ROWr16[3]=b3 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle)
@@ at this point, R0=b0, R1=b1, R2 (free), R3 (free), R4 (free),
@@ -342,18 +351,22 @@ __b_evaluation2:
@@ MAC16(b1, -W5, col[7x8]);
ldrsh r3, [r14, #80] @ R3=COLr16[5x8]
teq r3, #0 @ if 0 then avoid muls
+ itttt ne
mlane r0, r10, r3, r0 @ R0+=W5*ROWr16[5x8]=b0
mlane r5, r11, r3, r5 @ R5+=W7*ROWr16[5x8]=b2
mlane r7, r9, r3, r7 @ R7+=W3*ROWr16[5x8]=b3
rsbne r3, r3, #0 @ R3=-ROWr16[5x8]
ldrsh r4, [r14, #112] @ R4=COLr16[7x8]
+ it ne
mlane r1, r8, r3, r1 @ R7-=W1*ROWr16[5x8]=b1
@@ R3 is free now
teq r4, #0 @ if 0 then avoid muls
+ itttt ne
mlane r0, r11, r4, r0 @ R0+=W7*ROWr16[7x8]=b0
mlane r5, r9, r4, r5 @ R5+=W3*ROWr16[7x8]=b2
rsbne r4, r4, #0 @ R4=-ROWr16[7x8]
mlane r7, r8, r4, r7 @ R7-=W1*ROWr16[7x8]=b3
+ it ne
mlane r1, r10, r4, r1 @ R1-=W5*ROWr16[7x8]=b1
@@ R4 is free now
__end_b_evaluation2:
@@ -390,15 +403,18 @@ __a_evaluation2:
@@ a3 += W4*row[4]
ldrsh r11, [r14, #64] @ R11=ROWr16[4]
teq r11, #0 @ if null avoid muls
+ itttt ne
mulne r11, r9, r11 @ R11=W4*ROWr16[4]
@@ R9 is free now
addne r6, r6, r11 @ R6+=W4*ROWr16[4] (a0)
subne r2, r2, r11 @ R2-=W4*ROWr16[4] (a1)
subne r3, r3, r11 @ R3-=W4*ROWr16[4] (a2)
ldrsh r9, [r14, #96] @ R9=ROWr16[6]
+ it ne
addne r4, r4, r11 @ R4+=W4*ROWr16[4] (a3)
@@ W6 alone is no more useful, save W2*ROWr16[6] in it instead
teq r9, #0 @ if null avoid muls
+ itttt ne
mulne r11, r10, r9 @ R11=W6*ROWr16[6]
addne r6, r6, r11 @ R6+=W6*ROWr16[6] (a0)
mulne r10, r8, r9 @ R10=W2*ROWr16[6]
@@ -407,6 +423,7 @@ __a_evaluation2:
@@ a1 -= W2*row[6];
@@ a2 += W2*row[6];
subne r4, r4, r11 @ R4-=W6*ROWr16[6] (a3)
+ itt ne
subne r2, r2, r10 @ R2-=W2*ROWr16[6] (a1)
addne r3, r3, r10 @ R3+=W2*ROWr16[6] (a2)
__end_a_evaluation2:
diff --git a/libavcodec/arm/simple_idct_armv5te.S b/libavcodec/arm/simple_idct_armv5te.S
index 29ebf5c..24641e4 100644
--- a/libavcodec/arm/simple_idct_armv5te.S
+++ b/libavcodec/arm/simple_idct_armv5te.S
@@ -49,6 +49,7 @@ function idct_row_armv5te
ldrd v1, [a1, #8]
ldrd a3, [a1] /* a3 = row[1:0], a4 = row[3:2] */
orrs v1, v1, v2
+ itt eq
cmpeq v1, a4
cmpeq v1, a3, lsr #16
beq row_dc_only
@@ -269,6 +270,7 @@ function idct_col_armv5te
ldmfd sp!, {a3, a4}
adds a2, a3, v1
mov a2, a2, lsr #20
+ it mi
orrmi a2, a2, #0xf000
add ip, a4, v2
mov ip, ip, asr #20
@@ -276,6 +278,7 @@ function idct_col_armv5te
str a2, [a1]
subs a3, a3, v1
mov a2, a3, lsr #20
+ it mi
orrmi a2, a2, #0xf000
sub a4, a4, v2
mov a4, a4, asr #20
@@ -285,6 +288,7 @@ function idct_col_armv5te
subs a2, a3, v3
mov a2, a2, lsr #20
+ it mi
orrmi a2, a2, #0xf000
sub ip, a4, v4
mov ip, ip, asr #20
@@ -292,6 +296,7 @@ function idct_col_armv5te
str a2, [a1, #(16*1)]
adds a3, a3, v3
mov a2, a3, lsr #20
+ it mi
orrmi a2, a2, #0xf000
add a4, a4, v4
mov a4, a4, asr #20
@@ -301,6 +306,7 @@ function idct_col_armv5te
adds a2, a3, v5
mov a2, a2, lsr #20
+ it mi
orrmi a2, a2, #0xf000
add ip, a4, v6
mov ip, ip, asr #20
@@ -308,6 +314,7 @@ function idct_col_armv5te
str a2, [a1, #(16*2)]
subs a3, a3, v5
mov a2, a3, lsr #20
+ it mi
orrmi a2, a2, #0xf000
sub a4, a4, v6
mov a4, a4, asr #20
@@ -317,6 +324,7 @@ function idct_col_armv5te
adds a2, a3, v7
mov a2, a2, lsr #20
+ it mi
orrmi a2, a2, #0xf000
add ip, a4, fp
mov ip, ip, asr #20
@@ -324,6 +332,7 @@ function idct_col_armv5te
str a2, [a1, #(16*3)]
subs a3, a3, v7
mov a2, a3, lsr #20
+ it mi
orrmi a2, a2, #0xf000
sub a4, a4, fp
mov a4, a4, asr #20
@@ -335,15 +344,19 @@ endfunc
.macro clip dst, src:vararg
movs \dst, \src
+ it mi
movmi \dst, #0
cmp \dst, #255
+ it gt
movgt \dst, #255
.endm
.macro aclip dst, src:vararg
adds \dst, \src
+ it mi
movmi \dst, #0
cmp \dst, #255
+ it gt
movgt \dst, #255
.endm
@@ -370,35 +383,35 @@ function idct_col_put_armv5te
orr a2, a3, a4, lsl #8
rsb v2, lr, lr, lsl #3
ldmfd sp!, {a3, a4}
- strh a2, [v2, v1]!
+ strh_pre a2, v2, v1
sub a2, a3, v3
clip a2, a2, asr #20
sub ip, a4, v4
clip ip, ip, asr #20
orr a2, a2, ip, lsl #8
- strh a2, [v1, lr]!
+ strh_pre a2, v1, lr
add a3, a3, v3
clip a2, a3, asr #20
add a4, a4, v4
clip a4, a4, asr #20
orr a2, a2, a4, lsl #8
ldmfd sp!, {a3, a4}
- strh a2, [v2, -lr]!
+ strh_dpre a2, v2, lr
add a2, a3, v5
clip a2, a2, asr #20
add ip, a4, v6
clip ip, ip, asr #20
orr a2, a2, ip, lsl #8
- strh a2, [v1, lr]!
+ strh_pre a2, v1, lr
sub a3, a3, v5
clip a2, a3, asr #20
sub a4, a4, v6
clip a4, a4, asr #20
orr a2, a2, a4, lsl #8
ldmfd sp!, {a3, a4}
- strh a2, [v2, -lr]!
+ strh_dpre a2, v2, lr
add a2, a3, v7
clip a2, a2, asr #20
@@ -411,7 +424,7 @@ function idct_col_put_armv5te
sub a4, a4, fp
clip a4, a4, asr #20
orr a2, a2, a4, lsl #8
- strh a2, [v2, -lr]
+ strh_dpre a2, v2, lr
ldr pc, [sp], #4
endfunc
@@ -436,7 +449,7 @@ function idct_col_add_armv5te
ldr v1, [sp, #32]
sub a4, a4, v2
rsb v2, v1, v1, lsl #3
- ldrh ip, [v2, lr]!
+ ldrh_pre ip, v2, lr
strh a2, [lr]
and a2, ip, #255
aclip a3, a2, a3, asr #20
@@ -448,7 +461,7 @@ function idct_col_add_armv5te
strh a2, [v2]
ldmfd sp!, {a3, a4}
- ldrh ip, [lr, v1]!
+ ldrh_pre ip, lr, v1
sub a2, a3, v3
add a3, a3, v3
and v3, ip, #255
@@ -458,7 +471,7 @@ function idct_col_add_armv5te
aclip v3, v3, ip, lsr #8
orr a2, a2, v3, lsl #8
add a4, a4, v4
- ldrh ip, [v2, -v1]!
+ ldrh_dpre ip, v2, v1
strh a2, [lr]
and a2, ip, #255
aclip a3, a2, a3, asr #20
@@ -468,7 +481,7 @@ function idct_col_add_armv5te
strh a2, [v2]
ldmfd sp!, {a3, a4}
- ldrh ip, [lr, v1]!
+ ldrh_pre ip, lr, v1
add a2, a3, v5
sub a3, a3, v5
and v3, ip, #255
@@ -478,7 +491,7 @@ function idct_col_add_armv5te
aclip v3, v3, ip, lsr #8
orr a2, a2, v3, lsl #8
sub a4, a4, v6
- ldrh ip, [v2, -v1]!
+ ldrh_dpre ip, v2, v1
strh a2, [lr]
and a2, ip, #255
aclip a3, a2, a3, asr #20
@@ -488,7 +501,7 @@ function idct_col_add_armv5te
strh a2, [v2]
ldmfd sp!, {a3, a4}
- ldrh ip, [lr, v1]!
+ ldrh_pre ip, lr, v1
add a2, a3, v7
sub a3, a3, v7
and v3, ip, #255
@@ -498,7 +511,7 @@ function idct_col_add_armv5te
aclip v3, v3, ip, lsr #8
orr a2, a2, v3, lsl #8
sub a4, a4, fp
- ldrh ip, [v2, -v1]!
+ ldrh_dpre ip, v2, v1
strh a2, [lr]
and a2, ip, #255
aclip a3, a2, a3, asr #20
diff --git a/libavcodec/arm/simple_idct_armv6.S b/libavcodec/arm/simple_idct_armv6.S
index b2eb525..284eb1f 100644
--- a/libavcodec/arm/simple_idct_armv6.S
+++ b/libavcodec/arm/simple_idct_armv6.S
@@ -200,6 +200,7 @@ function idct_row_armv6
ldr r3, [r0, #8] /* r3 = row[3,1] */
ldr r2, [r0] /* r2 = row[2,0] */
orrs lr, lr, ip
+ itt eq
cmpeq lr, r3
cmpeq lr, r2, lsr #16
beq 1f
@@ -282,14 +283,14 @@ function idct_col_put_armv6
pop {r1, r2}
idct_finish_shift_sat COL_SHIFT
- strb r4, [r1], r2
- strb r5, [r1], r2
- strb r6, [r1], r2
- strb r7, [r1], r2
- strb r11,[r1], r2
- strb r10,[r1], r2
- strb r9, [r1], r2
- strb r8, [r1], r2
+ strb_post r4, r1, r2
+ strb_post r5, r1, r2
+ strb_post r6, r1, r2
+ strb_post r7, r1, r2
+ strb_post r11,r1, r2
+ strb_post r10,r1, r2
+ strb_post r9, r1, r2
+ strb_post r8, r1, r2
sub r1, r1, r2, lsl #3
@@ -318,16 +319,16 @@ function idct_col_add_armv6
add ip, r3, ip, asr #COL_SHIFT
usat ip, #8, ip
add r4, r7, r4, asr #COL_SHIFT
- strb ip, [r1], r2
+ strb_post ip, r1, r2
ldrb ip, [r1, r2]
usat r4, #8, r4
ldrb r11,[r1, r2, lsl #2]
add r5, ip, r5, asr #COL_SHIFT
usat r5, #8, r5
- strb r4, [r1], r2
+ strb_post r4, r1, r2
ldrb r3, [r1, r2]
ldrb ip, [r1, r2, lsl #2]
- strb r5, [r1], r2
+ strb_post r5, r1, r2
ldrb r7, [r1, r2]
ldrb r4, [r1, r2, lsl #2]
add r6, r3, r6, asr #COL_SHIFT
@@ -340,11 +341,11 @@ function idct_col_add_armv6
usat r8, #8, r8
add lr, r4, lr, asr #COL_SHIFT
usat lr, #8, lr
- strb r6, [r1], r2
- strb r10,[r1], r2
- strb r9, [r1], r2
- strb r8, [r1], r2
- strb lr, [r1], r2
+ strb_post r6, r1, r2
+ strb_post r10,r1, r2
+ strb_post r9, r1, r2
+ strb_post r8, r1, r2
+ strb_post lr, r1, r2
sub r1, r1, r2, lsl #3
diff --git a/libavcodec/arm/simple_idct_neon.S b/libavcodec/arm/simple_idct_neon.S
index 0628b96..0c4e05d 100644
--- a/libavcodec/arm/simple_idct_neon.S
+++ b/libavcodec/arm/simple_idct_neon.S
@@ -71,7 +71,7 @@ function idct_row4_pld_neon
add r3, r0, r1, lsl #2
pld [r0, r1]
pld [r0, r1, lsl #1]
- pld [r3, -r1]
+A pld [r3, -r1]
pld [r3]
pld [r3, r1]
add r3, r3, r1, lsl #1
@@ -164,6 +164,7 @@ function idct_col4_neon
orrs r4, r4, r5
idct_col4_top
+ it eq
addeq r2, r2, #16
beq 1f
@@ -176,6 +177,7 @@ function idct_col4_neon
1: orrs r6, r6, r7
ldrd r4, [r2, #16]
+ it eq
addeq r2, r2, #16
beq 2f
@@ -187,6 +189,7 @@ function idct_col4_neon
2: orrs r4, r4, r5
ldrd r4, [r2, #16]
+ it eq
addeq r2, r2, #16
beq 3f
@@ -199,6 +202,7 @@ function idct_col4_neon
vadd.i32 q13, q13, q8
3: orrs r4, r4, r5
+ it eq
addeq r2, r2, #16
beq 4f
@@ -239,10 +243,9 @@ function idct_col4_st8_neon
bx lr
endfunc
- .section .rodata
- .align 4
-idct_coeff_neon:
+const idct_coeff_neon, align=4
.short W1, W2, W3, W4, W5, W6, W7, W4c
+endconst
.macro idct_start data
push {r4-r7, lr}
diff --git a/libavcodec/arm/synth_filter_neon.S b/libavcodec/arm/synth_filter_neon.S
index d4f67b7..1d6e5b2 100644
--- a/libavcodec/arm/synth_filter_neon.S
+++ b/libavcodec/arm/synth_filter_neon.S
@@ -100,9 +100,11 @@ NOVFP vldr s0, [sp, #12*4] @ scale
vst1.32 {q9}, [r2,:128]
subs r1, r1, #1
+ it eq
popeq {r4-r11,pc}
cmp r4, #0
+ itt eq
subeq r8, r8, #512*4
subeq r9, r9, #512*4
sub r5, r5, #512*4
diff --git a/libavcodec/arm/vp3dsp_neon.S b/libavcodec/arm/vp3dsp_neon.S
index c1a55ca..279b132 100644
--- a/libavcodec/arm/vp3dsp_neon.S
+++ b/libavcodec/arm/vp3dsp_neon.S
@@ -20,11 +20,9 @@
#include "asm.S"
-.section .rodata
-.align 4
-
-vp3_idct_constants:
+const vp3_idct_constants, align=4
.short 64277, 60547, 54491, 46341, 36410, 25080, 12785
+endconst
#define xC1S7 d0[0]
#define xC2S6 d0[1]
@@ -34,8 +32,6 @@ vp3_idct_constants:
#define xC6S2 d1[1]
#define xC7S1 d1[2]
-.text
-
.macro vp3_loop_filter
vsubl.u8 q3, d18, d17
vsubl.u8 q2, d16, d19
diff --git a/libavcodec/arm/vp56_arith.h b/libavcodec/arm/vp56_arith.h
index 9ce3fd0..ef30ffe 100644
--- a/libavcodec/arm/vp56_arith.h
+++ b/libavcodec/arm/vp56_arith.h
@@ -21,6 +21,14 @@
#ifndef AVCODEC_ARM_VP56_ARITH_H
#define AVCODEC_ARM_VP56_ARITH_H
+#if CONFIG_THUMB
+# define A(x)
+# define T(x) x
+#else
+# define A(x) x
+# define T(x)
+#endif
+
#if HAVE_ARMV6 && HAVE_INLINE_ASM
#define vp56_rac_get_prob vp56_rac_get_prob_armv6
@@ -32,15 +40,21 @@ static inline int vp56_rac_get_prob_armv6(VP56RangeCoder *c, int pr)
unsigned bit;
__asm__ ("adds %3, %3, %0 \n"
+ "itt cs \n"
"cmpcs %7, %4 \n"
- "ldrcsh %2, [%4], #2 \n"
+ A("ldrcsh %2, [%4], #2 \n")
+ T("ldrhcs %2, [%4], #2 \n")
"rsb %0, %6, #256 \n"
"smlabb %0, %5, %6, %0 \n"
+ T("itttt cs \n")
"rev16cs %2, %2 \n"
- "orrcs %1, %1, %2, lsl %3 \n"
+ T("lslcs %2, %2, %3 \n")
+ T("orrcs %1, %1, %2 \n")
+ A("orrcs %1, %1, %2, lsl %3 \n")
"subcs %3, %3, #16 \n"
"lsr %0, %0, #8 \n"
"cmp %1, %0, lsl #16 \n"
+ "ittte ge \n"
"subge %1, %1, %0, lsl #16 \n"
"subge %0, %5, %0 \n"
"movge %2, #1 \n"
@@ -64,12 +78,17 @@ static inline int vp56_rac_get_prob_branchy_armv6(VP56RangeCoder *c, int pr)
unsigned tmp;
__asm__ ("adds %3, %3, %0 \n"
+ "itt cs \n"
"cmpcs %7, %4 \n"
- "ldrcsh %2, [%4], #2 \n"
+ A("ldrcsh %2, [%4], #2 \n")
+ T("ldrhcs %2, [%4], #2 \n")
"rsb %0, %6, #256 \n"
"smlabb %0, %5, %6, %0 \n"
+ T("itttt cs \n")
"rev16cs %2, %2 \n"
- "orrcs %1, %1, %2, lsl %3 \n"
+ T("lslcs %2, %2, %3 \n")
+ T("orrcs %1, %1, %2 \n")
+ A("orrcs %1, %1, %2, lsl %3 \n")
"subcs %3, %3, #16 \n"
"lsr %0, %0, #8 \n"
"lsl %2, %0, #16 \n"
diff --git a/libavcodec/arm/vp8_armv6.S b/libavcodec/arm/vp8_armv6.S
index 602c8a5..594046d 100644
--- a/libavcodec/arm/vp8_armv6.S
+++ b/libavcodec/arm/vp8_armv6.S
@@ -25,13 +25,18 @@
lsl \cw, \cw, \t0
lsl \t0, \h, \t0
rsb \h, \pr, #256
+ it cs
ldrhcs \t1, [\buf], #2
smlabb \h, \t0, \pr, \h
+T itttt cs
rev16cs \t1, \t1
- orrcs \cw, \cw, \t1, lsl \bs
+A orrcs \cw, \cw, \t1, lsl \bs
+T lslcs \t1, \t1, \bs
+T orrcs \cw, \cw, \t1
subcs \bs, \bs, #16
lsr \h, \h, #8
cmp \cw, \h, lsl #16
+ itt ge
subge \cw, \cw, \h, lsl #16
subge \h, \t0, \h
.endm
@@ -40,14 +45,20 @@
adds \bs, \bs, \t0
lsl \cw, \cw, \t0
lsl \t0, \h, \t0
+ it cs
ldrhcs \t1, [\buf], #2
mov \h, #128
+ it cs
rev16cs \t1, \t1
add \h, \h, \t0, lsl #7
- orrcs \cw, \cw, \t1, lsl \bs
+A orrcs \cw, \cw, \t1, lsl \bs
+T ittt cs
+T lslcs \t1, \t1, \bs
+T orrcs \cw, \cw, \t1
subcs \bs, \bs, #16
lsr \h, \h, #8
cmp \cw, \h, lsl #16
+ itt ge
subge \cw, \cw, \h, lsl #16
subge \h, \t0, \h
.endm
@@ -59,6 +70,7 @@ function ff_decode_block_coeffs_armv6, export=1
cmp r3, #0
ldr r11, [r5]
ldm r0, {r5-r7} @ high, bits, buf
+ it ne
pkhtbne r11, r11, r11, asr #16
ldr r8, [r0, #16] @ code_word
0:
@@ -80,19 +92,26 @@ function ff_decode_block_coeffs_armv6, export=1
adds r6, r6, r9
add r4, r4, #11
lsl r8, r8, r9
+ it cs
ldrhcs r10, [r7], #2
lsl r9, r5, r9
mov r5, #128
+ it cs
rev16cs r10, r10
add r5, r5, r9, lsl #7
- orrcs r8, r8, r10, lsl r6
+T ittt cs
+T lslcs r10, r10, r6
+T orrcs r8, r8, r10
+A orrcs r8, r8, r10, lsl r6
subcs r6, r6, #16
lsr r5, r5, #8
cmp r8, r5, lsl #16
movrel r10, zigzag_scan-1
+ itt ge
subge r8, r8, r5, lsl #16
subge r5, r9, r5
ldrb r10, [r10, r3]
+ it ge
rsbge r12, r12, #0
cmp r3, #16
strh r12, [r1, r10]
@@ -108,6 +127,7 @@ function ff_decode_block_coeffs_armv6, export=1
ldr r0, [sp]
ldr r9, [r0, #12]
cmp r7, r9
+ it hi
movhi r7, r9
stm r0, {r5-r7} @ high, bits, buf
str r8, [r0, #16] @ code_word
@@ -131,11 +151,13 @@ function ff_decode_block_coeffs_armv6, export=1
mov r12, #2
ldrb r0, [r4, #4]
rac_get_prob r5, r6, r7, r8, r0, r9, r10
+ it ge
addge r12, #1
ldrb r9, [lr, r5]
blt 4f
ldrb r0, [r4, #5]
rac_get_prob r5, r6, r7, r8, r0, r9, r10
+ it ge
addge r12, #1
ldrb r9, [lr, r5]
b 4f
@@ -153,6 +175,7 @@ function ff_decode_block_coeffs_armv6, export=1
mov r12, #5
mov r0, #159
rac_get_prob r5, r6, r7, r8, r0, r9, r10
+ it ge
addge r12, r12, #1
ldrb r9, [lr, r5]
b 4f
@@ -160,23 +183,28 @@ function ff_decode_block_coeffs_armv6, export=1
mov r12, #7
mov r0, #165
rac_get_prob r5, r6, r7, r8, r0, r9, r10
+ it ge
addge r12, r12, #2
ldrb r9, [lr, r5]
mov r0, #145
rac_get_prob r5, r6, r7, r8, r0, r9, r10
+ it ge
addge r12, r12, #1
ldrb r9, [lr, r5]
b 4f
3:
ldrb r0, [r4, #8]
rac_get_prob r5, r6, r7, r8, r0, r9, r10
+ it ge
addge r4, r4, #1
ldrb r9, [lr, r5]
+ ite ge
movge r12, #2
movlt r12, #0
ldrb r0, [r4, #9]
rac_get_prob r5, r6, r7, r8, r0, r9, r10
mov r9, #8
+ it ge
addge r12, r12, #1
movrel r4, X(ff_vp8_dct_cat_prob)
lsl r9, r9, r12
@@ -189,6 +217,7 @@ function ff_decode_block_coeffs_armv6, export=1
lsl r1, r1, #1
rac_get_prob r5, r6, r7, r8, r0, r9, r10
ldrb r0, [r4], #1
+ it ge
addge r1, r1, #1
cmp r0, #0
bne 1b
@@ -200,6 +229,7 @@ function ff_decode_block_coeffs_armv6, export=1
add r4, r2, r4
add r4, r4, #22
rac_get_128 r5, r6, r7, r8, r9, r10
+ it ge
rsbge r12, r12, #0
smulbb r12, r12, r11
movrel r9, zigzag_scan-1
@@ -210,9 +240,9 @@ function ff_decode_block_coeffs_armv6, export=1
b 5b
endfunc
- .section .rodata
-zigzag_scan:
+const zigzag_scan
.byte 0, 2, 8, 16
.byte 10, 4, 6, 12
.byte 18, 24, 26, 20
.byte 14, 22, 28, 30
+endconst
diff --git a/libavcodec/arm/vp8dsp_neon.S b/libavcodec/arm/vp8dsp_neon.S
index 92b1ef4..4ff53ad 100644
--- a/libavcodec/arm/vp8dsp_neon.S
+++ b/libavcodec/arm/vp8dsp_neon.S
@@ -22,6 +22,7 @@
*/
#include "asm.S"
+#include "neon.S"
function ff_vp8_luma_dc_wht_neon, export=1
vld1.16 {q0-q1}, [r1,:128]
@@ -454,23 +455,6 @@ endfunc
.endif
.endm
-.macro transpose8x16matrix
- vtrn.32 q0, q4
- vtrn.32 q1, q5
- vtrn.32 q2, q6
- vtrn.32 q3, q7
-
- vtrn.16 q0, q2
- vtrn.16 q1, q3
- vtrn.16 q4, q6
- vtrn.16 q5, q7
-
- vtrn.8 q0, q1
- vtrn.8 q2, q3
- vtrn.8 q4, q5
- vtrn.8 q6, q7
-.endm
-
.macro vp8_v_loop_filter16 name, inner=0, simple=0
function ff_vp8_v_loop_filter16\name\()_neon, export=1
vpush {q4-q7}
@@ -605,7 +589,7 @@ function ff_vp8_h_loop_filter16\name\()_neon, export=1
vld1.8 {d13}, [r0], r1
vld1.8 {d15}, [r0], r1
- transpose8x16matrix
+ transpose_8x8 q0, q1, q2, q3, q4, q5, q6, q7
vdup.8 q14, r2 @ flim_E
.if !\simple
@@ -616,7 +600,7 @@ function ff_vp8_h_loop_filter16\name\()_neon, export=1
sub r0, r0, r1, lsl #4 @ backup 16 rows
- transpose8x16matrix
+ transpose_8x8 q0, q1, q2, q3, q4, q5, q6, q7
@ Store pixels:
vst1.8 {d0}, [r0], r1
@@ -670,7 +654,7 @@ function ff_vp8_h_loop_filter8uv\name\()_neon, export=1
vld1.8 {d14}, [r0], r2
vld1.8 {d15}, [r1], r2
- transpose8x16matrix
+ transpose_8x8 q0, q1, q2, q3, q4, q5, q6, q7
vdup.8 q14, r3 @ flim_E
vdup.8 q15, r12 @ flim_I
@@ -681,7 +665,7 @@ function ff_vp8_h_loop_filter8uv\name\()_neon, export=1
sub r0, r0, r2, lsl #3 @ backup u 8 rows
sub r1, r1, r2, lsl #3 @ backup v 8 rows
- transpose8x16matrix
+ transpose_8x8 q0, q1, q2, q3, q4, q5, q6, q7
@ Store pixels:
vst1.8 {d0}, [r0], r2
@@ -746,14 +730,14 @@ function ff_put_vp8_pixels4_neon, export=1
push {r4-r6,lr}
1:
subs r12, r12, #4
- ldr r4, [r2], r3
- ldr r5, [r2], r3
- ldr r6, [r2], r3
- ldr lr, [r2], r3
- str r4, [r0], r1
- str r5, [r0], r1
- str r6, [r0], r1
- str lr, [r0], r1
+ ldr_post r4, r2, r3
+ ldr_post r5, r2, r3
+ ldr_post r6, r2, r3
+ ldr_post lr, r2, r3
+ str_post r4, r0, r1
+ str_post r5, r0, r1
+ str_post r6, r0, r1
+ str_post lr, r0, r1
bgt 1b
pop {r4-r6,pc}
endfunc
diff --git a/libavcodec/asv1.c b/libavcodec/asv1.c
index e8ab07b..8db23c0 100644
--- a/libavcodec/asv1.c
+++ b/libavcodec/asv1.c
@@ -497,7 +497,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
}
emms_c();
- align_put_bits(&a->pb);
+ avpriv_align_put_bits(&a->pb);
while(put_bits_count(&a->pb)&31)
put_bits(&a->pb, 8, 0);
@@ -603,39 +603,37 @@ static av_cold int decode_end(AVCodecContext *avctx){
}
AVCodec ff_asv1_decoder = {
- "asv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ASV1,
- sizeof(ASV1Context),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "asv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ASV1,
+ .priv_data_size = sizeof(ASV1Context),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name= NULL_IF_CONFIG_SMALL("ASUS V1"),
};
AVCodec ff_asv2_decoder = {
- "asv2",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ASV2,
- sizeof(ASV1Context),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "asv2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ASV2,
+ .priv_data_size = sizeof(ASV1Context),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name= NULL_IF_CONFIG_SMALL("ASUS V2"),
};
#if CONFIG_ASV1_ENCODER
AVCodec ff_asv1_encoder = {
- "asv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ASV1,
- sizeof(ASV1Context),
- encode_init,
- encode_frame,
+ .name = "asv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ASV1,
+ .priv_data_size = sizeof(ASV1Context),
+ .init = encode_init,
+ .encode = encode_frame,
//encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("ASUS V1"),
@@ -644,12 +642,12 @@ AVCodec ff_asv1_encoder = {
#if CONFIG_ASV2_ENCODER
AVCodec ff_asv2_encoder = {
- "asv2",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ASV2,
- sizeof(ASV1Context),
- encode_init,
- encode_frame,
+ .name = "asv2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ASV2,
+ .priv_data_size = sizeof(ASV1Context),
+ .init = encode_init,
+ .encode = encode_frame,
//encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("ASUS V2"),
diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c
index 0ba2cf6..9ead80d 100644
--- a/libavcodec/atrac1.c
+++ b/libavcodec/atrac1.c
@@ -36,6 +36,7 @@
#include "get_bits.h"
#include "dsputil.h"
#include "fft.h"
+#include "fmtconvert.h"
#include "sinewin.h"
#include "atrac.h"
@@ -71,6 +72,7 @@ typedef struct {
* The atrac1 context, holds all needed parameters for decoding
*/
typedef struct {
+ AVFrame frame;
AT1SUCtx SUs[AT1_MAX_CHANNELS]; ///< channel sound unit
DECLARE_ALIGNED(32, float, spec)[AT1_SU_SAMPLES]; ///< the mdct spectrum buffer
@@ -78,10 +80,11 @@ typedef struct {
DECLARE_ALIGNED(32, float, mid)[256];
DECLARE_ALIGNED(32, float, high)[512];
float* bands[3];
- DECLARE_ALIGNED(32, float, out_samples)[AT1_MAX_CHANNELS][AT1_SU_SAMPLES];
+ float *out_samples[AT1_MAX_CHANNELS];
FFTContext mdct_ctx[3];
int channels;
DSPContext dsp;
+ FmtConvertContext fmt_conv;
} AT1Ctx;
/** size of the transform in samples in the long mode for each QMF band */
@@ -129,7 +132,7 @@ static int at1_imdct_block(AT1SUCtx* su, AT1Ctx *q)
nbits = mdct_long_nbits[band_num] - log2_block_count;
if (nbits != 5 && nbits != 7 && nbits != 8)
- return -1;
+ return AVERROR_INVALIDDATA;
} else {
block_size = 32;
nbits = 5;
@@ -173,14 +176,14 @@ static int at1_parse_bsm(GetBitContext* gb, int log2_block_cnt[AT1_QMF_BANDS])
/* low and mid band */
log2_block_count_tmp = get_bits(gb, 2);
if (log2_block_count_tmp & 1)
- return -1;
+ return AVERROR_INVALIDDATA;
log2_block_cnt[i] = 2 - log2_block_count_tmp;
}
/* high band */
log2_block_count_tmp = get_bits(gb, 2);
if (log2_block_count_tmp != 0 && log2_block_count_tmp != 3)
- return -1;
+ return AVERROR_INVALIDDATA;
log2_block_cnt[IDX_HIGH_BAND] = 3 - log2_block_count_tmp;
skip_bits(gb, 2);
@@ -229,7 +232,7 @@ static int at1_unpack_dequant(GetBitContext* gb, AT1SUCtx* su,
/* check for bitstream overflow */
if (bits_used > AT1_SU_MAX_BITS)
- return -1;
+ return AVERROR_INVALIDDATA;
/* get the position of the 1st spec according to the block size mode */
pos = su->log2_block_count[band_num] ? bfu_start_short[bfu_num] : bfu_start_long[bfu_num];
@@ -271,21 +274,29 @@ static void at1_subband_synthesis(AT1Ctx *q, AT1SUCtx* su, float *pOut)
static int atrac1_decode_frame(AVCodecContext *avctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
AT1Ctx *q = avctx->priv_data;
- int ch, ret, i;
+ int ch, ret;
GetBitContext gb;
- float* samples = data;
+ float *samples;
if (buf_size < 212 * q->channels) {
- av_log(q,AV_LOG_ERROR,"Not enought data to decode!\n");
- return -1;
+ av_log(avctx, AV_LOG_ERROR, "Not enough data to decode!\n");
+ return AVERROR_INVALIDDATA;
}
+ /* get output buffer */
+ q->frame.nb_samples = AT1_SU_SAMPLES;
+ if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (float *)q->frame.data[0];
+
for (ch = 0; ch < q->channels; ch++) {
AT1SUCtx* su = &q->SUs[ch];
@@ -303,44 +314,74 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data,
ret = at1_imdct_block(su, q);
if (ret < 0)
return ret;
- at1_subband_synthesis(q, su, q->out_samples[ch]);
+ at1_subband_synthesis(q, su, q->channels == 1 ? samples : q->out_samples[ch]);
}
- /* interleave; FIXME, should create/use a DSP function */
- if (q->channels == 1) {
- /* mono */
- memcpy(samples, q->out_samples[0], AT1_SU_SAMPLES * 4);
- } else {
- /* stereo */
- for (i = 0; i < AT1_SU_SAMPLES; i++) {
- samples[i * 2] = q->out_samples[0][i];
- samples[i * 2 + 1] = q->out_samples[1][i];
- }
+ /* interleave */
+ if (q->channels == 2) {
+ q->fmt_conv.float_interleave(samples, (const float **)q->out_samples,
+ AT1_SU_SAMPLES, 2);
}
- *data_size = q->channels * AT1_SU_SAMPLES * sizeof(*samples);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = q->frame;
+
return avctx->block_align;
}
+static av_cold int atrac1_decode_end(AVCodecContext * avctx)
+{
+ AT1Ctx *q = avctx->priv_data;
+
+ av_freep(&q->out_samples[0]);
+
+ ff_mdct_end(&q->mdct_ctx[0]);
+ ff_mdct_end(&q->mdct_ctx[1]);
+ ff_mdct_end(&q->mdct_ctx[2]);
+
+ return 0;
+}
+
+
static av_cold int atrac1_decode_init(AVCodecContext *avctx)
{
AT1Ctx *q = avctx->priv_data;
+ int ret;
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ if (avctx->channels < 1 || avctx->channels > AT1_MAX_CHANNELS) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n",
+ avctx->channels);
+ return AVERROR(EINVAL);
+ }
q->channels = avctx->channels;
+ if (avctx->channels == 2) {
+ q->out_samples[0] = av_malloc(2 * AT1_SU_SAMPLES * sizeof(*q->out_samples[0]));
+ q->out_samples[1] = q->out_samples[0] + AT1_SU_SAMPLES;
+ if (!q->out_samples[0]) {
+ av_freep(&q->out_samples[0]);
+ return AVERROR(ENOMEM);
+ }
+ }
+
/* Init the mdct transforms */
- ff_mdct_init(&q->mdct_ctx[0], 6, 1, -1.0/ (1 << 15));
- ff_mdct_init(&q->mdct_ctx[1], 8, 1, -1.0/ (1 << 15));
- ff_mdct_init(&q->mdct_ctx[2], 9, 1, -1.0/ (1 << 15));
+ if ((ret = ff_mdct_init(&q->mdct_ctx[0], 6, 1, -1.0/ (1 << 15))) ||
+ (ret = ff_mdct_init(&q->mdct_ctx[1], 8, 1, -1.0/ (1 << 15))) ||
+ (ret = ff_mdct_init(&q->mdct_ctx[2], 9, 1, -1.0/ (1 << 15)))) {
+ av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
+ atrac1_decode_end(avctx);
+ return ret;
+ }
ff_init_ff_sine_windows(5);
atrac_generate_tables();
dsputil_init(&q->dsp, avctx);
+ ff_fmt_convert_init(&q->fmt_conv, avctx);
q->bands[0] = q->low;
q->bands[1] = q->mid;
@@ -352,16 +393,9 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx)
q->SUs[1].spectrum[0] = q->SUs[1].spec1;
q->SUs[1].spectrum[1] = q->SUs[1].spec2;
- return 0;
-}
-
-
-static av_cold int atrac1_decode_end(AVCodecContext * avctx) {
- AT1Ctx *q = avctx->priv_data;
+ avcodec_get_frame_defaults(&q->frame);
+ avctx->coded_frame = &q->frame;
- ff_mdct_end(&q->mdct_ctx[0]);
- ff_mdct_end(&q->mdct_ctx[1]);
- ff_mdct_end(&q->mdct_ctx[2]);
return 0;
}
@@ -374,5 +408,6 @@ AVCodec ff_atrac1_decoder = {
.init = atrac1_decode_init,
.close = atrac1_decode_end,
.decode = atrac1_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Atrac 1 (Adaptive TRansform Acoustic Coding)"),
};
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c
index accaae3..744ef17 100644
--- a/libavcodec/atrac3.c
+++ b/libavcodec/atrac3.c
@@ -41,6 +41,7 @@
#include "dsputil.h"
#include "bytestream.h"
#include "fft.h"
+#include "fmtconvert.h"
#include "atrac.h"
#include "atrac3data.h"
@@ -48,6 +49,8 @@
#define JOINT_STEREO 0x12
#define STEREO 0x2
+#define SAMPLES_PER_FRAME 1024
+#define MDCT_SIZE 512
/* These structures are needed to store the parsed gain control data. */
typedef struct {
@@ -70,12 +73,12 @@ typedef struct {
int bandsCoded;
int numComponents;
tonal_component components[64];
- float prevFrame[1024];
+ float prevFrame[SAMPLES_PER_FRAME];
int gcBlkSwitch;
gain_block gainBlock[2];
- DECLARE_ALIGNED(32, float, spectrum)[1024];
- DECLARE_ALIGNED(32, float, IMDCT_buf)[1024];
+ DECLARE_ALIGNED(32, float, spectrum)[SAMPLES_PER_FRAME];
+ DECLARE_ALIGNED(32, float, IMDCT_buf)[SAMPLES_PER_FRAME];
float delayBuf1[46]; ///<qmf delay buffers
float delayBuf2[46];
@@ -83,6 +86,7 @@ typedef struct {
} channel_unit;
typedef struct {
+ AVFrame frame;
GetBitContext gb;
//@{
/** stream data */
@@ -107,7 +111,7 @@ typedef struct {
//@}
//@{
/** data buffers */
- float outSamples[2048];
+ float *outSamples[2];
uint8_t* decoded_bytes_buffer;
float tempBuf[1070];
//@}
@@ -120,9 +124,10 @@ typedef struct {
//@}
FFTContext mdct_ctx;
+ FmtConvertContext fmt_conv;
} ATRAC3Context;
-static DECLARE_ALIGNED(32, float, mdct_window)[512];
+static DECLARE_ALIGNED(32, float, mdct_window)[MDCT_SIZE];
static VLC spectral_coeff_tab[7];
static float gain_tab1[16];
static float gain_tab2[31];
@@ -159,7 +164,7 @@ static void IMLT(ATRAC3Context *q, float *pInput, float *pOutput, int odd_band)
q->mdct_ctx.imdct_calc(&q->mdct_ctx,pOutput,pInput);
/* Perform windowing on the output. */
- dsp.vector_fmul(pOutput, pOutput, mdct_window, 512);
+ dsp.vector_fmul(pOutput, pOutput, mdct_window, MDCT_SIZE);
}
@@ -192,7 +197,7 @@ static int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){
}
-static av_cold void init_atrac3_transforms(ATRAC3Context *q) {
+static av_cold int init_atrac3_transforms(ATRAC3Context *q, int is_float) {
float enc_window[256];
int i;
@@ -208,7 +213,7 @@ static av_cold void init_atrac3_transforms(ATRAC3Context *q) {
}
/* Initialize the MDCT transform. */
- ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0);
+ return ff_mdct_init(&q->mdct_ctx, 9, 1, is_float ? 1.0 / 32768 : 1.0);
}
/**
@@ -221,6 +226,8 @@ static av_cold int atrac3_decode_close(AVCodecContext *avctx)
av_free(q->pUnits);
av_free(q->decoded_bytes_buffer);
+ av_freep(&q->outSamples[0]);
+
ff_mdct_end(&q->mdct_ctx);
return 0;
@@ -340,7 +347,7 @@ static int decodeSpectrum (GetBitContext *gb, float *pOut)
/* Clear the subbands that were not coded. */
first = subbandTab[cnt];
- memset(pOut+first, 0, (1024 - first) * sizeof(float));
+ memset(pOut+first, 0, (SAMPLES_PER_FRAME - first) * sizeof(float));
return numSubbands;
}
@@ -370,7 +377,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent
coding_mode_selector = get_bits(gb,2);
if (coding_mode_selector == 2)
- return -1;
+ return AVERROR_INVALIDDATA;
coding_mode = coding_mode_selector & 1;
@@ -382,7 +389,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent
quant_step_index = get_bits(gb,3);
if (quant_step_index <= 1)
- return -1;
+ return AVERROR_INVALIDDATA;
if (coding_mode_selector == 3)
coding_mode = get_bits1(gb);
@@ -396,7 +403,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent
for (k=0; k<coded_components; k++) {
sfIndx = get_bits(gb,6);
pComponent[component_count].pos = j * 64 + (get_bits(gb,6));
- max_coded_values = 1024 - pComponent[component_count].pos;
+ max_coded_values = SAMPLES_PER_FRAME - pComponent[component_count].pos;
coded_values = coded_values_per_component + 1;
coded_values = FFMIN(max_coded_values,coded_values);
@@ -445,7 +452,7 @@ static int decodeGainControl (GetBitContext *gb, gain_block *pGb, int numBands)
pLevel[cf]= get_bits(gb,4);
pLoc [cf]= get_bits(gb,5);
if(cf && pLoc[cf] <= pLoc[cf-1])
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
@@ -662,12 +669,12 @@ static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_
if (codingMode == JOINT_STEREO && channelNum == 1) {
if (get_bits(gb,2) != 3) {
av_log(NULL,AV_LOG_ERROR,"JS mono Sound Unit id != 3.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
} else {
if (get_bits(gb,6) != 0x28) {
av_log(NULL,AV_LOG_ERROR,"Sound Unit id != 0x28.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
@@ -701,9 +708,10 @@ static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_
memset(pSnd->IMDCT_buf, 0, 512 * sizeof(float));
/* gain compensation and overlapping */
- gainCompensateAndOverlap (pSnd->IMDCT_buf, &(pSnd->prevFrame[band*256]), &(pOut[band*256]),
- &((pSnd->gainBlock[1 - (pSnd->gcBlkSwitch)]).gBlock[band]),
- &((pSnd->gainBlock[pSnd->gcBlkSwitch]).gBlock[band]));
+ gainCompensateAndOverlap(pSnd->IMDCT_buf, &pSnd->prevFrame[band * 256],
+ &pOut[band * 256],
+ &pSnd->gainBlock[1 - pSnd->gcBlkSwitch].gBlock[band],
+ &pSnd->gainBlock[ pSnd->gcBlkSwitch].gBlock[band]);
}
/* Swap the gain control buffers for the next frame. */
@@ -719,7 +727,8 @@ static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_
* @param databuf the input data
*/
-static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf)
+static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf,
+ float **out_samples)
{
int result, i;
float *p1, *p2, *p3, *p4;
@@ -731,7 +740,7 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf)
/* decode Sound Unit 1 */
init_get_bits(&q->gb,databuf,q->bits_per_frame);
- result = decodeChannelSoundUnit(q,&q->gb, q->pUnits, q->outSamples, 0, JOINT_STEREO);
+ result = decodeChannelSoundUnit(q,&q->gb, q->pUnits, out_samples[0], 0, JOINT_STEREO);
if (result != 0)
return (result);
@@ -753,7 +762,7 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf)
ptr1 = q->decoded_bytes_buffer;
for (i = 4; *ptr1 == 0xF8; i++, ptr1++) {
if (i >= q->bytes_per_frame)
- return -1;
+ return AVERROR_INVALIDDATA;
}
@@ -772,14 +781,14 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf)
}
/* Decode Sound Unit 2. */
- result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[1], &q->outSamples[1024], 1, JOINT_STEREO);
+ result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[1], out_samples[1], 1, JOINT_STEREO);
if (result != 0)
return (result);
/* Reconstruct the channel coefficients. */
- reverseMatrixing(q->outSamples, &q->outSamples[1024], q->matrix_coeff_index_prev, q->matrix_coeff_index_now);
+ reverseMatrixing(out_samples[0], out_samples[1], q->matrix_coeff_index_prev, q->matrix_coeff_index_now);
- channelWeighting(q->outSamples, &q->outSamples[1024], q->weighting_delay);
+ channelWeighting(out_samples[0], out_samples[1], q->weighting_delay);
} else {
/* normal stereo mode or mono */
@@ -787,24 +796,25 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf)
for (i=0 ; i<q->channels ; i++) {
/* Set the bitstream reader at the start of a channel sound unit. */
- init_get_bits(&q->gb, databuf+((i*q->bytes_per_frame)/q->channels), (q->bits_per_frame)/q->channels);
+ init_get_bits(&q->gb,
+ databuf + i * q->bytes_per_frame / q->channels,
+ q->bits_per_frame / q->channels);
- result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[i], &q->outSamples[i*1024], i, q->codingMode);
+ result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[i], out_samples[i], i, q->codingMode);
if (result != 0)
return (result);
}
}
/* Apply the iQMF synthesis filter. */
- p1= q->outSamples;
for (i=0 ; i<q->channels ; i++) {
+ p1 = out_samples[i];
p2= p1+256;
p3= p2+256;
p4= p3+256;
atrac_iqmf (p1, p2, 256, p1, q->pUnits[i].delayBuf1, q->tempBuf);
atrac_iqmf (p4, p3, 256, p3, q->pUnits[i].delayBuf2, q->tempBuf);
atrac_iqmf (p1, p3, 512, p1, q->pUnits[i].delayBuf3, q->tempBuf);
- p1 +=1024;
}
return 0;
@@ -817,22 +827,31 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf)
* @param avctx pointer to the AVCodecContext
*/
-static int atrac3_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt) {
+static int atrac3_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
ATRAC3Context *q = avctx->priv_data;
- int result = 0, i;
+ int result;
const uint8_t* databuf;
- int16_t* samples = data;
+ float *samples_flt;
+ int16_t *samples_s16;
if (buf_size < avctx->block_align) {
av_log(avctx, AV_LOG_ERROR,
"Frame too small (%d bytes). Truncated file?\n", buf_size);
- *data_size = 0;
- return buf_size;
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* get output buffer */
+ q->frame.nb_samples = SAMPLES_PER_FRAME;
+ if ((result = avctx->get_buffer(avctx, &q->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return result;
}
+ samples_flt = (float *)q->frame.data[0];
+ samples_s16 = (int16_t *)q->frame.data[0];
/* Check if we need to descramble and what buffer to pass on. */
if (q->scrambled_stream) {
@@ -842,27 +861,30 @@ static int atrac3_decode_frame(AVCodecContext *avctx,
databuf = buf;
}
- result = decodeFrame(q, databuf);
+ if (q->channels == 1 && avctx->sample_fmt == AV_SAMPLE_FMT_FLT)
+ result = decodeFrame(q, databuf, &samples_flt);
+ else
+ result = decodeFrame(q, databuf, q->outSamples);
if (result != 0) {
av_log(NULL,AV_LOG_ERROR,"Frame decoding error!\n");
- return -1;
+ return result;
}
- if (q->channels == 1) {
- /* mono */
- for (i = 0; i<1024; i++)
- samples[i] = av_clip_int16(round(q->outSamples[i]));
- *data_size = 1024 * sizeof(int16_t);
- } else {
- /* stereo */
- for (i = 0; i < 1024; i++) {
- samples[i*2] = av_clip_int16(round(q->outSamples[i]));
- samples[i*2+1] = av_clip_int16(round(q->outSamples[1024+i]));
- }
- *data_size = 2048 * sizeof(int16_t);
+ /* interleave */
+ if (q->channels == 2 && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
+ q->fmt_conv.float_interleave(samples_flt,
+ (const float **)q->outSamples,
+ SAMPLES_PER_FRAME, 2);
+ } else if (avctx->sample_fmt == AV_SAMPLE_FMT_S16) {
+ q->fmt_conv.float_to_int16_interleave(samples_s16,
+ (const float **)q->outSamples,
+ SAMPLES_PER_FRAME, q->channels);
}
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = q->frame;
+
return avctx->block_align;
}
@@ -875,7 +897,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx,
static av_cold int atrac3_decode_init(AVCodecContext *avctx)
{
- int i;
+ int i, ret;
const uint8_t *edata_ptr = avctx->extradata;
ATRAC3Context *q = avctx->priv_data;
static VLC_TYPE atrac3_vlc_table[4096][2];
@@ -899,7 +921,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
av_log(avctx,AV_LOG_DEBUG,"[12-13] %d\n",bytestream_get_le16(&edata_ptr)); //Unknown always 0
/* setup */
- q->samples_per_frame = 1024 * q->channels;
+ q->samples_per_frame = SAMPLES_PER_FRAME * q->channels;
q->atrac3version = 4;
q->delay = 0x88E;
if (q->codingMode)
@@ -912,7 +934,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
if ((q->bytes_per_frame == 96*q->channels*q->frame_factor) || (q->bytes_per_frame == 152*q->channels*q->frame_factor) || (q->bytes_per_frame == 192*q->channels*q->frame_factor)) {
} else {
av_log(avctx,AV_LOG_ERROR,"Unknown frame/channel/frame_factor configuration %d/%d/%d\n", q->bytes_per_frame, q->channels, q->frame_factor);
- return -1;
+ return AVERROR_INVALIDDATA;
}
} else if (avctx->extradata_size == 10) {
@@ -932,17 +954,17 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
if (q->atrac3version != 4) {
av_log(avctx,AV_LOG_ERROR,"Version %d != 4.\n",q->atrac3version);
- return -1;
+ return AVERROR_INVALIDDATA;
}
- if (q->samples_per_frame != 1024 && q->samples_per_frame != 2048) {
+ if (q->samples_per_frame != SAMPLES_PER_FRAME && q->samples_per_frame != SAMPLES_PER_FRAME*2) {
av_log(avctx,AV_LOG_ERROR,"Unknown amount of samples per frame %d.\n",q->samples_per_frame);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (q->delay != 0x88E) {
av_log(avctx,AV_LOG_ERROR,"Unknown amount of delay %x != 0x88E.\n",q->delay);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (q->codingMode == STEREO) {
@@ -951,17 +973,17 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
av_log(avctx,AV_LOG_DEBUG,"Joint stereo detected.\n");
} else {
av_log(avctx,AV_LOG_ERROR,"Unknown channel coding mode %x!\n",q->codingMode);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (avctx->channels <= 0 || avctx->channels > 2 /*|| ((avctx->channels * 1024) != q->samples_per_frame)*/) {
av_log(avctx,AV_LOG_ERROR,"Channel configuration error!\n");
- return -1;
+ return AVERROR(EINVAL);
}
if(avctx->block_align >= UINT_MAX/2)
- return -1;
+ return AVERROR(EINVAL);
/* Pad the data buffer with FF_INPUT_BUFFER_PADDING_SIZE,
* this is for the bitstream reader. */
@@ -981,7 +1003,16 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
vlcs_initialized = 1;
}
- init_atrac3_transforms(q);
+ if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT)
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ else
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ if ((ret = init_atrac3_transforms(q, avctx->sample_fmt == AV_SAMPLE_FMT_FLT))) {
+ av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
+ av_freep(&q->decoded_bytes_buffer);
+ return ret;
+ }
atrac_generate_tables();
@@ -1007,14 +1038,26 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
}
dsputil_init(&dsp, avctx);
+ ff_fmt_convert_init(&q->fmt_conv, avctx);
q->pUnits = av_mallocz(sizeof(channel_unit)*q->channels);
if (!q->pUnits) {
- av_free(q->decoded_bytes_buffer);
+ atrac3_decode_close(avctx);
return AVERROR(ENOMEM);
}
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ if (avctx->channels > 1 || avctx->sample_fmt == AV_SAMPLE_FMT_S16) {
+ q->outSamples[0] = av_mallocz(SAMPLES_PER_FRAME * avctx->channels * sizeof(*q->outSamples[0]));
+ q->outSamples[1] = q->outSamples[0] + SAMPLES_PER_FRAME;
+ if (!q->outSamples[0]) {
+ atrac3_decode_close(avctx);
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ avcodec_get_frame_defaults(&q->frame);
+ avctx->coded_frame = &q->frame;
+
return 0;
}
@@ -1028,5 +1071,6 @@ AVCodec ff_atrac3_decoder =
.init = atrac3_decode_init,
.close = atrac3_decode_close,
.decode = atrac3_decode_frame,
+ .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"),
};
diff --git a/libavcodec/audioconvert.c b/libavcodec/audioconvert.c
index 4bea308..a244345 100644
--- a/libavcodec/audioconvert.c
+++ b/libavcodec/audioconvert.c
@@ -48,7 +48,7 @@ void avcodec_sample_fmt_string (char *buf, int buf_size, int sample_fmt)
}
#endif
-int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name)
+uint64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name)
{
switch(nb_channels) {
case 1: return AV_CH_LAYOUT_MONO;
diff --git a/libavcodec/audioconvert.h b/libavcodec/audioconvert.h
index e9a78fe..f50eb3e 100644
--- a/libavcodec/audioconvert.h
+++ b/libavcodec/audioconvert.h
@@ -80,7 +80,7 @@ int avcodec_channel_layout_num_channels(int64_t channel_layout);
* @param fmt_name Format name, or NULL if unknown
* @return Channel layout mask
*/
-int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name);
+uint64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name);
struct AVAudioConvert;
typedef struct AVAudioConvert AVAudioConvert;
diff --git a/libavcodec/aura.c b/libavcodec/aura.c
index e85e822..f1fdb5c 100644
--- a/libavcodec/aura.c
+++ b/libavcodec/aura.c
@@ -123,16 +123,14 @@ static av_cold int aura_decode_end(AVCodecContext *avctx)
}
AVCodec ff_aura2_decoder = {
- "aura2",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_AURA2,
- sizeof(AuraDecodeContext),
- aura_decode_init,
- NULL,
- aura_decode_end,
- aura_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "aura2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_AURA2,
+ .priv_data_size = sizeof(AuraDecodeContext),
+ .init = aura_decode_init,
+ .close = aura_decode_end,
+ .decode = aura_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Auravision Aura 2"),
};
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 2dbdc86..4f24f72 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -31,8 +31,42 @@
#include "libavutil/avutil.h"
#include "libavutil/cpu.h"
#include "libavutil/dict.h"
+#include "libavutil/log.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/rational.h"
#include "libavcodec/version.h"
+/**
+ * @defgroup libavc Encoding/Decoding Library
+ * @{
+ *
+ * @defgroup lavc_decoding Decoding
+ * @{
+ * @}
+ *
+ * @defgroup lavc_encoding Encoding
+ * @{
+ * @}
+ *
+ * @defgroup lavc_codec Codecs
+ * @{
+ * @defgroup lavc_codec_native Native Codecs
+ * @{
+ * @}
+ * @defgroup lavc_codec_wrappers External library wrappers
+ * @{
+ * @}
+ * @defgroup lavc_codec_hwaccel Hardware Accelerators bridge
+ * @{
+ * @}
+ * @}
+ * @defgroup lavc_internal Internal
+ * @{
+ * @}
+ * @}
+ *
+ */
+
/**
* Identify the syntax and semantics of the bitstream.
@@ -149,7 +183,9 @@ enum CodecID {
CODEC_ID_TIERTEXSEQVIDEO,
CODEC_ID_TIFF,
CODEC_ID_GIF,
+#if LIBAVCODEC_VERSION_MAJOR == 53
CODEC_ID_FFH264,
+#endif
CODEC_ID_DXA,
CODEC_ID_DNXHD,
CODEC_ID_THP,
@@ -167,8 +203,10 @@ enum CodecID {
CODEC_ID_INDEO5,
CODEC_ID_MIMIC,
CODEC_ID_RL2,
+#if LIBAVCODEC_VERSION_MAJOR == 53
CODEC_ID_8SVX_EXP,
CODEC_ID_8SVX_FIB,
+#endif
CODEC_ID_ESCAPE124,
CODEC_ID_DIRAC,
CODEC_ID_BFI,
@@ -205,9 +243,21 @@ enum CodecID {
CODEC_ID_PRORES,
CODEC_ID_JV,
CODEC_ID_DFA,
+ CODEC_ID_WMV3IMAGE,
+ CODEC_ID_VC1IMAGE,
+#if LIBAVCODEC_VERSION_MAJOR == 53
+ CODEC_ID_G723_1,
+ CODEC_ID_G729,
+#endif
+ CODEC_ID_UTVIDEO,
+ CODEC_ID_BMV_VIDEO,
+ CODEC_ID_VBLE,
+ CODEC_ID_DXTORY,
+ CODEC_ID_V410,
/* various PCM "codecs" */
- CODEC_ID_PCM_S16LE= 0x10000,
+ CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
+ CODEC_ID_PCM_S16LE = 0x10000,
CODEC_ID_PCM_S16BE,
CODEC_ID_PCM_U16LE,
CODEC_ID_PCM_U16BE,
@@ -234,9 +284,10 @@ enum CodecID {
CODEC_ID_PCM_BLURAY,
CODEC_ID_PCM_LXF,
CODEC_ID_S302M,
+ CODEC_ID_PCM_S8_PLANAR,
/* various ADPCM codecs */
- CODEC_ID_ADPCM_IMA_QT= 0x11000,
+ CODEC_ID_ADPCM_IMA_QT = 0x11000,
CODEC_ID_ADPCM_IMA_WAV,
CODEC_ID_ADPCM_IMA_DK3,
CODEC_ID_ADPCM_IMA_DK4,
@@ -267,21 +318,21 @@ enum CodecID {
CODEC_ID_ADPCM_G722,
/* AMR */
- CODEC_ID_AMR_NB= 0x12000,
+ CODEC_ID_AMR_NB = 0x12000,
CODEC_ID_AMR_WB,
/* RealAudio codecs*/
- CODEC_ID_RA_144= 0x13000,
+ CODEC_ID_RA_144 = 0x13000,
CODEC_ID_RA_288,
/* various DPCM codecs */
- CODEC_ID_ROQ_DPCM= 0x14000,
+ CODEC_ID_ROQ_DPCM = 0x14000,
CODEC_ID_INTERPLAY_DPCM,
CODEC_ID_XAN_DPCM,
CODEC_ID_SOL_DPCM,
/* audio codecs */
- CODEC_ID_MP2= 0x15000,
+ CODEC_ID_MP2 = 0x15000,
CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
CODEC_ID_AAC,
CODEC_ID_AC3,
@@ -293,8 +344,10 @@ enum CodecID {
CODEC_ID_MACE3,
CODEC_ID_MACE6,
CODEC_ID_VMDAUDIO,
+#if LIBAVCODEC_VERSION_MAJOR == 53
CODEC_ID_SONIC,
CODEC_ID_SONIC_LS,
+#endif
CODEC_ID_FLAC,
CODEC_ID_MP3ADU,
CODEC_ID_MP3ON4,
@@ -335,9 +388,18 @@ enum CodecID {
CODEC_ID_BINKAUDIO_DCT,
CODEC_ID_AAC_LATM,
CODEC_ID_QDMC,
+ CODEC_ID_CELT,
+#if LIBAVCODEC_VERSION_MAJOR > 53
+ CODEC_ID_G723_1,
+ CODEC_ID_G729,
+ CODEC_ID_8SVX_EXP,
+ CODEC_ID_8SVX_FIB,
+#endif
+ CODEC_ID_BMV_AUDIO,
/* subtitle codecs */
- CODEC_ID_DVD_SUBTITLE= 0x17000,
+ CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.
+ CODEC_ID_DVD_SUBTITLE = 0x17000,
CODEC_ID_DVB_SUBTITLE,
CODEC_ID_TEXT, ///< raw UTF-8 text
CODEC_ID_XSUB,
@@ -348,13 +410,16 @@ enum CodecID {
CODEC_ID_SRT,
/* other specific kind of codecs (generally used for attachments) */
- CODEC_ID_TTF= 0x18000,
+ CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs.
+ 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_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
+ CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS
+ * stream (only used by libavformat) */
+ CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems
* stream (only used by libavformat) */
- CODEC_ID_FFMETADATA=0x21000, ///< Dummy codec for streams containing only metadata information.
+ CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing only metadata information.
};
#if FF_API_OLD_SAMPLE_FMT
@@ -417,8 +482,10 @@ enum CodecID {
#define CH_LAYOUT_STEREO_DOWNMIX AV_CH_LAYOUT_STEREO_DOWNMIX
#endif
+#if FF_API_OLD_DECODE_AUDIO
/* in bytes */
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
+#endif
/**
* Required number of additionally allocated bytes at the end of the input bitstream for decoding.
@@ -520,7 +587,7 @@ enum AVChromaLocation{
/**
* LPC analysis type
*/
-attribute_deprecated enum AVLPCType {
+enum AVLPCType {
AV_LPC_TYPE_DEFAULT = -1, ///< use the codec default LPC type
AV_LPC_TYPE_NONE = 0, ///< do not use LPC prediction or use all zero coefficients
AV_LPC_TYPE_FIXED = 1, ///< fixed LPC coefficients
@@ -562,7 +629,6 @@ typedef struct RcOverride{
#define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC.
#define CODEC_FLAG_GMC 0x0020 ///< Use GMC.
#define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>.
-#define CODEC_FLAG_PART 0x0080 ///< Use data partitioning.
/**
* The parent program guarantees that the input for B-frames containing
* streams is not written to for at least s->max_b_frames+1 frames, if
@@ -571,7 +637,6 @@ typedef struct RcOverride{
#define CODEC_FLAG_INPUT_PRESERVED 0x0100
#define CODEC_FLAG_PASS1 0x0200 ///< Use internal 2pass ratecontrol in first pass mode.
#define CODEC_FLAG_PASS2 0x0400 ///< Use internal 2pass ratecontrol in second pass mode.
-#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< Use external Huffman table (for MJPEG).
#define CODEC_FLAG_GRAY 0x2000 ///< Only decode/encode grayscale.
#define CODEC_FLAG_EMU_EDGE 0x4000 ///< Don't draw edges.
#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding.
@@ -580,25 +645,42 @@ typedef struct RcOverride{
#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< Normalize adaptive quantization.
#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< Use interlaced DCT.
#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< Force low delay.
-#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< Use alternate scan.
#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< Place global headers in extradata instead of every keyframe.
#define CODEC_FLAG_BITEXACT 0x00800000 ///< Use only bitexact stuff (except (I)DCT).
/* Fx : Flag for h263+ extra options */
#define CODEC_FLAG_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction
-#define CODEC_FLAG_H263P_UMV 0x02000000 ///< unlimited motion vector
#define CODEC_FLAG_CBP_RD 0x04000000 ///< Use rate distortion optimization for cbp.
#define CODEC_FLAG_QP_RD 0x08000000 ///< Use rate distortion optimization for qp selectioon.
-#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H.263 alternative inter VLC
-#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC
#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter
-#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000
#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation
-#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< Will reserve space for SVCD scan offset user data.
#define CODEC_FLAG_CLOSED_GOP 0x80000000
#define CODEC_FLAG2_FAST 0x00000001 ///< Allow non spec compliant speedup tricks.
#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< Strictly enforce GOP size.
#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< Skip bitstream encoding.
#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< Place global headers at every keyframe instead of in extradata.
+#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping
+#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
+/**
+ * @defgroup deprecated_flags Deprecated codec flags
+ * Use corresponding private codec options instead.
+ * @{
+ */
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC
+#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H.263 alternative inter VLC
+#define CODEC_FLAG_PART 0x0080 ///< Use data partitioning.
+#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< Use alternate scan.
+#define CODEC_FLAG_H263P_UMV 0x02000000 ///< unlimited motion vector
+#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000
+#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< Will reserve space for SVCD scan offset user data.
+#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table.
+#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format.
+#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer.
+#endif
+#if FF_API_MJPEG_GLOBAL_OPTS
+#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< Use external Huffman table (for MJPEG).
+#endif
+#if FF_API_X264_GLOBAL_OPTS
#define CODEC_FLAG2_BPYRAMID 0x00000010 ///< H.264 allow B-frames to be used as references.
#define CODEC_FLAG2_WPRED 0x00000020 ///< H.264 weighted biprediction for B-frames
#define CODEC_FLAG2_MIXED_REFS 0x00000040 ///< H.264 one reference per partition, as opposed to one reference per macroblock
@@ -606,17 +688,20 @@ typedef struct RcOverride{
#define CODEC_FLAG2_FASTPSKIP 0x00000100 ///< H.264 fast pskip
#define CODEC_FLAG2_AUD 0x00000200 ///< H.264 access unit delimiters
#define CODEC_FLAG2_BRDO 0x00000400 ///< B-frame rate-distortion optimization
-#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table.
-#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC).
-#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format.
-#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping
-#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
-#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer.
-#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible
#define CODEC_FLAG2_MBTREE 0x00040000 ///< Use macroblock tree ratecontrol (x264 only)
#define CODEC_FLAG2_PSY 0x00080000 ///< Use psycho visual optimizations.
#define CODEC_FLAG2_SSIM 0x00100000 ///< Compute SSIM during encoding, error[] values are undefined.
#define CODEC_FLAG2_INTRA_REFRESH 0x00200000 ///< Use periodic insertion of intra blocks instead of keyframes.
+#endif
+#if FF_API_SNOW_GLOBAL_OPTS
+#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC).
+#endif
+#if FF_API_LAME_GLOBAL_OPTS
+#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible
+#endif
+/**
+ * @}
+ */
/* Unsupported options :
* Syntax Arithmetic coding (SAC)
@@ -632,14 +717,18 @@ typedef struct RcOverride{
* assume the buffer was allocated by avcodec_default_get_buffer.
*/
#define CODEC_CAP_DR1 0x0002
+#if FF_API_PARSE_FRAME
/* If 'parse_only' field is true, then avcodec_parse_frame() can be used. */
#define CODEC_CAP_PARSE_ONLY 0x0004
+#endif
#define CODEC_CAP_TRUNCATED 0x0008
/* Codec can export data for HW decoding (XvMC). */
#define CODEC_CAP_HWACCEL 0x0010
/**
- * Codec has a nonzero delay and needs to be fed with NULL at the end to get the delayed data.
- * If this is not set, the codec is guaranteed to never be fed with NULL data.
+ * Codec has a nonzero delay and needs to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to get the delayed data until the decoder no longer
+ * returns frames. If this is not set, the codec is guaranteed to never be fed
+ * with NULL data.
*/
#define CODEC_CAP_DELAY 0x0020
/**
@@ -684,6 +773,10 @@ typedef struct RcOverride{
* Codec supports slice-based (or partition-based) multithreading.
*/
#define CODEC_CAP_SLICE_THREADS 0x2000
+/**
+ * Codec supports changed parameters at any point.
+ */
+#define CODEC_CAP_PARAM_CHANGE 0x4000
//The following defines may change, don't expect compatibility if you use them.
#define MB_TYPE_INTRA4x4 0x0001
@@ -738,266 +831,6 @@ typedef struct AVPanScan{
int16_t position[3][2];
}AVPanScan;
-#define FF_COMMON_FRAME \
- /**\
- * pointer to the picture planes.\
- * This might be different from the first allocated byte\
- * - encoding: \
- * - decoding: \
- */\
- uint8_t *data[4];\
- int linesize[4];\
- /**\
- * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.\
- * This isn't used by libavcodec unless the default get/release_buffer() is used.\
- * - encoding: \
- * - decoding: \
- */\
- uint8_t *base[4];\
- /**\
- * 1 -> keyframe, 0-> not\
- * - encoding: Set by libavcodec.\
- * - decoding: Set by libavcodec.\
- */\
- int key_frame;\
-\
- /**\
- * Picture type of the frame, see ?_TYPE below.\
- * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\
- * - decoding: Set by libavcodec.\
- */\
- enum AVPictureType pict_type;\
-\
- /**\
- * presentation timestamp in time_base units (time when frame should be shown to user)\
- * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.\
- * - encoding: MUST be set by user.\
- * - decoding: Set by libavcodec.\
- */\
- int64_t pts;\
-\
- /**\
- * picture number in bitstream order\
- * - encoding: set by\
- * - decoding: Set by libavcodec.\
- */\
- int coded_picture_number;\
- /**\
- * picture number in display order\
- * - encoding: set by\
- * - decoding: Set by libavcodec.\
- */\
- int display_picture_number;\
-\
- /**\
- * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \
- * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\
- * - decoding: Set by libavcodec.\
- */\
- int quality; \
-\
- /**\
- * buffer age (1->was last buffer and dint change, 2->..., ...).\
- * Set to INT_MAX if the buffer has not been used yet.\
- * - encoding: unused\
- * - decoding: MUST be set by get_buffer().\
- */\
- int age;\
-\
- /**\
- * is this picture used as reference\
- * The values for this are the same as the MpegEncContext.picture_structure\
- * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.\
- * Set to 4 for delayed, non-reference frames.\
- * - encoding: unused\
- * - decoding: Set by libavcodec. (before get_buffer() call)).\
- */\
- int reference;\
-\
- /**\
- * QP table\
- * - encoding: unused\
- * - decoding: Set by libavcodec.\
- */\
- int8_t *qscale_table;\
- /**\
- * QP store stride\
- * - encoding: unused\
- * - decoding: Set by libavcodec.\
- */\
- int qstride;\
-\
- /**\
- * mbskip_table[mb]>=1 if MB didn't change\
- * stride= mb_width = (width+15)>>4\
- * - encoding: unused\
- * - decoding: Set by libavcodec.\
- */\
- uint8_t *mbskip_table;\
-\
- /**\
- * motion vector table\
- * @code\
- * example:\
- * int mv_sample_log2= 4 - motion_subsample_log2;\
- * int mb_width= (width+15)>>4;\
- * int mv_stride= (mb_width << mv_sample_log2) + 1;\
- * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];\
- * @endcode\
- * - encoding: Set by user.\
- * - decoding: Set by libavcodec.\
- */\
- int16_t (*motion_val[2])[2];\
-\
- /**\
- * macroblock type table\
- * mb_type_base + mb_width + 2\
- * - encoding: Set by user.\
- * - decoding: Set by libavcodec.\
- */\
- uint32_t *mb_type;\
-\
- /**\
- * log2 of the size of the block which a single vector in motion_val represents: \
- * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)\
- * - encoding: unused\
- * - decoding: Set by libavcodec.\
- */\
- uint8_t motion_subsample_log2;\
-\
- /**\
- * for some private data of the user\
- * - encoding: unused\
- * - decoding: Set by user.\
- */\
- void *opaque;\
-\
- /**\
- * error\
- * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.\
- * - decoding: unused\
- */\
- uint64_t error[4];\
-\
- /**\
- * type of the buffer (to keep track of who has to deallocate data[*])\
- * - encoding: Set by the one who allocates it.\
- * - decoding: Set by the one who allocates it.\
- * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.\
- */\
- int type;\
- \
- /**\
- * When decoding, this signals how much the picture must be delayed.\
- * extra_delay = repeat_pict / (2*fps)\
- * - encoding: unused\
- * - decoding: Set by libavcodec.\
- */\
- int repeat_pict;\
- \
- /**\
- * \
- */\
- int qscale_type;\
- \
- /**\
- * The content of the picture is interlaced.\
- * - encoding: Set by user.\
- * - decoding: Set by libavcodec. (default 0)\
- */\
- int interlaced_frame;\
- \
- /**\
- * If the content is interlaced, is top field displayed first.\
- * - encoding: Set by user.\
- * - decoding: Set by libavcodec.\
- */\
- int top_field_first;\
- \
- /**\
- * Pan scan.\
- * - encoding: Set by user.\
- * - decoding: Set by libavcodec.\
- */\
- AVPanScan *pan_scan;\
- \
- /**\
- * Tell user application that palette has changed from previous frame.\
- * - encoding: ??? (no palette-enabled encoder yet)\
- * - decoding: Set by libavcodec. (default 0).\
- */\
- int palette_has_changed;\
- \
- /**\
- * codec suggestion on buffer type if != 0\
- * - encoding: unused\
- * - decoding: Set by libavcodec. (before get_buffer() call)).\
- */\
- int buffer_hints;\
-\
- /**\
- * DCT coefficients\
- * - encoding: unused\
- * - decoding: Set by libavcodec.\
- */\
- short *dct_coeff;\
-\
- /**\
- * motion reference frame index\
- * the order in which these are stored can depend on the codec.\
- * - encoding: Set by user.\
- * - decoding: Set by libavcodec.\
- */\
- int8_t *ref_index[2];\
-\
- /**\
- * reordered opaque 64bit (generally an integer or a double precision float\
- * PTS but can be anything). \
- * The user sets AVCodecContext.reordered_opaque to represent the input at\
- * that time,\
- * the decoder reorders values as needed and sets AVFrame.reordered_opaque\
- * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque \
- * @deprecated in favor of pkt_pts\
- * - encoding: unused\
- * - decoding: Read by user.\
- */\
- int64_t reordered_opaque;\
-\
- /**\
- * hardware accelerator private data (Libav-allocated)\
- * - encoding: unused\
- * - decoding: Set by libavcodec\
- */\
- void *hwaccel_picture_private;\
-\
- /**\
- * reordered pts from the last AVPacket that has been input into the decoder\
- * - encoding: unused\
- * - decoding: Read by user.\
- */\
- int64_t pkt_pts;\
-\
- /**\
- * dts from the last AVPacket that has been input into the decoder\
- * - encoding: unused\
- * - decoding: Read by user.\
- */\
- int64_t pkt_dts;\
-\
- /**\
- * the AVCodecContext which ff_thread_get_buffer() was last called on\
- * - encoding: Set by libavcodec.\
- * - decoding: Set by libavcodec.\
- */\
- struct AVCodecContext *owner;\
-\
- /**\
- * used by multithreading to store frame-specific info\
- * - encoding: Set by libavcodec.\
- * - decoding: Set by libavcodec.\
- */\
- void *thread_opaque;\
-
#define FF_QSCALE_TYPE_MPEG1 0
#define FF_QSCALE_TYPE_MPEG2 1
#define FF_QSCALE_TYPE_H264 2
@@ -1026,6 +859,8 @@ typedef struct AVPanScan{
enum AVPacketSideDataType {
AV_PKT_DATA_PALETTE,
+ AV_PKT_DATA_NEW_EXTRADATA,
+ AV_PKT_DATA_PARAM_CHANGE,
};
typedef struct AVPacket {
@@ -1048,6 +883,9 @@ typedef struct AVPacket {
uint8_t *data;
int size;
int stream_index;
+ /**
+ * A combination of AV_PKT_FLAG values
+ */
int flags;
/**
* Additional packet data that can be provided by the container.
@@ -1088,21 +926,374 @@ typedef struct AVPacket {
*/
int64_t convergence_duration;
} AVPacket;
-#define AV_PKT_FLAG_KEY 0x0001
+#define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe
+#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
+
+/**
+ * An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows:
+ * u32le param_flags
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT)
+ * s32le channel_count
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT)
+ * u64le channel_layout
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE)
+ * s32le sample_rate
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS)
+ * s32le width
+ * s32le height
+ */
+
+enum AVSideDataParamChangeFlags {
+ AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001,
+ AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002,
+ AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004,
+ AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008,
+};
/**
* Audio Video Frame.
- * New fields can be added to the end of FF_COMMON_FRAME with minor version
- * bumps.
- * Removal, reordering and changes to existing fields require a major
- * version bump. No fields should be added into AVFrame before or after
- * FF_COMMON_FRAME!
+ * New fields can be added to the end of AVFRAME with minor version
+ * bumps. Removal, reordering and changes to existing fields require
+ * a major version bump.
* sizeof(AVFrame) must not be used outside libav*.
*/
typedef struct AVFrame {
- FF_COMMON_FRAME
+#if FF_API_DATA_POINTERS
+#define AV_NUM_DATA_POINTERS 4
+#else
+#define AV_NUM_DATA_POINTERS 8
+#endif
+ /**
+ * pointer to the picture/channel planes.
+ * This might be different from the first allocated byte
+ * - encoding: Set by user
+ * - decoding: set by AVCodecContext.get_buffer()
+ */
+ uint8_t *data[AV_NUM_DATA_POINTERS];
+
+ /**
+ * Size, in bytes, of the data for each picture/channel plane.
+ *
+ * For audio, only linesize[0] may be set. For planar audio, each channel
+ * plane must be the same size.
+ *
+ * - encoding: Set by user (video only)
+ * - decoding: set by AVCodecContext.get_buffer()
+ */
+ int linesize[AV_NUM_DATA_POINTERS];
+
+ /**
+ * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.
+ * This isn't used by libavcodec unless the default get/release_buffer() is used.
+ * - encoding:
+ * - decoding:
+ */
+ uint8_t *base[AV_NUM_DATA_POINTERS];
+ /**
+ * 1 -> keyframe, 0-> not
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ int key_frame;
+
+ /**
+ * Picture type of the frame, see ?_TYPE below.
+ * - encoding: Set by libavcodec. for coded_picture (and set by user for input).
+ * - decoding: Set by libavcodec.
+ */
+ enum AVPictureType pict_type;
+
+ /**
+ * presentation timestamp in time_base units (time when frame should be shown to user)
+ * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.
+ * - encoding: MUST be set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int64_t pts;
+
+ /**
+ * picture number in bitstream order
+ * - encoding: set by
+ * - decoding: Set by libavcodec.
+ */
+ int coded_picture_number;
+ /**
+ * picture number in display order
+ * - encoding: set by
+ * - decoding: Set by libavcodec.
+ */
+ int display_picture_number;
+
+ /**
+ * quality (between 1 (good) and FF_LAMBDA_MAX (bad))
+ * - encoding: Set by libavcodec. for coded_picture (and set by user for input).
+ * - decoding: Set by libavcodec.
+ */
+ int quality;
+
+#if FF_API_AVFRAME_AGE
+ /**
+ * @deprecated unused
+ */
+ attribute_deprecated int age;
+#endif
+
+ /**
+ * is this picture used as reference
+ * The values for this are the same as the MpegEncContext.picture_structure
+ * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.
+ * Set to 4 for delayed, non-reference frames.
+ * - encoding: unused
+ * - decoding: Set by libavcodec. (before get_buffer() call)).
+ */
+ int reference;
+
+ /**
+ * QP table
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ int8_t *qscale_table;
+ /**
+ * QP store stride
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ int qstride;
+
+ /**
+ * mbskip_table[mb]>=1 if MB didn't change
+ * stride= mb_width = (width+15)>>4
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ uint8_t *mbskip_table;
+
+ /**
+ * motion vector table
+ * @code
+ * example:
+ * int mv_sample_log2= 4 - motion_subsample_log2;
+ * int mb_width= (width+15)>>4;
+ * int mv_stride= (mb_width << mv_sample_log2) + 1;
+ * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];
+ * @endcode
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int16_t (*motion_val[2])[2];
+
+ /**
+ * macroblock type table
+ * mb_type_base + mb_width + 2
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ uint32_t *mb_type;
+
+ /**
+ * log2 of the size of the block which a single vector in motion_val represents:
+ * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ uint8_t motion_subsample_log2;
+
+ /**
+ * for some private data of the user
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ void *opaque;
+
+ /**
+ * error
+ * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.
+ * - decoding: unused
+ */
+ uint64_t error[AV_NUM_DATA_POINTERS];
+
+ /**
+ * type of the buffer (to keep track of who has to deallocate data[*])
+ * - encoding: Set by the one who allocates it.
+ * - decoding: Set by the one who allocates it.
+ * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.
+ */
+ int type;
+
+ /**
+ * When decoding, this signals how much the picture must be delayed.
+ * extra_delay = repeat_pict / (2*fps)
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ int repeat_pict;
+
+ /**
+ *
+ */
+ int qscale_type;
+
+ /**
+ * The content of the picture is interlaced.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec. (default 0)
+ */
+ int interlaced_frame;
+
+ /**
+ * If the content is interlaced, is top field displayed first.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int top_field_first;
+
+ /**
+ * Pan scan.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ AVPanScan *pan_scan;
+
+ /**
+ * Tell user application that palette has changed from previous frame.
+ * - encoding: ??? (no palette-enabled encoder yet)
+ * - decoding: Set by libavcodec. (default 0).
+ */
+ int palette_has_changed;
+
+ /**
+ * codec suggestion on buffer type if != 0
+ * - encoding: unused
+ * - decoding: Set by libavcodec. (before get_buffer() call)).
+ */
+ int buffer_hints;
+
+ /**
+ * DCT coefficients
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ short *dct_coeff;
+
+ /**
+ * motion reference frame index
+ * the order in which these are stored can depend on the codec.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int8_t *ref_index[2];
+
+ /**
+ * reordered opaque 64bit (generally an integer or a double precision float
+ * PTS but can be anything).
+ * The user sets AVCodecContext.reordered_opaque to represent the input at
+ * that time,
+ * the decoder reorders values as needed and sets AVFrame.reordered_opaque
+ * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque
+ * @deprecated in favor of pkt_pts
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ int64_t reordered_opaque;
+
+ /**
+ * hardware accelerator private data (Libav-allocated)
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ void *hwaccel_picture_private;
+
+ /**
+ * reordered pts from the last AVPacket that has been input into the decoder
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ int64_t pkt_pts;
+
+ /**
+ * dts from the last AVPacket that has been input into the decoder
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ int64_t pkt_dts;
+
+ /**
+ * the AVCodecContext which ff_thread_get_buffer() was last called on
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ struct AVCodecContext *owner;
+
+ /**
+ * used by multithreading to store frame-specific info
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ void *thread_opaque;
+
+ /**
+ * number of audio samples (per channel) described by this frame
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ int nb_samples;
+
+ /**
+ * pointers to the data planes/channels.
+ *
+ * For video, this should simply point to data[].
+ *
+ * For planar audio, each channel has a separate data pointer, and
+ * linesize[0] contains the size of each channel buffer.
+ * For packed audio, there is just one data pointer, and linesize[0]
+ * contains the total size of the buffer for all channels.
+ *
+ * Note: Both data and extended_data will always be set by get_buffer(),
+ * but for planar audio with more channels that can fit in data,
+ * extended_data must be used by the decoder in order to access all
+ * channels.
+ *
+ * encoding: unused
+ * decoding: set by AVCodecContext.get_buffer()
+ */
+ uint8_t **extended_data;
+
+ /**
+ * sample aspect ratio for the video frame, 0/1 if unknown\unspecified
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ AVRational sample_aspect_ratio;
+
+ /**
+ * width and height of the video frame
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ int width, height;
+
+ /**
+ * format of the frame, -1 if unknown or unset
+ * Values correspond to enum PixelFormat for video frames,
+ * enum AVSampleFormat for audio)
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ int format;
} AVFrame;
+struct AVCodecInternal;
+
+enum AVFieldOrder {
+ AV_FIELD_UNKNOWN,
+ AV_FIELD_PROGRESSIVE,
+ AV_FIELD_TT, //< Top coded_first, top displayed first
+ AV_FIELD_BB, //< Bottom coded first, bottom displayed first
+ AV_FIELD_TB, //< Top coded first, bottom displayed first
+ AV_FIELD_BT, //< Bottom coded first, top displayed first
+};
+
/**
* main external API structure.
* New fields can be added to the end with minor version bumps.
@@ -1113,7 +1304,7 @@ typedef struct AVFrame {
typedef struct AVCodecContext {
/**
* information on struct for av_log
- * - set by avcodec_alloc_context
+ * - set by avcodec_alloc_context3
*/
const AVClass *av_class;
/**
@@ -1142,7 +1333,7 @@ typedef struct AVCodecContext {
* Some codecs need additional format info. It is stored here.
* If any muxer uses this then ALL demuxers/parsers AND encoders for the
* specific codec MUST set it correctly otherwise stream copy breaks.
- * In general use of this field by muxers is not recommanded.
+ * In general use of this field by muxers is not recommended.
* - encoding: Set by libavcodec.
* - decoding: Set by libavcodec. (FIXME: Is this OK?)
*/
@@ -1233,7 +1424,7 @@ typedef struct AVCodecContext {
* @param offset offset into the AVFrame.data from which the slice should be read
*/
void (*draw_horiz_band)(struct AVCodecContext *s,
- const AVFrame *src, int offset[4],
+ const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],
int y, int type, int height);
/* audio only */
@@ -1364,7 +1555,7 @@ typedef struct AVCodecContext {
* A demuxer should set this to what is stored in the field used to identify the codec.
* If there are multiple such fields in a container then the demuxer should choose the one
* which maximizes the information about the used codec.
- * If the codec tag field in a container is larger then 32 bits then the demuxer should
+ * If the codec tag field in a container is larger than 32 bits then the demuxer should
* remap the longer ID to 32 bits with a table or other structure. Alternatively a new
* extra_codec_tag + size could be added but for this a clear advantage must be demonstrated
* first.
@@ -1437,29 +1628,73 @@ typedef struct AVCodecContext {
*/
float b_quant_offset;
+#if FF_API_ER
/**
- * Error recognization; higher values will detect more errors but may
+ * Error recognition; higher values will detect more errors but may
* misdetect some more or less valid parts as errors.
* - encoding: unused
* - decoding: Set by user.
*/
- int error_recognition;
+ attribute_deprecated int error_recognition;
#define FF_ER_CAREFUL 1
#define FF_ER_COMPLIANT 2
#define FF_ER_AGGRESSIVE 3
#define FF_ER_VERY_AGGRESSIVE 4
+#define FF_ER_EXPLODE 5
+#endif /* FF_API_ER */
/**
* Called at the beginning of each frame to get a buffer for it.
- * If pic.reference is set then the frame will be read later by libavcodec.
- * avcodec_align_dimensions2() should be used to find the required width and
- * height, as they normally need to be rounded up to the next multiple of 16.
+ *
+ * The function will set AVFrame.data[], AVFrame.linesize[].
+ * AVFrame.extended_data[] must also be set, but it should be the same as
+ * AVFrame.data[] except for planar audio with more channels than can fit
+ * in AVFrame.data[]. In that case, AVFrame.data[] shall still contain as
+ * many data pointers as it can hold.
+ *
* if CODEC_CAP_DR1 is not set then get_buffer() must call
* avcodec_default_get_buffer() instead of providing buffers allocated by
* some other means.
+ *
+ * AVFrame.data[] should be 32- or 16-byte-aligned unless the CPU doesn't
+ * need it. avcodec_default_get_buffer() aligns the output buffer properly,
+ * but if get_buffer() is overridden then alignment considerations should
+ * be taken into account.
+ *
+ * @see avcodec_default_get_buffer()
+ *
+ * Video:
+ *
+ * If pic.reference is set then the frame will be read later by libavcodec.
+ * avcodec_align_dimensions2() should be used to find the required width and
+ * height, as they normally need to be rounded up to the next multiple of 16.
+ *
* If frame multithreading is used and thread_safe_callbacks is set,
- * it may be called from a different thread, but not from more than one at once.
- * Does not need to be reentrant.
+ * it may be called from a different thread, but not from more than one at
+ * once. Does not need to be reentrant.
+ *
+ * @see release_buffer(), reget_buffer()
+ * @see avcodec_align_dimensions2()
+ *
+ * Audio:
+ *
+ * Decoders request a buffer of a particular size by setting
+ * AVFrame.nb_samples prior to calling get_buffer(). The decoder may,
+ * however, utilize only part of the buffer by setting AVFrame.nb_samples
+ * to a smaller value in the output frame.
+ *
+ * Decoders cannot use the buffer after returning from
+ * avcodec_decode_audio4(), so they will not call release_buffer(), as it
+ * is assumed to be released immediately upon return.
+ *
+ * As a convenience, av_samples_get_buffer_size() and
+ * av_samples_fill_arrays() in libavutil may be used by custom get_buffer()
+ * functions to find the required data size and to fill data pointers and
+ * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
+ * since all planes must be the same size.
+ *
+ * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
+ *
* - encoding: unused
* - decoding: Set by libavcodec, user can override.
*/
@@ -1490,9 +1725,15 @@ typedef struct AVCodecContext {
*/
int block_align;
- int parse_only; /* - decoding only: If true, only parsing is done
- (function avcodec_parse_frame()). The frame
- data is returned. Only MPEG codecs support this now. */
+#if FF_API_PARSE_FRAME
+ /**
+ * If true, only parsing is done. The frame data is returned.
+ * Only MPEG audio decoders support this now.
+ * - encoding: unused
+ * - decoding: Set by user
+ */
+ attribute_deprecated int parse_only;
+#endif
/**
* 0-> h263 quant 1-> mpeg quant
@@ -1772,7 +2013,7 @@ typedef struct AVCodecContext {
* - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR.
* - decoding: unused
*/
- uint64_t error[4];
+ uint64_t error[AV_NUM_DATA_POINTERS];
/**
* motion estimation comparison function
@@ -1917,17 +2158,21 @@ typedef struct AVCodecContext {
*/
int color_table_id;
+#if FF_API_INTERNAL_CONTEXT
/**
* internal_buffer count
* Don't touch, used by libavcodec default_get_buffer().
+ * @deprecated this field was moved to an internal context
*/
- int internal_buffer_count;
+ attribute_deprecated int internal_buffer_count;
/**
* internal_buffers
* Don't touch, used by libavcodec default_get_buffer().
+ * @deprecated this field was moved to an internal context
*/
- void *internal_buffer;
+ attribute_deprecated void *internal_buffer;
+#endif
/**
* Global quality for codecs which cannot change it per frame.
@@ -2233,6 +2478,23 @@ typedef struct AVCodecContext {
#define FF_PROFILE_VC1_COMPLEX 2
#define FF_PROFILE_VC1_ADVANCED 3
+#define FF_PROFILE_MPEG4_SIMPLE 0
+#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1
+#define FF_PROFILE_MPEG4_CORE 2
+#define FF_PROFILE_MPEG4_MAIN 3
+#define FF_PROFILE_MPEG4_N_BIT 4
+#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5
+#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6
+#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7
+#define FF_PROFILE_MPEG4_HYBRID 8
+#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9
+#define FF_PROFILE_MPEG4_CORE_SCALABLE 10
+#define FF_PROFILE_MPEG4_ADVANCED_CODING 11
+#define FF_PROFILE_MPEG4_ADVANCED_CORE 12
+#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13
+#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14
+#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15
+
/**
* level
* - encoding: Set by user.
@@ -2249,8 +2511,7 @@ typedef struct AVCodecContext {
int lowres;
/**
- * Bitstream width / height, may be different from width/height if lowres
- * or other things are used.
+ * Bitstream width / height, may be different from width/height if lowres enabled.
* - encoding: unused
* - decoding: Set by user before init if known. Codec should override / dynamically change if needed.
*/
@@ -2348,19 +2609,23 @@ typedef struct AVCodecContext {
*/
int brd_scale;
+#if FF_API_X264_GLOBAL_OPTS
/**
* constant rate factor - quality-based VBR - values ~correspond to qps
* - encoding: Set by user.
* - decoding: unused
+ * @deprecated use 'crf' libx264 private option
*/
- float crf;
+ attribute_deprecated float crf;
/**
* constant quantization parameter rate control method
* - encoding: Set by user.
* - decoding: unused
+ * @deprecated use 'cqp' libx264 private option
*/
- int cqp;
+ attribute_deprecated int cqp;
+#endif
/**
* minimum GOP size
@@ -2383,12 +2648,14 @@ typedef struct AVCodecContext {
*/
int chromaoffset;
+#if FF_API_X264_GLOBAL_OPTS
/**
- * Influences how often B-frames are used.
+ * Influence how often B-frames are used.
* - encoding: Set by user.
* - decoding: unused
*/
- int bframebias;
+ attribute_deprecated int bframebias;
+#endif
/**
* trellis RD quantization
@@ -2397,12 +2664,13 @@ typedef struct AVCodecContext {
*/
int trellis;
+#if FF_API_X264_GLOBAL_OPTS
/**
* Reduce fluctuations in qp (before curve compression).
* - encoding: Set by user.
* - decoding: unused
*/
- float complexityblur;
+ attribute_deprecated float complexityblur;
/**
* in-loop deblocking filter alphac0 parameter
@@ -2410,7 +2678,7 @@ typedef struct AVCodecContext {
* - encoding: Set by user.
* - decoding: unused
*/
- int deblockalpha;
+ attribute_deprecated int deblockalpha;
/**
* in-loop deblocking filter beta parameter
@@ -2418,14 +2686,14 @@ typedef struct AVCodecContext {
* - encoding: Set by user.
* - decoding: unused
*/
- int deblockbeta;
+ attribute_deprecated int deblockbeta;
/**
* macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4
* - encoding: Set by user.
* - decoding: unused
*/
- int partitions;
+ attribute_deprecated int partitions;
#define X264_PART_I4X4 0x001 /* Analyze i4x4 */
#define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */
#define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */
@@ -2437,7 +2705,8 @@ typedef struct AVCodecContext {
* - encoding: Set by user.
* - decoding: unused
*/
- int directpred;
+ attribute_deprecated int directpred;
+#endif
/**
* Audio cutoff bandwidth (0 means "automatic")
@@ -2462,7 +2731,7 @@ typedef struct AVCodecContext {
int mv0_threshold;
/**
- * Adjusts sensitivity of b_frame_strategy 1.
+ * Adjust sensitivity of b_frame_strategy 1.
* - encoding: Set by user.
* - decoding: unused
*/
@@ -2541,13 +2810,16 @@ typedef struct AVCodecContext {
int request_channels;
#endif
+#if FF_API_DRC_SCALE
/**
* Percentage of dynamic range compression to be applied by the decoder.
* The default value is 1.0, corresponding to full compression.
* - encoding: unused
* - decoding: Set by user.
+ * @deprecated use AC3 decoder private option instead.
*/
- float drc_scale;
+ attribute_deprecated float drc_scale;
+#endif
/**
* opaque 64bit number (generally a PTS) that will be reordered and
@@ -2570,14 +2842,14 @@ typedef struct AVCodecContext {
* - encoding: set by user.
* - decoding: set by libavcodec.
*/
- int64_t channel_layout;
+ uint64_t channel_layout;
/**
* Request decoder to use this channel layout if it can (0 for default)
* - encoding: unused
* - decoding: Set by user.
*/
- int64_t request_channel_layout;
+ uint64_t request_channel_layout;
/**
* Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow.
@@ -2676,6 +2948,7 @@ typedef struct AVCodecContext {
*/
int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
+#if FF_API_X264_GLOBAL_OPTS
/**
* explicit P-frame weighted prediction analysis method
* 0: off
@@ -2684,7 +2957,7 @@ typedef struct AVCodecContext {
* - encoding: Set by user.
* - decoding: unused
*/
- int weighted_p_pred;
+ attribute_deprecated int weighted_p_pred;
/**
* AQ mode
@@ -2694,7 +2967,7 @@ typedef struct AVCodecContext {
* - encoding: Set by user
* - decoding: unused
*/
- int aq_mode;
+ attribute_deprecated int aq_mode;
/**
* AQ strength
@@ -2702,7 +2975,7 @@ typedef struct AVCodecContext {
* - encoding: Set by user
* - decoding: unused
*/
- float aq_strength;
+ attribute_deprecated float aq_strength;
/**
* PSY RD
@@ -2710,7 +2983,7 @@ typedef struct AVCodecContext {
* - encoding: Set by user
* - decoding: unused
*/
- float psy_rd;
+ attribute_deprecated float psy_rd;
/**
* PSY trellis
@@ -2718,7 +2991,7 @@ typedef struct AVCodecContext {
* - encoding: Set by user
* - decoding: unused
*/
- float psy_trellis;
+ attribute_deprecated float psy_trellis;
/**
* RC lookahead
@@ -2726,7 +2999,7 @@ typedef struct AVCodecContext {
* - encoding: Set by user
* - decoding: unused
*/
- int rc_lookahead;
+ attribute_deprecated int rc_lookahead;
/**
* Constant rate factor maximum
@@ -2735,13 +3008,14 @@ typedef struct AVCodecContext {
* - encoding: Set by user.
* - decoding: unused
*/
- float crf_max;
+ attribute_deprecated float crf_max;
+#endif
int log_level_offset;
#if FF_API_FLAC_GLOBAL_OPTS
/**
- * Determines which LPC analysis algorithm to use.
+ * Determine which LPC analysis algorithm to use.
* - encoding: Set by user
* - decoding: unused
*/
@@ -2769,8 +3043,8 @@ typedef struct AVCodecContext {
* For SUBTITLE_ASS subtitle type, it should contain the whole ASS
* [Script Info] and [V4+ Styles] section, plus the [Events] line and
* the Format line following. It shouldn't include any Dialogue line.
- * - encoding: Set/allocated/freed by user (before avcodec_open())
- * - decoding: Set/allocated/freed by libavcodec (by avcodec_open())
+ * - encoding: Set/allocated/freed by user (before avcodec_open2())
+ * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2())
*/
uint8_t *subtitle_header;
int subtitle_header_size;
@@ -2784,14 +3058,18 @@ typedef struct AVCodecContext {
*/
AVPacket *pkt;
+#if FF_API_INTERNAL_CONTEXT
/**
* Whether this is a copy of the context which had init() called on it.
* This is used by multithreading - shared tables and picture pointers
* should be freed from the original context only.
* - encoding: Set by libavcodec.
* - decoding: Set by libavcodec.
+ *
+ * @deprecated this field has been moved to an internal context
*/
- int is_copy;
+ attribute_deprecated int is_copy;
+#endif
/**
* Which multithreading methods to use.
@@ -2802,8 +3080,8 @@ typedef struct AVCodecContext {
* - decoding: Set by user, otherwise the default is used.
*/
int thread_type;
-#define FF_THREAD_FRAME 1 //< Decode more than one frame at once
-#define FF_THREAD_SLICE 2 //< Decode more than one part of a single frame at once
+#define FF_THREAD_FRAME 1 ///< Decode more than one frame at once
+#define FF_THREAD_SLICE 2 ///< Decode more than one part of a single frame at once
/**
* Which multithreading methods are in use by the codec.
@@ -2843,6 +3121,31 @@ typedef struct AVCodecContext {
* - decoding: Set by user.
*/
enum AVSampleFormat request_sample_fmt;
+
+ /**
+ * Error recognition; may misdetect some more or less valid parts as errors.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int err_recognition;
+#define AV_EF_CRCCHECK (1<<0)
+#define AV_EF_BITSTREAM (1<<1)
+#define AV_EF_BUFFER (1<<2)
+#define AV_EF_EXPLODE (1<<3)
+
+ /**
+ * Private context used for internal data.
+ *
+ * Unlike priv_data, this is not codec-specific. It is used in general
+ * libavcodec functions.
+ */
+ struct AVCodecInternal *internal;
+
+ /** Field order
+ * - encoding: set by libavcodec
+ * - decoding: Set by libavcodec
+ */
+ enum AVFieldOrder field_order;
} AVCodecContext;
/**
@@ -2853,6 +3156,8 @@ typedef struct AVProfile {
const char *name; ///< short name for the profile
} AVProfile;
+typedef struct AVCodecDefault AVCodecDefault;
+
/**
* AVCodec.
*/
@@ -2891,7 +3196,7 @@ typedef struct AVCodec {
const char *long_name;
const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
- const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
+ const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
uint8_t max_lowres; ///< maximum value for lowres supported by the decoder
const AVClass *priv_class; ///< AVClass for the private context
const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}
@@ -2915,6 +3220,16 @@ typedef struct AVCodec {
*/
int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src);
/** @} */
+
+ /**
+ * Private codec-specific defaults.
+ */
+ const AVCodecDefault *defaults;
+
+ /**
+ * Initialize codec static data, called from avcodec_register().
+ */
+ void (*init_static_data)(struct AVCodec *codec);
} AVCodec;
/**
@@ -3012,10 +3327,12 @@ typedef struct AVHWAccel {
* the last component is alpha
*/
typedef struct AVPicture {
- uint8_t *data[4];
- int linesize[4]; ///< number of bytes per line
+ uint8_t *data[AV_NUM_DATA_POINTERS];
+ int linesize[AV_NUM_DATA_POINTERS]; ///< number of bytes per line
} AVPicture;
+#define AVPALETTE_SIZE 1024
+#define AVPALETTE_COUNT 256
#if FF_API_PALETTE_CONTROL
/**
* AVPaletteControl
@@ -3025,8 +3342,6 @@ typedef struct AVPicture {
* @deprecated Use AVPacket to send palette changes instead.
* This is totally broken.
*/
-#define AVPALETTE_SIZE 1024
-#define AVPALETTE_COUNT 256
typedef struct AVPaletteControl {
/* Demuxer sets this to 1 to indicate the palette has changed;
@@ -3194,7 +3509,7 @@ typedef struct ReSampleContext ReSampleContext;
* @param linear if 1 then the used FIR filter will be linearly interpolated
between the 2 closest, if 0 the closest will be used
* @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate
- * @return allocated ReSampleContext, NULL if error occured
+ * @return allocated ReSampleContext, NULL if error occurred
*/
ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
int output_rate, int input_rate,
@@ -3255,7 +3570,7 @@ void av_resample_close(struct AVResampleContext *c);
/**
* Allocate memory for a picture. Call avpicture_free() to free it.
*
- * \see avpicture_fill()
+ * @see avpicture_fill()
*
* @param picture the picture to be filled in
* @param pix_fmt the format of the picture
@@ -3302,7 +3617,7 @@ int avpicture_fill(AVPicture *picture, uint8_t *ptr,
* The data is stored compactly, without any gaps for alignment or padding
* which may be applied by avpicture_fill().
*
- * \see avpicture_get_size()
+ * @see avpicture_get_size()
*
* @param[in] src AVPicture containing image data
* @param[in] pix_fmt The format in which the picture data is stored.
@@ -3408,6 +3723,7 @@ int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_
enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
int has_alpha, int *loss_ptr);
+#if FF_API_GET_ALPHA_INFO
#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */
#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */
@@ -3415,8 +3731,10 @@ enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelForma
* Tell if an image really has transparent alpha values.
* @return ored mask of FF_ALPHA_xxx constants
*/
+attribute_deprecated
int img_get_alpha_info(const AVPicture *src,
enum PixelFormat pix_fmt, int width, int height);
+#endif
/* deinterlace a picture */
/* deinterlace - if not supported return -1 */
@@ -3447,21 +3765,22 @@ const char *avcodec_configuration(void);
*/
const char *avcodec_license(void);
+#if FF_API_AVCODEC_INIT
/**
- * Initialize libavcodec.
- * If called more than once, does nothing.
- *
- * @warning This function must be called before any other libavcodec
- * function.
- *
- * @warning This function is not thread-safe.
+ * @deprecated this function is called automatically from avcodec_register()
+ * and avcodec_register_all(), there is no need to call it manually
*/
+attribute_deprecated
void avcodec_init(void);
+#endif
/**
* Register the codec codec and initialize libavcodec.
*
- * @see avcodec_init(), avcodec_register_all()
+ * @warning either this function or avcodec_register_all() must be called
+ * before any other libavcodec functions.
+ *
+ * @see avcodec_register_all()
*/
void avcodec_register(AVCodec *codec);
@@ -3507,46 +3826,73 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode);
*/
const char *av_get_profile_name(const AVCodec *codec, int profile);
+#if FF_API_ALLOC_CONTEXT
/**
* Set the fields of the given AVCodecContext to default values.
*
* @param s The AVCodecContext of which the fields should be set to default values.
+ * @deprecated use avcodec_get_context_defaults3
*/
+attribute_deprecated
void avcodec_get_context_defaults(AVCodecContext *s);
/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
* we WILL change its arguments and name a few times! */
+attribute_deprecated
void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType);
+#endif
-/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
- * we WILL change its arguments and name a few times! */
+/**
+ * Set the fields of the given AVCodecContext to default values corresponding
+ * to the given codec (defaults may be codec-dependent).
+ *
+ * Do not call this function if a non-NULL codec has been passed
+ * to avcodec_alloc_context3() that allocated this AVCodecContext.
+ * If codec is non-NULL, it is illegal to call avcodec_open2() with a
+ * different codec on this AVCodecContext.
+ */
int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec);
+#if FF_API_ALLOC_CONTEXT
/**
* Allocate an AVCodecContext and set its fields to default values. The
* resulting struct can be deallocated by simply calling av_free().
*
* @return An AVCodecContext filled with default values or NULL on failure.
* @see avcodec_get_context_defaults
+ *
+ * @deprecated use avcodec_alloc_context3()
*/
+attribute_deprecated
AVCodecContext *avcodec_alloc_context(void);
/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
* we WILL change its arguments and name a few times! */
+attribute_deprecated
AVCodecContext *avcodec_alloc_context2(enum AVMediaType);
+#endif
-/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
- * we WILL change its arguments and name a few times! */
+/**
+ * Allocate an AVCodecContext and set its fields to default values. The
+ * resulting struct can be deallocated by simply calling av_free().
+ *
+ * @param codec if non-NULL, allocate private data and initialize defaults
+ * for the given codec. It is illegal to then call avcodec_open2()
+ * with a different codec.
+ *
+ * @return An AVCodecContext filled with default values or NULL on failure.
+ * @see avcodec_get_context_defaults
+ */
AVCodecContext *avcodec_alloc_context3(AVCodec *codec);
/**
* Copy the settings of the source AVCodecContext into the destination
* AVCodecContext. The resulting destination codec context will be
- * unopened, i.e. you are required to call avcodec_open() before you
+ * unopened, i.e. you are required to call avcodec_open2() before you
* can use this AVCodecContext to decode/encode video/audio data.
*
* @param dest target codec context, should be initialized with
- * avcodec_alloc_context(), but otherwise uninitialized
+ * avcodec_alloc_context3(), but otherwise uninitialized
* @param src source codec context
* @return AVERROR() on error (e.g. memory allocation error), 0 on success
*/
@@ -3600,13 +3946,13 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
* according to avcodec_get_edge_width() before.
*/
void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
- int linesize_align[4]);
+ int linesize_align[AV_NUM_DATA_POINTERS]);
enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt);
#if FF_API_THREAD_INIT
/**
- * @deprecated Set s->thread_count before calling avcodec_open() instead of calling this.
+ * @deprecated Set s->thread_count before calling avcodec_open2() instead of calling this.
*/
attribute_deprecated
int avcodec_thread_init(AVCodecContext *s, int thread_count);
@@ -3633,7 +3979,7 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2,
* if (!codec)
* exit(1);
*
- * context = avcodec_alloc_context();
+ * context = avcodec_alloc_context3(codec);
*
* if (avcodec_open(context, codec) < 0)
* exit(1);
@@ -3642,7 +3988,7 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2,
* @param avctx The context which will be set up to use the given codec.
* @param codec The codec to use within the context.
* @return zero on success, a negative value on error
- * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder, avcodec_close
+ * @see avcodec_alloc_context3, avcodec_find_decoder, avcodec_find_encoder, avcodec_close
*
* @deprecated use avcodec_open2
*/
@@ -3652,7 +3998,7 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
/**
* Initialize the AVCodecContext to use the given AVCodec. Prior to using this
- * function the context has to be allocated with avcodec_alloc_context().
+ * function the context has to be allocated with avcodec_alloc_context3().
*
* The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
* avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
@@ -3667,9 +4013,9 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
* if (!codec)
* exit(1);
*
- * context = avcodec_alloc_context();
+ * context = avcodec_alloc_context3(codec);
*
- * if (avcodec_open(context, codec, opts) < 0)
+ * if (avcodec_open2(context, codec, opts) < 0)
* exit(1);
* @endcode
*
@@ -3683,7 +4029,12 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
*/
int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options);
+#if FF_API_OLD_DECODE_AUDIO
/**
+ * Wrapper function which calls avcodec_decode_audio4.
+ *
+ * @deprecated Use avcodec_decode_audio4 instead.
+ *
* Decode the audio frame of size avpkt->size from avpkt->data into samples.
* Some decoders may support multiple frames in a single AVPacket, such
* decoders would then just decode the first frame. In this case,
@@ -3712,8 +4063,14 @@ int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
* samples should be 16 byte aligned unless the CPU doesn't need it
* (AltiVec and SSE do).
*
+ * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay
+ * between input and output, these need to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to return the remaining frames.
+ *
* @param avctx the codec context
* @param[out] samples the output buffer, sample type in avctx->sample_fmt
+ * If the sample format is planar, each channel plane will
+ * be the same size, with no padding between channels.
* @param[in,out] frame_size_ptr the output buffer size in bytes
* @param[in] avpkt The input AVPacket containing the input buffer.
* You can create such packet with av_init_packet() and by then setting
@@ -3722,9 +4079,46 @@ int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
* @return On error a negative value is returned, otherwise the number of bytes
* used or zero if no frame data was decompressed (used) from the input AVPacket.
*/
-int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
+attribute_deprecated int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
int *frame_size_ptr,
AVPacket *avpkt);
+#endif
+
+/**
+ * Decode the audio frame of size avpkt->size from avpkt->data into frame.
+ *
+ * Some decoders may support multiple frames in a single AVPacket. Such
+ * decoders would then just decode the first frame. In this case,
+ * avcodec_decode_audio4 has to be called again with an AVPacket containing
+ * the remaining data in order to decode the second frame, etc...
+ * Even if no frames are returned, the packet needs to be fed to the decoder
+ * with remaining data until it is completely consumed or an error occurs.
+ *
+ * @warning The input buffer, avpkt->data must be FF_INPUT_BUFFER_PADDING_SIZE
+ * larger than the actual read bytes because some optimized bitstream
+ * readers read 32 or 64 bits at once and could read over the end.
+ *
+ * @note You might have to align the input buffer. The alignment requirements
+ * depend on the CPU and the decoder.
+ *
+ * @param avctx the codec context
+ * @param[out] frame The AVFrame in which to store decoded audio samples.
+ * Decoders request a buffer of a particular size by setting
+ * AVFrame.nb_samples prior to calling get_buffer(). The
+ * decoder may, however, only utilize part of the buffer by
+ * setting AVFrame.nb_samples to a smaller value in the
+ * output frame.
+ * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is
+ * non-zero.
+ * @param[in] avpkt The input AVPacket containing the input buffer.
+ * At least avpkt->data and avpkt->size should be set. Some
+ * decoders might also require additional fields to be set.
+ * @return A negative error code is returned if an error occurred during
+ * decoding, otherwise the number of bytes consumed from the input
+ * AVPacket is returned.
+ */
+int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame,
+ int *got_frame_ptr, AVPacket *avpkt);
/**
* Decode the video frame of size avpkt->size from avpkt->data into picture.
@@ -3745,8 +4139,9 @@ int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
*
* In practice, avpkt->data should have 4 byte alignment at minimum.
*
- * @note Some codecs have a delay between input and output, these need to be
- * fed with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames.
+ * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay
+ * between input and output, these need to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to return the remaining frames.
*
* @param avctx the codec context
* @param[out] picture The AVFrame in which the decoded video frame will be stored.
@@ -3791,16 +4186,12 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
AVPacket *avpkt);
/**
- * Frees all allocated data in the given subtitle struct.
+ * Free all allocated data in the given subtitle struct.
*
* @param sub AVSubtitle to free.
*/
void avsubtitle_free(AVSubtitle *sub);
-int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata,
- int *data_size_ptr,
- uint8_t *buf, int buf_size);
-
/**
* Encode an audio frame from samples into buf.
*
@@ -3934,7 +4325,7 @@ typedef struct AVCodecParserContext {
int64_t offset; ///< byte offset from starting packet start
int64_t cur_frame_end[AV_PARSER_PTS_NB];
- /*!
+ /**
* Set by parser to 1 for key frames and 0 for non-key frames.
* It is initialized to -1, so if the parser doesn't set this flag,
* old-style fallback using AV_PICTURE_TYPE_I picture type as key frames
@@ -4160,7 +4551,7 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
unsigned int av_xiphlacing(unsigned char *s, unsigned int v);
/**
- * Logs a generic warning message about a missing feature. This function is
+ * Log a generic warning message about a missing feature. This function is
* intended to be used internally by Libav (libavcodec, libavformat, etc.)
* only, and would normally not be used by applications.
* @param[in] avc a pointer to an arbitrary struct of which the first field is
@@ -4181,7 +4572,7 @@ void av_log_missing_feature(void *avc, const char *feature, int want_sample);
* a pointer to an AVClass struct
* @param[in] msg string containing an optional message, or NULL if no message
*/
-void av_log_ask_for_sample(void *avc, const char *msg, ...);
+void av_log_ask_for_sample(void *avc, const char *msg, ...) av_printf_format(2, 3);
/**
* Register the hardware accelerator hwaccel.
@@ -4221,4 +4612,17 @@ enum AVLockOp {
*/
int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op));
+/**
+ * Get the type of the given codec.
+ */
+enum AVMediaType avcodec_get_type(enum CodecID codec_id);
+
+/**
+ * Get the AVClass for AVCodecContext. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avcodec_get_class(void);
+
#endif /* AVCODEC_AVCODEC_H */
diff --git a/libavcodec/avs.c b/libavcodec/avs.c
index 1a5e444..b3cd5b1 100644
--- a/libavcodec/avs.c
+++ b/libavcodec/avs.c
@@ -47,6 +47,7 @@ avs_decode_frame(AVCodecContext * avctx,
void *data, int *data_size, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
+ const uint8_t *buf_end = avpkt->data + avpkt->size;
int buf_size = avpkt->size;
AvsContext *const avs = avctx->priv_data;
AVFrame *picture = data;
@@ -69,6 +70,8 @@ avs_decode_frame(AVCodecContext * avctx,
out = avs->picture.data[0];
stride = avs->picture.linesize[0];
+ if (buf_end - buf < 4)
+ return AVERROR_INVALIDDATA;
sub_type = buf[0];
type = buf[1];
buf += 4;
@@ -79,6 +82,8 @@ avs_decode_frame(AVCodecContext * avctx,
first = AV_RL16(buf);
last = first + AV_RL16(buf + 2);
+ if (first >= 256 || last > 256 || buf_end - buf < 4 + 4 + 3 * (last - first))
+ return AVERROR_INVALIDDATA;
buf += 4;
for (i=first; i<last; i++, buf+=3)
pal[i] = (buf[0] << 18) | (buf[1] << 10) | (buf[2] << 2);
@@ -114,9 +119,13 @@ avs_decode_frame(AVCodecContext * avctx,
return -1;
}
+ if (buf_end - buf < 256 * vect_w * vect_h)
+ return AVERROR_INVALIDDATA;
table = buf + (256 * vect_w * vect_h);
if (sub_type != AVS_I_FRAME) {
int map_size = ((318 / vect_w + 7) / 8) * (198 / vect_h);
+ if (buf_end - table < map_size)
+ return AVERROR_INVALIDDATA;
init_get_bits(&change_map, table, map_size * 8);
table += map_size;
}
@@ -124,6 +133,8 @@ avs_decode_frame(AVCodecContext * avctx,
for (y=0; y<198; y+=vect_h) {
for (x=0; x<318; x+=vect_w) {
if (sub_type == AVS_I_FRAME || get_bits1(&change_map)) {
+ if (buf_end - table < 1)
+ return AVERROR_INVALIDDATA;
vect = &buf[*table++ * (vect_w * vect_h)];
for (j=0; j<vect_w; j++) {
out[(y + 0) * stride + x + j] = vect[(0 * vect_w) + j];
@@ -150,15 +161,23 @@ static av_cold int avs_decode_init(AVCodecContext * avctx)
return 0;
}
+static av_cold int avs_decode_end(AVCodecContext *avctx)
+{
+ AvsContext *s = avctx->priv_data;
+ if (s->picture.data[0])
+ avctx->release_buffer(avctx, &s->picture);
+ return 0;
+}
+
+
AVCodec ff_avs_decoder = {
- "avs",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_AVS,
- sizeof(AvsContext),
- avs_decode_init,
- NULL,
- NULL,
- avs_decode_frame,
- CODEC_CAP_DR1,
+ .name = "avs",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_AVS,
+ .priv_data_size = sizeof(AvsContext),
+ .init = avs_decode_init,
+ .decode = avs_decode_frame,
+ .close = avs_decode_end,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"),
};
diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c
index d294bbf..f4020d6 100644
--- a/libavcodec/bethsoftvideo.c
+++ b/libavcodec/bethsoftvideo.c
@@ -23,8 +23,8 @@
* @file
* @brief Bethesda Softworks VID Video Decoder
* @author Nicholas Tung [ntung (at. ntung com] (2007-03)
- * @sa http://wiki.multimedia.cx/index.php?title=Bethsoft_VID
- * @sa http://www.svatopluk.com/andux/docs/dfvid.html
+ * @see http://wiki.multimedia.cx/index.php?title=Bethsoft_VID
+ * @see http://www.svatopluk.com/andux/docs/dfvid.html
*/
#include "libavutil/common.h"
@@ -46,14 +46,19 @@ static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx)
return 0;
}
-static void set_palette(AVFrame * frame, const uint8_t * palette_buffer)
+static int set_palette(AVFrame * frame, const uint8_t * palette_buffer, int buf_size)
{
uint32_t * palette = (uint32_t *)frame->data[1];
int a;
+
+ if (buf_size < 256*3)
+ return AVERROR_INVALIDDATA;
+
for(a = 0; a < 256; a++){
palette[a] = AV_RB24(&palette_buffer[a * 3]) * 4;
}
frame->palette_has_changed = 1;
+ return 256*3;
}
static int bethsoftvid_decode_frame(AVCodecContext *avctx,
@@ -80,8 +85,7 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
switch(block_type = *buf++){
case PALETTE_BLOCK:
- set_palette(&vid->frame, buf);
- return 0;
+ return set_palette(&vid->frame, buf, buf_size);
case VIDEO_YOFF_P_FRAME:
yoffset = bytestream_get_le16(&buf);
if(yoffset >= avctx->height)
diff --git a/libavcodec/bfi.c b/libavcodec/bfi.c
index c97dfe2..3c66226 100644
--- a/libavcodec/bfi.c
+++ b/libavcodec/bfi.c
@@ -23,7 +23,7 @@
* @file
* @brief Brute Force & Ignorance (.bfi) video decoder
* @author Sisir Koppaka ( sisir.koppaka at gmail dot com )
- * @sa http://wiki.multimedia.cx/index.php?title=BFI
+ * @see http://wiki.multimedia.cx/index.php?title=BFI
*/
#include "libavutil/common.h"
diff --git a/libavcodec/bfin/dsputil_bfin.c b/libavcodec/bfin/dsputil_bfin.c
index 0db2d8b..58ec394 100644
--- a/libavcodec/bfin/dsputil_bfin.c
+++ b/libavcodec/bfin/dsputil_bfin.c
@@ -197,14 +197,14 @@ static int bfin_pix_abs8_xy2 (void *c, uint8_t *blk1, uint8_t *blk2, int line_si
void dsputil_init_bfin( DSPContext* c, AVCodecContext *avctx )
{
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
- c->get_pixels = ff_bfin_get_pixels;
c->diff_pixels = ff_bfin_diff_pixels;
c->put_pixels_clamped = ff_bfin_put_pixels_clamped;
c->add_pixels_clamped = ff_bfin_add_pixels_clamped;
if (!high_bit_depth)
+ c->get_pixels = ff_bfin_get_pixels;
c->clear_blocks = bfin_clear_blocks;
c->pix_sum = ff_bfin_pix_sum;
c->pix_norm1 = ff_bfin_pix_norm1;
@@ -253,19 +253,21 @@ void dsputil_init_bfin( DSPContext* c, AVCodecContext *avctx )
/* c->put_no_rnd_pixels_tab[0][3] = ff_bfin_put_pixels16_xy2_nornd; */
}
- if (avctx->dct_algo == FF_DCT_AUTO)
- c->fdct = ff_bfin_fdct;
-
- if (avctx->idct_algo==FF_IDCT_VP3) {
- c->idct_permutation_type = FF_NO_IDCT_PERM;
- c->idct = ff_bfin_vp3_idct;
- c->idct_add = ff_bfin_vp3_idct_add;
- c->idct_put = ff_bfin_vp3_idct_put;
- } else if (avctx->idct_algo == FF_IDCT_AUTO) {
- c->idct_permutation_type = FF_NO_IDCT_PERM;
- c->idct = ff_bfin_idct;
- c->idct_add = bfin_idct_add;
- c->idct_put = bfin_idct_put;
+ if (avctx->bits_per_raw_sample <= 8) {
+ if (avctx->dct_algo == FF_DCT_AUTO)
+ c->fdct = ff_bfin_fdct;
+
+ if (avctx->idct_algo == FF_IDCT_VP3) {
+ c->idct_permutation_type = FF_NO_IDCT_PERM;
+ c->idct = ff_bfin_vp3_idct;
+ c->idct_add = ff_bfin_vp3_idct_add;
+ c->idct_put = ff_bfin_vp3_idct_put;
+ } else if (avctx->idct_algo == FF_IDCT_AUTO) {
+ c->idct_permutation_type = FF_NO_IDCT_PERM;
+ c->idct = ff_bfin_idct;
+ c->idct_add = bfin_idct_add;
+ c->idct_put = bfin_idct_put;
+ }
}
}
diff --git a/libavcodec/bfin/fdct_bfin.S b/libavcodec/bfin/fdct_bfin.S
index 4c32436..47ec381 100644
--- a/libavcodec/bfin/fdct_bfin.S
+++ b/libavcodec/bfin/fdct_bfin.S
@@ -104,14 +104,14 @@ short dct_coef[]
S3,C3,
-----------------------------------------------------------
-FFMPEG conformance testing results
+Libav conformance testing results
-----------------------------------------------------------
dct-test: modified with the following
dct_error("BFINfdct", 0, ff_bfin_fdct, fdct, test);
produces the following output:
-root:/u/ffmpeg/bhead/libavcodec> ./dct-test
-ffmpeg DCT/IDCT test
+libavcodec> ./dct-test
+Libav DCT/IDCT test
2 -131 -6 -48 -36 33 -83 24
34 52 -24 -15 5 92 57 143
@@ -123,8 +123,6 @@ ffmpeg DCT/IDCT test
-17 -63 -15 73 50 -91 159 -14
DCT BFINfdct: err_inf=2 err2=0.16425938 syserr=0.00795000 maxout=2098 blockSumErr=27
DCT BFINfdct: 92.1 kdct/s
-root:/u/ffmpeg/bhead/libavcodec>
-
*/
#include "config.h"
diff --git a/libavcodec/bfin/idct_bfin.S b/libavcodec/bfin/idct_bfin.S
index b3dedd3..36d50a7 100644
--- a/libavcodec/bfin/idct_bfin.S
+++ b/libavcodec/bfin/idct_bfin.S
@@ -32,15 +32,15 @@ Performance :
-----------------------------------------------------------
-FFMPEG conformance testing results
+Libav conformance testing results
-----------------------------------------------------------
dct-test: modified with the following
dct_error("BFINidct", 1, ff_bfin_idct, idct, test);
produces the following output
-root:/u/ffmpeg/bhead/libavcodec> ./dct-test -i
-ffmpeg DCT/IDCT test
+libavcodec> ./dct-test -i
+Libav DCT/IDCT test
8 15 -2 21 24 17 0 10
2 -10 -5 -5 -3 7 -14 -3
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index e085aa5..f38c030 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -24,9 +24,10 @@
#include "avcodec.h"
#include "dsputil.h"
#include "binkdata.h"
+#include "binkdsp.h"
#include "mathops.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
#define BINK_FLAG_ALPHA 0x00100000
@@ -60,8 +61,8 @@ static const int binkb_bundle_signed[BINKB_NB_SRC] = {
0, 0, 0, 1, 1, 0, 1, 0, 0, 0
};
-static uint32_t binkb_intra_quant[16][64];
-static uint32_t binkb_inter_quant[16][64];
+static int32_t binkb_intra_quant[16][64];
+static int32_t binkb_inter_quant[16][64];
/**
* IDs for different data types used in Bink video codec
@@ -109,11 +110,11 @@ typedef struct Bundle {
typedef struct BinkContext {
AVCodecContext *avctx;
DSPContext dsp;
+ BinkDSPContext bdsp;
AVFrame pic, last;
int version; ///< internal Bink file version
int has_alpha;
int swap_planes;
- ScanTable scantable; ///< permutated scantable for DCT coeffs decoding
Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types
Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type
@@ -246,7 +247,7 @@ static void read_tree(GetBitContext *gb, Tree *tree)
tree->syms[i] = get_bits(gb, 4);
tmp1[tree->syms[i]] = 1;
}
- for (i = 0; i < 16; i++)
+ for (i = 0; i < 16 && len < 16 - 1; i++)
if (!tmp1[i])
tree->syms[++len] = i;
} else {
@@ -343,14 +344,14 @@ static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *
memset(b->cur_dec, v, t);
b->cur_dec += t;
} else {
- do {
+ while (b->cur_dec < dec_end) {
v = GET_HUFF(gb, b->tree);
if (v) {
sign = -get_bits1(gb);
v = (v ^ sign) - sign;
}
*b->cur_dec++ = v;
- } while (b->cur_dec < dec_end);
+ }
}
return 0;
}
@@ -374,7 +375,7 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
memset(b->cur_dec, v, t);
b->cur_dec += t;
} else {
- do {
+ while (b->cur_dec < dec_end) {
v = GET_HUFF(gb, b->tree);
if (v < 12) {
last = v;
@@ -382,10 +383,12 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
} else {
int run = bink_rlelens[v - 12];
+ if (dec_end - b->cur_dec < run)
+ return -1;
memset(b->cur_dec, last, run);
b->cur_dec += run;
}
- } while (b->cur_dec < dec_end);
+ }
}
return 0;
}
@@ -455,7 +458,8 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b,
int start_bits, int has_sign)
{
int i, j, len, len2, bsize, sign, v, v2;
- int16_t *dst = (int16_t*)b->cur_dec;
+ int16_t *dst = (int16_t*)b->cur_dec;
+ int16_t *dst_end = (int16_t*)b->data_end;
CHECK_READ_VAL(gb, b, len);
v = get_bits(gb, start_bits - has_sign);
@@ -463,10 +467,14 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b,
sign = -get_bits1(gb);
v = (v ^ sign) - sign;
}
+ if (dst_end - dst < 1)
+ return -1;
*dst++ = v;
len--;
for (i = 0; i < len; i += 8) {
len2 = FFMIN(len - i, 8);
+ if (dst_end - dst < len2)
+ return -1;
bsize = get_bits(gb, 4);
if (bsize) {
for (j = 0; j < len2; j++) {
@@ -534,6 +542,8 @@ static int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num)
int i, len;
CHECK_READ_VAL(gb, b, len);
+ if (b->data_end - b->cur_dec < len * (1 + (bits > 8)))
+ return -1;
if (bits <= 8) {
if (!issigned) {
for (i = 0; i < len; i++)
@@ -580,17 +590,17 @@ static inline int binkb_get_value(BinkContext *c, int bundle_num)
* @param quant_matrices quantization matrices
* @return 0 for success, negative value in other cases
*/
-static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan,
- const uint32_t quant_matrices[16][64], int q)
+static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t *scan,
+ const int32_t quant_matrices[16][64], int q)
{
int coef_list[128];
int mode_list[128];
- int i, t, mask, bits, ccoef, mode, sign;
+ int i, t, bits, ccoef, mode, sign;
int list_start = 64, list_end = 64, list_pos;
int coef_count = 0;
int coef_idx[64];
int quant_idx;
- const uint32_t *quant;
+ const int32_t *quant;
coef_list[list_end] = 4; mode_list[list_end++] = 0;
coef_list[list_end] = 24; mode_list[list_end++] = 0;
@@ -599,8 +609,7 @@ static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *
coef_list[list_end] = 2; mode_list[list_end++] = 3;
coef_list[list_end] = 3; mode_list[list_end++] = 3;
- bits = get_bits(gb, 4) - 1;
- for (mask = 1 << bits; bits >= 0; mask >>= 1, bits--) {
+ for (bits = get_bits(gb, 4) - 1; bits >= 0; bits--) {
list_pos = list_start;
while (list_pos < list_end) {
if (!(mode_list[list_pos] | coef_list[list_pos]) || !get_bits1(gb)) {
@@ -623,11 +632,10 @@ static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *
coef_list[--list_start] = ccoef;
mode_list[ list_start] = 3;
} else {
- int t;
if (!bits) {
t = 1 - (get_bits1(gb) << 1);
} else {
- t = get_bits(gb, bits) | mask;
+ t = get_bits(gb, bits) | 1 << bits;
sign = -get_bits1(gb);
t = (t ^ sign) - sign;
}
@@ -648,7 +656,7 @@ static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *
if (!bits) {
t = 1 - (get_bits1(gb) << 1);
} else {
- t = get_bits(gb, bits) | mask;
+ t = get_bits(gb, bits) | 1 << bits;
sign = -get_bits1(gb);
t = (t ^ sign) - sign;
}
@@ -791,6 +799,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
const uint8_t *scan;
int xoff, yoff;
LOCAL_ALIGNED_16(DCTELEM, block, [64]);
+ LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
int coordmap[64];
int ybias = is_key ? -15 : 0;
int qp;
@@ -845,11 +854,11 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS);
break;
case 2:
- c->dsp.clear_block(block);
- block[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC);
+ memset(dctblock, 0, sizeof(*dctblock) * 64);
+ dctblock[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC);
qp = binkb_get_value(c, BINKB_SRC_INTRA_Q);
- read_dct_coeffs(gb, block, c->scantable.permutated, binkb_intra_quant, qp);
- c->dsp.idct_put(dst, stride, block);
+ read_dct_coeffs(gb, dctblock, bink_scan, binkb_intra_quant, qp);
+ c->bdsp.idct_put(dst, stride, dctblock);
break;
case 3:
xoff = binkb_get_value(c, BINKB_SRC_X_OFF);
@@ -878,11 +887,11 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
} else {
put_pixels8x8_overlapped(dst, ref, stride);
}
- c->dsp.clear_block(block);
- block[0] = binkb_get_value(c, BINKB_SRC_INTER_DC);
+ memset(dctblock, 0, sizeof(*dctblock) * 64);
+ dctblock[0] = binkb_get_value(c, BINKB_SRC_INTER_DC);
qp = binkb_get_value(c, BINKB_SRC_INTER_Q);
- read_dct_coeffs(gb, block, c->scantable.permutated, binkb_inter_quant, qp);
- c->dsp.idct_add(dst, stride, block);
+ read_dct_coeffs(gb, dctblock, bink_scan, binkb_inter_quant, qp);
+ c->bdsp.idct_add(dst, stride, dctblock);
break;
case 5:
v = binkb_get_value(c, BINKB_SRC_COLORS);
@@ -937,6 +946,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
int xoff, yoff;
LOCAL_ALIGNED_16(DCTELEM, block, [64]);
LOCAL_ALIGNED_16(uint8_t, ublock, [64]);
+ LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
int coordmap[64];
const int stride = c->pic.linesize[plane_idx];
@@ -948,8 +958,9 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
for (i = 0; i < BINK_NB_SRC; i++)
read_bundle(gb, c, i);
- ref_start = c->last.data[plane_idx];
- ref_end = c->last.data[plane_idx]
+ ref_start = c->last.data[plane_idx] ? c->last.data[plane_idx]
+ : c->pic.data[plane_idx];
+ ref_end = ref_start
+ (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8;
for (i = 0; i < 64; i++)
@@ -978,7 +989,8 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
if (by == bh)
break;
dst = c->pic.data[plane_idx] + 8*by*stride;
- prev = c->last.data[plane_idx] + 8*by*stride;
+ prev = (c->last.data[plane_idx] ? c->last.data[plane_idx]
+ : c->pic.data[plane_idx]) + 8*by*stride;
for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {
blk = get_value(c, BINK_SRC_BLOCK_TYPES);
// 16x16 block type on odd line means part of the already decoded block, so skip it
@@ -1019,11 +1031,10 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
ublock[*scan++] = get_value(c, BINK_SRC_COLORS);
break;
case INTRA_BLOCK:
- c->dsp.clear_block(block);
- block[0] = get_value(c, BINK_SRC_INTRA_DC);
- read_dct_coeffs(gb, block, c->scantable.permutated, bink_intra_quant, -1);
- c->dsp.idct(block);
- c->dsp.put_pixels_nonclamped(block, ublock, 8);
+ memset(dctblock, 0, sizeof(*dctblock) * 64);
+ dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);
+ read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);
+ c->bdsp.idct_put(ublock, 8, dctblock);
break;
case FILL_BLOCK:
v = get_value(c, BINK_SRC_COLORS);
@@ -1048,7 +1059,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
return -1;
}
if (blk != FILL_BLOCK)
- c->dsp.scale_block(ublock, dst, stride);
+ c->bdsp.scale_block(ublock, dst, stride);
bx++;
dst += 8;
prev += 8;
@@ -1103,10 +1114,10 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
c->dsp.add_pixels8(dst, block, stride);
break;
case INTRA_BLOCK:
- c->dsp.clear_block(block);
- block[0] = get_value(c, BINK_SRC_INTRA_DC);
- read_dct_coeffs(gb, block, c->scantable.permutated, bink_intra_quant, -1);
- c->dsp.idct_put(dst, stride, block);
+ memset(dctblock, 0, sizeof(*dctblock) * 64);
+ dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);
+ read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);
+ c->bdsp.idct_put(dst, stride, dctblock);
break;
case FILL_BLOCK:
v = get_value(c, BINK_SRC_COLORS);
@@ -1117,10 +1128,10 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
yoff = get_value(c, BINK_SRC_Y_OFF);
ref = prev + xoff + yoff * stride;
c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
- c->dsp.clear_block(block);
- block[0] = get_value(c, BINK_SRC_INTER_DC);
- read_dct_coeffs(gb, block, c->scantable.permutated, bink_inter_quant, -1);
- c->dsp.idct_add(dst, stride, block);
+ memset(dctblock, 0, sizeof(*dctblock) * 64);
+ dctblock[0] = get_value(c, BINK_SRC_INTER_DC);
+ read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1);
+ c->bdsp.idct_add(dst, stride, dctblock);
break;
case PATTERN_BLOCK:
for (i = 0; i < 2; i++)
@@ -1288,7 +1299,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
avctx->idct_algo = FF_IDCT_BINK;
dsputil_init(&c->dsp, avctx);
- ff_init_scantable(c->dsp.idct_permutation, &c->scantable, bink_scan);
+ ff_binkdsp_init(&c->bdsp);
init_bundles(c);
@@ -1316,13 +1327,12 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_bink_decoder = {
- "binkvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_BINKVIDEO,
- sizeof(BinkContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
+ .name = "binkvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_BINKVIDEO,
+ .priv_data_size = sizeof(BinkContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Bink video"),
};
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index a05b0b5..d73ffcd 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -29,20 +29,23 @@
*/
#include "avcodec.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
#include "dsputil.h"
#include "dct.h"
#include "rdft.h"
#include "fmtconvert.h"
-#include "libavutil/intfloat_readwrite.h"
+#include "libavutil/intfloat.h"
extern const uint16_t ff_wma_critical_freqs[25];
+static float quant_table[96];
+
#define MAX_CHANNELS 2
#define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11)
typedef struct {
+ AVFrame frame;
GetBitContext gb;
DSPContext dsp;
FmtConvertContext fmt_conv;
@@ -56,8 +59,11 @@ typedef struct {
unsigned int *bands;
float root;
DECLARE_ALIGNED(32, FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE];
- DECLARE_ALIGNED(16, short, previous)[BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block
+ DECLARE_ALIGNED(16, int16_t, previous)[BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block
+ DECLARE_ALIGNED(16, int16_t, current)[BINK_BLOCK_MAX_SIZE / 16];
float *coeffs_ptr[MAX_CHANNELS]; ///< pointers to the coeffs arrays for float_to_int16_interleave
+ float *prev_ptr[MAX_CHANNELS]; ///< pointers to the overlap points in the coeffs array
+ uint8_t *packet_buffer;
union {
RDFTContext rdft;
DCTContext dct;
@@ -90,7 +96,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
return -1;
}
- s->version_b = avctx->codec_tag == MKTAG('B','I','K','b');
+ s->version_b = avctx->extradata && avctx->extradata[3] == 'b';
if (avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) {
// audio is already interleaved for the RDFT format variant
@@ -107,6 +113,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
s->block_size = (s->frame_len - s->overlap_len) * s->channels;
sample_rate_half = (sample_rate + 1) / 2;
s->root = 2.0 / sqrt(s->frame_len);
+ for (i = 0; i < 96; i++) {
+ /* constant is result of 0.066399999/log10(M_E) */
+ quant_table[i] = expf(i * 0.15289164787221953823f) * s->root;
+ }
/* calculate number of bands */
for (s->num_bands = 1; s->num_bands < 25; s->num_bands++)
@@ -126,8 +136,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
s->first = 1;
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- for (i = 0; i < s->channels; i++)
+ for (i = 0; i < s->channels; i++) {
s->coeffs_ptr[i] = s->coeffs + i * s->frame_len;
+ s->prev_ptr[i] = s->coeffs_ptr[i] + s->frame_len - s->overlap_len;
+ }
if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT)
ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R);
@@ -136,6 +148,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
else
return -1;
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
@@ -152,11 +167,18 @@ static const uint8_t rle_length_tab[16] = {
2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64
};
+#define GET_BITS_SAFE(out, nbits) do { \
+ if (get_bits_left(gb) < nbits) \
+ return AVERROR_INVALIDDATA; \
+ out = get_bits(gb, nbits); \
+} while (0)
+
/**
* Decode Bink Audio block
* @param[out] out Output buffer (must contain s->block_size elements)
+ * @return 0 on success, negative error code on failure
*/
-static void decode_block(BinkAudioContext *s, short *out, int use_dct)
+static int decode_block(BinkAudioContext *s, int16_t *out, int use_dct)
{
int ch, i, j, k;
float q, quant[25];
@@ -169,17 +191,22 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct)
for (ch = 0; ch < s->channels; ch++) {
FFTSample *coeffs = s->coeffs_ptr[ch];
if (s->version_b) {
- coeffs[0] = av_int2flt(get_bits(gb, 32)) * s->root;
- coeffs[1] = av_int2flt(get_bits(gb, 32)) * s->root;
+ if (get_bits_left(gb) < 64)
+ return AVERROR_INVALIDDATA;
+ coeffs[0] = av_int2float(get_bits_long(gb, 32)) * s->root;
+ coeffs[1] = av_int2float(get_bits_long(gb, 32)) * s->root;
} else {
+ if (get_bits_left(gb) < 58)
+ return AVERROR_INVALIDDATA;
coeffs[0] = get_float(gb) * s->root;
coeffs[1] = get_float(gb) * s->root;
}
+ if (get_bits_left(gb) < s->num_bands * 8)
+ return AVERROR_INVALIDDATA;
for (i = 0; i < s->num_bands; i++) {
- /* constant is result of 0.066399999/log10(M_E) */
int value = get_bits(gb, 8);
- quant[i] = expf(FFMIN(value, 95) * 0.15289164787221953823f) * s->root;
+ quant[i] = quant_table[FFMIN(value, 95)];
}
k = 0;
@@ -190,15 +217,20 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct)
while (i < s->frame_len) {
if (s->version_b) {
j = i + 16;
- } else if (get_bits1(gb)) {
- j = i + rle_length_tab[get_bits(gb, 4)] * 8;
} else {
- j = i + 8;
+ int v;
+ GET_BITS_SAFE(v, 1);
+ if (v) {
+ GET_BITS_SAFE(v, 4);
+ j = i + rle_length_tab[v] * 8;
+ } else {
+ j = i + 8;
+ }
}
j = FFMIN(j, s->frame_len);
- width = get_bits(gb, 4);
+ GET_BITS_SAFE(width, 4);
if (width == 0) {
memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
i = j;
@@ -208,9 +240,11 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct)
while (i < j) {
if (s->bands[k] == i)
q = quant[k++];
- coeff = get_bits(gb, width);
+ GET_BITS_SAFE(coeff, width);
if (coeff) {
- if (get_bits1(gb))
+ int v;
+ GET_BITS_SAFE(v, 1);
+ if (v)
coeffs[i] = -q * coeff;
else
coeffs[i] = q * coeff;
@@ -231,8 +265,12 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct)
s->trans.rdft.rdft_calc(&s->trans.rdft, coeffs);
}
+ s->fmt_conv.float_to_int16_interleave(s->current,
+ (const float **)s->prev_ptr,
+ s->overlap_len, s->channels);
s->fmt_conv.float_to_int16_interleave(out, (const float **)s->coeffs_ptr,
- s->frame_len, s->channels);
+ s->frame_len - s->overlap_len,
+ s->channels);
if (!s->first) {
int count = s->overlap_len * s->channels;
@@ -242,20 +280,24 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct)
}
}
- memcpy(s->previous, out + s->block_size,
- s->overlap_len * s->channels * sizeof(*out));
+ memcpy(s->previous, s->current,
+ s->overlap_len * s->channels * sizeof(*s->previous));
s->first = 0;
+
+ return 0;
}
static av_cold int decode_end(AVCodecContext *avctx)
{
BinkAudioContext * s = avctx->priv_data;
av_freep(&s->bands);
+ av_freep(&s->packet_buffer);
if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT)
ff_rdft_end(&s->trans.rdft);
else if (CONFIG_BINKAUDIO_DCT_DECODER)
ff_dct_end(&s->trans.dct);
+
return 0;
}
@@ -265,52 +307,77 @@ static void get_bits_align32(GetBitContext *s)
if (n) skip_bits(s, n);
}
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
BinkAudioContext *s = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- short *samples = data;
- short *samples_end = (short*)((uint8_t*)data + *data_size);
- int reported_size;
+ int16_t *samples;
GetBitContext *gb = &s->gb;
+ int ret, consumed = 0;
+
+ if (!get_bits_left(gb)) {
+ uint8_t *buf;
+ /* handle end-of-stream */
+ if (!avpkt->size) {
+ *got_frame_ptr = 0;
+ return 0;
+ }
+ if (avpkt->size < 4) {
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+ buf = av_realloc(s->packet_buffer, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!buf)
+ return AVERROR(ENOMEM);
+ s->packet_buffer = buf;
+ memcpy(s->packet_buffer, avpkt->data, avpkt->size);
+ init_get_bits(gb, s->packet_buffer, avpkt->size * 8);
+ consumed = avpkt->size;
+
+ /* skip reported size */
+ skip_bits_long(gb, 32);
+ }
- init_get_bits(gb, buf, buf_size * 8);
+ /* get output buffer */
+ s->frame.nb_samples = s->block_size / avctx->channels;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (int16_t *)s->frame.data[0];
- reported_size = get_bits_long(gb, 32);
- while (get_bits_count(gb) / 8 < buf_size &&
- samples + s->block_size <= samples_end) {
- decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT);
- samples += s->block_size;
- get_bits_align32(gb);
+ if (decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT)) {
+ av_log(avctx, AV_LOG_ERROR, "Incomplete packet\n");
+ return AVERROR_INVALIDDATA;
}
+ get_bits_align32(gb);
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
- *data_size = FFMIN(reported_size, (uint8_t*)samples - (uint8_t*)data);
- return buf_size;
+ return consumed;
}
AVCodec ff_binkaudio_rdft_decoder = {
- "binkaudio_rdft",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_BINKAUDIO_RDFT,
- sizeof(BinkAudioContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
+ .name = "binkaudio_rdft",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_BINKAUDIO_RDFT,
+ .priv_data_size = sizeof(BinkAudioContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)")
};
AVCodec ff_binkaudio_dct_decoder = {
- "binkaudio_dct",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_BINKAUDIO_DCT,
- sizeof(BinkAudioContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
+ .name = "binkaudio_dct",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_BINKAUDIO_DCT,
+ .priv_data_size = sizeof(BinkAudioContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)")
};
diff --git a/libavcodec/binkdata.h b/libavcodec/binkdata.h
index db289ad..60f0a59 100644
--- a/libavcodec/binkdata.h
+++ b/libavcodec/binkdata.h
@@ -285,7 +285,7 @@ static const uint8_t bink_patterns[16][64] = {
}
};
-static const uint32_t bink_intra_quant[16][64] = {
+static const int32_t bink_intra_quant[16][64] = {
{
0x010000, 0x016315, 0x01E83D, 0x02A535, 0x014E7B, 0x016577, 0x02F1E6, 0x02724C,
0x010000, 0x00EEDA, 0x024102, 0x017F9B, 0x00BE80, 0x00611E, 0x01083C, 0x00A552,
@@ -448,7 +448,7 @@ static const uint32_t bink_intra_quant[16][64] = {
},
};
-static const uint32_t bink_inter_quant[16][64] = {
+static const int32_t bink_inter_quant[16][64] = {
{
0x010000, 0x017946, 0x01A5A9, 0x0248DC, 0x016363, 0x0152A7, 0x0243EC, 0x0209EA,
0x012000, 0x00E248, 0x01BBDA, 0x015CBC, 0x00A486, 0x0053E0, 0x00F036, 0x008095,
diff --git a/libavcodec/binkdsp.c b/libavcodec/binkdsp.c
new file mode 100644
index 0000000..1f7855b
--- /dev/null
+++ b/libavcodec/binkdsp.c
@@ -0,0 +1,136 @@
+/*
+ * Bink DSP routines
+ * Copyright (c) 2009 Kostya Shishkov
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Bink DSP routines
+ */
+
+#include "dsputil.h"
+#include "binkdsp.h"
+
+#define A1 2896 /* (1/sqrt(2))<<12 */
+#define A2 2217
+#define A3 3784
+#define A4 -5352
+
+#define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\
+ const int a0 = (src)[s0] + (src)[s4]; \
+ const int a1 = (src)[s0] - (src)[s4]; \
+ const int a2 = (src)[s2] + (src)[s6]; \
+ const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \
+ const int a4 = (src)[s5] + (src)[s3]; \
+ const int a5 = (src)[s5] - (src)[s3]; \
+ const int a6 = (src)[s1] + (src)[s7]; \
+ const int a7 = (src)[s1] - (src)[s7]; \
+ const int b0 = a4 + a6; \
+ const int b1 = (A3*(a5 + a7)) >> 11; \
+ const int b2 = ((A4*a5) >> 11) - b0 + b1; \
+ const int b3 = (A1*(a6 - a4) >> 11) - b2; \
+ const int b4 = ((A2*a7) >> 11) + b3 - b1; \
+ (dest)[d0] = munge(a0+a2 +b0); \
+ (dest)[d1] = munge(a1+a3-a2+b2); \
+ (dest)[d2] = munge(a1-a3+a2+b3); \
+ (dest)[d3] = munge(a0-a2 -b4); \
+ (dest)[d4] = munge(a0-a2 +b4); \
+ (dest)[d5] = munge(a1-a3+a2-b3); \
+ (dest)[d6] = munge(a1+a3-a2-b2); \
+ (dest)[d7] = munge(a0+a2 -b0); \
+}
+/* end IDCT_TRANSFORM macro */
+
+#define MUNGE_NONE(x) (x)
+#define IDCT_COL(dest,src) IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src)
+
+#define MUNGE_ROW(x) (((x) + 0x7F)>>8)
+#define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src)
+
+static inline void bink_idct_col(int *dest, const int32_t *src)
+{
+ if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {
+ dest[0] =
+ dest[8] =
+ dest[16] =
+ dest[24] =
+ dest[32] =
+ dest[40] =
+ dest[48] =
+ dest[56] = src[0];
+ } else {
+ IDCT_COL(dest, src);
+ }
+}
+
+static void bink_idct_c(int32_t *block)
+{
+ int i;
+ int temp[64];
+
+ for (i = 0; i < 8; i++)
+ bink_idct_col(&temp[i], &block[i]);
+ for (i = 0; i < 8; i++) {
+ IDCT_ROW( (&block[8*i]), (&temp[8*i]) );
+ }
+}
+
+static void bink_idct_add_c(uint8_t *dest, int linesize, int32_t *block)
+{
+ int i, j;
+
+ bink_idct_c(block);
+ for (i = 0; i < 8; i++, dest += linesize, block += 8)
+ for (j = 0; j < 8; j++)
+ dest[j] += block[j];
+}
+
+static void bink_idct_put_c(uint8_t *dest, int linesize, int32_t *block)
+{
+ int i;
+ int temp[64];
+ for (i = 0; i < 8; i++)
+ bink_idct_col(&temp[i], &block[i]);
+ for (i = 0; i < 8; i++) {
+ IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) );
+ }
+}
+
+static void scale_block_c(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize)
+{
+ int i, j;
+ uint16_t *dst1 = (uint16_t *) dst;
+ uint16_t *dst2 = (uint16_t *)(dst + linesize);
+
+ for (j = 0; j < 8; j++) {
+ for (i = 0; i < 8; i++) {
+ dst1[i] = dst2[i] = src[i] * 0x0101;
+ }
+ src += 8;
+ dst1 += linesize;
+ dst2 += linesize;
+ }
+}
+
+void ff_binkdsp_init(BinkDSPContext *c)
+{
+ c->idct_add = bink_idct_add_c;
+ c->idct_put = bink_idct_put_c;
+ c->scale_block = scale_block_c;
+}
diff --git a/libavcodec/binkdsp.h b/libavcodec/binkdsp.h
new file mode 100644
index 0000000..d105f71
--- /dev/null
+++ b/libavcodec/binkdsp.h
@@ -0,0 +1,40 @@
+/*
+ * Bink DSP routines
+ * Copyright (c) 2009 Kostya Shishkov
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Bink DSP routines
+ */
+
+#ifndef AVCODEC_BINKDSP_H
+#define AVCODEC_BINKDSP_H
+
+#include "dsputil.h"
+
+typedef struct BinkDSPContext {
+ void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/);
+ void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/);
+ void (*scale_block)(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize);
+} BinkDSPContext;
+
+void ff_binkdsp_init(BinkDSPContext *c);
+
+#endif /* AVCODEC_BINKDSP_H */
diff --git a/libavcodec/binkidct.c b/libavcodec/binkidct.c
deleted file mode 100644
index 2326a61..0000000
--- a/libavcodec/binkidct.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Bink IDCT algorithm
- * Copyright (c) 2009 Kostya Shishkov
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Bink IDCT algorithm
- */
-
-#include "dsputil.h"
-
-#define A1 2896 /* (1/sqrt(2))<<12 */
-#define A2 2217
-#define A3 3784
-#define A4 -5352
-
-#define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\
- const int a0 = (src)[s0] + (src)[s4]; \
- const int a1 = (src)[s0] - (src)[s4]; \
- const int a2 = (src)[s2] + (src)[s6]; \
- const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \
- const int a4 = (src)[s5] + (src)[s3]; \
- const int a5 = (src)[s5] - (src)[s3]; \
- const int a6 = (src)[s1] + (src)[s7]; \
- const int a7 = (src)[s1] - (src)[s7]; \
- const int b0 = a4 + a6; \
- const int b1 = (A3*(a5 + a7)) >> 11; \
- const int b2 = ((A4*a5) >> 11) - b0 + b1; \
- const int b3 = (A1*(a6 - a4) >> 11) - b2; \
- const int b4 = ((A2*a7) >> 11) + b3 - b1; \
- (dest)[d0] = munge(a0+a2 +b0); \
- (dest)[d1] = munge(a1+a3-a2+b2); \
- (dest)[d2] = munge(a1-a3+a2+b3); \
- (dest)[d3] = munge(a0-a2 -b4); \
- (dest)[d4] = munge(a0-a2 +b4); \
- (dest)[d5] = munge(a1-a3+a2-b3); \
- (dest)[d6] = munge(a1+a3-a2-b2); \
- (dest)[d7] = munge(a0+a2 -b0); \
-}
-/* end IDCT_TRANSFORM macro */
-
-#define MUNGE_NONE(x) (x)
-#define IDCT_COL(dest,src) IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src)
-
-#define MUNGE_ROW(x) (((x) + 0x7F)>>8)
-#define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src)
-
-static inline void bink_idct_col(int *dest, const DCTELEM *src)
-{
- if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {
- dest[0] =
- dest[8] =
- dest[16] =
- dest[24] =
- dest[32] =
- dest[40] =
- dest[48] =
- dest[56] = src[0];
- } else {
- IDCT_COL(dest, src);
- }
-}
-
-void ff_bink_idct_c(DCTELEM *block)
-{
- int i;
- int temp[64];
-
- for (i = 0; i < 8; i++)
- bink_idct_col(&temp[i], &block[i]);
- for (i = 0; i < 8; i++) {
- IDCT_ROW( (&block[8*i]), (&temp[8*i]) );
- }
-}
-
-void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block)
-{
- int i, j;
-
- ff_bink_idct_c(block);
- for (i = 0; i < 8; i++, dest += linesize, block += 8)
- for (j = 0; j < 8; j++)
- dest[j] += block[j];
-}
-
-void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block)
-{
- int i;
- int temp[64];
- for (i = 0; i < 8; i++)
- bink_idct_col(&temp[i], &block[i]);
- for (i = 0; i < 8; i++) {
- IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) );
- }
-}
diff --git a/libavcodec/bit_depth_template.c b/libavcodec/bit_depth_template.c
new file mode 100644
index 0000000..9071ec2
--- /dev/null
+++ b/libavcodec/bit_depth_template.c
@@ -0,0 +1,91 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "dsputil.h"
+
+#ifndef BIT_DEPTH
+#define BIT_DEPTH 8
+#endif
+
+#ifdef AVCODEC_H264_HIGH_DEPTH_H
+# undef pixel
+# undef pixel2
+# undef pixel4
+# undef dctcoef
+# undef INIT_CLIP
+# undef no_rnd_avg_pixel4
+# undef rnd_avg_pixel4
+# undef AV_RN2P
+# undef AV_RN4P
+# undef AV_RN4PA
+# undef AV_WN2P
+# undef AV_WN4P
+# undef AV_WN4PA
+# undef CLIP
+# undef FUNC
+# undef FUNCC
+# undef av_clip_pixel
+# undef PIXEL_SPLAT_X4
+#else
+# define AVCODEC_H264_HIGH_DEPTH_H
+#endif
+
+#if BIT_DEPTH > 8
+# define pixel uint16_t
+# define pixel2 uint32_t
+# define pixel4 uint64_t
+# define dctcoef int32_t
+
+# define INIT_CLIP
+# define no_rnd_avg_pixel4 no_rnd_avg64
+# define rnd_avg_pixel4 rnd_avg64
+# define AV_RN2P AV_RN32
+# define AV_RN4P AV_RN64
+# define AV_RN4PA AV_RN64A
+# define AV_WN2P AV_WN32
+# define AV_WN4P AV_WN64
+# define AV_WN4PA AV_WN64A
+# define PIXEL_SPLAT_X4(x) ((x)*0x0001000100010001ULL)
+
+# define av_clip_pixel(a) av_clip_uintp2(a, BIT_DEPTH)
+# define CLIP(a) av_clip_uintp2(a, BIT_DEPTH)
+#else
+# define pixel uint8_t
+# define pixel2 uint16_t
+# define pixel4 uint32_t
+# define dctcoef int16_t
+
+# define INIT_CLIP uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+# define no_rnd_avg_pixel4 no_rnd_avg32
+# define rnd_avg_pixel4 rnd_avg32
+# define AV_RN2P AV_RN16
+# define AV_RN4P AV_RN32
+# define AV_RN4PA AV_RN32A
+# define AV_WN2P AV_WN16
+# define AV_WN4P AV_WN32
+# define AV_WN4PA AV_WN32A
+# define PIXEL_SPLAT_X4(x) ((x)*0x01010101U)
+
+# define av_clip_pixel(a) av_clip_uint8(a)
+# define CLIP(a) cm[a]
+#endif
+
+#define FUNC3(a, b, c) a ## _ ## b ## c
+#define FUNC2(a, b, c) FUNC3(a, b, c)
+#define FUNC(a) FUNC2(a, BIT_DEPTH,)
+#define FUNCC(a) FUNC2(a, BIT_DEPTH, _c)
diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c
index 17b1c69..14e392f 100644
--- a/libavcodec/bitstream.c
+++ b/libavcodec/bitstream.c
@@ -41,13 +41,9 @@ const uint8_t ff_log2_run[41]={
24,
};
-void align_put_bits(PutBitContext *s)
+void avpriv_align_put_bits(PutBitContext *s)
{
-#ifdef ALT_BITSTREAM_WRITER
- put_bits(s,( - s->index) & 7,0);
-#else
put_bits(s,s->bit_left & 7,0);
-#endif
}
void ff_put_string(PutBitContext *pb, const char *string, int terminate_string)
@@ -60,7 +56,7 @@ void ff_put_string(PutBitContext *pb, const char *string, int terminate_string)
put_bits(pb, 8, 0);
}
-void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
+void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
{
int words= length>>4;
int bits= length&15;
@@ -107,7 +103,7 @@ static int alloc_table(VLC *vlc, int size, int use_static)
vlc->table_size += size;
if (vlc->table_size > vlc->table_allocated) {
if(use_static)
- abort(); //cant do anything, init_vlc() is used with too little memory
+ abort(); // cannot do anything, init_vlc() is used with too little memory
vlc->table_allocated += (1 << vlc->bits);
vlc->table = av_realloc(vlc->table,
sizeof(VLC_TYPE) * 2 * vlc->table_allocated);
diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c
index b7fee13..f438d10 100644
--- a/libavcodec/bmp.c
+++ b/libavcodec/bmp.c
@@ -171,17 +171,15 @@ static int bmp_decode_frame(AVCodecContext *avctx,
else
avctx->pix_fmt = PIX_FMT_GRAY8;
break;
+ case 1:
case 4:
if(hsize - ihsize - 14 > 0){
avctx->pix_fmt = PIX_FMT_PAL8;
}else{
- av_log(avctx, AV_LOG_ERROR, "Unknown palette for 16-colour BMP\n");
+ av_log(avctx, AV_LOG_ERROR, "Unknown palette for %d-colour BMP\n", 1<<depth);
return -1;
}
break;
- case 1:
- avctx->pix_fmt = PIX_FMT_MONOBLACK;
- break;
default:
av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth);
return -1;
@@ -265,6 +263,22 @@ static int bmp_decode_frame(AVCodecContext *avctx,
}else{
switch(depth){
case 1:
+ for (i = 0; i < avctx->height; i++) {
+ int j;
+ for (j = 0; j < n; j++) {
+ ptr[j*8+0] = buf[j] >> 7;
+ ptr[j*8+1] = (buf[j] >> 6) & 1;
+ ptr[j*8+2] = (buf[j] >> 5) & 1;
+ ptr[j*8+3] = (buf[j] >> 4) & 1;
+ ptr[j*8+4] = (buf[j] >> 3) & 1;
+ ptr[j*8+5] = (buf[j] >> 2) & 1;
+ ptr[j*8+6] = (buf[j] >> 1) & 1;
+ ptr[j*8+7] = buf[j] & 1;
+ }
+ buf += n;
+ ptr += linesize;
+ }
+ break;
case 8:
case 24:
for(i = 0; i < avctx->height; i++){
@@ -336,14 +350,13 @@ static av_cold int bmp_decode_end(AVCodecContext *avctx)
}
AVCodec ff_bmp_decoder = {
- "bmp",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_BMP,
- sizeof(BMPContext),
- bmp_decode_init,
- NULL,
- bmp_decode_end,
- bmp_decode_frame,
- CODEC_CAP_DR1,
+ .name = "bmp",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_BMP,
+ .priv_data_size = sizeof(BMPContext),
+ .init = bmp_decode_init,
+ .close = bmp_decode_end,
+ .decode = bmp_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("BMP image"),
};
diff --git a/libavcodec/bmpenc.c b/libavcodec/bmpenc.c
index b3630f0..9cd7adb 100644
--- a/libavcodec/bmpenc.c
+++ b/libavcodec/bmpenc.c
@@ -150,13 +150,12 @@ static int bmp_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_s
}
AVCodec ff_bmp_encoder = {
- "bmp",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_BMP,
- sizeof(BMPContext),
- bmp_encode_init,
- bmp_encode_frame,
- NULL, //encode_end,
+ .name = "bmp",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_BMP,
+ .priv_data_size = sizeof(BMPContext),
+ .init = bmp_encode_init,
+ .encode = bmp_encode_frame,
.pix_fmts = (const enum PixelFormat[]){
PIX_FMT_BGR24,
PIX_FMT_RGB555, PIX_FMT_RGB565,
diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c
new file mode 100644
index 0000000..86d1e91
--- /dev/null
+++ b/libavcodec/bmv.c
@@ -0,0 +1,360 @@
+/*
+ * Discworld II BMV video and audio decoder
+ * Copyright (c) 2011 Konstantin Shishkov
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+#include "bytestream.h"
+
+enum BMVFlags{
+ BMV_NOP = 0,
+ BMV_END,
+ BMV_DELTA,
+ BMV_INTRA,
+
+ BMV_SCROLL = 0x04,
+ BMV_PALETTE = 0x08,
+ BMV_COMMAND = 0x10,
+ BMV_AUDIO = 0x20,
+ BMV_EXT = 0x40,
+ BMV_PRINT = 0x80
+};
+
+#define SCREEN_WIDE 640
+#define SCREEN_HIGH 429
+
+typedef struct BMVDecContext {
+ AVCodecContext *avctx;
+ AVFrame pic;
+
+ uint8_t *frame, frame_base[SCREEN_WIDE * (SCREEN_HIGH + 1)];
+ uint32_t pal[256];
+ const uint8_t *stream;
+} BMVDecContext;
+
+#define NEXT_BYTE(v) v = forward ? v + 1 : v - 1;
+
+static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, int frame_off)
+{
+ int val, saved_val = 0;
+ int tmplen = src_len;
+ const uint8_t *src, *source_end = source + src_len;
+ uint8_t *frame_end = frame + SCREEN_WIDE * SCREEN_HIGH;
+ uint8_t *dst, *dst_end;
+ int len, mask;
+ int forward = (frame_off <= -SCREEN_WIDE) || (frame_off >= 0);
+ int read_two_nibbles, flag;
+ int advance_mode;
+ int mode = 0;
+ int i;
+
+ if (src_len <= 0)
+ return -1;
+
+ if (forward) {
+ src = source;
+ dst = frame;
+ dst_end = frame_end;
+ } else {
+ src = source + src_len - 1;
+ dst = frame_end - 1;
+ dst_end = frame - 1;
+ }
+ for (;;) {
+ int shift = 0;
+ flag = 0;
+
+ /* The mode/len decoding is a bit strange:
+ * values are coded as variable-length codes with nibble units,
+ * code end is signalled by two top bits in the nibble being nonzero.
+ * And since data is bytepacked and we read two nibbles at a time,
+ * we may get a nibble belonging to the next code.
+ * Hence this convoluted loop.
+ */
+ if (!mode || (tmplen == 4)) {
+ if (src < source || src >= source_end)
+ return -1;
+ val = *src;
+ read_two_nibbles = 1;
+ } else {
+ val = saved_val;
+ read_two_nibbles = 0;
+ }
+ if (!(val & 0xC)) {
+ for (;;) {
+ if (!read_two_nibbles) {
+ if (src < source || src >= source_end)
+ return -1;
+ shift += 2;
+ val |= *src << shift;
+ if (*src & 0xC)
+ break;
+ }
+ // two upper bits of the nibble is zero,
+ // so shift top nibble value down into their place
+ read_two_nibbles = 0;
+ shift += 2;
+ mask = (1 << shift) - 1;
+ val = ((val >> 2) & ~mask) | (val & mask);
+ NEXT_BYTE(src);
+ if ((val & (0xC << shift))) {
+ flag = 1;
+ break;
+ }
+ }
+ } else if (mode) {
+ flag = tmplen != 4;
+ }
+ if (flag) {
+ tmplen = 4;
+ } else {
+ saved_val = val >> (4 + shift);
+ tmplen = 0;
+ val &= (1 << (shift + 4)) - 1;
+ NEXT_BYTE(src);
+ }
+ advance_mode = val & 1;
+ len = (val >> 1) - 1;
+ mode += 1 + advance_mode;
+ if (mode >= 4)
+ mode -= 3;
+ if (FFABS(dst_end - dst) < len)
+ return -1;
+ switch (mode) {
+ case 1:
+ if (forward) {
+ if (dst - frame + SCREEN_WIDE < frame_off ||
+ frame_end - dst < frame_off + len)
+ return -1;
+ for (i = 0; i < len; i++)
+ dst[i] = dst[frame_off + i];
+ dst += len;
+ } else {
+ dst -= len;
+ if (dst - frame + SCREEN_WIDE < frame_off ||
+ frame_end - dst < frame_off + len)
+ return -1;
+ for (i = len - 1; i >= 0; i--)
+ dst[i] = dst[frame_off + i];
+ }
+ break;
+ case 2:
+ if (forward) {
+ if (source + src_len - src < len)
+ return -1;
+ memcpy(dst, src, len);
+ dst += len;
+ src += len;
+ } else {
+ if (src - source < len)
+ return -1;
+ dst -= len;
+ src -= len;
+ memcpy(dst, src, len);
+ }
+ break;
+ case 3:
+ val = forward ? dst[-1] : dst[1];
+ if (forward) {
+ memset(dst, val, len);
+ dst += len;
+ } else {
+ dst -= len;
+ memset(dst, val, len);
+ }
+ break;
+ default:
+ break;
+ }
+ if (dst == dst_end)
+ return 0;
+ }
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
+{
+ BMVDecContext * const c = avctx->priv_data;
+ int type, scr_off;
+ int i;
+ uint8_t *srcptr, *outptr;
+
+ c->stream = pkt->data;
+ type = bytestream_get_byte(&c->stream);
+ if (type & BMV_AUDIO) {
+ int blobs = bytestream_get_byte(&c->stream);
+ if (pkt->size < blobs * 65 + 2) {
+ av_log(avctx, AV_LOG_ERROR, "Audio data doesn't fit in frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+ c->stream += blobs * 65;
+ }
+ if (type & BMV_COMMAND) {
+ int command_size = (type & BMV_PRINT) ? 8 : 10;
+ if (c->stream - pkt->data + command_size > pkt->size) {
+ av_log(avctx, AV_LOG_ERROR, "Command data doesn't fit in frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+ c->stream += command_size;
+ }
+ if (type & BMV_PALETTE) {
+ if (c->stream - pkt->data > pkt->size - 768) {
+ av_log(avctx, AV_LOG_ERROR, "Palette data doesn't fit in frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < 256; i++)
+ c->pal[i] = bytestream_get_be24(&c->stream);
+ }
+ if (type & BMV_SCROLL) {
+ if (c->stream - pkt->data > pkt->size - 2) {
+ av_log(avctx, AV_LOG_ERROR, "Screen offset data doesn't fit in frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+ scr_off = (int16_t)bytestream_get_le16(&c->stream);
+ } else if ((type & BMV_INTRA) == BMV_INTRA) {
+ scr_off = -640;
+ } else {
+ scr_off = 0;
+ }
+
+ if (decode_bmv_frame(c->stream, pkt->size - (c->stream - pkt->data), c->frame, scr_off)) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding frame data\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
+ c->pic.palette_has_changed = type & BMV_PALETTE;
+
+ outptr = c->pic.data[0];
+ srcptr = c->frame;
+
+ for (i = 0; i < avctx->height; i++) {
+ memcpy(outptr, srcptr, avctx->width);
+ srcptr += avctx->width;
+ outptr += c->pic.linesize[0];
+ }
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame*)data = c->pic;
+
+ /* always report that the buffer was completely consumed */
+ return pkt->size;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ BMVDecContext * const c = avctx->priv_data;
+
+ c->avctx = avctx;
+ avctx->pix_fmt = PIX_FMT_PAL8;
+
+ c->pic.reference = 1;
+ if (avctx->get_buffer(avctx, &c->pic) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return -1;
+ }
+
+ c->frame = c->frame_base + 640;
+
+ return 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ BMVDecContext *c = avctx->priv_data;
+
+ if (c->pic.data[0])
+ avctx->release_buffer(avctx, &c->pic);
+
+ return 0;
+}
+
+static const int bmv_aud_mults[16] = {
+ 16512, 8256, 4128, 2064, 1032, 516, 258, 192, 129, 88, 64, 56, 48, 40, 36, 32
+};
+
+static av_cold int bmv_aud_decode_init(AVCodecContext *avctx)
+{
+
+ if (avctx->channels != 2) {
+ av_log(avctx, AV_LOG_INFO, "invalid number of channels\n");
+ return AVERROR(EINVAL);
+ }
+
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ return 0;
+}
+
+static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int blocks = 0, total_blocks, i;
+ int out_size;
+ int16_t *output_samples = data;
+ int scale[2];
+
+ total_blocks = *buf++;
+ if (buf_size < total_blocks * 65 + 1) {
+ av_log(avctx, AV_LOG_ERROR, "expected %d bytes, got %d\n",
+ total_blocks * 65 + 1, buf_size);
+ return AVERROR_INVALIDDATA;
+ }
+ out_size = total_blocks * 64 * sizeof(*output_samples);
+ if (*data_size < out_size) {
+ av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
+ return AVERROR(EINVAL);
+ }
+
+ for (blocks = 0; blocks < total_blocks; blocks++) {
+ uint8_t code = *buf++;
+ code = (code >> 1) | (code << 7);
+ scale[0] = bmv_aud_mults[code & 0xF];
+ scale[1] = bmv_aud_mults[code >> 4];
+ for (i = 0; i < 32; i++) {
+ *output_samples++ = av_clip_int16((scale[0] * (int8_t)*buf++) >> 5);
+ *output_samples++ = av_clip_int16((scale[1] * (int8_t)*buf++) >> 5);
+ }
+ }
+
+ *data_size = out_size;
+ return buf_size;
+}
+
+AVCodec ff_bmv_video_decoder = {
+ .name = "bmv_video",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_BMV_VIDEO,
+ .priv_data_size = sizeof(BMVDecContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV video"),
+};
+
+AVCodec ff_bmv_audio_decoder = {
+ .name = "bmv_audio",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_BMV_AUDIO,
+ .init = bmv_aud_decode_init,
+ .decode = bmv_aud_decode_frame,
+ .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV audio"),
+};
diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h
index 98f0087..ba3e4e8 100644
--- a/libavcodec/bytestream.h
+++ b/libavcodec/bytestream.h
@@ -26,6 +26,10 @@
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
+typedef struct {
+ const uint8_t *buffer, *buffer_end;
+} GetByteContext;
+
#define DEF_T(type, name, bytes, read, write) \
static av_always_inline type bytestream_get_ ## name(const uint8_t **b){\
(*b) += bytes;\
@@ -34,6 +38,18 @@ static av_always_inline type bytestream_get_ ## name(const uint8_t **b){\
static av_always_inline void bytestream_put_ ##name(uint8_t **b, const type value){\
write(*b, value);\
(*b) += bytes;\
+}\
+static av_always_inline type bytestream2_get_ ## name(GetByteContext *g)\
+{\
+ if (g->buffer_end - g->buffer < bytes)\
+ return 0;\
+ return bytestream_get_ ## name(&g->buffer);\
+}\
+static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g)\
+{\
+ if (g->buffer_end - g->buffer < bytes)\
+ return 0;\
+ return read(g->buffer);\
}
#define DEF(name, bytes, read, write) \
@@ -55,6 +71,34 @@ DEF (byte, 1, AV_RB8 , AV_WB8 )
#undef DEF64
#undef DEF_T
+static av_always_inline void bytestream2_init(GetByteContext *g,
+ const uint8_t *buf, int buf_size)
+{
+ g->buffer = buf;
+ g->buffer_end = buf + buf_size;
+}
+
+static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
+{
+ return g->buffer_end - g->buffer;
+}
+
+static av_always_inline void bytestream2_skip(GetByteContext *g,
+ unsigned int size)
+{
+ g->buffer += FFMIN(g->buffer_end - g->buffer, size);
+}
+
+static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
+ uint8_t *dst,
+ unsigned int size)
+{
+ int size2 = FFMIN(g->buffer_end - g->buffer, size);
+ memcpy(dst, g->buffer, size2);
+ g->buffer += size2;
+ return size2;
+}
+
static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size)
{
memcpy(dst, *b, size);
diff --git a/libavcodec/c93.c b/libavcodec/c93.c
index 0b6eb02..ecfd035 100644
--- a/libavcodec/c93.c
+++ b/libavcodec/c93.c
@@ -243,14 +243,13 @@ static int decode_frame(AVCodecContext *avctx, void *data,
}
AVCodec ff_c93_decoder = {
- "c93",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_C93,
- sizeof(C93DecoderContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "c93",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_C93,
+ .priv_data_size = sizeof(C93DecoderContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Interplay C93"),
};
diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c
index 098cd6f..57ab395 100644
--- a/libavcodec/cabac.c
+++ b/libavcodec/cabac.c
@@ -75,18 +75,7 @@ static const uint8_t lps_state[64]= {
33,33,34,34,35,35,35,36,
36,36,37,37,37,38,38,63,
};
-#if 0
-const uint8_t ff_h264_norm_shift_old[128]= {
- 7,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 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,
- 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,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,0,0,0,0,
-};
-#endif
+
const uint8_t ff_h264_norm_shift[512]= {
9,8,7,7,6,6,6,6,5,5,5,5,5,5,5,5,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
@@ -161,19 +150,11 @@ void ff_init_cabac_states(CABACContext *c){
ff_h264_mps_state[2*i+1]= 2*mps_state[i]+1;
if( i ){
-#ifdef BRANCHLESS_CABAC_DECODER
ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0;
ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1;
}else{
ff_h264_mlps_state[128-2*i-1]= 1;
ff_h264_mlps_state[128-2*i-2]= 0;
-#else
- ff_h264_lps_state[2*i+0]= 2*lps_state[i]+0;
- ff_h264_lps_state[2*i+1]= 2*lps_state[i]+1;
- }else{
- ff_h264_lps_state[2*i+0]= 1;
- ff_h264_lps_state[2*i+1]= 0;
-#endif
}
}
}
@@ -185,6 +166,140 @@ void ff_init_cabac_states(CABACContext *c){
#include "avcodec.h"
#include "cabac.h"
+static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
+ int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
+
+ if(bit == ((*state)&1)){
+ c->range -= RangeLPS;
+ *state= ff_h264_mps_state[*state];
+ }else{
+ c->low += c->range - RangeLPS;
+ c->range = RangeLPS;
+ *state= ff_h264_lps_state[*state];
+ }
+
+ renorm_cabac_encoder(c);
+
+#ifdef STRICT_LIMITS
+ c->symCount++;
+#endif
+}
+
+/**
+ * @param bit 0 -> write zero bit, !=0 write one bit
+ */
+static void put_cabac_bypass(CABACContext *c, int bit){
+ c->low += c->low;
+
+ if(bit){
+ c->low += c->range;
+ }
+//FIXME optimize
+ if(c->low<0x200){
+ put_cabac_bit(c, 0);
+ }else if(c->low<0x400){
+ c->outstanding_count++;
+ c->low -= 0x200;
+ }else{
+ put_cabac_bit(c, 1);
+ c->low -= 0x400;
+ }
+
+#ifdef STRICT_LIMITS
+ c->symCount++;
+#endif
+}
+
+/**
+ *
+ * @return the number of bytes written
+ */
+static int put_cabac_terminate(CABACContext *c, int bit){
+ c->range -= 2;
+
+ if(!bit){
+ renorm_cabac_encoder(c);
+ }else{
+ c->low += c->range;
+ c->range= 2;
+
+ renorm_cabac_encoder(c);
+
+ assert(c->low <= 0x1FF);
+ put_cabac_bit(c, c->low>>9);
+ put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
+
+ flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
+ }
+
+#ifdef STRICT_LIMITS
+ c->symCount++;
+#endif
+
+ return (put_bits_count(&c->pb)+7)>>3;
+}
+
+/**
+ * put (truncated) unary binarization.
+ */
+static void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){
+ int i;
+
+ assert(v <= max);
+
+ for(i=0; i<v; i++){
+ put_cabac(c, state, 1);
+ if(i < max_index) state++;
+ }
+ if(truncated==0 || v<max)
+ put_cabac(c, state, 0);
+}
+
+/**
+ * put unary exp golomb k-th order binarization.
+ */
+static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){
+ int i;
+
+ if(v==0)
+ put_cabac(c, state, 0);
+ else{
+ const int sign= v < 0;
+
+ if(is_signed) v= FFABS(v);
+
+ if(v<max){
+ for(i=0; i<v; i++){
+ put_cabac(c, state, 1);
+ if(i < max_index) state++;
+ }
+
+ put_cabac(c, state, 0);
+ }else{
+ int m= 1<<k;
+
+ for(i=0; i<max; i++){
+ put_cabac(c, state, 1);
+ if(i < max_index) state++;
+ }
+
+ v -= max;
+ while(v >= m){ //FIXME optimize
+ put_cabac_bypass(c, 1);
+ v-= m;
+ m+= m;
+ }
+ put_cabac_bypass(c, 0);
+ while(m>>=1){
+ put_cabac_bypass(c, v&m);
+ }
+ }
+
+ if(is_signed)
+ put_cabac_bypass(c, sign);
+ }
+}
+
int main(void){
CABACContext c;
uint8_t b[9*SIZE];
diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h
index 4708563..1260642 100644
--- a/libavcodec/cabac.h
+++ b/libavcodec/cabac.h
@@ -27,16 +27,15 @@
#ifndef AVCODEC_CABAC_H
#define AVCODEC_CABAC_H
+#include <stddef.h>
+
#include "put_bits.h"
//#undef NDEBUG
#include <assert.h>
-#include "libavutil/x86_cpu.h"
#define CABAC_BITS 16
#define CABAC_MASK ((1<<CABAC_BITS)-1)
-#define BRANCHLESS_CABAC_DECODER 1
-//#define ARCH_X86_DISABLED 1
typedef struct CABACContext{
int low;
@@ -57,6 +56,9 @@ extern uint8_t ff_h264_mps_state[2*64]; ///< transIdxMPS
extern uint8_t ff_h264_lps_state[2*64]; ///< transIdxLPS
extern const uint8_t ff_h264_norm_shift[512];
+#if ARCH_X86
+# include "x86/cabac.h"
+#endif
void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
@@ -88,178 +90,6 @@ static inline void renorm_cabac_encoder(CABACContext *c){
}
}
-#ifdef TEST
-static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
- int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
-
- if(bit == ((*state)&1)){
- c->range -= RangeLPS;
- *state= ff_h264_mps_state[*state];
- }else{
- c->low += c->range - RangeLPS;
- c->range = RangeLPS;
- *state= ff_h264_lps_state[*state];
- }
-
- renorm_cabac_encoder(c);
-
-#ifdef STRICT_LIMITS
- c->symCount++;
-#endif
-}
-
-static void put_cabac_static(CABACContext *c, int RangeLPS, int bit){
- assert(c->range > RangeLPS);
-
- if(!bit){
- c->range -= RangeLPS;
- }else{
- c->low += c->range - RangeLPS;
- c->range = RangeLPS;
- }
-
- renorm_cabac_encoder(c);
-
-#ifdef STRICT_LIMITS
- c->symCount++;
-#endif
-}
-
-/**
- * @param bit 0 -> write zero bit, !=0 write one bit
- */
-static void put_cabac_bypass(CABACContext *c, int bit){
- c->low += c->low;
-
- if(bit){
- c->low += c->range;
- }
-//FIXME optimize
- if(c->low<0x200){
- put_cabac_bit(c, 0);
- }else if(c->low<0x400){
- c->outstanding_count++;
- c->low -= 0x200;
- }else{
- put_cabac_bit(c, 1);
- c->low -= 0x400;
- }
-
-#ifdef STRICT_LIMITS
- c->symCount++;
-#endif
-}
-
-/**
- *
- * @return the number of bytes written
- */
-static int put_cabac_terminate(CABACContext *c, int bit){
- c->range -= 2;
-
- if(!bit){
- renorm_cabac_encoder(c);
- }else{
- c->low += c->range;
- c->range= 2;
-
- renorm_cabac_encoder(c);
-
- assert(c->low <= 0x1FF);
- put_cabac_bit(c, c->low>>9);
- put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
-
- flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
- }
-
-#ifdef STRICT_LIMITS
- c->symCount++;
-#endif
-
- return (put_bits_count(&c->pb)+7)>>3;
-}
-
-/**
- * put (truncated) unary binarization.
- */
-static void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){
- int i;
-
- assert(v <= max);
-
-#if 1
- for(i=0; i<v; i++){
- put_cabac(c, state, 1);
- if(i < max_index) state++;
- }
- if(truncated==0 || v<max)
- put_cabac(c, state, 0);
-#else
- if(v <= max_index){
- for(i=0; i<v; i++){
- put_cabac(c, state+i, 1);
- }
- if(truncated==0 || v<max)
- put_cabac(c, state+i, 0);
- }else{
- for(i=0; i<=max_index; i++){
- put_cabac(c, state+i, 1);
- }
- for(; i<v; i++){
- put_cabac(c, state+max_index, 1);
- }
- if(truncated==0 || v<max)
- put_cabac(c, state+max_index, 0);
- }
-#endif
-}
-
-/**
- * put unary exp golomb k-th order binarization.
- */
-static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){
- int i;
-
- if(v==0)
- put_cabac(c, state, 0);
- else{
- const int sign= v < 0;
-
- if(is_signed) v= FFABS(v);
-
- if(v<max){
- for(i=0; i<v; i++){
- put_cabac(c, state, 1);
- if(i < max_index) state++;
- }
-
- put_cabac(c, state, 0);
- }else{
- int m= 1<<k;
-
- for(i=0; i<max; i++){
- put_cabac(c, state, 1);
- if(i < max_index) state++;
- }
-
- v -= max;
- while(v >= m){ //FIXME optimize
- put_cabac_bypass(c, 1);
- v-= m;
- m+= m;
- }
- put_cabac_bypass(c, 0);
- while(m>>=1){
- put_cabac_bypass(c, v&m);
- }
- }
-
- if(is_signed)
- put_cabac_bypass(c, sign);
- }
-}
-#endif /* TEST */
-
static void refill(CABACContext *c){
#if CABAC_BITS == 16
c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
@@ -270,26 +100,6 @@ static void refill(CABACContext *c){
c->bytestream+= CABAC_BITS/8;
}
-#if ! ( ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) )
-static void refill2(CABACContext *c){
- int i, x;
-
- x= c->low ^ (c->low-1);
- i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)];
-
- x= -CABAC_MASK;
-
-#if CABAC_BITS == 16
- x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
-#else
- x+= c->bytestream[0]<<1;
-#endif
-
- c->low += x<<i;
- c->bytestream+= CABAC_BITS/8;
-}
-#endif
-
static inline void renorm_cabac_decoder(CABACContext *c){
while(c->range < 0x100){
c->range+= c->range;
@@ -300,267 +110,38 @@ static inline void renorm_cabac_decoder(CABACContext *c){
}
static inline void renorm_cabac_decoder_once(CABACContext *c){
-#ifdef ARCH_X86_DISABLED
- int temp;
-#if 0
- //P3:683 athlon:475
- __asm__(
- "lea -0x100(%0), %2 \n\t"
- "shr $31, %2 \n\t" //FIXME 31->63 for x86-64
- "shl %%cl, %0 \n\t"
- "shl %%cl, %1 \n\t"
- : "+r"(c->range), "+r"(c->low), "+c"(temp)
- );
-#elif 0
- //P3:680 athlon:474
- __asm__(
- "cmp $0x100, %0 \n\t"
- "setb %%cl \n\t" //FIXME 31->63 for x86-64
- "shl %%cl, %0 \n\t"
- "shl %%cl, %1 \n\t"
- : "+r"(c->range), "+r"(c->low), "+c"(temp)
- );
-#elif 1
- int temp2;
- //P3:665 athlon:517
- __asm__(
- "lea -0x100(%0), %%eax \n\t"
- "cltd \n\t"
- "mov %0, %%eax \n\t"
- "and %%edx, %0 \n\t"
- "and %1, %%edx \n\t"
- "add %%eax, %0 \n\t"
- "add %%edx, %1 \n\t"
- : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
- );
-#elif 0
- int temp2;
- //P3:673 athlon:509
- __asm__(
- "cmp $0x100, %0 \n\t"
- "sbb %%edx, %%edx \n\t"
- "mov %0, %%eax \n\t"
- "and %%edx, %0 \n\t"
- "and %1, %%edx \n\t"
- "add %%eax, %0 \n\t"
- "add %%edx, %1 \n\t"
- : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
- );
-#else
- int temp2;
- //P3:677 athlon:511
- __asm__(
- "cmp $0x100, %0 \n\t"
- "lea (%0, %0), %%eax \n\t"
- "lea (%1, %1), %%edx \n\t"
- "cmovb %%eax, %0 \n\t"
- "cmovb %%edx, %1 \n\t"
- : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
- );
-#endif
-#else
- //P3:675 athlon:476
int shift= (uint32_t)(c->range - 0x100)>>31;
c->range<<= shift;
c->low <<= shift;
-#endif
if(!(c->low & CABAC_MASK))
refill(c);
}
-static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){
- //FIXME gcc generates duplicate load/stores for c->low and c->range
-#define LOW "0"
-#define RANGE "4"
-#if ARCH_X86_64
-#define BYTESTART "16"
-#define BYTE "24"
-#define BYTEEND "32"
-#else
-#define BYTESTART "12"
-#define BYTE "16"
-#define BYTEEND "20"
-#endif
-#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS)
- int bit;
-
-#ifndef BRANCHLESS_CABAC_DECODER
- __asm__ volatile(
- "movzbl (%1), %0 \n\t"
- "movl "RANGE "(%2), %%ebx \n\t"
- "movl "RANGE "(%2), %%edx \n\t"
- "andl $0xC0, %%ebx \n\t"
- "movzbl "MANGLE(ff_h264_lps_range)"(%0, %%ebx, 2), %%esi\n\t"
- "movl "LOW "(%2), %%ebx \n\t"
-//eax:state ebx:low, edx:range, esi:RangeLPS
- "subl %%esi, %%edx \n\t"
- "movl %%edx, %%ecx \n\t"
- "shll $17, %%ecx \n\t"
- "cmpl %%ecx, %%ebx \n\t"
- " ja 1f \n\t"
-
-#if 1
- //athlon:4067 P3:4110
- "lea -0x100(%%edx), %%ecx \n\t"
- "shr $31, %%ecx \n\t"
- "shl %%cl, %%edx \n\t"
- "shl %%cl, %%ebx \n\t"
+#ifndef get_cabac_inline
+static void refill2(CABACContext *c){
+ int i, x;
+
+ x= c->low ^ (c->low-1);
+ i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)];
+
+ x= -CABAC_MASK;
+
+#if CABAC_BITS == 16
+ x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
#else
- //athlon:4057 P3:4130
- "cmp $0x100, %%edx \n\t" //FIXME avoidable
- "setb %%cl \n\t"
- "shl %%cl, %%edx \n\t"
- "shl %%cl, %%ebx \n\t"
+ x+= c->bytestream[0]<<1;
#endif
- "movzbl "MANGLE(ff_h264_mps_state)"(%0), %%ecx \n\t"
- "movb %%cl, (%1) \n\t"
-//eax:state ebx:low, edx:range, esi:RangeLPS
- "test %%bx, %%bx \n\t"
- " jnz 2f \n\t"
- "mov "BYTE "(%2), %%"REG_S" \n\t"
- "subl $0xFFFF, %%ebx \n\t"
- "movzwl (%%"REG_S"), %%ecx \n\t"
- "bswap %%ecx \n\t"
- "shrl $15, %%ecx \n\t"
- "add $2, %%"REG_S" \n\t"
- "addl %%ecx, %%ebx \n\t"
- "mov %%"REG_S", "BYTE "(%2) \n\t"
- "jmp 2f \n\t"
- "1: \n\t"
-//eax:state ebx:low, edx:range, esi:RangeLPS
- "subl %%ecx, %%ebx \n\t"
- "movl %%esi, %%edx \n\t"
- "movzbl " MANGLE(ff_h264_norm_shift) "(%%esi), %%ecx \n\t"
- "shll %%cl, %%ebx \n\t"
- "shll %%cl, %%edx \n\t"
- "movzbl "MANGLE(ff_h264_lps_state)"(%0), %%ecx \n\t"
- "movb %%cl, (%1) \n\t"
- "add $1, %0 \n\t"
- "test %%bx, %%bx \n\t"
- " jnz 2f \n\t"
-
- "mov "BYTE "(%2), %%"REG_c" \n\t"
- "movzwl (%%"REG_c"), %%esi \n\t"
- "bswap %%esi \n\t"
- "shrl $15, %%esi \n\t"
- "subl $0xFFFF, %%esi \n\t"
- "add $2, %%"REG_c" \n\t"
- "mov %%"REG_c", "BYTE "(%2) \n\t"
-
- "leal -1(%%ebx), %%ecx \n\t"
- "xorl %%ebx, %%ecx \n\t"
- "shrl $15, %%ecx \n\t"
- "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"
- "neg %%ecx \n\t"
- "add $7, %%ecx \n\t"
-
- "shll %%cl , %%esi \n\t"
- "addl %%esi, %%ebx \n\t"
- "2: \n\t"
- "movl %%edx, "RANGE "(%2) \n\t"
- "movl %%ebx, "LOW "(%2) \n\t"
- :"=&a"(bit) //FIXME this is fragile gcc either runs out of registers or miscompiles it (for example if "+a"(bit) or "+m"(*state) is used
- :"r"(state), "r"(c)
- : "%"REG_c, "%ebx", "%edx", "%"REG_S, "memory"
- );
- bit&=1;
-#else /* BRANCHLESS_CABAC_DECODER */
-
-
-#if HAVE_FAST_CMOV
-#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
- "mov "tmp" , %%ecx \n\t"\
- "shl $17 , "tmp" \n\t"\
- "cmp "low" , "tmp" \n\t"\
- "cmova %%ecx , "range" \n\t"\
- "sbb %%ecx , %%ecx \n\t"\
- "and %%ecx , "tmp" \n\t"\
- "sub "tmp" , "low" \n\t"\
- "xor %%ecx , "ret" \n\t"
-#else /* HAVE_FAST_CMOV */
-#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
- "mov "tmp" , %%ecx \n\t"\
- "shl $17 , "tmp" \n\t"\
- "sub "low" , "tmp" \n\t"\
- "sar $31 , "tmp" \n\t" /*lps_mask*/\
- "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\
- "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\
- "add %%ecx , "range" \n\t" /*new range*/\
- "shl $17 , %%ecx \n\t"\
- "and "tmp" , %%ecx \n\t"\
- "sub %%ecx , "low" \n\t"\
- "xor "tmp" , "ret" \n\t"
-#endif /* HAVE_FAST_CMOV */
-
-
-#define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
- "movzbl "statep" , "ret" \n\t"\
- "mov "range" , "tmp" \n\t"\
- "and $0xC0 , "range" \n\t"\
- "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\
- "sub "range" , "tmp" \n\t"\
- BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
- "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\
- "shl %%cl , "range" \n\t"\
- "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\
- "mov "tmpbyte" , "statep" \n\t"\
- "shl %%cl , "low" \n\t"\
- "test "lowword" , "lowword" \n\t"\
- " jnz 1f \n\t"\
- "mov "BYTE"("cabac"), %%"REG_c" \n\t"\
- "movzwl (%%"REG_c") , "tmp" \n\t"\
- "bswap "tmp" \n\t"\
- "shr $15 , "tmp" \n\t"\
- "sub $0xFFFF , "tmp" \n\t"\
- "add $2 , %%"REG_c" \n\t"\
- "mov %%"REG_c" , "BYTE "("cabac") \n\t"\
- "lea -1("low") , %%ecx \n\t"\
- "xor "low" , %%ecx \n\t"\
- "shr $15 , %%ecx \n\t"\
- "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\
- "neg %%ecx \n\t"\
- "add $7 , %%ecx \n\t"\
- "shl %%cl , "tmp" \n\t"\
- "add "tmp" , "low" \n\t"\
- "1: \n\t"
-
- __asm__ volatile(
- "movl "RANGE "(%2), %%esi \n\t"
- "movl "LOW "(%2), %%ebx \n\t"
- BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl")
- "movl %%esi, "RANGE "(%2) \n\t"
- "movl %%ebx, "LOW "(%2) \n\t"
-
- :"=&a"(bit)
- :"r"(state), "r"(c)
- : "%"REG_c, "%ebx", "%edx", "%esi", "memory"
- );
- bit&=1;
-#endif /* BRANCHLESS_CABAC_DECODER */
-#else /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */
+
+ c->low += x<<i;
+ c->bytestream+= CABAC_BITS/8;
+}
+
+static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){
int s = *state;
int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s];
- int bit, lps_mask av_unused;
+ int bit, lps_mask;
c->range -= RangeLPS;
-#ifndef BRANCHLESS_CABAC_DECODER
- if(c->low < (c->range<<(CABAC_BITS+1))){
- bit= s&1;
- *state= ff_h264_mps_state[s];
- renorm_cabac_decoder_once(c);
- }else{
- bit= ff_h264_norm_shift[RangeLPS];
- c->low -= (c->range<<(CABAC_BITS+1));
- *state= ff_h264_lps_state[s];
- c->range = RangeLPS<<bit;
- c->low <<= bit;
- bit= (s&1)^1;
-
- if(!(c->low & CABAC_MASK)){
- refill2(c);
- }
- }
-#else /* BRANCHLESS_CABAC_DECODER */
lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31;
c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask;
@@ -575,10 +156,9 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st
c->low <<= lps_mask;
if(!(c->low & CABAC_MASK))
refill2(c);
-#endif /* BRANCHLESS_CABAC_DECODER */
-#endif /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */
return bit;
}
+#endif
static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){
return get_cabac_inline(c,state);
@@ -589,36 +169,6 @@ static int av_unused get_cabac(CABACContext *c, uint8_t * const state){
}
static int av_unused get_cabac_bypass(CABACContext *c){
-#if 0 //not faster
- int bit;
- __asm__ volatile(
- "movl "RANGE "(%1), %%ebx \n\t"
- "movl "LOW "(%1), %%eax \n\t"
- "shl $17, %%ebx \n\t"
- "add %%eax, %%eax \n\t"
- "sub %%ebx, %%eax \n\t"
- "cltd \n\t"
- "and %%edx, %%ebx \n\t"
- "add %%ebx, %%eax \n\t"
- "test %%ax, %%ax \n\t"
- " jnz 1f \n\t"
- "movl "BYTE "(%1), %%"REG_b" \n\t"
- "subl $0xFFFF, %%eax \n\t"
- "movzwl (%%"REG_b"), %%ecx \n\t"
- "bswap %%ecx \n\t"
- "shrl $15, %%ecx \n\t"
- "addl $2, %%"REG_b" \n\t"
- "addl %%ecx, %%eax \n\t"
- "movl %%"REG_b", "BYTE "(%1) \n\t"
- "1: \n\t"
- "movl %%eax, "LOW "(%1) \n\t"
-
- :"=&d"(bit)
- :"r"(c)
- : "%eax", "%"REG_b, "%ecx", "memory"
- );
- return bit+1;
-#else
int range;
c->low += c->low;
@@ -632,42 +182,11 @@ static int av_unused get_cabac_bypass(CABACContext *c){
c->low -= range;
return 1;
}
-#endif
}
+#ifndef get_cabac_bypass_sign
static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
-#if ARCH_X86 && HAVE_EBX_AVAILABLE
- __asm__ volatile(
- "movl "RANGE "(%1), %%ebx \n\t"
- "movl "LOW "(%1), %%eax \n\t"
- "shl $17, %%ebx \n\t"
- "add %%eax, %%eax \n\t"
- "sub %%ebx, %%eax \n\t"
- "cltd \n\t"
- "and %%edx, %%ebx \n\t"
- "add %%ebx, %%eax \n\t"
- "xor %%edx, %%ecx \n\t"
- "sub %%edx, %%ecx \n\t"
- "test %%ax, %%ax \n\t"
- " jnz 1f \n\t"
- "mov "BYTE "(%1), %%"REG_b" \n\t"
- "subl $0xFFFF, %%eax \n\t"
- "movzwl (%%"REG_b"), %%edx \n\t"
- "bswap %%edx \n\t"
- "shrl $15, %%edx \n\t"
- "add $2, %%"REG_b" \n\t"
- "addl %%edx, %%eax \n\t"
- "mov %%"REG_b", "BYTE "(%1) \n\t"
- "1: \n\t"
- "movl %%eax, "LOW "(%1) \n\t"
-
- :"+c"(val)
- :"r"(c)
- : "%eax", "%"REG_b, "%edx", "memory"
- );
- return val;
-#else
int range, mask;
c->low += c->low;
@@ -680,8 +199,8 @@ static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
range &= mask;
c->low += range;
return (val^mask)-mask;
-#endif
}
+#endif
/**
*
diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c
index 9a73e2a..6f63c23 100644
--- a/libavcodec/cavs.c
+++ b/libavcodec/cavs.c
@@ -333,9 +333,9 @@ static inline void mc_dir_part(AVSContext *h,Picture *pic,int square,
const int mx= mv->x + src_x_offset*8;
const int my= mv->y + src_y_offset*8;
const int luma_xy= (mx&3) + ((my&3)<<2);
- uint8_t * src_y = pic->data[0] + (mx>>2) + (my>>2)*h->l_stride;
- uint8_t * src_cb= pic->data[1] + (mx>>3) + (my>>3)*h->c_stride;
- uint8_t * src_cr= pic->data[2] + (mx>>3) + (my>>3)*h->c_stride;
+ uint8_t * src_y = pic->f.data[0] + (mx >> 2) + (my >> 2) * h->l_stride;
+ uint8_t * src_cb = pic->f.data[1] + (mx >> 3) + (my >> 3) * h->c_stride;
+ uint8_t * src_cr = pic->f.data[2] + (mx >> 3) + (my >> 3) * h->c_stride;
int extra_width= 0; //(s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16;
int extra_height= extra_width;
int emu=0;
@@ -344,7 +344,7 @@ static inline void mc_dir_part(AVSContext *h,Picture *pic,int square,
const int pic_width = 16*h->mb_width;
const int pic_height = 16*h->mb_height;
- if(!pic->data[0])
+ if(!pic->f.data[0])
return;
if(mx&7) extra_width -= 3;
if(my&7) extra_height -= 3;
@@ -602,9 +602,9 @@ int ff_cavs_next_mb(AVSContext *h) {
h->mbx = 0;
h->mby++;
/* re-calculate sample pointers */
- h->cy = h->picture.data[0] + h->mby*16*h->l_stride;
- h->cu = h->picture.data[1] + h->mby*8*h->c_stride;
- h->cv = h->picture.data[2] + h->mby*8*h->c_stride;
+ h->cy = h->picture.f.data[0] + h->mby * 16 * h->l_stride;
+ h->cu = h->picture.f.data[1] + h->mby * 8 * h->c_stride;
+ h->cv = h->picture.f.data[2] + h->mby * 8 * h->c_stride;
if(h->mby == h->mb_height) { //frame end
return 0;
}
@@ -629,11 +629,11 @@ void ff_cavs_init_pic(AVSContext *h) {
h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
- h->cy = h->picture.data[0];
- h->cu = h->picture.data[1];
- h->cv = h->picture.data[2];
- h->l_stride = h->picture.linesize[0];
- h->c_stride = h->picture.linesize[1];
+ h->cy = h->picture.f.data[0];
+ h->cu = h->picture.f.data[1];
+ h->cv = h->picture.f.data[2];
+ h->l_stride = h->picture.f.linesize[0];
+ h->c_stride = h->picture.f.linesize[1];
h->luma_scan[2] = 8*h->l_stride;
h->luma_scan[3] = 8*h->l_stride+8;
h->mbx = h->mby = h->mbidx = 0;
diff --git a/libavcodec/cavs_parser.c b/libavcodec/cavs_parser.c
index 2cc6566..a91be3a 100644
--- a/libavcodec/cavs_parser.c
+++ b/libavcodec/cavs_parser.c
@@ -30,7 +30,7 @@
/**
- * finds the end of the current frame in the bitstream.
+ * Find the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
static int cavs_find_frame_end(ParseContext *pc, const uint8_t *buf,
@@ -98,10 +98,9 @@ static int cavsvideo_parse(AVCodecParserContext *s,
}
AVCodecParser ff_cavsvideo_parser = {
- { CODEC_ID_CAVS },
- sizeof(ParseContext1),
- NULL,
- cavsvideo_parse,
- ff_parse1_close,
- ff_mpeg4video_split,
+ .codec_ids = { CODEC_ID_CAVS },
+ .priv_data_size = sizeof(ParseContext1),
+ .parser_parse = cavsvideo_parse,
+ .parser_close = ff_parse1_close,
+ .split = ff_mpeg4video_split,
};
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index 35c37d0..514752a 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -481,8 +481,8 @@ static int decode_pic(AVSContext *h) {
return -1;
}
/* make sure we have the reference frames we need */
- if(!h->DPB[0].data[0] ||
- (!h->DPB[1].data[0] && h->pic_type == AV_PICTURE_TYPE_B))
+ if(!h->DPB[0].f.data[0] ||
+ (!h->DPB[1].f.data[0] && h->pic_type == AV_PICTURE_TYPE_B))
return -1;
} else {
h->pic_type = AV_PICTURE_TYPE_I;
@@ -499,7 +499,7 @@ static int decode_pic(AVSContext *h) {
skip_bits(&s->gb,1); //marker_bit
}
/* release last B frame */
- if(h->picture.data[0])
+ if(h->picture.f.data[0])
s->avctx->release_buffer(s->avctx, (AVFrame *)&h->picture);
s->avctx->get_buffer(s->avctx, (AVFrame *)&h->picture);
@@ -590,7 +590,7 @@ static int decode_pic(AVSContext *h) {
} while(ff_cavs_next_mb(h));
}
if(h->pic_type != AV_PICTURE_TYPE_B) {
- if(h->DPB[1].data[0])
+ if(h->DPB[1].f.data[0])
s->avctx->release_buffer(s->avctx, (AVFrame *)&h->DPB[1]);
h->DPB[1] = h->DPB[0];
h->DPB[0] = h->picture;
@@ -624,8 +624,8 @@ static int decode_seq_header(AVSContext *h) {
s->low_delay = get_bits1(&s->gb);
h->mb_width = (s->width + 15) >> 4;
h->mb_height = (s->height + 15) >> 4;
- h->s.avctx->time_base.den = ff_frame_rate_tab[frame_rate_code].num;
- h->s.avctx->time_base.num = ff_frame_rate_tab[frame_rate_code].den;
+ h->s.avctx->time_base.den = avpriv_frame_rate_tab[frame_rate_code].num;
+ h->s.avctx->time_base.num = avpriv_frame_rate_tab[frame_rate_code].den;
h->s.avctx->width = s->width;
h->s.avctx->height = s->height;
if(!h->top_qp)
@@ -653,7 +653,7 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size,
s->avctx = avctx;
if (buf_size == 0) {
- if(!s->low_delay && h->DPB[0].data[0]) {
+ if (!s->low_delay && h->DPB[0].f.data[0]) {
*data_size = sizeof(AVPicture);
*picture = *(AVFrame *) &h->DPB[0];
}
@@ -663,7 +663,7 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size,
buf_ptr = buf;
buf_end = buf + buf_size;
for(;;) {
- buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc);
+ buf_ptr = avpriv_mpv_find_start_code(buf_ptr,buf_end, &stc);
if((stc & 0xFFFFFE00) || buf_ptr == buf_end)
return FFMAX(0, buf_ptr - buf - s->parse_context.last_index);
input_size = (buf_end - buf_ptr)*8;
@@ -674,9 +674,9 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size,
break;
case PIC_I_START_CODE:
if(!h->got_keyframe) {
- if(h->DPB[0].data[0])
+ if(h->DPB[0].f.data[0])
avctx->release_buffer(avctx, (AVFrame *)&h->DPB[0]);
- if(h->DPB[1].data[0])
+ if(h->DPB[1].f.data[0])
avctx->release_buffer(avctx, (AVFrame *)&h->DPB[1]);
h->got_keyframe = 1;
}
@@ -690,7 +690,7 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size,
break;
*data_size = sizeof(AVPicture);
if(h->pic_type != AV_PICTURE_TYPE_B) {
- if(h->DPB[1].data[0]) {
+ if(h->DPB[1].f.data[0]) {
*picture = *(AVFrame *) &h->DPB[1];
} else {
*data_size = 0;
@@ -715,15 +715,14 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size,
}
AVCodec ff_cavs_decoder = {
- "cavs",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_CAVS,
- sizeof(AVSContext),
- ff_cavs_init,
- NULL,
- ff_cavs_end,
- cavs_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+ .name = "cavs",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_CAVS,
+ .priv_data_size = sizeof(AVSContext),
+ .init = ff_cavs_init,
+ .close = ff_cavs_end,
+ .decode = cavs_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
.flush= cavs_flush,
.long_name= NULL_IF_CONFIG_SMALL("Chinese AVS video (AVS1-P2, JiZhun profile)"),
};
diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c
index bcfb6e9..f1f474f 100644
--- a/libavcodec/cdgraphics.c
+++ b/libavcodec/cdgraphics.c
@@ -26,8 +26,8 @@
* @file
* @brief CD Graphics Video Decoder
* @author Michael Tison
- * @sa http://wiki.multimedia.cx/index.php?title=CD_Graphics
- * @sa http://www.ccs.neu.edu/home/bchafy/cdb/info/cdg
+ * @see http://wiki.multimedia.cx/index.php?title=CD_Graphics
+ * @see http://www.ccs.neu.edu/home/bchafy/cdb/info/cdg
*/
/// default screen sizes
@@ -368,14 +368,13 @@ static av_cold int cdg_decode_end(AVCodecContext *avctx)
}
AVCodec ff_cdgraphics_decoder = {
- "cdgraphics",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_CDGRAPHICS,
- sizeof(CDGraphicsContext),
- cdg_decode_init,
- NULL,
- cdg_decode_end,
- cdg_decode_frame,
- CODEC_CAP_DR1,
+ .name = "cdgraphics",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_CDGRAPHICS,
+ .priv_data_size = sizeof(CDGraphicsContext),
+ .init = cdg_decode_init,
+ .close = cdg_decode_end,
+ .decode = cdg_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("CD Graphics video"),
};
diff --git a/libavcodec/celp_filters.h b/libavcodec/celp_filters.h
index 03d481d..cfd08fd 100644
--- a/libavcodec/celp_filters.h
+++ b/libavcodec/celp_filters.h
@@ -34,7 +34,7 @@
*
* fc_out[n] = sum(i,0,len-1){ fc_in[i] * filter[(len + n - i)%len] }
*
- * \note fc_in and fc_out should not overlap!
+ * @note fc_in and fc_out should not overlap!
*/
void ff_celp_convolve_circ(int16_t *fc_out, const int16_t *fc_in,
const int16_t *filter, int len);
diff --git a/libavcodec/celp_math.c b/libavcodec/celp_math.c
index 4ab20ad..8d36d4e 100644
--- a/libavcodec/celp_math.c
+++ b/libavcodec/celp_math.c
@@ -27,82 +27,6 @@
#include "avcodec.h"
#include "celp_math.h"
-#ifdef G729_BITEXACT
-/**
- * Cosine table: base_cos[i] = (1<<15) * cos(i*PI/64)
- */
-static const int16_t base_cos[64] =
-{
- 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853,
- 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279,
- 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010,
- 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608,
- 0, -1608, -3212, -4808, -6393, -7962, -9512, -11039,
- -12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006,
- -23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622,
- -30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729
-};
-
-/**
- * Slope used to compute cos(x)
- *
- * cos(ind*64+offset) = base_cos[ind]+offset*slope_cos[ind]
- * values multiplied by 1<<19
- */
-static const int16_t slope_cos[64] =
-{
- -632, -1893, -3150, -4399, -5638, -6863, -8072, -9261,
- -10428, -11570, -12684, -13767, -14817, -15832, -16808, -17744,
- -18637, -19486, -20287, -21039, -21741, -22390, -22986, -23526,
- -24009, -24435, -24801, -25108, -25354, -25540, -25664, -25726,
- -25726, -25664, -25540, -25354, -25108, -24801, -24435, -24009,
- -23526, -22986, -22390, -21741, -21039, -20287, -19486, -18637,
- -17744, -16808, -15832, -14817, -13767, -12684, -11570, -10428,
- -9261, -8072, -6863, -5638, -4399, -3150, -1893, -632
-};
-
-/**
- * Table used to compute exp2(x)
- *
- * tab_exp2[i] = (1<<14) * exp2(i/32) = 2^(i/32) i=0..32
- */
-static const uint16_t tab_exp2[33] =
-{
- 16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911,
- 20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726,
- 25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706,
- 31379, 32066, 32767
-};
-
-int16_t ff_cos(uint16_t arg)
-{
- uint8_t offset= arg;
- uint8_t ind = arg >> 8;
-
- assert(arg < 0x4000);
-
- return FFMAX(base_cos[ind] + ((slope_cos[ind] * offset) >> 12), -0x8000);
-}
-
-int ff_exp2(uint16_t power)
-{
- uint16_t frac_x0;
- uint16_t frac_dx;
- int result;
-
- assert(power <= 0x7fff);
-
- frac_x0 = power >> 10;
- frac_dx = (power & 0x03ff) << 5;
-
- result = tab_exp2[frac_x0] << 15;
- result += frac_dx * (tab_exp2[frac_x0+1] - tab_exp2[frac_x0]);
-
- return result >> 10;
-}
-
-#else // G729_BITEXACT
-
/**
* Cosine table: base_cos[i] = (1<<15) * cos(i*PI/64)
*/
@@ -154,8 +78,6 @@ int ff_exp2(uint16_t power)
return result + ((result*(power&31)*89)>>22);
}
-#endif // else G729_BITEXACT
-
/**
* Table used to compute log2(x)
*
@@ -163,17 +85,10 @@ int ff_exp2(uint16_t power)
*/
static const uint16_t tab_log2[33] =
{
-#ifdef G729_BITEXACT
- 0, 1455, 2866, 4236, 5568, 6863, 8124, 9352,
- 10549, 11716, 12855, 13967, 15054, 16117, 17156, 18172,
- 19167, 20142, 21097, 22033, 22951, 23852, 24735, 25603,
- 26455, 27291, 28113, 28922, 29716, 30497, 31266, 32023, 32767,
-#else
4, 1459, 2870, 4240, 5572, 6867, 8127, 9355,
10552, 11719, 12858, 13971, 15057, 16120, 17158, 18175,
19170, 20145, 21100, 22036, 22954, 23854, 24738, 25605,
26457, 27294, 28116, 28924, 29719, 30500, 31269, 32025, 32769,
-#endif
};
int ff_log2(uint32_t value)
diff --git a/libavcodec/celp_math.h b/libavcodec/celp_math.h
index 9cd9ae2..4a502ca 100644
--- a/libavcodec/celp_math.h
+++ b/libavcodec/celp_math.h
@@ -64,7 +64,7 @@ static inline int bidir_sal(int value, int offset)
}
/**
- * returns the dot product.
+ * Return the dot product.
* @param a input data array
* @param b input data array
* @param length number of elements
diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c
index 4bda2a7..08ab05f 100644
--- a/libavcodec/cinepak.c
+++ b/libavcodec/cinepak.c
@@ -22,10 +22,11 @@
/**
* @file
* Cinepak video decoder
- * by Ewald Snel <ewald at rambo.its.tudelft.nl>
- * For more information on the Cinepak algorithm, visit:
+ * @author Ewald Snel <ewald at rambo.its.tudelft.nl>
+ *
+ * @see For more information on the Cinepak algorithm, visit:
* http://www.csse.monash.edu.au/~timf/
- * For more information on the quirky data inside Sega FILM/CPK files, visit:
+ * @see For more information on the quirky data inside Sega FILM/CPK files, visit:
* http://wiki.multimedia.cx/index.php?title=Sega_FILM
*/
@@ -147,7 +148,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
for (x=strip->x1; x < strip->x2; x+=4) {
if ((chunk_id & 0x01) && !(mask >>= 1)) {
if ((data + 4) > eod)
- return -1;
+ return AVERROR_INVALIDDATA;
flag = AV_RB32 (data);
data += 4;
@@ -157,7 +158,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
if (!(chunk_id & 0x01) || (flag & mask)) {
if (!(chunk_id & 0x02) && !(mask >>= 1)) {
if ((data + 4) > eod)
- return -1;
+ return AVERROR_INVALIDDATA;
flag = AV_RB32 (data);
data += 4;
@@ -166,7 +167,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
if ((chunk_id & 0x02) || (~flag & mask)) {
if (data >= eod)
- return -1;
+ return AVERROR_INVALIDDATA;
codebook = &strip->v1_codebook[*data++];
s->frame.data[0][iy[0] + 0] = codebook->y0;
@@ -207,7 +208,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
} else if (flag & mask) {
if ((data + 4) > eod)
- return -1;
+ return AVERROR_INVALIDDATA;
codebook = &strip->v4_codebook[*data++];
s->frame.data[0][iy[0] + 0] = codebook->y0;
@@ -269,16 +270,16 @@ static int cinepak_decode_strip (CinepakContext *s,
int chunk_id, chunk_size;
/* coordinate sanity checks */
- if (strip->x1 >= s->width || strip->x2 > s->width ||
- strip->y1 >= s->height || strip->y2 > s->height ||
+ if (strip->x2 > s->width ||
+ strip->y2 > s->height ||
strip->x1 >= strip->x2 || strip->y1 >= strip->y2)
- return -1;
+ return AVERROR_INVALIDDATA;
while ((data + 4) <= eod) {
chunk_id = data[0];
chunk_size = AV_RB24 (&data[1]) - 4;
if(chunk_size < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
data += 4;
chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size;
@@ -311,7 +312,7 @@ static int cinepak_decode_strip (CinepakContext *s,
data += chunk_size;
}
- return -1;
+ return AVERROR_INVALIDDATA;
}
static int cinepak_decode (CinepakContext *s)
@@ -322,21 +323,27 @@ static int cinepak_decode (CinepakContext *s)
int encoded_buf_size;
if (s->size < 10)
- return -1;
+ return AVERROR_INVALIDDATA;
frame_flags = s->data[0];
num_strips = AV_RB16 (&s->data[8]);
- encoded_buf_size = ((s->data[1] << 16) | AV_RB16 (&s->data[2]));
+ encoded_buf_size = AV_RB24(&s->data[1]);
/* if this is the first frame, check for deviant Sega FILM data */
if (s->sega_film_skip_bytes == -1) {
- if (encoded_buf_size != s->size) {
+ if (!encoded_buf_size) {
+ av_log_ask_for_sample(s->avctx, "encoded_buf_size is 0");
+ return AVERROR_INVALIDDATA;
+ }
+ if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) {
/* If the encoded frame size differs from the frame size as indicated
* by the container file, this data likely comes from a Sega FILM/CPK file.
* If the frame header is followed by the bytes FE 00 00 06 00 00 then
* this is probably one of the two known files that have 6 extra bytes
- * after the frame header. Else, assume 2 extra bytes. */
- if ((s->data[10] == 0xFE) &&
+ * after the frame header. Else, assume 2 extra bytes. The container
+ * size also cannot be a multiple of the encoded size. */
+ if (s->size >= 16 &&
+ (s->data[10] == 0xFE) &&
(s->data[11] == 0x00) &&
(s->data[12] == 0x00) &&
(s->data[13] == 0x06) &&
@@ -351,12 +358,11 @@ static int cinepak_decode (CinepakContext *s)
s->data += 10 + s->sega_film_skip_bytes;
- if (num_strips > MAX_STRIPS)
- num_strips = MAX_STRIPS;
+ num_strips = FFMIN(num_strips, MAX_STRIPS);
for (i=0; i < num_strips; i++) {
if ((s->data + 12) > eod)
- return -1;
+ return AVERROR_INVALIDDATA;
s->strips[i].id = s->data[0];
s->strips[i].y1 = y0;
@@ -365,6 +371,8 @@ static int cinepak_decode (CinepakContext *s)
s->strips[i].x2 = s->avctx->width;
strip_size = AV_RB24 (&s->data[1]) - 12;
+ if (strip_size < 0)
+ return AVERROR_INVALIDDATA;
s->data += 12;
strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size;
@@ -414,7 +422,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
+ int ret = 0, buf_size = avpkt->size;
CinepakContext *s = avctx->priv_data;
s->data = buf;
@@ -423,9 +431,9 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
s->frame.reference = 1;
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
FF_BUFFER_HINTS_REUSABLE;
- if (avctx->reget_buffer(avctx, &s->frame)) {
+ if ((ret = avctx->reget_buffer(avctx, &s->frame))) {
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
- return -1;
+ return ret;
}
if (s->palette_video) {
@@ -459,14 +467,13 @@ static av_cold int cinepak_decode_end(AVCodecContext *avctx)
}
AVCodec ff_cinepak_decoder = {
- "cinepak",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_CINEPAK,
- sizeof(CinepakContext),
- cinepak_decode_init,
- NULL,
- cinepak_decode_end,
- cinepak_decode_frame,
- CODEC_CAP_DR1,
+ .name = "cinepak",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_CINEPAK,
+ .priv_data_size = sizeof(CinepakContext),
+ .init = cinepak_decode_init,
+ .close = cinepak_decode_end,
+ .decode = cinepak_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Cinepak"),
};
diff --git a/libavcodec/cljr.c b/libavcodec/cljr.c
index b83919e..cf307bb 100644
--- a/libavcodec/cljr.c
+++ b/libavcodec/cljr.c
@@ -25,143 +25,150 @@
*/
#include "avcodec.h"
-#include "dsputil.h"
#include "get_bits.h"
+#include "put_bits.h"
-/* Disable the encoder. */
-#undef CONFIG_CLJR_ENCODER
-#define CONFIG_CLJR_ENCODER 0
-
-typedef struct CLJRContext{
- AVCodecContext *avctx;
- AVFrame picture;
- int delta[16];
- int offset[4];
- GetBitContext gb;
+typedef struct CLJRContext {
+ AVFrame picture;
} CLJRContext;
+static av_cold int common_init(AVCodecContext *avctx)
+{
+ CLJRContext * const a = avctx->priv_data;
+
+ avctx->coded_frame = &a->picture;
+
+ return 0;
+}
+
+#if CONFIG_CLJR_DECODER
static int decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
+ int buf_size = avpkt->size;
CLJRContext * const a = avctx->priv_data;
+ GetBitContext gb;
AVFrame *picture = data;
- AVFrame * const p= (AVFrame*)&a->picture;
+ AVFrame * const p = &a->picture;
int x, y;
- if(p->data[0])
+ if (p->data[0])
avctx->release_buffer(avctx, p);
- if(buf_size/avctx->height < avctx->width) {
- av_log(avctx, AV_LOG_ERROR, "Resolution larger than buffer size. Invalid header?\n");
- return -1;
+ if (avctx->height <= 0 || avctx->width <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid width or height\n");
+ return AVERROR_INVALIDDATA;
}
- p->reference= 0;
- if(avctx->get_buffer(avctx, p) < 0){
+ if (buf_size < avctx->height * avctx->width) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Resolution larger than buffer size. Invalid header?\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ p->reference = 0;
+ if (avctx->get_buffer(avctx, p) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
- p->pict_type= AV_PICTURE_TYPE_I;
- p->key_frame= 1;
-
- init_get_bits(&a->gb, buf, buf_size * 8);
-
- for(y=0; y<avctx->height; y++){
- uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ];
- uint8_t *cb= &a->picture.data[1][ y*a->picture.linesize[1] ];
- uint8_t *cr= &a->picture.data[2][ y*a->picture.linesize[2] ];
- for(x=0; x<avctx->width; x+=4){
- luma[3] = get_bits(&a->gb, 5) << 3;
- luma[2] = get_bits(&a->gb, 5) << 3;
- luma[1] = get_bits(&a->gb, 5) << 3;
- luma[0] = get_bits(&a->gb, 5) << 3;
- luma+= 4;
- *(cb++) = get_bits(&a->gb, 6) << 2;
- *(cr++) = get_bits(&a->gb, 6) << 2;
+ p->pict_type = AV_PICTURE_TYPE_I;
+ p->key_frame = 1;
+
+ init_get_bits(&gb, buf, buf_size * 8);
+
+ for (y = 0; y < avctx->height; y++) {
+ uint8_t *luma = &a->picture.data[0][y * a->picture.linesize[0]];
+ uint8_t *cb = &a->picture.data[1][y * a->picture.linesize[1]];
+ uint8_t *cr = &a->picture.data[2][y * a->picture.linesize[2]];
+ for (x = 0; x < avctx->width; x += 4) {
+ luma[3] = get_bits(&gb, 5) << 3;
+ luma[2] = get_bits(&gb, 5) << 3;
+ luma[1] = get_bits(&gb, 5) << 3;
+ luma[0] = get_bits(&gb, 5) << 3;
+ luma += 4;
+ *(cb++) = get_bits(&gb, 6) << 2;
+ *(cr++) = get_bits(&gb, 6) << 2;
}
}
- *picture= *(AVFrame*)&a->picture;
+ *picture = a->picture;
*data_size = sizeof(AVPicture);
- emms_c();
-
return buf_size;
}
-#if CONFIG_CLJR_ENCODER
-static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
- CLJRContext * const a = avctx->priv_data;
- AVFrame *pict = data;
- AVFrame * const p= (AVFrame*)&a->picture;
- int size;
-
- *p = *pict;
- p->pict_type= AV_PICTURE_TYPE_I;
- p->key_frame= 1;
-
- emms_c();
-
- align_put_bits(&a->pb);
- while(get_bit_count(&a->pb)&31)
- put_bits(&a->pb, 8, 0);
-
- size= get_bit_count(&a->pb)/32;
-
- return size*4;
-}
-#endif
-
-static av_cold void common_init(AVCodecContext *avctx){
- CLJRContext * const a = avctx->priv_data;
-
- avctx->coded_frame= (AVFrame*)&a->picture;
- a->avctx= avctx;
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ avctx->pix_fmt = PIX_FMT_YUV411P;
+ return common_init(avctx);
}
-static av_cold int decode_init(AVCodecContext *avctx){
-
- common_init(avctx);
-
- avctx->pix_fmt= PIX_FMT_YUV411P;
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ CLJRContext *a = avctx->priv_data;
+ if (a->picture.data[0])
+ avctx->release_buffer(avctx, &a->picture);
return 0;
}
+AVCodec ff_cljr_decoder = {
+ .name = "cljr",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_CLJR,
+ .priv_data_size = sizeof(CLJRContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
+};
+#endif
+
#if CONFIG_CLJR_ENCODER
-static av_cold int encode_init(AVCodecContext *avctx){
+static int encode_frame(AVCodecContext *avctx, unsigned char *buf,
+ int buf_size, void *data)
+{
+ PutBitContext pb;
+ AVFrame *p = data;
+ int x, y;
- common_init(avctx);
+ p->pict_type = AV_PICTURE_TYPE_I;
+ p->key_frame = 1;
+
+ init_put_bits(&pb, buf, buf_size / 8);
+
+ for (y = 0; y < avctx->height; y++) {
+ uint8_t *luma = &p->data[0][y * p->linesize[0]];
+ uint8_t *cb = &p->data[1][y * p->linesize[1]];
+ uint8_t *cr = &p->data[2][y * p->linesize[2]];
+ for (x = 0; x < avctx->width; x += 4) {
+ put_bits(&pb, 5, luma[3] >> 3);
+ put_bits(&pb, 5, luma[2] >> 3);
+ put_bits(&pb, 5, luma[1] >> 3);
+ put_bits(&pb, 5, luma[0] >> 3);
+ luma += 4;
+ put_bits(&pb, 6, *(cb++) >> 2);
+ put_bits(&pb, 6, *(cr++) >> 2);
+ }
+ }
- return 0;
-}
-#endif
+ flush_put_bits(&pb);
-AVCodec ff_cljr_decoder = {
- "cljr",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_CLJR,
- sizeof(CLJRContext),
- decode_init,
- NULL,
- NULL,
- decode_frame,
- CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
-};
+ return put_bits_count(&pb) / 8;
+}
-#if CONFIG_CLJR_ENCODER
AVCodec ff_cljr_encoder = {
- "cljr",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_CLJR,
- sizeof(CLJRContext),
- encode_init,
- encode_frame,
- //encode_end,
- .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
+ .name = "cljr",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_CLJR,
+ .priv_data_size = sizeof(CLJRContext),
+ .init = common_init,
+ .encode = encode_frame,
+ .pix_fmts = (const enum PixelFormat[]) { PIX_FMT_YUV411P,
+ PIX_FMT_NONE },
+ .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
};
#endif
diff --git a/libavcodec/cook.c b/libavcodec/cook.c
index 05d8d7a..81a1aae 100644
--- a/libavcodec/cook.c
+++ b/libavcodec/cook.c
@@ -42,12 +42,7 @@
* available.
*/
-#include <math.h>
-#include <stddef.h>
-#include <stdio.h>
-
#include "libavutil/lfg.h"
-#include "libavutil/random_seed.h"
#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
@@ -124,9 +119,10 @@ typedef struct cook {
void (* interpolate) (struct cook *q, float* buffer,
int gain_index, int gain_index_next);
- void (* saturate_output) (struct cook *q, int chan, int16_t *out);
+ void (* saturate_output) (struct cook *q, int chan, float *out);
AVCodecContext* avctx;
+ AVFrame frame;
GetBitContext gb;
/* stream data */
int nb_channels;
@@ -136,6 +132,7 @@ typedef struct cook {
int samples_per_channel;
/* states */
AVLFG random_state;
+ int discarded_packets;
/* transform data */
FFTContext mdct_ctx;
@@ -217,11 +214,11 @@ static av_cold int init_cook_vlc_tables(COOKContext *q) {
}
static av_cold int init_cook_mlt(COOKContext *q) {
- int j;
+ int j, ret;
int mlt_size = q->samples_per_channel;
- if ((q->mlt_window = av_malloc(sizeof(float)*mlt_size)) == 0)
- return -1;
+ if ((q->mlt_window = av_malloc(mlt_size * sizeof(*q->mlt_window))) == 0)
+ return AVERROR(ENOMEM);
/* Initialize the MLT window: simple sine window. */
ff_sine_window_init(q->mlt_window, mlt_size);
@@ -229,9 +226,9 @@ static av_cold int init_cook_mlt(COOKContext *q) {
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, 1.0)) {
- av_free(q->mlt_window);
- return -1;
+ if ((ret = ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1, 1.0/32768.0))) {
+ av_free(q->mlt_window);
+ return ret;
}
av_log(q->avctx,AV_LOG_DEBUG,"MDCT initialized, order = %d.\n",
av_log2(mlt_size)+1);
@@ -278,6 +275,10 @@ static av_cold void init_cplscales_table (COOKContext *q) {
*/
static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){
+ static const uint32_t tab[4] = {
+ AV_BE2NE32C(0x37c511f2), AV_BE2NE32C(0xf237c511),
+ AV_BE2NE32C(0x11f237c5), AV_BE2NE32C(0xc511f237),
+ };
int i, off;
uint32_t c;
const uint32_t* buf;
@@ -290,7 +291,7 @@ static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes)
off = (intptr_t)inbuffer & 3;
buf = (const uint32_t*) (inbuffer - off);
- c = av_be2ne32((0x37c511f2 >> (off*8)) | (0x37c511f2 << (32-(off*8))));
+ c = tab[off];
bytes += 3 + off;
for (i = 0; i < bytes/4; i++)
obuf[i] = c ^ buf[i];
@@ -410,9 +411,9 @@ static void categorize(COOKContext *q, COOKSubpacket *p, int* quant_index_table,
//av_log(q->avctx, AV_LOG_ERROR, "bits_left = %d\n",bits_left);
}
- memset(&exp_index1,0,102*sizeof(int));
- memset(&exp_index2,0,102*sizeof(int));
- memset(&tmp_categorize_array,0,128*2*sizeof(int));
+ memset(&exp_index1, 0, sizeof(exp_index1));
+ memset(&exp_index2, 0, sizeof(exp_index2));
+ memset(&tmp_categorize_array, 0, sizeof(tmp_categorize_array));
bias=-32;
@@ -633,8 +634,8 @@ static void mono_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer) {
int quant_index_table[102];
int category[128];
- memset(&category, 0, 128*sizeof(int));
- memset(&category_index, 0, 128*sizeof(int));
+ memset(&category, 0, sizeof(category));
+ memset(&category_index, 0, sizeof(category_index));
decode_envelope(q, p, quant_index_table);
q->num_vectors = get_bits(&q->gb,p->log2_numvector_size);
@@ -663,14 +664,12 @@ static void interpolate_float(COOKContext *q, float* buffer,
for(i=0 ; i<q->gain_size_factor ; i++){
buffer[i]*=fc1;
}
- return;
} else { //smooth gain
fc2 = q->gain_table[11 + (gain_index_next-gain_index)];
for(i=0 ; i<q->gain_size_factor ; i++){
buffer[i]*=fc1;
fc1*=fc2;
}
- return;
}
}
@@ -733,7 +732,8 @@ static void imlt_gain(COOKContext *q, float *inbuffer,
}
/* Save away the current to be previous block. */
- memcpy(previous_buffer, buffer0, sizeof(float)*q->samples_per_channel);
+ memcpy(previous_buffer, buffer0,
+ q->samples_per_channel * sizeof(*previous_buffer));
}
@@ -744,27 +744,24 @@ static void imlt_gain(COOKContext *q, float *inbuffer,
* @param decouple_tab decoupling array
*
*/
+static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab)
+{
+ int i;
+ int vlc = get_bits1(&q->gb);
+ int start = cplband[p->js_subband_start];
+ int end = cplband[p->subbands-1];
+ int length = end - start + 1;
-static void decouple_info(COOKContext *q, COOKSubpacket *p, int* decouple_tab){
- int length, i;
-
- if(get_bits1(&q->gb)) {
- if(cplband[p->js_subband_start] > cplband[p->subbands-1]) return;
-
- length = cplband[p->subbands-1] - cplband[p->js_subband_start] + 1;
- for (i=0 ; i<length ; i++) {
- decouple_tab[cplband[p->js_subband_start] + i] = get_vlc2(&q->gb, p->ccpl.table, p->ccpl.bits, 2);
- }
+ if (start > end)
return;
- }
-
- if(cplband[p->js_subband_start] > cplband[p->subbands-1]) return;
- length = cplband[p->subbands-1] - cplband[p->js_subband_start] + 1;
- for (i=0 ; i<length ; i++) {
- decouple_tab[cplband[p->js_subband_start] + i] = get_bits(&q->gb, p->js_vlc_bits);
+ if (vlc) {
+ for (i = 0; i < length; i++)
+ decouple_tab[start + i] = get_vlc2(&q->gb, p->ccpl.table, p->ccpl.bits, 2);
+ } else {
+ for (i = 0; i < length; i++)
+ decouple_tab[start + i] = get_bits(&q->gb, p->js_vlc_bits);
}
- return;
}
/*
@@ -811,11 +808,11 @@ static void joint_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer1,
const float* cplscale;
memset(decouple_tab, 0, sizeof(decouple_tab));
- memset(decode_buffer, 0, sizeof(decode_buffer));
+ memset(decode_buffer, 0, sizeof(q->decode_buffer_0));
/* Make sure the buffers are zeroed out. */
- memset(mlt_buffer1,0, 1024*sizeof(float));
- memset(mlt_buffer2,0, 1024*sizeof(float));
+ memset(mlt_buffer1, 0, 1024 * sizeof(*mlt_buffer1));
+ memset(mlt_buffer2, 0, 1024 * sizeof(*mlt_buffer2));
decouple_info(q, p, decouple_tab);
mono_decode(q, p, decode_buffer);
@@ -867,22 +864,18 @@ decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p, const uint8_t *inbuffer,
}
/**
- * Saturate the output signal to signed 16bit integers.
+ * Saturate the output signal and interleave.
*
* @param q pointer to the COOKContext
* @param chan channel to saturate
* @param out pointer to the output vector
*/
-static void
-saturate_output_float (COOKContext *q, int chan, int16_t *out)
+static void saturate_output_float(COOKContext *q, int chan, float *out)
{
int j;
float *output = q->mono_mdct_output + q->samples_per_channel;
- /* Clip and convert floats to 16 bits.
- */
for (j = 0; j < q->samples_per_channel; j++) {
- out[chan + q->nb_channels * j] =
- av_clip_int16(lrintf(output[j]));
+ out[chan + q->nb_channels * j] = av_clipf(output[j], -1.0, 1.0);
}
}
@@ -902,10 +895,11 @@ saturate_output_float (COOKContext *q, int chan, int16_t *out)
static inline void
mlt_compensate_output(COOKContext *q, float *decode_buffer,
cook_gains *gains_ptr, float *previous_buffer,
- int16_t *out, int chan)
+ float *out, int chan)
{
imlt_gain(q, decode_buffer, gains_ptr, previous_buffer);
- q->saturate_output (q, chan, out);
+ if (out)
+ q->saturate_output(q, chan, out);
}
@@ -917,7 +911,9 @@ mlt_compensate_output(COOKContext *q, float *decode_buffer,
* @param inbuffer pointer to the inbuffer
* @param outbuffer pointer to the outbuffer
*/
-static void decode_subpacket(COOKContext *q, COOKSubpacket* p, const uint8_t *inbuffer, int16_t *outbuffer) {
+static void decode_subpacket(COOKContext *q, COOKSubpacket *p,
+ const uint8_t *inbuffer, float *outbuffer)
+{
int sub_packet_size = p->size;
/* packet dump */
// for (i=0 ; i<sub_packet_size ; i++) {
@@ -960,19 +956,30 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket* p, const uint8_t *in
* @param avctx pointer to the AVCodecContext
*/
-static int cook_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt) {
+static int cook_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
COOKContext *q = avctx->priv_data;
- int i;
+ float *samples = NULL;
+ int i, ret;
int offset = 0;
int chidx = 0;
if (buf_size < avctx->block_align)
return buf_size;
+ /* get output buffer */
+ if (q->discarded_packets >= 2) {
+ q->frame.nb_samples = q->samples_per_channel;
+ if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (float *)q->frame.data[0];
+ }
+
/* estimate subpacket sizes */
q->subpacket[0].size = avctx->block_align;
@@ -981,25 +988,30 @@ static int cook_decode_frame(AVCodecContext *avctx,
q->subpacket[0].size -= q->subpacket[i].size + 1;
if (q->subpacket[0].size < 0) {
av_log(avctx,AV_LOG_DEBUG,"frame subpacket size total > avctx->block_align!\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
/* decode supbackets */
- *data_size = 0;
for(i=0;i<q->num_subpackets;i++){
q->subpacket[i].bits_per_subpacket = (q->subpacket[i].size*8)>>q->subpacket[i].bits_per_subpdiv;
q->subpacket[i].ch_idx = chidx;
av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] size %i js %i %i block_align %i\n",i,q->subpacket[i].size,q->subpacket[i].joint_stereo,offset,avctx->block_align);
- decode_subpacket(q, &q->subpacket[i], buf + offset, (int16_t*)data);
+ decode_subpacket(q, &q->subpacket[i], buf + offset, samples);
offset += q->subpacket[i].size;
chidx += q->subpacket[i].num_channels;
av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] %i %i\n",i,q->subpacket[i].size * 8,get_bits_count(&q->gb));
}
- *data_size = sizeof(int16_t) * q->nb_channels * q->samples_per_channel;
/* Discard the first two frames: no valid audio. */
- if (avctx->frame_number < 2) *data_size = 0;
+ if (q->discarded_packets < 2) {
+ q->discarded_packets++;
+ *got_frame_ptr = 0;
+ return avctx->block_align;
+ }
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = q->frame;
return avctx->block_align;
}
@@ -1053,12 +1065,13 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
int extradata_size = avctx->extradata_size;
int s = 0;
unsigned int channel_mask = 0;
+ int ret;
q->avctx = avctx;
/* Take care of the codec specific extradata. */
if (extradata_size <= 0) {
av_log(avctx,AV_LOG_ERROR,"Necessary extradata missing!\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
av_log(avctx,AV_LOG_DEBUG,"codecdata_length=%d\n",avctx->extradata_size);
@@ -1079,7 +1092,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr);
extradata_size -= 8;
}
- if (avctx->extradata_size >= 8){
+ if (extradata_size >= 8) {
bytestream_get_be32(&edata_ptr); //Unknown unused
q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr);
q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr);
@@ -1103,7 +1116,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
case MONO:
if (q->nb_channels != 1) {
av_log_ask_for_sample(avctx, "Container channels != 1.\n");
- return -1;
+ return AVERROR_PATCHWELCOME;
}
av_log(avctx,AV_LOG_DEBUG,"MONO\n");
break;
@@ -1117,7 +1130,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
case JOINT_STEREO:
if (q->nb_channels != 2) {
av_log_ask_for_sample(avctx, "Container channels != 2.\n");
- return -1;
+ return AVERROR_PATCHWELCOME;
}
av_log(avctx,AV_LOG_DEBUG,"JOINT_STEREO\n");
if (avctx->extradata_size >= 16){
@@ -1155,13 +1168,12 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
break;
default:
av_log_ask_for_sample(avctx, "Unknown Cook version.\n");
- return -1;
- break;
+ return AVERROR_PATCHWELCOME;
}
if(s > 1 && q->subpacket[s].samples_per_channel != q->samples_per_channel) {
av_log(avctx,AV_LOG_ERROR,"different number of samples per channel!\n");
- return -1;
+ return AVERROR_INVALIDDATA;
} else
q->samples_per_channel = q->subpacket[0].samples_per_channel;
@@ -1172,17 +1184,18 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
/* Try to catch some obviously faulty streams, othervise it might be exploitable */
if (q->subpacket[s].total_subbands > 53) {
av_log_ask_for_sample(avctx, "total_subbands > 53\n");
- return -1;
+ return AVERROR_PATCHWELCOME;
}
- if ((q->subpacket[s].js_vlc_bits > 6) || (q->subpacket[s].js_vlc_bits < 0)) {
- av_log(avctx,AV_LOG_ERROR,"js_vlc_bits = %d, only >= 0 and <= 6 allowed!\n",q->subpacket[s].js_vlc_bits);
- return -1;
+ if ((q->subpacket[s].js_vlc_bits > 6) || (q->subpacket[s].js_vlc_bits < 2*q->subpacket[s].joint_stereo)) {
+ av_log(avctx,AV_LOG_ERROR,"js_vlc_bits = %d, only >= %d and <= 6 allowed!\n",
+ q->subpacket[s].js_vlc_bits, 2*q->subpacket[s].joint_stereo);
+ return AVERROR_INVALIDDATA;
}
if (q->subpacket[s].subbands > 50) {
av_log_ask_for_sample(avctx, "subbands > 50\n");
- return -1;
+ return AVERROR_PATCHWELCOME;
}
q->subpacket[s].gains1.now = q->subpacket[s].gain_1;
q->subpacket[s].gains1.previous = q->subpacket[s].gain_2;
@@ -1193,7 +1206,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
s++;
if (s > MAX_SUBPACKETS) {
av_log_ask_for_sample(avctx, "Too many subpackets > 5\n");
- return -1;
+ return AVERROR_PATCHWELCOME;
}
}
/* Generate tables */
@@ -1201,12 +1214,12 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
init_gain_table(q);
init_cplscales_table(q);
- if (init_cook_vlc_tables(q) != 0)
- return -1;
+ if ((ret = init_cook_vlc_tables(q)))
+ return ret;
if(avctx->block_align >= UINT_MAX/2)
- return -1;
+ return AVERROR(EINVAL);
/* Pad the databuffer with:
DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(),
@@ -1216,11 +1229,11 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
+ DECODE_BYTES_PAD1(avctx->block_align)
+ FF_INPUT_BUFFER_PADDING_SIZE);
if (q->decoded_bytes_buffer == NULL)
- return -1;
+ return AVERROR(ENOMEM);
/* Initialize transform. */
- if ( init_cook_mlt(q) != 0 )
- return -1;
+ if ((ret = init_cook_mlt(q)))
+ return ret;
/* Initialize COOK signal arithmetic handling */
if (1) {
@@ -1237,15 +1250,18 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
av_log_ask_for_sample(avctx,
"unknown amount of samples_per_channel = %d\n",
q->samples_per_channel);
- return -1;
+ return AVERROR_PATCHWELCOME;
}
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
if (channel_mask)
avctx->channel_layout = channel_mask;
else
avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
+ avcodec_get_frame_defaults(&q->frame);
+ avctx->coded_frame = &q->frame;
+
#ifdef DEBUG
dump_cook_context(q);
#endif
@@ -1262,5 +1278,6 @@ AVCodec ff_cook_decoder =
.init = cook_decode_init,
.close = cook_decode_close,
.decode = cook_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("COOK"),
};
diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c
index 3518929..00921bc 100644
--- a/libavcodec/cscd.c
+++ b/libavcodec/cscd.c
@@ -255,15 +255,14 @@ static av_cold int decode_end(AVCodecContext *avctx) {
}
AVCodec ff_cscd_decoder = {
- "camstudio",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_CSCD,
- sizeof(CamStudioContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "camstudio",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_CSCD,
+ .priv_data_size = sizeof(CamStudioContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("CamStudio"),
};
diff --git a/libavcodec/cyuv.c b/libavcodec/cyuv.c
index ecdec17..60cce82 100644
--- a/libavcodec/cyuv.c
+++ b/libavcodec/cyuv.c
@@ -179,32 +179,28 @@ static av_cold int cyuv_decode_end(AVCodecContext *avctx)
#if CONFIG_AURA_DECODER
AVCodec ff_aura_decoder = {
- "aura",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_AURA,
- sizeof(CyuvDecodeContext),
- cyuv_decode_init,
- NULL,
- cyuv_decode_end,
- cyuv_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "aura",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_AURA,
+ .priv_data_size = sizeof(CyuvDecodeContext),
+ .init = cyuv_decode_init,
+ .close = cyuv_decode_end,
+ .decode = cyuv_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Auravision AURA"),
};
#endif
#if CONFIG_CYUV_DECODER
AVCodec ff_cyuv_decoder = {
- "cyuv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_CYUV,
- sizeof(CyuvDecodeContext),
- cyuv_decode_init,
- NULL,
- cyuv_decode_end,
- cyuv_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "cyuv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_CYUV,
+ .priv_data_size = sizeof(CyuvDecodeContext),
+ .init = cyuv_decode_init,
+ .close = cyuv_decode_end,
+ .decode = cyuv_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Creative YUV (CYUV)"),
};
#endif
diff --git a/libavcodec/dca.c b/libavcodec/dca.c
index fad6bce..e3f87b9 100644
--- a/libavcodec/dca.c
+++ b/libavcodec/dca.c
@@ -42,6 +42,10 @@
#include "dcadsp.h"
#include "fmtconvert.h"
+#if ARCH_ARM
+# include "arm/dca.h"
+#endif
+
//#define TRACE
#define DCA_PRIM_CHANNELS_MAX (7)
@@ -124,7 +128,7 @@ static const int dca_ext_audio_descr_mask[] = {
* All 2 channel configurations -> AV_CH_LAYOUT_STEREO
*/
-static const int64_t dca_core_channel_layout[] = {
+static const uint64_t dca_core_channel_layout[] = {
AV_CH_FRONT_CENTER, ///< 1, A
AV_CH_LAYOUT_STEREO, ///< 2, A + B (dual mono)
AV_CH_LAYOUT_STEREO, ///< 2, L + R (stereo)
@@ -257,6 +261,7 @@ static av_always_inline int get_bitalloc(GetBitContext *gb, BitAlloc *ba, int id
typedef struct {
AVCodecContext *avctx;
+ AVFrame frame;
/* Frame header */
int frame_type; ///< type of the current frame
int samples_deficit; ///< deficit sample count
@@ -320,7 +325,7 @@ typedef struct {
int lfe_scale_factor;
/* Subband samples history (for ADPCM) */
- float subband_samples_hist[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4];
+ DECLARE_ALIGNED(16, float, subband_samples_hist)[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4];
DECLARE_ALIGNED(32, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512];
DECLARE_ALIGNED(32, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][32];
int hist_index[DCA_PRIM_CHANNELS_MAX];
@@ -516,7 +521,7 @@ static int dca_parse_frame_header(DCAContext * s)
init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);
/* Sync code */
- get_bits(&s->gb, 32);
+ skip_bits_long(&s->gb, 32);
/* Frame header */
s->frame_type = get_bits(&s->gb, 1);
@@ -525,15 +530,15 @@ static int dca_parse_frame_header(DCAContext * s)
s->sample_blocks = get_bits(&s->gb, 7) + 1;
s->frame_size = get_bits(&s->gb, 14) + 1;
if (s->frame_size < 95)
- return -1;
+ return AVERROR_INVALIDDATA;
s->amode = get_bits(&s->gb, 6);
s->sample_rate = dca_sample_rates[get_bits(&s->gb, 4)];
if (!s->sample_rate)
- return -1;
+ return AVERROR_INVALIDDATA;
s->bit_rate_index = get_bits(&s->gb, 5);
s->bit_rate = dca_bit_rates[s->bit_rate_index];
if (!s->bit_rate)
- return -1;
+ return AVERROR_INVALIDDATA;
s->downmix = get_bits(&s->gb, 1);
s->dynrange = get_bits(&s->gb, 1);
@@ -623,7 +628,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index
int j, k;
if (get_bits_left(&s->gb) < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
if (!base_channel) {
s->subsubframes[s->current_subframe] = get_bits(&s->gb, 2) + 1;
@@ -655,7 +660,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index
else if (s->bitalloc_huffman[j] == 7) {
av_log(s->avctx, AV_LOG_ERROR,
"Invalid bit allocation index\n");
- return -1;
+ return AVERROR_INVALIDDATA;
} else {
s->bitalloc[j][k] =
get_bitalloc(&s->gb, &dca_bitalloc_index, s->bitalloc_huffman[j]);
@@ -664,7 +669,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index
if (s->bitalloc[j][k] > 26) {
// av_log(s->avctx,AV_LOG_DEBUG,"bitalloc index [%i][%i] too big (%i)\n",
// j, k, s->bitalloc[j][k]);
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
}
@@ -682,7 +687,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index
}
if (get_bits_left(&s->gb) < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
for (j = base_channel; j < s->prim_channels; j++) {
const uint32_t *scale_table;
@@ -720,7 +725,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index
}
if (get_bits_left(&s->gb) < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
/* Scale factors for joint subband coding */
for (j = base_channel; j < s->prim_channels; j++) {
@@ -898,15 +903,17 @@ static void qmf_32_subbands(DCAContext * s, int chans,
else /* Perfect reconstruction */
prCoeff = fir_32bands_perfect;
+ for (i = sb_act; i < 32; i++)
+ s->raXin[i] = 0.0;
+
/* Reconstructed channel sample index */
for (subindex = 0; subindex < 8; subindex++) {
/* Load in one sample from each subband and clear inactive subbands */
for (i = 0; i < sb_act; i++){
- uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ ((i-1)&2)<<30;
+ unsigned sign = (i - 1) & 2;
+ uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30;
AV_WN32A(&s->raXin[i], v);
}
- for (; i < 32; i++)
- s->raXin[i] = 0.0;
s->synth.synth_filter_float(&s->imdct,
s->subband_fir_hist[chans], &s->hist_index[chans],
@@ -1032,6 +1039,7 @@ static void dca_downmix(float *samples, int srcfmt,
}
+#ifndef decode_blockcodes
/* Very compact version of the block code decoder that does not use table
* look-up but is slightly slower */
static int decode_blockcode(int code, int levels, int *values)
@@ -1045,17 +1053,29 @@ static int decode_blockcode(int code, int levels, int *values)
code = div;
}
- if (code == 0)
- return 0;
- else {
- av_log(NULL, AV_LOG_ERROR, "ERROR: block code look-up failed\n");
- return -1;
- }
+ return code;
}
+static int decode_blockcodes(int code1, int code2, int levels, int *values)
+{
+ return decode_blockcode(code1, levels, values) |
+ decode_blockcode(code2, levels, values + 4);
+}
+#endif
+
static const uint8_t abits_sizes[7] = { 7, 10, 12, 13, 15, 17, 19 };
static const uint8_t abits_levels[7] = { 3, 5, 7, 9, 13, 17, 25 };
+#ifndef int8x8_fmul_int32
+static inline void int8x8_fmul_int32(float *dst, const int8_t *src, int scale)
+{
+ float fscale = scale / 16.0;
+ int i;
+ for (i = 0; i < 8; i++)
+ dst[i] = src[i] * fscale;
+}
+#endif
+
static int dca_subsubframe(DCAContext * s, int base_channel, int block_index)
{
int k, l;
@@ -1079,7 +1099,7 @@ static int dca_subsubframe(DCAContext * s, int base_channel, int block_index)
for (k = base_channel; k < s->prim_channels; k++) {
if (get_bits_left(&s->gb) < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
for (l = 0; l < s->vq_start_subband[k]; l++) {
int m;
@@ -1109,16 +1129,20 @@ static int dca_subsubframe(DCAContext * s, int base_channel, int block_index)
if (abits >= 11 || !dca_smpl_bitalloc[abits].vlc[sel].table){
if (abits <= 7){
/* Block code */
- int block_code1, block_code2, size, levels;
+ int block_code1, block_code2, size, levels, err;
size = abits_sizes[abits-1];
levels = abits_levels[abits-1];
block_code1 = get_bits(&s->gb, size);
- /* FIXME Should test return value */
- decode_blockcode(block_code1, levels, block);
block_code2 = get_bits(&s->gb, size);
- decode_blockcode(block_code2, levels, &block[4]);
+ err = decode_blockcodes(block_code1, block_code2,
+ levels, block);
+ if (err) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "ERROR: block code look-up failed\n");
+ return AVERROR_INVALIDDATA;
+ }
}else{
/* no coding */
for (m = 0; m < 8; m++)
@@ -1160,19 +1184,16 @@ static int dca_subsubframe(DCAContext * s, int base_channel, int block_index)
for (l = s->vq_start_subband[k]; l < s->subband_activity[k]; l++) {
/* 1 vector -> 32 samples but we only need the 8 samples
* for this subsubframe. */
- int m;
+ int hfvq = s->high_freq_vq[k][l];
if (!s->debug_flag & 0x01) {
av_log(s->avctx, AV_LOG_DEBUG, "Stream with high frequencies VQ coding\n");
s->debug_flag |= 0x01;
}
- for (m = 0; m < 8; m++) {
- subband_samples[k][l][m] =
- high_freq_vq[s->high_freq_vq[k][l]][subsubframe * 8 +
- m]
- * (float) s->scale_factor[k][l][0] / 16.0;
- }
+ int8x8_fmul_int32(subband_samples[k][l],
+ &high_freq_vq[hfvq][subsubframe * 8],
+ s->scale_factor[k][l][0]);
}
}
@@ -1238,7 +1259,7 @@ static int dca_subframe_footer(DCAContext * s, int base_channel)
/* presumably optional information only appears in the core? */
if (!base_channel) {
if (s->timestamp)
- get_bits(&s->gb, 32);
+ skip_bits_long(&s->gb, 32);
if (s->aux_data)
aux_data_count = get_bits(&s->gb, 6);
@@ -1261,12 +1282,13 @@ static int dca_subframe_footer(DCAContext * s, int base_channel)
static int dca_decode_block(DCAContext * s, int base_channel, int block_index)
{
+ int ret;
/* Sanity check */
if (s->current_subframe >= s->subframes) {
av_log(s->avctx, AV_LOG_DEBUG, "check failed: %i>%i",
s->current_subframe, s->subframes);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (!s->current_subsubframe) {
@@ -1274,16 +1296,16 @@ static int dca_decode_block(DCAContext * s, int base_channel, int block_index)
av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_header\n");
#endif
/* Read subframe header */
- if (dca_subframe_header(s, base_channel, block_index))
- return -1;
+ if ((ret = dca_subframe_header(s, base_channel, block_index)))
+ return ret;
}
/* Read subsubframe */
#ifdef TRACE
av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subsubframe\n");
#endif
- if (dca_subsubframe(s, base_channel, block_index))
- return -1;
+ if ((ret = dca_subsubframe(s, base_channel, block_index)))
+ return ret;
/* Update state */
s->current_subsubframe++;
@@ -1296,8 +1318,8 @@ static int dca_decode_block(DCAContext * s, int base_channel, int block_index)
av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_footer\n");
#endif
/* Read subframe footer */
- if (dca_subframe_footer(s, base_channel))
- return -1;
+ if ((ret = dca_subframe_footer(s, base_channel)))
+ return ret;
}
return 0;
@@ -1316,7 +1338,7 @@ static int dca_convert_bitstream(const uint8_t * src, int src_size, uint8_t * ds
PutBitContext pb;
if ((unsigned)src_size > (unsigned)max_size) {
-// av_log(NULL, AV_LOG_ERROR, "Input frame size larger then DCA_MAX_FRAME_SIZE!\n");
+// av_log(NULL, AV_LOG_ERROR, "Input frame size larger than DCA_MAX_FRAME_SIZE!\n");
// return -1;
src_size = max_size;
}
@@ -1340,7 +1362,7 @@ static int dca_convert_bitstream(const uint8_t * src, int src_size, uint8_t * ds
flush_put_bits(&pb);
return (put_bits_count(&pb) + 7) >> 3;
default:
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
@@ -1614,19 +1636,17 @@ static void dca_exss_parse_header(DCAContext *s)
* Main frame decoding function
* FIXME add arguments
*/
-static int dca_decode_frame(AVCodecContext * avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int dca_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
int lfe_samples;
int num_core_channels = 0;
- int i;
- float *samples_flt = data;
- int16_t *samples_s16 = data;
- int out_size;
+ int i, ret;
+ float *samples_flt;
+ int16_t *samples_s16;
DCAContext *s = avctx->priv_data;
int channels;
int core_ss_end;
@@ -1636,16 +1656,15 @@ static int dca_decode_frame(AVCodecContext * avctx,
s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer,
DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);
- if (s->dca_buffer_size == -1) {
+ if (s->dca_buffer_size == AVERROR_INVALIDDATA) {
av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);
- if (dca_parse_frame_header(s) < 0) {
+ if ((ret = dca_parse_frame_header(s)) < 0) {
//seems like the frame is corrupt, try with the next one
- *data_size=0;
- return buf_size;
+ return ret;
}
//set AVCodec values with parsed data
avctx->sample_rate = s->sample_rate;
@@ -1655,7 +1674,10 @@ static int dca_decode_frame(AVCodecContext * avctx,
s->profile = FF_PROFILE_DTS;
for (i = 0; i < (s->sample_blocks / 8); i++) {
- dca_decode_block(s, 0, i);
+ if ((ret = dca_decode_block(s, 0, i))) {
+ av_log(avctx, AV_LOG_ERROR, "error decoding block\n");
+ return ret;
+ }
}
/* record number of core channels incase less than max channels are requested */
@@ -1711,7 +1733,10 @@ static int dca_decode_frame(AVCodecContext * avctx,
dca_parse_audio_coding_header(s, s->xch_base_channel);
for (i = 0; i < (s->sample_blocks / 8); i++) {
- dca_decode_block(s, s->xch_base_channel, i);
+ if ((ret = dca_decode_block(s, s->xch_base_channel, i))) {
+ av_log(avctx, AV_LOG_ERROR, "error decoding XCh extension\n");
+ continue;
+ }
}
s->xch_present = 1;
@@ -1785,7 +1810,7 @@ static int dca_decode_frame(AVCodecContext * avctx,
if (channels > !!s->lfe &&
s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
if (avctx->request_channels == 2 && s->prim_channels > 2) {
channels = 2;
@@ -1794,7 +1819,7 @@ static int dca_decode_frame(AVCodecContext * avctx,
}
} else {
av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n",s->amode);
- return -1;
+ return AVERROR_INVALIDDATA;
}
@@ -1810,14 +1835,17 @@ static int dca_decode_frame(AVCodecContext * avctx,
if (avctx->channels != channels) {
av_log(avctx, AV_LOG_ERROR, "DCA decoder does not support number of "
"channels changing in stream. Skipping frame.\n");
- return -1;
+ return AVERROR_PATCHWELCOME;
}
- out_size = 256 / 8 * s->sample_blocks * channels *
- (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8);
- if (*data_size < out_size)
- return -1;
- *data_size = out_size;
+ /* get output buffer */
+ s->frame.nb_samples = 256 * (s->sample_blocks / 8);
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples_flt = (float *)s->frame.data[0];
+ samples_s16 = (int16_t *)s->frame.data[0];
/* filter to get final output */
for (i = 0; i < (s->sample_blocks / 8); i++) {
@@ -1829,11 +1857,8 @@ static int dca_decode_frame(AVCodecContext * avctx,
float* back_chan = s->samples + s->channel_order_tab[s->xch_base_channel] * 256;
float* lt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 2] * 256;
float* rt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 1] * 256;
- int j;
- for(j = 0; j < 256; ++j) {
- lt_chan[j] -= back_chan[j] * M_SQRT1_2;
- rt_chan[j] -= back_chan[j] * M_SQRT1_2;
- }
+ s->dsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
+ s->dsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
}
if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
@@ -1854,6 +1879,9 @@ static int dca_decode_frame(AVCodecContext * avctx,
s->lfe_data[i] = s->lfe_data[i + lfe_samples];
}
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return buf_size;
}
@@ -1896,6 +1924,9 @@ static av_cold int dca_decode_init(AVCodecContext * avctx)
avctx->channels = avctx->request_channels;
}
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
@@ -1924,7 +1955,7 @@ AVCodec ff_dca_decoder = {
.decode = dca_decode_frame,
.close = dca_decode_end,
.long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
- .capabilities = CODEC_CAP_CHANNEL_CONF,
+ .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
.sample_fmts = (const enum AVSampleFormat[]) {
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
},
diff --git a/libavcodec/dca_parser.c b/libavcodec/dca_parser.c
index 70a3e98..136cc45 100644
--- a/libavcodec/dca_parser.c
+++ b/libavcodec/dca_parser.c
@@ -39,7 +39,7 @@ typedef struct DCAParseContext {
|| state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE)
/**
- * finds the end of the current frame in the bitstream.
+ * Find the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf,
@@ -126,9 +126,9 @@ static int dca_parse(AVCodecParserContext * s,
}
AVCodecParser ff_dca_parser = {
- {CODEC_ID_DTS},
- sizeof(DCAParseContext),
- dca_parse_init,
- dca_parse,
- ff_parse_close,
+ .codec_ids = { CODEC_ID_DTS },
+ .priv_data_size = sizeof(DCAParseContext),
+ .parser_init = dca_parse_init,
+ .parser_parse = dca_parse,
+ .parser_close = ff_parse_close,
};
diff --git a/libavcodec/dcadata.h b/libavcodec/dcadata.h
index ed3ec4e..0a83cdf 100644
--- a/libavcodec/dcadata.h
+++ b/libavcodec/dcadata.h
@@ -4224,7 +4224,7 @@ static const float lossless_quant_d[32] = {
/* Vector quantization tables */
-static const int8_t high_freq_vq[1024][32] =
+DECLARE_ALIGNED(8, static const int8_t, high_freq_vq)[1024][32] =
{
{ 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, 0, 0 },
diff --git a/libavcodec/dct-test.c b/libavcodec/dct-test.c
index d0fe34e..daa95bd 100644
--- a/libavcodec/dct-test.c
+++ b/libavcodec/dct-test.c
@@ -68,12 +68,12 @@ void ff_simple_idct_neon(DCTELEM *data);
void ff_simple_idct_axp(DCTELEM *data);
struct algo {
- const char *name;
- enum { FDCT, IDCT } is_idct;
- void (* func) (DCTELEM *block);
- void (* ref) (DCTELEM *block);
- enum formattag { NO_PERM,MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM, SSE2_PERM, PARTTRANS_PERM } format;
- int mm_support;
+ const char *name;
+ void (*func)(DCTELEM *block);
+ enum formattag { NO_PERM, MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM,
+ SSE2_PERM, PARTTRANS_PERM } format;
+ int mm_support;
+ int nonspec;
};
#ifndef FAAN_POSTSCALE
@@ -84,71 +84,77 @@ struct algo {
static int cpu_flags;
-struct algo algos[] = {
- {"REF-DBL", 0, ff_ref_fdct, ff_ref_fdct, NO_PERM},
- {"FAAN", 0, ff_faandct, ff_ref_fdct, FAAN_SCALE},
- {"FAANI", 1, ff_faanidct, ff_ref_idct, NO_PERM},
- {"IJG-AAN-INT", 0, fdct_ifast, ff_ref_fdct, SCALE_PERM},
- {"IJG-LLM-INT", 0, ff_jpeg_fdct_islow, ff_ref_fdct, NO_PERM},
- {"REF-DBL", 1, ff_ref_idct, ff_ref_idct, NO_PERM},
- {"INT", 1, j_rev_dct, ff_ref_idct, MMX_PERM},
- {"SIMPLE-C", 1, ff_simple_idct, ff_ref_idct, NO_PERM},
+static const struct algo fdct_tab[] = {
+ { "REF-DBL", ff_ref_fdct, NO_PERM },
+ { "FAAN", ff_faandct, FAAN_SCALE },
+ { "IJG-AAN-INT", fdct_ifast, SCALE_PERM },
+ { "IJG-LLM-INT", ff_jpeg_fdct_islow_8, NO_PERM },
#if HAVE_MMX
- {"MMX", 0, ff_fdct_mmx, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_MMX},
-#if HAVE_MMX2
- {"MMX2", 0, ff_fdct_mmx2, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_MMX2},
- {"SSE2", 0, ff_fdct_sse2, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_SSE2},
+ { "MMX", ff_fdct_mmx, NO_PERM, AV_CPU_FLAG_MMX },
+ { "MMX2", ff_fdct_mmx2, NO_PERM, AV_CPU_FLAG_MMX2 },
+ { "SSE2", ff_fdct_sse2, NO_PERM, AV_CPU_FLAG_SSE2 },
#endif
-#if CONFIG_GPL
- {"LIBMPEG2-MMX", 1, ff_mmx_idct, ff_ref_idct, MMX_PERM, AV_CPU_FLAG_MMX},
- {"LIBMPEG2-MMX2", 1, ff_mmxext_idct, ff_ref_idct, MMX_PERM, AV_CPU_FLAG_MMX2},
+#if HAVE_ALTIVEC
+ { "altivecfdct", fdct_altivec, NO_PERM, AV_CPU_FLAG_ALTIVEC },
#endif
- {"SIMPLE-MMX", 1, ff_simple_idct_mmx, ff_ref_idct, MMX_SIMPLE_PERM, AV_CPU_FLAG_MMX},
- {"XVID-MMX", 1, ff_idct_xvid_mmx, ff_ref_idct, NO_PERM, AV_CPU_FLAG_MMX},
- {"XVID-MMX2", 1, ff_idct_xvid_mmx2, ff_ref_idct, NO_PERM, AV_CPU_FLAG_MMX2},
- {"XVID-SSE2", 1, ff_idct_xvid_sse2, ff_ref_idct, SSE2_PERM, AV_CPU_FLAG_SSE2},
+
+#if ARCH_BFIN
+ { "BFINfdct", ff_bfin_fdct, NO_PERM },
#endif
-#if HAVE_ALTIVEC
- {"altivecfdct", 0, fdct_altivec, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_ALTIVEC},
+ { 0 }
+};
+
+static const struct algo idct_tab[] = {
+ { "FAANI", ff_faanidct, NO_PERM },
+ { "REF-DBL", ff_ref_idct, NO_PERM },
+ { "INT", j_rev_dct, MMX_PERM },
+ { "SIMPLE-C", ff_simple_idct_8, NO_PERM },
+
+#if HAVE_MMX
+#if CONFIG_GPL
+ { "LIBMPEG2-MMX", ff_mmx_idct, MMX_PERM, AV_CPU_FLAG_MMX, 1 },
+ { "LIBMPEG2-MMX2", ff_mmxext_idct, MMX_PERM, AV_CPU_FLAG_MMX2, 1 },
+#endif
+ { "SIMPLE-MMX", ff_simple_idct_mmx, MMX_SIMPLE_PERM, AV_CPU_FLAG_MMX },
+ { "XVID-MMX", ff_idct_xvid_mmx, NO_PERM, AV_CPU_FLAG_MMX, 1 },
+ { "XVID-MMX2", ff_idct_xvid_mmx2, NO_PERM, AV_CPU_FLAG_MMX2, 1 },
+ { "XVID-SSE2", ff_idct_xvid_sse2, SSE2_PERM, AV_CPU_FLAG_SSE2, 1 },
#endif
#if ARCH_BFIN
- {"BFINfdct", 0, ff_bfin_fdct, ff_ref_fdct, NO_PERM},
- {"BFINidct", 1, ff_bfin_idct, ff_ref_idct, NO_PERM},
+ { "BFINidct", ff_bfin_idct, NO_PERM },
#endif
#if ARCH_ARM
- {"SIMPLE-ARM", 1, ff_simple_idct_arm, ff_ref_idct, NO_PERM },
- {"INT-ARM", 1, ff_j_rev_dct_arm, ff_ref_idct, MMX_PERM },
+ { "SIMPLE-ARM", ff_simple_idct_arm, NO_PERM },
+ { "INT-ARM", ff_j_rev_dct_arm, MMX_PERM },
+#endif
#if HAVE_ARMV5TE
- {"SIMPLE-ARMV5TE", 1, ff_simple_idct_armv5te, ff_ref_idct, NO_PERM },
+ { "SIMPLE-ARMV5TE", ff_simple_idct_armv5te,NO_PERM },
#endif
#if HAVE_ARMV6
- {"SIMPLE-ARMV6", 1, ff_simple_idct_armv6, ff_ref_idct, MMX_PERM },
+ { "SIMPLE-ARMV6", ff_simple_idct_armv6, MMX_PERM },
#endif
#if HAVE_NEON
- {"SIMPLE-NEON", 1, ff_simple_idct_neon, ff_ref_idct, PARTTRANS_PERM },
+ { "SIMPLE-NEON", ff_simple_idct_neon, PARTTRANS_PERM },
#endif
-#endif /* ARCH_ARM */
#if ARCH_ALPHA
- {"SIMPLE-ALPHA", 1, ff_simple_idct_axp, ff_ref_idct, NO_PERM },
+ { "SIMPLE-ALPHA", ff_simple_idct_axp, NO_PERM },
#endif
- { 0 }
+ { 0 }
};
#define AANSCALE_BITS 12
-uint8_t cropTbl[256 + 2 * MAX_NEG_CROP];
-
static int64_t gettime(void)
{
struct timeval tv;
- gettimeofday(&tv,NULL);
+ gettimeofday(&tv, NULL);
return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}
@@ -157,18 +163,18 @@ static int64_t gettime(void)
static short idct_mmx_perm[64];
-static short idct_simple_mmx_perm[64]={
- 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D,
- 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D,
- 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D,
- 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F,
- 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F,
- 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D,
- 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F,
- 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F,
+static short idct_simple_mmx_perm[64] = {
+ 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D,
+ 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D,
+ 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D,
+ 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F,
+ 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F,
+ 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D,
+ 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F,
+ 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F,
};
-static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7};
+static const uint8_t idct_sse2_row_perm[8] = { 0, 4, 1, 5, 2, 6, 3, 7 };
static void idct_mmx_init(void)
{
@@ -177,13 +183,11 @@ static void idct_mmx_init(void)
/* the mmx/mmxext idct uses a reordered input, so we patch scan tables */
for (i = 0; i < 64; i++) {
idct_mmx_perm[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
-// idct_simple_mmx_perm[i] = simple_block_permute_op(i);
}
}
DECLARE_ALIGNED(16, static DCTELEM, block)[64];
-DECLARE_ALIGNED(8, static DCTELEM, block1)[64];
-DECLARE_ALIGNED(8, static DCTELEM, block_org)[64];
+DECLARE_ALIGNED(8, static DCTELEM, block1)[64];
static inline void mmx_emms(void)
{
@@ -193,187 +197,153 @@ static inline void mmx_emms(void)
#endif
}
-static void dct_error(const char *name, int is_idct,
- void (*fdct_func)(DCTELEM *block),
- void (*fdct_ref)(DCTELEM *block), int form, int test)
+static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng)
{
- int it, i, scale;
- int err_inf, v;
- int64_t err2, ti, ti1, it1;
- int64_t sysErr[64], sysErrMax=0;
- int maxout=0;
- int blockSumErrMax=0, blockSumErr;
- AVLFG prng;
+ int i, j;
- av_lfg_init(&prng, 1);
+ memset(block, 0, 64 * sizeof(*block));
- err_inf = 0;
- err2 = 0;
- for(i=0; i<64; i++) sysErr[i]=0;
- for(it=0;it<NB_ITS;it++) {
- for(i=0;i<64;i++)
- block1[i] = 0;
- switch(test){
- case 0:
- for(i=0;i<64;i++)
- block1[i] = (av_lfg_get(&prng) % 512) -256;
- if (is_idct){
- ff_ref_fdct(block1);
-
- for(i=0;i<64;i++)
- block1[i]>>=3;
- }
+ switch (test) {
+ case 0:
+ for (i = 0; i < 64; i++)
+ block[i] = (av_lfg_get(prng) % 512) - 256;
+ if (is_idct) {
+ ff_ref_fdct(block);
+ for (i = 0; i < 64; i++)
+ block[i] >>= 3;
+ }
break;
- case 1:{
- int num = av_lfg_get(&prng) % 10 + 1;
- for(i=0;i<num;i++)
- block1[av_lfg_get(&prng) % 64] = av_lfg_get(&prng) % 512 -256;
- }break;
- case 2:
- block1[0] = av_lfg_get(&prng) % 4096 - 2048;
- block1[63]= (block1[0]&1)^1;
+ case 1:
+ j = av_lfg_get(prng) % 10 + 1;
+ for (i = 0; i < j; i++)
+ block[av_lfg_get(prng) % 64] = av_lfg_get(prng) % 512 - 256;
break;
- }
+ case 2:
+ block[ 0] = av_lfg_get(prng) % 4096 - 2048;
+ block[63] = (block[0] & 1) ^ 1;
+ break;
+ }
+}
-#if 0 // simulate mismatch control
-{ int sum=0;
- for(i=0;i<64;i++)
- sum+=block1[i];
+static void permute(DCTELEM dst[64], const DCTELEM src[64], int perm)
+{
+ int i;
- if((sum&1)==0) block1[63]^=1;
+ if (perm == MMX_PERM) {
+ for (i = 0; i < 64; i++)
+ dst[idct_mmx_perm[i]] = src[i];
+ } else if (perm == MMX_SIMPLE_PERM) {
+ for (i = 0; i < 64; i++)
+ dst[idct_simple_mmx_perm[i]] = src[i];
+ } else if (perm == SSE2_PERM) {
+ for (i = 0; i < 64; i++)
+ dst[(i & 0x38) | idct_sse2_row_perm[i & 7]] = src[i];
+ } else if (perm == PARTTRANS_PERM) {
+ for (i = 0; i < 64; i++)
+ dst[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = src[i];
+ } else {
+ for (i = 0; i < 64; i++)
+ dst[i] = src[i];
+ }
}
-#endif
- for(i=0; i<64; i++)
- block_org[i]= block1[i];
-
- if (form == MMX_PERM) {
- for(i=0;i<64;i++)
- block[idct_mmx_perm[i]] = block1[i];
- } else if (form == MMX_SIMPLE_PERM) {
- for(i=0;i<64;i++)
- block[idct_simple_mmx_perm[i]] = block1[i];
-
- } else if (form == SSE2_PERM) {
- for(i=0; i<64; i++)
- block[(i&0x38) | idct_sse2_row_perm[i&7]] = block1[i];
- } else if (form == PARTTRANS_PERM) {
- for(i=0; i<64; i++)
- block[(i&0x24) | ((i&3)<<3) | ((i>>3)&3)] = block1[i];
- } else {
- for(i=0; i<64; i++)
- block[i]= block1[i];
- }
-#if 0 // simulate mismatch control for tested IDCT but not the ref
-{ int sum=0;
- for(i=0;i<64;i++)
- sum+=block[i];
+static int dct_error(const struct algo *dct, int test, int is_idct, int speed)
+{
+ void (*ref)(DCTELEM *block) = is_idct ? ff_ref_idct : ff_ref_fdct;
+ int it, i, scale;
+ int err_inf, v;
+ int64_t err2, ti, ti1, it1, err_sum = 0;
+ int64_t sysErr[64], sysErrMax = 0;
+ int maxout = 0;
+ int blockSumErrMax = 0, blockSumErr;
+ AVLFG prng;
+ double omse, ome;
+ int spec_err;
- if((sum&1)==0) block[63]^=1;
-}
-#endif
+ av_lfg_init(&prng, 1);
- fdct_func(block);
+ err_inf = 0;
+ err2 = 0;
+ for (i = 0; i < 64; i++)
+ sysErr[i] = 0;
+ for (it = 0; it < NB_ITS; it++) {
+ init_block(block1, test, is_idct, &prng);
+ permute(block, block1, dct->format);
+
+ dct->func(block);
mmx_emms();
- if (form == SCALE_PERM) {
- for(i=0; i<64; i++) {
- scale = 8*(1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
- block[i] = (block[i] * scale /*+ (1<<(AANSCALE_BITS-1))*/) >> AANSCALE_BITS;
+ if (dct->format == SCALE_PERM) {
+ for (i = 0; i < 64; i++) {
+ scale = 8 * (1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
+ block[i] = (block[i] * scale) >> AANSCALE_BITS;
}
}
- fdct_ref(block1);
+ ref(block1);
- blockSumErr=0;
- for(i=0;i<64;i++) {
- v = abs(block[i] - block1[i]);
+ blockSumErr = 0;
+ for (i = 0; i < 64; i++) {
+ int err = block[i] - block1[i];
+ err_sum += err;
+ v = abs(err);
if (v > err_inf)
err_inf = v;
err2 += v * v;
sysErr[i] += block[i] - block1[i];
blockSumErr += v;
- if( abs(block[i])>maxout) maxout=abs(block[i]);
- }
- if(blockSumErrMax < blockSumErr) blockSumErrMax= blockSumErr;
-#if 0 // print different matrix pairs
- if(blockSumErr){
- printf("\n");
- for(i=0; i<64; i++){
- if((i&7)==0) printf("\n");
- printf("%4d ", block_org[i]);
- }
- for(i=0; i<64; i++){
- if((i&7)==0) printf("\n");
- printf("%4d ", block[i] - block1[i]);
- }
+ if (abs(block[i]) > maxout)
+ maxout = abs(block[i]);
}
-#endif
+ if (blockSumErrMax < blockSumErr)
+ blockSumErrMax = blockSumErr;
}
- for(i=0; i<64; i++) sysErrMax= FFMAX(sysErrMax, FFABS(sysErr[i]));
+ for (i = 0; i < 64; i++)
+ sysErrMax = FFMAX(sysErrMax, FFABS(sysErr[i]));
- for(i=0; i<64; i++){
- if(i%8==0) printf("\n");
- printf("%7d ", (int)sysErr[i]);
+ for (i = 0; i < 64; i++) {
+ if (i % 8 == 0)
+ printf("\n");
+ printf("%7d ", (int) sysErr[i]);
}
printf("\n");
- printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
- is_idct ? "IDCT" : "DCT",
- name, err_inf, (double)err2 / NB_ITS / 64.0, (double)sysErrMax / NB_ITS, maxout, blockSumErrMax);
+ omse = (double) err2 / NB_ITS / 64;
+ ome = (double) err_sum / NB_ITS / 64;
- /* speed test */
- for(i=0;i<64;i++)
- block1[i] = 0;
- switch(test){
- case 0:
- for(i=0;i<64;i++)
- block1[i] = av_lfg_get(&prng) % 512 -256;
- if (is_idct){
- ff_ref_fdct(block1);
+ spec_err = is_idct && (err_inf > 1 || omse > 0.02 || fabs(ome) > 0.0015);
- for(i=0;i<64;i++)
- block1[i]>>=3;
- }
- break;
- case 1:{
- case 2:
- block1[0] = av_lfg_get(&prng) % 512 -256;
- block1[1] = av_lfg_get(&prng) % 512 -256;
- block1[2] = av_lfg_get(&prng) % 512 -256;
- block1[3] = av_lfg_get(&prng) % 512 -256;
- }break;
- }
+ printf("%s %s: ppe=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
+ is_idct ? "IDCT" : "DCT", dct->name, err_inf,
+ omse, ome, (double) sysErrMax / NB_ITS,
+ maxout, blockSumErrMax);
- if (form == MMX_PERM) {
- for(i=0;i<64;i++)
- block[idct_mmx_perm[i]] = block1[i];
- } else if(form == MMX_SIMPLE_PERM) {
- for(i=0;i<64;i++)
- block[idct_simple_mmx_perm[i]] = block1[i];
- } else {
- for(i=0; i<64; i++)
- block[i]= block1[i];
- }
+ if (spec_err && !dct->nonspec)
+ return 1;
+
+ if (!speed)
+ return 0;
+
+ /* speed test */
+ init_block(block, test, is_idct, &prng);
+ permute(block1, block, dct->format);
ti = gettime();
it1 = 0;
do {
- for(it=0;it<NB_ITS_SPEED;it++) {
- for(i=0; i<64; i++)
- block[i]= block1[i];
-// memcpy(block, block1, sizeof(DCTELEM) * 64);
-// do not memcpy especially not fastmemcpy because it does movntq !!!
- fdct_func(block);
+ for (it = 0; it < NB_ITS_SPEED; it++) {
+ memcpy(block, block1, sizeof(block));
+ dct->func(block);
}
it1 += NB_ITS_SPEED;
ti1 = gettime() - ti;
} while (ti1 < 1000000);
mmx_emms();
- printf("%s %s: %0.1f kdct/s\n",
- is_idct ? "IDCT" : "DCT",
- name, (double)it1 * 1000.0 / (double)ti1);
+ printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", dct->name,
+ (double) it1 * 1000.0 / (double) ti1);
+
+ return 0;
}
DECLARE_ALIGNED(8, static uint8_t, img_dest)[64];
@@ -391,19 +361,19 @@ static void idct248_ref(uint8_t *dest, int linesize, int16_t *block)
if (!init) {
init = 1;
- for(i=0;i<8;i++) {
+ for (i = 0; i < 8; i++) {
sum = 0;
- for(j=0;j<8;j++) {
- s = (i==0) ? sqrt(1.0/8.0) : sqrt(1.0/4.0);
+ for (j = 0; j < 8; j++) {
+ s = (i == 0) ? sqrt(1.0 / 8.0) : sqrt(1.0 / 4.0);
c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0);
sum += c8[i][j] * c8[i][j];
}
}
- for(i=0;i<4;i++) {
+ for (i = 0; i < 4; i++) {
sum = 0;
- for(j=0;j<4;j++) {
- s = (i==0) ? sqrt(1.0/4.0) : sqrt(1.0/2.0);
+ for (j = 0; j < 4; j++) {
+ s = (i == 0) ? sqrt(1.0 / 4.0) : sqrt(1.0 / 2.0);
c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0);
sum += c4[i][j] * c4[i][j];
}
@@ -412,58 +382,59 @@ static void idct248_ref(uint8_t *dest, int linesize, int16_t *block)
/* butterfly */
s = 0.5 * sqrt(2.0);
- for(i=0;i<4;i++) {
- for(j=0;j<8;j++) {
- block1[8*(2*i)+j] = (block[8*(2*i)+j] + block[8*(2*i+1)+j]) * s;
- block1[8*(2*i+1)+j] = (block[8*(2*i)+j] - block[8*(2*i+1)+j]) * s;
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 8; j++) {
+ block1[8 * (2 * i) + j] =
+ (block[8 * (2 * i) + j] + block[8 * (2 * i + 1) + j]) * s;
+ block1[8 * (2 * i + 1) + j] =
+ (block[8 * (2 * i) + j] - block[8 * (2 * i + 1) + j]) * s;
}
}
/* idct8 on lines */
- for(i=0;i<8;i++) {
- for(j=0;j<8;j++) {
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 8; j++) {
sum = 0;
- for(k=0;k<8;k++)
- sum += c8[k][j] * block1[8*i+k];
- block2[8*i+j] = sum;
+ for (k = 0; k < 8; k++)
+ sum += c8[k][j] * block1[8 * i + k];
+ block2[8 * i + j] = sum;
}
}
/* idct4 */
- for(i=0;i<8;i++) {
- for(j=0;j<4;j++) {
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 4; j++) {
/* top */
sum = 0;
- for(k=0;k<4;k++)
- sum += c4[k][j] * block2[8*(2*k)+i];
- block3[8*(2*j)+i] = sum;
+ for (k = 0; k < 4; k++)
+ sum += c4[k][j] * block2[8 * (2 * k) + i];
+ block3[8 * (2 * j) + i] = sum;
/* bottom */
sum = 0;
- for(k=0;k<4;k++)
- sum += c4[k][j] * block2[8*(2*k+1)+i];
- block3[8*(2*j+1)+i] = sum;
+ for (k = 0; k < 4; k++)
+ sum += c4[k][j] * block2[8 * (2 * k + 1) + i];
+ block3[8 * (2 * j + 1) + i] = sum;
}
}
/* clamp and store the result */
- for(i=0;i<8;i++) {
- for(j=0;j<8;j++) {
- v = block3[8*i+j];
- if (v < 0)
- v = 0;
- else if (v > 255)
- v = 255;
- dest[i * linesize + j] = (int)rint(v);
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 8; j++) {
+ v = block3[8 * i + j];
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ dest[i * linesize + j] = (int) rint(v);
}
}
}
static void idct248_error(const char *name,
- void (*idct248_put)(uint8_t *dest, int line_size, int16_t *block))
+ void (*idct248_put)(uint8_t *dest, int line_size,
+ int16_t *block),
+ int speed)
{
int it, i, it1, ti, ti1, err_max, v;
-
AVLFG prng;
av_lfg_init(&prng, 1);
@@ -471,41 +442,39 @@ static void idct248_error(const char *name,
/* just one test to see if code is correct (precision is less
important here) */
err_max = 0;
- for(it=0;it<NB_ITS;it++) {
-
+ for (it = 0; it < NB_ITS; it++) {
/* XXX: use forward transform to generate values */
- for(i=0;i<64;i++)
+ for (i = 0; i < 64; i++)
block1[i] = av_lfg_get(&prng) % 256 - 128;
block1[0] += 1024;
- for(i=0; i<64; i++)
- block[i]= block1[i];
+ for (i = 0; i < 64; i++)
+ block[i] = block1[i];
idct248_ref(img_dest1, 8, block);
- for(i=0; i<64; i++)
- block[i]= block1[i];
+ for (i = 0; i < 64; i++)
+ block[i] = block1[i];
idct248_put(img_dest, 8, block);
- for(i=0;i<64;i++) {
- v = abs((int)img_dest[i] - (int)img_dest1[i]);
+ for (i = 0; i < 64; i++) {
+ v = abs((int) img_dest[i] - (int) img_dest1[i]);
if (v == 255)
printf("%d %d\n", img_dest[i], img_dest1[i]);
if (v > err_max)
err_max = v;
}
}
- printf("%s %s: err_inf=%d\n",
- 1 ? "IDCT248" : "DCT248",
- name, err_max);
+ printf("%s %s: err_inf=%d\n", 1 ? "IDCT248" : "DCT248", name, err_max);
+
+ if (!speed)
+ return;
ti = gettime();
it1 = 0;
do {
- for(it=0;it<NB_ITS_SPEED;it++) {
- for(i=0; i<64; i++)
- block[i]= block1[i];
-// memcpy(block, block1, sizeof(DCTELEM) * 64);
-// do not memcpy especially not fastmemcpy because it does movntq !!!
+ for (it = 0; it < NB_ITS_SPEED; it++) {
+ for (i = 0; i < 64; i++)
+ block[i] = block1[i];
idct248_put(img_dest, 8, block);
}
it1 += NB_ITS_SPEED;
@@ -513,9 +482,8 @@ static void idct248_error(const char *name,
} while (ti1 < 1000000);
mmx_emms();
- printf("%s %s: %0.1f kdct/s\n",
- 1 ? "IDCT248" : "DCT248",
- name, (double)it1 * 1000.0 / (double)ti1);
+ printf("%s %s: %0.1f kdct/s\n", 1 ? "IDCT248" : "DCT248", name,
+ (double) it1 * 1000.0 / (double) ti1);
}
static void help(void)
@@ -525,54 +493,58 @@ static void help(void)
" 1 -> test with random sparse matrixes\n"
" 2 -> do 3. test from mpeg4 std\n"
"-i test IDCT implementations\n"
- "-4 test IDCT248 implementations\n");
+ "-4 test IDCT248 implementations\n"
+ "-t speed test\n");
}
int main(int argc, char **argv)
{
int test_idct = 0, test_248_dct = 0;
- int c,i;
- int test=1;
+ int c, i;
+ int test = 1;
+ int speed = 0;
+ int err = 0;
+
cpu_flags = av_get_cpu_flags();
ff_ref_dct_init();
idct_mmx_init();
- for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i;
- for(i=0;i<MAX_NEG_CROP;i++) {
- cropTbl[i] = 0;
- cropTbl[i + MAX_NEG_CROP + 256] = 255;
- }
-
- for(;;) {
- c = getopt(argc, argv, "ih4");
+ for (;;) {
+ c = getopt(argc, argv, "ih4t");
if (c == -1)
break;
- switch(c) {
+ switch (c) {
case 'i':
test_idct = 1;
break;
case '4':
test_248_dct = 1;
break;
- default :
+ case 't':
+ speed = 1;
+ break;
+ default:
case 'h':
help();
return 0;
}
}
- if(optind <argc) test= atoi(argv[optind]);
+ if (optind < argc)
+ test = atoi(argv[optind]);
- printf("ffmpeg DCT/IDCT test\n");
+ printf("Libav DCT/IDCT test\n");
if (test_248_dct) {
- idct248_error("SIMPLE-C", ff_simple_idct248_put);
+ idct248_error("SIMPLE-C", ff_simple_idct248_put, speed);
} else {
- for (i=0;algos[i].name;i++)
- 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);
- }
+ const struct algo *algos = test_idct ? idct_tab : fdct_tab;
+ for (i = 0; algos[i].name; i++)
+ if (!(~cpu_flags & algos[i].mm_support)) {
+ err |= dct_error(&algos[i], test, test_idct, speed);
+ }
}
- return 0;
+
+ return err;
}
diff --git a/libavcodec/dctref.h b/libavcodec/dctref.h
index ba89abd..a93b70d 100644
--- a/libavcodec/dctref.h
+++ b/libavcodec/dctref.h
@@ -22,10 +22,8 @@
#ifndef AVCODEC_DCTREF_H
#define AVCODEC_DCTREF_H
-#include "dsputil.h"
-
-void ff_ref_fdct(DCTELEM *block);
-void ff_ref_idct(DCTELEM *block);
+void ff_ref_fdct(short *block);
+void ff_ref_idct(short *block);
void ff_ref_dct_init(void);
#endif /* AVCODEC_DCTREF_H */
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 919375b..08bb2a4 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -384,14 +384,13 @@ static av_cold int dfa_decode_end(AVCodecContext *avctx)
}
AVCodec ff_dfa_decoder = {
- "dfa",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DFA,
- sizeof(DfaContext),
- dfa_decode_init,
- NULL,
- dfa_decode_end,
- dfa_decode_frame,
- CODEC_CAP_DR1,
+ .name = "dfa",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DFA,
+ .priv_data_size = sizeof(DfaContext),
+ .init = dfa_decode_init,
+ .close = dfa_decode_end,
+ .decode = dfa_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
};
diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c
index 09da1cb..bf56088 100644
--- a/libavcodec/dirac.c
+++ b/libavcodec/dirac.c
@@ -145,7 +145,7 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb,
}
if (source->frame_rate_index > 0) {
if (source->frame_rate_index <= 8)
- frame_rate = ff_frame_rate_tab[source->frame_rate_index];
+ frame_rate = avpriv_frame_rate_tab[source->frame_rate_index];
else
frame_rate = dirac_frame_rate[source->frame_rate_index-9];
}
@@ -242,7 +242,7 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb,
return 0;
}
-int ff_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb,
+int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb,
dirac_source_params *source)
{
unsigned version_major;
diff --git a/libavcodec/dirac.h b/libavcodec/dirac.h
index 0be66c2..f8063d9 100644
--- a/libavcodec/dirac.h
+++ b/libavcodec/dirac.h
@@ -51,7 +51,7 @@ typedef struct {
uint8_t color_spec_index; ///< index into dirac_color_spec_presets[]
} dirac_source_params;
-int ff_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb,
- dirac_source_params *source);
+int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb,
+ dirac_source_params *source);
#endif /* AVCODEC_DIRAC_H */
diff --git a/libavcodec/dirac_parser.c b/libavcodec/dirac_parser.c
index 87c3a04..11d0cf8 100644
--- a/libavcodec/dirac_parser.c
+++ b/libavcodec/dirac_parser.c
@@ -248,9 +248,8 @@ static void dirac_parse_close(AVCodecParserContext *s)
}
AVCodecParser ff_dirac_parser = {
- { CODEC_ID_DIRAC },
- sizeof(DiracParseContext),
- NULL,
- dirac_parse,
- dirac_parse_close,
+ .codec_ids = { CODEC_ID_DIRAC },
+ .priv_data_size = sizeof(DiracParseContext),
+ .parser_parse = dirac_parse,
+ .parser_close = dirac_parse_close,
};
diff --git a/libavcodec/dnxhd_parser.c b/libavcodec/dnxhd_parser.c
index 44ea8f0..870fed4 100644
--- a/libavcodec/dnxhd_parser.c
+++ b/libavcodec/dnxhd_parser.c
@@ -87,9 +87,8 @@ static int dnxhd_parse(AVCodecParserContext *s,
}
AVCodecParser ff_dnxhd_parser = {
- { CODEC_ID_DNXHD },
- sizeof(ParseContext),
- NULL,
- dnxhd_parse,
- ff_parse_close,
+ .codec_ids = { CODEC_ID_DNXHD },
+ .priv_data_size = sizeof(ParseContext),
+ .parser_parse = dnxhd_parse,
+ .parser_close = ff_parse_close,
};
diff --git a/libavcodec/dnxhddata.c b/libavcodec/dnxhddata.c
index 82d083c..576e85e 100644
--- a/libavcodec/dnxhddata.c
+++ b/libavcodec/dnxhddata.c
@@ -22,6 +22,28 @@
#include "avcodec.h"
#include "dnxhddata.h"
+static const uint8_t dnxhd_1235_luma_weight[] = {
+ 0, 32, 32, 32, 33, 35, 38, 39,
+ 32, 33, 32, 33, 36, 36, 39, 42,
+ 32, 32, 33, 36, 35, 37, 41, 43,
+ 31, 33, 34, 36, 36, 40, 42, 48,
+ 32, 34, 36, 37, 39, 42, 46, 51,
+ 36, 37, 37, 39, 41, 46, 51, 55,
+ 37, 39, 41, 41, 47, 50, 55, 56,
+ 41, 42, 41, 44, 50, 53, 60, 60
+};
+
+static const uint8_t dnxhd_1235_chroma_weight[] = {
+ 0, 32, 33, 34, 39, 41, 54, 59,
+ 33, 34, 35, 38, 43, 49, 58, 84,
+ 34, 37, 39, 44, 46, 55, 74, 87,
+ 40, 42, 47, 48, 58, 70, 87, 86,
+ 43, 50, 56, 63, 72, 94, 91, 82,
+ 55, 63, 65, 75, 93, 89, 85, 73,
+ 61, 67, 82, 81, 83, 90, 79, 73,
+ 74, 84, 75, 78, 90, 85, 73, 73
+};
+
static const uint8_t dnxhd_1237_luma_weight[] = {
0, 32, 33, 34, 34, 36, 37, 36,
36, 37, 38, 38, 38, 39, 41, 44,
@@ -108,7 +130,7 @@ static const uint8_t dnxhd_1242_chroma_weight[] = {
48, 49, 51, 51, 52, 52, 54, 54,
49, 49, 52, 53, 54, 54, 53, 53,
55, 59, 63, 62, 60, 60, 60, 60,
- };
+};
static const uint8_t dnxhd_1243_luma_weight[] = {
0, 32, 32, 33, 33, 35, 35, 35,
@@ -132,6 +154,28 @@ static const uint8_t dnxhd_1243_chroma_weight[] = {
46, 45, 46, 47, 47, 48, 47, 47,
};
+static const uint8_t dnxhd_1250_luma_weight[] = {
+ 0, 32, 35, 35, 36, 36, 41, 43,
+ 32, 34, 35, 36, 37, 39, 43, 47,
+ 33, 34, 36, 38, 38, 42, 42, 50,
+ 34, 36, 38, 38, 41, 40, 47, 54,
+ 35, 38, 39, 40, 39, 45, 49, 58,
+ 38, 39, 40, 39, 46, 47, 54, 60,
+ 38, 39, 41, 46, 46, 48, 57, 62,
+ 40, 41, 44, 45, 49, 54, 63, 63
+};
+
+static const uint8_t dnxhd_1250_chroma_weight[] = {
+ 0, 32, 35, 36, 40, 42, 51, 51,
+ 35, 36, 39, 39, 43, 51, 52, 55,
+ 36, 41, 41, 43, 51, 53, 54, 56,
+ 43, 44, 45, 50, 54, 54, 55, 57,
+ 45, 48, 50, 51, 55, 58, 59, 58,
+ 49, 52, 49, 57, 58, 62, 58, 60,
+ 51, 51, 56, 58, 62, 61, 59, 62,
+ 52, 52, 60, 61, 59, 59, 63, 63
+};
+
static const uint8_t dnxhd_1251_luma_weight[] = {
0, 32, 32, 34, 34, 34, 34, 35,
35, 35, 36, 37, 36, 36, 35, 36,
@@ -184,35 +228,144 @@ static const uint8_t dnxhd_1237_dc_bits[12] = {
};
static const uint16_t dnxhd_1237_ac_codes[257] = {
- 0, 1, 4, 5, 12, 26, 27, 56, 57, 58, 59, 120, 121, 244, 245, 246, 247, 248, 498, 499, 500, 501, 502, 1006, 1007, 1008, 1009, 1010, 1011, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 32668, 32669, 32670, 32671, 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 65370, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, 65379, 65380, 65381, 65382, 65383, 65384, 65385, 65386, 65387, 65388, 65389, 65390, 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
+ 0, 1, 4, 5, 12, 26, 27, 56,
+ 57, 58, 59, 120, 121, 244, 245, 246,
+ 247, 248, 498, 499, 500, 501, 502, 1006,
+ 1007, 1008, 1009, 1010, 1011, 2024, 2025, 2026,
+ 2027, 2028, 2029, 2030, 2031, 4064, 4065, 4066,
+ 4067, 4068, 4069, 4070, 4071, 4072, 4073, 8148,
+ 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156,
+ 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323,
+ 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331,
+ 16332, 16333, 32668, 32669, 32670, 32671, 32672, 32673,
+ 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681,
+ 32682, 32683, 32684, 65370, 65371, 65372, 65373, 65374,
+ 65375, 65376, 65377, 65378, 65379, 65380, 65381, 65382,
+ 65383, 65384, 65385, 65386, 65387, 65388, 65389, 65390,
+ 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398,
+ 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406,
+ 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414,
+ 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422,
+ 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430,
+ 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438,
+ 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446,
+ 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454,
+ 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462,
+ 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470,
+ 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478,
+ 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486,
+ 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494,
+ 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502,
+ 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510,
+ 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518,
+ 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526,
+ 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534,
+ 65535,
};
static const uint8_t dnxhd_1237_ac_bits[257] = {
- 2, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 2, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8,
+ 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11,
+ 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16,
};
static const uint8_t dnxhd_1237_ac_level[257] = {
- 1, 1, 2, 0, 3, 4, 2, 5, 6, 7, 3, 8, 9, 10, 11, 12, 4, 5, 13, 14, 15, 16, 6, 17, 18, 19, 20, 21, 7, 22, 23, 24, 25, 26, 27, 8, 9, 28, 29, 30, 31, 32, 33, 34, 10, 11, 12, 35, 36, 37, 38, 39, 40, 41, 13, 14, 15, 16, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 17, 18, 19, 20, 21, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 1, 22, 23, 24, 25, 26, 27, 62, 63, 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 1, 1, 2, 0, 3, 4, 2, 5, 6, 7, 3, 8, 9, 10, 11, 12,
+ 4, 5, 13, 14, 15, 16, 6, 17, 18, 19, 20, 21, 7, 22, 23, 24,
+ 25, 26, 27, 8, 9, 28, 29, 30, 31, 32, 33, 34, 10, 11, 12, 35,
+ 36, 37, 38, 39, 40, 41, 13, 14, 15, 16, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 17, 18, 19, 20, 21, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 64, 1, 22, 23, 24, 25, 26, 27, 62, 63, 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, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 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,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64,
};
static const uint8_t dnxhd_1237_ac_run_flag[257] = {
- 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 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, 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, 0, 0, 0, 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, 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, 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, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 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, 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, 0, 0, 0, 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, 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, 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, 1, 1, 1, 1, 1, 1,
+ 1,
};
static const uint8_t dnxhd_1237_ac_index_flag[257] = {
- 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 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, 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, 1, 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, 0, 0, 0, 0, 0, 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, 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, 1, 1,
+ 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 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, 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, 1, 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, 0, 0, 0, 0, 0, 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, 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, 1,
+ 1,
};
static const uint16_t dnxhd_1237_run_codes[62] = {
- 0, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 58, 118, 119, 240, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
+ 0, 4, 10, 11, 24, 25, 26, 54,
+ 55, 56, 57, 58, 118, 119, 240, 482,
+ 483, 484, 485, 486, 487, 488, 489, 490,
+ 491, 492, 493, 494, 990, 991, 992, 993,
+ 994, 995, 996, 997, 998, 999, 1000, 1001,
+ 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009,
+ 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017,
+ 1018, 1019, 1020, 1021, 1022, 1023,
};
static const uint8_t dnxhd_1237_run_bits[62] = {
- 1, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 1, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 8, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
};
static const uint8_t dnxhd_1237_run[62] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 53, 57, 58, 59, 60, 61, 62, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 53, 57, 58, 59, 60, 61, 62, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56,
};
static const uint8_t dnxhd_1238_dc_codes[12] = {
@@ -224,122 +377,698 @@ static const uint8_t dnxhd_1238_dc_bits[12] = {
};
static const uint16_t dnxhd_1238_ac_codes[257] = {
- 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 499, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
+ 0, 1, 4, 10, 11, 24, 25, 26,
+ 54, 55, 56, 57, 116, 117, 118, 119,
+ 240, 241, 242, 243, 244, 245, 492, 493,
+ 494, 495, 496, 497, 498, 499, 1000, 1001,
+ 1002, 1003, 1004, 1005, 1006, 1007, 1008, 2018,
+ 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026,
+ 2027, 4056, 4057, 4058, 4059, 4060, 4061, 4062,
+ 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140,
+ 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148,
+ 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156,
+ 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321,
+ 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329,
+ 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337,
+ 16338, 32678, 32679, 32680, 32681, 32682, 32683, 32684,
+ 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692,
+ 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700,
+ 32701, 32702, 32703, 32704, 32705, 65412, 65413, 65414,
+ 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422,
+ 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430,
+ 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438,
+ 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446,
+ 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454,
+ 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462,
+ 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470,
+ 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478,
+ 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486,
+ 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494,
+ 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502,
+ 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510,
+ 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518,
+ 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526,
+ 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534,
+ 65535,
};
static const uint8_t dnxhd_1238_ac_bits[257] = {
- 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16,
};
static const uint8_t dnxhd_1238_ac_level[257] = {
- 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 22, 6, 7, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 10, 11, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 12, 13, 14, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 15, 16, 17, 18, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 40, 25, 26, 27, 28, 29, 30, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4,
+ 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 22, 6, 7, 23, 24,
+ 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 10,
+ 11, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 12, 13, 14, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 15, 16, 17, 18,
+ 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 40, 25,
+ 26, 27, 28, 29, 30, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 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,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64,
}; /* 0 is EOB */
static const uint8_t dnxhd_1238_ac_run_flag[257] = {
- 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 1, 1,
+ 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 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, 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, 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, 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, 1,
+ 1,
};
static const uint8_t dnxhd_1238_ac_index_flag[257] = {
- 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 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, 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, 0, 0, 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, 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, 1, 1,
+ 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 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, 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, 0, 0, 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, 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, 1,
+ 1,
};
-static const uint16_t dnxhd_1238_run_codes[62] = {
- 0, 4, 10, 11, 24, 25, 26, 27, 56, 57, 58, 59, 120, 242, 486, 487, 488, 489, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
+static const uint16_t dnxhd_1235_1238_1241_run_codes[62] = {
+ 0, 4, 10, 11, 24, 25, 26, 27,
+ 56, 57, 58, 59, 120, 242, 486, 487,
+ 488, 489, 980, 981, 982, 983, 984, 985,
+ 986, 987, 988, 989, 990, 991, 992, 993,
+ 994, 995, 996, 997, 998, 999, 1000, 1001,
+ 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009,
+ 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017,
+ 1018, 1019, 1020, 1021, 1022, 1023,
};
-static const uint8_t dnxhd_1238_run_bits[62] = {
- 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+static const uint8_t dnxhd_1235_1238_1241_run_bits[62] = {
+ 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9,
+ 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
};
static const uint8_t dnxhd_1238_run[62] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 21, 17, 18, 19, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 20, 21, 17, 18, 19, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
};
-static const uint8_t dnxhd_1241_dc_codes[14] = {
+static const uint8_t dnxhd_1235_1241_dc_codes[14] = {
10, 62, 11, 12, 13, 0, 1, 2, 3, 4, 14, 30, 126, 127,
};
-static const uint8_t dnxhd_1241_dc_bits[14] = {
+static const uint8_t dnxhd_1235_1241_dc_bits[14] = {
4, 6, 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 7, 7,
};
-static const uint16_t dnxhd_1241_ac_codes[257] = {
- 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
+
+static const uint16_t dnxhd_1235_1241_ac_codes[257] = {
+ 0, 1, 4, 10, 11, 24, 25, 26,
+ 54, 55, 56, 57, 116, 117, 118, 119,
+ 240, 241, 242, 243, 244, 245, 492, 493,
+ 494, 495, 496, 497, 498, 998, 999, 1000,
+ 1001, 1002, 1003, 1004, 1005, 1006, 1007, 2016,
+ 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024,
+ 2025, 2026, 4054, 4055, 4056, 4057, 4058, 4059,
+ 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067,
+ 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145,
+ 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153,
+ 8154, 8155, 8156, 8157, 16316, 16317, 16318, 16319,
+ 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327,
+ 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335,
+ 16336, 16337, 32676, 32677, 32678, 32679, 32680, 32681,
+ 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689,
+ 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697,
+ 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705,
+ 32706, 32707, 32708, 65418, 65419, 65420, 65421, 65422,
+ 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430,
+ 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438,
+ 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446,
+ 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454,
+ 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462,
+ 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470,
+ 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478,
+ 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486,
+ 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494,
+ 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502,
+ 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510,
+ 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518,
+ 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526,
+ 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534,
+ 65535,
+};
+
+static const uint8_t dnxhd_1235_1241_ac_bits[257] = {
+ 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16,
};
-static const uint8_t dnxhd_1241_ac_bits[257] = {
- 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+static const uint8_t dnxhd_1235_1241_ac_level[257] = {
+ 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4,
+ 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 7, 22, 23, 24,
+ 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 10, 11, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 12, 13,
+ 14, 15, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 1,
+ 16, 17, 18, 19, 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 25, 26, 27, 28, 29, 30, 31, 32, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 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,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64,
};
-static const uint8_t dnxhd_1241_ac_level[257] = {
- 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 7, 22, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 38, 10, 11, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 12, 13, 14, 15, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 1, 16, 17, 18, 19, 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 25, 26, 27, 28, 29, 30, 31, 32, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+static const uint8_t dnxhd_1235_1241_ac_run_flag[257] = {
+ 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 1,
+ 1,
};
-static const uint8_t dnxhd_1241_ac_run_flag[257] = {
- 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 1, 1,
+static const uint8_t dnxhd_1235_1241_ac_index_flag[257] = {
+ 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 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, 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, 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, 1,
+ 1,
};
-static const uint8_t dnxhd_1241_ac_index_flag[257] = {
- 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 1, 1,
+static const uint8_t dnxhd_1235_1241_run[62] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 18, 20, 17, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
};
-static const uint8_t dnxhd_1241_run[62] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 17, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+static const uint8_t dnxhd_1250_dc_codes[14] = {
+ 10, 62, 11, 12, 13, 0, 1, 2, 3, 4, 14, 30, 126, 127
+};
+static const uint8_t dnxhd_1250_dc_bits[14] = {
+ 4, 6, 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 7, 7
+};
+static const uint16_t dnxhd_1250_ac_codes[257] = {
+ 0, 1, 4, 10, 11, 24, 25, 26,
+ 54, 55, 56, 57, 116, 117, 118, 119,
+ 240, 241, 242, 243, 244, 245, 492, 493,
+ 494, 495, 496, 497, 498, 998, 999, 1000,
+ 1001, 1002, 1003, 1004, 1005, 1006, 2014, 2015,
+ 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023,
+ 2024, 2025, 4052, 4053, 4054, 4055, 4056, 4057,
+ 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065,
+ 4066, 4067, 8136, 8137, 8138, 8139, 8140, 8141,
+ 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149,
+ 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314,
+ 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322,
+ 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330,
+ 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338,
+ 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685,
+ 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693,
+ 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701,
+ 32702, 32703, 32704, 32705, 32706, 32707, 32708, 32709,
+ 32710, 32711, 32712, 65426, 65427, 65428, 65429, 65430,
+ 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438,
+ 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446,
+ 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454,
+ 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462,
+ 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470,
+ 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478,
+ 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486,
+ 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494,
+ 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502,
+ 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510,
+ 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518,
+ 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526,
+ 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534,
+ 65535
+};
+static const uint8_t dnxhd_1250_ac_bits[257] = {
+ 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16
+};
+static const uint8_t dnxhd_1250_ac_level[257] = {
+ 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4,
+ 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 22, 6, 23, 24, 25,
+ 26, 27, 28, 29, 7, 8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 9, 10, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 11,
+ 12, 13, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2,
+ 3, 4, 5, 14, 15, 16, 17, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 18, 19, 20, 21,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 55, 56, 22, 23, 24,
+ 25, 26, 27, 54, 57, 58, 59, 60, 61, 62, 63, 64, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 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,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64
+};
+static const uint8_t dnxhd_1250_ac_run_flag[257] = {
+ 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+ 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, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 1, 1, 1, 1, 1, 1,
+ 1
+};
+static const uint8_t dnxhd_1250_ac_index_flag[257] = {
+ 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 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, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 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, 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, 1,
+ 1
+};
+static const uint16_t dnxhd_1250_run_codes[62] = {
+ 0, 4, 5, 12, 26, 27, 28, 58,
+ 118, 119, 120, 242, 486, 487, 976, 977,
+ 978, 979, 980, 981, 982, 983, 984, 985,
+ 986, 987, 988, 989, 990, 991, 992, 993,
+ 994, 995, 996, 997, 998, 999, 1000, 1001,
+ 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009,
+ 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017,
+ 1018, 1019, 1020, 1021, 1022, 1023
+};
+static const uint8_t dnxhd_1250_run_bits[62] = {
+ 1, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10
+};
+static const uint8_t dnxhd_1250_run[62] = {
+ 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, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62
};
static const uint8_t dnxhd_1251_dc_codes[12] = {
0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63,
};
+
static const uint8_t dnxhd_1251_dc_bits[12] = {
3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6,
};
+
static const uint16_t dnxhd_1251_ac_codes[257] = {
- 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 8134, 8135, 8136, 8137, 8138, 8139, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 16339, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 32709, 32710, 32711, 32712, 32713, 32714, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
+ 0, 1, 4, 10, 11, 24, 25, 26,
+ 54, 55, 56, 57, 116, 117, 118, 119,
+ 240, 241, 242, 243, 244, 245, 492, 493,
+ 494, 495, 496, 497, 996, 997, 998, 999,
+ 1000, 1001, 1002, 1003, 1004, 1005, 2012, 2013,
+ 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021,
+ 2022, 2023, 2024, 2025, 4052, 4053, 4054, 4055,
+ 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063,
+ 4064, 4065, 4066, 8134, 8135, 8136, 8137, 8138,
+ 8139, 8140, 8141, 8142, 8143, 8144, 8145, 8146,
+ 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154,
+ 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319,
+ 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327,
+ 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335,
+ 16336, 16337, 16338, 16339, 32680, 32681, 32682, 32683,
+ 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691,
+ 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699,
+ 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707,
+ 32708, 32709, 32710, 32711, 32712, 32713, 32714, 65430,
+ 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438,
+ 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446,
+ 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454,
+ 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462,
+ 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470,
+ 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478,
+ 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486,
+ 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494,
+ 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502,
+ 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510,
+ 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518,
+ 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526,
+ 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534,
+ 65535,
};
+
static const uint8_t dnxhd_1251_ac_bits[257] = {
- 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16,
};
+
static const uint8_t dnxhd_1251_ac_level[257] = {
- 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 22, 23, 24, 25, 26, 27, 28, 29, 7, 8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 9, 10, 11, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 12, 13, 14, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 15, 16, 17, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18, 19, 20, 21, 22, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 23, 24, 25, 26, 27, 28, 59, 60, 61, 62, 63, 64, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4,
+ 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 22, 23, 24, 25,
+ 26, 27, 28, 29, 7, 8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 9, 10, 11, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 12, 13, 14, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1,
+ 2, 3, 4, 5, 6, 7, 8, 15, 16, 17, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18,
+ 19, 20, 21, 22, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 23, 24, 25, 26, 27, 28, 59, 60, 61, 62, 63, 64, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 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,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64,
};
+
static const uint8_t dnxhd_1251_ac_run_flag[257] = {
- 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 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, 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, 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, 1, 1, 1, 1, 1, 1,
+ 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 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, 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, 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, 1, 1, 1, 1, 1,
+ 1,
};
+
static const uint8_t dnxhd_1251_ac_index_flag[257] = {
- 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 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, 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, 1, 1,
+ 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 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, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 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, 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, 1,
+ 1,
};
+
static const uint16_t dnxhd_1251_run_codes[62] = {
- 0, 4, 5, 12, 26, 27, 28, 58, 118, 119, 120, 242, 486, 487, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
+ 0, 4, 5, 12, 26, 27, 28, 58,
+ 118, 119, 120, 242, 486, 487, 976, 977,
+ 978, 979, 980, 981, 982, 983, 984, 985,
+ 986, 987, 988, 989, 990, 991, 992, 993,
+ 994, 995, 996, 997, 998, 999, 1000, 1001,
+ 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009,
+ 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017,
+ 1018, 1019, 1020, 1021, 1022, 1023,
};
+
static const uint8_t dnxhd_1251_run_bits[62] = {
- 1, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 1, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
};
+
static const uint8_t dnxhd_1251_run[62] = {
- 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 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, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
};
static const uint8_t dnxhd_1252_dc_codes[12] = {
0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63,
};
+
static const uint8_t dnxhd_1252_dc_bits[12] = {
3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6,
};
+
static const uint16_t dnxhd_1252_ac_codes[257] = {
- 0, 1, 4, 10, 11, 12, 26, 27, 56, 57, 58, 118, 119, 120, 242, 243, 244, 245, 246, 247, 496, 497, 498, 499, 500, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 65390, 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
+ 0, 1, 4, 10, 11, 12, 26, 27,
+ 56, 57, 58, 118, 119, 120, 242, 243,
+ 244, 245, 246, 247, 496, 497, 498, 499,
+ 500, 1002, 1003, 1004, 1005, 1006, 1007, 1008,
+ 1009, 2020, 2021, 2022, 2023, 2024, 2025, 2026,
+ 2027, 2028, 2029, 4060, 4061, 4062, 4063, 4064,
+ 4065, 4066, 4067, 4068, 4069, 4070, 4071, 8144,
+ 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152,
+ 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319,
+ 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327,
+ 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335,
+ 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679,
+ 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687,
+ 32688, 32689, 32690, 32691, 32692, 32693, 32694, 65390,
+ 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398,
+ 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406,
+ 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414,
+ 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422,
+ 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430,
+ 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438,
+ 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446,
+ 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454,
+ 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462,
+ 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470,
+ 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478,
+ 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486,
+ 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494,
+ 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502,
+ 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510,
+ 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518,
+ 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526,
+ 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534,
+ 65535,
};
+
static const uint8_t dnxhd_1252_ac_bits[257] = {
- 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10,
+ 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16,
};
+
static const uint8_t dnxhd_1252_ac_level[257] = {
- 1, 1, 2, 3, 2, 0, 4, 5, 6, 7, 3, 8, 9, 10, 11, 12, 13, 14, 4, 5, 15, 16, 17, 18, 6, 19, 20, 21, 22, 23, 24, 7, 8, 25, 26, 27, 28, 29, 30, 31, 32, 9, 10, 33, 34, 35, 36, 37, 38, 39, 40, 41, 11, 12, 13, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 14, 15, 16, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 17, 18, 19, 20, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 1, 1, 2, 3, 2, 0, 4, 5, 6, 7, 3, 8, 9, 10, 11, 12,
+ 13, 14, 4, 5, 15, 16, 17, 18, 6, 19, 20, 21, 22, 23, 24, 7,
+ 8, 25, 26, 27, 28, 29, 30, 31, 32, 9, 10, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 11, 12, 13, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 14, 15, 16, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 1, 2, 3, 17, 18, 19, 20, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 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,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64,
};
+
static const uint8_t dnxhd_1252_ac_run_flag[257] = {
- 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1,
};
+
static const uint8_t dnxhd_1252_ac_index_flag[257] = {
- 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 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, 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, 1, 1,
+ 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 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, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 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, 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, 1,
+ 1,
};
const CIDEntry ff_dnxhd_cid_table[] = {
+ { 1235, 1920, 1080, 0, 917504, 917504, 6, 10,
+ dnxhd_1235_luma_weight, dnxhd_1235_chroma_weight,
+ dnxhd_1235_1241_dc_codes, dnxhd_1235_1241_dc_bits,
+ dnxhd_1235_1241_ac_codes, dnxhd_1235_1241_ac_bits, dnxhd_1235_1241_ac_level,
+ dnxhd_1235_1241_ac_run_flag, dnxhd_1235_1241_ac_index_flag,
+ dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1235_1241_run,
+ { 175, 185, 365, 440 } },
{ 1237, 1920, 1080, 0, 606208, 606208, 4, 8,
dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight,
dnxhd_1237_dc_codes, dnxhd_1237_dc_bits,
@@ -352,14 +1081,14 @@ const CIDEntry ff_dnxhd_cid_table[] = {
dnxhd_1238_dc_codes, dnxhd_1238_dc_bits,
dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level,
dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag,
- dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run,
+ dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1238_run,
{ 175, 185, 220, 365, 440 } },
{ 1241, 1920, 1080, 1, 917504, 458752, 6, 10,
dnxhd_1241_luma_weight, dnxhd_1241_chroma_weight,
- dnxhd_1241_dc_codes, dnxhd_1241_dc_bits,
- dnxhd_1241_ac_codes, dnxhd_1241_ac_bits, dnxhd_1241_ac_level,
- dnxhd_1241_ac_run_flag, dnxhd_1241_ac_index_flag,
- dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1241_run,
+ dnxhd_1235_1241_dc_codes, dnxhd_1235_1241_dc_bits,
+ dnxhd_1235_1241_ac_codes, dnxhd_1235_1241_ac_bits, dnxhd_1235_1241_ac_level,
+ dnxhd_1235_1241_ac_run_flag, dnxhd_1235_1241_ac_index_flag,
+ dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1235_1241_run,
{ 185, 220 } },
{ 1242, 1920, 1080, 1, 606208, 303104, 4, 8,
dnxhd_1242_luma_weight, dnxhd_1242_chroma_weight,
@@ -373,8 +1102,15 @@ const CIDEntry ff_dnxhd_cid_table[] = {
dnxhd_1238_dc_codes, dnxhd_1238_dc_bits,
dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level,
dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag,
- dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run,
+ dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1238_run,
{ 185, 220 } },
+ { 1250, 1280, 720, 0, 458752, 458752, 6, 10,
+ dnxhd_1250_luma_weight, dnxhd_1250_chroma_weight,
+ dnxhd_1250_dc_codes, dnxhd_1250_dc_bits,
+ dnxhd_1250_ac_codes, dnxhd_1250_ac_bits, dnxhd_1250_ac_level,
+ dnxhd_1250_ac_run_flag, dnxhd_1250_ac_index_flag,
+ dnxhd_1250_run_codes, dnxhd_1250_run_bits, dnxhd_1250_run,
+ { 90, 180, 220 } },
{ 1251, 1280, 720, 0, 458752, 458752, 4, 8,
dnxhd_1251_luma_weight, dnxhd_1251_chroma_weight,
dnxhd_1251_dc_codes, dnxhd_1251_dc_bits,
@@ -407,7 +1143,7 @@ int ff_dnxhd_get_cid_table(int cid)
return -1;
}
-int ff_dnxhd_find_cid(AVCodecContext *avctx)
+int ff_dnxhd_find_cid(AVCodecContext *avctx, int bit_depth)
{
int i, j;
int mbs = avctx->bit_rate/1000000;
@@ -417,7 +1153,7 @@ int ff_dnxhd_find_cid(AVCodecContext *avctx)
const CIDEntry *cid = &ff_dnxhd_cid_table[i];
if (cid->width == avctx->width && cid->height == avctx->height &&
cid->interlaced == !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT) &&
- cid->bit_depth == 8) { // until 10 bit is supported
+ cid->bit_depth == bit_depth) {
for (j = 0; j < sizeof(cid->bit_rates); j++) {
if (cid->bit_rates[j] == mbs)
return cid->cid;
diff --git a/libavcodec/dnxhddata.h b/libavcodec/dnxhddata.h
index df84187..74cf0b5 100644
--- a/libavcodec/dnxhddata.h
+++ b/libavcodec/dnxhddata.h
@@ -46,6 +46,6 @@ typedef struct {
extern const CIDEntry ff_dnxhd_cid_table[];
int ff_dnxhd_get_cid_table(int cid);
-int ff_dnxhd_find_cid(AVCodecContext *avctx);
+int ff_dnxhd_find_cid(AVCodecContext *avctx, int bit_depth);
#endif /* AVCODEC_DNXHDDATA_H */
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 6928b32..956196c 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -1,6 +1,9 @@
/*
* VC3/DNxHD decoder.
* Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
+ * Copyright (c) 2011 MirriAd Ltd
+ *
+ * 10 bit support added by MirriAd Ltd, Joseph Artsimovich <joseph at mirriad.com>
*
* This file is part of Libav.
*
@@ -28,7 +31,7 @@
#include "dnxhddata.h"
#include "dsputil.h"
-typedef struct {
+typedef struct DNXHDContext {
AVCodecContext *avctx;
AVFrame picture;
GetBitContext gb;
@@ -43,17 +46,22 @@ typedef struct {
DECLARE_ALIGNED(16, DCTELEM, blocks)[8][64];
ScanTable scantable;
const CIDEntry *cid_table;
+ int bit_depth; // 8, 10 or 0 if not initialized at all.
+ void (*decode_dct_block)(struct DNXHDContext *ctx, DCTELEM *block,
+ int n, int qscale);
} DNXHDContext;
#define DNXHD_VLC_BITS 9
#define DNXHD_DC_VLC_BITS 7
+static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, DCTELEM *block, int n, int qscale);
+static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, DCTELEM *block, int n, int qscale);
+
static av_cold int dnxhd_decode_init(AVCodecContext *avctx)
{
DNXHDContext *ctx = avctx->priv_data;
ctx->avctx = avctx;
- dsputil_init(&ctx->dsp, avctx);
avctx->coded_frame = &ctx->picture;
ctx->picture.type = AV_PICTURE_TYPE_I;
ctx->picture.key_frame = 1;
@@ -62,7 +70,7 @@ static av_cold int dnxhd_decode_init(AVCodecContext *avctx)
static int dnxhd_init_vlc(DNXHDContext *ctx, int cid)
{
- if (!ctx->cid_table) {
+ if (cid != ctx->cid) {
int index;
if ((index = ff_dnxhd_get_cid_table(cid)) < 0) {
@@ -70,10 +78,15 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid)
return -1;
}
ctx->cid_table = &ff_dnxhd_cid_table[index];
+
+ free_vlc(&ctx->ac_vlc);
+ free_vlc(&ctx->dc_vlc);
+ free_vlc(&ctx->run_vlc);
+
init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257,
ctx->cid_table->ac_bits, 1, 1,
ctx->cid_table->ac_codes, 2, 2, 0);
- init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, ctx->cid_table->bit_depth+4,
+ init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, ctx->bit_depth + 4,
ctx->cid_table->dc_bits, 1, 1,
ctx->cid_table->dc_codes, 1, 1, 0);
init_vlc(&ctx->run_vlc, DNXHD_VLC_BITS, 62,
@@ -81,6 +94,7 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid)
ctx->cid_table->run_codes, 2, 2, 0);
ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, ff_zigzag_direct);
+ ctx->cid = cid;
}
return 0;
}
@@ -88,7 +102,7 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid)
static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field)
{
static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 };
- int i;
+ int i, cid;
if (buf_size < 0x280)
return -1;
@@ -107,17 +121,30 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si
ctx->height = AV_RB16(buf + 0x18);
ctx->width = AV_RB16(buf + 0x1a);
- av_dlog(ctx->avctx, "width %d, heigth %d\n", ctx->width, ctx->height);
+ av_dlog(ctx->avctx, "width %d, height %d\n", ctx->width, ctx->height);
if (buf[0x21] & 0x40) {
- av_log(ctx->avctx, AV_LOG_ERROR, "10 bit per component\n");
- return -1;
+ ctx->avctx->pix_fmt = PIX_FMT_YUV422P10;
+ ctx->avctx->bits_per_raw_sample = 10;
+ if (ctx->bit_depth != 10) {
+ dsputil_init(&ctx->dsp, ctx->avctx);
+ ctx->bit_depth = 10;
+ ctx->decode_dct_block = dnxhd_decode_dct_block_10;
+ }
+ } else {
+ ctx->avctx->pix_fmt = PIX_FMT_YUV422P;
+ ctx->avctx->bits_per_raw_sample = 8;
+ if (ctx->bit_depth != 8) {
+ dsputil_init(&ctx->dsp, ctx->avctx);
+ ctx->bit_depth = 8;
+ ctx->decode_dct_block = dnxhd_decode_dct_block_8;
+ }
}
- ctx->cid = AV_RB32(buf + 0x28);
- av_dlog(ctx->avctx, "compression id %d\n", ctx->cid);
+ cid = AV_RB32(buf + 0x28);
+ av_dlog(ctx->avctx, "compression id %d\n", cid);
- if (dnxhd_init_vlc(ctx, ctx->cid) < 0)
+ if (dnxhd_init_vlc(ctx, cid) < 0)
return -1;
if (buf_size < ctx->cid_table->coding_unit_size) {
@@ -151,79 +178,103 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si
return 0;
}
-static int dnxhd_decode_dc(DNXHDContext *ctx)
-{
- int len;
-
- len = get_vlc2(&ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1);
- return len ? get_xbits(&ctx->gb, len) : 0;
-}
-
-static void dnxhd_decode_dct_block(DNXHDContext *ctx, DCTELEM *block, int n, int qscale)
+static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx,
+ DCTELEM *block, int n,
+ int qscale,
+ int index_bits,
+ int level_bias,
+ int level_shift)
{
- int i, j, index, index2;
+ int i, j, index1, index2, len;
int level, component, sign;
- const uint8_t *weigth_matrix;
+ const uint8_t *weight_matrix;
+ OPEN_READER(bs, &ctx->gb);
if (n&2) {
component = 1 + (n&1);
- weigth_matrix = ctx->cid_table->chroma_weight;
+ weight_matrix = ctx->cid_table->chroma_weight;
} else {
component = 0;
- weigth_matrix = ctx->cid_table->luma_weight;
+ weight_matrix = ctx->cid_table->luma_weight;
}
- ctx->last_dc[component] += dnxhd_decode_dc(ctx);
+ UPDATE_CACHE(bs, &ctx->gb);
+ GET_VLC(len, bs, &ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1);
+ if (len) {
+ level = GET_CACHE(bs, &ctx->gb);
+ LAST_SKIP_BITS(bs, &ctx->gb, len);
+ sign = ~level >> 31;
+ level = (NEG_USR32(sign ^ level, len) ^ sign) - sign;
+ ctx->last_dc[component] += level;
+ }
block[0] = ctx->last_dc[component];
//av_log(ctx->avctx, AV_LOG_DEBUG, "dc %d\n", block[0]);
+
for (i = 1; ; i++) {
- index = get_vlc2(&ctx->gb, ctx->ac_vlc.table, DNXHD_VLC_BITS, 2);
- //av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index);
- level = ctx->cid_table->ac_level[index];
+ UPDATE_CACHE(bs, &ctx->gb);
+ GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table,
+ DNXHD_VLC_BITS, 2);
+ //av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index1);
+ level = ctx->cid_table->ac_level[index1];
if (!level) { /* EOB */
//av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n");
- return;
+ break;
}
- sign = get_sbits(&ctx->gb, 1);
- if (ctx->cid_table->ac_index_flag[index]) {
- level += get_bits(&ctx->gb, ctx->cid_table->index_bits)<<6;
+ sign = SHOW_SBITS(bs, &ctx->gb, 1);
+ SKIP_BITS(bs, &ctx->gb, 1);
+
+ if (ctx->cid_table->ac_index_flag[index1]) {
+ level += SHOW_UBITS(bs, &ctx->gb, index_bits) << 6;
+ SKIP_BITS(bs, &ctx->gb, index_bits);
}
- if (ctx->cid_table->ac_run_flag[index]) {
- index2 = get_vlc2(&ctx->gb, ctx->run_vlc.table, DNXHD_VLC_BITS, 2);
+ if (ctx->cid_table->ac_run_flag[index1]) {
+ UPDATE_CACHE(bs, &ctx->gb);
+ GET_VLC(index2, bs, &ctx->gb, ctx->run_vlc.table,
+ DNXHD_VLC_BITS, 2);
i += ctx->cid_table->run[index2];
}
if (i > 63) {
av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i);
- return;
+ break;
}
j = ctx->scantable.permutated[i];
//av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j);
- //av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weigth %d\n", level, weigth_matrix[i]);
- level = (2*level+1) * qscale * weigth_matrix[i];
- if (ctx->cid_table->bit_depth == 10) {
- if (weigth_matrix[i] != 8)
- level += 8;
- level >>= 4;
- } else {
- if (weigth_matrix[i] != 32)
- level += 32;
- level >>= 6;
- }
+ //av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weight %d\n", level, weight_matrix[i]);
+ level = (2*level+1) * qscale * weight_matrix[i];
+ if (level_bias < 32 || weight_matrix[i] != level_bias)
+ level += level_bias;
+ level >>= level_shift;
+
//av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level);
block[j] = (level^sign) - sign;
}
+
+ CLOSE_READER(bs, &ctx->gb);
+}
+
+static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, DCTELEM *block,
+ int n, int qscale)
+{
+ dnxhd_decode_dct_block(ctx, block, n, qscale, 4, 32, 6);
+}
+
+static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, DCTELEM *block,
+ int n, int qscale)
+{
+ dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 8, 4);
}
static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
{
+ int shift1 = ctx->bit_depth == 10;
int dct_linesize_luma = ctx->picture.linesize[0];
int dct_linesize_chroma = ctx->picture.linesize[1];
uint8_t *dest_y, *dest_u, *dest_v;
- int dct_offset;
+ int dct_y_offset, dct_x_offset;
int qscale, i;
qscale = get_bits(&ctx->gb, 11);
@@ -232,7 +283,7 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
for (i = 0; i < 8; i++) {
ctx->dsp.clear_block(ctx->blocks[i]);
- dnxhd_decode_dct_block(ctx, ctx->blocks[i], i, qscale);
+ ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale);
}
if (ctx->picture.interlaced_frame) {
@@ -240,9 +291,9 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
dct_linesize_chroma <<= 1;
}
- dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << 4);
- dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << 3);
- dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << 3);
+ dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << (4 + shift1));
+ dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1));
+ dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1));
if (ctx->cur_field) {
dest_y += ctx->picture.linesize[0];
@@ -250,18 +301,19 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
dest_v += ctx->picture.linesize[2];
}
- dct_offset = dct_linesize_luma << 3;
- ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]);
- ctx->dsp.idct_put(dest_y + 8, dct_linesize_luma, ctx->blocks[1]);
- ctx->dsp.idct_put(dest_y + dct_offset, dct_linesize_luma, ctx->blocks[4]);
- ctx->dsp.idct_put(dest_y + dct_offset + 8, dct_linesize_luma, ctx->blocks[5]);
+ dct_y_offset = dct_linesize_luma << 3;
+ dct_x_offset = 8 << shift1;
+ ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]);
+ ctx->dsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, ctx->blocks[1]);
+ ctx->dsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, ctx->blocks[4]);
+ ctx->dsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[5]);
if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) {
- dct_offset = dct_linesize_chroma << 3;
- ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]);
- ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]);
- ctx->dsp.idct_put(dest_u + dct_offset, dct_linesize_chroma, ctx->blocks[6]);
- ctx->dsp.idct_put(dest_v + dct_offset, dct_linesize_chroma, ctx->blocks[7]);
+ dct_y_offset = dct_linesize_chroma << 3;
+ ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]);
+ ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]);
+ ctx->dsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[6]);
+ ctx->dsp.idct_put(dest_v + dct_y_offset, dct_linesize_chroma, ctx->blocks[7]);
}
return 0;
@@ -273,7 +325,7 @@ static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int b
for (y = 0; y < ctx->mb_height; y++) {
ctx->last_dc[0] =
ctx->last_dc[1] =
- ctx->last_dc[2] = 1<<(ctx->cid_table->bit_depth+2); // for levels +2^(bitdepth-1)
+ ctx->last_dc[2] = 1 << (ctx->bit_depth + 2); // for levels +2^(bitdepth-1)
init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3);
for (x = 0; x < ctx->mb_width; x++) {
//START_TIMER;
@@ -306,7 +358,6 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
first_field = 1;
}
- avctx->pix_fmt = PIX_FMT_YUV422P;
if (av_image_check_size(ctx->width, ctx->height, 0, avctx))
return -1;
avcodec_set_dimensions(avctx, ctx->width, ctx->height);
@@ -347,14 +398,13 @@ static av_cold int dnxhd_decode_close(AVCodecContext *avctx)
}
AVCodec ff_dnxhd_decoder = {
- "dnxhd",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DNXHD,
- sizeof(DNXHDContext),
- dnxhd_decode_init,
- NULL,
- dnxhd_decode_close,
- dnxhd_decode_frame,
- CODEC_CAP_DR1,
+ .name = "dnxhd",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DNXHD,
+ .priv_data_size = sizeof(DNXHDContext),
+ .init = dnxhd_decode_init,
+ .close = dnxhd_decode_close,
+ .decode = dnxhd_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
};
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 78da1c1..d1ab597 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -1,8 +1,10 @@
/*
* VC3/DNxHD encoder
* Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
+ * Copyright (c) 2011 MirriAd Ltd
*
* VC-3 encoder funded by the British Broadcasting Corporation
+ * 10 bit support added by MirriAd Ltd, Joseph Artsimovich <joseph at mirriad.com>
*
* This file is part of Libav.
*
@@ -28,21 +30,21 @@
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
+#include "mpegvideo_common.h"
#include "dnxhdenc.h"
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+#define DNX10BIT_QMAT_SHIFT 18 // The largest value that will not lead to overflow for 10bit samples.
static const AVOption options[]={
- {"nitris_compat", "encode with Avid Nitris compatibility", offsetof(DNXHDEncContext, nitris_compat), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 1, VE},
+ {"nitris_compat", "encode with Avid Nitris compatibility", offsetof(DNXHDEncContext, nitris_compat), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, VE},
{NULL}
};
static const AVClass class = { "dnxhd", av_default_item_name, options, LIBAVUTIL_VERSION_INT };
-int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
-
#define LAMBDA_FRAC_BITS 10
-static av_always_inline void dnxhd_get_pixels_8x4(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
+static void dnxhd_8bit_get_pixels_8x4_sym(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
{
int i;
for (i = 0; i < 4; i++) {
@@ -53,10 +55,48 @@ static av_always_inline void dnxhd_get_pixels_8x4(DCTELEM *restrict block, const
pixels += line_size;
block += 8;
}
- memcpy(block , block- 8, sizeof(*block)*8);
- memcpy(block+ 8, block-16, sizeof(*block)*8);
- memcpy(block+16, block-24, sizeof(*block)*8);
- memcpy(block+24, block-32, sizeof(*block)*8);
+ memcpy(block, block - 8, sizeof(*block) * 8);
+ memcpy(block + 8, block - 16, sizeof(*block) * 8);
+ memcpy(block + 16, block - 24, sizeof(*block) * 8);
+ memcpy(block + 24, block - 32, sizeof(*block) * 8);
+}
+
+static av_always_inline void dnxhd_10bit_get_pixels_8x4_sym(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
+{
+ int i;
+
+ block += 32;
+
+ for (i = 0; i < 4; i++) {
+ memcpy(block + i * 8, pixels + i * line_size, 8 * sizeof(*block));
+ memcpy(block - (i+1) * 8, pixels + i * line_size, 8 * sizeof(*block));
+ }
+}
+
+static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block,
+ int n, int qscale, int *overflow)
+{
+ const uint8_t *scantable= ctx->intra_scantable.scantable;
+ const int *qmat = ctx->q_intra_matrix[qscale];
+ int last_non_zero = 0;
+ int i;
+
+ ctx->dsp.fdct(block);
+
+ // Divide by 4 with rounding, to compensate scaling of DCT coefficients
+ block[0] = (block[0] + 2) >> 2;
+
+ for (i = 1; i < 64; ++i) {
+ int j = scantable[i];
+ int sign = block[j] >> 31;
+ int level = (block[j] ^ sign) - sign;
+ level = level * qmat[j] >> DNX10BIT_QMAT_SHIFT;
+ block[j] = (level ^ sign) - sign;
+ if (level)
+ last_non_zero = i;
+ }
+
+ return last_non_zero;
}
static int dnxhd_init_vlc(DNXHDEncContext *ctx)
@@ -65,9 +105,9 @@ static int dnxhd_init_vlc(DNXHDEncContext *ctx)
int max_level = 1<<(ctx->cid_table->bit_depth+2);
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->vlc_codes, max_level*4*sizeof(*ctx->vlc_codes), fail);
- FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->vlc_bits , max_level*4*sizeof(*ctx->vlc_bits ), fail);
- FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_codes, 63*2 , fail);
- FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_bits , 63 , fail);
+ FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->vlc_bits, max_level*4*sizeof(*ctx->vlc_bits) , fail);
+ FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_codes, 63*2, fail);
+ FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_bits, 63, fail);
ctx->vlc_codes += max_level*2;
ctx->vlc_bits += max_level*2;
@@ -119,31 +159,55 @@ static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
// init first elem to 1 to avoid div by 0 in convert_matrix
uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t*
int qscale, i;
+ const uint8_t *luma_weight_table = ctx->cid_table->luma_weight;
+ const uint8_t *chroma_weight_table = ctx->cid_table->chroma_weight;
- FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int) , fail);
- FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int) , fail);
+ FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int), fail);
+ FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int), fail);
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t), fail);
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t), fail);
- for (i = 1; i < 64; i++) {
- int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
- weight_matrix[j] = ctx->cid_table->luma_weight[i];
- }
- ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_l, ctx->qmatrix_l16, weight_matrix,
- ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1);
- for (i = 1; i < 64; i++) {
- int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
- weight_matrix[j] = ctx->cid_table->chroma_weight[i];
- }
- ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_c, ctx->qmatrix_c16, weight_matrix,
- ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1);
- for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) {
- for (i = 0; i < 64; i++) {
- ctx->qmatrix_l [qscale] [i] <<= 2; ctx->qmatrix_c [qscale] [i] <<= 2;
- ctx->qmatrix_l16[qscale][0][i] <<= 2; ctx->qmatrix_l16[qscale][1][i] <<= 2;
- ctx->qmatrix_c16[qscale][0][i] <<= 2; ctx->qmatrix_c16[qscale][1][i] <<= 2;
+ if (ctx->cid_table->bit_depth == 8) {
+ for (i = 1; i < 64; i++) {
+ int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
+ weight_matrix[j] = ctx->cid_table->luma_weight[i];
+ }
+ ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_l, ctx->qmatrix_l16, weight_matrix,
+ ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1);
+ for (i = 1; i < 64; i++) {
+ int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
+ weight_matrix[j] = ctx->cid_table->chroma_weight[i];
+ }
+ ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_c, ctx->qmatrix_c16, weight_matrix,
+ ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1);
+
+ for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) {
+ for (i = 0; i < 64; i++) {
+ ctx->qmatrix_l [qscale] [i] <<= 2; ctx->qmatrix_c [qscale] [i] <<= 2;
+ ctx->qmatrix_l16[qscale][0][i] <<= 2; ctx->qmatrix_l16[qscale][1][i] <<= 2;
+ ctx->qmatrix_c16[qscale][0][i] <<= 2; ctx->qmatrix_c16[qscale][1][i] <<= 2;
+ }
+ }
+ } else {
+ // 10-bit
+ for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) {
+ for (i = 1; i < 64; i++) {
+ int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
+
+ // The quantization formula from the VC-3 standard is:
+ // quantized = sign(block[i]) * floor(abs(block[i]/s) * p / (qscale * weight_table[i]))
+ // Where p is 32 for 8-bit samples and 8 for 10-bit ones.
+ // The s factor compensates scaling of DCT coefficients done by the DCT routines,
+ // and therefore is not present in standard. It's 8 for 8-bit samples and 4 for 10-bit ones.
+ // We want values of ctx->qtmatrix_l and ctx->qtmatrix_r to be:
+ // ((1 << DNX10BIT_QMAT_SHIFT) * (p / s)) / (qscale * weight_table[i])
+ // For 10-bit samples, p / s == 2
+ ctx->qmatrix_l[qscale][j] = (1 << (DNX10BIT_QMAT_SHIFT + 1)) / (qscale * luma_weight_table[i]);
+ ctx->qmatrix_c[qscale][j] = (1 << (DNX10BIT_QMAT_SHIFT + 1)) / (qscale * chroma_weight_table[i]);
+ }
}
}
+
return 0;
fail:
return -1;
@@ -166,10 +230,22 @@ static int dnxhd_init_rc(DNXHDEncContext *ctx)
static int dnxhd_encode_init(AVCodecContext *avctx)
{
DNXHDEncContext *ctx = avctx->priv_data;
- int i, index;
+ int i, index, bit_depth;
+
+ switch (avctx->pix_fmt) {
+ case PIX_FMT_YUV422P:
+ bit_depth = 8;
+ break;
+ case PIX_FMT_YUV422P10:
+ bit_depth = 10;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "pixel format is incompatible with DNxHD\n");
+ return -1;
+ }
- ctx->cid = ff_dnxhd_find_cid(avctx);
- if (!ctx->cid || avctx->pix_fmt != PIX_FMT_YUV422P) {
+ ctx->cid = ff_dnxhd_find_cid(avctx, bit_depth);
+ if (!ctx->cid) {
av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n");
return -1;
}
@@ -182,15 +258,25 @@ static int dnxhd_encode_init(AVCodecContext *avctx)
ctx->m.mb_intra = 1;
ctx->m.h263_aic = 1;
- ctx->get_pixels_8x4_sym = dnxhd_get_pixels_8x4;
+ avctx->bits_per_raw_sample = ctx->cid_table->bit_depth;
dsputil_init(&ctx->m.dsp, avctx);
ff_dct_common_init(&ctx->m);
+ if (!ctx->m.dct_quantize)
+ ctx->m.dct_quantize = dct_quantize_c;
+
+ if (ctx->cid_table->bit_depth == 10) {
+ ctx->m.dct_quantize = dnxhd_10bit_dct_quantize;
+ ctx->get_pixels_8x4_sym = dnxhd_10bit_get_pixels_8x4_sym;
+ ctx->block_width_l2 = 4;
+ } else {
+ ctx->get_pixels_8x4_sym = dnxhd_8bit_get_pixels_8x4_sym;
+ ctx->block_width_l2 = 3;
+ }
+
#if HAVE_MMX
ff_dnxhd_init_mmx(ctx);
#endif
- if (!ctx->m.dct_quantize)
- ctx->m.dct_quantize = dct_quantize_c;
ctx->m.mb_height = (avctx->height + 15) / 16;
ctx->m.mb_width = (avctx->width + 15) / 16;
@@ -219,7 +305,7 @@ static int dnxhd_encode_init(AVCodecContext *avctx)
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t), fail);
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_offs, ctx->m.mb_height*sizeof(uint32_t), fail);
FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t), fail);
- FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t) , fail);
+ FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t), fail);
ctx->frame.key_frame = 1;
ctx->frame.pict_type = AV_PICTURE_TYPE_I;
@@ -256,7 +342,7 @@ static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf)
AV_WB16(buf + 0x1a, avctx->width); // SPL
AV_WB16(buf + 0x1d, avctx->height>>ctx->interlaced); // NAL
- buf[0x21] = 0x38; // FIXME 8 bit per comp
+ buf[0x21] = ctx->cid_table->bit_depth == 10 ? 0x58 : 0x38;
buf[0x22] = 0x88 + (ctx->interlaced<<2);
AV_WB32(buf + 0x28, ctx->cid); // CID
buf[0x2c] = ctx->interlaced ? 0 : 0x80;
@@ -322,15 +408,27 @@ static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, DCTELEM *b
if (level) {
if (level < 0) {
level = (1-2*level) * qscale * weight_matrix[i];
- if (weight_matrix[i] != 32)
- level += 32;
- level >>= 6;
+ if (ctx->cid_table->bit_depth == 10) {
+ if (weight_matrix[i] != 8)
+ level += 8;
+ level >>= 4;
+ } else {
+ if (weight_matrix[i] != 32)
+ level += 32;
+ level >>= 6;
+ }
level = -level;
} else {
level = (2*level+1) * qscale * weight_matrix[i];
- if (weight_matrix[i] != 32)
- level += 32;
- level >>= 6;
+ if (ctx->cid_table->bit_depth == 10) {
+ if (weight_matrix[i] != 8)
+ level += 8;
+ level >>= 4;
+ } else {
+ if (weight_matrix[i] != 32)
+ level += 32;
+ level >>= 6;
+ }
}
block[j] = level;
}
@@ -342,7 +440,7 @@ static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block)
int score = 0;
int i;
for (i = 0; i < 64; i++)
- score += (block[i]-qblock[i])*(block[i]-qblock[i]);
+ score += (block[i] - qblock[i]) * (block[i] - qblock[i]);
return score;
}
@@ -365,31 +463,35 @@ static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, DCTELEM *bl
static av_always_inline void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
{
- const uint8_t *ptr_y = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize) + (mb_x << 4);
- const uint8_t *ptr_u = ctx->thread[0]->src[1] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3);
- const uint8_t *ptr_v = ctx->thread[0]->src[2] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3);
+ const int bs = ctx->block_width_l2;
+ const int bw = 1 << bs;
+ const uint8_t *ptr_y = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize) + (mb_x << bs+1);
+ const uint8_t *ptr_u = ctx->thread[0]->src[1] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs);
+ const uint8_t *ptr_v = ctx->thread[0]->src[2] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs);
DSPContext *dsp = &ctx->m.dsp;
- dsp->get_pixels(ctx->blocks[0], ptr_y , ctx->m.linesize);
- dsp->get_pixels(ctx->blocks[1], ptr_y + 8, ctx->m.linesize);
- dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize);
- dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize);
+ dsp->get_pixels(ctx->blocks[0], ptr_y, ctx->m.linesize);
+ dsp->get_pixels(ctx->blocks[1], ptr_y + bw, ctx->m.linesize);
+ dsp->get_pixels(ctx->blocks[2], ptr_u, ctx->m.uvlinesize);
+ dsp->get_pixels(ctx->blocks[3], ptr_v, ctx->m.uvlinesize);
if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {
if (ctx->interlaced) {
- ctx->get_pixels_8x4_sym(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize);
- ctx->get_pixels_8x4_sym(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize);
- ctx->get_pixels_8x4_sym(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize);
- ctx->get_pixels_8x4_sym(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize);
+ ctx->get_pixels_8x4_sym(ctx->blocks[4], ptr_y + ctx->dct_y_offset, ctx->m.linesize);
+ ctx->get_pixels_8x4_sym(ctx->blocks[5], ptr_y + ctx->dct_y_offset + bw, ctx->m.linesize);
+ ctx->get_pixels_8x4_sym(ctx->blocks[6], ptr_u + ctx->dct_uv_offset, ctx->m.uvlinesize);
+ ctx->get_pixels_8x4_sym(ctx->blocks[7], ptr_v + ctx->dct_uv_offset, ctx->m.uvlinesize);
} else {
- dsp->clear_block(ctx->blocks[4]); dsp->clear_block(ctx->blocks[5]);
- dsp->clear_block(ctx->blocks[6]); dsp->clear_block(ctx->blocks[7]);
+ dsp->clear_block(ctx->blocks[4]);
+ dsp->clear_block(ctx->blocks[5]);
+ dsp->clear_block(ctx->blocks[6]);
+ dsp->clear_block(ctx->blocks[7]);
}
} else {
- dsp->get_pixels(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize);
- dsp->get_pixels(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize);
- dsp->get_pixels(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize);
- dsp->get_pixels(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize);
+ dsp->get_pixels(ctx->blocks[4], ptr_y + ctx->dct_y_offset, ctx->m.linesize);
+ dsp->get_pixels(ctx->blocks[5], ptr_y + ctx->dct_y_offset + bw, ctx->m.linesize);
+ dsp->get_pixels(ctx->blocks[6], ptr_u + ctx->dct_uv_offset, ctx->m.uvlinesize);
+ dsp->get_pixels(ctx->blocks[7], ptr_v + ctx->dct_uv_offset, ctx->m.uvlinesize);
}
}
@@ -416,7 +518,7 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, i
ctx->m.last_dc[0] =
ctx->m.last_dc[1] =
- ctx->m.last_dc[2] = 1024;
+ ctx->m.last_dc[2] = 1 << (ctx->cid_table->bit_depth + 2);
for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
unsigned mb = mb_y * ctx->m.mb_width + mb_x;
@@ -439,6 +541,8 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, i
diff = block[0] - ctx->m.last_dc[n];
if (diff < 0) nbits = av_log2_16bit(-2*diff);
else nbits = av_log2_16bit( 2*diff);
+
+ assert(nbits < ctx->cid_table->bit_depth + 4);
dc_bits += ctx->cid_table->dc_bits[nbits] + nbits;
ctx->m.last_dc[n] = block[0];
@@ -464,7 +568,7 @@ static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, int jobnr, int
ctx->m.last_dc[0] =
ctx->m.last_dc[1] =
- ctx->m.last_dc[2] = 1024;
+ ctx->m.last_dc[2] = 1 << (ctx->cid_table->bit_depth + 2);
for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
unsigned mb = mb_y * ctx->m.mb_width + mb_x;
int qscale = ctx->mb_qscale[mb];
@@ -497,14 +601,14 @@ static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx)
for (mb_y = 0; mb_y < ctx->m.mb_height; mb_y++) {
int thread_size;
ctx->slice_offs[mb_y] = offset;
- ctx->slice_size[mb_y] = 0;
- for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
- unsigned mb = mb_y * ctx->m.mb_width + mb_x;
- ctx->slice_size[mb_y] += ctx->mb_bits[mb];
- }
- ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31;
- ctx->slice_size[mb_y] >>= 3;
- thread_size = ctx->slice_size[mb_y];
+ ctx->slice_size[mb_y] = 0;
+ for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
+ unsigned mb = mb_y * ctx->m.mb_width + mb_x;
+ ctx->slice_size[mb_y] += ctx->mb_bits[mb];
+ }
+ ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31;
+ ctx->slice_size[mb_y] >>= 3;
+ thread_size = ctx->slice_size[mb_y];
offset += thread_size;
}
}
@@ -514,13 +618,40 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, int jobnr, int
DNXHDEncContext *ctx = avctx->priv_data;
int mb_y = jobnr, mb_x;
ctx = ctx->thread[threadnr];
- for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
- unsigned mb = mb_y * ctx->m.mb_width + mb_x;
- uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize) + (mb_x<<4);
- int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize);
- int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)(sum*sum))>>8)+128)>>8;
- ctx->mb_cmp[mb].value = varc;
- ctx->mb_cmp[mb].mb = mb;
+ if (ctx->cid_table->bit_depth == 8) {
+ uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize);
+ for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x, pix += 16) {
+ unsigned mb = mb_y * ctx->m.mb_width + mb_x;
+ int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize);
+ int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)sum*sum)>>8)+128)>>8;
+ ctx->mb_cmp[mb].value = varc;
+ ctx->mb_cmp[mb].mb = mb;
+ }
+ } else { // 10-bit
+ int const linesize = ctx->m.linesize >> 1;
+ for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x) {
+ uint16_t *pix = (uint16_t*)ctx->thread[0]->src[0] + ((mb_y << 4) * linesize) + (mb_x << 4);
+ unsigned mb = mb_y * ctx->m.mb_width + mb_x;
+ int sum = 0;
+ int sqsum = 0;
+ int mean, sqmean;
+ int i, j;
+ // Macroblocks are 16x16 pixels, unlike DCT blocks which are 8x8.
+ for (i = 0; i < 16; ++i) {
+ for (j = 0; j < 16; ++j) {
+ // Turn 16-bit pixels into 10-bit ones.
+ int const sample = (unsigned)pix[j] >> 6;
+ sum += sample;
+ sqsum += sample * sample;
+ // 2^10 * 2^10 * 16 * 16 = 2^28, which is less than INT_MAX
+ }
+ pix += linesize;
+ }
+ mean = sum >> 8; // 16*16 == 2^8
+ sqmean = sqsum >> 8;
+ ctx->mb_cmp[mb].value = sqmean - mean * mean;
+ ctx->mb_cmp[mb].mb = mb;
+ }
}
return 0;
}
@@ -551,7 +682,8 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
int qscale = 1;
int mb = y*ctx->m.mb_width+x;
for (q = 1; q < avctx->qmax; q++) {
- unsigned score = ctx->mb_rc[q][mb].bits*lambda+(ctx->mb_rc[q][mb].ssd<<LAMBDA_FRAC_BITS);
+ unsigned score = ctx->mb_rc[q][mb].bits*lambda+
+ ((unsigned)ctx->mb_rc[q][mb].ssd<<LAMBDA_FRAC_BITS);
if (score < min) {
min = score;
qscale = q;
@@ -578,7 +710,7 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
lambda = (lambda+last_higher)>>1;
else
lambda -= down_step;
- down_step *= 5; // XXX tune ?
+ down_step = FFMIN((int64_t)down_step*5, INT_MAX);
up_step = 1<<LAMBDA_FRAC_BITS;
lambda = FFMAX(1, lambda);
if (lambda == last_lower)
@@ -862,15 +994,15 @@ static int dnxhd_encode_end(AVCodecContext *avctx)
}
AVCodec ff_dnxhd_encoder = {
- "dnxhd",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DNXHD,
- sizeof(DNXHDEncContext),
- dnxhd_encode_init,
- dnxhd_encode_picture,
- dnxhd_encode_end,
+ .name = "dnxhd",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DNXHD,
+ .priv_data_size = sizeof(DNXHDEncContext),
+ .init = dnxhd_encode_init,
+ .encode = dnxhd_encode_picture,
+ .close = dnxhd_encode_end,
.capabilities = CODEC_CAP_SLICE_THREADS,
- .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_NONE},
+ .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_YUV422P10, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
.priv_class = &class,
};
diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h
index bb24540..861546a 100644
--- a/libavcodec/dnxhdenc.h
+++ b/libavcodec/dnxhdenc.h
@@ -52,8 +52,12 @@ typedef struct DNXHDEncContext {
struct DNXHDEncContext *thread[MAX_THREADS];
+ // Because our samples are either 8 or 16 bits for 8-bit and 10-bit
+ // encoding respectively, these refer either to bytes or to two-byte words.
unsigned dct_y_offset;
unsigned dct_uv_offset;
+ unsigned block_width_l2;
+
int interlaced;
int cur_field;
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c
index af5bf8a..935f67c 100644
--- a/libavcodec/dpcm.c
+++ b/libavcodec/dpcm.c
@@ -39,17 +39,17 @@
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
+#include "bytestream.h"
typedef struct DPCMContext {
+ AVFrame frame;
int channels;
- short roq_square_array[256];
- long sample[2];//for SOL_DPCM
- const int *sol_table;//for SOL_DPCM
+ int16_t roq_square_array[256];
+ int sample[2]; ///< previous sample (for SOL_DPCM)
+ const int8_t *sol_table; ///< delta table for SOL_DPCM
} DPCMContext;
-#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000;
-
-static const int interplay_delta_table[] = {
+static const int16_t 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,
@@ -85,15 +85,17 @@ static const int interplay_delta_table[] = {
};
-static const int sol_table_old[16] =
- { 0x0, 0x1, 0x2 , 0x3, 0x6, 0xA, 0xF, 0x15,
- -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0};
+static const int8_t sol_table_old[16] = {
+ 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
+ -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0
+};
-static const int sol_table_new[16] =
- { 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
- 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15};
+static const int8_t sol_table_new[16] = {
+ 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
+ 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15
+};
-static const int sol_table_16[128] = {
+static const int16_t sol_table_16[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,
@@ -110,12 +112,15 @@ static const int sol_table_16[128] = {
};
-
static av_cold int dpcm_decode_init(AVCodecContext *avctx)
{
DPCMContext *s = avctx->priv_data;
int i;
- short square;
+
+ if (avctx->channels < 1 || avctx->channels > 2) {
+ av_log(avctx, AV_LOG_INFO, "invalid number of channels\n");
+ return AVERROR(EINVAL);
+ }
s->channels = avctx->channels;
s->sample[0] = s->sample[1] = 0;
@@ -125,25 +130,23 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
case CODEC_ID_ROQ_DPCM:
/* initialize square table */
for (i = 0; i < 128; i++) {
- square = i * i;
- s->roq_square_array[i] = square;
+ int16_t square = i * i;
+ s->roq_square_array[i ] = square;
s->roq_square_array[i + 128] = -square;
}
break;
-
case CODEC_ID_SOL_DPCM:
switch(avctx->codec_tag){
case 1:
- s->sol_table=sol_table_old;
+ s->sol_table = sol_table_old;
s->sample[0] = s->sample[1] = 0x80;
break;
case 2:
- s->sol_table=sol_table_new;
+ s->sol_table = sol_table_new;
s->sample[0] = s->sample[1] = 0x80;
break;
case 3:
- s->sol_table=sol_table_16;
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
@@ -155,163 +158,181 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
break;
}
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ if (avctx->codec->id == CODEC_ID_SOL_DPCM && avctx->codec_tag != 3)
+ avctx->sample_fmt = AV_SAMPLE_FMT_U8;
+ else
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
-static int dpcm_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+
+static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
+ const uint8_t *buf_end = buf + buf_size;
DPCMContext *s = avctx->priv_data;
- int in, out = 0;
+ int out = 0, ret;
int predictor[2];
- int channel_number = 0;
- short *output_samples = data;
- int shift[2];
- unsigned char byte;
- short diff;
+ int ch = 0;
+ int stereo = s->channels - 1;
+ int16_t *output_samples;
- if (!buf_size)
- return 0;
+ /* calculate output size */
+ switch(avctx->codec->id) {
+ case CODEC_ID_ROQ_DPCM:
+ out = buf_size - 8;
+ break;
+ case CODEC_ID_INTERPLAY_DPCM:
+ out = buf_size - 6 - s->channels;
+ break;
+ case CODEC_ID_XAN_DPCM:
+ out = buf_size - 2 * s->channels;
+ break;
+ case CODEC_ID_SOL_DPCM:
+ if (avctx->codec_tag != 3)
+ out = buf_size * 2;
+ else
+ out = buf_size;
+ break;
+ }
+ if (out <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
+ return AVERROR(EINVAL);
+ }
- // almost every DPCM variant expands one byte of data into two
- if(*data_size/2 < buf_size)
- return -1;
+ /* get output buffer */
+ s->frame.nb_samples = out / s->channels;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ output_samples = (int16_t *)s->frame.data[0];
switch(avctx->codec->id) {
case CODEC_ID_ROQ_DPCM:
- if (s->channels == 1)
- predictor[0] = AV_RL16(&buf[6]);
- else {
- predictor[0] = buf[7] << 8;
- predictor[1] = buf[6] << 8;
+ buf += 6;
+
+ if (stereo) {
+ predictor[1] = (int16_t)(bytestream_get_byte(&buf) << 8);
+ predictor[0] = (int16_t)(bytestream_get_byte(&buf) << 8);
+ } else {
+ predictor[0] = (int16_t)bytestream_get_le16(&buf);
}
- SE_16BIT(predictor[0]);
- SE_16BIT(predictor[1]);
/* decode the samples */
- for (in = 8, out = 0; in < buf_size; in++, out++) {
- predictor[channel_number] += s->roq_square_array[buf[in]];
- predictor[channel_number] = av_clip_int16(predictor[channel_number]);
- output_samples[out] = predictor[channel_number];
+ while (buf < buf_end) {
+ predictor[ch] += s->roq_square_array[*buf++];
+ predictor[ch] = av_clip_int16(predictor[ch]);
+ *output_samples++ = predictor[ch];
/* toggle channel */
- channel_number ^= s->channels - 1;
+ ch ^= stereo;
}
break;
case CODEC_ID_INTERPLAY_DPCM:
- in = 6; /* skip over the stream mask and stream length */
- predictor[0] = AV_RL16(&buf[in]);
- in += 2;
- SE_16BIT(predictor[0])
- output_samples[out++] = predictor[0];
- if (s->channels == 2) {
- predictor[1] = AV_RL16(&buf[in]);
- in += 2;
- SE_16BIT(predictor[1])
- output_samples[out++] = predictor[1];
+ buf += 6; /* skip over the stream mask and stream length */
+
+ for (ch = 0; ch < s->channels; ch++) {
+ predictor[ch] = (int16_t)bytestream_get_le16(&buf);
+ *output_samples++ = predictor[ch];
}
- while (in < buf_size) {
- predictor[channel_number] += interplay_delta_table[buf[in++]];
- predictor[channel_number] = av_clip_int16(predictor[channel_number]);
- output_samples[out++] = predictor[channel_number];
+ ch = 0;
+ while (buf < buf_end) {
+ predictor[ch] += interplay_delta_table[*buf++];
+ predictor[ch] = av_clip_int16(predictor[ch]);
+ *output_samples++ = predictor[ch];
/* toggle channel */
- channel_number ^= s->channels - 1;
+ ch ^= stereo;
}
-
break;
case CODEC_ID_XAN_DPCM:
- in = 0;
- shift[0] = shift[1] = 4;
- predictor[0] = AV_RL16(&buf[in]);
- in += 2;
- SE_16BIT(predictor[0]);
- if (s->channels == 2) {
- predictor[1] = AV_RL16(&buf[in]);
- in += 2;
- SE_16BIT(predictor[1]);
- }
-
- while (in < buf_size) {
- byte = buf[in++];
- diff = (byte & 0xFC) << 8;
- if ((byte & 0x03) == 3)
- shift[channel_number]++;
+ {
+ int shift[2] = { 4, 4 };
+
+ for (ch = 0; ch < s->channels; ch++)
+ predictor[ch] = (int16_t)bytestream_get_le16(&buf);
+
+ ch = 0;
+ while (buf < buf_end) {
+ uint8_t n = *buf++;
+ int16_t diff = (n & 0xFC) << 8;
+ if ((n & 0x03) == 3)
+ shift[ch]++;
else
- shift[channel_number] -= (2 * (byte & 3));
+ shift[ch] -= (2 * (n & 3));
/* saturate the shifter to a lower limit of 0 */
- if (shift[channel_number] < 0)
- shift[channel_number] = 0;
+ if (shift[ch] < 0)
+ shift[ch] = 0;
- diff >>= shift[channel_number];
- predictor[channel_number] += diff;
+ diff >>= shift[ch];
+ predictor[ch] += diff;
- predictor[channel_number] = av_clip_int16(predictor[channel_number]);
- output_samples[out++] = predictor[channel_number];
+ predictor[ch] = av_clip_int16(predictor[ch]);
+ *output_samples++ = predictor[ch];
/* toggle channel */
- channel_number ^= s->channels - 1;
+ ch ^= stereo;
}
break;
+ }
case CODEC_ID_SOL_DPCM:
- in = 0;
if (avctx->codec_tag != 3) {
- if(*data_size/4 < buf_size)
- return -1;
- while (in < buf_size) {
- int n1, n2;
- n1 = (buf[in] >> 4) & 0xF;
- n2 = buf[in++] & 0xF;
- s->sample[0] += s->sol_table[n1];
- if (s->sample[0] < 0) s->sample[0] = 0;
- if (s->sample[0] > 255) s->sample[0] = 255;
- output_samples[out++] = (s->sample[0] - 128) << 8;
- s->sample[s->channels - 1] += s->sol_table[n2];
- if (s->sample[s->channels - 1] < 0) s->sample[s->channels - 1] = 0;
- if (s->sample[s->channels - 1] > 255) s->sample[s->channels - 1] = 255;
- output_samples[out++] = (s->sample[s->channels - 1] - 128) << 8;
+ uint8_t *output_samples_u8 = data;
+ while (buf < buf_end) {
+ uint8_t n = *buf++;
+
+ s->sample[0] += s->sol_table[n >> 4];
+ s->sample[0] = av_clip_uint8(s->sample[0]);
+ *output_samples_u8++ = s->sample[0];
+
+ s->sample[stereo] += s->sol_table[n & 0x0F];
+ s->sample[stereo] = av_clip_uint8(s->sample[stereo]);
+ *output_samples_u8++ = s->sample[stereo];
}
} else {
- while (in < buf_size) {
- int n;
- n = buf[in++];
- if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F];
- else s->sample[channel_number] += s->sol_table[n & 0x7F];
- s->sample[channel_number] = av_clip_int16(s->sample[channel_number]);
- output_samples[out++] = s->sample[channel_number];
+ while (buf < buf_end) {
+ uint8_t n = *buf++;
+ if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F];
+ else s->sample[ch] += sol_table_16[n & 0x7F];
+ s->sample[ch] = av_clip_int16(s->sample[ch]);
+ *output_samples++ = s->sample[ch];
/* toggle channel */
- channel_number ^= s->channels - 1;
+ ch ^= stereo;
}
}
break;
}
- *data_size = out * sizeof(short);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return buf_size;
}
-#define DPCM_DECODER(id, name, long_name_) \
-AVCodec ff_ ## name ## _decoder = { \
- #name, \
- AVMEDIA_TYPE_AUDIO, \
- id, \
- sizeof(DPCMContext), \
- dpcm_decode_init, \
- NULL, \
- NULL, \
- dpcm_decode_frame, \
- .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+#define DPCM_DECODER(id_, name_, long_name_) \
+AVCodec ff_ ## name_ ## _decoder = { \
+ .name = #name_, \
+ .type = AVMEDIA_TYPE_AUDIO, \
+ .id = id_, \
+ .priv_data_size = sizeof(DPCMContext), \
+ .init = dpcm_decode_init, \
+ .decode = dpcm_decode_frame, \
+ .capabilities = CODEC_CAP_DR1, \
+ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
}
DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
-DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ");
-DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol");
-DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");
+DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ");
+DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol");
+DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 0722dd0..156f1de 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -234,15 +234,12 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_dpx_decoder = {
- "dpx",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DPX,
- sizeof(DPXContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- 0,
- NULL,
+ .name = "dpx",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DPX,
+ .priv_data_size = sizeof(DPXContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("DPX image"),
};
diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c
index 7ae9292..1ff9d97 100644
--- a/libavcodec/dpxenc.c
+++ b/libavcodec/dpxenc.c
@@ -35,7 +35,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
DPXContext *s = avctx->priv_data;
avctx->coded_frame = &s->picture;
- avctx->coded_frame->pict_type = FF_I_TYPE;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
avctx->coded_frame->key_frame = 1;
s->big_endian = 1;
diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c
index 643aed9..37d39f5 100644
--- a/libavcodec/dsicinav.c
+++ b/libavcodec/dsicinav.c
@@ -26,6 +26,7 @@
#include "avcodec.h"
#include "bytestream.h"
+#include "mathops.h"
typedef enum CinVideoBitmapIndex {
@@ -43,7 +44,7 @@ typedef struct CinVideoContext {
} CinVideoContext;
typedef struct CinAudioContext {
- AVCodecContext *avctx;
+ AVFrame frame;
int initial_decode_frame;
int delta;
} CinAudioContext;
@@ -216,7 +217,11 @@ static int cinvideo_decode_frame(AVCodecContext *avctx,
bitmap_frame_size = buf_size - 4;
/* handle palette */
+ if (bitmap_frame_size < palette_colors_count * (3 + (palette_type != 0)))
+ return AVERROR_INVALIDDATA;
if (palette_type == 0) {
+ if (palette_colors_count > 256)
+ return AVERROR_INVALIDDATA;
for (i = 0; i < palette_colors_count; ++i) {
cin->palette[i] = bytestream_get_le24(&buf);
bitmap_frame_size -= 3;
@@ -304,66 +309,78 @@ static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
{
CinAudioContext *cin = avctx->priv_data;
- cin->avctx = avctx;
+ if (avctx->channels != 1) {
+ av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
cin->initial_decode_frame = 1;
cin->delta = 0;
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ avcodec_get_frame_defaults(&cin->frame);
+ avctx->coded_frame = &cin->frame;
+
return 0;
}
-static int cinaudio_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
CinAudioContext *cin = avctx->priv_data;
- const uint8_t *src = buf;
- int16_t *samples = (int16_t *)data;
-
- buf_size = FFMIN(buf_size, *data_size/2);
+ const uint8_t *buf_end = buf + avpkt->size;
+ int16_t *samples;
+ int delta, ret;
+
+ /* get output buffer */
+ cin->frame.nb_samples = avpkt->size - cin->initial_decode_frame;
+ if ((ret = avctx->get_buffer(avctx, &cin->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (int16_t *)cin->frame.data[0];
+ delta = cin->delta;
if (cin->initial_decode_frame) {
cin->initial_decode_frame = 0;
- cin->delta = (int16_t)AV_RL16(src); src += 2;
- *samples++ = cin->delta;
- buf_size -= 2;
+ delta = sign_extend(AV_RL16(buf), 16);
+ buf += 2;
+ *samples++ = delta;
}
- while (buf_size > 0) {
- cin->delta += cinaudio_delta16_table[*src++];
- cin->delta = av_clip_int16(cin->delta);
- *samples++ = cin->delta;
- --buf_size;
+ while (buf < buf_end) {
+ delta += cinaudio_delta16_table[*buf++];
+ delta = av_clip_int16(delta);
+ *samples++ = delta;
}
+ cin->delta = delta;
- *data_size = (uint8_t *)samples - (uint8_t *)data;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = cin->frame;
- return src - buf;
+ return avpkt->size;
}
AVCodec ff_dsicinvideo_decoder = {
- "dsicinvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DSICINVIDEO,
- sizeof(CinVideoContext),
- cinvideo_decode_init,
- NULL,
- cinvideo_decode_end,
- cinvideo_decode_frame,
- CODEC_CAP_DR1,
+ .name = "dsicinvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DSICINVIDEO,
+ .priv_data_size = sizeof(CinVideoContext),
+ .init = cinvideo_decode_init,
+ .close = cinvideo_decode_end,
+ .decode = cinvideo_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
};
AVCodec ff_dsicinaudio_decoder = {
- "dsicinaudio",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_DSICINAUDIO,
- sizeof(CinAudioContext),
- cinaudio_decode_init,
- NULL,
- NULL,
- cinaudio_decode_frame,
+ .name = "dsicinaudio",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_DSICINAUDIO,
+ .priv_data_size = sizeof(CinAudioContext),
+ .init = cinaudio_decode_init,
+ .decode = cinaudio_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
};
diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
index 4389289..5c1039b 100644
--- a/libavcodec/dsputil.c
+++ b/libavcodec/dsputil.c
@@ -145,6 +145,41 @@ void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_s
}
}
+void ff_init_scantable_permutation(uint8_t *idct_permutation,
+ int idct_permutation_type)
+{
+ int i;
+
+ switch(idct_permutation_type){
+ case FF_NO_IDCT_PERM:
+ for(i=0; i<64; i++)
+ idct_permutation[i]= i;
+ break;
+ case FF_LIBMPEG2_IDCT_PERM:
+ for(i=0; i<64; i++)
+ idct_permutation[i]= (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
+ break;
+ case FF_SIMPLE_IDCT_PERM:
+ for(i=0; i<64; i++)
+ idct_permutation[i]= simple_mmx_permutation[i];
+ break;
+ case FF_TRANSPOSE_IDCT_PERM:
+ for(i=0; i<64; i++)
+ idct_permutation[i]= ((i&7)<<3) | (i>>3);
+ break;
+ case FF_PARTTRANS_IDCT_PERM:
+ for(i=0; i<64; i++)
+ idct_permutation[i]= (i&0x24) | ((i&3)<<3) | ((i>>3)&3);
+ break;
+ case FF_SSE2_IDCT_PERM:
+ for(i=0; i<64; i++)
+ idct_permutation[i]= (i&0x38) | idct_sse2_row_perm[i&7];
+ break;
+ default:
+ av_log(NULL, AV_LOG_ERROR, "Internal error, IDCT permutation not set\n");
+ }
+}
+
static int pix_sum_c(uint8_t * pix, int line_size)
{
int s, i, j;
@@ -185,7 +220,7 @@ static int pix_norm1_c(uint8_t * pix, int line_size)
s += sq[pix[6]];
s += sq[pix[7]];
#else
-#if LONG_MAX > 2147483647
+#if HAVE_FAST_64BIT
register uint64_t x=*(uint64_t*)pix;
s += sq[x&0xff];
s += sq[(x>>8)&0xff];
@@ -307,25 +342,6 @@ static int sse16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
return s;
}
-static void get_pixels_c(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
-{
- int i;
-
- /* read the pixels */
- for(i=0;i<8;i++) {
- block[0] = pixels[0];
- block[1] = pixels[1];
- block[2] = pixels[2];
- block[3] = pixels[3];
- block[4] = pixels[4];
- block[5] = pixels[5];
- block[6] = pixels[6];
- block[7] = pixels[7];
- pixels += line_size;
- block += 8;
- }
-}
-
static void diff_pixels_c(DCTELEM *restrict block, const uint8_t *s1,
const uint8_t *s2, int stride){
int i;
@@ -424,27 +440,6 @@ void ff_put_signed_pixels_clamped_c(const DCTELEM *block,
}
}
-static void put_pixels_nonclamped_c(const DCTELEM *block, uint8_t *restrict pixels,
- int line_size)
-{
- int i;
-
- /* read the pixels */
- for(i=0;i<8;i++) {
- pixels[0] = block[0];
- pixels[1] = block[1];
- pixels[2] = block[2];
- pixels[3] = block[3];
- pixels[4] = block[4];
- pixels[5] = block[5];
- pixels[6] = block[6];
- pixels[7] = block[7];
-
- pixels += line_size;
- block += 8;
- }
-}
-
void ff_add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels,
int line_size)
{
@@ -526,22 +521,6 @@ static void fill_block8_c(uint8_t *block, uint8_t value, int line_size, int h)
}
}
-static void scale_block_c(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize)
-{
- int i, j;
- uint16_t *dst1 = (uint16_t *) dst;
- uint16_t *dst2 = (uint16_t *)(dst + linesize);
-
- for (j = 0; j < 8; j++) {
- for (i = 0; i < 8; i++) {
- dst1[i] = dst2[i] = src[i] * 0x0101;
- }
- src += 8;
- dst1 += linesize;
- dst2 += linesize;
- }
-}
-
#define avg2(a,b) ((a+b+1)>>1)
#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
@@ -819,27 +798,6 @@ static inline void avg_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int
dst += stride;
}
}
-#if 0
-#define TPEL_WIDTH(width)\
-static void put_tpel_pixels ## width ## _mc00_c(uint8_t *dst, const uint8_t *src, int stride, int height){\
- void put_tpel_pixels_mc00_c(dst, src, stride, width, height);}\
-static void put_tpel_pixels ## width ## _mc10_c(uint8_t *dst, const uint8_t *src, int stride, int height){\
- void put_tpel_pixels_mc10_c(dst, src, stride, width, height);}\
-static void put_tpel_pixels ## width ## _mc20_c(uint8_t *dst, const uint8_t *src, int stride, int height){\
- void put_tpel_pixels_mc20_c(dst, src, stride, width, height);}\
-static void put_tpel_pixels ## width ## _mc01_c(uint8_t *dst, const uint8_t *src, int stride, int height){\
- void put_tpel_pixels_mc01_c(dst, src, stride, width, height);}\
-static void put_tpel_pixels ## width ## _mc11_c(uint8_t *dst, const uint8_t *src, int stride, int height){\
- void put_tpel_pixels_mc11_c(dst, src, stride, width, height);}\
-static void put_tpel_pixels ## width ## _mc21_c(uint8_t *dst, const uint8_t *src, int stride, int height){\
- void put_tpel_pixels_mc21_c(dst, src, stride, width, height);}\
-static void put_tpel_pixels ## width ## _mc02_c(uint8_t *dst, const uint8_t *src, int stride, int height){\
- void put_tpel_pixels_mc02_c(dst, src, stride, width, height);}\
-static void put_tpel_pixels ## width ## _mc12_c(uint8_t *dst, const uint8_t *src, int stride, int height){\
- void put_tpel_pixels_mc12_c(dst, src, stride, width, height);}\
-static void put_tpel_pixels ## width ## _mc22_c(uint8_t *dst, const uint8_t *src, int stride, int height){\
- void put_tpel_pixels_mc22_c(dst, src, stride, width, height);}
-#endif
#define QPEL_MC(r, OPNAME, RND, OP) \
static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\
@@ -1357,16 +1315,16 @@ static void wmv2_mspel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int
}
#if CONFIG_RV40_DECODER
-static void put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){
+void ff_put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){
put_pixels16_xy2_8_c(dst, src, stride, 16);
}
-static void avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){
+void ff_avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){
avg_pixels16_xy2_8_c(dst, src, stride, 16);
}
-static void put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){
+void ff_put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){
put_pixels8_xy2_8_c(dst, src, stride, 8);
}
-static void avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){
+void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){
avg_pixels8_xy2_8_c(dst, src, stride, 8);
}
#endif /* CONFIG_RV40_DECODER */
@@ -1821,7 +1779,7 @@ static void add_8x8basis_c(int16_t rem[64], int16_t basis[64], int scale){
}
/**
- * permutes an 8x8 block.
+ * Permute an 8x8 block.
* @param block the block which will be permuted according to the given permutation vector
* @param permutation the permutation vector
* @param last the last non zero coefficient in scantable order, used to speed the permutation up
@@ -2258,7 +2216,7 @@ static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *s
s->block_last_index[0/*FIXME*/]= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i);
s->dct_unquantize_inter(s, temp, 0, s->qscale);
- ff_simple_idct(temp); //FIXME
+ ff_simple_idct_8(temp); //FIXME
for(i=0; i<64; i++)
sum+= (temp[i]-bak[i])*(temp[i]-bak[i]);
@@ -2532,48 +2490,12 @@ static void vector_fmul_scalar_c(float *dst, const float *src, float mul,
dst[i] = src[i] * mul;
}
-static void vector_fmul_sv_scalar_2_c(float *dst, const float *src,
- const float **sv, float mul, int len)
-{
- int i;
- for (i = 0; i < len; i += 2, sv++) {
- dst[i ] = src[i ] * sv[0][0] * mul;
- dst[i+1] = src[i+1] * sv[0][1] * mul;
- }
-}
-
-static void vector_fmul_sv_scalar_4_c(float *dst, const float *src,
- const float **sv, float mul, int len)
-{
- int i;
- for (i = 0; i < len; i += 4, sv++) {
- dst[i ] = src[i ] * sv[0][0] * mul;
- dst[i+1] = src[i+1] * sv[0][1] * mul;
- dst[i+2] = src[i+2] * sv[0][2] * mul;
- dst[i+3] = src[i+3] * sv[0][3] * mul;
- }
-}
-
-static void sv_fmul_scalar_2_c(float *dst, const float **sv, float mul,
- int len)
-{
- int i;
- for (i = 0; i < len; i += 2, sv++) {
- dst[i ] = sv[0][0] * mul;
- dst[i+1] = sv[0][1] * mul;
- }
-}
-
-static void sv_fmul_scalar_4_c(float *dst, const float **sv, float mul,
- int len)
+static void vector_fmac_scalar_c(float *dst, const float *src, float mul,
+ int len)
{
int i;
- for (i = 0; i < len; i += 4, sv++) {
- dst[i ] = sv[0][0] * mul;
- dst[i+1] = sv[0][1] * mul;
- dst[i+2] = sv[0][2] * mul;
- dst[i+3] = sv[0][3] * mul;
- }
+ for (i = 0; i < len; i++)
+ dst[i] += src[i] * mul;
}
static void butterflies_float_c(float *restrict v1, float *restrict v2,
@@ -2587,6 +2509,18 @@ static void butterflies_float_c(float *restrict v1, float *restrict v2,
}
}
+static void butterflies_float_interleave_c(float *dst, const float *src0,
+ const float *src1, int len)
+{
+ int i;
+ for (i = 0; i < len; i++) {
+ float f1 = src0[i];
+ float f2 = src1[i];
+ dst[2*i ] = f1 + f2;
+ dst[2*i + 1] = f1 - f2;
+ }
+}
+
static float scalarproduct_float_c(const float *v1, const float *v2, int len)
{
float p = 0.0;
@@ -2676,6 +2610,22 @@ static void apply_window_int16_c(int16_t *output, const int16_t *input,
}
}
+static void vector_clip_int32_c(int32_t *dst, const int32_t *src, int32_t min,
+ int32_t max, unsigned int len)
+{
+ do {
+ *dst++ = av_clip(*src++, min, max);
+ *dst++ = av_clip(*src++, min, max);
+ *dst++ = av_clip(*src++, min, max);
+ *dst++ = av_clip(*src++, min, max);
+ *dst++ = av_clip(*src++, min, max);
+ *dst++ = av_clip(*src++, min, max);
+ *dst++ = av_clip(*src++, min, max);
+ *dst++ = av_clip(*src++, min, max);
+ len -= 8;
+ } while (len > 0);
+}
+
#define W0 2048
#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
@@ -2828,9 +2778,9 @@ av_cold void dsputil_static_init(void)
int ff_check_alignment(void){
static int did_fail=0;
- DECLARE_ALIGNED(16, int, aligned);
+ LOCAL_ALIGNED_16(int, aligned, [4]);
- if((intptr_t)&aligned & 15){
+ if((intptr_t)aligned & 15){
if(!did_fail){
#if HAVE_MMX || HAVE_ALTIVEC
av_log(NULL, AV_LOG_ERROR,
@@ -2853,44 +2803,28 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
ff_check_alignment();
#if CONFIG_ENCODERS
- if(avctx->dct_algo==FF_DCT_FASTINT) {
- c->fdct = fdct_ifast;
- c->fdct248 = fdct_ifast248;
- }
- else if(avctx->dct_algo==FF_DCT_FAAN) {
- c->fdct = ff_faandct;
- c->fdct248 = ff_faandct248;
- }
- else {
- c->fdct = ff_jpeg_fdct_islow; //slow/accurate/default
- c->fdct248 = ff_fdct248_islow;
+ if (avctx->bits_per_raw_sample == 10) {
+ c->fdct = ff_jpeg_fdct_islow_10;
+ c->fdct248 = ff_fdct248_islow_10;
+ } else {
+ if(avctx->dct_algo==FF_DCT_FASTINT) {
+ c->fdct = fdct_ifast;
+ c->fdct248 = fdct_ifast248;
+ }
+ else if(avctx->dct_algo==FF_DCT_FAAN) {
+ c->fdct = ff_faandct;
+ c->fdct248 = ff_faandct248;
+ }
+ else {
+ c->fdct = ff_jpeg_fdct_islow_8; //slow/accurate/default
+ c->fdct248 = ff_fdct248_islow_8;
+ }
}
#endif //CONFIG_ENCODERS
if(avctx->lowres==1){
- if(avctx->idct_algo==FF_IDCT_INT || avctx->idct_algo==FF_IDCT_AUTO || !CONFIG_H264_DECODER){
- c->idct_put= ff_jref_idct4_put;
- c->idct_add= ff_jref_idct4_add;
- }else{
- if (avctx->codec_id != CODEC_ID_H264) {
- c->idct_put= ff_h264_lowres_idct_put_8_c;
- c->idct_add= ff_h264_lowres_idct_add_8_c;
- } else {
- switch (avctx->bits_per_raw_sample) {
- case 9:
- c->idct_put= ff_h264_lowres_idct_put_9_c;
- c->idct_add= ff_h264_lowres_idct_add_9_c;
- break;
- case 10:
- c->idct_put= ff_h264_lowres_idct_put_10_c;
- c->idct_add= ff_h264_lowres_idct_add_10_c;
- break;
- default:
- c->idct_put= ff_h264_lowres_idct_put_8_c;
- c->idct_add= ff_h264_lowres_idct_add_8_c;
- }
- }
- }
+ c->idct_put= ff_jref_idct4_put;
+ c->idct_add= ff_jref_idct4_add;
c->idct = j_rev_dct4;
c->idct_permutation_type= FF_NO_IDCT_PERM;
}else if(avctx->lowres==2){
@@ -2904,6 +2838,12 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
c->idct = j_rev_dct1;
c->idct_permutation_type= FF_NO_IDCT_PERM;
}else{
+ if (avctx->bits_per_raw_sample == 10) {
+ c->idct_put = ff_simple_idct_put_10;
+ c->idct_add = ff_simple_idct_add_10;
+ c->idct = ff_simple_idct_10;
+ c->idct_permutation_type = FF_NO_IDCT_PERM;
+ } else {
if(avctx->idct_algo==FF_IDCT_INT){
c->idct_put= ff_jref_idct_put;
c->idct_add= ff_jref_idct_add;
@@ -2928,24 +2868,18 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
}else if(CONFIG_EATGQ_DECODER && avctx->idct_algo==FF_IDCT_EA) {
c->idct_put= ff_ea_idct_put_c;
c->idct_permutation_type= FF_NO_IDCT_PERM;
- }else if(CONFIG_BINK_DECODER && avctx->idct_algo==FF_IDCT_BINK) {
- c->idct = ff_bink_idct_c;
- c->idct_add = ff_bink_idct_add_c;
- c->idct_put = ff_bink_idct_put_c;
- c->idct_permutation_type = FF_NO_IDCT_PERM;
}else{ //accurate/default
- c->idct_put= ff_simple_idct_put;
- c->idct_add= ff_simple_idct_add;
- c->idct = ff_simple_idct;
+ c->idct_put = ff_simple_idct_put_8;
+ c->idct_add = ff_simple_idct_add_8;
+ c->idct = ff_simple_idct_8;
c->idct_permutation_type= FF_NO_IDCT_PERM;
}
+ }
}
- c->get_pixels = get_pixels_c;
c->diff_pixels = diff_pixels_c;
c->put_pixels_clamped = ff_put_pixels_clamped_c;
c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_c;
- c->put_pixels_nonclamped = put_pixels_nonclamped_c;
c->add_pixels_clamped = ff_add_pixels_clamped_c;
c->sum_abs_dctelem = sum_abs_dctelem_c;
c->gmc1 = gmc1_c;
@@ -2955,7 +2889,6 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
c->fill_block_tab[0] = fill_block16_c;
c->fill_block_tab[1] = fill_block8_c;
- c->scale_block = scale_block_c;
/* TODO [0] 16 [1] 8 */
c->pix_abs[0][0] = pix_abs16_c;
@@ -3025,16 +2958,6 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
#if CONFIG_WMV2_DECODER || CONFIG_VC1_DECODER
ff_intrax8dsp_init(c,avctx);
#endif
-#if CONFIG_RV30_DECODER
- ff_rv30dsp_init(c,avctx);
-#endif
-#if CONFIG_RV40_DECODER
- ff_rv40dsp_init(c,avctx);
- c->put_rv40_qpel_pixels_tab[0][15] = put_rv40_qpel16_mc33_c;
- c->avg_rv40_qpel_pixels_tab[0][15] = avg_rv40_qpel16_mc33_c;
- c->put_rv40_qpel_pixels_tab[1][15] = put_rv40_qpel8_mc33_c;
- c->avg_rv40_qpel_pixels_tab[1][15] = avg_rv40_qpel8_mc33_c;
-#endif
c->put_mspel_pixels_tab[0]= ff_put_pixels8x8_c;
c->put_mspel_pixels_tab[1]= put_mspel8_mc10_c;
@@ -3122,15 +3045,12 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
c->scalarproduct_int16 = scalarproduct_int16_c;
c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c;
c->apply_window_int16 = apply_window_int16_c;
+ c->vector_clip_int32 = vector_clip_int32_c;
c->scalarproduct_float = scalarproduct_float_c;
c->butterflies_float = butterflies_float_c;
+ c->butterflies_float_interleave = butterflies_float_interleave_c;
c->vector_fmul_scalar = vector_fmul_scalar_c;
-
- c->vector_fmul_sv_scalar[0] = vector_fmul_sv_scalar_2_c;
- c->vector_fmul_sv_scalar[1] = vector_fmul_sv_scalar_4_c;
-
- c->sv_fmul_scalar[0] = sv_fmul_scalar_2_c;
- c->sv_fmul_scalar[1] = sv_fmul_scalar_4_c;
+ c->vector_fmac_scalar = vector_fmac_scalar_c;
c->shrink[0]= av_image_copy_plane;
c->shrink[1]= ff_shrink22;
@@ -3172,13 +3092,14 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
c->PFX ## _pixels_tab[IDX][15] = FUNCC(PFX ## NUM ## _mc33, depth)
-#define BIT_DEPTH_FUNCS(depth)\
+#define BIT_DEPTH_FUNCS(depth, dct)\
+ c->get_pixels = FUNCC(get_pixels ## dct , depth);\
c->draw_edges = FUNCC(draw_edges , depth);\
c->emulated_edge_mc = FUNC (ff_emulated_edge_mc , depth);\
- c->clear_block = FUNCC(clear_block , depth);\
- c->clear_blocks = FUNCC(clear_blocks , depth);\
- c->add_pixels8 = FUNCC(add_pixels8 , depth);\
- c->add_pixels4 = FUNCC(add_pixels4 , depth);\
+ c->clear_block = FUNCC(clear_block ## dct , depth);\
+ c->clear_blocks = FUNCC(clear_blocks ## dct , depth);\
+ c->add_pixels8 = FUNCC(add_pixels8 ## dct , depth);\
+ c->add_pixels4 = FUNCC(add_pixels4 ## dct , depth);\
c->put_no_rnd_pixels_l2[0] = FUNCC(put_no_rnd_pixels16_l2, depth);\
c->put_no_rnd_pixels_l2[1] = FUNCC(put_no_rnd_pixels8_l2 , depth);\
\
@@ -3210,21 +3131,26 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
dspfunc2(avg_h264_qpel, 1, 8, depth);\
dspfunc2(avg_h264_qpel, 2, 4, depth);
- if (avctx->codec_id != CODEC_ID_H264 || avctx->bits_per_raw_sample == 8) {
- BIT_DEPTH_FUNCS(8)
- } else {
- switch (avctx->bits_per_raw_sample) {
- case 9:
- BIT_DEPTH_FUNCS(9)
- break;
- case 10:
- BIT_DEPTH_FUNCS(10)
- break;
- default:
- av_log(avctx, AV_LOG_DEBUG, "Unsupported bit depth: %d\n", avctx->bits_per_raw_sample);
- BIT_DEPTH_FUNCS(8)
- break;
+ switch (avctx->bits_per_raw_sample) {
+ case 9:
+ if (c->dct_bits == 32) {
+ BIT_DEPTH_FUNCS(9, _32);
+ } else {
+ BIT_DEPTH_FUNCS(9, _16);
}
+ break;
+ case 10:
+ if (c->dct_bits == 32) {
+ BIT_DEPTH_FUNCS(10, _32);
+ } else {
+ BIT_DEPTH_FUNCS(10, _16);
+ }
+ break;
+ default:
+ av_log(avctx, AV_LOG_DEBUG, "Unsupported bit depth: %d\n", avctx->bits_per_raw_sample);
+ case 8:
+ BIT_DEPTH_FUNCS(8, _16);
+ break;
}
@@ -3245,43 +3171,6 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
c->avg_2tap_qpel_pixels_tab[0][i]= c->avg_h264_qpel_pixels_tab[0][i];
}
- c->put_rv30_tpel_pixels_tab[0][0] = c->put_h264_qpel_pixels_tab[0][0];
- c->put_rv30_tpel_pixels_tab[1][0] = c->put_h264_qpel_pixels_tab[1][0];
- c->avg_rv30_tpel_pixels_tab[0][0] = c->avg_h264_qpel_pixels_tab[0][0];
- c->avg_rv30_tpel_pixels_tab[1][0] = c->avg_h264_qpel_pixels_tab[1][0];
-
- c->put_rv40_qpel_pixels_tab[0][0] = c->put_h264_qpel_pixels_tab[0][0];
- c->put_rv40_qpel_pixels_tab[1][0] = c->put_h264_qpel_pixels_tab[1][0];
- c->avg_rv40_qpel_pixels_tab[0][0] = c->avg_h264_qpel_pixels_tab[0][0];
- c->avg_rv40_qpel_pixels_tab[1][0] = c->avg_h264_qpel_pixels_tab[1][0];
-
- switch(c->idct_permutation_type){
- case FF_NO_IDCT_PERM:
- for(i=0; i<64; i++)
- c->idct_permutation[i]= i;
- break;
- case FF_LIBMPEG2_IDCT_PERM:
- for(i=0; i<64; i++)
- c->idct_permutation[i]= (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
- break;
- case FF_SIMPLE_IDCT_PERM:
- for(i=0; i<64; i++)
- c->idct_permutation[i]= simple_mmx_permutation[i];
- break;
- case FF_TRANSPOSE_IDCT_PERM:
- for(i=0; i<64; i++)
- c->idct_permutation[i]= ((i&7)<<3) | (i>>3);
- break;
- case FF_PARTTRANS_IDCT_PERM:
- for(i=0; i<64; i++)
- c->idct_permutation[i]= (i&0x24) | ((i&3)<<3) | ((i>>3)&3);
- break;
- case FF_SSE2_IDCT_PERM:
- for(i=0; i<64; i++)
- c->idct_permutation[i]= (i&0x38) | idct_sse2_row_perm[i&7];
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "Internal error, IDCT permutation not set\n");
- }
+ ff_init_scantable_permutation(c->idct_permutation,
+ c->idct_permutation_type);
}
-
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index 7a28b06..3001609 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -40,8 +40,10 @@ typedef short DCTELEM;
void fdct_ifast (DCTELEM *data);
void fdct_ifast248 (DCTELEM *data);
-void ff_jpeg_fdct_islow (DCTELEM *data);
-void ff_fdct248_islow (DCTELEM *data);
+void ff_jpeg_fdct_islow_8(DCTELEM *data);
+void ff_jpeg_fdct_islow_10(DCTELEM *data);
+void ff_fdct248_islow_8(DCTELEM *data);
+void ff_fdct248_islow_10(DCTELEM *data);
void j_rev_dct (DCTELEM *data);
void j_rev_dct4 (DCTELEM *data);
@@ -58,13 +60,13 @@ void ff_h264_idct8_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride)
void ff_h264_idct_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
void ff_h264_idct8_dc_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
void ff_h264_idct_dc_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
-void ff_h264_lowres_idct_add_ ## depth ## _c(uint8_t *dst, int stride, DCTELEM *block);\
-void ff_h264_lowres_idct_put_ ## depth ## _c(uint8_t *dst, int stride, DCTELEM *block);\
void ff_h264_idct_add16_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
void ff_h264_idct_add16intra_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
void ff_h264_idct8_add4_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_idct_add8_422_ ## depth ## _c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
void ff_h264_idct_add8_ ## depth ## _c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
void ff_h264_luma_dc_dequant_idct_ ## depth ## _c(DCTELEM *output, DCTELEM *input, int qmul);\
+void ff_h264_chroma422_dc_dequant_idct_ ## depth ## _c(DCTELEM *block, int qmul);\
void ff_h264_chroma_dc_dequant_idct_ ## depth ## _c(DCTELEM *block, int qmul);
H264_IDCT( 8)
@@ -111,14 +113,15 @@ void ff_vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size, const DCTELEM
void ff_vp3_v_loop_filter_c(uint8_t *src, int stride, int *bounding_values);
void ff_vp3_h_loop_filter_c(uint8_t *src, int stride, int *bounding_values);
-/* Bink functions */
-void ff_bink_idct_c (DCTELEM *block);
-void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block);
-void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block);
-
/* EA functions */
void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block);
+/* RV40 functions */
+void ff_put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride);
+void ff_avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride);
+void ff_put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride);
+void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride);
+
/* 1/2^n downscaling functions from imgconvert.c */
void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
@@ -150,7 +153,7 @@ void clear_blocks_c(DCTELEM *blocks);
/* add and put pixel (decoding) */
// blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16
-//h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller then 4
+//h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller than 4
typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h);
typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h);
typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);
@@ -183,7 +186,7 @@ static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
}
/* motion estimation */
-// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2
+// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller than 2
// although currently h<4 is not used as functions with width <8 are neither used nor implemented
typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/;
@@ -201,6 +204,8 @@ typedef struct ScanTable{
} ScanTable;
void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable);
+void ff_init_scantable_permutation(uint8_t *idct_permutation,
+ int idct_permutation_type);
#define EMULATED_EDGE(depth) \
void ff_emulated_edge_mc_ ## depth (uint8_t *buf, const uint8_t *src, int linesize,\
@@ -211,8 +216,6 @@ EMULATED_EDGE(8)
EMULATED_EDGE(9)
EMULATED_EDGE(10)
-#define ff_emulated_edge_mc ff_emulated_edge_mc_8
-
void ff_add_pixels_clamped_c(const DCTELEM *block, uint8_t *dest, int linesize);
void ff_put_pixels_clamped_c(const DCTELEM *block, uint8_t *dest, int linesize);
void ff_put_signed_pixels_clamped_c(const DCTELEM *block, uint8_t *dest, int linesize);
@@ -221,12 +224,16 @@ void ff_put_signed_pixels_clamped_c(const DCTELEM *block, uint8_t *dest, int lin
* DSPContext.
*/
typedef struct DSPContext {
+ /**
+ * Size of DCT coefficients.
+ */
+ int dct_bits;
+
/* pixel ops : interface with DCT */
void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size);
void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride);
void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
- void (*put_pixels_nonclamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size);
void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size);
@@ -421,31 +428,16 @@ typedef struct DSPContext {
void (*vector_fmul_scalar)(float *dst, const float *src, float mul,
int len);
/**
- * Multiply a vector of floats by concatenated short vectors of
- * floats and by a scalar float. Source and destination vectors
- * must overlap exactly or not at all.
- * [0]: short vectors of length 2, 8-byte aligned
- * [1]: short vectors of length 4, 16-byte aligned
- * @param dst output vector, 16-byte aligned
+ * Multiply a vector of floats by a scalar float and add to
+ * destination vector. Source and destination vectors must
+ * overlap exactly or not at all.
+ * @param dst result vector, 16-byte aligned
* @param src input vector, 16-byte aligned
- * @param sv array of pointers to short vectors
- * @param mul scalar value
- * @param len number of elements in src and dst, multiple of 4
- */
- void (*vector_fmul_sv_scalar[2])(float *dst, const float *src,
- const float **sv, float mul, int len);
- /**
- * Multiply short vectors of floats by a scalar float, store
- * concatenated result.
- * [0]: short vectors of length 2, 8-byte aligned
- * [1]: short vectors of length 4, 16-byte aligned
- * @param dst output vector, 16-byte aligned
- * @param sv array of pointers to short vectors
* @param mul scalar value
- * @param len number of output elements, multiple of 4
+ * @param len length of vector, multiple of 4
*/
- void (*sv_fmul_scalar[2])(float *dst, const float **sv,
- float mul, int len);
+ void (*vector_fmac_scalar)(float *dst, const float *src, float mul,
+ int len);
/**
* Calculate the scalar product of two vectors of floats.
* @param v1 first vector, 16-byte aligned
@@ -461,6 +453,23 @@ typedef struct DSPContext {
*/
void (*butterflies_float)(float *restrict v1, float *restrict v2, int len);
+ /**
+ * Calculate the sum and difference of two vectors of floats and interleave
+ * results into a separate output vector of floats, with each sum
+ * positioned before the corresponding difference.
+ *
+ * @param dst output vector
+ * constraints: 16-byte aligned
+ * @param src0 first input vector
+ * constraints: 32-byte aligned
+ * @param src1 second input vector
+ * constraints: 32-byte aligned
+ * @param len number of elements in the input
+ * constraints: multiple of 8
+ */
+ void (*butterflies_float_interleave)(float *dst, const float *src0,
+ const float *src1, int len);
+
/* (I)DCT */
void (*fdct)(DCTELEM *block/* align 16*/);
void (*fdct248)(DCTELEM *block/* align 16*/);
@@ -489,8 +498,8 @@ typedef struct DSPContext {
* with the zigzag/alternate scan<br>
* an example to avoid confusion:
* - (->decode coeffs -> zigzag reorder -> dequant -> reference idct ->...)
- * - (x -> referece dct -> reference idct -> x)
- * - (x -> referece dct -> simple_mmx_perm = idct_permutation -> simple_idct_mmx -> x)
+ * - (x -> reference dct -> reference idct -> x)
+ * - (x -> reference dct -> simple_mmx_perm = idct_permutation -> simple_idct_mmx -> x)
* - (->decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant -> simple_idct_mmx ->...)
*/
uint8_t idct_permutation[64];
@@ -555,19 +564,23 @@ typedef struct DSPContext {
void (*apply_window_int16)(int16_t *output, const int16_t *input,
const int16_t *window, unsigned int len);
- /* rv30 functions */
- qpel_mc_func put_rv30_tpel_pixels_tab[4][16];
- qpel_mc_func avg_rv30_tpel_pixels_tab[4][16];
-
- /* rv40 functions */
- qpel_mc_func put_rv40_qpel_pixels_tab[4][16];
- qpel_mc_func avg_rv40_qpel_pixels_tab[4][16];
- h264_chroma_mc_func put_rv40_chroma_pixels_tab[3];
- h264_chroma_mc_func avg_rv40_chroma_pixels_tab[3];
+ /**
+ * Clip each element in an array of int32_t to a given minimum and maximum value.
+ * @param dst destination array
+ * constraints: 16-byte aligned
+ * @param src source array
+ * constraints: 16-byte aligned
+ * @param min minimum value
+ * constraints: must in the the range [-(1<<24), 1<<24]
+ * @param max maximum value
+ * constraints: must in the the range [-(1<<24), 1<<24]
+ * @param len number of elements in the array
+ * constraints: multiple of 32 greater than zero
+ */
+ void (*vector_clip_int32)(int32_t *dst, const int32_t *src, int32_t min,
+ int32_t max, unsigned int len);
- /* bink functions */
op_fill_func fill_block_tab[2];
- void (*scale_block)(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize);
} DSPContext;
void dsputil_static_init(void);
@@ -641,8 +654,6 @@ void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx);
void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx);
void ff_dsputil_init_dwt(DSPContext *c);
-void ff_rv30dsp_init(DSPContext* c, AVCodecContext *avctx);
-void ff_rv40dsp_init(DSPContext* c, AVCodecContext *avctx);
void ff_intrax8dsp_init(DSPContext* c, AVCodecContext *avctx);
void ff_mlp_init(DSPContext* c, AVCodecContext *avctx);
void ff_mlp_init_x86(DSPContext* c, AVCodecContext *avctx);
diff --git a/libavcodec/dsputil_template.c b/libavcodec/dsputil_template.c
index b859318..72ed6bf 100644
--- a/libavcodec/dsputil_template.c
+++ b/libavcodec/dsputil_template.c
@@ -27,7 +27,7 @@
* DSP utils
*/
-#include "high_bit_depth.h"
+#include "bit_depth_template.c"
static inline void FUNC(copy_block2)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
{
@@ -192,187 +192,89 @@ void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src, int linesize, i
}
}
-static void FUNCC(add_pixels8)(uint8_t *restrict _pixels, DCTELEM *_block, int line_size)
-{
- int i;
- pixel *restrict pixels = (pixel *restrict)_pixels;
- dctcoef *block = (dctcoef*)_block;
- line_size /= sizeof(pixel);
-
- for(i=0;i<8;i++) {
- pixels[0] += block[0];
- pixels[1] += block[1];
- pixels[2] += block[2];
- pixels[3] += block[3];
- pixels[4] += block[4];
- pixels[5] += block[5];
- pixels[6] += block[6];
- pixels[7] += block[7];
- pixels += line_size;
- block += 8;
- }
+#define DCTELEM_FUNCS(dctcoef, suffix) \
+static void FUNCC(get_pixels ## suffix)(DCTELEM *restrict _block, \
+ const uint8_t *_pixels, \
+ int line_size) \
+{ \
+ const pixel *pixels = (const pixel *) _pixels; \
+ dctcoef *restrict block = (dctcoef *) _block; \
+ int i; \
+ \
+ /* read the pixels */ \
+ for(i=0;i<8;i++) { \
+ block[0] = pixels[0]; \
+ block[1] = pixels[1]; \
+ block[2] = pixels[2]; \
+ block[3] = pixels[3]; \
+ block[4] = pixels[4]; \
+ block[5] = pixels[5]; \
+ block[6] = pixels[6]; \
+ block[7] = pixels[7]; \
+ pixels += line_size / sizeof(pixel); \
+ block += 8; \
+ } \
+} \
+ \
+static void FUNCC(add_pixels8 ## suffix)(uint8_t *restrict _pixels, \
+ DCTELEM *_block, \
+ int line_size) \
+{ \
+ int i; \
+ pixel *restrict pixels = (pixel *restrict)_pixels; \
+ dctcoef *block = (dctcoef*)_block; \
+ line_size /= sizeof(pixel); \
+ \
+ for(i=0;i<8;i++) { \
+ pixels[0] += block[0]; \
+ pixels[1] += block[1]; \
+ pixels[2] += block[2]; \
+ pixels[3] += block[3]; \
+ pixels[4] += block[4]; \
+ pixels[5] += block[5]; \
+ pixels[6] += block[6]; \
+ pixels[7] += block[7]; \
+ pixels += line_size; \
+ block += 8; \
+ } \
+} \
+ \
+static void FUNCC(add_pixels4 ## suffix)(uint8_t *restrict _pixels, \
+ DCTELEM *_block, \
+ int line_size) \
+{ \
+ int i; \
+ pixel *restrict pixels = (pixel *restrict)_pixels; \
+ dctcoef *block = (dctcoef*)_block; \
+ line_size /= sizeof(pixel); \
+ \
+ for(i=0;i<4;i++) { \
+ pixels[0] += block[0]; \
+ pixels[1] += block[1]; \
+ pixels[2] += block[2]; \
+ pixels[3] += block[3]; \
+ pixels += line_size; \
+ block += 4; \
+ } \
+} \
+ \
+static void FUNCC(clear_block ## suffix)(DCTELEM *block) \
+{ \
+ memset(block, 0, sizeof(dctcoef)*64); \
+} \
+ \
+/** \
+ * memset(blocks, 0, sizeof(DCTELEM)*6*64) \
+ */ \
+static void FUNCC(clear_blocks ## suffix)(DCTELEM *blocks) \
+{ \
+ memset(blocks, 0, sizeof(dctcoef)*6*64); \
}
-static void FUNCC(add_pixels4)(uint8_t *restrict _pixels, DCTELEM *_block, int line_size)
-{
- int i;
- pixel *restrict pixels = (pixel *restrict)_pixels;
- dctcoef *block = (dctcoef*)_block;
- line_size /= sizeof(pixel);
-
- for(i=0;i<4;i++) {
- pixels[0] += block[0];
- pixels[1] += block[1];
- pixels[2] += block[2];
- pixels[3] += block[3];
- pixels += line_size;
- block += 4;
- }
-}
-
-#if 0
-
-#define PIXOP2(OPNAME, OP) \
-static void OPNAME ## _pixels(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
-{\
- int i;\
- for(i=0; i<h; i++){\
- OP(*((uint64_t*)block), AV_RN64(pixels));\
- pixels+=line_size;\
- block +=line_size;\
- }\
-}\
-\
-static void OPNAME ## _no_rnd_pixels_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
-{\
- int i;\
- for(i=0; i<h; i++){\
- const uint64_t a= AV_RN64(pixels );\
- const uint64_t b= AV_RN64(pixels+1);\
- OP(*((uint64_t*)block), (a&b) + (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\
- pixels+=line_size;\
- block +=line_size;\
- }\
-}\
-\
-static void OPNAME ## _pixels_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
-{\
- int i;\
- for(i=0; i<h; i++){\
- const uint64_t a= AV_RN64(pixels );\
- const uint64_t b= AV_RN64(pixels+1);\
- OP(*((uint64_t*)block), (a|b) - (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\
- pixels+=line_size;\
- block +=line_size;\
- }\
-}\
-\
-static void OPNAME ## _no_rnd_pixels_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
-{\
- int i;\
- for(i=0; i<h; i++){\
- const uint64_t a= AV_RN64(pixels );\
- const uint64_t b= AV_RN64(pixels+line_size);\
- OP(*((uint64_t*)block), (a&b) + (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\
- pixels+=line_size;\
- block +=line_size;\
- }\
-}\
-\
-static void OPNAME ## _pixels_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
-{\
- int i;\
- for(i=0; i<h; i++){\
- const uint64_t a= AV_RN64(pixels );\
- const uint64_t b= AV_RN64(pixels+line_size);\
- OP(*((uint64_t*)block), (a|b) - (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\
- pixels+=line_size;\
- block +=line_size;\
- }\
-}\
-\
-static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
-{\
- int i;\
- const uint64_t a= AV_RN64(pixels );\
- const uint64_t b= AV_RN64(pixels+1);\
- uint64_t l0= (a&0x0303030303030303ULL)\
- + (b&0x0303030303030303ULL)\
- + 0x0202020202020202ULL;\
- uint64_t h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\
- + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\
- uint64_t l1,h1;\
-\
- pixels+=line_size;\
- for(i=0; i<h; i+=2){\
- uint64_t a= AV_RN64(pixels );\
- uint64_t b= AV_RN64(pixels+1);\
- l1= (a&0x0303030303030303ULL)\
- + (b&0x0303030303030303ULL);\
- h1= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\
- + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\
- OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\
- pixels+=line_size;\
- block +=line_size;\
- a= AV_RN64(pixels );\
- b= AV_RN64(pixels+1);\
- l0= (a&0x0303030303030303ULL)\
- + (b&0x0303030303030303ULL)\
- + 0x0202020202020202ULL;\
- h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\
- + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\
- OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\
- pixels+=line_size;\
- block +=line_size;\
- }\
-}\
-\
-static void OPNAME ## _no_rnd_pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
-{\
- int i;\
- const uint64_t a= AV_RN64(pixels );\
- const uint64_t b= AV_RN64(pixels+1);\
- uint64_t l0= (a&0x0303030303030303ULL)\
- + (b&0x0303030303030303ULL)\
- + 0x0101010101010101ULL;\
- uint64_t h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\
- + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\
- uint64_t l1,h1;\
-\
- pixels+=line_size;\
- for(i=0; i<h; i+=2){\
- uint64_t a= AV_RN64(pixels );\
- uint64_t b= AV_RN64(pixels+1);\
- l1= (a&0x0303030303030303ULL)\
- + (b&0x0303030303030303ULL);\
- h1= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\
- + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\
- OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\
- pixels+=line_size;\
- block +=line_size;\
- a= AV_RN64(pixels );\
- b= AV_RN64(pixels+1);\
- l0= (a&0x0303030303030303ULL)\
- + (b&0x0303030303030303ULL)\
- + 0x0101010101010101ULL;\
- h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\
- + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\
- OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\
- pixels+=line_size;\
- block +=line_size;\
- }\
-}\
-\
-CALL_2X_PIXELS(OPNAME ## _pixels16_c , OPNAME ## _pixels_c , 8*sizeof(pixel))\
-CALL_2X_PIXELS(OPNAME ## _pixels16_x2_c , OPNAME ## _pixels_x2_c , 8*sizeof(pixel))\
-CALL_2X_PIXELS(OPNAME ## _pixels16_y2_c , OPNAME ## _pixels_y2_c , 8*sizeof(pixel))\
-CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_c, OPNAME ## _pixels_xy2_c, 8*sizeof(pixel))\
-CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_x2_c , OPNAME ## _no_rnd_pixels_x2_c , 8*sizeof(pixel))\
-CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_y2_c , OPNAME ## _no_rnd_pixels_y2_c , 8*sizeof(pixel))\
-CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_c, OPNAME ## _no_rnd_pixels_xy2_c, 8*sizeof(pixel))
-
-#define op_avg(a, b) a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEFEFEFEFEULL)>>1) )
-#else // 64 bit variant
+DCTELEM_FUNCS(DCTELEM, _16)
+#if BIT_DEPTH > 8
+DCTELEM_FUNCS(dctcoef, _32)
+#endif
#define PIXOP2(OPNAME, OP) \
static void FUNCC(OPNAME ## _pixels2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
@@ -749,7 +651,6 @@ CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_y2) , FUNCC(OPNAME ## _no_rnd_pi
CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_xy2), FUNCC(OPNAME ## _no_rnd_pixels8_xy2), 8*sizeof(pixel))\
#define op_avg(a, b) a = rnd_avg_pixel4(a, b)
-#endif
#define op_put(a, b) a = b
PIXOP2(avg, op_avg)
@@ -1376,16 +1277,3 @@ void FUNCC(ff_put_pixels16x16)(uint8_t *dst, uint8_t *src, int stride) {
void FUNCC(ff_avg_pixels16x16)(uint8_t *dst, uint8_t *src, int stride) {
FUNCC(avg_pixels16)(dst, src, stride, 16);
}
-
-static void FUNCC(clear_block)(DCTELEM *block)
-{
- memset(block, 0, sizeof(dctcoef)*64);
-}
-
-/**
- * memset(blocks, 0, sizeof(DCTELEM)*6*64)
- */
-static void FUNCC(clear_blocks)(DCTELEM *blocks)
-{
- memset(blocks, 0, sizeof(dctcoef)*6*64);
-}
diff --git a/libavcodec/dv.c b/libavcodec/dv.c
index 4fde2a7..76825f5 100644
--- a/libavcodec/dv.c
+++ b/libavcodec/dv.c
@@ -37,7 +37,7 @@
* @file
* DV codec.
*/
-#define ALT_BITSTREAM_READER
+
#include "libavutil/pixdesc.h"
#include "avcodec.h"
#include "dsputil.h"
@@ -349,7 +349,7 @@ static av_cold int dvvideo_init(AVCodecContext *avctx)
static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
{
- if (!ff_dv_codec_profile(avctx)) {
+ if (!avpriv_dv_codec_profile(avctx)) {
av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video\n",
avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt));
return -1;
@@ -364,13 +364,12 @@ typedef struct BlockInfo {
uint8_t pos; /* position in block */
void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
uint8_t partial_bit_count;
- uint16_t partial_bit_buffer;
+ uint32_t partial_bit_buffer;
int shift_offset;
} BlockInfo;
/* bit budget for AC only in 5 MBs */
static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
-/* see dv_88_areas and dv_248_areas for details */
static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
static inline int put_bits_left(PutBitContext* s)
@@ -378,7 +377,7 @@ static inline int put_bits_left(PutBitContext* s)
return (s->buf_end - s->buf) * 8 - put_bits_count(s);
}
-/* decode ac coefficients */
+/* decode AC coefficients */
static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
{
int last_index = gb->size_in_bits;
@@ -391,10 +390,9 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
- /* if we must parse a partial vlc, we do it here */
+ /* if we must parse a partial VLC, we do it here */
if (partial_bit_count > 0) {
- re_cache = ((unsigned)re_cache >> partial_bit_count) |
- (mb->partial_bit_buffer << (sizeof(re_cache) * 8 - partial_bit_count));
+ re_cache = re_cache >> partial_bit_count | mb->partial_bit_buffer;
re_index -= partial_bit_count;
mb->partial_bit_count = 0;
}
@@ -417,7 +415,7 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
if (re_index + vlc_len > last_index) {
/* should be < 16 bits otherwise a codeword could have been parsed */
mb->partial_bit_count = last_index - re_index;
- mb->partial_bit_buffer = NEG_USR32(re_cache, mb->partial_bit_count);
+ mb->partial_bit_buffer = re_cache & ~(-1u >> mb->partial_bit_count);
re_index = last_index;
break;
}
@@ -476,8 +474,8 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
GetBitContext gb;
BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1;
LOCAL_ALIGNED_16(DCTELEM, sblock, [5*DV_MAX_BPM], [64]);
- LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [80 + 4]); /* allow some slack */
- LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [5 * 80 + 4]); /* allow some slack */
+ LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [ 80 + FF_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */
+ LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [5*80 + FF_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */
const int log2_blocksize = 3-s->avctx->lowres;
int is_field_mode[5];
@@ -486,7 +484,7 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
memset(sblock, 0, 5*DV_MAX_BPM*sizeof(*sblock));
- /* pass 1 : read DC and AC coefficients in blocks */
+ /* pass 1: read DC and AC coefficients in blocks */
buf_ptr = &s->buf[work_chunk->buf_offset*80];
block1 = &sblock[0][0];
mb1 = mb_data;
@@ -503,7 +501,7 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
last_index = s->sys->block_sizes[j];
init_get_bits(&gb, buf_ptr, last_index);
- /* get the dc */
+ /* get the DC */
dc = get_sbits(&gb, 9);
dct_mode = get_bits1(&gb);
class1 = get_bits(&gb, 2);
@@ -530,7 +528,7 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
av_dlog(avctx, "MB block: %d, %d ", mb_index, j);
dv_decode_ac(&gb, mb, block);
- /* write the remaining bits in a new buffer only if the
+ /* write the remaining bits in a new buffer only if the
block is finished */
if (mb->pos >= 64)
bit_copy(&pb, &gb);
@@ -539,11 +537,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
mb++;
}
- /* pass 2 : we can do it just after */
+ /* pass 2: we can do it just after */
av_dlog(avctx, "***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index);
block = block1;
mb = mb1;
init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb));
+ put_bits32(&pb, 0); // padding must be zeroed
flush_put_bits(&pb);
for (j = 0; j < s->sys->bpm; j++, block += 64, mb++) {
if (mb->pos < 64 && get_bits_left(&gb) > 0) {
@@ -559,11 +558,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
bit_copy(&vs_pb, &gb);
}
- /* we need a pass other the whole video segment */
+ /* we need a pass over the whole video segment */
av_dlog(avctx, "***pass 3 size=%d\n", put_bits_count(&vs_pb));
block = &sblock[0][0];
mb = mb_data;
init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb));
+ put_bits32(&vs_pb, 0); // padding must be zeroed
flush_put_bits(&vs_pb);
for (mb_index = 0; mb_index < 5; mb_index++) {
for (j = 0; j < s->sys->bpm; j++) {
@@ -640,7 +640,7 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
}
#if CONFIG_SMALL
-/* Converts run and level (where level != 0) pair into vlc, returning bit size */
+/* Converts run and level (where level != 0) pair into VLC, returning bit size */
static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)
{
int size;
@@ -817,7 +817,7 @@ static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, i
if (level + 15 > 30U) {
bi->sign[i] = (level >> 31) & 1;
- /* weigh it and and shift down into range, adding for rounding */
+ /* weight it and and shift down into range, adding for rounding */
/* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT
AND the 2x doubling of the weights */
level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits+3))) >> (dv_weight_bits+4);
@@ -1071,7 +1071,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
const uint8_t* vsc_pack;
int apt, is16_9;
- s->sys = ff_dv_frame_profile(s->sys, buf, buf_size);
+ s->sys = avpriv_dv_frame_profile(s->sys, buf, buf_size);
if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys)) {
av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
return -1; /* NOTE: we only accept several full frames */
@@ -1244,7 +1244,7 @@ static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size,
{
DVVideoContext *s = c->priv_data;
- s->sys = ff_dv_codec_profile(c);
+ s->sys = avpriv_dv_codec_profile(c);
if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys))
return -1;
@@ -1278,12 +1278,12 @@ static int dvvideo_close(AVCodecContext *c)
#if CONFIG_DVVIDEO_ENCODER
AVCodec ff_dvvideo_encoder = {
- "dvvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DVVIDEO,
- sizeof(DVVideoContext),
- dvvideo_init_encoder,
- dvvideo_encode_frame,
+ .name = "dvvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DVVIDEO,
+ .priv_data_size = sizeof(DVVideoContext),
+ .init = dvvideo_init_encoder,
+ .encode = dvvideo_encode_frame,
.capabilities = CODEC_CAP_SLICE_THREADS,
.pix_fmts = (const enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
@@ -1292,16 +1292,14 @@ AVCodec ff_dvvideo_encoder = {
#if CONFIG_DVVIDEO_DECODER
AVCodec ff_dvvideo_decoder = {
- "dvvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DVVIDEO,
- sizeof(DVVideoContext),
- dvvideo_init,
- NULL,
- dvvideo_close,
- dvvideo_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
- NULL,
+ .name = "dvvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DVVIDEO,
+ .priv_data_size = sizeof(DVVideoContext),
+ .init = dvvideo_init,
+ .close = dvvideo_close,
+ .decode = dvvideo_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
.max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
};
diff --git a/libavcodec/dvbsub.c b/libavcodec/dvbsub.c
index 206e50e..4788d50 100644
--- a/libavcodec/dvbsub.c
+++ b/libavcodec/dvbsub.c
@@ -1,5 +1,5 @@
/*
- * DVB subtitle encoding for ffmpeg
+ * DVB subtitle encoding
* Copyright (c) 2005 Fabrice Bellard
*
* This file is part of Libav.
@@ -403,11 +403,10 @@ static int dvbsub_encode(AVCodecContext *avctx,
}
AVCodec ff_dvbsub_encoder = {
- "dvbsub",
- AVMEDIA_TYPE_SUBTITLE,
- CODEC_ID_DVB_SUBTITLE,
- sizeof(DVBSubtitleContext),
- NULL,
- dvbsub_encode,
+ .name = "dvbsub",
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = CODEC_ID_DVB_SUBTITLE,
+ .priv_data_size = sizeof(DVBSubtitleContext),
+ .encode = dvbsub_encode,
.long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
};
diff --git a/libavcodec/dvbsub_parser.c b/libavcodec/dvbsub_parser.c
index 8f3b065..6433528 100644
--- a/libavcodec/dvbsub_parser.c
+++ b/libavcodec/dvbsub_parser.c
@@ -172,9 +172,9 @@ static av_cold void dvbsub_parse_close(AVCodecParserContext *s)
}
AVCodecParser ff_dvbsub_parser = {
- { CODEC_ID_DVB_SUBTITLE },
- sizeof(DVBSubParseContext),
- dvbsub_parse_init,
- dvbsub_parse,
- dvbsub_parse_close,
+ .codec_ids = { CODEC_ID_DVB_SUBTITLE },
+ .priv_data_size = sizeof(DVBSubParseContext),
+ .parser_init = dvbsub_parse_init,
+ .parser_parse = dvbsub_parse,
+ .parser_close = dvbsub_parse_close,
};
diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index 3f39a96..aafc046 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -1,5 +1,5 @@
/*
- * DVB subtitle decoding for ffmpeg
+ * DVB subtitle decoding
* Copyright (c) 2005 Ian Caulfield
*
* This file is part of Libav.
@@ -1464,13 +1464,12 @@ static int dvbsub_decode(AVCodecContext *avctx,
AVCodec ff_dvbsub_decoder = {
- "dvbsub",
- AVMEDIA_TYPE_SUBTITLE,
- CODEC_ID_DVB_SUBTITLE,
- sizeof(DVBSubContext),
- dvbsub_init_decoder,
- NULL,
- dvbsub_close_decoder,
- dvbsub_decode,
+ .name = "dvbsub",
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = CODEC_ID_DVB_SUBTITLE,
+ .priv_data_size = sizeof(DVBSubContext),
+ .init = dvbsub_init_decoder,
+ .close = dvbsub_close_decoder,
+ .decode = dvbsub_decode,
.long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
};
diff --git a/libavcodec/dvdata.c b/libavcodec/dvdata.c
index a80d2da..3a135a9 100644
--- a/libavcodec/dvdata.c
+++ b/libavcodec/dvdata.c
@@ -245,7 +245,7 @@ static const DVprofile dv_profiles[] = {
}
};
-const DVprofile* ff_dv_frame_profile(const DVprofile *sys,
+const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
const uint8_t* frame, unsigned buf_size)
{
int i;
@@ -270,7 +270,7 @@ const DVprofile* ff_dv_frame_profile(const DVprofile *sys,
return NULL;
}
-const DVprofile* ff_dv_codec_profile(AVCodecContext* codec)
+const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec)
{
int i;
diff --git a/libavcodec/dvdata.h b/libavcodec/dvdata.h
index 817b506..b2fb127 100644
--- a/libavcodec/dvdata.h
+++ b/libavcodec/dvdata.h
@@ -274,9 +274,9 @@ enum dv_pack_type {
*/
#define DV_MAX_BPM 8
-const DVprofile* ff_dv_frame_profile(const DVprofile *sys,
- const uint8_t* frame, unsigned buf_size);
-const DVprofile* ff_dv_codec_profile(AVCodecContext* codec);
+const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
+ const uint8_t* frame, unsigned buf_size);
+const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec);
static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num,
uint8_t seq_num, uint8_t dif_num,
diff --git a/libavcodec/dvdsub_parser.c b/libavcodec/dvdsub_parser.c
index 5b07de6..f46d1a4 100644
--- a/libavcodec/dvdsub_parser.c
+++ b/libavcodec/dvdsub_parser.c
@@ -1,5 +1,5 @@
/*
- * DVD subtitle decoding for ffmpeg
+ * DVD subtitle decoding
* Copyright (c) 2005 Fabrice Bellard
*
* This file is part of Libav.
@@ -77,9 +77,9 @@ static av_cold void dvdsub_parse_close(AVCodecParserContext *s)
}
AVCodecParser ff_dvdsub_parser = {
- { CODEC_ID_DVD_SUBTITLE },
- sizeof(DVDSubParseContext),
- dvdsub_parse_init,
- dvdsub_parse,
- dvdsub_parse_close,
+ .codec_ids = { CODEC_ID_DVD_SUBTITLE },
+ .priv_data_size = sizeof(DVDSubParseContext),
+ .parser_init = dvdsub_parse_init,
+ .parser_parse = dvdsub_parse,
+ .parser_close = dvdsub_parse_close,
};
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index 8f3ba63..ee9331c 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -1,5 +1,5 @@
/*
- * DVD subtitle decoding for ffmpeg
+ * DVD subtitle decoding
* Copyright (c) 2005 Fabrice Bellard
*
* This file is part of Libav.
@@ -487,13 +487,9 @@ static int dvdsub_decode(AVCodecContext *avctx,
}
AVCodec ff_dvdsub_decoder = {
- "dvdsub",
- AVMEDIA_TYPE_SUBTITLE,
- CODEC_ID_DVD_SUBTITLE,
- 0,
- NULL,
- NULL,
- NULL,
- dvdsub_decode,
+ .name = "dvdsub",
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = CODEC_ID_DVD_SUBTITLE,
+ .decode = dvdsub_decode,
.long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
};
diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c
index 71c5e79..82d0608 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -1,5 +1,5 @@
/*
- * DVD subtitle encoding for ffmpeg
+ * DVD subtitle encoding
* Copyright (c) 2005 Wolfram Gloger
*
* This file is part of Libav.
@@ -216,11 +216,9 @@ static int dvdsub_encode(AVCodecContext *avctx,
}
AVCodec ff_dvdsub_encoder = {
- "dvdsub",
- AVMEDIA_TYPE_SUBTITLE,
- CODEC_ID_DVD_SUBTITLE,
- 0,
- NULL,
- dvdsub_encode,
+ .name = "dvdsub",
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = CODEC_ID_DVD_SUBTITLE,
+ .encode = dvdsub_encode,
.long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
};
diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c
index 75f3212..97b912a 100644
--- a/libavcodec/dxa.c
+++ b/libavcodec/dxa.c
@@ -318,15 +318,14 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_dxa_decoder = {
- "dxa",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DXA,
- sizeof(DxaDecContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "dxa",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DXA,
+ .priv_data_size = sizeof(DxaDecContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"),
};
diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c
new file mode 100644
index 0000000..5f67fbd
--- /dev/null
+++ b/libavcodec/dxtory.c
@@ -0,0 +1,109 @@
+/*
+ * Dxtory decoder
+ *
+ * Copyright (c) 2011 Konstantin Shishkov
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+#include "libavutil/intreadwrite.h"
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ avctx->pix_fmt = PIX_FMT_YUV420P;
+ avctx->coded_frame = avcodec_alloc_frame();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ int h, w;
+ AVFrame *pic = avctx->coded_frame;
+ const uint8_t *src = avpkt->data;
+ uint8_t *Y1, *Y2, *U, *V;
+ int ret;
+
+ if (pic->data[0])
+ avctx->release_buffer(avctx, pic);
+
+ if (avpkt->size < avctx->width * avctx->height * 3 / 2 + 16) {
+ av_log(avctx, AV_LOG_ERROR, "packet too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ pic->reference = 0;
+ if ((ret = avctx->get_buffer(avctx, pic)) < 0)
+ return ret;
+
+ pic->pict_type = AV_PICTURE_TYPE_I;
+ pic->key_frame = 1;
+
+ if (AV_RL32(src) != 0x01000002) {
+ av_log_ask_for_sample(avctx, "Unknown frame header %X\n", AV_RL32(src));
+ return AVERROR_PATCHWELCOME;
+ }
+ src += 16;
+
+ Y1 = pic->data[0];
+ Y2 = pic->data[0] + pic->linesize[0];
+ U = pic->data[1];
+ V = pic->data[2];
+ for (h = 0; h < avctx->height; h += 2) {
+ for (w = 0; w < avctx->width; w += 2) {
+ AV_WN16A(Y1 + w, AV_RN16A(src));
+ AV_WN16A(Y2 + w, AV_RN16A(src + 2));
+ U[w >> 1] = src[4] + 0x80;
+ V[w >> 1] = src[5] + 0x80;
+ src += 6;
+ }
+ Y1 += pic->linesize[0] << 1;
+ Y2 += pic->linesize[0] << 1;
+ U += pic->linesize[1];
+ V += pic->linesize[2];
+ }
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame*)data = *pic;
+
+ return avpkt->size;
+}
+
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+ AVFrame *pic = avctx->coded_frame;
+ if (pic->data[0])
+ avctx->release_buffer(avctx, pic);
+ av_freep(&avctx->coded_frame);
+
+ return 0;
+}
+
+AVCodec ff_dxtory_decoder = {
+ .name = "dxtory",
+ .long_name = NULL_IF_CONFIG_SMALL("Dxtory"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DXTORY,
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+};
diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
index 25b021a..e56a645 100644
--- a/libavcodec/dxva2.c
+++ b/libavcodec/dxva2.c
@@ -24,7 +24,7 @@
void *ff_dxva2_get_surface(const Picture *picture)
{
- return picture->data[3];
+ return picture->f.data[3];
}
unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
diff --git a/libavcodec/dxva2.h b/libavcodec/dxva2.h
index 5db5d0b..374ae03 100644
--- a/libavcodec/dxva2.h
+++ b/libavcodec/dxva2.h
@@ -25,8 +25,11 @@
#include <stdint.h>
+#include <d3d9.h>
#include <dxva2api.h>
+#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards
+
/**
* This structure is used to provides the necessary configurations and data
* to the DXVA2 Libav HWAccel implementation.
diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
index 8de4c51..9608ecb 100644
--- a/libavcodec/dxva2_h264.c
+++ b/libavcodec/dxva2_h264.c
@@ -70,15 +70,15 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
ff_dxva2_get_surface_index(ctx, r),
r->long_ref != 0);
- if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)
+ if ((r->f.reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)
pp->FieldOrderCntList[i][0] = r->field_poc[0];
- if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX)
+ if ((r->f.reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX)
pp->FieldOrderCntList[i][1] = r->field_poc[1];
pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num;
- if (r->reference & PICT_TOP_FIELD)
+ if (r->f.reference & PICT_TOP_FIELD)
pp->UsedForReferenceFlags |= 1 << (2*i + 0);
- if (r->reference & PICT_BOTTOM_FIELD)
+ if (r->f.reference & PICT_BOTTOM_FIELD)
pp->UsedForReferenceFlags |= 1 << (2*i + 1);
} else {
pp->RefFrameList[i].bPicEntry = 0xff;
@@ -113,7 +113,10 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
pp->bit_depth_luma_minus8 = h->sps.bit_depth_luma - 8;
pp->bit_depth_chroma_minus8 = h->sps.bit_depth_chroma - 8;
- pp->Reserved16Bits = 3; /* FIXME is there a way to detect the right mode ? */
+ if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG)
+ pp->Reserved16Bits = 0;
+ else
+ pp->Reserved16Bits = 3; /* FIXME is there a way to detect the right mode ? */
pp->StatusReportFeedbackNumber = 1 + ctx->report_id++;
pp->CurrFieldOrderCnt[0] = 0;
if ((s->picture_structure & PICT_TOP_FIELD) &&
@@ -150,17 +153,29 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
//pp->SliceGroupMap[810]; /* XXX not implemented by Libav */
}
-static void fill_scaling_lists(const H264Context *h, DXVA_Qmatrix_H264 *qm)
+static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm)
{
unsigned i, j;
memset(qm, 0, sizeof(*qm));
- for (i = 0; i < 6; i++)
- for (j = 0; j < 16; j++)
- qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][zigzag_scan[j]];
+ if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) {
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 16; j++)
+ qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j];
+
+ for (i = 0; i < 64; i++) {
+ qm->bScalingLists8x8[0][i] = h->pps.scaling_matrix8[0][i];
+ qm->bScalingLists8x8[1][i] = h->pps.scaling_matrix8[3][i];
+ }
+ } else {
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 16; j++)
+ qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][zigzag_scan[j]];
- for (i = 0; i < 2; i++)
- for (j = 0; j < 64; j++)
- qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][ff_zigzag_direct[j]];
+ for (i = 0; i < 64; i++) {
+ qm->bScalingLists8x8[0][i] = h->pps.scaling_matrix8[0][ff_zigzag_direct[i]];
+ qm->bScalingLists8x8[1][i] = h->pps.scaling_matrix8[3][ff_zigzag_direct[i]];
+ }
+ }
}
static int is_slice_short(struct dxva_context *ctx)
@@ -216,7 +231,7 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
unsigned plane;
fill_picture_entry(&slice->RefPicList[list][i],
ff_dxva2_get_surface_index(ctx, r),
- r->reference == PICT_BOTTOM_FIELD);
+ r->f.reference == PICT_BOTTOM_FIELD);
for (plane = 0; plane < 3; plane++) {
int w, o;
if (plane == 0 && h->luma_weight_flag[list]) {
@@ -265,7 +280,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
const unsigned mb_count = s->mb_width * s->mb_height;
struct dxva_context *ctx = avctx->hwaccel_context;
const Picture *current_picture = h->s.current_picture_ptr;
- struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
+ struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
DXVA_Slice_H264_Short *slice = NULL;
uint8_t *dxva_data, *current, *end;
unsigned dxva_size;
@@ -360,7 +375,7 @@ static int start_frame(AVCodecContext *avctx,
{
const H264Context *h = avctx->priv_data;
struct dxva_context *ctx = avctx->hwaccel_context;
- struct dxva2_picture_context *ctx_pic = h->s.current_picture_ptr->hwaccel_picture_private;
+ struct dxva2_picture_context *ctx_pic = h->s.current_picture_ptr->f.hwaccel_picture_private;
if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
return -1;
@@ -370,7 +385,7 @@ static int start_frame(AVCodecContext *avctx,
fill_picture_parameters(ctx, h, &ctx_pic->pp);
/* Fill up DXVA_Qmatrix_H264 */
- fill_scaling_lists(h, &ctx_pic->qm);
+ fill_scaling_lists(ctx, h, &ctx_pic->qm);
ctx_pic->slice_count = 0;
ctx_pic->bitstream_size = 0;
@@ -384,7 +399,7 @@ static int decode_slice(AVCodecContext *avctx,
const H264Context *h = avctx->priv_data;
struct dxva_context *ctx = avctx->hwaccel_context;
const Picture *current_picture = h->s.current_picture_ptr;
- struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
+ struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
unsigned position;
if (ctx_pic->slice_count >= MAX_SLICES)
@@ -413,7 +428,7 @@ static int end_frame(AVCodecContext *avctx)
H264Context *h = avctx->priv_data;
MpegEncContext *s = &h->s;
struct dxva2_picture_context *ctx_pic =
- h->s.current_picture_ptr->hwaccel_picture_private;
+ h->s.current_picture_ptr->f.hwaccel_picture_private;
if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
return -1;
@@ -428,7 +443,6 @@ AVHWAccel ff_h264_dxva2_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_H264,
.pix_fmt = PIX_FMT_DXVA2_VLD,
- .capabilities = 0,
.start_frame = start_frame,
.decode_slice = decode_slice,
.end_frame = end_frame,
diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c
index f14aabd..2e77cd1 100644
--- a/libavcodec/dxva2_mpeg2.c
+++ b/libavcodec/dxva2_mpeg2.c
@@ -151,7 +151,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
const struct MpegEncContext *s = avctx->priv_data;
struct dxva_context *ctx = avctx->hwaccel_context;
struct dxva2_picture_context *ctx_pic =
- s->current_picture_ptr->hwaccel_picture_private;
+ s->current_picture_ptr->f.hwaccel_picture_private;
const int is_field = s->picture_structure != PICT_FRAME;
const unsigned mb_count = s->mb_width * (s->mb_height >> is_field);
uint8_t *dxva_data, *current, *end;
@@ -210,7 +210,7 @@ static int start_frame(AVCodecContext *avctx,
const struct MpegEncContext *s = avctx->priv_data;
struct dxva_context *ctx = avctx->hwaccel_context;
struct dxva2_picture_context *ctx_pic =
- s->current_picture_ptr->hwaccel_picture_private;
+ s->current_picture_ptr->f.hwaccel_picture_private;
if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
return -1;
@@ -230,7 +230,7 @@ static int decode_slice(AVCodecContext *avctx,
{
const struct MpegEncContext *s = avctx->priv_data;
struct dxva2_picture_context *ctx_pic =
- s->current_picture_ptr->hwaccel_picture_private;
+ s->current_picture_ptr->f.hwaccel_picture_private;
unsigned position;
if (ctx_pic->slice_count >= MAX_SLICES)
@@ -250,7 +250,7 @@ static int end_frame(AVCodecContext *avctx)
{
struct MpegEncContext *s = avctx->priv_data;
struct dxva2_picture_context *ctx_pic =
- s->current_picture_ptr->hwaccel_picture_private;
+ s->current_picture_ptr->f.hwaccel_picture_private;
if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
return -1;
@@ -265,7 +265,6 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_MPEG2VIDEO,
.pix_fmt = PIX_FMT_DXVA2_VLD,
- .capabilities = 0,
.start_frame = start_frame,
.decode_slice = decode_slice,
.end_frame = end_frame,
diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c
index 112d7df..22ad459 100644
--- a/libavcodec/dxva2_vc1.c
+++ b/libavcodec/dxva2_vc1.c
@@ -68,7 +68,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
pp->bPicStructure |= 0x01;
if (s->picture_structure & PICT_BOTTOM_FIELD)
pp->bPicStructure |= 0x02;
- pp->bSecondField = v->interlace && v->fcm != 0x03 && !s->first_field;
+ pp->bSecondField = v->interlace && v->fcm != ILACE_FIELD && !s->first_field;
pp->bPicIntra = s->pict_type == AV_PICTURE_TYPE_I;
pp->bPicBackwardPrediction = s->pict_type == AV_PICTURE_TYPE_B;
pp->bBidirectionalAveragingMode = (1 << 7) |
@@ -100,7 +100,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
(s->resync_marker << 4) |
(v->rangered << 3) |
(s->max_b_frames );
- pp->bPicExtrapolation = (!v->interlace || v->fcm == 0x00) ? 1 : 2;
+ pp->bPicExtrapolation = (!v->interlace || v->fcm == PROGRESSIVE) ? 1 : 2;
pp->bPicDeblocked = ((v->profile != PROFILE_ADVANCED && v->rangeredfrm) << 5) |
(s->loop_filter << 1);
pp->bPicDeblockConfined = (v->postprocflag << 7) |
@@ -161,7 +161,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
const VC1Context *v = avctx->priv_data;
struct dxva_context *ctx = avctx->hwaccel_context;
const MpegEncContext *s = &v->s;
- struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->hwaccel_picture_private;
+ struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->f.hwaccel_picture_private;
DXVA_SliceInfo *slice = &ctx_pic->si;
@@ -213,7 +213,7 @@ static int start_frame(AVCodecContext *avctx,
{
const VC1Context *v = avctx->priv_data;
struct dxva_context *ctx = avctx->hwaccel_context;
- struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private;
+ struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->f.hwaccel_picture_private;
if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
return -1;
@@ -231,7 +231,7 @@ static int decode_slice(AVCodecContext *avctx,
{
const VC1Context *v = avctx->priv_data;
const Picture *current_picture = v->s.current_picture_ptr;
- struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
+ struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
if (ctx_pic->bitstream_size > 0)
return -1;
@@ -252,7 +252,7 @@ static int decode_slice(AVCodecContext *avctx,
static int end_frame(AVCodecContext *avctx)
{
VC1Context *v = avctx->priv_data;
- struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private;
+ struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->f.hwaccel_picture_private;
if (ctx_pic->bitstream_size <= 0)
return -1;
@@ -269,7 +269,6 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_WMV3,
.pix_fmt = PIX_FMT_DXVA2_VLD,
- .capabilities = 0,
.start_frame = start_frame,
.decode_slice = decode_slice,
.end_frame = end_frame,
@@ -282,7 +281,6 @@ AVHWAccel ff_vc1_dxva2_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_VC1,
.pix_fmt = PIX_FMT_DXVA2_VLD,
- .capabilities = 0,
.start_frame = start_frame,
.decode_slice = decode_slice,
.end_frame = end_frame,
diff --git a/libavcodec/eac3_data.c b/libavcodec/eac3_data.c
new file mode 100644
index 0000000..b0416f3
--- /dev/null
+++ b/libavcodec/eac3_data.c
@@ -0,0 +1,1134 @@
+/*
+ * E-AC-3 tables
+ * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Tables taken directly from the E-AC-3 spec.
+ */
+
+#include "eac3_data.h"
+#include "ac3.h"
+
+const uint8_t ff_eac3_bits_vs_hebap[20] = {
+ 0, 2, 3, 4, 5, 7, 8, 9, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 14, 16,
+};
+
+/**
+ * Table E3.6, Gk=1
+ * No gain (Gk=1) inverse quantization, remapping scale factors
+ * ff_eac3_gaq_remap[hebap+8]
+ */
+const int16_t ff_eac3_gaq_remap_1[12] = {
+ 4681, 2185, 1057, 520, 258, 129, 64, 32, 16, 8, 2, 0
+};
+
+/**
+ * Table E3.6, Gk=2 & Gk=4, A
+ * Large mantissa inverse quantization, remapping scale factors
+ * ff_eac3_gaq_remap_2_4_a[hebap-8][Gk=2,4]
+ */
+const int16_t ff_eac3_gaq_remap_2_4_a[9][2] = {
+ { -10923, -4681 },
+ { -14043, -6554 },
+ { -15292, -7399 },
+ { -15855, -7802 },
+ { -16124, -7998 },
+ { -16255, -8096 },
+ { -16320, -8144 },
+ { -16352, -8168 },
+ { -16368, -8180 }
+};
+
+/**
+ * Table E3.6, Gk=2 & Gk=4, B
+ * Large mantissa inverse quantization, negative mantissa remapping offsets
+ * ff_eac3_gaq_remap_3_4_b[hebap-8][Gk=2,4]
+ */
+const int16_t ff_eac3_gaq_remap_2_4_b[9][2] = {
+ { -5461, -1170 },
+ { -11703, -4915 },
+ { -14199, -6606 },
+ { -15327, -7412 },
+ { -15864, -7805 },
+ { -16126, -7999 },
+ { -16255, -8096 },
+ { -16320, -8144 },
+ { -16352, -8168 }
+};
+
+static const int16_t vq_hebap1[4][6] = {
+{ 7167, 4739, 1106, 4269, 10412, 4820},
+{ -5702, -3187, -14483, -1392, -2027, 849},
+{ 633, 6199, 7009, -12779, -2306, -2636},
+{ -1468, -7031, 7592, 10617, -5946, -3062},
+};
+static const int16_t vq_hebap2[8][6] = {
+{ -12073, 608, -7019, 590, 4000, 869},
+{ 6692, 15689, -6178, -9239, -74, 133},
+{ 1855, -989, 20596, -2920, -4475, 225},
+{ -1194, -3901, -821, -6566, -875, -20298},
+{ -2762, -3181, -4094, -5623, -16945, 9765},
+{ 1547, 6839, 1980, 20233, -1071, -4986},
+{ 6221, -17915, -5516, 6266, 358, 1162},
+{ 3753, -1066, 4283, -3227, 15928, 10186},
+};
+static const int16_t vq_hebap3[16][6] = {
+{ -10028, 20779, 10982, -4560, 798, -68},
+{ 11050, 20490, -6617, -5342, -1797, -1631},
+{ 3977, -542, 7118, -1166, 18844, 14678},
+{ -4320, -96, -7295, -492, -22050, -4277},
+{ 2692, 5856, 5530, 21862, -7212, -5325},
+{ -135, -23391, 962, 8115, -644, 382},
+{ -1563, 3400, -3299, 4693, -6892, 22398},
+{ 3535, 3030, 7296, 6214, 20476, -12099},
+{ 57, -6823, 1848, -22349, -5919, 6823},
+{ -821, -3655, -387, -6253, -1735, -22373},
+{ -6046, 1586, -18890, -14392, 9214, 705},
+{ -5716, 264, -17964, 14618, 7921, -337},
+{ -110, 108, 8, 74, -89, -50},
+{ 6612, -1517, 21687, -1658, -7949, -246},
+{ 21667, -6335, -8290, -101, -1349, -22},
+{ -22003, -6476, 7974, 648, 2054, -331},
+};
+static const int16_t vq_hebap4[32][6] = {
+{ 6636, -4593, 14173, -17297, -16523, 864},
+{ 3658, 22540, 104, -1763, -84, 6},
+{ 21580, -17815, -7282, -1575, -2078, -320},
+{ -2233, 10017, -2728, 14938, -13640, -17659},
+{ -1564, -17738, -19161, 13735, 2757, 2951},
+{ 4520, 5510, 7393, 10799, 19231, -13770},
+{ 399, 2976, -1099, 5013, -1159, 22095},
+{ 3624, -2359, 4680, -2238, 22702, 3765},
+{ -4201, -8285, -6810, -12390, -18414, 15382},
+{ -5198, -6869, -10047, -8364, -16022, -20562},
+{ -142, -22671, -368, 4391, -464, -13},
+{ 814, -1118, -1089, -22019, 74, 1553},
+{ -1618, 19222, -17642, -13490, 842, -2309},
+{ 4689, 16490, 20813, -15387, -4164, -3968},
+{ -3308, 11214, -13542, 13599, -19473, 13770},
+{ 1817, 854, 21225, -966, -1643, -268},
+{ -2587, -107, -20154, 376, 1174, -304},
+{ -2919, 453, -5390, 750, -22034, -978},
+{ -19012, 16839, 10000, -3580, 2211, 1459},
+{ 1363, -2658, -33, -4067, 1165, -21985},
+{ -8592, -2760, -17520, -15985, 14897, 1323},
+{ 652, -9331, 3253, -14622, 12181, 19692},
+{ -6361, 5773, -15395, 17291, 16590, -2922},
+{ -661, -601, 1609, 22610, 992, -1045},
+{ 4961, 9107, 11225, 7829, 16320, 18627},
+{ -21872, -1433, 138, 1470, -1891, -196},
+{ -19499, -18203, 11056, -516, 2543, -2249},
+{ -1196, -17574, 20150, 11462, -401, 2619},
+{ 4638, -8154, 11891, -15759, 17615, -14955},
+{ -83, 278, 323, 55, -154, 232},
+{ 7788, 1462, 18395, 15296, -15763, -1131},
+};
+static const int16_t vq_hebap5[128][6] = {
+{ -3394, -19730, 2963, 9590, 4660, 19673},
+{ -15665, -6405, 17671, 3860, -8232, -19429},
+{ 4467, 412, -17873, -8037, 691, -17307},
+{ 3580, 2363, 6886, 3763, 6379, -20522},
+{ -17230, -14133, -1396, -23939, 8373, -12537},
+{ -8073, -21469, -15638, 3214, 8105, -5965},
+{ 4343, 5169, 2683, -16822, -5146, -16558},
+{ 6348, -10668, 12995, -25500, -22090, 4091},
+{ -2880, -8366, -5968, -17158, -2638, 23132},
+{ -5095, -14281, -22371, 21741, 3689, 2961},
+{ -2443, -17739, 25155, 2707, 1594, 7},
+{ -18379, 9010, 4270, 731, -426, -640},
+{ -23695, 24732, 5642, 612, -308, -964},
+{ -767, 1268, 225, 1635, 173, 916},
+{ 5455, 6493, 4902, 10560, 23041, -17140},
+{ 17219, -21054, -18716, 4936, -3420, 3357},
+{ -1390, 15488, -21946, -14611, 1339, 542},
+{ -6866, -2254, -12070, -3075, -19981, -20622},
+{ -1803, 11775, 1343, 8917, 693, 24497},
+{ -21610, 9462, 4681, 9254, -7815, 15904},
+{ -5559, -3018, -9169, -1347, -22547, 12868},
+{ -366, 5076, -1727, 20427, -283, -2923},
+{ -1886, -6313, -939, -2081, -1399, 3513},
+{ -3161, -537, -5075, 11268, 19396, 989},
+{ 2345, 4153, 5769, -4273, 233, -399},
+{ -21894, -1138, -16474, 5902, 5488, -3211},
+{ 10007, -12530, 18829, 20932, -1158, 1790},
+{ -1165, 5014, -1199, 6415, -8418, -21038},
+{ 1892, -3534, 3815, -5846, 16427, 20288},
+{ -2664, -11627, -4147, -18311, -22710, 14848},
+{ 17256, 10419, 7764, 12040, 18956, 2525},
+{ -21419, -18685, -10897, 4368, -7051, 4539},
+{ -1574, 2050, 5760, 24756, 15983, 17678},
+{ -538, -22867, 11067, 10301, 385, 528},
+{ -8465, -3025, -16357, -23237, 16491, 3654},
+{ 5840, 575, 11890, 1947, 25157, 6653},
+{ 6625, -3516, -1964, 3850, -390, -116},
+{ 18005, 20900, 14323, -7621, -10922, 11802},
+{ -4857, -2932, -13334, -7815, 21622, 2267},
+{ -579, -9431, -748, -21321, 12367, 8265},
+{ -8317, 1375, -17847, 2921, 9062, 22046},
+{ 18398, 8635, -1503, -2418, -18295, -14734},
+{ -2987, 15129, -3331, 22300, 13878, -13639},
+{ 5874, -19026, 15587, 11350, -20738, 1971},
+{ 1581, -6955, -21440, 2455, 65, 414},
+{ 515, -4468, -665, -4672, 125, -19222},
+{ 21495, -20301, -1872, -1926, -211, -1022},
+{ 5189, -12250, -1775, -23550, -4546, 5813},
+{ 321, -6331, 14646, 6975, -1773, 867},
+{ -13814, 3180, 7927, 444, 19552, 3146},
+{ -6660, 12252, -1972, 17408, -24280, -12956},
+{ -745, 14356, -1107, 23742, -9631, -18344},
+{ 18284, -7909, -7531, 19118, 7721, -12659},
+{ 1926, 15101, -12848, 2153, 21631, 1864},
+{ -2130, 23416, 17056, -15597, -1544, 87},
+{ 8314, -11824, 14581, -20591, 7891, -2099},
+{ 19600, 22814, -17304, -2040, 285, -3863},
+{ -8214, -18322, 10724, -13744, -13469, -1666},
+{ 14351, 4880, -20034, 964, -4221, -180},
+{ -24598, -16635, 19724, 5925, 4777, 4414},
+{ -2495, 23493, -16141, 2918, -1038, -2010},
+{ 18974, -2540, 13343, 1405, -6194, -1136},
+{ 2489, 13670, 22638, -7311, -129, -2792},
+{ -13962, 16775, 23012, 728, 3397, 162},
+{ 3038, 993, 8774, -21969, -6609, 910},
+{ -12444, -22386, -2626, -5295, 19520, 9872},
+{ -1911, -18274, -18506, -14962, 4760, 7119},
+{ 8298, -2978, 25886, 7660, -7897, 1020},
+{ 6132, 15127, 18757, -24370, -6529, -6627},
+{ 7924, 12125, -9459, -23962, 5502, 937},
+{ -17056, -5373, 2522, 327, 1129, -390},
+{ 15774, 19955, -10380, 11172, -3107, 14853},
+{ -11904, -8091, -17928, -22287, -17237, -6803},
+{ -12862, -2172, -6509, 5927, 12458, -22355},
+{ -497, 322, 1038, -6643, -5404, 20311},
+{ 1083, -22984, -8494, 12130, -762, 2623},
+{ 5067, 19712, -1901, -30, -325, 85},
+{ 987, -5830, 4212, -9030, 9121, -25038},
+{ -7868, 7284, -12292, 12914, -21592, 20941},
+{ -1630, -7694, -2187, -8525, -5604, -25196},
+{ -6668, 388, -22535, 1526, 9082, 193},
+{ -7867, -22308, 5163, 362, 944, -259},
+{ 3824, -11850, 7591, -23176, 25342, 23771},
+{ -10504, 4123, -21111, 21173, 22439, -838},
+{ -4723, 21795, 6184, -122, 1642, -717},
+{ 24504, 19887, -2043, 986, 7, -55},
+{ -27313, -135, 2437, 259, 89, 307},
+{ 24446, -3873, -5391, -820, -2387, 361},
+{ 5529, 5784, 18682, 242, -21896, -4003},
+{ 22304, 4483, 722, -12242, 7570, 15448},
+{ 8673, 3009, 20437, 21108, -21100, -3080},
+{ -1132, 2705, -1825, 5420, -785, 18532},
+{ 16932, -13517, -16509, -14858, -20327, -14221},
+{ 2219, 1380, 21474, -1128, 327, 83},
+{ -2177, 21517, -3856, -14180, -204, -2191},
+{ 953, -9426, 15874, -10710, -3231, 21030},
+{ -421, -1377, 640, -8239, -20976, 2174},
+{ 4309, 18514, -9100, -18319, -15518, 3704},
+{ -5943, 449, -8387, 1075, -22210, -4992},
+{ 2953, 12788, 18285, 1430, 14937, 21731},
+{ -2913, 401, -4739, -20105, 1699, -1147},
+{ 3449, 5241, 8853, 22134, -7547, 1451},
+{ -2154, 8584, 18120, -15614, 19319, -5991},
+{ 3501, 2841, 5897, 6397, 8630, 23018},
+{ 2467, 2956, 379, 5703, -22047, -2189},
+{ -16963, -594, 18822, -5295, 1640, 774},
+{ 2896, -1424, 3586, -2292, 19910, -1822},
+{ -18575, 21219, -14001, -12573, 16466, 635},
+{ -1998, -19314, -16527, 12208, -16576, -7854},
+{ -9674, 1012, -21645, 2883, -12712, 2321},
+{ -1005, 471, -3629, 8045, -11087, 25533},
+{ 4141, -21472, -2673, 756, -663, -523},
+{ 6490, 8531, 19289, 18949, 6092, -9347},
+{ 16965, 24599, 14024, 10072, -536, -10438},
+{ -8147, 2145, -23028, -17073, 5451, -4401},
+{ -14873, 20520, -18303, -9717, -11885, -17831},
+{ -2290, -14120, 2070, 22467, 1671, 725},
+{ -8538, 14629, 3521, -20577, 6673, 8200},
+{ 20248, 4410, -1366, -585, 1229, -2449},
+{ 7467, -7148, 13667, -8246, 22392, -17320},
+{ -1932, 3875, -9064, -3812, 958, 265},
+{ -4399, 2959, -15911, 19598, 4954, -1105},
+{ 18009, -9923, -18137, -3862, 11178, 5821},
+{ -14596, -1227, 9660, 21619, 11228, -11721},
+{ -721, -1700, 109, -2142, 61, -6772},
+{ -24619, -22520, 5608, -1957, -1761, -1012},
+{ -23728, -4451, -2688, -14679, -4266, 9919},
+{ 8495, -894, 20438, -13820, -17267, 139},
+};
+static const int16_t vq_hebap6[256][6] = {
+{ 10154, 7365, 16861, 18681, -22893, -3636},
+{ -2619, -3788, -5529, -5192, -9009, -20298},
+{ -5583, -22800, 21297, 7012, 745, 720},
+{ 428, -1459, 109, -3082, 361, -8403},
+{ 8161, 22401, 241, 1755, -874, -2824},
+{ 1140, 12643, 2306, 22263, -25146, -17557},
+{ -2609, 3379, 10337, -19730, -15468, -23944},
+{ -4040, -12796, -25772, 13096, 3905, 1315},
+{ 4624, -23799, 13608, 25317, -1175, 2173},
+{ -97, 13747, -5122, 23255, 4214, -22145},
+{ 6878, -322, 18264, -854, -11916, -733},
+{ 17280, -12669, -9693, 23563, -16240, -1309},
+{ 5802, -4968, 19526, -21194, -24622, -183},
+{ 5851, -16137, 15229, -9496, -1538, 377},
+{ 14096, 25057, 13419, 8290, 23320, 16818},
+{ -7261, 118, -15867, 19097, 9781, -277},
+{ -4288, 21589, -13288, -16259, 16633, -4862},
+{ 4909, -19217, 23411, 14705, -722, 125},
+{ 19462, -4732, -1928, -11527, 20770, 5425},
+{ -27562, -2881, -4331, 384, -2103, 1367},
+{ -266, -9175, 5441, 26333, -1924, 4221},
+{ -2970, -20170, -21816, 5450, -7426, 5344},
+{ -221, -6696, 603, -9140, 1308, -27506},
+{ 9621, -8380, -1967, 9403, -1651, 22817},
+{ 7566, -5250, -4165, 1385, -990, 560},
+{ -1262, 24738, -19057, 10741, 7585, -7098},
+{ 451, 20130, -9949, -6015, -2188, -1458},
+{ 22249, 9380, 9096, 10959, -2365, -3724},
+{ 18668, -650, -1234, 11092, 7678, 5969},
+{ 19207, -1485, -1076, -731, -684, 43},
+{ -4973, 13430, 20139, 60, 476, -935},
+{ -20029, 8710, 2499, 1016, -1158, 335},
+{ -26413, 18598, -2201, -669, 3409, 793},
+{ -4726, 8875, -24607, -9646, 3643, -283},
+{ 13303, -21404, -3691, -1184, -1970, 1612},
+{ 173, 60, 919, 1229, 6942, -665},
+{ 16377, 16991, 5341, -14015, -2304, -20390},
+{ 25334, -10609, 11947, -7653, -6363, 14058},
+{ 23929, -13259, -7226, -937, 234, -187},
+{ 6311, -1877, 12506, -1879, 18751, -23341},
+{ 621, 6445, 3354, -24274, 8406, 5315},
+{ -3297, -5034, -4704, -5080, -25730, 5347},
+{ -1275, -13295, -965, -23318, 1214, 26259},
+{ -6252, 10035, -20105, 15301, -16073, 5136},
+{ 9562, -3911, -19510, 4745, 22270, -4171},
+{ 7978, -19600, 14024, -5745, -20855, 8939},
+{ 7, -4039, 991, -6065, 52, -19423},
+{ 3485, 2969, 7732, 7786, 25312, 6206},
+{ -959, -12812, -1840, -22743, 7324, 10830},
+{ -4686, 1678, -10172, -5205, 4294, -1271},
+{ 3889, 1302, 7450, 638, 20374, -3133},
+{ -12496, -9123, 18463, -12343, -7238, 18552},
+{ -6185, 8649, -6903, -895, 17109, 16604},
+{ -9896, 28579, 2845, 1640, 2925, -298},
+{ 14968, -25988, 14878, -24012, 1815, -6474},
+{ 26107, 5166, 21225, 15873, 21617, 14825},
+{ -21684, 16438, 20504, -14346, -7114, -4162},
+{ 28647, 90, -1572, 789, -902, -75},
+{ -1479, 2471, -4061, 3612, -2240, 10914},
+{ 8616, 17491, 17255, -17456, 17022, -16357},
+{ -20722, -18597, 25274, 17720, -3573, 1695},
+{ -997, 6129, -6303, 11250, -11359, -19739},
+{ -74, -4001, -1584, 13384, 162, -144},
+{ -529, 21068, 7923, -11396, 422, -26},
+{ 7102, -13531, -20055, 2629, -178, -429},
+{ 9201, 1368, -22238, 2623, -20499, 24889},
+{ -432, 6675, -266, 8723, 80, 28024},
+{ 19493, -3108, -9261, 1910, -21777, 5345},
+{ 14079, -11489, 12604, 6079, 19877, 1315},
+{ 10947, 9837, -18612, 15742, 4792, 605},
+{ -1777, 3758, -4087, 21696, 6024, -576},
+{ 3567, -3578, 16379, 2680, -1752, 716},
+{ -5049, -1399, -4550, -652, -17721, -3366},
+{ -3635, -4372, -6522, -22152, 7382, 1458},
+{ 12242, 19190, 5646, -7815, -20289, 21344},
+{ -7508, 19952, 23542, -9753, 5669, -1990},
+{ -2275, 15438, 10907, -17879, 6497, 13582},
+{ -15894, -15646, -4716, 6019, 24250, -6179},
+{ -2049, -6856, -1208, 918, 17735, -69},
+{ -3721, 9099, -16065, -23621, 5981, -2344},
+{ 7862, -8918, 24033, 25508, -11033, -741},
+{ -12588, 19468, 14649, 15451, -21226, 1171},
+{ 2102, 1147, 2789, 4096, 2179, 8750},
+{ -18214, -17758, -10366, -5203, -1066, -3541},
+{ -2819, -19958, -11921, 6032, 8315, 10374},
+{ -9078, -2100, 19431, -17, 732, -689},
+{ -14512, -19224, -7095, 18727, 1870, 22906},
+{ 3912, 659, 25597, -4006, 9619, 877},
+{ 2616, 22695, -5770, 17920, 3812, 20220},
+{ 2561, 26847, -5245, -10908, 2256, -517},
+{ -4974, 198, -21983, -3608, 22174, -18924},
+{ 21308, -1211, 19144, 16691, -1588, 11390},
+{ -1790, 3959, -3488, 7003, -7107, 20877},
+{ -6108, -17955, -18722, 24763, 16508, 3211},
+{ 20462, -24987, -20361, 4484, -5111, -478},
+{ -6378, -1998, -10229, -561, -22039, -22339},
+{ 3047, -18850, 7586, 14743, -19862, 6351},
+{ -5047, 1405, -9672, 1055, -21881, 11170},
+{ 3481, -9699, 6526, -16655, 22813, 21907},
+{ -18570, 17501, 14664, 1291, 5026, 19676},
+{ 16134, -19810, -16956, -17939, -16933, 5800},
+{ -8224, 4908, 8935, 2272, -1140, -23217},
+{ 1572, 2753, -1598, 2143, -3346, -21926},
+{ -9832, -1060, -27818, 1214, 7289, 150},
+{ 98, 1538, 535, 17429, -23198, -901},
+{ 21340, -20146, 3297, -1744, -8207, -21462},
+{ -4166, -4633, -17902, 5478, 1285, 136},
+{ 18713, 21003, 24818, 11421, 1282, -4618},
+{ -3535, 7636, -265, 2141, -829, -2035},
+{ -3184, 19713, 2775, -2, 1090, 104},
+{ -6771, -20185, 2938, -2125, -36, 1268},
+{ 9560, 9430, 9586, 22100, 13827, 6296},
+{ -535, -20018, 4276, -1868, -448, -17183},
+{ -24352, 14244, -13647, -21040, 2271, 11555},
+{ -2646, 15437, -4589, 18638, -4299, -622},
+{ -20064, 4169, 18115, -1404, 13722, -1825},
+{ -16359, 9080, 744, 22021, 125, 10794},
+{ 9644, -14607, -18479, -14714, 11174, -20754},
+{ -326, -23762, 6144, 7909, 602, 1540},
+{ -6650, 6634, -12683, 21396, 20785, -6839},
+{ 4252, -21043, 5628, 18687, 23860, 8328},
+{ 17986, 5704, -5245, -18093, -555, 3219},
+{ 6091, 14232, -5117, -17456, -19452, -11649},
+{ -21586, 11302, 15434, 25590, 6777, -26683},
+{ 21355, -8244, 5877, -3540, 6079, -2567},
+{ 2603, -2455, 5421, -12286, -19100, 5574},
+{ -1721, -26393, -23664, 22904, -349, 3787},
+{ 2189, -1203, 5340, 3249, -22617, 104},
+{ -1664, -11020, -2857, -20723, -24049, 19900},
+{ 22873, -7345, -18481, -14616, -8400, -12965},
+{ 3777, 3958, 8239, 20494, -6991, -1201},
+{ -160, -1613, -793, -8681, 573, 776},
+{ 4297, -3786, 20373, 6082, -5321, -18400},
+{ 18745, 2463, 12546, -7749, -7734, -2183},
+{ 11074, -4720, 22119, 1825, -24351, 4080},
+{ 1503, -19178, -1569, 13, -313, 375},
+{ 318, -575, 2544, 178, 102, 40},
+{ -15996, -26897, 5008, 3320, 686, 1159},
+{ 25755, 26886, 574, -5930, -3916, 1407},
+{ -9148, -7665, -2875, -8384, -18663, 26400},
+{ -7445, -18040, -18396, 8802, -2252, -21886},
+{ 7851, 11773, 27485, -12847, -1410, 19590},
+{ 2240, 5947, 11247, 15980, -6499, 24280},
+{ 21673, -18515, 9771, 6550, -2730, 334},
+{ -4149, 1576, -11010, 89, -24429, -5710},
+{ 7720, 1478, 21412, -25025, -8385, 9},
+{ -2448, 10218, -12756, -16079, 1161, -21284},
+{ -8757, -14429, -22918, -14812, 2629, 13844},
+{ -7252, 2843, -9639, 2882, -14625, 24497},
+{ -674, -6530, 414, -23333, -21343, 454},
+{ 2104, -6312, 10887, 18087, -1199, 175},
+{ -493, -562, -2739, 118, -1074, 93},
+{ -10011, -4075, -28071, 22180, 15077, -636},
+{ -4637, -16408, -9003, -20418, -11608, -20932},
+{ 4815, 15892, 24238, -13634, -3074, -1059},
+{ -6724, 4610, -18772, -15283, -16685, 23988},
+{ 15349, -674, -3682, 21679, 4475, -12088},
+{ 4756, 2593, 5354, 6001, 15063, 26490},
+{ -23815, -17251, 6944, 378, 694, 670},
+{ 23392, -8839, -14713, 7544, -876, 11088},
+{ 3640, 3336, 22593, -3495, -2328, -113},
+{ 284, 6914, 3097, 10171, 6638, -18621},
+{ 2472, 5976, 11054, -11936, -603, -663},
+{ 16175, 16441, 13164, -4043, 4667, 7431},
+{ 19338, 15534, -6533, 1681, -4857, 17048},
+{ 17027, 532, -19064, -1441, -5130, 1085},
+{ -12617, -17609, 2062, -25332, 19009, -16121},
+{ 10056, -21000, -13634, -2949, 15367, 19934},
+{ -648, -1605, 10046, -1592, 13296, 19808},
+{ -1054, 10744, 538, 24938, 9630, -9052},
+{ -10099, 3042, -25076, -24052, 13971, 100},
+{ 6547, 6907, 7031, 10348, 23775, -17886},
+{ -22793, -1984, -1393, -3330, 9267, 14317},
+{ -14346, -3967, 3042, 16254, -17303, 9646},
+{ -21393, 23628, 16773, 716, 2663, 114},
+{ -19016, -3038, 1574, -245, 1463, -793},
+{ 22410, 23441, -14637, -530, 17310, 13617},
+{ -11582, 7935, -13954, 23465, -24628, 26550},
+{ -1045, 3679, -2218, 10572, 20999, -3702},
+{ -15513, 197, 16718, -24603, 4945, 5},
+{ 10781, 4335, 26790, -9059, -16152, -2840},
+{ 16075, -24100, -3933, -6833, 12645, -7029},
+{ 2096, -25572, -8370, 6814, 11, 1178},
+{ -11848, -583, -8889, -20543, -10471, -380},
+{ -2487, 24777, -21639, -19341, 1660, -732},
+{ 2313, 13679, 4085, 24549, 24691, -21179},
+{ -2366, -504, -4130, -10570, 23668, 1961},
+{ 20379, 17809, -9506, 3733, -18954, -6292},
+{ -3856, 16802, -929, -20310, -17739, 6797},
+{ 12431, 6078, -11272, -14450, 6913, 23476},
+{ 7636, -1655, 23017, 10719, -8292, 838},
+{ -8559, -1235, -18096, 3897, 16093, 1490},
+{ -3586, 8276, 15165, -3791, -21149, 1741},
+{ -4497, 21739, 2366, -278, -4792, 15549},
+{ -23122, -13708, 7668, 16232, 24120, 15025},
+{ -20043, 12821, -20160, 16691, -11655, -16081},
+{ -12601, 20239, 3496, -2549, -6745, -11850},
+{ 4441, 7812, 20783, 17080, 11523, -9643},
+{ 24766, 8494, -23298, -3262, 11101, -7120},
+{ -10107, -7623, -22152, -18303, 26645, 9550},
+{ -25549, 477, 7874, -1538, 1123, -168},
+{ 470, 9834, -347, 23945, -10381, -9467},
+{ -4096, -9702, -6856, -21544, 20845, 7174},
+{ 5370, 9748, -23765, -1190, 512, -1538},
+{ -1006, -10046, -12649, 19234, -1790, -890},
+{ 15108, 23620, -15646, -2522, -1203, -1325},
+{ -7406, -2605, 1095, -247, -473, 177},
+{ 8089, 4, 12424, -22284, 10405, -7728},
+{ 22196, 10775, -5043, 690, 534, -212},
+{ -3153, -1418, -16835, 18426, 15821, 22956},
+{ 5681, -2229, 3196, -3414, -21817, -14807},
+{ 19, 787, 1032, 170, -8295, -645},
+{ -882, -2319, -27105, 432, -4392, 1499},
+{ -1354, -11819, -76, -20380, -10293, 11328},
+{ 211, -4753, -4675, -6933, -13538, 14479},
+{ 6043, 5260, -459, -462, 143, -65},
+{ -2572, 7256, -3317, 9212, -23184, -9990},
+{ -24882, -9532, 18874, 6101, 2429, -14482},
+{ 8314, 2277, 14192, 3512, 25881, 22000},
+{ 208, 20218, -281, -24778, -63, -1183},
+{ 1095, -6034, 2706, -21935, -2655, 563},
+{ 23, -5930, 243, -8989, 5345, 20558},
+{ -15466, 12699, 4160, 11087, 20621, -10416},
+{ 20995, -85, -8468, 194, 1003, -9515},
+{ -19637, -3335, -14081, 3574, -23381, -667},
+{ -2076, 3489, -3192, -19367, 539, -1530},
+{ 7352, -15213, 22596, 19369, 1043, 16627},
+{ -1872, -413, 1235, -5276, -3550, 21903},
+{ 7931, -2008, 16968, -6799, 29393, -2475},
+{ -13589, 8389, -23636, -22091, -14178, -14297},
+{ -11575, -20090, 16056, -1848, 15721, 4500},
+{ 3849, -16581, 20161, -21155, 7778, 11864},
+{ -6547, -1273, -18837, -11218, 11636, 1044},
+{ 2528, -6691, -17917, -11362, -4894, -1008},
+{ 1241, 4260, 2319, 6111, 3485, 20209},
+{ 3014, -3048, 5316, -4539, 20831, 8702},
+{ -1790, -14683, 278, 13956, -10065, -10547},
+{ -22732, -7957, -1154, 13821, -1484, -1247},
+{ -7317, -615, 13094, 18927, 9897, 1452},
+{ 2552, -2338, 3424, -4630, 11124, -19584},
+{ -11125, -20553, -10855, -10783, -20767, 6833},
+{ 984, -15095, 5775, 25125, 5377, -19799},
+{ 517, 13272, -7458, -1711, 20612, -6013},
+{ -21417, 13251, -20795, 13449, 17281, 13104},
+{ -15811, -16248, 23093, -4037, -8195, 871},
+{ 582, 12571, -21129, -14766, -9187, 5685},
+{ 4318, -1776, 11425, -17763, -9921, 577},
+{ 6013, 16830, 17655, -25766, -4400, -3550},
+{ -13744, -16541, 3636, -3330, -21091, -15886},
+{ 6565, -11147, 8649, -13114, 23345, -13565},
+{ -2542, -9046, -7558, 29240, 3701, -383},
+{ -10612, 24995, 1893, -8210, 20920, -16210},
+{ 5276, 16726, 10659, 19940, -4799, -19324},
+{ -532, -9300, 27856, 4965, -241, 536},
+{ -765, -20706, -3412, 18870, 2765, 1420},
+{ -3059, 2708, -19022, -331, 3537, 116},
+};
+static const int16_t vq_hebap7[512][6] = {
+{ -21173, 21893, 10390, 13646, 10718, -9177},
+{ -22519, -8193, 18328, -6629, 25518, -10848},
+{ 6800, -13758, -13278, 22418, 14667, -20938},
+{ 2347, 10516, 1125, -3455, 5569, 27136},
+{ -6617, 11851, -24524, 22937, 20362, -6019},
+{ -21768, 10681, -19615, -15021, -8478, -2081},
+{ -2745, 8684, -4895, 27739, 7554, -11961},
+{ -1020, 2460, -954, 4754, -627, -16368},
+{ -19702, 23097, 75, -13684, -2644, 2108},
+{ 4049, -2872, 5851, -4459, 22150, 12560},
+{ -21304, -17129, -730, 7419, -11658, -10523},
+{ 11332, 1792, 26666, 23518, -19561, -491},
+{ -17827, -16777, -13606, -14389, -22029, -2464},
+{ 1091, -5967, -7975, -16977, -20432, -21931},
+{ 18388, -1103, 1933, 13342, -17463, 18114},
+{ 22646, 17345, -9966, 17919, 18274, 698},
+{ 1484, 20297, -5754, -26515, 4941, -22263},
+{ -2603, 4587, -5842, 18464, 8767, -2568},
+{ -2797, -1602, 21713, 3099, -25683, 3224},
+{ -19027, 4693, -5007, 6060, 1972, -15095},
+{ -2189, 9516, -530, 20669, -4662, -8301},
+{ -22325, -8887, 2529, -11352, 5476, 998},
+{ 22100, -5052, 1651, -2657, 4615, 2319},
+{ 20855, -3078, -3330, 4105, 13470, 3069},
+{ 85, 17289, 10264, -14752, 214, 90},
+{ -26365, -18849, -19352, 19244, -10218, 9909},
+{ -9739, 20497, -6579, -6983, 2891, -738},
+{ 20575, -15860, -22913, 6870, 76, 327},
+{ 8744, -12877, -22945, -2372, -19424, -9771},
+{ -12886, 16183, 21084, 3821, 749, -13792},
+{ -15995, 18399, 2391, -17661, 19484, -6018},
+{ 1423, 11734, 4051, 19290, 6857, -19681},
+{ -5200, 9766, 18246, 2463, 18764, -4852},
+{ -597, 19498, 1323, -9096, -308, -1104},
+{ -3099, -25731, -15665, 25332, 4634, 2635},
+{ 19623, -2384, -7913, 11796, -9333, -14084},
+{ 2642, 26453, -21091, -10354, -1693, -1711},
+{ 22031, 21625, 11580, -22915, -4141, 129},
+{ -6122, 3542, 915, -261, -17, -383},
+{ 1696, 6704, -1425, 20838, 857, -4416},
+{ 1423, -15280, -8550, -9667, 5210, 5687},
+{ -4520, -613, -11683, 5618, 4230, 619},
+{ 937, -4963, -14102, -17104, -6906, -5952},
+{ -15068, -481, -7237, -14894, 18876, 21673},
+{ -25658, 2910, 1143, -327, -458, -995},
+{ -9656, -819, -24900, 2804, 20225, 1083},
+{ -1111, -3682, -1788, -19492, 966, 821},
+{ 7293, -21759, 10790, -7059, -23293, -1723},
+{ -282, -11093, 170, -20950, -28926, 12615},
+{ 17938, 3713, -1563, 885, 5, 564},
+{ 6116, 22696, 2242, -6951, 9975, -6132},
+{ 4338, 26808, -3705, 1976, -1079, -2570},
+{ -661, -7901, -2668, -15194, 17722, 4375},
+{ -4174, -11053, 717, -22506, 1562, 12252},
+{ -6405, 18334, 6103, 6983, 5956, 18195},
+{ 9851, 5370, 23604, -6861, -6569, -62},
+{ 21964, 13359, -683, 3785, 2168, 209},
+{ -3569, -1127, -19724, -1544, 1308, -803},
+{ -3083, 16049, -13791, -3077, 4294, 23713},
+{ -9999, 9943, -15872, 12934, -23631, 21699},
+{ 9722, 22837, 12192, 15091, 5533, 4837},
+{ 2243, 2099, 1243, 4089, 4748, 12956},
+{ 4007, -2468, 3353, -3092, 8843, 17024},
+{ 4330, 6127, 5549, 9249, 11226, 28592},
+{ -9586, -8825, 236, 1009, 455, -964},
+{ 6829, 19290, -1018, 200, 1821, 578},
+{ 5196, 957, 10372, 3330, -12800, -127},
+{ -3022, -8193, -14557, 22061, 5920, 1053},
+{ 10982, 25942, -24546, -23278, -11905, -6789},
+{ 22667, -11010, 5736, 2567, 23705, -10253},
+{ -3343, -4233, -5458, 20667, -10843, -3605},
+{ -4131, -3612, 4575, -829, -350, -847},
+{ -3303, 3451, -7398, -11604, 3023, 455},
+{ 3200, -9547, 3202, -22893, 11184, -26466},
+{ -14093, -4117, 15382, 14295, -10915, -20377},
+{ 3807, -11016, 22052, 14370, -15328, -7733},
+{ -6291, -17719, -1560, 12048, -19805, -443},
+{ -6147, -4234, -160, 8363, 22638, 11911},
+{ 19197, 1175, 7422, -9875, -4136, 4704},
+{ -72, -7652, -112, -11955, -3230, 27175},
+{ 3274, 5963, 7501, -17019, 866, -25452},
+{ 737, 1861, 1833, 2022, 2384, 4755},
+{ -5217, 7512, 3323, 2715, 3065, -1606},
+{ 4247, 565, 5629, 2497, 18019, -4920},
+{ -2833, -17920, -8062, 15738, -1018, 2136},
+{ 3050, -19483, 16930, 29835, -10222, 15153},
+{ -11346, 118, -25796, -13761, 15320, -468},
+{ -4824, 4960, -4263, 1575, -10593, 19561},
+{ -8203, -1409, -763, -1139, -607, 1408},
+{ -2203, -11415, 2021, -6388, -2600, 711},
+{ -413, -2511, -216, -3519, -28267, 1719},
+{ -14446, 17050, 13917, 13499, -25762, -16121},
+{ 19228, 7341, -12301, 682, -3791, -199},
+{ -4193, 20746, -15651, 11349, 5860, -824},
+{ -21490, -3546, -3, -1705, -3959, 9213},
+{ 15445, -1876, 2012, -19627, 16228, -4845},
+{ -2867, -3733, -7354, -175, -20119, 11174},
+{ -3571, -24587, 19700, 6654, 979, -654},
+{ 21820, -7430, -6639, -10767, -8362, 15543},
+{ 14827, 17977, -7204, -3409, 1906, -17288},
+{ 3525, -3947, -1415, -2798, 17648, 2082},
+{ -6580, -15255, -17913, 1337, 15338, 21158},
+{ 6210, 9698, 15155, -24666, -22507, -3999},
+{ -1740, -593, 1095, -7779, 25058, 5601},
+{ 21415, -432, -1658, -6898, -1438, -14454},
+{ -6943, 700, -12139, -745, -24187, 22466},
+{ 6287, 3283, 11006, 3844, 19184, 14781},
+{ -22502, 15274, 5443, -2808, -970, -3343},
+{ 3257, -3708, 4744, -8301, 22814, -10208},
+{ 24346, -20970, 19846, 987, -11958, -6277},
+{ 3906, -19701, 13060, -1609, 18641, 7466},
+{ -26409, -22549, 16305, 2014, 10975, 18032},
+{ -7039, 4655, -14818, 18739, 15789, 1296},
+{ 9310, -1681, 14667, -3326, 26535, -11853},
+{ 5728, 5917, 13400, 10020, -2236, -24704},
+{ 1741, -6727, 12695, -22009, 4080, 5450},
+{ -2621, 9393, 21143, -25938, -3162, -2529},
+{ 20672, 18894, -13939, 6990, -8260, 15811},
+{ -23818, 11183, -13639, 11868, 16045, 2630},
+{ 18361, -10220, 829, 856, -1010, 157},
+{ 14400, -4678, 5153, -13290, -27434, -11028},
+{ 21613, 11256, 17453, 7604, 13130, -484},
+{ 7, 1236, 573, 4214, 5576, -3081},
+{ 916, -9092, 1285, -8958, 1185, -28699},
+{ 21587, 23695, 19116, -2885, -14282, -8438},
+{ 23414, -6161, 12978, 3061, -9351, 2236},
+{ -3070, -7344, -20140, 5788, 582, -551},
+{ -3993, 315, -7773, 8224, -28082, -12465},
+{ 13766, -15357, 19205, -20624, 13043, -19247},
+{ 3777, -177, 8029, -1001, 17812, 5162},
+{ -7308, -4327, -18096, -620, -1350, 14932},
+{ 14756, -1221, -12819, -14922, -547, 27125},
+{ 2234, 1708, 2764, 5416, 7986, -25163},
+{ 2873, 3636, 3992, 5344, 10142, 21259},
+{ 1158, 5379, 508, -10514, 290, -1615},
+{ 1114, 24789, 16575, -25168, -298, -2832},
+{ -1107, -6144, -1918, -7791, -2971, -23276},
+{ 4016, 10793, 17317, -4342, -20982, -3383},
+{ -4494, -207, -9951, -3575, 7947, 1154},
+{ -7576, 8117, -14047, 16982, -26457, -27540},
+{ -15164, 16096, -16844, -8886, -23720, 15906},
+{ 24922, 5680, -1874, 420, 132, 117},
+{ -506, -19310, -198, 412, -311, 752},
+{ -1906, 3981, -7688, 16566, -19291, -14722},
+{ -399, -729, -3807, -4196, -12395, 7639},
+{ 3368, 2330, 9092, 23686, -10290, -1705},
+{ -3148, 2596, -7986, 14602, -4807, 16627},
+{ 8057, 1481, 49, 17205, 24869, 7474},
+{ -19304, -513, 11905, 2346, 5588, 3365},
+{ -5063, -21812, 11370, 10896, 4881, 261},
+{ 4794, 20577, 5109, -6025, -8049, -1521},
+{ 8125, -14756, 20639, -14918, 23941, -3650},
+{ 12451, 1381, 3613, 8687, -24002, 4848},
+{ 6726, 10643, 10086, 25217, -25159, -1065},
+{ 6561, 13977, 2911, 21737, 16465, -26050},
+{ -1776, 2575, -19606, -16800, 3032, 6679},
+{ 15012, -17910, -8438, -21554, -27111, 11808},
+{ 3448, -924, -15913, -1135, 5126, -20613},
+{ 7720, 2226, 17463, 5434, 28942, 17552},
+{ 1246, 15614, -11743, 24618, -17539, 3272},
+{ 3215, 17950, 2783, -722, -22672, 5979},
+{ -5678, -3184, -26087, 26034, 6583, 3302},
+{ 20310, -3555, -2715, -444, -1487, 1526},
+{ -20640, -21970, -12207, -25793, 8863, -1036},
+{ 17888, 570, -16102, 8329, -2553, 15275},
+{ -2677, 9950, -1879, 16477, -12762, -29007},
+{ -120, -2221, 219, 97, 365, 35},
+{ 1270, -718, 1480, -2689, 1930, -7527},
+{ 1896, 8750, 1906, 18235, -12692, -6174},
+{ -3733, 13713, -9882, -15960, -1376, -7146},
+{ -10600, 8496, 15967, -8792, 7532, 20439},
+{ 3041, -13457, 1032, -26952, 5787, 24984},
+{ -4590, -8220, -9322, -6112, -17243, 25745},
+{ -17808, 6970, 3752, 626, -114, 2178},
+{ 4449, -4862, 7054, -5404, 4738, -2827},
+{ 4922, -651, 18939, -9866, 848, 1886},
+{ -336, -5410, 7234, 20444, -9583, -600},
+{ 781, -19474, -12648, 6634, 1414, 450},
+{ -3399, -16770, 11107, 13200, -5498, 21663},
+{ -3265, 4859, -5961, 7530, -10837, 28086},
+{ 10350, -12901, 25699, 25640, -639, 351},
+{ 1163, 18763, -5466, -15087, -145, -1377},
+{ -14477, 27229, -31383, -32653, 21439, -2894},
+{ 15420, 18823, 22128, 19398, 22583, 13587},
+{ -10674, 10710, 5089, -4756, 909, -20760},
+{ -12948, -20660, 7410, 2722, 3427, 11585},
+{ -1105, 18374, 19731, -9650, 22442, 19634},
+{ -296, -6798, -14677, 21603, 19796, 21399},
+{ -19350, -7501, 25446, 13144, 8588, -25298},
+{ 3092, -10618, 20896, 9249, -3326, 1796},
+{ -811, 1449, 3106, 4748, 12073, -14262},
+{ -20720, 14275, -4332, -25838, -5781, -21149},
+{ -5132, 10554, -14020, -22150, 2840, -554},
+{ 25533, 17648, 14886, -21074, 2459, 25142},
+{ -9370, -1788, -12862, -5870, -25811, -11023},
+{ 6698, 819, 10313, 166, 27581, 523},
+{ 101, -19388, 3413, 9638, 64, 806},
+{ -2742, -17931, -2576, 22818, 8553, 1126},
+{ 2972, 15203, 1792, 25434, -5728, -17265},
+{ -1419, 1604, 4398, 11452, 1731, 23787},
+{ -5136, 4625, -10653, 27981, 9897, -2510},
+{ -10528, -28033, 2999, -1530, -832, -830},
+{ -11133, -12511, 22206, -7243, -23578, -21698},
+{ 16935, -21892, 1861, -9606, 9432, 19026},
+{ 10277, 9516, 26815, 2010, -4943, -9080},
+{ 5547, -2210, 14270, -15300, -19316, 1822},
+{ -4850, -783, -8959, -3076, -20056, -3197},
+{ 8232, -2794, -17752, 13308, 3229, -991},
+{ -12237, -6581, 10315, -9552, 2260, -20648},
+{ -7000, 5529, -7553, -7490, -10342, -10266},
+{ 3641, 19479, -5972, -19097, -18570, 12805},
+{ 1283, -4164, 4198, -28473, -2498, 1866},
+{ 16047, 26826, -13053, -6316, 985, -1597},
+{ -403, 13680, 6457, 25070, 27124, -20710},
+{ -18070, -1790, -24986, 5953, -954, 26600},
+{ -24224, -15383, 24788, 1953, -1136, 187},
+{ -2289, 12505, -20738, -904, 18324, 21258},
+{ 2658, -6140, 16179, 22276, -556, 2154},
+{ -6087, 13950, -25682, -27713, 4049, -4795},
+{ -21452, 26473, 19435, -9124, 895, 303},
+{ -22200, -26177, -6026, 24729, -22926, -9030},
+{ -14276, -15982, 23732, -22851, 9268, -3841},
+{ 29482, 21923, -6213, 1679, -2059, -1120},
+{ -435, 9802, -3891, 12359, -4288, -18971},
+{ 19768, -86, 2467, 1990, -1021, -5354},
+{ 20986, -8783, -5329, -23562, -4730, 2673},
+{ -5095, 5605, -4629, 19150, 26037, -12259},
+{ 972, 6858, 4551, 27949, -4025, -2272},
+{ 6075, -3260, -4989, -373, -1571, -3730},
+{ -7256, -12992, -8820, -5109, 23054, 5054},
+{ 920, 2615, 7912, -7353, -4905, 20186},
+{ -250, 5454, 3140, 6928, -18723, -2051},
+{ -10299, -4372, 19608, 4879, -661, -1885},
+{ 14816, -8603, -19815, 6135, -21210, 14108},
+{ -11945, -2223, 5018, 11892, 22741, 406},
+{ -13184, -2613, -13256, -22433, -12482, -8380},
+{ 17066, 25267, -2273, 5056, -342, 145},
+{ 8401, -17683, 19112, 10615, -19453, 17083},
+{ 20821, -5700, 12298, -25598, 10391, 7692},
+{ 4550, 15779, 17338, -19379, -4768, 1206},
+{ -7723, 10836, -27164, -11439, 6835, -1776},
+{ 2542, 3199, 4442, 17513, -3711, -914},
+{ 20960, -16774, -5814, 11087, -70, 22961},
+{ 3305, 2919, 6256, -4800, -20966, -3230},
+{ 5924, -16547, 2183, 2733, 3446, -23306},
+{ -6061, -194, -13852, -10971, 19488, 1029},
+{ 4467, -5964, -19004, 1519, -359, 855},
+{ -1581, -7607, 22070, -11580, -10032, 17102},
+{ -12412, 2553, 4324, 22500, 5751, 12170},
+{ -25127, 17996, -6384, 1180, 1182, 9622},
+{ 23462, -8471, -4392, -2669, 7638, -16835},
+{ -5511, -2887, -10757, -20883, 7246, 1053},
+{ 2703, -20602, -7554, 7516, -7740, 5868},
+{ 20670, 21901, 457, 14969, -17657, -11921},
+{ 3603, -1595, -2177, -157, -43, 605},
+{ 2513, 8954, 10527, 22559, -16100, -16041},
+{ 6002, 4951, 6795, -4862, -22400, 18849},
+{ 7590, -1693, -24688, -3404, 14169, 1214},
+{ -4398, -6663, -6870, -10083, -24596, 9253},
+{ 10468, 17751, -7748, 147, -6314, 4419},
+{ 16187, -16557, -4119, 4302, 7625, 5409},
+{ 3303, 2735, 7458, -19902, -2254, -3702},
+{ -2077, 21609, 14870, 12545, -6081, -1764},
+{ 4678, 11740, 2859, 6953, 1919, -3871},
+{ 3522, -21853, -2469, -10453, 18893, -10742},
+{ 3759, -10191, -4866, -2659, -17831, -1242},
+{ 14991, 9351, 11870, -1573, -4848, 22549},
+{ 9509, -27152, 10734, 20851, -26185, -17878},
+{ -7170, -1392, -19495, 12746, 8198, -1988},
+{ 1883, 28158, -846, -7235, 249, 233},
+{ -7200, 669, -371, -2948, 23234, -5635},
+{ 3141, 288, 3223, -1258, -98, -27607},
+{ 17373, -23235, 5110, -11199, -2574, -11487},
+{ -4928, 1518, -5456, 670, -18278, 1951},
+{ 10334, -19865, -4649, 361, -160, -923},
+{ 18732, 14264, -3155, -7485, -3328, 5959},
+{ -3614, 21077, 7276, 3536, 8121, -1528},
+{ -8422, 500, -19182, 18929, 26392, -1039},
+{ 15639, 25668, 8375, 1903, 1945, -11979},
+{ -2716, 3389, 26850, -4587, 1803, 22},
+{ 1177, -655, 1233, -2128, 7844, 1767},
+{ -761, 8209, -19290, -4593, 1923, -343},
+{ -689, -3530, -3267, -3804, -2753, 18566},
+{ -2110, 1962, -1353, 16643, 2765, -23102},
+{ -433, 4905, 302, 13016, 15933, -5905},
+{ 3203, 4126, 11181, -5496, -2529, -1160},
+{ -1091, -6469, -1415, 5682, -268, 583},
+{ -9405, -19572, 6216, 1658, 993, -75},
+{ -1695, -4504, -2289, -4088, -6556, -16577},
+{ 4760, -892, -10902, 6516, 24199, -6011},
+{ -253, 1000, 63, -81, -115, -382},
+{ -1333, 24224, -698, -4667, -2801, -19144},
+{ -876, -28866, -21873, 12677, -6344, 3235},
+{ 16847, 21145, -26172, -3183, -396, 230},
+{ 18296, -7790, -12857, -679, -1473, 5},
+{ -10488, 11429, 25805, -1122, 1401, -438},
+{ 3782, -7429, 26720, 17567, 19257, 12542},
+{ 6332, -746, 12789, 9316, -22542, -5354},
+{ 3418, -22728, 26978, 18303, 1076, 956},
+{ -27315, -2988, 920, 235, 2233, 81},
+{ 6199, 5296, 16093, 14768, -8429, -1112},
+{ -6432, 19244, 9921, -3253, 1278, -954},
+{ 24213, 2049, -22931, 2585, -2410, -4216},
+{ 9286, 14282, -19735, -3985, -2344, 1028},
+{ -20128, 17993, -9458, 23012, -16983, 8625},
+{ -6896, -20730, 3762, 17415, 22341, 19024},
+{ 842, 24181, 25062, -5839, -78, 937},
+{ -621, 19722, -24204, -1962, -14854, -56},
+{ 22766, -5119, 17365, 23868, -19480, -6558},
+{ -2158, 17490, -21435, 3340, -12819, -20295},
+{ -9621, 17325, 715, 2265, -4123, -492},
+{ 9156, 12947, 27303, -21175, -6072, -9457},
+{ -13164, -23269, -14006, -4184, 6978, 2},
+{ 938, -13381, 3520, -24297, 22902, 19589},
+{ -4911, -19774, 19764, -9310, -12650, 3819},
+{ -5462, -4249, -6987, -6260, -13943, -25150},
+{ 9341, 10369, -13862, -6704, 22556, -519},
+{ 6651, 18768, -4855, 12570, 14730, -10209},
+{ -823, 18119, 398, -1582, -116, -363},
+{ -6935, -12694, -28392, 8552, 6961, -239},
+{ -2602, -4704, -1021, 2015, 5129, 23670},
+{ -12559, -8190, -25028, 18544, 14179, 1663},
+{ 3813, 21036, -9620, -5051, -1800, -1087},
+{ -22057, 16675, 14960, 9459, 2786, 16991},
+{ -26040, -19318, -6414, 1104, 5798, -18039},
+{ -1737, 24825, 10417, -11087, 896, -5273},
+{ -1855, 11661, -2803, 24809, -21435, -19792},
+{ -23473, -16729, -5782, 5643, 2636, 4940},
+{ -1724, 4388, -26673, -13695, 10570, -25895},
+{ 15358, -19496, 26242, -18493, 1736, 8054},
+{ 5684, 20890, 4091, -19100, -14588, -10468},
+{ 17260, -16291, 14859, -17711, -19174, 12435},
+{ -27185, -12573, 6743, -562, 976, -257},
+{ 12395, -8618, -22248, -19843, 11013, 7762},
+{ 3799, 11853, -27622, -8473, 1089, -1495},
+{ 4141, -2182, -26720, -735, -774, 1469},
+{ 3125, 13762, 4606, 29257, 18771, -9958},
+{ -17465, -9445, -17562, -2530, -6435, -3726},
+{ -1742, 4351, -6841, -19773, 9627, -10654},
+{ 7251, 3525, 10835, 5601, 25198, -23348},
+{ -10300, -17830, 631, 11640, 2044, -20878},
+{ -873, -8502, -1063, -15674, -10693, 14934},
+{ -15957, 28137, 5268, 477, -1053, 1158},
+{ -1495, -8814, -5764, -24965, 25988, 7907},
+{ -1038, -114, -2308, -1319, -6480, 1472},
+{ 4895, -17897, -25850, 5301, -188, 1581},
+{ 3200, 17225, 4346, 22101, -18543, 22028},
+{ -10250, 545, -10932, 2276, -28070, 8118},
+{ 15343, 2329, 9316, 20537, 14908, 21021},
+{ 6329, 6130, -24508, 837, -8637, -5844},
+{ 7386, -501, 10503, 20131, 11435, -4755},
+{ -2745, 24174, -9274, 15273, -8389, -5835},
+{ 2992, -2864, 6048, -7473, 11687, -19996},
+{ -883, -11954, -9976, -21829, -4436, -27178},
+{ 3458, 19626, 1280, 2597, 19849, 5255},
+{ -5315, 19133, -14518, -8946, 13749, -1352},
+{ 18642, 17655, 11001, 6817, -18418, 6336},
+{ -1697, 2244, -4640, 3948, -12890, -5273},
+{ 20428, 10542, 4170, -1012, 19439, 21691},
+{ -2943, -19735, -4208, 1320, 909, -8897},
+{ 9351, -8066, -2618, -12933, 26582, 3507},
+{ 9705, -22628, 8311, 8167, -13293, 5608},
+{ 3222, 3749, -1508, 165, -52, -196},
+{ 102, -22744, -8832, 903, -11421, -14662},
+{ -120, 5998, 19765, 13401, 3628, 5197},
+{ 8528, 5827, -1066, 774, -39, -166},
+{ 9411, -9476, 9581, -13004, 24456, 24900},
+{ 17878, 2235, -21639, 20478, 4716, -7190},
+{ -2482, 9511, 1611, -21943, 14230, -1289},
+{ 9288, -2291, 23215, -3452, -10842, 11},
+{ 9496, 3041, 5130, -3890, -21219, -22589},
+{ 14262, -9838, 20195, 14019, 91, -17200},
+{ -18591, 980, 17, 821, 120, -574},
+{ 12285, -19269, 13742, 16373, -161, 6025},
+{ -3364, 1530, -4005, 2454, -10872, -23839},
+{ 105, 5085, -260, 5790, -588, 19170},
+{ 4121, 4169, 13439, 14644, 20899, 7434},
+{ -175, 13101, -3704, 23233, 3907, 10106},
+{ -6101, 23467, 5204, -1341, 1599, 13174},
+{ -3217, -3494, 15117, -8387, -11762, -4750},
+{ 1146, 4675, -19378, 14917, -5091, 249},
+{ -21506, 10136, -16473, -13305, 18382, -8601},
+{ 628, 2447, 3344, 3130, -5115, 119},
+{ 17900, -22422, -17633, 21967, -16293, -7676},
+{ 16863, 24214, 5612, -3858, -809, 3822},
+{ -2291, 10091, -2360, -25109, -1226, 312},
+{ 2957, 11256, 26745, -13266, -3455, -1128},
+{ -19762, -2708, 4604, 6355, 1638, 25501},
+{ -19593, -7753, 3159, -85, -489, -1855},
+{ 814, 12510, 19077, -4681, -2610, -1474},
+{ -23408, -19027, 8137, 19878, 7912, -282},
+{ 839, -19652, 11927, 27278, -3211, 2266},
+{ 4020, -1110, 8226, -1274, 20922, 25060},
+{ 26576, 325, -8693, -232, -2218, -699},
+{ -11293, -4200, 1805, -6673, -22940, -1339},
+{ -2005, -15886, -1047, -27687, -13235, 14370},
+{ -22073, 1949, 13175, -15656, -1846, 8055},
+{ 3039, 12025, 7132, -24632, 413, -2347},
+{ -24048, -206, 12459, -6654, -417, -10091},
+{ 18179, -23688, -20515, -16396, 7230, 763},
+{ 5659, -5085, 13878, -23729, -11077, -19587},
+{ 11340, 501, 25040, 7616, -19658, 1605},
+{ -26650, 8878, 10544, 417, 1299, 261},
+{ 14460, 11369, -3263, 9990, 8194, 18111},
+{ 1355, -20838, -9196, -16060, -8559, -730},
+{ -1918, -20937, -18293, -2461, -2651, 4316},
+{ -2810, 24521, -10996, -25721, 308, -1234},
+{ -9075, -17280, -1833, -29342, -24213, -16631},
+{ -2843, 10165, -5339, -2888, 21858, -21340},
+{ -15832, 14849, -23780, 5184, 10113, -20639},
+{ -19535, -11361, 8413, 1486, -23658, -5759},
+{ -7512, 1027, -20794, 13732, 19892, -21934},
+{ -12132, -7022, -19175, -8840, 22125, -16490},
+{ 1937, 5210, -6318, -23788, 13141, 11082},
+{ -205, 6036, -380, 8658, -233, 28020},
+{ -5523, 7477, 7635, 23595, 9763, -2590},
+{ 21658, -28313, -3086, -300, -1032, 1744},
+{ -22352, 16646, 208, 6665, -17400, -3028},
+{ 18482, 9336, -2737, -19372, 407, -4389},
+{ -4913, -17370, 18819, -17654, 13416, 15232},
+{ 7749, 6368, 23135, -18174, 7584, -4248},
+{ -1489, -6523, 586, -10157, 14964, 25568},
+{ 3844, -6156, 4897, -13045, -22526, 5647},
+{ -8491, -2105, -24774, 905, -9326, 1456},
+{ -3040, -1476, 1166, -4428, 11236, 9204},
+{ 3397, -1451, 13598, -15841, 24540, 5819},
+{ 8483, -2993, 21547, -16916, 7741, 24018},
+{ -14932, -23758, -5332, -6664, -4497, 13267},
+{ 19379, 12916, -2142, -737, 21100, -22101},
+{ 3393, -4629, 5735, -18913, -6969, 2687},
+{ 1148, -16147, -21433, -28095, -630, -14449},
+{ 7300, 672, 18530, -17452, -10149, 351},
+{ 11356, -10974, 17212, 4624, 145, 17791},
+{ -711, -3479, -2238, 15887, 2027, 0},
+{ -28048, 1794, -593, -2758, -21852, 11535},
+{ -19683, 4937, 22004, 21523, -3148, 1790},
+{ 813, 8231, 2633, 11981, -3043, 22201},
+{ 8952, -24760, -690, 14873, -2366, -5372},
+{ 8406, -5439, -274, -642, -145, 778},
+{ -6605, 7258, 20780, -23507, -18625, 22782},
+{ -22896, -25488, 10020, -1614, 1508, -1393},
+{ 7607, 407, -24678, -16385, -1804, -4699},
+{ -10592, -19139, 10462, -3747, 8721, -6919},
+{ 13010, 5292, -6230, -4884, -20904, -1797},
+{ 16891, -13770, -465, 19343, -10741, -12959},
+{ 25193, -14799, -5681, -521, -321, -1211},
+{ 6917, -3093, 20183, -26903, -12026, 1295},
+{ 305, 1992, 19457, -985, 25, -521},
+{ 6707, -3698, 8365, -8687, 21921, -27166},
+{ 4668, 5997, 7117, 11696, 24401, -10794},
+{ 744, -9416, 19893, 1963, 7922, -9824},
+{ 3430, 21282, -1736, 10844, 8821, 27015},
+{ -8813, 1521, -24038, 1651, 7838, -1208},
+{ 3911, -11221, 3273, -12541, 7168, 18402},
+{ 21642, 9117, -11536, -5256, 7077, 2382},
+{ 100, 3817, -6713, 1244, 1518, -321},
+{ 7946, -18670, 10667, -4866, 727, 776},
+{ -15883, -8150, -2087, 22739, 1567, -3482},
+{ 4380, -2735, 8469, -7025, -11424, 1317},
+{ 26970, 4393, 7665, 17561, -714, 650},
+{ -16191, -835, 8365, 1795, -14314, 16297},
+{ 4504, -10048, 7662, -26690, -17428, 2580},
+{ 48, -3984, 564, -5871, 2658, -18658},
+{ 12579, -26016, -15642, 2672, -1347, -887},
+{ -4950, 4208, -6811, 2569, -20621, -8658},
+{ -1836, -14818, -5571, -23322, -14800, 25867},
+{ 5434, -28139, -2357, -2883, -570, 2431},
+{ 13096, -2771, 24994, -12496, -24723, -1025},
+{ -5676, -4339, 1908, 18628, -21323, 17366},
+{ 27660, -27897, -15409, 1436, -7112, -2241},
+{ 8019, 3847, 24568, -469, 9674, 10683},
+{ -903, -10149, 1801, -21260, 4795, -8751},
+{ 1122, -9582, 2625, 22791, 956, 882},
+{ 7876, 19075, -9900, -24266, 7496, 9277},
+{ 980, -26764, -5386, 5396, 1086, 1648},
+{ 28838, -1270, -447, 5, -429, -20},
+{ -15283, 6132, 22812, 1252, -9963, 511},
+{ 851, 7925, -457, -12210, 4261, 7579},
+{ -4530, 8452, -1246, 14501, -24951, -5760},
+{ -17814, -10727, 9887, -23929, -13432, 1878},
+{ -15049, 10165, 16491, -14603, -11712, -21156},
+{ -3317, 840, -5683, 22413, 1994, 586},
+{ 23158, -5788, -15043, -10372, -9271, -13523},
+{ -773, -9509, -3993, -24264, 8463, 5804},
+{ -8545, -703, -12440, -3985, -25122, -28147},
+{ -16659, 16001, 2746, 1611, 5097, -1043},
+{ 41, -7181, 19903, 31555, -32237, 13927},
+{ -5658, 845, -12774, 5705, 16695, -86},
+{ 5282, 14875, 27026, 21124, 15776, -10477},
+{ 14712, 19648, -11487, -13361, -20196, -15229},
+{ 8597, -9138, -626, 10891, -6015, 6346},
+{ -1488, -1272, -1479, -1303, -3704, -5485},
+{ -3370, 17871, -6604, 24930, 25886, -3127},
+{ 8416, 27783, -1385, 5350, -4260, 19993},
+{ 5688, 362, 17246, 3809, -3246, 1088},
+{ -105, -29607, 2747, 15223, -167, 3722},
+{ 3502, -3195, 8602, 7772, -1566, -915},
+{ -491, 3257, -2423, 5522, 20606, -100},
+{ -13948, -11368, -15375, -21866, -8520, 12221},
+{ -616, 2424, -2023, 4398, -3805, 8108},
+{ -7204, 21043, 21211, -9395, -19391, 896},
+{ -5737, -15160, -21298, 17066, -1006, -366},
+{ 6261, 3240, -11937, -16213, -15820, 6581},
+{ -3155, 24796, 2733, -1257, -875, -1597},
+{ -20469, 11094, 24071, -8987, 14136, 2220},
+{ -14106, 11959, -22495, 4135, -1055, -5420},
+{ 801, -2655, 60, -5324, -790, 5937},
+{ -7372, -1764, -22433, -26060, 21707, 4178},
+{ -5715, -6648, -14908, 1325, -24044, 1493},
+{ -6024, -12488, 23930, 2950, 1601, 1173},
+{ 19067, 17630, 17929, -10654, 10928, -4958},
+{ 3231, -3284, 27336, 4174, -1683, 497},
+};
+
+const int16_t (* const ff_eac3_mantissa_vq[8])[6] = {
+ NULL,
+ vq_hebap1,
+ vq_hebap2,
+ vq_hebap3,
+ vq_hebap4,
+ vq_hebap5,
+ vq_hebap6,
+ vq_hebap7,
+};
+
+/**
+ * Table E2.14 Frame Exponent Strategy Combinations
+ */
+const uint8_t ff_eac3_frm_expstr[32][6] = {
+{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE},
+{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D45},
+{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE},
+{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D45},
+{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_REUSE},
+{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D45},
+{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE},
+{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D45, EXP_D45},
+{ EXP_D25, EXP_REUSE, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE},
+{ EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45},
+{ EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE},
+{ EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D45, EXP_D45},
+{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE},
+{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE, EXP_D45},
+{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE},
+{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D45, EXP_D45, EXP_D45},
+{ EXP_D45, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE},
+{ EXP_D45, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D45},
+{ EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE},
+{ EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D45},
+{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_REUSE},
+{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D45},
+{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE},
+{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D45, EXP_D45, EXP_D45},
+{ EXP_D45, EXP_D45, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE},
+{ EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45},
+{ EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE},
+{ EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_D45, EXP_D45},
+{ EXP_D45, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE},
+{ EXP_D45, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_D45},
+{ EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE},
+{ EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D45},
+};
+
+/**
+ * Table E.25: Spectral Extension Attenuation Table
+ * ff_eac3_spx_atten_tab[code][bin]=pow(2.0,(bin+1)*(code+1)/-15.0);
+ */
+const float ff_eac3_spx_atten_tab[32][3] = {
+ { 0.954841603910416503f, 0.911722488558216804f, 0.870550563296124125f },
+ { 0.911722488558216804f, 0.831237896142787758f, 0.757858283255198995f },
+ { 0.870550563296124125f, 0.757858283255198995f, 0.659753955386447100f },
+ { 0.831237896142787758f, 0.690956439983888004f, 0.574349177498517438f },
+ { 0.793700525984099792f, 0.629960524947436595f, 0.500000000000000000f },
+ { 0.757858283255198995f, 0.574349177498517438f, 0.435275281648062062f },
+ { 0.723634618720189082f, 0.523647061410313364f, 0.378929141627599553f },
+ { 0.690956439983888004f, 0.477420801955208307f, 0.329876977693223550f },
+ { 0.659753955386447100f, 0.435275281648062062f, 0.287174588749258719f },
+ { 0.629960524947436595f, 0.396850262992049896f, 0.250000000000000000f },
+ { 0.601512518041058319f, 0.361817309360094541f, 0.217637640824031003f },
+ { 0.574349177498517438f, 0.329876977693223550f, 0.189464570813799776f },
+ { 0.548412489847312945f, 0.300756259020529160f, 0.164938488846611775f },
+ { 0.523647061410313364f, 0.274206244923656473f, 0.143587294374629387f },
+ { 0.500000000000000000f, 0.250000000000000000f, 0.125000000000000000f },
+ { 0.477420801955208307f, 0.227930622139554201f, 0.108818820412015502f },
+ { 0.455861244279108402f, 0.207809474035696939f, 0.094732285406899888f },
+ { 0.435275281648062062f, 0.189464570813799776f, 0.082469244423305887f },
+ { 0.415618948071393879f, 0.172739109995972029f, 0.071793647187314694f },
+ { 0.396850262992049896f, 0.157490131236859149f, 0.062500000000000000f },
+ { 0.378929141627599553f, 0.143587294374629387f, 0.054409410206007751f },
+ { 0.361817309360094541f, 0.130911765352578369f, 0.047366142703449930f },
+ { 0.345478219991944002f, 0.119355200488802049f, 0.041234622211652958f },
+ { 0.329876977693223550f, 0.108818820412015502f, 0.035896823593657347f },
+ { 0.314980262473718298f, 0.099212565748012460f, 0.031250000000000000f },
+ { 0.300756259020529160f, 0.090454327340023621f, 0.027204705103003875f },
+ { 0.287174588749258719f, 0.082469244423305887f, 0.023683071351724965f },
+ { 0.274206244923656473f, 0.075189064755132290f, 0.020617311105826479f },
+ { 0.261823530705156682f, 0.068551561230914118f, 0.017948411796828673f },
+ { 0.250000000000000000f, 0.062500000000000000f, 0.015625000000000000f },
+ { 0.238710400977604098f, 0.056982655534888536f, 0.013602352551501938f },
+ { 0.227930622139554201f, 0.051952368508924235f, 0.011841535675862483f }
+};
diff --git a/libavcodec/eac3_data.h b/libavcodec/eac3_data.h
new file mode 100644
index 0000000..4d88ce0
--- /dev/null
+++ b/libavcodec/eac3_data.h
@@ -0,0 +1,36 @@
+/*
+ * E-AC-3 tables
+ * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_EAC3_DATA_H
+#define AVCODEC_EAC3_DATA_H
+
+#include <stdint.h>
+
+extern const uint8_t ff_eac3_bits_vs_hebap[20];
+extern const int16_t ff_eac3_gaq_remap_1[12];
+extern const int16_t ff_eac3_gaq_remap_2_4_a[9][2];
+extern const int16_t ff_eac3_gaq_remap_2_4_b[9][2];
+
+extern const int16_t (* const ff_eac3_mantissa_vq[8])[6];
+extern const uint8_t ff_eac3_frm_expstr[32][6];
+extern const float ff_eac3_spx_atten_tab[32][3];
+
+#endif /* AVCODEC_EAC3_DATA_H */
diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c
index 5400768..212f6b4 100644
--- a/libavcodec/eac3dec.c
+++ b/libavcodec/eac3dec.c
@@ -51,7 +51,7 @@
#include "ac3_parser.h"
#include "ac3dec.h"
#include "ac3dec_data.h"
-#include "eac3dec_data.h"
+#include "eac3_data.h"
/** gain adaptive quantization mode */
typedef enum {
diff --git a/libavcodec/eac3dec_data.c b/libavcodec/eac3dec_data.c
deleted file mode 100644
index 4cea26f..0000000
--- a/libavcodec/eac3dec_data.c
+++ /dev/null
@@ -1,1134 +0,0 @@
-/*
- * E-AC-3 decoder tables
- * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Tables taken directly from the E-AC-3 spec.
- */
-
-#include "eac3dec_data.h"
-#include "ac3.h"
-
-const uint8_t ff_eac3_bits_vs_hebap[20] = {
- 0, 2, 3, 4, 5, 7, 8, 9, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 14, 16,
-};
-
-/**
- * Table E3.6, Gk=1
- * No gain (Gk=1) inverse quantization, remapping scale factors
- * ff_eac3_gaq_remap[hebap+8]
- */
-const int16_t ff_eac3_gaq_remap_1[12] = {
- 4681, 2185, 1057, 520, 258, 129, 64, 32, 16, 8, 2, 0
-};
-
-/**
- * Table E3.6, Gk=2 & Gk=4, A
- * Large mantissa inverse quantization, remapping scale factors
- * ff_eac3_gaq_remap_2_4_a[hebap-8][Gk=2,4]
- */
-const int16_t ff_eac3_gaq_remap_2_4_a[9][2] = {
- { -10923, -4681 },
- { -14043, -6554 },
- { -15292, -7399 },
- { -15855, -7802 },
- { -16124, -7998 },
- { -16255, -8096 },
- { -16320, -8144 },
- { -16352, -8168 },
- { -16368, -8180 }
-};
-
-/**
- * Table E3.6, Gk=2 & Gk=4, B
- * Large mantissa inverse quantization, negative mantissa remapping offsets
- * ff_eac3_gaq_remap_3_4_b[hebap-8][Gk=2,4]
- */
-const int16_t ff_eac3_gaq_remap_2_4_b[9][2] = {
- { -5461, -1170 },
- { -11703, -4915 },
- { -14199, -6606 },
- { -15327, -7412 },
- { -15864, -7805 },
- { -16126, -7999 },
- { -16255, -8096 },
- { -16320, -8144 },
- { -16352, -8168 }
-};
-
-static const int16_t vq_hebap1[4][6] = {
-{ 7167, 4739, 1106, 4269, 10412, 4820},
-{ -5702, -3187, -14483, -1392, -2027, 849},
-{ 633, 6199, 7009, -12779, -2306, -2636},
-{ -1468, -7031, 7592, 10617, -5946, -3062},
-};
-static const int16_t vq_hebap2[8][6] = {
-{ -12073, 608, -7019, 590, 4000, 869},
-{ 6692, 15689, -6178, -9239, -74, 133},
-{ 1855, -989, 20596, -2920, -4475, 225},
-{ -1194, -3901, -821, -6566, -875, -20298},
-{ -2762, -3181, -4094, -5623, -16945, 9765},
-{ 1547, 6839, 1980, 20233, -1071, -4986},
-{ 6221, -17915, -5516, 6266, 358, 1162},
-{ 3753, -1066, 4283, -3227, 15928, 10186},
-};
-static const int16_t vq_hebap3[16][6] = {
-{ -10028, 20779, 10982, -4560, 798, -68},
-{ 11050, 20490, -6617, -5342, -1797, -1631},
-{ 3977, -542, 7118, -1166, 18844, 14678},
-{ -4320, -96, -7295, -492, -22050, -4277},
-{ 2692, 5856, 5530, 21862, -7212, -5325},
-{ -135, -23391, 962, 8115, -644, 382},
-{ -1563, 3400, -3299, 4693, -6892, 22398},
-{ 3535, 3030, 7296, 6214, 20476, -12099},
-{ 57, -6823, 1848, -22349, -5919, 6823},
-{ -821, -3655, -387, -6253, -1735, -22373},
-{ -6046, 1586, -18890, -14392, 9214, 705},
-{ -5716, 264, -17964, 14618, 7921, -337},
-{ -110, 108, 8, 74, -89, -50},
-{ 6612, -1517, 21687, -1658, -7949, -246},
-{ 21667, -6335, -8290, -101, -1349, -22},
-{ -22003, -6476, 7974, 648, 2054, -331},
-};
-static const int16_t vq_hebap4[32][6] = {
-{ 6636, -4593, 14173, -17297, -16523, 864},
-{ 3658, 22540, 104, -1763, -84, 6},
-{ 21580, -17815, -7282, -1575, -2078, -320},
-{ -2233, 10017, -2728, 14938, -13640, -17659},
-{ -1564, -17738, -19161, 13735, 2757, 2951},
-{ 4520, 5510, 7393, 10799, 19231, -13770},
-{ 399, 2976, -1099, 5013, -1159, 22095},
-{ 3624, -2359, 4680, -2238, 22702, 3765},
-{ -4201, -8285, -6810, -12390, -18414, 15382},
-{ -5198, -6869, -10047, -8364, -16022, -20562},
-{ -142, -22671, -368, 4391, -464, -13},
-{ 814, -1118, -1089, -22019, 74, 1553},
-{ -1618, 19222, -17642, -13490, 842, -2309},
-{ 4689, 16490, 20813, -15387, -4164, -3968},
-{ -3308, 11214, -13542, 13599, -19473, 13770},
-{ 1817, 854, 21225, -966, -1643, -268},
-{ -2587, -107, -20154, 376, 1174, -304},
-{ -2919, 453, -5390, 750, -22034, -978},
-{ -19012, 16839, 10000, -3580, 2211, 1459},
-{ 1363, -2658, -33, -4067, 1165, -21985},
-{ -8592, -2760, -17520, -15985, 14897, 1323},
-{ 652, -9331, 3253, -14622, 12181, 19692},
-{ -6361, 5773, -15395, 17291, 16590, -2922},
-{ -661, -601, 1609, 22610, 992, -1045},
-{ 4961, 9107, 11225, 7829, 16320, 18627},
-{ -21872, -1433, 138, 1470, -1891, -196},
-{ -19499, -18203, 11056, -516, 2543, -2249},
-{ -1196, -17574, 20150, 11462, -401, 2619},
-{ 4638, -8154, 11891, -15759, 17615, -14955},
-{ -83, 278, 323, 55, -154, 232},
-{ 7788, 1462, 18395, 15296, -15763, -1131},
-};
-static const int16_t vq_hebap5[128][6] = {
-{ -3394, -19730, 2963, 9590, 4660, 19673},
-{ -15665, -6405, 17671, 3860, -8232, -19429},
-{ 4467, 412, -17873, -8037, 691, -17307},
-{ 3580, 2363, 6886, 3763, 6379, -20522},
-{ -17230, -14133, -1396, -23939, 8373, -12537},
-{ -8073, -21469, -15638, 3214, 8105, -5965},
-{ 4343, 5169, 2683, -16822, -5146, -16558},
-{ 6348, -10668, 12995, -25500, -22090, 4091},
-{ -2880, -8366, -5968, -17158, -2638, 23132},
-{ -5095, -14281, -22371, 21741, 3689, 2961},
-{ -2443, -17739, 25155, 2707, 1594, 7},
-{ -18379, 9010, 4270, 731, -426, -640},
-{ -23695, 24732, 5642, 612, -308, -964},
-{ -767, 1268, 225, 1635, 173, 916},
-{ 5455, 6493, 4902, 10560, 23041, -17140},
-{ 17219, -21054, -18716, 4936, -3420, 3357},
-{ -1390, 15488, -21946, -14611, 1339, 542},
-{ -6866, -2254, -12070, -3075, -19981, -20622},
-{ -1803, 11775, 1343, 8917, 693, 24497},
-{ -21610, 9462, 4681, 9254, -7815, 15904},
-{ -5559, -3018, -9169, -1347, -22547, 12868},
-{ -366, 5076, -1727, 20427, -283, -2923},
-{ -1886, -6313, -939, -2081, -1399, 3513},
-{ -3161, -537, -5075, 11268, 19396, 989},
-{ 2345, 4153, 5769, -4273, 233, -399},
-{ -21894, -1138, -16474, 5902, 5488, -3211},
-{ 10007, -12530, 18829, 20932, -1158, 1790},
-{ -1165, 5014, -1199, 6415, -8418, -21038},
-{ 1892, -3534, 3815, -5846, 16427, 20288},
-{ -2664, -11627, -4147, -18311, -22710, 14848},
-{ 17256, 10419, 7764, 12040, 18956, 2525},
-{ -21419, -18685, -10897, 4368, -7051, 4539},
-{ -1574, 2050, 5760, 24756, 15983, 17678},
-{ -538, -22867, 11067, 10301, 385, 528},
-{ -8465, -3025, -16357, -23237, 16491, 3654},
-{ 5840, 575, 11890, 1947, 25157, 6653},
-{ 6625, -3516, -1964, 3850, -390, -116},
-{ 18005, 20900, 14323, -7621, -10922, 11802},
-{ -4857, -2932, -13334, -7815, 21622, 2267},
-{ -579, -9431, -748, -21321, 12367, 8265},
-{ -8317, 1375, -17847, 2921, 9062, 22046},
-{ 18398, 8635, -1503, -2418, -18295, -14734},
-{ -2987, 15129, -3331, 22300, 13878, -13639},
-{ 5874, -19026, 15587, 11350, -20738, 1971},
-{ 1581, -6955, -21440, 2455, 65, 414},
-{ 515, -4468, -665, -4672, 125, -19222},
-{ 21495, -20301, -1872, -1926, -211, -1022},
-{ 5189, -12250, -1775, -23550, -4546, 5813},
-{ 321, -6331, 14646, 6975, -1773, 867},
-{ -13814, 3180, 7927, 444, 19552, 3146},
-{ -6660, 12252, -1972, 17408, -24280, -12956},
-{ -745, 14356, -1107, 23742, -9631, -18344},
-{ 18284, -7909, -7531, 19118, 7721, -12659},
-{ 1926, 15101, -12848, 2153, 21631, 1864},
-{ -2130, 23416, 17056, -15597, -1544, 87},
-{ 8314, -11824, 14581, -20591, 7891, -2099},
-{ 19600, 22814, -17304, -2040, 285, -3863},
-{ -8214, -18322, 10724, -13744, -13469, -1666},
-{ 14351, 4880, -20034, 964, -4221, -180},
-{ -24598, -16635, 19724, 5925, 4777, 4414},
-{ -2495, 23493, -16141, 2918, -1038, -2010},
-{ 18974, -2540, 13343, 1405, -6194, -1136},
-{ 2489, 13670, 22638, -7311, -129, -2792},
-{ -13962, 16775, 23012, 728, 3397, 162},
-{ 3038, 993, 8774, -21969, -6609, 910},
-{ -12444, -22386, -2626, -5295, 19520, 9872},
-{ -1911, -18274, -18506, -14962, 4760, 7119},
-{ 8298, -2978, 25886, 7660, -7897, 1020},
-{ 6132, 15127, 18757, -24370, -6529, -6627},
-{ 7924, 12125, -9459, -23962, 5502, 937},
-{ -17056, -5373, 2522, 327, 1129, -390},
-{ 15774, 19955, -10380, 11172, -3107, 14853},
-{ -11904, -8091, -17928, -22287, -17237, -6803},
-{ -12862, -2172, -6509, 5927, 12458, -22355},
-{ -497, 322, 1038, -6643, -5404, 20311},
-{ 1083, -22984, -8494, 12130, -762, 2623},
-{ 5067, 19712, -1901, -30, -325, 85},
-{ 987, -5830, 4212, -9030, 9121, -25038},
-{ -7868, 7284, -12292, 12914, -21592, 20941},
-{ -1630, -7694, -2187, -8525, -5604, -25196},
-{ -6668, 388, -22535, 1526, 9082, 193},
-{ -7867, -22308, 5163, 362, 944, -259},
-{ 3824, -11850, 7591, -23176, 25342, 23771},
-{ -10504, 4123, -21111, 21173, 22439, -838},
-{ -4723, 21795, 6184, -122, 1642, -717},
-{ 24504, 19887, -2043, 986, 7, -55},
-{ -27313, -135, 2437, 259, 89, 307},
-{ 24446, -3873, -5391, -820, -2387, 361},
-{ 5529, 5784, 18682, 242, -21896, -4003},
-{ 22304, 4483, 722, -12242, 7570, 15448},
-{ 8673, 3009, 20437, 21108, -21100, -3080},
-{ -1132, 2705, -1825, 5420, -785, 18532},
-{ 16932, -13517, -16509, -14858, -20327, -14221},
-{ 2219, 1380, 21474, -1128, 327, 83},
-{ -2177, 21517, -3856, -14180, -204, -2191},
-{ 953, -9426, 15874, -10710, -3231, 21030},
-{ -421, -1377, 640, -8239, -20976, 2174},
-{ 4309, 18514, -9100, -18319, -15518, 3704},
-{ -5943, 449, -8387, 1075, -22210, -4992},
-{ 2953, 12788, 18285, 1430, 14937, 21731},
-{ -2913, 401, -4739, -20105, 1699, -1147},
-{ 3449, 5241, 8853, 22134, -7547, 1451},
-{ -2154, 8584, 18120, -15614, 19319, -5991},
-{ 3501, 2841, 5897, 6397, 8630, 23018},
-{ 2467, 2956, 379, 5703, -22047, -2189},
-{ -16963, -594, 18822, -5295, 1640, 774},
-{ 2896, -1424, 3586, -2292, 19910, -1822},
-{ -18575, 21219, -14001, -12573, 16466, 635},
-{ -1998, -19314, -16527, 12208, -16576, -7854},
-{ -9674, 1012, -21645, 2883, -12712, 2321},
-{ -1005, 471, -3629, 8045, -11087, 25533},
-{ 4141, -21472, -2673, 756, -663, -523},
-{ 6490, 8531, 19289, 18949, 6092, -9347},
-{ 16965, 24599, 14024, 10072, -536, -10438},
-{ -8147, 2145, -23028, -17073, 5451, -4401},
-{ -14873, 20520, -18303, -9717, -11885, -17831},
-{ -2290, -14120, 2070, 22467, 1671, 725},
-{ -8538, 14629, 3521, -20577, 6673, 8200},
-{ 20248, 4410, -1366, -585, 1229, -2449},
-{ 7467, -7148, 13667, -8246, 22392, -17320},
-{ -1932, 3875, -9064, -3812, 958, 265},
-{ -4399, 2959, -15911, 19598, 4954, -1105},
-{ 18009, -9923, -18137, -3862, 11178, 5821},
-{ -14596, -1227, 9660, 21619, 11228, -11721},
-{ -721, -1700, 109, -2142, 61, -6772},
-{ -24619, -22520, 5608, -1957, -1761, -1012},
-{ -23728, -4451, -2688, -14679, -4266, 9919},
-{ 8495, -894, 20438, -13820, -17267, 139},
-};
-static const int16_t vq_hebap6[256][6] = {
-{ 10154, 7365, 16861, 18681, -22893, -3636},
-{ -2619, -3788, -5529, -5192, -9009, -20298},
-{ -5583, -22800, 21297, 7012, 745, 720},
-{ 428, -1459, 109, -3082, 361, -8403},
-{ 8161, 22401, 241, 1755, -874, -2824},
-{ 1140, 12643, 2306, 22263, -25146, -17557},
-{ -2609, 3379, 10337, -19730, -15468, -23944},
-{ -4040, -12796, -25772, 13096, 3905, 1315},
-{ 4624, -23799, 13608, 25317, -1175, 2173},
-{ -97, 13747, -5122, 23255, 4214, -22145},
-{ 6878, -322, 18264, -854, -11916, -733},
-{ 17280, -12669, -9693, 23563, -16240, -1309},
-{ 5802, -4968, 19526, -21194, -24622, -183},
-{ 5851, -16137, 15229, -9496, -1538, 377},
-{ 14096, 25057, 13419, 8290, 23320, 16818},
-{ -7261, 118, -15867, 19097, 9781, -277},
-{ -4288, 21589, -13288, -16259, 16633, -4862},
-{ 4909, -19217, 23411, 14705, -722, 125},
-{ 19462, -4732, -1928, -11527, 20770, 5425},
-{ -27562, -2881, -4331, 384, -2103, 1367},
-{ -266, -9175, 5441, 26333, -1924, 4221},
-{ -2970, -20170, -21816, 5450, -7426, 5344},
-{ -221, -6696, 603, -9140, 1308, -27506},
-{ 9621, -8380, -1967, 9403, -1651, 22817},
-{ 7566, -5250, -4165, 1385, -990, 560},
-{ -1262, 24738, -19057, 10741, 7585, -7098},
-{ 451, 20130, -9949, -6015, -2188, -1458},
-{ 22249, 9380, 9096, 10959, -2365, -3724},
-{ 18668, -650, -1234, 11092, 7678, 5969},
-{ 19207, -1485, -1076, -731, -684, 43},
-{ -4973, 13430, 20139, 60, 476, -935},
-{ -20029, 8710, 2499, 1016, -1158, 335},
-{ -26413, 18598, -2201, -669, 3409, 793},
-{ -4726, 8875, -24607, -9646, 3643, -283},
-{ 13303, -21404, -3691, -1184, -1970, 1612},
-{ 173, 60, 919, 1229, 6942, -665},
-{ 16377, 16991, 5341, -14015, -2304, -20390},
-{ 25334, -10609, 11947, -7653, -6363, 14058},
-{ 23929, -13259, -7226, -937, 234, -187},
-{ 6311, -1877, 12506, -1879, 18751, -23341},
-{ 621, 6445, 3354, -24274, 8406, 5315},
-{ -3297, -5034, -4704, -5080, -25730, 5347},
-{ -1275, -13295, -965, -23318, 1214, 26259},
-{ -6252, 10035, -20105, 15301, -16073, 5136},
-{ 9562, -3911, -19510, 4745, 22270, -4171},
-{ 7978, -19600, 14024, -5745, -20855, 8939},
-{ 7, -4039, 991, -6065, 52, -19423},
-{ 3485, 2969, 7732, 7786, 25312, 6206},
-{ -959, -12812, -1840, -22743, 7324, 10830},
-{ -4686, 1678, -10172, -5205, 4294, -1271},
-{ 3889, 1302, 7450, 638, 20374, -3133},
-{ -12496, -9123, 18463, -12343, -7238, 18552},
-{ -6185, 8649, -6903, -895, 17109, 16604},
-{ -9896, 28579, 2845, 1640, 2925, -298},
-{ 14968, -25988, 14878, -24012, 1815, -6474},
-{ 26107, 5166, 21225, 15873, 21617, 14825},
-{ -21684, 16438, 20504, -14346, -7114, -4162},
-{ 28647, 90, -1572, 789, -902, -75},
-{ -1479, 2471, -4061, 3612, -2240, 10914},
-{ 8616, 17491, 17255, -17456, 17022, -16357},
-{ -20722, -18597, 25274, 17720, -3573, 1695},
-{ -997, 6129, -6303, 11250, -11359, -19739},
-{ -74, -4001, -1584, 13384, 162, -144},
-{ -529, 21068, 7923, -11396, 422, -26},
-{ 7102, -13531, -20055, 2629, -178, -429},
-{ 9201, 1368, -22238, 2623, -20499, 24889},
-{ -432, 6675, -266, 8723, 80, 28024},
-{ 19493, -3108, -9261, 1910, -21777, 5345},
-{ 14079, -11489, 12604, 6079, 19877, 1315},
-{ 10947, 9837, -18612, 15742, 4792, 605},
-{ -1777, 3758, -4087, 21696, 6024, -576},
-{ 3567, -3578, 16379, 2680, -1752, 716},
-{ -5049, -1399, -4550, -652, -17721, -3366},
-{ -3635, -4372, -6522, -22152, 7382, 1458},
-{ 12242, 19190, 5646, -7815, -20289, 21344},
-{ -7508, 19952, 23542, -9753, 5669, -1990},
-{ -2275, 15438, 10907, -17879, 6497, 13582},
-{ -15894, -15646, -4716, 6019, 24250, -6179},
-{ -2049, -6856, -1208, 918, 17735, -69},
-{ -3721, 9099, -16065, -23621, 5981, -2344},
-{ 7862, -8918, 24033, 25508, -11033, -741},
-{ -12588, 19468, 14649, 15451, -21226, 1171},
-{ 2102, 1147, 2789, 4096, 2179, 8750},
-{ -18214, -17758, -10366, -5203, -1066, -3541},
-{ -2819, -19958, -11921, 6032, 8315, 10374},
-{ -9078, -2100, 19431, -17, 732, -689},
-{ -14512, -19224, -7095, 18727, 1870, 22906},
-{ 3912, 659, 25597, -4006, 9619, 877},
-{ 2616, 22695, -5770, 17920, 3812, 20220},
-{ 2561, 26847, -5245, -10908, 2256, -517},
-{ -4974, 198, -21983, -3608, 22174, -18924},
-{ 21308, -1211, 19144, 16691, -1588, 11390},
-{ -1790, 3959, -3488, 7003, -7107, 20877},
-{ -6108, -17955, -18722, 24763, 16508, 3211},
-{ 20462, -24987, -20361, 4484, -5111, -478},
-{ -6378, -1998, -10229, -561, -22039, -22339},
-{ 3047, -18850, 7586, 14743, -19862, 6351},
-{ -5047, 1405, -9672, 1055, -21881, 11170},
-{ 3481, -9699, 6526, -16655, 22813, 21907},
-{ -18570, 17501, 14664, 1291, 5026, 19676},
-{ 16134, -19810, -16956, -17939, -16933, 5800},
-{ -8224, 4908, 8935, 2272, -1140, -23217},
-{ 1572, 2753, -1598, 2143, -3346, -21926},
-{ -9832, -1060, -27818, 1214, 7289, 150},
-{ 98, 1538, 535, 17429, -23198, -901},
-{ 21340, -20146, 3297, -1744, -8207, -21462},
-{ -4166, -4633, -17902, 5478, 1285, 136},
-{ 18713, 21003, 24818, 11421, 1282, -4618},
-{ -3535, 7636, -265, 2141, -829, -2035},
-{ -3184, 19713, 2775, -2, 1090, 104},
-{ -6771, -20185, 2938, -2125, -36, 1268},
-{ 9560, 9430, 9586, 22100, 13827, 6296},
-{ -535, -20018, 4276, -1868, -448, -17183},
-{ -24352, 14244, -13647, -21040, 2271, 11555},
-{ -2646, 15437, -4589, 18638, -4299, -622},
-{ -20064, 4169, 18115, -1404, 13722, -1825},
-{ -16359, 9080, 744, 22021, 125, 10794},
-{ 9644, -14607, -18479, -14714, 11174, -20754},
-{ -326, -23762, 6144, 7909, 602, 1540},
-{ -6650, 6634, -12683, 21396, 20785, -6839},
-{ 4252, -21043, 5628, 18687, 23860, 8328},
-{ 17986, 5704, -5245, -18093, -555, 3219},
-{ 6091, 14232, -5117, -17456, -19452, -11649},
-{ -21586, 11302, 15434, 25590, 6777, -26683},
-{ 21355, -8244, 5877, -3540, 6079, -2567},
-{ 2603, -2455, 5421, -12286, -19100, 5574},
-{ -1721, -26393, -23664, 22904, -349, 3787},
-{ 2189, -1203, 5340, 3249, -22617, 104},
-{ -1664, -11020, -2857, -20723, -24049, 19900},
-{ 22873, -7345, -18481, -14616, -8400, -12965},
-{ 3777, 3958, 8239, 20494, -6991, -1201},
-{ -160, -1613, -793, -8681, 573, 776},
-{ 4297, -3786, 20373, 6082, -5321, -18400},
-{ 18745, 2463, 12546, -7749, -7734, -2183},
-{ 11074, -4720, 22119, 1825, -24351, 4080},
-{ 1503, -19178, -1569, 13, -313, 375},
-{ 318, -575, 2544, 178, 102, 40},
-{ -15996, -26897, 5008, 3320, 686, 1159},
-{ 25755, 26886, 574, -5930, -3916, 1407},
-{ -9148, -7665, -2875, -8384, -18663, 26400},
-{ -7445, -18040, -18396, 8802, -2252, -21886},
-{ 7851, 11773, 27485, -12847, -1410, 19590},
-{ 2240, 5947, 11247, 15980, -6499, 24280},
-{ 21673, -18515, 9771, 6550, -2730, 334},
-{ -4149, 1576, -11010, 89, -24429, -5710},
-{ 7720, 1478, 21412, -25025, -8385, 9},
-{ -2448, 10218, -12756, -16079, 1161, -21284},
-{ -8757, -14429, -22918, -14812, 2629, 13844},
-{ -7252, 2843, -9639, 2882, -14625, 24497},
-{ -674, -6530, 414, -23333, -21343, 454},
-{ 2104, -6312, 10887, 18087, -1199, 175},
-{ -493, -562, -2739, 118, -1074, 93},
-{ -10011, -4075, -28071, 22180, 15077, -636},
-{ -4637, -16408, -9003, -20418, -11608, -20932},
-{ 4815, 15892, 24238, -13634, -3074, -1059},
-{ -6724, 4610, -18772, -15283, -16685, 23988},
-{ 15349, -674, -3682, 21679, 4475, -12088},
-{ 4756, 2593, 5354, 6001, 15063, 26490},
-{ -23815, -17251, 6944, 378, 694, 670},
-{ 23392, -8839, -14713, 7544, -876, 11088},
-{ 3640, 3336, 22593, -3495, -2328, -113},
-{ 284, 6914, 3097, 10171, 6638, -18621},
-{ 2472, 5976, 11054, -11936, -603, -663},
-{ 16175, 16441, 13164, -4043, 4667, 7431},
-{ 19338, 15534, -6533, 1681, -4857, 17048},
-{ 17027, 532, -19064, -1441, -5130, 1085},
-{ -12617, -17609, 2062, -25332, 19009, -16121},
-{ 10056, -21000, -13634, -2949, 15367, 19934},
-{ -648, -1605, 10046, -1592, 13296, 19808},
-{ -1054, 10744, 538, 24938, 9630, -9052},
-{ -10099, 3042, -25076, -24052, 13971, 100},
-{ 6547, 6907, 7031, 10348, 23775, -17886},
-{ -22793, -1984, -1393, -3330, 9267, 14317},
-{ -14346, -3967, 3042, 16254, -17303, 9646},
-{ -21393, 23628, 16773, 716, 2663, 114},
-{ -19016, -3038, 1574, -245, 1463, -793},
-{ 22410, 23441, -14637, -530, 17310, 13617},
-{ -11582, 7935, -13954, 23465, -24628, 26550},
-{ -1045, 3679, -2218, 10572, 20999, -3702},
-{ -15513, 197, 16718, -24603, 4945, 5},
-{ 10781, 4335, 26790, -9059, -16152, -2840},
-{ 16075, -24100, -3933, -6833, 12645, -7029},
-{ 2096, -25572, -8370, 6814, 11, 1178},
-{ -11848, -583, -8889, -20543, -10471, -380},
-{ -2487, 24777, -21639, -19341, 1660, -732},
-{ 2313, 13679, 4085, 24549, 24691, -21179},
-{ -2366, -504, -4130, -10570, 23668, 1961},
-{ 20379, 17809, -9506, 3733, -18954, -6292},
-{ -3856, 16802, -929, -20310, -17739, 6797},
-{ 12431, 6078, -11272, -14450, 6913, 23476},
-{ 7636, -1655, 23017, 10719, -8292, 838},
-{ -8559, -1235, -18096, 3897, 16093, 1490},
-{ -3586, 8276, 15165, -3791, -21149, 1741},
-{ -4497, 21739, 2366, -278, -4792, 15549},
-{ -23122, -13708, 7668, 16232, 24120, 15025},
-{ -20043, 12821, -20160, 16691, -11655, -16081},
-{ -12601, 20239, 3496, -2549, -6745, -11850},
-{ 4441, 7812, 20783, 17080, 11523, -9643},
-{ 24766, 8494, -23298, -3262, 11101, -7120},
-{ -10107, -7623, -22152, -18303, 26645, 9550},
-{ -25549, 477, 7874, -1538, 1123, -168},
-{ 470, 9834, -347, 23945, -10381, -9467},
-{ -4096, -9702, -6856, -21544, 20845, 7174},
-{ 5370, 9748, -23765, -1190, 512, -1538},
-{ -1006, -10046, -12649, 19234, -1790, -890},
-{ 15108, 23620, -15646, -2522, -1203, -1325},
-{ -7406, -2605, 1095, -247, -473, 177},
-{ 8089, 4, 12424, -22284, 10405, -7728},
-{ 22196, 10775, -5043, 690, 534, -212},
-{ -3153, -1418, -16835, 18426, 15821, 22956},
-{ 5681, -2229, 3196, -3414, -21817, -14807},
-{ 19, 787, 1032, 170, -8295, -645},
-{ -882, -2319, -27105, 432, -4392, 1499},
-{ -1354, -11819, -76, -20380, -10293, 11328},
-{ 211, -4753, -4675, -6933, -13538, 14479},
-{ 6043, 5260, -459, -462, 143, -65},
-{ -2572, 7256, -3317, 9212, -23184, -9990},
-{ -24882, -9532, 18874, 6101, 2429, -14482},
-{ 8314, 2277, 14192, 3512, 25881, 22000},
-{ 208, 20218, -281, -24778, -63, -1183},
-{ 1095, -6034, 2706, -21935, -2655, 563},
-{ 23, -5930, 243, -8989, 5345, 20558},
-{ -15466, 12699, 4160, 11087, 20621, -10416},
-{ 20995, -85, -8468, 194, 1003, -9515},
-{ -19637, -3335, -14081, 3574, -23381, -667},
-{ -2076, 3489, -3192, -19367, 539, -1530},
-{ 7352, -15213, 22596, 19369, 1043, 16627},
-{ -1872, -413, 1235, -5276, -3550, 21903},
-{ 7931, -2008, 16968, -6799, 29393, -2475},
-{ -13589, 8389, -23636, -22091, -14178, -14297},
-{ -11575, -20090, 16056, -1848, 15721, 4500},
-{ 3849, -16581, 20161, -21155, 7778, 11864},
-{ -6547, -1273, -18837, -11218, 11636, 1044},
-{ 2528, -6691, -17917, -11362, -4894, -1008},
-{ 1241, 4260, 2319, 6111, 3485, 20209},
-{ 3014, -3048, 5316, -4539, 20831, 8702},
-{ -1790, -14683, 278, 13956, -10065, -10547},
-{ -22732, -7957, -1154, 13821, -1484, -1247},
-{ -7317, -615, 13094, 18927, 9897, 1452},
-{ 2552, -2338, 3424, -4630, 11124, -19584},
-{ -11125, -20553, -10855, -10783, -20767, 6833},
-{ 984, -15095, 5775, 25125, 5377, -19799},
-{ 517, 13272, -7458, -1711, 20612, -6013},
-{ -21417, 13251, -20795, 13449, 17281, 13104},
-{ -15811, -16248, 23093, -4037, -8195, 871},
-{ 582, 12571, -21129, -14766, -9187, 5685},
-{ 4318, -1776, 11425, -17763, -9921, 577},
-{ 6013, 16830, 17655, -25766, -4400, -3550},
-{ -13744, -16541, 3636, -3330, -21091, -15886},
-{ 6565, -11147, 8649, -13114, 23345, -13565},
-{ -2542, -9046, -7558, 29240, 3701, -383},
-{ -10612, 24995, 1893, -8210, 20920, -16210},
-{ 5276, 16726, 10659, 19940, -4799, -19324},
-{ -532, -9300, 27856, 4965, -241, 536},
-{ -765, -20706, -3412, 18870, 2765, 1420},
-{ -3059, 2708, -19022, -331, 3537, 116},
-};
-static const int16_t vq_hebap7[512][6] = {
-{ -21173, 21893, 10390, 13646, 10718, -9177},
-{ -22519, -8193, 18328, -6629, 25518, -10848},
-{ 6800, -13758, -13278, 22418, 14667, -20938},
-{ 2347, 10516, 1125, -3455, 5569, 27136},
-{ -6617, 11851, -24524, 22937, 20362, -6019},
-{ -21768, 10681, -19615, -15021, -8478, -2081},
-{ -2745, 8684, -4895, 27739, 7554, -11961},
-{ -1020, 2460, -954, 4754, -627, -16368},
-{ -19702, 23097, 75, -13684, -2644, 2108},
-{ 4049, -2872, 5851, -4459, 22150, 12560},
-{ -21304, -17129, -730, 7419, -11658, -10523},
-{ 11332, 1792, 26666, 23518, -19561, -491},
-{ -17827, -16777, -13606, -14389, -22029, -2464},
-{ 1091, -5967, -7975, -16977, -20432, -21931},
-{ 18388, -1103, 1933, 13342, -17463, 18114},
-{ 22646, 17345, -9966, 17919, 18274, 698},
-{ 1484, 20297, -5754, -26515, 4941, -22263},
-{ -2603, 4587, -5842, 18464, 8767, -2568},
-{ -2797, -1602, 21713, 3099, -25683, 3224},
-{ -19027, 4693, -5007, 6060, 1972, -15095},
-{ -2189, 9516, -530, 20669, -4662, -8301},
-{ -22325, -8887, 2529, -11352, 5476, 998},
-{ 22100, -5052, 1651, -2657, 4615, 2319},
-{ 20855, -3078, -3330, 4105, 13470, 3069},
-{ 85, 17289, 10264, -14752, 214, 90},
-{ -26365, -18849, -19352, 19244, -10218, 9909},
-{ -9739, 20497, -6579, -6983, 2891, -738},
-{ 20575, -15860, -22913, 6870, 76, 327},
-{ 8744, -12877, -22945, -2372, -19424, -9771},
-{ -12886, 16183, 21084, 3821, 749, -13792},
-{ -15995, 18399, 2391, -17661, 19484, -6018},
-{ 1423, 11734, 4051, 19290, 6857, -19681},
-{ -5200, 9766, 18246, 2463, 18764, -4852},
-{ -597, 19498, 1323, -9096, -308, -1104},
-{ -3099, -25731, -15665, 25332, 4634, 2635},
-{ 19623, -2384, -7913, 11796, -9333, -14084},
-{ 2642, 26453, -21091, -10354, -1693, -1711},
-{ 22031, 21625, 11580, -22915, -4141, 129},
-{ -6122, 3542, 915, -261, -17, -383},
-{ 1696, 6704, -1425, 20838, 857, -4416},
-{ 1423, -15280, -8550, -9667, 5210, 5687},
-{ -4520, -613, -11683, 5618, 4230, 619},
-{ 937, -4963, -14102, -17104, -6906, -5952},
-{ -15068, -481, -7237, -14894, 18876, 21673},
-{ -25658, 2910, 1143, -327, -458, -995},
-{ -9656, -819, -24900, 2804, 20225, 1083},
-{ -1111, -3682, -1788, -19492, 966, 821},
-{ 7293, -21759, 10790, -7059, -23293, -1723},
-{ -282, -11093, 170, -20950, -28926, 12615},
-{ 17938, 3713, -1563, 885, 5, 564},
-{ 6116, 22696, 2242, -6951, 9975, -6132},
-{ 4338, 26808, -3705, 1976, -1079, -2570},
-{ -661, -7901, -2668, -15194, 17722, 4375},
-{ -4174, -11053, 717, -22506, 1562, 12252},
-{ -6405, 18334, 6103, 6983, 5956, 18195},
-{ 9851, 5370, 23604, -6861, -6569, -62},
-{ 21964, 13359, -683, 3785, 2168, 209},
-{ -3569, -1127, -19724, -1544, 1308, -803},
-{ -3083, 16049, -13791, -3077, 4294, 23713},
-{ -9999, 9943, -15872, 12934, -23631, 21699},
-{ 9722, 22837, 12192, 15091, 5533, 4837},
-{ 2243, 2099, 1243, 4089, 4748, 12956},
-{ 4007, -2468, 3353, -3092, 8843, 17024},
-{ 4330, 6127, 5549, 9249, 11226, 28592},
-{ -9586, -8825, 236, 1009, 455, -964},
-{ 6829, 19290, -1018, 200, 1821, 578},
-{ 5196, 957, 10372, 3330, -12800, -127},
-{ -3022, -8193, -14557, 22061, 5920, 1053},
-{ 10982, 25942, -24546, -23278, -11905, -6789},
-{ 22667, -11010, 5736, 2567, 23705, -10253},
-{ -3343, -4233, -5458, 20667, -10843, -3605},
-{ -4131, -3612, 4575, -829, -350, -847},
-{ -3303, 3451, -7398, -11604, 3023, 455},
-{ 3200, -9547, 3202, -22893, 11184, -26466},
-{ -14093, -4117, 15382, 14295, -10915, -20377},
-{ 3807, -11016, 22052, 14370, -15328, -7733},
-{ -6291, -17719, -1560, 12048, -19805, -443},
-{ -6147, -4234, -160, 8363, 22638, 11911},
-{ 19197, 1175, 7422, -9875, -4136, 4704},
-{ -72, -7652, -112, -11955, -3230, 27175},
-{ 3274, 5963, 7501, -17019, 866, -25452},
-{ 737, 1861, 1833, 2022, 2384, 4755},
-{ -5217, 7512, 3323, 2715, 3065, -1606},
-{ 4247, 565, 5629, 2497, 18019, -4920},
-{ -2833, -17920, -8062, 15738, -1018, 2136},
-{ 3050, -19483, 16930, 29835, -10222, 15153},
-{ -11346, 118, -25796, -13761, 15320, -468},
-{ -4824, 4960, -4263, 1575, -10593, 19561},
-{ -8203, -1409, -763, -1139, -607, 1408},
-{ -2203, -11415, 2021, -6388, -2600, 711},
-{ -413, -2511, -216, -3519, -28267, 1719},
-{ -14446, 17050, 13917, 13499, -25762, -16121},
-{ 19228, 7341, -12301, 682, -3791, -199},
-{ -4193, 20746, -15651, 11349, 5860, -824},
-{ -21490, -3546, -3, -1705, -3959, 9213},
-{ 15445, -1876, 2012, -19627, 16228, -4845},
-{ -2867, -3733, -7354, -175, -20119, 11174},
-{ -3571, -24587, 19700, 6654, 979, -654},
-{ 21820, -7430, -6639, -10767, -8362, 15543},
-{ 14827, 17977, -7204, -3409, 1906, -17288},
-{ 3525, -3947, -1415, -2798, 17648, 2082},
-{ -6580, -15255, -17913, 1337, 15338, 21158},
-{ 6210, 9698, 15155, -24666, -22507, -3999},
-{ -1740, -593, 1095, -7779, 25058, 5601},
-{ 21415, -432, -1658, -6898, -1438, -14454},
-{ -6943, 700, -12139, -745, -24187, 22466},
-{ 6287, 3283, 11006, 3844, 19184, 14781},
-{ -22502, 15274, 5443, -2808, -970, -3343},
-{ 3257, -3708, 4744, -8301, 22814, -10208},
-{ 24346, -20970, 19846, 987, -11958, -6277},
-{ 3906, -19701, 13060, -1609, 18641, 7466},
-{ -26409, -22549, 16305, 2014, 10975, 18032},
-{ -7039, 4655, -14818, 18739, 15789, 1296},
-{ 9310, -1681, 14667, -3326, 26535, -11853},
-{ 5728, 5917, 13400, 10020, -2236, -24704},
-{ 1741, -6727, 12695, -22009, 4080, 5450},
-{ -2621, 9393, 21143, -25938, -3162, -2529},
-{ 20672, 18894, -13939, 6990, -8260, 15811},
-{ -23818, 11183, -13639, 11868, 16045, 2630},
-{ 18361, -10220, 829, 856, -1010, 157},
-{ 14400, -4678, 5153, -13290, -27434, -11028},
-{ 21613, 11256, 17453, 7604, 13130, -484},
-{ 7, 1236, 573, 4214, 5576, -3081},
-{ 916, -9092, 1285, -8958, 1185, -28699},
-{ 21587, 23695, 19116, -2885, -14282, -8438},
-{ 23414, -6161, 12978, 3061, -9351, 2236},
-{ -3070, -7344, -20140, 5788, 582, -551},
-{ -3993, 315, -7773, 8224, -28082, -12465},
-{ 13766, -15357, 19205, -20624, 13043, -19247},
-{ 3777, -177, 8029, -1001, 17812, 5162},
-{ -7308, -4327, -18096, -620, -1350, 14932},
-{ 14756, -1221, -12819, -14922, -547, 27125},
-{ 2234, 1708, 2764, 5416, 7986, -25163},
-{ 2873, 3636, 3992, 5344, 10142, 21259},
-{ 1158, 5379, 508, -10514, 290, -1615},
-{ 1114, 24789, 16575, -25168, -298, -2832},
-{ -1107, -6144, -1918, -7791, -2971, -23276},
-{ 4016, 10793, 17317, -4342, -20982, -3383},
-{ -4494, -207, -9951, -3575, 7947, 1154},
-{ -7576, 8117, -14047, 16982, -26457, -27540},
-{ -15164, 16096, -16844, -8886, -23720, 15906},
-{ 24922, 5680, -1874, 420, 132, 117},
-{ -506, -19310, -198, 412, -311, 752},
-{ -1906, 3981, -7688, 16566, -19291, -14722},
-{ -399, -729, -3807, -4196, -12395, 7639},
-{ 3368, 2330, 9092, 23686, -10290, -1705},
-{ -3148, 2596, -7986, 14602, -4807, 16627},
-{ 8057, 1481, 49, 17205, 24869, 7474},
-{ -19304, -513, 11905, 2346, 5588, 3365},
-{ -5063, -21812, 11370, 10896, 4881, 261},
-{ 4794, 20577, 5109, -6025, -8049, -1521},
-{ 8125, -14756, 20639, -14918, 23941, -3650},
-{ 12451, 1381, 3613, 8687, -24002, 4848},
-{ 6726, 10643, 10086, 25217, -25159, -1065},
-{ 6561, 13977, 2911, 21737, 16465, -26050},
-{ -1776, 2575, -19606, -16800, 3032, 6679},
-{ 15012, -17910, -8438, -21554, -27111, 11808},
-{ 3448, -924, -15913, -1135, 5126, -20613},
-{ 7720, 2226, 17463, 5434, 28942, 17552},
-{ 1246, 15614, -11743, 24618, -17539, 3272},
-{ 3215, 17950, 2783, -722, -22672, 5979},
-{ -5678, -3184, -26087, 26034, 6583, 3302},
-{ 20310, -3555, -2715, -444, -1487, 1526},
-{ -20640, -21970, -12207, -25793, 8863, -1036},
-{ 17888, 570, -16102, 8329, -2553, 15275},
-{ -2677, 9950, -1879, 16477, -12762, -29007},
-{ -120, -2221, 219, 97, 365, 35},
-{ 1270, -718, 1480, -2689, 1930, -7527},
-{ 1896, 8750, 1906, 18235, -12692, -6174},
-{ -3733, 13713, -9882, -15960, -1376, -7146},
-{ -10600, 8496, 15967, -8792, 7532, 20439},
-{ 3041, -13457, 1032, -26952, 5787, 24984},
-{ -4590, -8220, -9322, -6112, -17243, 25745},
-{ -17808, 6970, 3752, 626, -114, 2178},
-{ 4449, -4862, 7054, -5404, 4738, -2827},
-{ 4922, -651, 18939, -9866, 848, 1886},
-{ -336, -5410, 7234, 20444, -9583, -600},
-{ 781, -19474, -12648, 6634, 1414, 450},
-{ -3399, -16770, 11107, 13200, -5498, 21663},
-{ -3265, 4859, -5961, 7530, -10837, 28086},
-{ 10350, -12901, 25699, 25640, -639, 351},
-{ 1163, 18763, -5466, -15087, -145, -1377},
-{ -14477, 27229, -31383, -32653, 21439, -2894},
-{ 15420, 18823, 22128, 19398, 22583, 13587},
-{ -10674, 10710, 5089, -4756, 909, -20760},
-{ -12948, -20660, 7410, 2722, 3427, 11585},
-{ -1105, 18374, 19731, -9650, 22442, 19634},
-{ -296, -6798, -14677, 21603, 19796, 21399},
-{ -19350, -7501, 25446, 13144, 8588, -25298},
-{ 3092, -10618, 20896, 9249, -3326, 1796},
-{ -811, 1449, 3106, 4748, 12073, -14262},
-{ -20720, 14275, -4332, -25838, -5781, -21149},
-{ -5132, 10554, -14020, -22150, 2840, -554},
-{ 25533, 17648, 14886, -21074, 2459, 25142},
-{ -9370, -1788, -12862, -5870, -25811, -11023},
-{ 6698, 819, 10313, 166, 27581, 523},
-{ 101, -19388, 3413, 9638, 64, 806},
-{ -2742, -17931, -2576, 22818, 8553, 1126},
-{ 2972, 15203, 1792, 25434, -5728, -17265},
-{ -1419, 1604, 4398, 11452, 1731, 23787},
-{ -5136, 4625, -10653, 27981, 9897, -2510},
-{ -10528, -28033, 2999, -1530, -832, -830},
-{ -11133, -12511, 22206, -7243, -23578, -21698},
-{ 16935, -21892, 1861, -9606, 9432, 19026},
-{ 10277, 9516, 26815, 2010, -4943, -9080},
-{ 5547, -2210, 14270, -15300, -19316, 1822},
-{ -4850, -783, -8959, -3076, -20056, -3197},
-{ 8232, -2794, -17752, 13308, 3229, -991},
-{ -12237, -6581, 10315, -9552, 2260, -20648},
-{ -7000, 5529, -7553, -7490, -10342, -10266},
-{ 3641, 19479, -5972, -19097, -18570, 12805},
-{ 1283, -4164, 4198, -28473, -2498, 1866},
-{ 16047, 26826, -13053, -6316, 985, -1597},
-{ -403, 13680, 6457, 25070, 27124, -20710},
-{ -18070, -1790, -24986, 5953, -954, 26600},
-{ -24224, -15383, 24788, 1953, -1136, 187},
-{ -2289, 12505, -20738, -904, 18324, 21258},
-{ 2658, -6140, 16179, 22276, -556, 2154},
-{ -6087, 13950, -25682, -27713, 4049, -4795},
-{ -21452, 26473, 19435, -9124, 895, 303},
-{ -22200, -26177, -6026, 24729, -22926, -9030},
-{ -14276, -15982, 23732, -22851, 9268, -3841},
-{ 29482, 21923, -6213, 1679, -2059, -1120},
-{ -435, 9802, -3891, 12359, -4288, -18971},
-{ 19768, -86, 2467, 1990, -1021, -5354},
-{ 20986, -8783, -5329, -23562, -4730, 2673},
-{ -5095, 5605, -4629, 19150, 26037, -12259},
-{ 972, 6858, 4551, 27949, -4025, -2272},
-{ 6075, -3260, -4989, -373, -1571, -3730},
-{ -7256, -12992, -8820, -5109, 23054, 5054},
-{ 920, 2615, 7912, -7353, -4905, 20186},
-{ -250, 5454, 3140, 6928, -18723, -2051},
-{ -10299, -4372, 19608, 4879, -661, -1885},
-{ 14816, -8603, -19815, 6135, -21210, 14108},
-{ -11945, -2223, 5018, 11892, 22741, 406},
-{ -13184, -2613, -13256, -22433, -12482, -8380},
-{ 17066, 25267, -2273, 5056, -342, 145},
-{ 8401, -17683, 19112, 10615, -19453, 17083},
-{ 20821, -5700, 12298, -25598, 10391, 7692},
-{ 4550, 15779, 17338, -19379, -4768, 1206},
-{ -7723, 10836, -27164, -11439, 6835, -1776},
-{ 2542, 3199, 4442, 17513, -3711, -914},
-{ 20960, -16774, -5814, 11087, -70, 22961},
-{ 3305, 2919, 6256, -4800, -20966, -3230},
-{ 5924, -16547, 2183, 2733, 3446, -23306},
-{ -6061, -194, -13852, -10971, 19488, 1029},
-{ 4467, -5964, -19004, 1519, -359, 855},
-{ -1581, -7607, 22070, -11580, -10032, 17102},
-{ -12412, 2553, 4324, 22500, 5751, 12170},
-{ -25127, 17996, -6384, 1180, 1182, 9622},
-{ 23462, -8471, -4392, -2669, 7638, -16835},
-{ -5511, -2887, -10757, -20883, 7246, 1053},
-{ 2703, -20602, -7554, 7516, -7740, 5868},
-{ 20670, 21901, 457, 14969, -17657, -11921},
-{ 3603, -1595, -2177, -157, -43, 605},
-{ 2513, 8954, 10527, 22559, -16100, -16041},
-{ 6002, 4951, 6795, -4862, -22400, 18849},
-{ 7590, -1693, -24688, -3404, 14169, 1214},
-{ -4398, -6663, -6870, -10083, -24596, 9253},
-{ 10468, 17751, -7748, 147, -6314, 4419},
-{ 16187, -16557, -4119, 4302, 7625, 5409},
-{ 3303, 2735, 7458, -19902, -2254, -3702},
-{ -2077, 21609, 14870, 12545, -6081, -1764},
-{ 4678, 11740, 2859, 6953, 1919, -3871},
-{ 3522, -21853, -2469, -10453, 18893, -10742},
-{ 3759, -10191, -4866, -2659, -17831, -1242},
-{ 14991, 9351, 11870, -1573, -4848, 22549},
-{ 9509, -27152, 10734, 20851, -26185, -17878},
-{ -7170, -1392, -19495, 12746, 8198, -1988},
-{ 1883, 28158, -846, -7235, 249, 233},
-{ -7200, 669, -371, -2948, 23234, -5635},
-{ 3141, 288, 3223, -1258, -98, -27607},
-{ 17373, -23235, 5110, -11199, -2574, -11487},
-{ -4928, 1518, -5456, 670, -18278, 1951},
-{ 10334, -19865, -4649, 361, -160, -923},
-{ 18732, 14264, -3155, -7485, -3328, 5959},
-{ -3614, 21077, 7276, 3536, 8121, -1528},
-{ -8422, 500, -19182, 18929, 26392, -1039},
-{ 15639, 25668, 8375, 1903, 1945, -11979},
-{ -2716, 3389, 26850, -4587, 1803, 22},
-{ 1177, -655, 1233, -2128, 7844, 1767},
-{ -761, 8209, -19290, -4593, 1923, -343},
-{ -689, -3530, -3267, -3804, -2753, 18566},
-{ -2110, 1962, -1353, 16643, 2765, -23102},
-{ -433, 4905, 302, 13016, 15933, -5905},
-{ 3203, 4126, 11181, -5496, -2529, -1160},
-{ -1091, -6469, -1415, 5682, -268, 583},
-{ -9405, -19572, 6216, 1658, 993, -75},
-{ -1695, -4504, -2289, -4088, -6556, -16577},
-{ 4760, -892, -10902, 6516, 24199, -6011},
-{ -253, 1000, 63, -81, -115, -382},
-{ -1333, 24224, -698, -4667, -2801, -19144},
-{ -876, -28866, -21873, 12677, -6344, 3235},
-{ 16847, 21145, -26172, -3183, -396, 230},
-{ 18296, -7790, -12857, -679, -1473, 5},
-{ -10488, 11429, 25805, -1122, 1401, -438},
-{ 3782, -7429, 26720, 17567, 19257, 12542},
-{ 6332, -746, 12789, 9316, -22542, -5354},
-{ 3418, -22728, 26978, 18303, 1076, 956},
-{ -27315, -2988, 920, 235, 2233, 81},
-{ 6199, 5296, 16093, 14768, -8429, -1112},
-{ -6432, 19244, 9921, -3253, 1278, -954},
-{ 24213, 2049, -22931, 2585, -2410, -4216},
-{ 9286, 14282, -19735, -3985, -2344, 1028},
-{ -20128, 17993, -9458, 23012, -16983, 8625},
-{ -6896, -20730, 3762, 17415, 22341, 19024},
-{ 842, 24181, 25062, -5839, -78, 937},
-{ -621, 19722, -24204, -1962, -14854, -56},
-{ 22766, -5119, 17365, 23868, -19480, -6558},
-{ -2158, 17490, -21435, 3340, -12819, -20295},
-{ -9621, 17325, 715, 2265, -4123, -492},
-{ 9156, 12947, 27303, -21175, -6072, -9457},
-{ -13164, -23269, -14006, -4184, 6978, 2},
-{ 938, -13381, 3520, -24297, 22902, 19589},
-{ -4911, -19774, 19764, -9310, -12650, 3819},
-{ -5462, -4249, -6987, -6260, -13943, -25150},
-{ 9341, 10369, -13862, -6704, 22556, -519},
-{ 6651, 18768, -4855, 12570, 14730, -10209},
-{ -823, 18119, 398, -1582, -116, -363},
-{ -6935, -12694, -28392, 8552, 6961, -239},
-{ -2602, -4704, -1021, 2015, 5129, 23670},
-{ -12559, -8190, -25028, 18544, 14179, 1663},
-{ 3813, 21036, -9620, -5051, -1800, -1087},
-{ -22057, 16675, 14960, 9459, 2786, 16991},
-{ -26040, -19318, -6414, 1104, 5798, -18039},
-{ -1737, 24825, 10417, -11087, 896, -5273},
-{ -1855, 11661, -2803, 24809, -21435, -19792},
-{ -23473, -16729, -5782, 5643, 2636, 4940},
-{ -1724, 4388, -26673, -13695, 10570, -25895},
-{ 15358, -19496, 26242, -18493, 1736, 8054},
-{ 5684, 20890, 4091, -19100, -14588, -10468},
-{ 17260, -16291, 14859, -17711, -19174, 12435},
-{ -27185, -12573, 6743, -562, 976, -257},
-{ 12395, -8618, -22248, -19843, 11013, 7762},
-{ 3799, 11853, -27622, -8473, 1089, -1495},
-{ 4141, -2182, -26720, -735, -774, 1469},
-{ 3125, 13762, 4606, 29257, 18771, -9958},
-{ -17465, -9445, -17562, -2530, -6435, -3726},
-{ -1742, 4351, -6841, -19773, 9627, -10654},
-{ 7251, 3525, 10835, 5601, 25198, -23348},
-{ -10300, -17830, 631, 11640, 2044, -20878},
-{ -873, -8502, -1063, -15674, -10693, 14934},
-{ -15957, 28137, 5268, 477, -1053, 1158},
-{ -1495, -8814, -5764, -24965, 25988, 7907},
-{ -1038, -114, -2308, -1319, -6480, 1472},
-{ 4895, -17897, -25850, 5301, -188, 1581},
-{ 3200, 17225, 4346, 22101, -18543, 22028},
-{ -10250, 545, -10932, 2276, -28070, 8118},
-{ 15343, 2329, 9316, 20537, 14908, 21021},
-{ 6329, 6130, -24508, 837, -8637, -5844},
-{ 7386, -501, 10503, 20131, 11435, -4755},
-{ -2745, 24174, -9274, 15273, -8389, -5835},
-{ 2992, -2864, 6048, -7473, 11687, -19996},
-{ -883, -11954, -9976, -21829, -4436, -27178},
-{ 3458, 19626, 1280, 2597, 19849, 5255},
-{ -5315, 19133, -14518, -8946, 13749, -1352},
-{ 18642, 17655, 11001, 6817, -18418, 6336},
-{ -1697, 2244, -4640, 3948, -12890, -5273},
-{ 20428, 10542, 4170, -1012, 19439, 21691},
-{ -2943, -19735, -4208, 1320, 909, -8897},
-{ 9351, -8066, -2618, -12933, 26582, 3507},
-{ 9705, -22628, 8311, 8167, -13293, 5608},
-{ 3222, 3749, -1508, 165, -52, -196},
-{ 102, -22744, -8832, 903, -11421, -14662},
-{ -120, 5998, 19765, 13401, 3628, 5197},
-{ 8528, 5827, -1066, 774, -39, -166},
-{ 9411, -9476, 9581, -13004, 24456, 24900},
-{ 17878, 2235, -21639, 20478, 4716, -7190},
-{ -2482, 9511, 1611, -21943, 14230, -1289},
-{ 9288, -2291, 23215, -3452, -10842, 11},
-{ 9496, 3041, 5130, -3890, -21219, -22589},
-{ 14262, -9838, 20195, 14019, 91, -17200},
-{ -18591, 980, 17, 821, 120, -574},
-{ 12285, -19269, 13742, 16373, -161, 6025},
-{ -3364, 1530, -4005, 2454, -10872, -23839},
-{ 105, 5085, -260, 5790, -588, 19170},
-{ 4121, 4169, 13439, 14644, 20899, 7434},
-{ -175, 13101, -3704, 23233, 3907, 10106},
-{ -6101, 23467, 5204, -1341, 1599, 13174},
-{ -3217, -3494, 15117, -8387, -11762, -4750},
-{ 1146, 4675, -19378, 14917, -5091, 249},
-{ -21506, 10136, -16473, -13305, 18382, -8601},
-{ 628, 2447, 3344, 3130, -5115, 119},
-{ 17900, -22422, -17633, 21967, -16293, -7676},
-{ 16863, 24214, 5612, -3858, -809, 3822},
-{ -2291, 10091, -2360, -25109, -1226, 312},
-{ 2957, 11256, 26745, -13266, -3455, -1128},
-{ -19762, -2708, 4604, 6355, 1638, 25501},
-{ -19593, -7753, 3159, -85, -489, -1855},
-{ 814, 12510, 19077, -4681, -2610, -1474},
-{ -23408, -19027, 8137, 19878, 7912, -282},
-{ 839, -19652, 11927, 27278, -3211, 2266},
-{ 4020, -1110, 8226, -1274, 20922, 25060},
-{ 26576, 325, -8693, -232, -2218, -699},
-{ -11293, -4200, 1805, -6673, -22940, -1339},
-{ -2005, -15886, -1047, -27687, -13235, 14370},
-{ -22073, 1949, 13175, -15656, -1846, 8055},
-{ 3039, 12025, 7132, -24632, 413, -2347},
-{ -24048, -206, 12459, -6654, -417, -10091},
-{ 18179, -23688, -20515, -16396, 7230, 763},
-{ 5659, -5085, 13878, -23729, -11077, -19587},
-{ 11340, 501, 25040, 7616, -19658, 1605},
-{ -26650, 8878, 10544, 417, 1299, 261},
-{ 14460, 11369, -3263, 9990, 8194, 18111},
-{ 1355, -20838, -9196, -16060, -8559, -730},
-{ -1918, -20937, -18293, -2461, -2651, 4316},
-{ -2810, 24521, -10996, -25721, 308, -1234},
-{ -9075, -17280, -1833, -29342, -24213, -16631},
-{ -2843, 10165, -5339, -2888, 21858, -21340},
-{ -15832, 14849, -23780, 5184, 10113, -20639},
-{ -19535, -11361, 8413, 1486, -23658, -5759},
-{ -7512, 1027, -20794, 13732, 19892, -21934},
-{ -12132, -7022, -19175, -8840, 22125, -16490},
-{ 1937, 5210, -6318, -23788, 13141, 11082},
-{ -205, 6036, -380, 8658, -233, 28020},
-{ -5523, 7477, 7635, 23595, 9763, -2590},
-{ 21658, -28313, -3086, -300, -1032, 1744},
-{ -22352, 16646, 208, 6665, -17400, -3028},
-{ 18482, 9336, -2737, -19372, 407, -4389},
-{ -4913, -17370, 18819, -17654, 13416, 15232},
-{ 7749, 6368, 23135, -18174, 7584, -4248},
-{ -1489, -6523, 586, -10157, 14964, 25568},
-{ 3844, -6156, 4897, -13045, -22526, 5647},
-{ -8491, -2105, -24774, 905, -9326, 1456},
-{ -3040, -1476, 1166, -4428, 11236, 9204},
-{ 3397, -1451, 13598, -15841, 24540, 5819},
-{ 8483, -2993, 21547, -16916, 7741, 24018},
-{ -14932, -23758, -5332, -6664, -4497, 13267},
-{ 19379, 12916, -2142, -737, 21100, -22101},
-{ 3393, -4629, 5735, -18913, -6969, 2687},
-{ 1148, -16147, -21433, -28095, -630, -14449},
-{ 7300, 672, 18530, -17452, -10149, 351},
-{ 11356, -10974, 17212, 4624, 145, 17791},
-{ -711, -3479, -2238, 15887, 2027, 0},
-{ -28048, 1794, -593, -2758, -21852, 11535},
-{ -19683, 4937, 22004, 21523, -3148, 1790},
-{ 813, 8231, 2633, 11981, -3043, 22201},
-{ 8952, -24760, -690, 14873, -2366, -5372},
-{ 8406, -5439, -274, -642, -145, 778},
-{ -6605, 7258, 20780, -23507, -18625, 22782},
-{ -22896, -25488, 10020, -1614, 1508, -1393},
-{ 7607, 407, -24678, -16385, -1804, -4699},
-{ -10592, -19139, 10462, -3747, 8721, -6919},
-{ 13010, 5292, -6230, -4884, -20904, -1797},
-{ 16891, -13770, -465, 19343, -10741, -12959},
-{ 25193, -14799, -5681, -521, -321, -1211},
-{ 6917, -3093, 20183, -26903, -12026, 1295},
-{ 305, 1992, 19457, -985, 25, -521},
-{ 6707, -3698, 8365, -8687, 21921, -27166},
-{ 4668, 5997, 7117, 11696, 24401, -10794},
-{ 744, -9416, 19893, 1963, 7922, -9824},
-{ 3430, 21282, -1736, 10844, 8821, 27015},
-{ -8813, 1521, -24038, 1651, 7838, -1208},
-{ 3911, -11221, 3273, -12541, 7168, 18402},
-{ 21642, 9117, -11536, -5256, 7077, 2382},
-{ 100, 3817, -6713, 1244, 1518, -321},
-{ 7946, -18670, 10667, -4866, 727, 776},
-{ -15883, -8150, -2087, 22739, 1567, -3482},
-{ 4380, -2735, 8469, -7025, -11424, 1317},
-{ 26970, 4393, 7665, 17561, -714, 650},
-{ -16191, -835, 8365, 1795, -14314, 16297},
-{ 4504, -10048, 7662, -26690, -17428, 2580},
-{ 48, -3984, 564, -5871, 2658, -18658},
-{ 12579, -26016, -15642, 2672, -1347, -887},
-{ -4950, 4208, -6811, 2569, -20621, -8658},
-{ -1836, -14818, -5571, -23322, -14800, 25867},
-{ 5434, -28139, -2357, -2883, -570, 2431},
-{ 13096, -2771, 24994, -12496, -24723, -1025},
-{ -5676, -4339, 1908, 18628, -21323, 17366},
-{ 27660, -27897, -15409, 1436, -7112, -2241},
-{ 8019, 3847, 24568, -469, 9674, 10683},
-{ -903, -10149, 1801, -21260, 4795, -8751},
-{ 1122, -9582, 2625, 22791, 956, 882},
-{ 7876, 19075, -9900, -24266, 7496, 9277},
-{ 980, -26764, -5386, 5396, 1086, 1648},
-{ 28838, -1270, -447, 5, -429, -20},
-{ -15283, 6132, 22812, 1252, -9963, 511},
-{ 851, 7925, -457, -12210, 4261, 7579},
-{ -4530, 8452, -1246, 14501, -24951, -5760},
-{ -17814, -10727, 9887, -23929, -13432, 1878},
-{ -15049, 10165, 16491, -14603, -11712, -21156},
-{ -3317, 840, -5683, 22413, 1994, 586},
-{ 23158, -5788, -15043, -10372, -9271, -13523},
-{ -773, -9509, -3993, -24264, 8463, 5804},
-{ -8545, -703, -12440, -3985, -25122, -28147},
-{ -16659, 16001, 2746, 1611, 5097, -1043},
-{ 41, -7181, 19903, 31555, -32237, 13927},
-{ -5658, 845, -12774, 5705, 16695, -86},
-{ 5282, 14875, 27026, 21124, 15776, -10477},
-{ 14712, 19648, -11487, -13361, -20196, -15229},
-{ 8597, -9138, -626, 10891, -6015, 6346},
-{ -1488, -1272, -1479, -1303, -3704, -5485},
-{ -3370, 17871, -6604, 24930, 25886, -3127},
-{ 8416, 27783, -1385, 5350, -4260, 19993},
-{ 5688, 362, 17246, 3809, -3246, 1088},
-{ -105, -29607, 2747, 15223, -167, 3722},
-{ 3502, -3195, 8602, 7772, -1566, -915},
-{ -491, 3257, -2423, 5522, 20606, -100},
-{ -13948, -11368, -15375, -21866, -8520, 12221},
-{ -616, 2424, -2023, 4398, -3805, 8108},
-{ -7204, 21043, 21211, -9395, -19391, 896},
-{ -5737, -15160, -21298, 17066, -1006, -366},
-{ 6261, 3240, -11937, -16213, -15820, 6581},
-{ -3155, 24796, 2733, -1257, -875, -1597},
-{ -20469, 11094, 24071, -8987, 14136, 2220},
-{ -14106, 11959, -22495, 4135, -1055, -5420},
-{ 801, -2655, 60, -5324, -790, 5937},
-{ -7372, -1764, -22433, -26060, 21707, 4178},
-{ -5715, -6648, -14908, 1325, -24044, 1493},
-{ -6024, -12488, 23930, 2950, 1601, 1173},
-{ 19067, 17630, 17929, -10654, 10928, -4958},
-{ 3231, -3284, 27336, 4174, -1683, 497},
-};
-
-const int16_t (* const ff_eac3_mantissa_vq[8])[6] = {
- NULL,
- vq_hebap1,
- vq_hebap2,
- vq_hebap3,
- vq_hebap4,
- vq_hebap5,
- vq_hebap6,
- vq_hebap7,
-};
-
-/**
- * Table E2.14 Frame Exponent Strategy Combinations
- */
-const uint8_t ff_eac3_frm_expstr[32][6] = {
-{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE},
-{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D45},
-{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE},
-{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D45},
-{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_REUSE},
-{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D45},
-{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE},
-{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D45, EXP_D45},
-{ EXP_D25, EXP_REUSE, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE},
-{ EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45},
-{ EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE},
-{ EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D45, EXP_D45},
-{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE},
-{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE, EXP_D45},
-{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE},
-{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D45, EXP_D45, EXP_D45},
-{ EXP_D45, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE},
-{ EXP_D45, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D45},
-{ EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE},
-{ EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D45},
-{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_REUSE},
-{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D45},
-{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE},
-{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D45, EXP_D45, EXP_D45},
-{ EXP_D45, EXP_D45, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE},
-{ EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45},
-{ EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE},
-{ EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_D45, EXP_D45},
-{ EXP_D45, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE},
-{ EXP_D45, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_D45},
-{ EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE},
-{ EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D45},
-};
-
-/**
- * Table E.25: Spectral Extension Attenuation Table
- * ff_eac3_spx_atten_tab[code][bin]=pow(2.0,(bin+1)*(code+1)/-15.0);
- */
-const float ff_eac3_spx_atten_tab[32][3] = {
- { 0.954841603910416503f, 0.911722488558216804f, 0.870550563296124125f },
- { 0.911722488558216804f, 0.831237896142787758f, 0.757858283255198995f },
- { 0.870550563296124125f, 0.757858283255198995f, 0.659753955386447100f },
- { 0.831237896142787758f, 0.690956439983888004f, 0.574349177498517438f },
- { 0.793700525984099792f, 0.629960524947436595f, 0.500000000000000000f },
- { 0.757858283255198995f, 0.574349177498517438f, 0.435275281648062062f },
- { 0.723634618720189082f, 0.523647061410313364f, 0.378929141627599553f },
- { 0.690956439983888004f, 0.477420801955208307f, 0.329876977693223550f },
- { 0.659753955386447100f, 0.435275281648062062f, 0.287174588749258719f },
- { 0.629960524947436595f, 0.396850262992049896f, 0.250000000000000000f },
- { 0.601512518041058319f, 0.361817309360094541f, 0.217637640824031003f },
- { 0.574349177498517438f, 0.329876977693223550f, 0.189464570813799776f },
- { 0.548412489847312945f, 0.300756259020529160f, 0.164938488846611775f },
- { 0.523647061410313364f, 0.274206244923656473f, 0.143587294374629387f },
- { 0.500000000000000000f, 0.250000000000000000f, 0.125000000000000000f },
- { 0.477420801955208307f, 0.227930622139554201f, 0.108818820412015502f },
- { 0.455861244279108402f, 0.207809474035696939f, 0.094732285406899888f },
- { 0.435275281648062062f, 0.189464570813799776f, 0.082469244423305887f },
- { 0.415618948071393879f, 0.172739109995972029f, 0.071793647187314694f },
- { 0.396850262992049896f, 0.157490131236859149f, 0.062500000000000000f },
- { 0.378929141627599553f, 0.143587294374629387f, 0.054409410206007751f },
- { 0.361817309360094541f, 0.130911765352578369f, 0.047366142703449930f },
- { 0.345478219991944002f, 0.119355200488802049f, 0.041234622211652958f },
- { 0.329876977693223550f, 0.108818820412015502f, 0.035896823593657347f },
- { 0.314980262473718298f, 0.099212565748012460f, 0.031250000000000000f },
- { 0.300756259020529160f, 0.090454327340023621f, 0.027204705103003875f },
- { 0.287174588749258719f, 0.082469244423305887f, 0.023683071351724965f },
- { 0.274206244923656473f, 0.075189064755132290f, 0.020617311105826479f },
- { 0.261823530705156682f, 0.068551561230914118f, 0.017948411796828673f },
- { 0.250000000000000000f, 0.062500000000000000f, 0.015625000000000000f },
- { 0.238710400977604098f, 0.056982655534888536f, 0.013602352551501938f },
- { 0.227930622139554201f, 0.051952368508924235f, 0.011841535675862483f }
-};
diff --git a/libavcodec/eac3dec_data.h b/libavcodec/eac3dec_data.h
deleted file mode 100644
index 91892a3..0000000
--- a/libavcodec/eac3dec_data.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * E-AC-3 decoder tables
- * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_EAC3DEC_DATA_H
-#define AVCODEC_EAC3DEC_DATA_H
-
-#include <stdint.h>
-
-extern const uint8_t ff_eac3_bits_vs_hebap[20];
-extern const int16_t ff_eac3_gaq_remap_1[12];
-extern const int16_t ff_eac3_gaq_remap_2_4_a[9][2];
-extern const int16_t ff_eac3_gaq_remap_2_4_b[9][2];
-
-extern const int16_t (* const ff_eac3_mantissa_vq[8])[6];
-extern const uint8_t ff_eac3_frm_expstr[32][6];
-extern const float ff_eac3_spx_atten_tab[32][3];
-
-#endif /* AVCODEC_EAC3DEC_DATA_H */
diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c
index d37acaf..f3b4418 100644
--- a/libavcodec/eac3enc.c
+++ b/libavcodec/eac3enc.c
@@ -27,12 +27,63 @@
#define CONFIG_AC3ENC_FLOAT 1
#include "ac3enc.h"
#include "eac3enc.h"
+#include "eac3_data.h"
#define AC3ENC_TYPE AC3ENC_TYPE_EAC3
#include "ac3enc_opts_template.c"
-static AVClass eac3enc_class = { "E-AC-3 Encoder", av_default_item_name,
- eac3_options, LIBAVUTIL_VERSION_INT };
+static const AVClass eac3enc_class = { "E-AC-3 Encoder", av_default_item_name,
+ eac3_options, LIBAVUTIL_VERSION_INT };
+
+
+/**
+ * LUT for finding a matching frame exponent strategy index from a set of
+ * exponent strategies for a single channel across all 6 blocks.
+ */
+static int8_t eac3_frame_expstr_index_tab[3][4][4][4][4][4];
+
+
+void ff_eac3_exponent_init(void)
+{
+ int i;
+
+ memset(eac3_frame_expstr_index_tab, -1, sizeof(eac3_frame_expstr_index_tab));
+ for (i = 0; i < 32; i++) {
+ eac3_frame_expstr_index_tab[ff_eac3_frm_expstr[i][0]-1]
+ [ff_eac3_frm_expstr[i][1]]
+ [ff_eac3_frm_expstr[i][2]]
+ [ff_eac3_frm_expstr[i][3]]
+ [ff_eac3_frm_expstr[i][4]]
+ [ff_eac3_frm_expstr[i][5]] = i;
+ }
+}
+
+
+void ff_eac3_get_frame_exp_strategy(AC3EncodeContext *s)
+{
+ int ch;
+
+ if (s->num_blocks < 6) {
+ s->use_frame_exp_strategy = 0;
+ return;
+ }
+
+ s->use_frame_exp_strategy = 1;
+ for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) {
+ int expstr = eac3_frame_expstr_index_tab[s->exp_strategy[ch][0]-1]
+ [s->exp_strategy[ch][1]]
+ [s->exp_strategy[ch][2]]
+ [s->exp_strategy[ch][3]]
+ [s->exp_strategy[ch][4]]
+ [s->exp_strategy[ch][5]];
+ if (expstr < 0) {
+ s->use_frame_exp_strategy = 0;
+ break;
+ }
+ s->frame_exp_strategy[ch] = expstr;
+ }
+}
+
void ff_eac3_set_cpl_states(AC3EncodeContext *s)
@@ -43,12 +94,12 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s)
/* set first cpl coords */
for (ch = 1; ch <= s->fbw_channels; ch++)
first_cpl_coords[ch] = 1;
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch]) {
if (first_cpl_coords[ch]) {
- block->new_cpl_coords = 2;
+ block->new_cpl_coords[ch] = 2;
first_cpl_coords[ch] = 0;
}
} else {
@@ -58,7 +109,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s)
}
/* set first cpl leak */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
if (block->cpl_in_use) {
block->new_cpl_leak = 2;
@@ -84,22 +135,64 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
put_bits(&s->pb, 2, s->bit_alloc.sr_code); /* sample rate code */
} else {
put_bits(&s->pb, 2, s->bit_alloc.sr_code); /* sample rate code */
- put_bits(&s->pb, 2, 0x3); /* number of blocks = 6 */
+ put_bits(&s->pb, 2, s->num_blks_code); /* number of blocks */
}
put_bits(&s->pb, 3, s->channel_mode); /* audio coding mode */
put_bits(&s->pb, 1, s->lfe_on); /* LFE channel indicator */
put_bits(&s->pb, 5, s->bitstream_id); /* bitstream id (EAC3=16) */
put_bits(&s->pb, 5, -opt->dialogue_level); /* dialogue normalization level */
put_bits(&s->pb, 1, 0); /* no compression gain */
- put_bits(&s->pb, 1, 0); /* no mixing metadata */
- /* TODO: mixing metadata */
- put_bits(&s->pb, 1, 0); /* no info metadata */
- /* TODO: info metadata */
+ /* mixing metadata*/
+ put_bits(&s->pb, 1, opt->eac3_mixing_metadata);
+ if (opt->eac3_mixing_metadata) {
+ if (s->channel_mode > AC3_CHMODE_STEREO)
+ put_bits(&s->pb, 2, opt->preferred_stereo_downmix);
+ if (s->has_center) {
+ put_bits(&s->pb, 3, s->ltrt_center_mix_level);
+ put_bits(&s->pb, 3, s->loro_center_mix_level);
+ }
+ if (s->has_surround) {
+ put_bits(&s->pb, 3, s->ltrt_surround_mix_level);
+ put_bits(&s->pb, 3, s->loro_surround_mix_level);
+ }
+ if (s->lfe_on)
+ put_bits(&s->pb, 1, 0);
+ put_bits(&s->pb, 1, 0); /* no program scale */
+ put_bits(&s->pb, 1, 0); /* no ext program scale */
+ put_bits(&s->pb, 2, 0); /* no mixing parameters */
+ if (s->channel_mode < AC3_CHMODE_STEREO)
+ put_bits(&s->pb, 1, 0); /* no pan info */
+ put_bits(&s->pb, 1, 0); /* no frame mix config info */
+ }
+ /* info metadata*/
+ put_bits(&s->pb, 1, opt->eac3_info_metadata);
+ if (opt->eac3_info_metadata) {
+ put_bits(&s->pb, 3, s->bitstream_mode);
+ put_bits(&s->pb, 1, opt->copyright);
+ put_bits(&s->pb, 1, opt->original);
+ if (s->channel_mode == AC3_CHMODE_STEREO) {
+ put_bits(&s->pb, 2, opt->dolby_surround_mode);
+ put_bits(&s->pb, 2, opt->dolby_headphone_mode);
+ }
+ if (s->channel_mode >= AC3_CHMODE_2F2R)
+ put_bits(&s->pb, 2, opt->dolby_surround_ex_mode);
+ put_bits(&s->pb, 1, opt->audio_production_info);
+ if (opt->audio_production_info) {
+ put_bits(&s->pb, 5, opt->mixing_level - 80);
+ put_bits(&s->pb, 2, opt->room_type);
+ put_bits(&s->pb, 1, opt->ad_converter_type);
+ }
+ put_bits(&s->pb, 1, 0);
+ }
+ if (s->num_blocks != 6)
+ put_bits(&s->pb, 1, !(s->avctx->frame_number % 6)); /* converter sync flag */
put_bits(&s->pb, 1, 0); /* no additional bit stream info */
/* frame header */
- put_bits(&s->pb, 1, 1); /* exponent strategy syntax = each block */
+ if (s->num_blocks == 6) {
+ put_bits(&s->pb, 1, !s->use_frame_exp_strategy);/* exponent strategy syntax */
put_bits(&s->pb, 1, 0); /* aht enabled = no */
+ }
put_bits(&s->pb, 2, 0); /* snr offset strategy = 1 */
put_bits(&s->pb, 1, 0); /* transient pre-noise processing enabled = no */
put_bits(&s->pb, 1, 0); /* block switch syntax enabled = no */
@@ -112,7 +205,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
/* coupling strategy use flags */
if (s->channel_mode > AC3_CHMODE_MONO) {
put_bits(&s->pb, 1, s->blocks[0].cpl_in_use);
- for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) {
+ for (blk = 1; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
put_bits(&s->pb, 1, block->new_cpl_strategy);
if (block->new_cpl_strategy)
@@ -120,21 +213,35 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
}
}
/* exponent strategy */
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
- for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++)
- put_bits(&s->pb, 2, s->exp_strategy[ch][blk]);
+ if (s->use_frame_exp_strategy) {
+ for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++)
+ put_bits(&s->pb, 5, s->frame_exp_strategy[ch]);
+ } else {
+ for (blk = 0; blk < s->num_blocks; blk++)
+ for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++)
+ put_bits(&s->pb, 2, s->exp_strategy[ch][blk]);
+ }
if (s->lfe_on) {
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
+ for (blk = 0; blk < s->num_blocks; blk++)
put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]);
}
- /* E-AC-3 to AC-3 converter exponent strategy (unfortunately not optional...) */
- for (ch = 1; ch <= s->fbw_channels; ch++)
- put_bits(&s->pb, 5, 0);
+ /* E-AC-3 to AC-3 converter exponent strategy (not optional when num blocks == 6) */
+ if (s->num_blocks != 6) {
+ put_bits(&s->pb, 1, 0);
+ } else {
+ for (ch = 1; ch <= s->fbw_channels; ch++) {
+ if (s->use_frame_exp_strategy)
+ put_bits(&s->pb, 5, s->frame_exp_strategy[ch]);
+ else
+ put_bits(&s->pb, 5, 0);
+ }
+ }
/* snr offsets */
put_bits(&s->pb, 6, s->coarse_snr_offset);
put_bits(&s->pb, 4, s->fine_snr_offset[1]);
/* block start info */
- put_bits(&s->pb, 1, 0);
+ if (s->num_blocks > 1)
+ put_bits(&s->pb, 1, 0);
}
@@ -145,7 +252,7 @@ AVCodec ff_eac3_encoder = {
.id = CODEC_ID_EAC3,
.priv_data_size = sizeof(AC3EncodeContext),
.init = ff_ac3_encode_init,
- .encode = ff_ac3_encode_frame,
+ .encode = ff_ac3_float_encode_frame,
.close = ff_ac3_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 E-AC-3"),
diff --git a/libavcodec/eac3enc.h b/libavcodec/eac3enc.h
index eacb8cf..a92a24c 100644
--- a/libavcodec/eac3enc.h
+++ b/libavcodec/eac3enc.h
@@ -30,6 +30,16 @@
#include "ac3enc.h"
/**
+ * Initialize E-AC-3 exponent tables.
+ */
+void ff_eac3_exponent_init(void);
+
+/**
+ * Determine frame exponent strategy use and indices.
+ */
+void ff_eac3_get_frame_exp_strategy(AC3EncodeContext *s);
+
+/**
* Set coupling states.
* This determines whether certain flags must be written to the bitstream or
* whether they will be implicitly already known by the decoder.
diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c
index c968a3d..085e2d8 100644
--- a/libavcodec/eacmv.c
+++ b/libavcodec/eacmv.c
@@ -52,7 +52,7 @@ static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const uint8_t *
unsigned char *dst = s->frame.data[0];
int i;
- for (i=0; i < s->avctx->height && buf+s->avctx->width<=buf_end; i++) {
+ for (i=0; i < s->avctx->height && buf_end - buf >= s->avctx->width; i++) {
memcpy(dst, buf, s->avctx->width);
dst += s->frame.linesize[0];
buf += s->avctx->width;
@@ -84,7 +84,7 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t *
i = 0;
for(y=0; y<s->avctx->height/4; y++)
- for(x=0; x<s->avctx->width/4 && buf+i<buf_end; x++) {
+ for(x=0; x<s->avctx->width/4 && buf_end - buf > i; x++) {
if (buf[i]==0xFF) {
unsigned char *dst = s->frame.data[0] + (y*4)*s->frame.linesize[0] + x*4;
if (raw+16<buf_end && *raw==0xFF) { /* intra */
@@ -118,7 +118,7 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t
{
int pal_start, pal_count, i;
- if(buf+16>=buf_end) {
+ if(buf_end - buf < 16) {
av_log(s->avctx, AV_LOG_WARNING, "truncated header\n");
return;
}
@@ -135,7 +135,7 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t
pal_count = AV_RL16(&buf[14]);
buf += 16;
- for (i=pal_start; i<pal_start+pal_count && i<AVPALETTE_COUNT && buf+2<buf_end; i++) {
+ for (i=pal_start; i<pal_start+pal_count && i<AVPALETTE_COUNT && buf_end - buf >= 3; i++) {
s->palette[i] = AV_RB24(buf);
buf += 3;
}
@@ -153,6 +153,9 @@ static int cmv_decode_frame(AVCodecContext *avctx,
CmvContext *s = avctx->priv_data;
const uint8_t *buf_end = buf + buf_size;
+ if (buf_end - buf < EA_PREAMBLE_SIZE)
+ return AVERROR_INVALIDDATA;
+
if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) {
cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end);
return buf_size;
@@ -206,14 +209,13 @@ static av_cold int cmv_decode_end(AVCodecContext *avctx){
}
AVCodec ff_eacmv_decoder = {
- "eacmv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_CMV,
- sizeof(CmvContext),
- cmv_decode_init,
- NULL,
- cmv_decode_end,
- cmv_decode_frame,
- CODEC_CAP_DR1,
+ .name = "eacmv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_CMV,
+ .priv_data_size = sizeof(CmvContext),
+ .init = cmv_decode_init,
+ .close = cmv_decode_end,
+ .decode = cmv_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts CMV video"),
};
diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c
index db22781..c5aa6ac 100644
--- a/libavcodec/eamad.c
+++ b/libavcodec/eamad.c
@@ -22,9 +22,9 @@
/**
* @file
* Electronic Arts Madcow Video Decoder
- * by Peter Ross <pross at xvid.org>
+ * @author Peter Ross <pross at xvid.org>
*
- * Technical details here:
+ * @see technical details at
* http://wiki.multimedia.cx/index.php?title=Electronic_Arts_MAD
*/
@@ -307,14 +307,13 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_eamad_decoder = {
- "eamad",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MAD,
- sizeof(MadContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "eamad",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MAD,
+ .priv_data_size = sizeof(MadContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video")
};
diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c
index d4f8b8f..e82ed32 100644
--- a/libavcodec/eatgq.c
+++ b/libavcodec/eatgq.c
@@ -29,7 +29,7 @@
*/
#include "avcodec.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
#include "bytestream.h"
#include "dsputil.h"
@@ -244,14 +244,13 @@ static av_cold int tgq_decode_end(AVCodecContext *avctx){
}
AVCodec ff_eatgq_decoder = {
- "eatgq",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TGQ,
- sizeof(TgqContext),
- tgq_decode_init,
- NULL,
- tgq_decode_end,
- tgq_decode_frame,
- CODEC_CAP_DR1,
+ .name = "eatgq",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TGQ,
+ .priv_data_size = sizeof(TgqContext),
+ .init = tgq_decode_init,
+ .close = tgq_decode_end,
+ .decode = tgq_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),
};
diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c
index ee5c094..ccdb35e 100644
--- a/libavcodec/eatgv.c
+++ b/libavcodec/eatgv.c
@@ -29,7 +29,7 @@
*/
#include "avcodec.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
#include "libavutil/lzo.h"
#include "libavutil/imgutils.h"
@@ -155,7 +155,7 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b
vector_bits = AV_RL16(&buf[6]);
buf += 12;
- /* allocate codebook buffers as neccessary */
+ /* allocate codebook buffers as necessary */
if (num_mvs > s->num_mvs) {
s->mv_codebook = av_realloc(s->mv_codebook, num_mvs*2*sizeof(int));
s->num_mvs = num_mvs;
@@ -286,7 +286,7 @@ static int tgv_decode_frame(AVCodecContext *avctx,
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
s->frame.linesize[0] = s->width;
- /* allocate additional 12 bytes to accomodate av_memcpy_backptr() OUTBUF_PADDED optimisation */
+ /* allocate additional 12 bytes to accommodate av_memcpy_backptr() OUTBUF_PADDED optimisation */
s->frame.data[0] = av_malloc(s->width*s->height + 12);
if (!s->frame.data[0])
return AVERROR(ENOMEM);
@@ -335,13 +335,12 @@ static av_cold int tgv_decode_end(AVCodecContext *avctx)
}
AVCodec ff_eatgv_decoder = {
- "eatgv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TGV,
- sizeof(TgvContext),
- tgv_decode_init,
- NULL,
- tgv_decode_end,
- tgv_decode_frame,
+ .name = "eatgv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TGV,
+ .priv_data_size = sizeof(TgvContext),
+ .init = tgv_decode_init,
+ .close = tgv_decode_end,
+ .decode = tgv_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"),
};
diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c
index aa96437..aaf704b 100644
--- a/libavcodec/eatqi.c
+++ b/libavcodec/eatqi.c
@@ -22,10 +22,8 @@
/**
* @file
* Electronic Arts TQI Video Decoder
- * by Peter Ross <pross at xvid.org>
- *
- * Technical details here:
- * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TQI
+ * @author Peter Ross <pross at xvid.org>
+ * @see http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TQI
*/
#include "avcodec.h"
@@ -155,14 +153,13 @@ static av_cold int tqi_decode_end(AVCodecContext *avctx)
}
AVCodec ff_eatqi_decoder = {
- "eatqi",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TQI,
- sizeof(TqiContext),
- tqi_decode_init,
- NULL,
- tqi_decode_end,
- tqi_decode_frame,
- CODEC_CAP_DR1,
+ .name = "eatqi",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TQI,
+ .priv_data_size = sizeof(TqiContext),
+ .init = tqi_decode_init,
+ .close = tqi_decode_end,
+ .decode = tqi_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"),
};
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index 8906b49..fe28f46 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -41,9 +41,9 @@
#undef mb_intra
static void decode_mb(MpegEncContext *s, int ref){
- s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16;
- s->dest[1] = s->current_picture.data[1] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift);
- s->dest[2] = s->current_picture.data[2] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift);
+ s->dest[0] = s->current_picture.f.data[0] + (s->mb_y * 16 * s->linesize) + s->mb_x * 16;
+ s->dest[1] = s->current_picture.f.data[1] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
+ s->dest[2] = s->current_picture.f.data[2] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
if(CONFIG_H264_DECODER && s->codec_id == CODEC_ID_H264){
H264Context *h= (void*)s;
@@ -52,7 +52,7 @@ static void decode_mb(MpegEncContext *s, int ref){
assert(ref>=0);
if(ref >= h->ref_count[0]) //FIXME it is posible albeit uncommon that slice references differ between slices, we take the easy approuch and ignore it for now. If this turns out to have any relevance in practice then correct remapping should be added
ref=0;
- fill_rectangle(&s->current_picture.ref_index[0][4*h->mb_xy], 2, 2, 2, ref, 1);
+ fill_rectangle(&s->current_picture.f.ref_index[0][4*h->mb_xy], 2, 2, 2, ref, 1);
fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4);
assert(!FRAME_MBAFF);
@@ -80,7 +80,7 @@ static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride){
}
/**
- * replaces the current MB with a flat dc only version.
+ * Replace the current MB with a flat dc-only version.
*/
static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int mb_x, int mb_y)
{
@@ -166,15 +166,15 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
error= s->error_status_table[mb_index];
- if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter
- if(!(error&DC_ERROR)) continue; //dc-ok
+ if(IS_INTER(s->current_picture.f.mb_type[mb_index])) continue; //inter
+ if(!(error&ER_DC_ERROR)) continue; //dc-ok
/* right block */
for(j=b_x+1; j<w; j++){
int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
int error_j= s->error_status_table[mb_index_j];
- int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
- if(intra_j==0 || !(error_j&DC_ERROR)){
+ int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
+ if(intra_j==0 || !(error_j&ER_DC_ERROR)){
color[0]= dc[j + b_y*stride];
distance[0]= j-b_x;
break;
@@ -185,8 +185,8 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
for(j=b_x-1; j>=0; j--){
int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
int error_j= s->error_status_table[mb_index_j];
- int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
- if(intra_j==0 || !(error_j&DC_ERROR)){
+ int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
+ if(intra_j==0 || !(error_j&ER_DC_ERROR)){
color[1]= dc[j + b_y*stride];
distance[1]= b_x-j;
break;
@@ -197,8 +197,8 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
for(j=b_y+1; j<h; j++){
int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
int error_j= s->error_status_table[mb_index_j];
- int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
- if(intra_j==0 || !(error_j&DC_ERROR)){
+ int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
+ if(intra_j==0 || !(error_j&ER_DC_ERROR)){
color[2]= dc[b_x + j*stride];
distance[2]= j-b_y;
break;
@@ -209,8 +209,8 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
for(j=b_y-1; j>=0; j--){
int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
int error_j= s->error_status_table[mb_index_j];
- int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
- if(intra_j==0 || !(error_j&DC_ERROR)){
+ int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
+ if(intra_j==0 || !(error_j&ER_DC_ERROR)){
color[3]= dc[b_x + j*stride];
distance[3]= b_y-j;
break;
@@ -248,13 +248,13 @@ static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int st
int y;
int left_status = s->error_status_table[( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride];
int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride];
- int left_intra= IS_INTRA(s->current_picture.mb_type [( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride]);
- int right_intra= IS_INTRA(s->current_picture.mb_type [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride]);
- int left_damage = left_status&(DC_ERROR|AC_ERROR|MV_ERROR);
- int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR);
+ int left_intra = IS_INTRA(s->current_picture.f.mb_type[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
+ int right_intra = IS_INTRA(s->current_picture.f.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
+ int left_damage = left_status&ER_MB_ERROR;
+ int right_damage= right_status&ER_MB_ERROR;
int offset= b_x*8 + b_y*stride*8;
- int16_t *left_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride* b_x ];
- int16_t *right_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride*(b_x+1)];
+ int16_t *left_mv= s->current_picture.f.motion_val[0][mvy_stride*b_y + mvx_stride* b_x ];
+ int16_t *right_mv= s->current_picture.f.motion_val[0][mvy_stride*b_y + mvx_stride*(b_x+1)];
if(!(left_damage||right_damage)) continue; // both undamaged
@@ -311,13 +311,13 @@ static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int st
int x;
int top_status = s->error_status_table[(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride];
int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride];
- int top_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride]);
- int bottom_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride]);
- int top_damage = top_status&(DC_ERROR|AC_ERROR|MV_ERROR);
- int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR);
+ int top_intra = IS_INTRA(s->current_picture.f.mb_type[(b_x >> is_luma) + ( b_y >> is_luma) * s->mb_stride]);
+ int bottom_intra = IS_INTRA(s->current_picture.f.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
+ int top_damage = top_status&ER_MB_ERROR;
+ int bottom_damage= bottom_status&ER_MB_ERROR;
int offset= b_x*8 + b_y*stride*8;
- int16_t *top_mv= s->current_picture.motion_val[0][mvy_stride* b_y + mvx_stride*b_x];
- int16_t *bottom_mv= s->current_picture.motion_val[0][mvy_stride*(b_y+1) + mvx_stride*b_x];
+ int16_t *top_mv = s->current_picture.f.motion_val[0][mvy_stride * b_y + mvx_stride * b_x];
+ int16_t *bottom_mv = s->current_picture.f.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
if(!(top_damage||bottom_damage)) continue; // both undamaged
@@ -376,8 +376,8 @@ static void guess_mv(MpegEncContext *s){
int f=0;
int error= s->error_status_table[mb_xy];
- if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
- if(!(error&MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV
+ if(IS_INTRA(s->current_picture.f.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
+ if(!(error&ER_MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV
fixed[mb_xy]= f;
if(f==MV_FROZEN)
@@ -389,10 +389,10 @@ static void guess_mv(MpegEncContext *s){
for(mb_x=0; mb_x<s->mb_width; mb_x++){
const int mb_xy= mb_x + mb_y*s->mb_stride;
- if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue;
- if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
+ if(IS_INTRA(s->current_picture.f.mb_type[mb_xy])) continue;
+ if(!(s->error_status_table[mb_xy]&ER_MV_ERROR)) continue;
- s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
+ s->mv_dir = s->last_picture.f.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
s->mb_intra=0;
s->mv_type = MV_TYPE_16X16;
s->mb_skipped=0;
@@ -434,8 +434,8 @@ int score_sum=0;
if((mb_x^mb_y^pass)&1) continue;
if(fixed[mb_xy]==MV_FROZEN) continue;
- assert(!IS_INTRA(s->current_picture.mb_type[mb_xy]));
- assert(s->last_picture_ptr && s->last_picture_ptr->data[0]);
+ assert(!IS_INTRA(s->current_picture.f.mb_type[mb_xy]));
+ assert(s->last_picture_ptr && s->last_picture_ptr->f.data[0]);
j=0;
if(mb_x>0 && fixed[mb_xy-1 ]==MV_FROZEN) j=1;
@@ -454,27 +454,27 @@ int score_sum=0;
none_left=0;
if(mb_x>0 && fixed[mb_xy-1]){
- mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_step][0];
- mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1];
- ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-1)];
+ mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index - mot_step][0];
+ mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index - mot_step][1];
+ ref [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy-1)];
pred_count++;
}
if(mb_x+1<mb_width && fixed[mb_xy+1]){
- mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_step][0];
- mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1];
- ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+1)];
+ mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index + mot_step][0];
+ mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index + mot_step][1];
+ ref [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy+1)];
pred_count++;
}
if(mb_y>0 && fixed[mb_xy-mb_stride]){
- mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][0];
- mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1];
- ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-s->mb_stride)];
+ mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index - mot_stride*mot_step][0];
+ mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index - mot_stride*mot_step][1];
+ ref [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy-s->mb_stride)];
pred_count++;
}
if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
- mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][0];
- mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1];
- ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+s->mb_stride)];
+ mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index + mot_stride*mot_step][0];
+ mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index + mot_stride*mot_step][1];
+ ref [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy+s->mb_stride)];
pred_count++;
}
if(pred_count==0) continue;
@@ -534,16 +534,16 @@ skip_mean_and_median:
ff_thread_await_progress((AVFrame *) s->last_picture_ptr,
mb_y, 0);
}
- if (!s->last_picture.motion_val[0] ||
- !s->last_picture.ref_index[0])
+ if (!s->last_picture.f.motion_val[0] ||
+ !s->last_picture.f.ref_index[0])
goto skip_last_mv;
- prev_x = s->last_picture.motion_val[0][mot_index][0];
- prev_y = s->last_picture.motion_val[0][mot_index][1];
- prev_ref = s->last_picture.ref_index[0][4*mb_xy];
+ prev_x = s->last_picture.f.motion_val[0][mot_index][0];
+ prev_y = s->last_picture.f.motion_val[0][mot_index][1];
+ prev_ref = s->last_picture.f.ref_index[0][4*mb_xy];
} else {
- prev_x = s->current_picture.motion_val[0][mot_index][0];
- prev_y = s->current_picture.motion_val[0][mot_index][1];
- prev_ref = s->current_picture.ref_index[0][4*mb_xy];
+ prev_x = s->current_picture.f.motion_val[0][mot_index][0];
+ prev_y = s->current_picture.f.motion_val[0][mot_index][1];
+ prev_ref = s->current_picture.f.ref_index[0][4*mb_xy];
}
/* last MV */
@@ -565,10 +565,10 @@ skip_mean_and_median:
for(j=0; j<pred_count; j++){
int score=0;
- uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
+ uint8_t *src = s->current_picture.f.data[0] + mb_x*16 + mb_y*16*s->linesize;
- s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
- s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
+ s->current_picture.f.motion_val[0][mot_index][0] = s->mv[0][0][0] = mv_predictor[j][0];
+ s->current_picture.f.motion_val[0][mot_index][1] = s->mv[0][0][1] = mv_predictor[j][1];
if(ref[j]<0) //predictor intra or otherwise not available
continue;
@@ -607,8 +607,8 @@ score_sum+= best_score;
for(i=0; i<mot_step; i++)
for(j=0; j<mot_step; j++){
- s->current_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0];
- s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1];
+ s->current_picture.f.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
+ s->current_picture.f.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
}
decode_mb(s, ref[best_pred]);
@@ -640,19 +640,19 @@ score_sum+= best_score;
static int is_intra_more_likely(MpegEncContext *s){
int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
- if(!s->last_picture_ptr || !s->last_picture_ptr->data[0]) return 1; //no previous frame available -> use spatial prediction
+ if (!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) return 1; //no previous frame available -> use spatial prediction
undamaged_count=0;
for(i=0; i<s->mb_num; i++){
const int mb_xy= s->mb_index2xy[i];
const int error= s->error_status_table[mb_xy];
- if(!((error&DC_ERROR) && (error&MV_ERROR)))
+ if(!((error&ER_DC_ERROR) && (error&ER_MV_ERROR)))
undamaged_count++;
}
if(s->codec_id == CODEC_ID_H264){
H264Context *h= (void*)s;
- if(h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0])
+ if (h->list_count <= 0 || h->ref_count[0] <= 0 || !h->ref_list[0][0].f.data[0])
return 1;
}
@@ -672,15 +672,15 @@ static int is_intra_more_likely(MpegEncContext *s){
const int mb_xy= mb_x + mb_y*s->mb_stride;
error= s->error_status_table[mb_xy];
- if((error&DC_ERROR) && (error&MV_ERROR))
+ if((error&ER_DC_ERROR) && (error&ER_MV_ERROR))
continue; //skip damaged
j++;
if((j%skip_amount) != 0) continue; //skip a few to speed things up
if(s->pict_type==AV_PICTURE_TYPE_I){
- uint8_t *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
- uint8_t *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize;
+ uint8_t *mb_ptr = s->current_picture.f.data[0] + mb_x*16 + mb_y*16*s->linesize;
+ uint8_t *last_mb_ptr= s->last_picture.f.data [0] + mb_x*16 + mb_y*16*s->linesize;
if (s->avctx->codec_id == CODEC_ID_H264) {
// FIXME
@@ -691,7 +691,7 @@ static int is_intra_more_likely(MpegEncContext *s){
is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr , s->linesize, 16);
is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
}else{
- if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
+ if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
is_intra_likely++;
else
is_intra_likely--;
@@ -703,17 +703,17 @@ static int is_intra_more_likely(MpegEncContext *s){
}
void ff_er_frame_start(MpegEncContext *s){
- if(!s->error_recognition) return;
+ if(!s->err_recognition) return;
- memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_stride*s->mb_height*sizeof(uint8_t));
+ memset(s->error_status_table, ER_MB_ERROR|VP_START|ER_MB_END, s->mb_stride*s->mb_height*sizeof(uint8_t));
s->error_count= 3*s->mb_num;
s->error_occurred = 0;
}
/**
- * adds a slice.
+ * Add a slice.
* @param endx x component of the last macroblock, can be -1 for the last of the previous line
- * @param status the status at the end (MV_END, AC_ERROR, ...), it is assumed that no earlier end or
+ * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is assumed that no earlier end or
* error of the same type occurred
*/
void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
@@ -731,23 +731,23 @@ void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int en
return;
}
- if(!s->error_recognition) return;
+ if(!s->err_recognition) return;
mask &= ~VP_START;
- if(status & (AC_ERROR|AC_END)){
- mask &= ~(AC_ERROR|AC_END);
+ if(status & (ER_AC_ERROR|ER_AC_END)){
+ mask &= ~(ER_AC_ERROR|ER_AC_END);
s->error_count -= end_i - start_i + 1;
}
- if(status & (DC_ERROR|DC_END)){
- mask &= ~(DC_ERROR|DC_END);
+ if(status & (ER_DC_ERROR|ER_DC_END)){
+ mask &= ~(ER_DC_ERROR|ER_DC_END);
s->error_count -= end_i - start_i + 1;
}
- if(status & (MV_ERROR|MV_END)){
- mask &= ~(MV_ERROR|MV_END);
+ if(status & (ER_MV_ERROR|ER_MV_END)){
+ mask &= ~(ER_MV_ERROR|ER_MV_END);
s->error_count -= end_i - start_i + 1;
}
- if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) {
+ if(status & ER_MB_ERROR) {
s->error_occurred = 1;
s->error_count= INT_MAX;
}
@@ -774,7 +774,7 @@ void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int en
int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ];
prev_status &= ~ VP_START;
- if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX;
+ if(prev_status != (ER_MV_END|ER_DC_END|ER_AC_END)) s->error_count= INT_MAX;
}
}
@@ -787,21 +787,21 @@ void ff_er_frame_end(MpegEncContext *s){
int size = s->b8_stride * 2 * s->mb_height;
Picture *pic= s->current_picture_ptr;
- if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
+ if(!s->err_recognition || s->error_count==0 || s->avctx->lowres ||
s->avctx->hwaccel ||
s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
- s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
+ s->picture_structure != PICT_FRAME || // we do not support ER of field pictures yet, though it should not crash if enabled
s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
- if(s->current_picture.motion_val[0] == NULL){
+ if (s->current_picture.f.motion_val[0] == NULL) {
av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
for(i=0; i<2; i++){
- pic->ref_index[i]= av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
+ pic->f.ref_index[i] = av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t));
- pic->motion_val[i]= pic->motion_val_base[i]+4;
+ pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
}
- pic->motion_subsample_log2= 3;
+ pic->f.motion_subsample_log2 = 3;
s->current_picture= *s->current_picture_ptr;
}
@@ -845,13 +845,13 @@ void ff_er_frame_end(MpegEncContext *s){
const int mb_xy= s->mb_index2xy[i];
int error= s->error_status_table[mb_xy];
- if(error&AC_END)
+ if(error&ER_AC_END)
end_ok=0;
- if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
+ if((error&ER_MV_END) || (error&ER_DC_END) || (error&ER_AC_ERROR))
end_ok=1;
if(!end_ok)
- s->error_status_table[mb_xy]|= AC_ERROR;
+ s->error_status_table[mb_xy]|= ER_AC_ERROR;
if(error&VP_START)
end_ok=0;
@@ -859,7 +859,7 @@ void ff_er_frame_end(MpegEncContext *s){
}
/* handle missing slices */
- if(s->error_recognition>=4){
+ if(s->err_recognition&AV_EF_EXPLODE){
int end_ok=1;
for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
@@ -870,14 +870,14 @@ void ff_er_frame_end(MpegEncContext *s){
if(error1&VP_START)
end_ok=1;
- if( error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
- && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
- && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninit
+ if( error2==(VP_START|ER_MB_ERROR|ER_MB_END)
+ && error1!=(VP_START|ER_MB_ERROR|ER_MB_END)
+ && ((error1&ER_AC_END) || (error1&ER_DC_END) || (error1&ER_MV_END))){ //end & uninit
end_ok=0;
}
if(!end_ok)
- s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
+ s->error_status_table[mb_xy]|= ER_MB_ERROR;
}
}
@@ -913,9 +913,9 @@ void ff_er_frame_end(MpegEncContext *s){
int old_error= s->error_status_table[mb_xy];
if(old_error&VP_START)
- error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
+ error= old_error& ER_MB_ERROR;
else{
- error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
+ error|= old_error& ER_MB_ERROR;
s->error_status_table[mb_xy]|= error;
}
}
@@ -925,8 +925,8 @@ void ff_er_frame_end(MpegEncContext *s){
for(i=0; i<s->mb_num; i++){
const int mb_xy= s->mb_index2xy[i];
error= s->error_status_table[mb_xy];
- if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
- error|= AC_ERROR|DC_ERROR|MV_ERROR;
+ if(error&ER_MB_ERROR)
+ error|= ER_MB_ERROR;
s->error_status_table[mb_xy]= error;
}
}
@@ -935,9 +935,9 @@ void ff_er_frame_end(MpegEncContext *s){
for(i=0; i<s->mb_num; i++){
const int mb_xy= s->mb_index2xy[i];
error= s->error_status_table[mb_xy];
- if(error&DC_ERROR) dc_error ++;
- if(error&AC_ERROR) ac_error ++;
- if(error&MV_ERROR) mv_error ++;
+ if(error&ER_DC_ERROR) dc_error ++;
+ if(error&ER_AC_ERROR) ac_error ++;
+ if(error&ER_MV_ERROR) mv_error ++;
}
av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);
@@ -947,34 +947,34 @@ void ff_er_frame_end(MpegEncContext *s){
for(i=0; i<s->mb_num; i++){
const int mb_xy= s->mb_index2xy[i];
error= s->error_status_table[mb_xy];
- if(!((error&DC_ERROR) && (error&MV_ERROR)))
+ if(!((error&ER_DC_ERROR) && (error&ER_MV_ERROR)))
continue;
if(is_intra_likely)
- s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
+ s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
else
- s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
}
// change inter to intra blocks if no reference frames are available
- if (!s->last_picture.data[0] && !s->next_picture.data[0])
+ if (!s->last_picture.f.data[0] && !s->next_picture.f.data[0])
for(i=0; i<s->mb_num; i++){
const int mb_xy= s->mb_index2xy[i];
- if(!IS_INTRA(s->current_picture.mb_type[mb_xy]))
- s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
+ if (!IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
+ s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
}
/* handle inter blocks with damaged AC */
for(mb_y=0; mb_y<s->mb_height; mb_y++){
for(mb_x=0; mb_x<s->mb_width; mb_x++){
const int mb_xy= mb_x + mb_y * s->mb_stride;
- const int mb_type= s->current_picture.mb_type[mb_xy];
- int dir = !s->last_picture.data[0];
+ const int mb_type= s->current_picture.f.mb_type[mb_xy];
+ int dir = !s->last_picture.f.data[0];
error= s->error_status_table[mb_xy];
if(IS_INTRA(mb_type)) continue; //intra
- if(error&MV_ERROR) continue; //inter with damaged MV
- if(!(error&AC_ERROR)) continue; //undamaged inter
+ if(error&ER_MV_ERROR) continue; //inter with damaged MV
+ if(!(error&ER_AC_ERROR)) continue; //undamaged inter
s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
s->mb_intra=0;
@@ -984,13 +984,13 @@ void ff_er_frame_end(MpegEncContext *s){
int j;
s->mv_type = MV_TYPE_8X8;
for(j=0; j<4; j++){
- s->mv[0][j][0] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
- s->mv[0][j][1] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
+ s->mv[0][j][0] = s->current_picture.f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
+ s->mv[0][j][1] = s->current_picture.f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
}
}else{
s->mv_type = MV_TYPE_16X16;
- s->mv[0][0][0] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
- s->mv[0][0][1] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
+ s->mv[0][0][0] = s->current_picture.f.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
+ s->mv[0][0][1] = s->current_picture.f.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
}
s->dsp.clear_blocks(s->block[0]);
@@ -1007,16 +1007,16 @@ void ff_er_frame_end(MpegEncContext *s){
for(mb_x=0; mb_x<s->mb_width; mb_x++){
int xy= mb_x*2 + mb_y*2*s->b8_stride;
const int mb_xy= mb_x + mb_y * s->mb_stride;
- const int mb_type= s->current_picture.mb_type[mb_xy];
+ const int mb_type= s->current_picture.f.mb_type[mb_xy];
error= s->error_status_table[mb_xy];
if(IS_INTRA(mb_type)) continue;
- if(!(error&MV_ERROR)) continue; //inter with undamaged MV
- if(!(error&AC_ERROR)) continue; //undamaged inter
+ if(!(error&ER_MV_ERROR)) continue; //inter with undamaged MV
+ if(!(error&ER_AC_ERROR)) continue; //undamaged inter
s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
- if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
- if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
+ if(!s->last_picture.f.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
+ if(!s->next_picture.f.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
s->mb_intra=0;
s->mv_type = MV_TYPE_16X16;
s->mb_skipped=0;
@@ -1031,10 +1031,10 @@ void ff_er_frame_end(MpegEncContext *s){
ff_thread_await_progress((AVFrame *) s->next_picture_ptr,
mb_y, 0);
}
- s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
- s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
- s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
- s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp;
+ s->mv[0][0][0] = s->next_picture.f.motion_val[0][xy][0] * time_pb / time_pp;
+ s->mv[0][0][1] = s->next_picture.f.motion_val[0][xy][1] * time_pb / time_pp;
+ s->mv[1][0][0] = s->next_picture.f.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
+ s->mv[1][0][1] = s->next_picture.f.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
}else{
s->mv[0][0][0]= 0;
s->mv[0][0][1]= 0;
@@ -1061,16 +1061,16 @@ void ff_er_frame_end(MpegEncContext *s){
int16_t *dc_ptr;
uint8_t *dest_y, *dest_cb, *dest_cr;
const int mb_xy= mb_x + mb_y * s->mb_stride;
- const int mb_type= s->current_picture.mb_type[mb_xy];
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
error= s->error_status_table[mb_xy];
if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
-// if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
+// if(error&ER_MV_ERROR) continue; //inter data damaged FIXME is this good?
- dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
- dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
- dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
+ dest_y = s->current_picture.f.data[0] + mb_x * 16 + mb_y * 16 * s->linesize;
+ dest_cb = s->current_picture.f.data[1] + mb_x * 8 + mb_y * 8 * s->uvlinesize;
+ dest_cr = s->current_picture.f.data[2] + mb_x * 8 + mb_y * 8 * s->uvlinesize;
dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
for(n=0; n<4; n++){
@@ -1110,16 +1110,16 @@ void ff_er_frame_end(MpegEncContext *s){
for(mb_x=0; mb_x<s->mb_width; mb_x++){
uint8_t *dest_y, *dest_cb, *dest_cr;
const int mb_xy= mb_x + mb_y * s->mb_stride;
- const int mb_type= s->current_picture.mb_type[mb_xy];
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
error= s->error_status_table[mb_xy];
if(IS_INTER(mb_type)) continue;
- if(!(error&AC_ERROR)) continue; //undamaged
+ if(!(error&ER_AC_ERROR)) continue; //undamaged
- dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
- dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
- dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
+ dest_y = s->current_picture.f.data[0] + mb_x * 16 + mb_y * 16 * s->linesize;
+ dest_cb = s->current_picture.f.data[1] + mb_x * 8 + mb_y * 8 * s->uvlinesize;
+ dest_cr = s->current_picture.f.data[2] + mb_x * 8 + mb_y * 8 * s->uvlinesize;
put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
}
@@ -1127,14 +1127,14 @@ void ff_er_frame_end(MpegEncContext *s){
if(s->avctx->error_concealment&FF_EC_DEBLOCK){
/* filter horizontal block boundaries */
- h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
- h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
- h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
+ h_block_filter(s, s->current_picture.f.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
+ h_block_filter(s, s->current_picture.f.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
+ h_block_filter(s, s->current_picture.f.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
/* filter vertical block boundaries */
- v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
- v_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
- v_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
+ v_block_filter(s, s->current_picture.f.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
+ v_block_filter(s, s->current_picture.f.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
+ v_block_filter(s, s->current_picture.f.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
}
ec_clean:
@@ -1143,7 +1143,7 @@ ec_clean:
const int mb_xy= s->mb_index2xy[i];
int error= s->error_status_table[mb_xy];
- if(s->pict_type!=AV_PICTURE_TYPE_B && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
+ if(s->pict_type!=AV_PICTURE_TYPE_B && (error&(ER_DC_ERROR|ER_MV_ERROR|ER_AC_ERROR))){
s->mbskip_table[mb_xy]=0;
}
s->mbintra_table[mb_xy]=1;
diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c
index 9d216a4..f6d7c82 100644
--- a/libavcodec/escape124.c
+++ b/libavcodec/escape124.c
@@ -21,7 +21,7 @@
#include "avcodec.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
typedef union MacroBlock {
@@ -364,15 +364,14 @@ static int escape124_decode_frame(AVCodecContext *avctx,
AVCodec ff_escape124_decoder = {
- "escape124",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ESCAPE124,
- sizeof(Escape124Context),
- escape124_decode_init,
- NULL,
- escape124_decode_close,
- escape124_decode_frame,
- CODEC_CAP_DR1,
+ .name = "escape124",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ESCAPE124,
+ .priv_data_size = sizeof(Escape124Context),
+ .init = escape124_decode_init,
+ .close = escape124_decode_close,
+ .decode = escape124_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Escape 124"),
};
diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c
index 79e8d75..e59dad6 100644
--- a/libavcodec/faxcompr.c
+++ b/libavcodec/faxcompr.c
@@ -20,8 +20,8 @@
*/
/**
- * CCITT Fax Group 3 and 4 decompression
* @file
+ * CCITT Fax Group 3 and 4 decompression
* @author Konstantin Shishkov
*/
#include "avcodec.h"
diff --git a/libavcodec/faxcompr.h b/libavcodec/faxcompr.h
index 4742d15..8157f1f 100644
--- a/libavcodec/faxcompr.h
+++ b/libavcodec/faxcompr.h
@@ -20,8 +20,8 @@
*/
/**
- * CCITT Fax Group 3 and 4 decompression
* @file
+ * CCITT Fax Group 3 and 4 decompression
* @author Konstantin Shishkov
*/
#ifndef AVCODEC_FAXCOMPR_H
diff --git a/libavcodec/fft-test.c b/libavcodec/fft-test.c
index 0112c6f..f890de6 100644
--- a/libavcodec/fft-test.c
+++ b/libavcodec/fft-test.c
@@ -37,8 +37,6 @@
#include <stdlib.h>
#include <string.h>
-#undef exit
-
/* reference fft */
#define MUL16(a,b) ((a) * (b))
@@ -228,7 +226,6 @@ static void help(void)
"-n b set the transform size to 2^b\n"
"-f x set scale factor for output data of (I)MDCT to x\n"
);
- exit(1);
}
enum tf_transform {
@@ -252,8 +249,9 @@ int main(int argc, char **argv)
#if CONFIG_FFT_FLOAT
RDFTContext r1, *r = &r1;
DCTContext d1, *d = &d1;
+ int fft_size_2;
#endif
- int fft_nbits, fft_size, fft_size_2;
+ int fft_nbits, fft_size;
double scale = 1.0;
AVLFG prng;
av_lfg_init(&prng, 1);
@@ -266,7 +264,7 @@ int main(int argc, char **argv)
switch(c) {
case 'h':
help();
- break;
+ return 1;
case 's':
do_speed = 1;
break;
@@ -292,7 +290,6 @@ int main(int argc, char **argv)
}
fft_size = 1 << fft_nbits;
- fft_size_2 = fft_size >> 1;
tab = av_malloc(fft_size * sizeof(FFTComplex));
tab1 = av_malloc(fft_size * sizeof(FFTComplex));
tab_ref = av_malloc(fft_size * sizeof(FFTComplex));
@@ -372,6 +369,7 @@ int main(int argc, char **argv)
break;
#if CONFIG_FFT_FLOAT
case TRANSFORM_RDFT:
+ fft_size_2 = fft_size >> 1;
if (do_inverse) {
tab1[ 0].im = 0;
tab1[fft_size_2].im = 0;
diff --git a/libavcodec/fft.h b/libavcodec/fft.h
index dc3c190..706f94b 100644
--- a/libavcodec/fft.h
+++ b/libavcodec/fft.h
@@ -119,7 +119,7 @@ extern COSTABLE_CONST FFTSample* const FFT_NAME(ff_cos_tabs)[17];
/**
* Initialize the cosine table in ff_cos_tabs[index]
- * \param index index in ff_cos_tabs array of the table to initialize
+ * @param index index in ff_cos_tabs array of the table to initialize
*/
void ff_init_ff_cos_tabs(int index);
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index ab2cc6e..8a6f33f 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -42,25 +42,6 @@
extern const uint8_t ff_log2_run[41];
-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,
- 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,
- 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,
- 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,
--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,
--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,
--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,
--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, 0,
-};
-
static const int8_t quant5_10bit[256]={
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -98,42 +79,7 @@ static const int8_t quant5[256]={
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,
};
-static const int8_t quant7[256]={
- 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,
-};
-static const int8_t quant9[256]={
- 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1,
-};
+
static const int8_t quant9_10bit[256]={
0, 0, 0, 0, 0, 1, 1, 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,
@@ -171,24 +117,6 @@ static const int8_t quant11[256]={
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1,
};
-static const int8_t quant13[256]={
- 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1,
-};
static const uint8_t ver2_state[256]= {
0, 10, 10, 10, 10, 16, 16, 16, 28, 16, 16, 29, 42, 49, 20, 49,
@@ -1796,28 +1724,26 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
}
AVCodec ff_ffv1_decoder = {
- "ffv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FFV1,
- sizeof(FFV1Context),
- decode_init,
- NULL,
- common_end,
- decode_frame,
- CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ | CODEC_CAP_SLICE_THREADS,
- NULL,
+ .name = "ffv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FFV1,
+ .priv_data_size = sizeof(FFV1Context),
+ .init = decode_init,
+ .close = common_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ | CODEC_CAP_SLICE_THREADS,
.long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
};
#if CONFIG_FFV1_ENCODER
AVCodec ff_ffv1_encoder = {
- "ffv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FFV1,
- sizeof(FFV1Context),
- encode_init,
- encode_frame,
- common_end,
+ .name = "ffv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FFV1,
+ .priv_data_size = sizeof(FFV1Context),
+ .init = encode_init,
+ .encode = encode_frame,
+ .close = common_end,
.capabilities = CODEC_CAP_SLICE_THREADS,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
diff --git a/libavcodec/flac.h b/libavcodec/flac.h
index 6ec8a37..b826fd4 100644
--- a/libavcodec/flac.h
+++ b/libavcodec/flac.h
@@ -95,8 +95,8 @@ typedef struct FLACFrameInfo {
* @param[out] s where parsed information is stored
* @param[in] buffer pointer to start of 34-byte streaminfo data
*/
-void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
- const uint8_t *buffer);
+void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
+ const uint8_t *buffer);
/**
* Validate the FLAC extradata.
@@ -105,9 +105,9 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
* @param[out] streaminfo_start pointer to start of 34-byte STREAMINFO data.
* @return 1 if valid, 0 if not valid.
*/
-int ff_flac_is_extradata_valid(AVCodecContext *avctx,
- enum FLACExtradataFormat *format,
- uint8_t **streaminfo_start);
+int avpriv_flac_is_extradata_valid(AVCodecContext *avctx,
+ enum FLACExtradataFormat *format,
+ uint8_t **streaminfo_start);
/**
* Parse the metadata block parameters from the header.
@@ -116,8 +116,8 @@ int ff_flac_is_extradata_valid(AVCodecContext *avctx,
* @param[out] type metadata block type
* @param[out] size metadata block size
*/
-void ff_flac_parse_block_header(const uint8_t *block_header,
- int *last, int *type, int *size);
+void avpriv_flac_parse_block_header(const uint8_t *block_header,
+ int *last, int *type, int *size);
/**
* Calculate an estimate for the maximum frame size based on verbatim mode.
diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c
index 947a5b6..87f3f95 100644
--- a/libavcodec/flac_parser.c
+++ b/libavcodec/flac_parser.c
@@ -674,9 +674,9 @@ static void flac_parse_close(AVCodecParserContext *c)
}
AVCodecParser ff_flac_parser = {
- { CODEC_ID_FLAC },
- sizeof(FLACParseContext),
- flac_parse_init,
- flac_parse,
- flac_parse_close,
+ .codec_ids = { CODEC_ID_FLAC },
+ .priv_data_size = sizeof(FLACParseContext),
+ .parser_init = flac_parse_init,
+ .parser_parse = flac_parse,
+ .parser_close = flac_parse_close,
};
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 1ce8559..58eb66d 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -23,9 +23,7 @@
* @file
* FLAC (Free Lossless Audio Codec) decoder
* @author Alex Beregszaszi
- *
- * For more information on the FLAC format, visit:
- * http://flac.sourceforge.net/
+ * @see http://flac.sourceforge.net/
*
* This decoder can be used in 1 of 2 ways: Either raw FLAC data can be fed
* through, starting from the initial 'fLaC' signature; or by passing the
@@ -51,6 +49,7 @@ typedef struct FLACContext {
FLACSTREAMINFO
AVCodecContext *avctx; ///< parent AVCodecContext
+ AVFrame frame;
GetBitContext gb; ///< GetBitContext initialized to start at the current frame
int blocksize; ///< number of samples in the current frame
@@ -65,7 +64,7 @@ typedef struct FLACContext {
static void allocate_buffers(FLACContext *s);
-int ff_flac_is_extradata_valid(AVCodecContext *avctx,
+int avpriv_flac_is_extradata_valid(AVCodecContext *avctx,
enum FLACExtradataFormat *format,
uint8_t **streaminfo_start)
{
@@ -106,11 +105,11 @@ static av_cold int flac_decode_init(AVCodecContext *avctx)
if (!avctx->extradata)
return 0;
- if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
+ if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo))
return -1;
/* initialize based on the demuxer-supplied streamdata header */
- ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo);
+ avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo);
if (s->bps > 16)
avctx->sample_fmt = AV_SAMPLE_FMT_S32;
else
@@ -118,6 +117,9 @@ static av_cold int flac_decode_init(AVCodecContext *avctx)
allocate_buffers(s);
s->got_streaminfo = 1;
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
@@ -142,7 +144,7 @@ static void allocate_buffers(FLACContext *s)
}
}
-void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
+void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
const uint8_t *buffer)
{
GetBitContext gb;
@@ -176,7 +178,7 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
dump_headers(avctx, s);
}
-void ff_flac_parse_block_header(const uint8_t *block_header,
+void avpriv_flac_parse_block_header(const uint8_t *block_header,
int *last, int *type, int *size)
{
int tmp = bytestream_get_byte(&block_header);
@@ -203,12 +205,12 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size)
/* need more data */
return 0;
}
- ff_flac_parse_block_header(&buf[4], NULL, &metadata_type, &metadata_size);
+ avpriv_flac_parse_block_header(&buf[4], NULL, &metadata_type, &metadata_size);
if (metadata_type != FLAC_METADATA_TYPE_STREAMINFO ||
metadata_size != FLAC_STREAMINFO_SIZE) {
return AVERROR_INVALIDDATA;
}
- ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]);
+ avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]);
allocate_buffers(s);
s->got_streaminfo = 1;
@@ -228,9 +230,11 @@ static int get_metadata_size(const uint8_t *buf, int buf_size)
buf += 4;
do {
- ff_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size);
+ if (buf_end - buf < 4)
+ return 0;
+ avpriv_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size);
buf += 4;
- if (buf + metadata_size > buf_end) {
+ if (buf_end - buf < metadata_size) {
/* need more data in order to read the complete header */
return 0;
}
@@ -542,20 +546,18 @@ static int decode_frame(FLACContext *s)
return 0;
}
-static int flac_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int flac_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
FLACContext *s = avctx->priv_data;
int i, j = 0, bytes_read = 0;
- int16_t *samples_16 = data;
- int32_t *samples_32 = data;
- int alloc_data_size= *data_size;
- int output_size;
+ int16_t *samples_16;
+ int32_t *samples_32;
+ int ret;
- *data_size=0;
+ *got_frame_ptr = 0;
if (s->max_framesize == 0) {
s->max_framesize =
@@ -586,14 +588,14 @@ static int flac_decode_frame(AVCodecContext *avctx,
}
bytes_read = (get_bits_count(&s->gb)+7)/8;
- /* check if allocated data size is large enough for output */
- output_size = s->blocksize * s->channels * (s->is32 ? 4 : 2);
- if (output_size > alloc_data_size) {
- av_log(s->avctx, AV_LOG_ERROR, "output data size is larger than "
- "allocated data size\n");
- return -1;
+ /* get output buffer */
+ s->frame.nb_samples = s->blocksize;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
- *data_size = output_size;
+ samples_16 = (int16_t *)s->frame.data[0];
+ samples_32 = (int32_t *)s->frame.data[0];
#define DECORRELATE(left, right)\
assert(s->channels == 2);\
@@ -638,6 +640,9 @@ static int flac_decode_frame(AVCodecContext *avctx,
buf_size - bytes_read, buf_size);
}
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return bytes_read;
}
@@ -654,13 +659,13 @@ static av_cold int flac_decode_close(AVCodecContext *avctx)
}
AVCodec ff_flac_decoder = {
- "flac",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_FLAC,
- sizeof(FLACContext),
- flac_decode_init,
- NULL,
- flac_decode_close,
- flac_decode_frame,
+ .name = "flac",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_FLAC,
+ .priv_data_size = sizeof(FLACContext),
+ .init = flac_decode_init,
+ .close = flac_decode_close,
+ .decode = flac_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name= NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
};
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index be775ca..94e381d 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -1330,22 +1330,22 @@ static av_cold int flac_encode_close(AVCodecContext *avctx)
#define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption options[] = {
-{ "lpc_coeff_precision", "LPC coefficient precision", offsetof(FlacEncodeContext, options.lpc_coeff_precision), FF_OPT_TYPE_INT, {.dbl = 15 }, 0, MAX_LPC_PRECISION, FLAGS },
-{ "lpc_type", "LPC algorithm", offsetof(FlacEncodeContext, options.lpc_type), FF_OPT_TYPE_INT, {.dbl = FF_LPC_TYPE_DEFAULT }, FF_LPC_TYPE_DEFAULT, FF_LPC_TYPE_NB-1, FLAGS, "lpc_type" },
-{ "none", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_LPC_TYPE_NONE }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
-{ "fixed", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_LPC_TYPE_FIXED }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
-{ "levinson", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_LPC_TYPE_LEVINSON }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
-{ "cholesky", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_LPC_TYPE_CHOLESKY }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
-{ "lpc_passes", "Number of passes to use for Cholesky factorization during LPC analysis", offsetof(FlacEncodeContext, options.lpc_passes), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, FLAGS },
-{ "min_partition_order", NULL, offsetof(FlacEncodeContext, options.min_partition_order), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, MAX_PARTITION_ORDER, FLAGS },
-{ "max_partition_order", NULL, offsetof(FlacEncodeContext, options.max_partition_order), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, MAX_PARTITION_ORDER, FLAGS },
-{ "prediction_order_method", "Search method for selecting prediction order", offsetof(FlacEncodeContext, options.prediction_order_method), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, ORDER_METHOD_LOG, FLAGS, "predm" },
-{ "estimation", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_EST }, INT_MIN, INT_MAX, FLAGS, "predm" },
-{ "2level", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_2LEVEL }, INT_MIN, INT_MAX, FLAGS, "predm" },
-{ "4level", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_4LEVEL }, INT_MIN, INT_MAX, FLAGS, "predm" },
-{ "8level", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_8LEVEL }, INT_MIN, INT_MAX, FLAGS, "predm" },
-{ "search", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_SEARCH }, INT_MIN, INT_MAX, FLAGS, "predm" },
-{ "log", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_LOG }, INT_MIN, INT_MAX, FLAGS, "predm" },
+{ "lpc_coeff_precision", "LPC coefficient precision", offsetof(FlacEncodeContext, options.lpc_coeff_precision), AV_OPT_TYPE_INT, {.dbl = 15 }, 0, MAX_LPC_PRECISION, FLAGS },
+{ "lpc_type", "LPC algorithm", offsetof(FlacEncodeContext, options.lpc_type), AV_OPT_TYPE_INT, {.dbl = FF_LPC_TYPE_DEFAULT }, FF_LPC_TYPE_DEFAULT, FF_LPC_TYPE_NB-1, FLAGS, "lpc_type" },
+{ "none", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_LPC_TYPE_NONE }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
+{ "fixed", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_LPC_TYPE_FIXED }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
+{ "levinson", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_LPC_TYPE_LEVINSON }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
+{ "cholesky", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_LPC_TYPE_CHOLESKY }, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
+{ "lpc_passes", "Number of passes to use for Cholesky factorization during LPC analysis", offsetof(FlacEncodeContext, options.lpc_passes), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, FLAGS },
+{ "min_partition_order", NULL, offsetof(FlacEncodeContext, options.min_partition_order), AV_OPT_TYPE_INT, {.dbl = -1 }, -1, MAX_PARTITION_ORDER, FLAGS },
+{ "max_partition_order", NULL, offsetof(FlacEncodeContext, options.max_partition_order), AV_OPT_TYPE_INT, {.dbl = -1 }, -1, MAX_PARTITION_ORDER, FLAGS },
+{ "prediction_order_method", "Search method for selecting prediction order", offsetof(FlacEncodeContext, options.prediction_order_method), AV_OPT_TYPE_INT, {.dbl = -1 }, -1, ORDER_METHOD_LOG, FLAGS, "predm" },
+{ "estimation", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_EST }, INT_MIN, INT_MAX, FLAGS, "predm" },
+{ "2level", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_2LEVEL }, INT_MIN, INT_MAX, FLAGS, "predm" },
+{ "4level", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_4LEVEL }, INT_MIN, INT_MAX, FLAGS, "predm" },
+{ "8level", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_8LEVEL }, INT_MIN, INT_MAX, FLAGS, "predm" },
+{ "search", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_SEARCH }, INT_MIN, INT_MAX, FLAGS, "predm" },
+{ "log", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = ORDER_METHOD_LOG }, INT_MIN, INT_MAX, FLAGS, "predm" },
{ NULL },
};
@@ -1357,14 +1357,13 @@ static const AVClass flac_encoder_class = {
};
AVCodec ff_flac_encoder = {
- "flac",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_FLAC,
- sizeof(FlacEncodeContext),
- flac_encode_init,
- flac_encode_frame,
- flac_encode_close,
- NULL,
+ .name = "flac",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_FLAC,
+ .priv_data_size = sizeof(FlacEncodeContext),
+ .init = flac_encode_init,
+ .encode = flac_encode_frame,
+ .close = flac_encode_close,
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index a958bda..c99c21c 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -25,35 +25,29 @@
* Flash Screen Video decoder
* @author Alex Beregszaszi
* @author Benjamin Larsson
- */
-
-/* Bitstream description
- * The picture is divided into blocks that are zlib compressed.
- *
- * The decoder is fed complete frames, the frameheader contains:
- * 4bits of block width
- * 12bits of frame width
- * 4bits of block height
- * 12bits of frame height
+ * @author Daniel Verkamp
+ * @author Konstantin Shishkov
*
- * Directly after the header are the compressed blocks. The blocks
- * have their compressed size represented with 16bits in the beginnig.
- * If the size = 0 then the block is unchanged from the previous frame.
- * All blocks are decompressed until the buffer is consumed.
- *
- * Encoding ideas, a basic encoder would just use a fixed block size.
- * Block sizes can be multipels of 16, from 16 to 256. The blocks don't
- * have to be quadratic. A brute force search with a set of diffrent
- * block sizes should give a better result then to just use a fixed size.
+ * A description of the bitstream format for Flash Screen Video version 1/2
+ * is part of the SWF File Format Specification (version 10), which can be
+ * downloaded from http://www.adobe.com/devnet/swf.html.
*/
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>
+#include "libavutil/intreadwrite.h"
#include "avcodec.h"
+#include "bytestream.h"
#include "get_bits.h"
+typedef struct BlockInfo {
+ uint8_t *pos;
+ int size;
+ int unp_size;
+} BlockInfo;
+
typedef struct FlashSVContext {
AVCodecContext *avctx;
AVFrame frame;
@@ -62,21 +56,50 @@ typedef struct FlashSVContext {
uint8_t *tmpblock;
int block_size;
z_stream zstream;
+ int ver;
+ const uint32_t *pal;
+ int is_keyframe;
+ uint8_t *keyframedata;
+ uint8_t *keyframe;
+ BlockInfo *blocks;
+ uint8_t *deflate_block;
+ int deflate_block_size;
+ int color_depth;
+ int zlibprime_curr, zlibprime_prev;
+ int diff_start, diff_height;
} FlashSVContext;
-static void copy_region(uint8_t *sptr, uint8_t *dptr,
- int dx, int dy, int h, int w, int stride)
+static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
+ int h, int w, int stride, const uint32_t *pal)
{
- int i;
-
- for (i = dx + h; i > dx; i--) {
- memcpy(dptr + (i * stride) + dy * 3, sptr, w * 3);
- sptr += w * 3;
+ int x, y;
+ const uint8_t *orig_src = sptr;
+
+ for (y = dx+h; y > dx; y--) {
+ uint8_t *dst = dptr + (y * stride) + dy * 3;
+ for (x = 0; x < w; x++) {
+ if (*sptr & 0x80) {
+ /* 15-bit color */
+ unsigned c = AV_RB16(sptr) & ~0x8000;
+ unsigned b = c & 0x1F;
+ unsigned g = (c >> 5) & 0x1F;
+ unsigned r = c >> 10;
+ /* 000aaabb -> aaabbaaa */
+ *dst++ = (b << 3) | (b >> 2);
+ *dst++ = (g << 3) | (g >> 2);
+ *dst++ = (r << 3) | (r >> 2);
+ sptr += 2;
+ } else {
+ /* palette index */
+ uint32_t c = pal[*sptr++];
+ bytestream_put_le24(&dst, c);
+ }
+ }
}
+ return sptr - orig_src;
}
-
static av_cold int flashsv_decode_init(AVCodecContext *avctx)
{
FlashSVContext *s = avctx->priv_data;
@@ -86,7 +109,7 @@ static av_cold int flashsv_decode_init(AVCodecContext *avctx)
s->zstream.zalloc = Z_NULL;
s->zstream.zfree = Z_NULL;
s->zstream.opaque = Z_NULL;
- zret = inflateInit(&(s->zstream));
+ zret = inflateInit(&s->zstream);
if (zret != Z_OK) {
av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
return 1;
@@ -98,10 +121,114 @@ static av_cold int flashsv_decode_init(AVCodecContext *avctx)
}
+static void flashsv2_prime(FlashSVContext *s, uint8_t *src,
+ int size, int unp_size)
+{
+ z_stream zs;
+
+ zs.zalloc = NULL;
+ zs.zfree = NULL;
+ zs.opaque = NULL;
+
+ s->zstream.next_in = src;
+ s->zstream.avail_in = size;
+ s->zstream.next_out = s->tmpblock;
+ s->zstream.avail_out = s->block_size * 3;
+ inflate(&s->zstream, Z_SYNC_FLUSH);
+
+ deflateInit(&zs, 0);
+ zs.next_in = s->tmpblock;
+ zs.avail_in = s->block_size * 3 - s->zstream.avail_out;
+ zs.next_out = s->deflate_block;
+ zs.avail_out = s->deflate_block_size;
+ deflate(&zs, Z_SYNC_FLUSH);
+ deflateEnd(&zs);
+
+ inflateReset(&s->zstream);
+
+ s->zstream.next_in = s->deflate_block;
+ s->zstream.avail_in = s->deflate_block_size - zs.avail_out;
+ s->zstream.next_out = s->tmpblock;
+ s->zstream.avail_out = s->block_size * 3;
+ inflate(&s->zstream, Z_SYNC_FLUSH);
+}
+
+static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
+ GetBitContext *gb, int block_size,
+ int width, int height, int x_pos, int y_pos,
+ int blk_idx)
+{
+ struct FlashSVContext *s = avctx->priv_data;
+ uint8_t *line = s->tmpblock;
+ int k;
+ int ret = inflateReset(&s->zstream);
+ if (ret != Z_OK) {
+ //return -1;
+ }
+ if (s->zlibprime_curr || s->zlibprime_prev) {
+ flashsv2_prime(s, s->blocks[blk_idx].pos, s->blocks[blk_idx].size,
+ s->blocks[blk_idx].unp_size);
+ }
+ s->zstream.next_in = avpkt->data + get_bits_count(gb) / 8;
+ s->zstream.avail_in = block_size;
+ s->zstream.next_out = s->tmpblock;
+ s->zstream.avail_out = s->block_size * 3;
+ ret = inflate(&s->zstream, Z_FINISH);
+ if (ret == Z_DATA_ERROR) {
+ av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
+ inflateSync(&s->zstream);
+ ret = inflate(&s->zstream, Z_FINISH);
+ }
+
+ if (ret != Z_OK && ret != Z_STREAM_END) {
+ //return -1;
+ }
+
+ if (s->is_keyframe) {
+ s->blocks[blk_idx].pos = s->keyframedata + (get_bits_count(gb) / 8);
+ s->blocks[blk_idx].size = block_size;
+ s->blocks[blk_idx].unp_size = s->block_size * 3 - s->zstream.avail_out;
+ }
+ if (!s->color_depth) {
+ /* Flash Screen Video stores the image upside down, so copy
+ * lines to destination in reverse order. */
+ for (k = 1; k <= s->diff_height; k++) {
+ memcpy(s->frame.data[0] + x_pos * 3 +
+ (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0],
+ line, width * 3);
+ /* advance source pointer to next line */
+ line += width * 3;
+ }
+ } else {
+ /* hybrid 15-bit/palette mode */
+ decode_hybrid(s->tmpblock, s->frame.data[0],
+ s->image_height - (y_pos + 1 + s->diff_start + s->diff_height),
+ x_pos, s->diff_height, width,
+ s->frame.linesize[0], s->pal);
+ }
+ skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
+ return 0;
+}
+
+static int calc_deflate_block_size(int tmpblock_size)
+{
+ z_stream zstream;
+ int size;
+
+ zstream.zalloc = Z_NULL;
+ zstream.zfree = Z_NULL;
+ zstream.opaque = Z_NULL;
+ if (deflateInit(&zstream, 0) != Z_OK)
+ return -1;
+ size = deflateBound(&zstream, tmpblock_size);
+ deflateEnd(&zstream);
+
+ return size;
+}
+
static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
int *data_size, AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
FlashSVContext *s = avctx->priv_data;
int h_blocks, v_blocks, h_part, v_part, i, j;
@@ -113,7 +240,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
if (buf_size < 4)
return -1;
- init_get_bits(&gb, buf, buf_size * 8);
+ init_get_bits(&gb, avpkt->data, buf_size * 8);
/* start to parse the bitstream */
s->block_width = 16 * (get_bits(&gb, 4) + 1);
@@ -121,7 +248,19 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
s->block_height = 16 * (get_bits(&gb, 4) + 1);
s->image_height = get_bits(&gb, 12);
- /* calculate amount of blocks and the size of the border blocks */
+ if (s->ver == 2) {
+ skip_bits(&gb, 6);
+ if (get_bits1(&gb)) {
+ av_log_missing_feature(avctx, "iframe", 1);
+ return AVERROR_PATCHWELCOME;
+ }
+ if (get_bits1(&gb)) {
+ av_log_missing_feature(avctx, "custom palette", 1);
+ return AVERROR_PATCHWELCOME;
+ }
+ }
+
+ /* calculate number of blocks and size of border (partial) blocks */
h_blocks = s->image_width / s->block_width;
h_part = s->image_width % s->block_width;
v_blocks = s->image_height / s->block_height;
@@ -130,34 +269,61 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
/* the block size could change between frames, make sure the buffer
* is large enough, if not, get a larger one */
if (s->block_size < s->block_width * s->block_height) {
- av_free(s->tmpblock);
- if ((s->tmpblock = av_malloc(3 * s->block_width * s->block_height)) == NULL) {
+ int tmpblock_size = 3 * s->block_width * s->block_height;
+
+ s->tmpblock = av_realloc(s->tmpblock, tmpblock_size);
+ if (!s->tmpblock) {
av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
return AVERROR(ENOMEM);
}
+ if (s->ver == 2) {
+ s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
+ if (s->deflate_block_size <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n");
+ return -1;
+ }
+ s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size);
+ if (!s->deflate_block) {
+ av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n");
+ return AVERROR(ENOMEM);
+ }
+ }
}
s->block_size = s->block_width * s->block_height;
- /* init the image size once */
- if ((avctx->width == 0) && (avctx->height == 0)) {
+ /* initialize the image size once */
+ if (avctx->width == 0 && avctx->height == 0) {
avctx->width = s->image_width;
avctx->height = s->image_height;
}
/* check for changes of image width and image height */
- if ((avctx->width != s->image_width) || (avctx->height != s->image_height)) {
- av_log(avctx, AV_LOG_ERROR, "Frame width or height differs from first frames!\n");
- av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d vs ch = %d, cv = %d\n", avctx->height,
- avctx->width, s->image_height, s->image_width);
- return -1;
+ if (avctx->width != s->image_width || avctx->height != s->image_height) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Frame width or height differs from first frame!\n");
+ av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d vs ch = %d, cv = %d\n",
+ avctx->height, avctx->width, s->image_height, s->image_width);
+ return AVERROR_INVALIDDATA;
}
- av_log(avctx, AV_LOG_DEBUG, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
- s->image_width, s->image_height, s->block_width, s->block_height,
- h_blocks, v_blocks, h_part, v_part);
+ /* we care for keyframes only in Screen Video v2 */
+ s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
+ if (s->is_keyframe) {
+ s->keyframedata = av_realloc(s->keyframedata, avpkt->size);
+ memcpy(s->keyframedata, avpkt->data, avpkt->size);
+ s->blocks = av_realloc(s->blocks,
+ (v_blocks + !!v_part) * (h_blocks + !!h_part)
+ * sizeof(s->blocks[0]));
+ }
- s->frame.reference = 1;
- s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
+ av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
+ s->image_width, s->image_height, s->block_width, s->block_height,
+ h_blocks, v_blocks, h_part, v_part);
+
+ s->frame.reference = 3;
+ s->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
+ FF_BUFFER_HINTS_PRESERVE |
+ FF_BUFFER_HINTS_REUSABLE;
if (avctx->reget_buffer(avctx, &s->frame) < 0) {
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1;
@@ -166,53 +332,97 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
/* loop over all block columns */
for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
- int hp = j * s->block_height; // horiz position in frame
- int hs = (j < v_blocks) ? s->block_height : v_part; // size of block
-
+ int y_pos = j * s->block_height; // vertical position in frame
+ int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;
/* loop over all block rows */
for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
- int wp = i * s->block_width; // vert position in frame
- int ws = (i < h_blocks) ? s->block_width : h_part; // size of block
+ int x_pos = i * s->block_width; // horizontal position in frame
+ int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
+ int has_diff = 0;
/* get the size of the compressed zlib chunk */
int size = get_bits(&gb, 16);
+
+ s->color_depth = 0;
+ s->zlibprime_curr = 0;
+ s->zlibprime_prev = 0;
+ s->diff_start = 0;
+ s->diff_height = cur_blk_height;
+
if (8 * size > get_bits_left(&gb)) {
avctx->release_buffer(avctx, &s->frame);
s->frame.data[0] = NULL;
- return -1;
+ return AVERROR_INVALIDDATA;
}
- if (size == 0) {
- /* no change, don't do anything */
- } else {
- /* decompress block */
- int ret = inflateReset(&(s->zstream));
- if (ret != Z_OK) {
- av_log(avctx, AV_LOG_ERROR, "error in decompression (reset) of block %dx%d\n", i, j);
- /* return -1; */
+ if (s->ver == 2 && size) {
+ skip_bits(&gb, 3);
+ s->color_depth = get_bits(&gb, 2);
+ has_diff = get_bits1(&gb);
+ s->zlibprime_curr = get_bits1(&gb);
+ s->zlibprime_prev = get_bits1(&gb);
+
+ if (s->color_depth != 0 && s->color_depth != 2) {
+ av_log(avctx, AV_LOG_ERROR,
+ "%dx%d invalid color depth %d\n", i, j, s->color_depth);
+ return AVERROR_INVALIDDATA;
}
- s->zstream.next_in = buf + (get_bits_count(&gb) / 8);
- s->zstream.avail_in = size;
- s->zstream.next_out = s->tmpblock;
- s->zstream.avail_out = s->block_size * 3;
- ret = inflate(&(s->zstream), Z_FINISH);
- if (ret == Z_DATA_ERROR) {
- av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
- inflateSync(&(s->zstream));
- ret = inflate(&(s->zstream), Z_FINISH);
+
+ if (has_diff) {
+ s->diff_start = get_bits(&gb, 8);
+ s->diff_height = get_bits(&gb, 8);
+ av_log(avctx, AV_LOG_DEBUG,
+ "%dx%d diff start %d height %d\n",
+ i, j, s->diff_start, s->diff_height);
+ size -= 2;
}
- if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
- av_log(avctx, AV_LOG_ERROR, "error in decompression of block %dx%d: %d\n", i, j, ret);
- /* return -1; */
+ if (s->zlibprime_prev)
+ av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);
+
+ if (s->zlibprime_curr) {
+ int col = get_bits(&gb, 8);
+ int row = get_bits(&gb, 8);
+ av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row);
+ size -= 2;
+ av_log_missing_feature(avctx, "zlibprime_curr", 1);
+ return AVERROR_PATCHWELCOME;
}
- copy_region(s->tmpblock, s->frame.data[0], s->image_height - (hp + hs + 1),
- wp, hs, ws, s->frame.linesize[0]);
- skip_bits_long(&gb, 8 * size); /* skip the consumed bits */
+ size--; // account for flags byte
+ }
+
+ if (has_diff) {
+ int k;
+ int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];
+
+ for (k = 0; k < cur_blk_height; k++)
+ memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3,
+ s->keyframe + off - k*s->frame.linesize[0] + x_pos*3,
+ cur_blk_width * 3);
+ }
+
+ /* skip unchanged blocks, which have size 0 */
+ if (size) {
+ if (flashsv_decode_block(avctx, avpkt, &gb, size,
+ cur_blk_width, cur_blk_height,
+ x_pos, y_pos,
+ i + j * (h_blocks + !!h_part)))
+ av_log(avctx, AV_LOG_ERROR,
+ "error in decompression of block %dx%d\n", i, j);
}
}
}
+ if (s->is_keyframe && s->ver == 2) {
+ if (!s->keyframe) {
+ s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);
+ if (!s->keyframe) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
+ return AVERROR(ENOMEM);
+ }
+ }
+ memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
+ }
*data_size = sizeof(AVFrame);
*(AVFrame*)data = s->frame;
@@ -229,7 +439,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
static av_cold int flashsv_decode_end(AVCodecContext *avctx)
{
FlashSVContext *s = avctx->priv_data;
- inflateEnd(&(s->zstream));
+ inflateEnd(&s->zstream);
/* release the frame if needed */
if (s->frame.data[0])
avctx->release_buffer(avctx, &s->frame);
@@ -241,6 +451,7 @@ static av_cold int flashsv_decode_end(AVCodecContext *avctx)
}
+#if CONFIG_FLASHSV_DECODER
AVCodec ff_flashsv_decoder = {
.name = "flashsv",
.type = AVMEDIA_TYPE_VIDEO,
@@ -253,3 +464,67 @@ AVCodec ff_flashsv_decoder = {
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
};
+#endif /* CONFIG_FLASHSV_DECODER */
+
+#if CONFIG_FLASHSV2_DECODER
+static const uint32_t ff_flashsv2_default_palette[128] = {
+ 0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
+ 0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
+ 0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
+ 0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
+ 0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
+ 0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
+ 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
+ 0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
+ 0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
+ 0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
+ 0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
+ 0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
+ 0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
+ 0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
+ 0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
+ 0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
+ 0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
+ 0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
+ 0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
+ 0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
+ 0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
+ 0xDDDDDD, 0xEEEEEE
+};
+
+static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
+{
+ FlashSVContext *s = avctx->priv_data;
+ flashsv_decode_init(avctx);
+ s->pal = ff_flashsv2_default_palette;
+ s->ver = 2;
+
+ return 0;
+}
+
+static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
+{
+ FlashSVContext *s = avctx->priv_data;
+
+ av_freep(&s->keyframedata);
+ av_freep(&s->blocks);
+ av_freep(&s->keyframe);
+ av_freep(&s->deflate_block);
+ flashsv_decode_end(avctx);
+
+ return 0;
+}
+
+AVCodec ff_flashsv2_decoder = {
+ .name = "flashsv2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FLASHSV2,
+ .priv_data_size = sizeof(FlashSVContext),
+ .init = flashsv2_decode_init,
+ .close = flashsv2_decode_end,
+ .decode = flashsv_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .pix_fmts = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
+ .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
+};
+#endif /* CONFIG_FLASHSV2_DECODER */
diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c
index ad14104..81aa5b6 100644
--- a/libavcodec/flashsvenc.c
+++ b/libavcodec/flashsvenc.c
@@ -27,31 +27,21 @@
* Flash Screen Video encoder
* @author Alex Beregszaszi
* @author Benjamin Larsson
+ *
+ * A description of the bitstream format for Flash Screen Video version 1/2
+ * is part of the SWF File Format Specification (version 10), which can be
+ * downloaded from http://www.adobe.com/devnet/swf.html.
*/
-/* Bitstream description
- * The picture is divided into blocks that are zlib-compressed.
- *
- * The decoder is fed complete frames, the frameheader contains:
- * 4bits of block width
- * 12bits of frame width
- * 4bits of block height
- * 12bits of frame height
- *
- * Directly after the header are the compressed blocks. The blocks
- * have their compressed size represented with 16bits in the beginig.
- * If the size = 0 then the block is unchanged from the previous frame.
- * All blocks are decompressed until the buffer is consumed.
- *
- * Encoding ideas, a basic encoder would just use a fixed block size.
- * Block sizes can be multipels of 16, from 16 to 256. The blocks don't
+/*
+ * Encoding ideas: A basic encoder would just use a fixed block size.
+ * Block sizes can be multiples of 16, from 16 to 256. The blocks don't
* have to be quadratic. A brute force search with a set of different
* block sizes should give a better result than to just use a fixed size.
- */
-
-/* TODO:
- * Don't reencode the frame in brute force mode if the frame is a dupe. Speed up.
- * Make the difference check faster.
+ *
+ * TODO:
+ * Don't reencode the frame in brute force mode if the frame is a dupe.
+ * Speed up. Make the difference check faster.
*/
#include <stdio.h>
@@ -85,8 +75,8 @@ static int copy_region_enc(uint8_t *sptr, uint8_t *dptr, int dx, int dy,
int diff = 0;
for (i = dx + h; i > dx; i--) {
- nsptr = sptr + (i * stride) + dy * 3;
- npfptr = pfptr + (i * stride) + dy * 3;
+ nsptr = sptr + i * stride + dy * 3;
+ npfptr = pfptr + i * stride + dy * 3;
for (j = 0; j < w * 3; j++) {
diff |= npfptr[j] ^ nsptr[j];
dptr[j] = nsptr[j];
@@ -104,13 +94,14 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx)
s->avctx = avctx;
- if ((avctx->width > 4095) || (avctx->height > 4095)) {
- av_log(avctx, AV_LOG_ERROR, "Input dimensions too large, input must be max 4096x4096 !\n");
+ if (avctx->width > 4095 || avctx->height > 4095) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Input dimensions too large, input must be max 4096x4096 !\n");
return AVERROR_INVALIDDATA;
}
// Needed if zlib unused or init aborted before deflateInit
- memset(&(s->zstream), 0, sizeof(z_stream));
+ memset(&s->zstream, 0, sizeof(z_stream));
s->last_key_frame = 0;
@@ -141,9 +132,9 @@ static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf,
init_put_bits(&pb, buf, buf_size * 8);
- put_bits(&pb, 4, (block_width / 16) - 1);
+ put_bits(&pb, 4, block_width / 16 - 1);
put_bits(&pb, 12, s->image_width);
- put_bits(&pb, 4, (block_height / 16) - 1);
+ put_bits(&pb, 4, block_height / 16 - 1);
put_bits(&pb, 12, s->image_height);
flush_put_bits(&pb);
buf_pos = 4;
@@ -156,37 +147,36 @@ static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf,
/* loop over all block columns */
for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
- int hp = j * block_height; // horiz position in frame
- int hs = (j < v_blocks) ? block_height : v_part; // size of block
+ int y_pos = j * block_height; // vertical position in frame
+ int cur_blk_height = (j < v_blocks) ? block_height : v_part;
/* loop over all block rows */
for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
- int wp = i * block_width; // vert position in frame
- int ws = (i < h_blocks) ? block_width : h_part; // size of block
+ int x_pos = i * block_width; // horizontal position in frame
+ int cur_blk_width = (i < h_blocks) ? block_width : h_part;
int ret = Z_OK;
- uint8_t *ptr;
-
- ptr = buf + buf_pos;
+ uint8_t *ptr = buf + buf_pos;
/* copy the block to the temp buffer before compression
* (if it differs from the previous frame's block) */
res = copy_region_enc(p->data[0], s->tmpblock,
- s->image_height - (hp + hs + 1),
- wp, hs, ws, p->linesize[0], previous_frame);
+ s->image_height - (y_pos + cur_blk_height + 1),
+ x_pos, cur_blk_height, cur_blk_width,
+ p->linesize[0], previous_frame);
if (res || *I_frame) {
- unsigned long zsize;
- zsize = 3 * block_width * block_height;
- ret = compress2(ptr + 2, &zsize, s->tmpblock, 3 * ws * hs, 9);
-
+ unsigned long zsize = 3 * block_width * block_height;
+ ret = compress2(ptr + 2, &zsize, s->tmpblock,
+ 3 * cur_blk_width * cur_blk_height, 9);
- //ret = deflateReset(&(s->zstream));
+ //ret = deflateReset(&s->zstream);
if (ret != Z_OK)
- av_log(s->avctx, AV_LOG_ERROR, "error while compressing block %dx%d\n", i, j);
+ av_log(s->avctx, AV_LOG_ERROR,
+ "error while compressing block %dx%d\n", i, j);
- bytestream_put_be16(&ptr, (unsigned int) zsize);
+ bytestream_put_be16(&ptr, zsize);
buf_pos += zsize + 2;
- //av_log(avctx, AV_LOG_ERROR, "buf_pos = %d\n", buf_pos);
+ av_dlog(s->avctx, "buf_pos = %d\n", buf_pos);
} else {
pred_blocks++;
bytestream_put_be16(&ptr, 0);
@@ -213,7 +203,7 @@ static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf,
uint8_t *pfptr;
int res;
int I_frame = 0;
- int opt_w, opt_h;
+ int opt_w = 4, opt_h = 4;
*p = *pict;
@@ -228,42 +218,40 @@ static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf,
}
if (p->linesize[0] < 0)
- pfptr = s->previous_frame - ((s->image_height - 1) * p->linesize[0]);
+ pfptr = s->previous_frame - (s->image_height - 1) * p->linesize[0];
else
pfptr = s->previous_frame;
/* Check the placement of keyframes */
- if (avctx->gop_size > 0) {
- if (avctx->frame_number >= s->last_key_frame + avctx->gop_size) {
- I_frame = 1;
- }
+ if (avctx->gop_size > 0 &&
+ avctx->frame_number >= s->last_key_frame + avctx->gop_size) {
+ I_frame = 1;
}
- opt_w = 4;
- opt_h = 4;
-
- if (buf_size < s->image_width*s->image_height*3) {
+ if (buf_size < s->image_width * s->image_height * 3) {
//Conservative upper bound check for compressed data
av_log(avctx, AV_LOG_ERROR, "buf_size %d < %d\n",
buf_size, s->image_width * s->image_height * 3);
return -1;
}
- res = encode_bitstream(s, p, buf, buf_size, opt_w * 16, opt_h * 16, pfptr, &I_frame);
+ res = encode_bitstream(s, p, buf, buf_size, opt_w * 16, opt_h * 16,
+ pfptr, &I_frame);
//save the current frame
if (p->linesize[0] > 0)
memcpy(s->previous_frame, p->data[0], s->image_height * p->linesize[0]);
else
- memcpy(s->previous_frame, p->data[0] + p->linesize[0] * (s->image_height - 1),
+ memcpy(s->previous_frame,
+ p->data[0] + p->linesize[0] * (s->image_height - 1),
s->image_height * FFABS(p->linesize[0]));
//mark the frame type so the muxer can mux it correctly
if (I_frame) {
- p->pict_type = AV_PICTURE_TYPE_I;
- p->key_frame = 1;
+ p->pict_type = AV_PICTURE_TYPE_I;
+ p->key_frame = 1;
s->last_key_frame = avctx->frame_number;
- av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n", avctx->frame_number);
+ av_dlog(avctx, "Inserting keyframe at frame %d\n", avctx->frame_number);
} else {
p->pict_type = AV_PICTURE_TYPE_P;
p->key_frame = 0;
@@ -278,7 +266,7 @@ static av_cold int flashsv_encode_end(AVCodecContext *avctx)
{
FlashSVContext *s = avctx->priv_data;
- deflateEnd(&(s->zstream));
+ deflateEnd(&s->zstream);
av_free(s->encbuffer);
av_free(s->previous_frame);
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index ed9972c..8e8a813 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -81,6 +81,12 @@ static av_cold int flic_decode_init(AVCodecContext *avctx)
unsigned char *fli_header = (unsigned char *)avctx->extradata;
int depth;
+ if (avctx->extradata_size != 12 &&
+ avctx->extradata_size != 128) {
+ av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
+ return AVERROR_INVALIDDATA;
+ }
+
s->avctx = avctx;
s->fli_type = AV_RL16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */
@@ -90,9 +96,6 @@ static av_cold int flic_decode_init(AVCodecContext *avctx)
/* special case for magic carpet FLIs */
s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
depth = 8;
- } else if (s->avctx->extradata_size != 128) {
- av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
- return -1;
} else {
depth = AV_RL16(&fli_header[12]);
}
@@ -112,7 +115,6 @@ static av_cold int flic_decode_init(AVCodecContext *avctx)
case 24 : avctx->pix_fmt = PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */
av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n");
return -1;
- break;
default :
av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
return -1;
@@ -743,18 +745,13 @@ static av_cold int flic_decode_end(AVCodecContext *avctx)
}
AVCodec ff_flic_decoder = {
- "flic",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FLIC,
- sizeof(FlicDecodeContext),
- flic_decode_init,
- NULL,
- flic_decode_end,
- flic_decode_frame,
- CODEC_CAP_DR1,
- NULL,
- NULL,
- NULL,
- NULL,
+ .name = "flic",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FLIC,
+ .priv_data_size = sizeof(FlicDecodeContext),
+ .init = flic_decode_init,
+ .close = flic_decode_end,
+ .decode = flic_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
};
diff --git a/libavcodec/flvdec.c b/libavcodec/flvdec.c
index 9546c1c..29d6808 100644
--- a/libavcodec/flvdec.c
+++ b/libavcodec/flvdec.c
@@ -119,15 +119,14 @@ int ff_flv_decode_picture_header(MpegEncContext *s)
}
AVCodec ff_flv_decoder = {
- "flv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FLV1,
- sizeof(MpegEncContext),
- ff_h263_decode_init,
- NULL,
- ff_h263_decode_end,
- ff_h263_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+ .name = "flv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FLV1,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_h263_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
.max_lowres= 3,
.long_name= NULL_IF_CONFIG_SMALL("Flash Video (FLV) / Sorenson Spark / Sorenson H.263"),
.pix_fmts= ff_pixfmt_list_420,
diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index 28bca2e..c0d9a04 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -25,7 +25,7 @@ void ff_flv_encode_picture_header(MpegEncContext * s, int picture_number)
{
int format;
- align_put_bits(&s->pb);
+ avpriv_align_put_bits(&s->pb);
put_bits(&s->pb, 17, 1);
put_bits(&s->pb, 5, (s->h263_flv-1)); /* 0: h263 escape codes 1: 11-bit escape codes */
@@ -85,13 +85,13 @@ void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level, int run, in
}
AVCodec ff_flv_encoder = {
- "flv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FLV1,
- sizeof(MpegEncContext),
- MPV_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "flv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FLV1,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = MPV_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("Flash Video (FLV) / Sorenson Spark / Sorenson H.263"),
};
diff --git a/libavcodec/fmtconvert.h b/libavcodec/fmtconvert.h
index d774113..1b53401 100644
--- a/libavcodec/fmtconvert.h
+++ b/libavcodec/fmtconvert.h
@@ -70,7 +70,15 @@ typedef struct FmtConvertContext {
long len, int channels);
/**
- * Convert an array of interleaved float to multiple arrays of float.
+ * Convert multiple arrays of float to an array of interleaved float.
+ *
+ * @param dst destination array of interleaved float.
+ * constraints: 16-byte aligned
+ * @param src source array of float arrays, one for each channel.
+ * constraints: 16-byte aligned
+ * @param len number of elements to convert.
+ * constraints: multiple of 8
+ * @param channels number of channels
*/
void (*float_interleave)(float *dst, const float **src, unsigned int len,
int channels);
diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c
index 2bbc7b9..1444eda 100644
--- a/libavcodec/fraps.c
+++ b/libavcodec/fraps.c
@@ -111,6 +111,10 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w,
*/
if(j) dst[i] += dst[i - stride];
else if(Uoff) dst[i] += 0x80;
+ if (get_bits_left(&gb) < 0) {
+ free_vlc(&vlc);
+ return AVERROR_INVALIDDATA;
+ }
}
dst += stride;
}
@@ -356,14 +360,13 @@ static av_cold int decode_end(AVCodecContext *avctx)
AVCodec ff_fraps_decoder = {
- "fraps",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FRAPS,
- sizeof(FrapsContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "fraps",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FRAPS,
+ .priv_data_size = sizeof(FrapsContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Fraps"),
};
diff --git a/libavcodec/frwu.c b/libavcodec/frwu.c
index ee3d2e4..061c460 100644
--- a/libavcodec/frwu.c
+++ b/libavcodec/frwu.c
@@ -110,14 +110,12 @@ static av_cold int decode_close(AVCodecContext *avctx)
}
AVCodec ff_frwu_decoder = {
- "FRWU",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FRWU,
- 0,
- decode_init,
- NULL,
- decode_close,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "FRWU",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FRWU,
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Forward Uncompressed"),
};
diff --git a/libavcodec/g722.c b/libavcodec/g722.c
index 257292d..7b9ff72 100644
--- a/libavcodec/g722.c
+++ b/libavcodec/g722.c
@@ -26,7 +26,6 @@
/**
* @file
- *
* G.722 ADPCM audio codec
*
* This G.722 decoder is a bit-exact implementation of the ITU G.722
@@ -37,45 +36,8 @@
* respectively of each byte are ignored.
*/
-#include "avcodec.h"
#include "mathops.h"
-#include "get_bits.h"
-
-#define PREV_SAMPLES_BUF_SIZE 1024
-
-#define FREEZE_INTERVAL 128
-
-typedef struct {
- int16_t prev_samples[PREV_SAMPLES_BUF_SIZE]; ///< memory of past decoded samples
- int prev_samples_pos; ///< the number of values in prev_samples
-
- /**
- * The band[0] and band[1] correspond respectively to the lower band and higher band.
- */
- struct G722Band {
- int16_t s_predictor; ///< predictor output value
- int32_t s_zero; ///< previous output signal from zero predictor
- int8_t part_reconst_mem[2]; ///< signs of previous partially reconstructed signals
- int16_t prev_qtzd_reconst; ///< previous quantized reconstructed signal (internal value, using low_inv_quant4)
- int16_t pole_mem[2]; ///< second-order pole section coefficient buffer
- int32_t diff_mem[6]; ///< quantizer difference signal memory
- int16_t zero_mem[6]; ///< Seventh-order zero section coefficient buffer
- int16_t log_factor; ///< delayed 2-logarithmic quantizer factor
- int16_t scale_factor; ///< delayed quantizer scale factor
- } band[2];
-
- struct TrellisNode {
- struct G722Band state;
- uint32_t ssd;
- int path;
- } *node_buf[2], **nodep_buf[2];
-
- struct TrellisPath {
- int value;
- int prev;
- } *paths[2];
-} G722Context;
-
+#include "g722.h"
static const int8_t sign_lookup[2] = { -1, 1 };
@@ -86,7 +48,7 @@ static const int16_t inv_log2_table[32] = {
3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008
};
static const int16_t high_log_factor_step[2] = { 798, -214 };
-static const int16_t high_inv_quant[4] = { -926, -202, 926, 202 };
+const int16_t ff_g722_high_inv_quant[4] = { -926, -202, 926, 202 };
/**
* low_log_factor_step[index] == wl[rl42[index]]
*/
@@ -94,11 +56,11 @@ static const int16_t low_log_factor_step[16] = {
-60, 3042, 1198, 538, 334, 172, 58, -30,
3042, 1198, 538, 334, 172, 58, -30, -60
};
-static const int16_t low_inv_quant4[16] = {
+const int16_t ff_g722_low_inv_quant4[16] = {
0, -2557, -1612, -1121, -786, -530, -323, -150,
2557, 1612, 1121, 786, 530, 323, 150, 0
};
-static const int16_t low_inv_quant6[64] = {
+const int16_t ff_g722_low_inv_quant6[64] = {
-17, -17, -17, -17, -3101, -2738, -2376, -2088,
-1873, -1689, -1535, -1399, -1279, -1170, -1072, -982,
-899, -822, -750, -682, -618, -558, -501, -447,
@@ -174,10 +136,10 @@ static int inline linear_scale_factor(const int log_factor)
return shift < 0 ? wd1 >> -shift : wd1 << shift;
}
-static void update_low_predictor(struct G722Band *band, const int ilow)
+void ff_g722_update_low_predictor(struct G722Band *band, const int ilow)
{
do_adaptive_prediction(band,
- band->scale_factor * low_inv_quant4[ilow] >> 10);
+ band->scale_factor * ff_g722_low_inv_quant4[ilow] >> 10);
// quantizer adaptation
band->log_factor = av_clip((band->log_factor * 127 >> 7) +
@@ -185,7 +147,7 @@ static void update_low_predictor(struct G722Band *band, const int ilow)
band->scale_factor = linear_scale_factor(band->log_factor - (8 << 11));
}
-static void update_high_predictor(struct G722Band *band, const int dhigh,
+void ff_g722_update_high_predictor(struct G722Band *band, const int dhigh,
const int ihigh)
{
do_adaptive_prediction(band, dhigh);
@@ -196,7 +158,7 @@ static void update_high_predictor(struct G722Band *band, const int dhigh,
band->scale_factor = linear_scale_factor(band->log_factor - (10 << 11));
}
-static void apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2)
+void ff_g722_apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2)
{
int i;
@@ -207,377 +169,3 @@ static void apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2)
MAC16(*xout1, prev_samples[2*i+1], qmf_coeffs[11-i]);
}
}
-
-static av_cold int g722_init(AVCodecContext * avctx)
-{
- G722Context *c = avctx->priv_data;
-
- if (avctx->channels != 1) {
- av_log(avctx, AV_LOG_ERROR, "Only mono tracks are allowed.\n");
- return AVERROR_INVALIDDATA;
- }
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-
- switch (avctx->bits_per_coded_sample) {
- case 8:
- case 7:
- case 6:
- break;
- default:
- av_log(avctx, AV_LOG_WARNING, "Unsupported bits_per_coded_sample [%d], "
- "assuming 8\n",
- avctx->bits_per_coded_sample);
- case 0:
- avctx->bits_per_coded_sample = 8;
- break;
- }
-
- c->band[0].scale_factor = 8;
- c->band[1].scale_factor = 2;
- c->prev_samples_pos = 22;
-
- if (avctx->lowres)
- avctx->sample_rate /= 2;
-
- if (avctx->trellis) {
- int frontier = 1 << avctx->trellis;
- int max_paths = frontier * FREEZE_INTERVAL;
- int i;
- for (i = 0; i < 2; i++) {
- c->paths[i] = av_mallocz(max_paths * sizeof(**c->paths));
- c->node_buf[i] = av_mallocz(2 * frontier * sizeof(**c->node_buf));
- c->nodep_buf[i] = av_mallocz(2 * frontier * sizeof(**c->nodep_buf));
- }
- }
-
- return 0;
-}
-
-static av_cold int g722_close(AVCodecContext *avctx)
-{
- G722Context *c = avctx->priv_data;
- int i;
- for (i = 0; i < 2; i++) {
- av_freep(&c->paths[i]);
- av_freep(&c->node_buf[i]);
- av_freep(&c->nodep_buf[i]);
- }
- return 0;
-}
-
-#if CONFIG_ADPCM_G722_DECODER
-static const int16_t low_inv_quant5[32] = {
- -35, -35, -2919, -2195, -1765, -1458, -1219, -1023,
- -858, -714, -587, -473, -370, -276, -190, -110,
- 2919, 2195, 1765, 1458, 1219, 1023, 858, 714,
- 587, 473, 370, 276, 190, 110, 35, -35
-};
-
-static const int16_t *low_inv_quants[3] = { low_inv_quant6, low_inv_quant5,
- low_inv_quant4 };
-
-static int g722_decode_frame(AVCodecContext *avctx, void *data,
- int *data_size, AVPacket *avpkt)
-{
- G722Context *c = avctx->priv_data;
- int16_t *out_buf = data;
- int j, out_len = 0;
- const int skip = 8 - avctx->bits_per_coded_sample;
- const int16_t *quantizer_table = low_inv_quants[skip];
- GetBitContext gb;
-
- init_get_bits(&gb, avpkt->data, avpkt->size * 8);
-
- for (j = 0; j < avpkt->size; j++) {
- int ilow, ihigh, rlow;
-
- ihigh = get_bits(&gb, 2);
- ilow = get_bits(&gb, 6 - skip);
- skip_bits(&gb, skip);
-
- rlow = av_clip((c->band[0].scale_factor * quantizer_table[ilow] >> 10)
- + c->band[0].s_predictor, -16384, 16383);
-
- update_low_predictor(&c->band[0], ilow >> (2 - skip));
-
- if (!avctx->lowres) {
- const int dhigh = c->band[1].scale_factor *
- high_inv_quant[ihigh] >> 10;
- const int rhigh = av_clip(dhigh + c->band[1].s_predictor,
- -16384, 16383);
- int xout1, xout2;
-
- update_high_predictor(&c->band[1], dhigh, ihigh);
-
- c->prev_samples[c->prev_samples_pos++] = rlow + rhigh;
- c->prev_samples[c->prev_samples_pos++] = rlow - rhigh;
- apply_qmf(c->prev_samples + c->prev_samples_pos - 24,
- &xout1, &xout2);
- out_buf[out_len++] = av_clip_int16(xout1 >> 12);
- out_buf[out_len++] = av_clip_int16(xout2 >> 12);
- if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) {
- memmove(c->prev_samples,
- c->prev_samples + c->prev_samples_pos - 22,
- 22 * sizeof(c->prev_samples[0]));
- c->prev_samples_pos = 22;
- }
- } else
- out_buf[out_len++] = rlow;
- }
- *data_size = out_len << 1;
- return avpkt->size;
-}
-
-AVCodec ff_adpcm_g722_decoder = {
- .name = "g722",
- .type = AVMEDIA_TYPE_AUDIO,
- .id = CODEC_ID_ADPCM_G722,
- .priv_data_size = sizeof(G722Context),
- .init = g722_init,
- .decode = g722_decode_frame,
- .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
- .max_lowres = 1,
-};
-#endif
-
-#if CONFIG_ADPCM_G722_ENCODER
-static const int16_t low_quant[33] = {
- 35, 72, 110, 150, 190, 233, 276, 323,
- 370, 422, 473, 530, 587, 650, 714, 786,
- 858, 940, 1023, 1121, 1219, 1339, 1458, 1612,
- 1765, 1980, 2195, 2557, 2919
-};
-
-static inline void filter_samples(G722Context *c, const int16_t *samples,
- int *xlow, int *xhigh)
-{
- int xout1, xout2;
- c->prev_samples[c->prev_samples_pos++] = samples[0];
- c->prev_samples[c->prev_samples_pos++] = samples[1];
- apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2);
- *xlow = xout1 + xout2 >> 13;
- *xhigh = xout1 - xout2 >> 13;
- if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) {
- memmove(c->prev_samples,
- c->prev_samples + c->prev_samples_pos - 22,
- 22 * sizeof(c->prev_samples[0]));
- c->prev_samples_pos = 22;
- }
-}
-
-static inline int encode_high(const struct G722Band *state, int xhigh)
-{
- int diff = av_clip_int16(xhigh - state->s_predictor);
- int pred = 141 * state->scale_factor >> 8;
- /* = diff >= 0 ? (diff < pred) + 2 : diff >= -pred */
- return ((diff ^ (diff >> (sizeof(diff)*8-1))) < pred) + 2*(diff >= 0);
-}
-
-static inline int encode_low(const struct G722Band* state, int xlow)
-{
- int diff = av_clip_int16(xlow - state->s_predictor);
- /* = diff >= 0 ? diff : -(diff + 1) */
- int limit = diff ^ (diff >> (sizeof(diff)*8-1));
- int i = 0;
- limit = limit + 1 << 10;
- if (limit > low_quant[8] * state->scale_factor)
- i = 9;
- while (i < 29 && limit > low_quant[i] * state->scale_factor)
- i++;
- return (diff < 0 ? (i < 2 ? 63 : 33) : 61) - i;
-}
-
-static int g722_encode_trellis(AVCodecContext *avctx,
- uint8_t *dst, int buf_size, void *data)
-{
- G722Context *c = avctx->priv_data;
- const int16_t *samples = data;
- int i, j, k;
- int frontier = 1 << avctx->trellis;
- struct TrellisNode **nodes[2];
- struct TrellisNode **nodes_next[2];
- int pathn[2] = {0, 0}, froze = -1;
- struct TrellisPath *p[2];
-
- for (i = 0; i < 2; i++) {
- nodes[i] = c->nodep_buf[i];
- nodes_next[i] = c->nodep_buf[i] + frontier;
- memset(c->nodep_buf[i], 0, 2 * frontier * sizeof(*c->nodep_buf));
- nodes[i][0] = c->node_buf[i] + frontier;
- nodes[i][0]->ssd = 0;
- nodes[i][0]->path = 0;
- nodes[i][0]->state = c->band[i];
- }
-
- for (i = 0; i < buf_size >> 1; i++) {
- int xlow, xhigh;
- struct TrellisNode *next[2];
- int heap_pos[2] = {0, 0};
-
- for (j = 0; j < 2; j++) {
- next[j] = c->node_buf[j] + frontier*(i & 1);
- memset(nodes_next[j], 0, frontier * sizeof(**nodes_next));
- }
-
- filter_samples(c, &samples[2*i], &xlow, &xhigh);
-
- for (j = 0; j < frontier && nodes[0][j]; j++) {
- /* Only k >> 2 affects the future adaptive state, therefore testing
- * small steps that don't change k >> 2 is useless, the orignal
- * value from encode_low is better than them. Since we step k
- * in steps of 4, make sure range is a multiple of 4, so that
- * we don't miss the original value from encode_low. */
- int range = j < frontier/2 ? 4 : 0;
- struct TrellisNode *cur_node = nodes[0][j];
-
- int ilow = encode_low(&cur_node->state, xlow);
-
- for (k = ilow - range; k <= ilow + range && k <= 63; k += 4) {
- int decoded, dec_diff, pos;
- uint32_t ssd;
- struct TrellisNode* node;
-
- if (k < 0)
- continue;
-
- decoded = av_clip((cur_node->state.scale_factor *
- low_inv_quant6[k] >> 10)
- + cur_node->state.s_predictor, -16384, 16383);
- dec_diff = xlow - decoded;
-
-#define STORE_NODE(index, UPDATE, VALUE)\
- ssd = cur_node->ssd + dec_diff*dec_diff;\
- /* Check for wraparound. Using 64 bit ssd counters would \
- * be simpler, but is slower on x86 32 bit. */\
- if (ssd < cur_node->ssd)\
- continue;\
- if (heap_pos[index] < frontier) {\
- pos = heap_pos[index]++;\
- assert(pathn[index] < FREEZE_INTERVAL * frontier);\
- node = nodes_next[index][pos] = next[index]++;\
- node->path = pathn[index]++;\
- } else {\
- /* Try to replace one of the leaf nodes with the new \
- * one, but not always testing the same leaf position */\
- pos = (frontier>>1) + (heap_pos[index] & ((frontier>>1) - 1));\
- if (ssd >= nodes_next[index][pos]->ssd)\
- continue;\
- heap_pos[index]++;\
- node = nodes_next[index][pos];\
- }\
- node->ssd = ssd;\
- node->state = cur_node->state;\
- UPDATE;\
- c->paths[index][node->path].value = VALUE;\
- c->paths[index][node->path].prev = cur_node->path;\
- /* Sift the newly inserted node up in the heap to restore \
- * the heap property */\
- while (pos > 0) {\
- int parent = (pos - 1) >> 1;\
- if (nodes_next[index][parent]->ssd <= ssd)\
- break;\
- FFSWAP(struct TrellisNode*, nodes_next[index][parent],\
- nodes_next[index][pos]);\
- pos = parent;\
- }
- STORE_NODE(0, update_low_predictor(&node->state, k >> 2), k);
- }
- }
-
- for (j = 0; j < frontier && nodes[1][j]; j++) {
- int ihigh;
- struct TrellisNode *cur_node = nodes[1][j];
-
- /* We don't try to get any initial guess for ihigh via
- * encode_high - since there's only 4 possible values, test
- * them all. Testing all of these gives a much, much larger
- * gain than testing a larger range around ilow. */
- for (ihigh = 0; ihigh < 4; ihigh++) {
- int dhigh, decoded, dec_diff, pos;
- uint32_t ssd;
- struct TrellisNode* node;
-
- dhigh = cur_node->state.scale_factor *
- high_inv_quant[ihigh] >> 10;
- decoded = av_clip(dhigh + cur_node->state.s_predictor,
- -16384, 16383);
- dec_diff = xhigh - decoded;
-
- STORE_NODE(1, update_high_predictor(&node->state, dhigh, ihigh), ihigh);
- }
- }
-
- for (j = 0; j < 2; j++) {
- FFSWAP(struct TrellisNode**, nodes[j], nodes_next[j]);
-
- if (nodes[j][0]->ssd > (1 << 16)) {
- for (k = 1; k < frontier && nodes[j][k]; k++)
- nodes[j][k]->ssd -= nodes[j][0]->ssd;
- nodes[j][0]->ssd = 0;
- }
- }
-
- if (i == froze + FREEZE_INTERVAL) {
- p[0] = &c->paths[0][nodes[0][0]->path];
- p[1] = &c->paths[1][nodes[1][0]->path];
- for (j = i; j > froze; j--) {
- dst[j] = p[1]->value << 6 | p[0]->value;
- p[0] = &c->paths[0][p[0]->prev];
- p[1] = &c->paths[1][p[1]->prev];
- }
- froze = i;
- pathn[0] = pathn[1] = 0;
- memset(nodes[0] + 1, 0, (frontier - 1)*sizeof(**nodes));
- memset(nodes[1] + 1, 0, (frontier - 1)*sizeof(**nodes));
- }
- }
-
- p[0] = &c->paths[0][nodes[0][0]->path];
- p[1] = &c->paths[1][nodes[1][0]->path];
- for (j = i; j > froze; j--) {
- dst[j] = p[1]->value << 6 | p[0]->value;
- p[0] = &c->paths[0][p[0]->prev];
- p[1] = &c->paths[1][p[1]->prev];
- }
- c->band[0] = nodes[0][0]->state;
- c->band[1] = nodes[1][0]->state;
-
- return i;
-}
-
-static int g722_encode_frame(AVCodecContext *avctx,
- uint8_t *dst, int buf_size, void *data)
-{
- G722Context *c = avctx->priv_data;
- const int16_t *samples = data;
- int i;
-
- if (avctx->trellis)
- return g722_encode_trellis(avctx, dst, buf_size, data);
-
- for (i = 0; i < buf_size >> 1; i++) {
- int xlow, xhigh, ihigh, ilow;
- filter_samples(c, &samples[2*i], &xlow, &xhigh);
- ihigh = encode_high(&c->band[1], xhigh);
- ilow = encode_low(&c->band[0], xlow);
- update_high_predictor(&c->band[1], c->band[1].scale_factor *
- high_inv_quant[ihigh] >> 10, ihigh);
- update_low_predictor(&c->band[0], ilow >> 2);
- *dst++ = ihigh << 6 | ilow;
- }
- return i;
-}
-
-AVCodec ff_adpcm_g722_encoder = {
- .name = "g722",
- .type = AVMEDIA_TYPE_AUDIO,
- .id = CODEC_ID_ADPCM_G722,
- .priv_data_size = sizeof(G722Context),
- .init = g722_init,
- .close = g722_close,
- .encode = g722_encode_frame,
- .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
- .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
-};
-#endif
-
diff --git a/libavcodec/g722.h b/libavcodec/g722.h
new file mode 100644
index 0000000..eb3b9b8
--- /dev/null
+++ b/libavcodec/g722.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) CMU 1993 Computer Science, Speech Group
+ * Chengxiang Lu and Alex Hauptmann
+ * Copyright (c) 2005 Steve Underwood <steveu at coppice.org>
+ * Copyright (c) 2009 Kenan Gillet
+ * Copyright (c) 2010 Martin Storsjo
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_G722_H
+#define AVCODEC_G722_H
+
+#include <stdint.h>
+#include "avcodec.h"
+
+#define PREV_SAMPLES_BUF_SIZE 1024
+
+typedef struct {
+ const AVClass *class;
+ AVFrame frame;
+ int bits_per_codeword;
+ int16_t prev_samples[PREV_SAMPLES_BUF_SIZE]; ///< memory of past decoded samples
+ int prev_samples_pos; ///< the number of values in prev_samples
+
+ /**
+ * The band[0] and band[1] correspond respectively to the lower band and higher band.
+ */
+ struct G722Band {
+ int16_t s_predictor; ///< predictor output value
+ int32_t s_zero; ///< previous output signal from zero predictor
+ int8_t part_reconst_mem[2]; ///< signs of previous partially reconstructed signals
+ int16_t prev_qtzd_reconst; ///< previous quantized reconstructed signal (internal value, using low_inv_quant4)
+ int16_t pole_mem[2]; ///< second-order pole section coefficient buffer
+ int32_t diff_mem[6]; ///< quantizer difference signal memory
+ int16_t zero_mem[6]; ///< Seventh-order zero section coefficient buffer
+ int16_t log_factor; ///< delayed 2-logarithmic quantizer factor
+ int16_t scale_factor; ///< delayed quantizer scale factor
+ } band[2];
+
+ struct TrellisNode {
+ struct G722Band state;
+ uint32_t ssd;
+ int path;
+ } *node_buf[2], **nodep_buf[2];
+
+ struct TrellisPath {
+ int value;
+ int prev;
+ } *paths[2];
+} G722Context;
+
+extern const int16_t ff_g722_high_inv_quant[4];
+extern const int16_t ff_g722_low_inv_quant4[16];
+extern const int16_t ff_g722_low_inv_quant6[64];
+
+void ff_g722_update_low_predictor(struct G722Band *band, const int ilow);
+
+void ff_g722_update_high_predictor(struct G722Band *band, const int dhigh,
+ const int ihigh);
+
+void ff_g722_apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2);
+
+#endif /* AVCODEC_G722_H */
diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c
new file mode 100644
index 0000000..50a224b
--- /dev/null
+++ b/libavcodec/g722dec.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) CMU 1993 Computer Science, Speech Group
+ * Chengxiang Lu and Alex Hauptmann
+ * Copyright (c) 2005 Steve Underwood <steveu at coppice.org>
+ * Copyright (c) 2009 Kenan Gillet
+ * Copyright (c) 2010 Martin Storsjo
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * G.722 ADPCM audio decoder
+ *
+ * This G.722 decoder is a bit-exact implementation of the ITU G.722
+ * specification for all three specified bitrates - 64000bps, 56000bps
+ * and 48000bps. It passes the ITU tests.
+ *
+ * @note For the 56000bps and 48000bps bitrates, the lowest 1 or 2 bits
+ * respectively of each byte are ignored.
+ */
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "g722.h"
+#include "libavutil/opt.h"
+
+#define OFFSET(x) offsetof(G722Context, x)
+#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ { "bits_per_codeword", "Bits per G722 codeword", OFFSET(bits_per_codeword), AV_OPT_TYPE_FLAGS, { 8 }, 6, 8, AD },
+ { NULL }
+};
+
+static const AVClass g722_decoder_class = {
+ .class_name = "g722 decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static av_cold int g722_decode_init(AVCodecContext * avctx)
+{
+ G722Context *c = avctx->priv_data;
+
+ if (avctx->channels != 1) {
+ av_log(avctx, AV_LOG_ERROR, "Only mono tracks are allowed.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ c->band[0].scale_factor = 8;
+ c->band[1].scale_factor = 2;
+ c->prev_samples_pos = 22;
+
+ avcodec_get_frame_defaults(&c->frame);
+ avctx->coded_frame = &c->frame;
+
+ return 0;
+}
+
+static const int16_t low_inv_quant5[32] = {
+ -35, -35, -2919, -2195, -1765, -1458, -1219, -1023,
+ -858, -714, -587, -473, -370, -276, -190, -110,
+ 2919, 2195, 1765, 1458, 1219, 1023, 858, 714,
+ 587, 473, 370, 276, 190, 110, 35, -35
+};
+
+static const int16_t *low_inv_quants[3] = { ff_g722_low_inv_quant6,
+ low_inv_quant5,
+ ff_g722_low_inv_quant4 };
+
+static int g722_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ G722Context *c = avctx->priv_data;
+ int16_t *out_buf;
+ int j, ret;
+ const int skip = 8 - c->bits_per_codeword;
+ const int16_t *quantizer_table = low_inv_quants[skip];
+ GetBitContext gb;
+
+ /* get output buffer */
+ c->frame.nb_samples = avpkt->size * 2;
+ if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ out_buf = (int16_t *)c->frame.data[0];
+
+ init_get_bits(&gb, avpkt->data, avpkt->size * 8);
+
+ for (j = 0; j < avpkt->size; j++) {
+ int ilow, ihigh, rlow, rhigh, dhigh;
+ int xout1, xout2;
+
+ ihigh = get_bits(&gb, 2);
+ ilow = get_bits(&gb, 6 - skip);
+ skip_bits(&gb, skip);
+
+ rlow = av_clip((c->band[0].scale_factor * quantizer_table[ilow] >> 10)
+ + c->band[0].s_predictor, -16384, 16383);
+
+ ff_g722_update_low_predictor(&c->band[0], ilow >> (2 - skip));
+
+ dhigh = c->band[1].scale_factor * ff_g722_high_inv_quant[ihigh] >> 10;
+ rhigh = av_clip(dhigh + c->band[1].s_predictor, -16384, 16383);
+
+ ff_g722_update_high_predictor(&c->band[1], dhigh, ihigh);
+
+ c->prev_samples[c->prev_samples_pos++] = rlow + rhigh;
+ c->prev_samples[c->prev_samples_pos++] = rlow - rhigh;
+ ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24,
+ &xout1, &xout2);
+ *out_buf++ = av_clip_int16(xout1 >> 12);
+ *out_buf++ = av_clip_int16(xout2 >> 12);
+ if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) {
+ memmove(c->prev_samples, c->prev_samples + c->prev_samples_pos - 22,
+ 22 * sizeof(c->prev_samples[0]));
+ c->prev_samples_pos = 22;
+ }
+ }
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = c->frame;
+
+ return avpkt->size;
+}
+
+AVCodec ff_adpcm_g722_decoder = {
+ .name = "g722",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ADPCM_G722,
+ .priv_data_size = sizeof(G722Context),
+ .init = g722_decode_init,
+ .decode = g722_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
+ .priv_class = &g722_decoder_class,
+};
diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c
new file mode 100644
index 0000000..1eed784
--- /dev/null
+++ b/libavcodec/g722enc.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) CMU 1993 Computer Science, Speech Group
+ * Chengxiang Lu and Alex Hauptmann
+ * Copyright (c) 2005 Steve Underwood <steveu at coppice.org>
+ * Copyright (c) 2009 Kenan Gillet
+ * Copyright (c) 2010 Martin Storsjo
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * G.722 ADPCM audio encoder
+ */
+
+#include "avcodec.h"
+#include "g722.h"
+
+#define FREEZE_INTERVAL 128
+
+static av_cold int g722_encode_init(AVCodecContext * avctx)
+{
+ G722Context *c = avctx->priv_data;
+
+ if (avctx->channels != 1) {
+ av_log(avctx, AV_LOG_ERROR, "Only mono tracks are allowed.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ c->band[0].scale_factor = 8;
+ c->band[1].scale_factor = 2;
+ c->prev_samples_pos = 22;
+
+ if (avctx->trellis) {
+ int frontier = 1 << avctx->trellis;
+ int max_paths = frontier * FREEZE_INTERVAL;
+ int i;
+ for (i = 0; i < 2; i++) {
+ c->paths[i] = av_mallocz(max_paths * sizeof(**c->paths));
+ c->node_buf[i] = av_mallocz(2 * frontier * sizeof(**c->node_buf));
+ c->nodep_buf[i] = av_mallocz(2 * frontier * sizeof(**c->nodep_buf));
+ }
+ }
+
+ return 0;
+}
+
+static av_cold int g722_encode_close(AVCodecContext *avctx)
+{
+ G722Context *c = avctx->priv_data;
+ int i;
+ for (i = 0; i < 2; i++) {
+ av_freep(&c->paths[i]);
+ av_freep(&c->node_buf[i]);
+ av_freep(&c->nodep_buf[i]);
+ }
+ return 0;
+}
+
+static const int16_t low_quant[33] = {
+ 35, 72, 110, 150, 190, 233, 276, 323,
+ 370, 422, 473, 530, 587, 650, 714, 786,
+ 858, 940, 1023, 1121, 1219, 1339, 1458, 1612,
+ 1765, 1980, 2195, 2557, 2919
+};
+
+static inline void filter_samples(G722Context *c, const int16_t *samples,
+ int *xlow, int *xhigh)
+{
+ int xout1, xout2;
+ c->prev_samples[c->prev_samples_pos++] = samples[0];
+ c->prev_samples[c->prev_samples_pos++] = samples[1];
+ ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2);
+ *xlow = xout1 + xout2 >> 13;
+ *xhigh = xout1 - xout2 >> 13;
+ if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) {
+ memmove(c->prev_samples,
+ c->prev_samples + c->prev_samples_pos - 22,
+ 22 * sizeof(c->prev_samples[0]));
+ c->prev_samples_pos = 22;
+ }
+}
+
+static inline int encode_high(const struct G722Band *state, int xhigh)
+{
+ int diff = av_clip_int16(xhigh - state->s_predictor);
+ int pred = 141 * state->scale_factor >> 8;
+ /* = diff >= 0 ? (diff < pred) + 2 : diff >= -pred */
+ return ((diff ^ (diff >> (sizeof(diff)*8-1))) < pred) + 2*(diff >= 0);
+}
+
+static inline int encode_low(const struct G722Band* state, int xlow)
+{
+ int diff = av_clip_int16(xlow - state->s_predictor);
+ /* = diff >= 0 ? diff : -(diff + 1) */
+ int limit = diff ^ (diff >> (sizeof(diff)*8-1));
+ int i = 0;
+ limit = limit + 1 << 10;
+ if (limit > low_quant[8] * state->scale_factor)
+ i = 9;
+ while (i < 29 && limit > low_quant[i] * state->scale_factor)
+ i++;
+ return (diff < 0 ? (i < 2 ? 63 : 33) : 61) - i;
+}
+
+static int g722_encode_trellis(AVCodecContext *avctx,
+ uint8_t *dst, int buf_size, void *data)
+{
+ G722Context *c = avctx->priv_data;
+ const int16_t *samples = data;
+ int i, j, k;
+ int frontier = 1 << avctx->trellis;
+ struct TrellisNode **nodes[2];
+ struct TrellisNode **nodes_next[2];
+ int pathn[2] = {0, 0}, froze = -1;
+ struct TrellisPath *p[2];
+
+ for (i = 0; i < 2; i++) {
+ nodes[i] = c->nodep_buf[i];
+ nodes_next[i] = c->nodep_buf[i] + frontier;
+ memset(c->nodep_buf[i], 0, 2 * frontier * sizeof(*c->nodep_buf));
+ nodes[i][0] = c->node_buf[i] + frontier;
+ nodes[i][0]->ssd = 0;
+ nodes[i][0]->path = 0;
+ nodes[i][0]->state = c->band[i];
+ }
+
+ for (i = 0; i < buf_size; i++) {
+ int xlow, xhigh;
+ struct TrellisNode *next[2];
+ int heap_pos[2] = {0, 0};
+
+ for (j = 0; j < 2; j++) {
+ next[j] = c->node_buf[j] + frontier*(i & 1);
+ memset(nodes_next[j], 0, frontier * sizeof(**nodes_next));
+ }
+
+ filter_samples(c, &samples[2*i], &xlow, &xhigh);
+
+ for (j = 0; j < frontier && nodes[0][j]; j++) {
+ /* Only k >> 2 affects the future adaptive state, therefore testing
+ * small steps that don't change k >> 2 is useless, the original
+ * value from encode_low is better than them. Since we step k
+ * in steps of 4, make sure range is a multiple of 4, so that
+ * we don't miss the original value from encode_low. */
+ int range = j < frontier/2 ? 4 : 0;
+ struct TrellisNode *cur_node = nodes[0][j];
+
+ int ilow = encode_low(&cur_node->state, xlow);
+
+ for (k = ilow - range; k <= ilow + range && k <= 63; k += 4) {
+ int decoded, dec_diff, pos;
+ uint32_t ssd;
+ struct TrellisNode* node;
+
+ if (k < 0)
+ continue;
+
+ decoded = av_clip((cur_node->state.scale_factor *
+ ff_g722_low_inv_quant6[k] >> 10)
+ + cur_node->state.s_predictor, -16384, 16383);
+ dec_diff = xlow - decoded;
+
+#define STORE_NODE(index, UPDATE, VALUE)\
+ ssd = cur_node->ssd + dec_diff*dec_diff;\
+ /* Check for wraparound. Using 64 bit ssd counters would \
+ * be simpler, but is slower on x86 32 bit. */\
+ if (ssd < cur_node->ssd)\
+ continue;\
+ if (heap_pos[index] < frontier) {\
+ pos = heap_pos[index]++;\
+ assert(pathn[index] < FREEZE_INTERVAL * frontier);\
+ node = nodes_next[index][pos] = next[index]++;\
+ node->path = pathn[index]++;\
+ } else {\
+ /* Try to replace one of the leaf nodes with the new \
+ * one, but not always testing the same leaf position */\
+ pos = (frontier>>1) + (heap_pos[index] & ((frontier>>1) - 1));\
+ if (ssd >= nodes_next[index][pos]->ssd)\
+ continue;\
+ heap_pos[index]++;\
+ node = nodes_next[index][pos];\
+ }\
+ node->ssd = ssd;\
+ node->state = cur_node->state;\
+ UPDATE;\
+ c->paths[index][node->path].value = VALUE;\
+ c->paths[index][node->path].prev = cur_node->path;\
+ /* Sift the newly inserted node up in the heap to restore \
+ * the heap property */\
+ while (pos > 0) {\
+ int parent = (pos - 1) >> 1;\
+ if (nodes_next[index][parent]->ssd <= ssd)\
+ break;\
+ FFSWAP(struct TrellisNode*, nodes_next[index][parent],\
+ nodes_next[index][pos]);\
+ pos = parent;\
+ }
+ STORE_NODE(0, ff_g722_update_low_predictor(&node->state, k >> 2), k);
+ }
+ }
+
+ for (j = 0; j < frontier && nodes[1][j]; j++) {
+ int ihigh;
+ struct TrellisNode *cur_node = nodes[1][j];
+
+ /* We don't try to get any initial guess for ihigh via
+ * encode_high - since there's only 4 possible values, test
+ * them all. Testing all of these gives a much, much larger
+ * gain than testing a larger range around ilow. */
+ for (ihigh = 0; ihigh < 4; ihigh++) {
+ int dhigh, decoded, dec_diff, pos;
+ uint32_t ssd;
+ struct TrellisNode* node;
+
+ dhigh = cur_node->state.scale_factor *
+ ff_g722_high_inv_quant[ihigh] >> 10;
+ decoded = av_clip(dhigh + cur_node->state.s_predictor,
+ -16384, 16383);
+ dec_diff = xhigh - decoded;
+
+ STORE_NODE(1, ff_g722_update_high_predictor(&node->state, dhigh, ihigh), ihigh);
+ }
+ }
+
+ for (j = 0; j < 2; j++) {
+ FFSWAP(struct TrellisNode**, nodes[j], nodes_next[j]);
+
+ if (nodes[j][0]->ssd > (1 << 16)) {
+ for (k = 1; k < frontier && nodes[j][k]; k++)
+ nodes[j][k]->ssd -= nodes[j][0]->ssd;
+ nodes[j][0]->ssd = 0;
+ }
+ }
+
+ if (i == froze + FREEZE_INTERVAL) {
+ p[0] = &c->paths[0][nodes[0][0]->path];
+ p[1] = &c->paths[1][nodes[1][0]->path];
+ for (j = i; j > froze; j--) {
+ dst[j] = p[1]->value << 6 | p[0]->value;
+ p[0] = &c->paths[0][p[0]->prev];
+ p[1] = &c->paths[1][p[1]->prev];
+ }
+ froze = i;
+ pathn[0] = pathn[1] = 0;
+ memset(nodes[0] + 1, 0, (frontier - 1)*sizeof(**nodes));
+ memset(nodes[1] + 1, 0, (frontier - 1)*sizeof(**nodes));
+ }
+ }
+
+ p[0] = &c->paths[0][nodes[0][0]->path];
+ p[1] = &c->paths[1][nodes[1][0]->path];
+ for (j = i; j > froze; j--) {
+ dst[j] = p[1]->value << 6 | p[0]->value;
+ p[0] = &c->paths[0][p[0]->prev];
+ p[1] = &c->paths[1][p[1]->prev];
+ }
+ c->band[0] = nodes[0][0]->state;
+ c->band[1] = nodes[1][0]->state;
+
+ return i;
+}
+
+static int g722_encode_frame(AVCodecContext *avctx,
+ uint8_t *dst, int buf_size, void *data)
+{
+ G722Context *c = avctx->priv_data;
+ const int16_t *samples = data;
+ int i;
+
+ if (avctx->trellis)
+ return g722_encode_trellis(avctx, dst, buf_size, data);
+
+ for (i = 0; i < buf_size; i++) {
+ int xlow, xhigh, ihigh, ilow;
+ filter_samples(c, &samples[2*i], &xlow, &xhigh);
+ ihigh = encode_high(&c->band[1], xhigh);
+ ilow = encode_low(&c->band[0], xlow);
+ ff_g722_update_high_predictor(&c->band[1], c->band[1].scale_factor *
+ ff_g722_high_inv_quant[ihigh] >> 10, ihigh);
+ ff_g722_update_low_predictor(&c->band[0], ilow >> 2);
+ *dst++ = ihigh << 6 | ilow;
+ }
+ return i;
+}
+
+AVCodec ff_adpcm_g722_encoder = {
+ .name = "g722",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ADPCM_G722,
+ .priv_data_size = sizeof(G722Context),
+ .init = g722_encode_init,
+ .close = g722_encode_close,
+ .encode = g722_encode_frame,
+ .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
+ .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
+};
diff --git a/libavcodec/g726.c b/libavcodec/g726.c
index 09df727..85711f8 100644
--- a/libavcodec/g726.c
+++ b/libavcodec/g726.c
@@ -22,7 +22,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <limits.h>
+#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
#include "avcodec.h"
+#include "internal.h"
#include "get_bits.h"
#include "put_bits.h"
@@ -71,6 +74,8 @@ typedef struct G726Tables {
} G726Tables;
typedef struct G726Context {
+ AVClass *class;
+ AVFrame frame;
G726Tables tbls; /**< static tables needed for computation */
Float11 sr[2]; /**< prev. reconstructed samples */
@@ -266,11 +271,11 @@ static int16_t g726_decode(G726Context* c, int I)
return av_clip(re_signal << 2, -0xffff, 0xffff);
}
-static av_cold int g726_reset(G726Context* c, int index)
+static av_cold int g726_reset(G726Context *c)
{
int i;
- c->tbls = G726Tables_pool[index];
+ c->tbls = G726Tables_pool[c->code_size - 2];
for (i=0; i<2; i++) {
c->sr[i].mant = 1<<5;
c->pk[i] = 1;
@@ -295,65 +300,59 @@ static int16_t g726_encode(G726Context* c, int16_t sig)
g726_decode(c, i);
return i;
}
-#endif
/* Interfacing to the libavcodec */
-static av_cold int g726_init(AVCodecContext * avctx)
+static av_cold int g726_encode_init(AVCodecContext *avctx)
{
G726Context* c = avctx->priv_data;
- unsigned int index;
- if (avctx->sample_rate <= 0) {
- av_log(avctx, AV_LOG_ERROR, "Samplerate is invalid\n");
- return -1;
+ if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL &&
+ avctx->sample_rate != 8000) {
+ av_log(avctx, AV_LOG_ERROR, "Sample rates other than 8kHz are not "
+ "allowed when the compliance level is higher than unofficial. "
+ "Resample or reduce the compliance level.\n");
+ return AVERROR(EINVAL);
}
+ av_assert0(avctx->sample_rate > 0);
- index = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate - 2;
-
- if (avctx->bit_rate % avctx->sample_rate && avctx->codec->encode) {
- av_log(avctx, AV_LOG_ERROR, "Bitrate - Samplerate combination is invalid\n");
- return -1;
- }
if(avctx->channels != 1){
av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
- return -1;
- }
- if(index>3){
- av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits %d\n", index+2);
- return -1;
+ return AVERROR(EINVAL);
}
- g726_reset(c, index);
- c->code_size = index+2;
+
+ if (avctx->bit_rate)
+ c->code_size = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate;
+
+ c->code_size = av_clip(c->code_size, 2, 5);
+ avctx->bit_rate = c->code_size * avctx->sample_rate;
+ avctx->bits_per_coded_sample = c->code_size;
+
+ g726_reset(c);
avctx->coded_frame = avcodec_alloc_frame();
if (!avctx->coded_frame)
return AVERROR(ENOMEM);
avctx->coded_frame->key_frame = 1;
- if (avctx->codec->decode)
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-
/* select a frame size that will end on a byte boundary and have a size of
approximately 1024 bytes */
- if (avctx->codec->encode)
- avctx->frame_size = ((int[]){ 4096, 2736, 2048, 1640 })[index];
+ avctx->frame_size = ((int[]){ 4096, 2736, 2048, 1640 })[c->code_size - 2];
return 0;
}
-static av_cold int g726_close(AVCodecContext *avctx)
+static av_cold int g726_encode_close(AVCodecContext *avctx)
{
av_freep(&avctx->coded_frame);
return 0;
}
-#if CONFIG_ADPCM_G726_ENCODER
static int g726_encode_frame(AVCodecContext *avctx,
uint8_t *dst, int buf_size, void *data)
{
G726Context *c = avctx->priv_data;
- const short *samples = data;
+ const int16_t *samples = data;
PutBitContext pb;
int i;
@@ -366,54 +365,124 @@ static int g726_encode_frame(AVCodecContext *avctx,
return put_bits_count(&pb)>>3;
}
+
+#define OFFSET(x) offsetof(G726Context, x)
+#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "code_size", "Bits per code", OFFSET(code_size), AV_OPT_TYPE_INT, { 4 }, 2, 5, AE },
+ { NULL },
+};
+
+static const AVClass class = {
+ .class_name = "g726",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVCodecDefault defaults[] = {
+ { "b", "0" },
+ { NULL },
+};
+
+AVCodec ff_adpcm_g726_encoder = {
+ .name = "g726",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ADPCM_G726,
+ .priv_data_size = sizeof(G726Context),
+ .init = g726_encode_init,
+ .encode = g726_encode_frame,
+ .close = g726_encode_close,
+ .capabilities = CODEC_CAP_SMALL_LAST_FRAME,
+ .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
+ .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
+ .priv_class = &class,
+ .defaults = defaults,
+};
#endif
-static int g726_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+#if CONFIG_ADPCM_G726_DECODER
+static av_cold int g726_decode_init(AVCodecContext *avctx)
+{
+ G726Context* c = avctx->priv_data;
+
+ if (avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&
+ avctx->sample_rate != 8000) {
+ av_log(avctx, AV_LOG_ERROR, "Only 8kHz sample rate is allowed when "
+ "the compliance level is strict. Reduce the compliance level "
+ "if you wish to decode the stream anyway.\n");
+ return AVERROR(EINVAL);
+ }
+
+ if(avctx->channels != 1){
+ av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
+ return AVERROR(EINVAL);
+ }
+
+ c->code_size = avctx->bits_per_coded_sample;
+ if (c->code_size < 2 || c->code_size > 5) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of bits %d\n", c->code_size);
+ return AVERROR(EINVAL);
+ }
+ g726_reset(c);
+
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ avcodec_get_frame_defaults(&c->frame);
+ avctx->coded_frame = &c->frame;
+
+ return 0;
+}
+
+static int g726_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
G726Context *c = avctx->priv_data;
- short *samples = data;
+ int16_t *samples;
GetBitContext gb;
+ int out_samples, ret;
+
+ out_samples = buf_size * 8 / c->code_size;
+
+ /* get output buffer */
+ c->frame.nb_samples = out_samples;
+ if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (int16_t *)c->frame.data[0];
init_get_bits(&gb, buf, buf_size * 8);
- while (get_bits_count(&gb) + c->code_size <= buf_size*8)
+ while (out_samples--)
*samples++ = g726_decode(c, get_bits(&gb, c->code_size));
- if(buf_size*8 != get_bits_count(&gb))
+ if (get_bits_left(&gb) > 0)
av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n");
- *data_size = (uint8_t*)samples - (uint8_t*)data;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = c->frame;
+
return buf_size;
}
-#if CONFIG_ADPCM_G726_ENCODER
-AVCodec ff_adpcm_g726_encoder = {
- "g726",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_ADPCM_G726,
- sizeof(G726Context),
- g726_init,
- g726_encode_frame,
- g726_close,
- NULL,
- .capabilities = CODEC_CAP_SMALL_LAST_FRAME,
- .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
- .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
-};
-#endif
+static void g726_decode_flush(AVCodecContext *avctx)
+{
+ G726Context *c = avctx->priv_data;
+ g726_reset(c);
+}
AVCodec ff_adpcm_g726_decoder = {
- "g726",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_ADPCM_G726,
- sizeof(G726Context),
- g726_init,
- NULL,
- g726_close,
- g726_decode_frame,
+ .name = "g726",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ADPCM_G726,
+ .priv_data_size = sizeof(G726Context),
+ .init = g726_decode_init,
+ .decode = g726_decode_frame,
+ .flush = g726_decode_flush,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
};
+#endif
diff --git a/libavcodec/g729data.h b/libavcodec/g729data.h
deleted file mode 100644
index 48010a7..0000000
--- a/libavcodec/g729data.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * data for G.729 decoder
- * Copyright (c) 2007 Vladimir Voroshilov
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_G729DATA_H
-#define AVCODEC_G729DATA_H
-
-#include <stdint.h>
-
-#define MA_NP 4 ///< Moving Average (MA) prediction order
-
-#define VQ_1ST_BITS 7 ///< first stage vector of quantizer (size in bits)
-#define VQ_2ND_BITS 5 ///< second stage vector of quantizer (size in bits)
-
-#define GC_1ST_IDX_BITS_8K 3 ///< gain codebook (first stage) index, 8k mode (size in bits)
-#define GC_2ND_IDX_BITS_8K 4 ///< gain codebook (second stage) index, 8k mode (size in bits)
-
-#define GC_1ST_IDX_BITS_6K4 3 ///< gain codebook (first stage) index, 6.4k mode (size in bits)
-#define GC_2ND_IDX_BITS_6K4 3 ///< gain codebook (second stage) index, 6.4k mode (size in bits)
-
-/**
- * first stage LSP codebook
- * (10-dimensional, with 128 entries (3.24 of G.729)
- */
-static const int16_t cb_lsp_1st[1<<VQ_1ST_BITS][10] = { /* (2.13) */
- { 1486, 2168, 3751, 9074, 12134, 13944, 17983, 19173, 21190, 21820},
- { 1730, 2640, 3450, 4870, 6126, 7876, 15644, 17817, 20294, 21902},
- { 1568, 2256, 3088, 4874, 11063, 13393, 18307, 19293, 21109, 21741},
- { 1733, 2512, 3357, 4708, 6977, 10296, 17024, 17956, 19145, 20350},
- { 1744, 2436, 3308, 8731, 10432, 12007, 15614, 16639, 21359, 21913},
- { 1786, 2369, 3372, 4521, 6795, 12963, 17674, 18988, 20855, 21640},
- { 1631, 2433, 3361, 6328, 10709, 12013, 13277, 13904, 19441, 21088},
- { 1489, 2364, 3291, 6250, 9227, 10403, 13843, 15278, 17721, 21451},
- { 1869, 2533, 3475, 4365, 9152, 14513, 15908, 17022, 20611, 21411},
- { 2070, 3025, 4333, 5854, 7805, 9231, 10597, 16047, 20109, 21834},
- { 1910, 2673, 3419, 4261, 11168, 15111, 16577, 17591, 19310, 20265},
- { 1141, 1815, 2624, 4623, 6495, 9588, 13968, 16428, 19351, 21286},
- { 2192, 3171, 4707, 5808, 10904, 12500, 14162, 15664, 21124, 21789},
- { 1286, 1907, 2548, 3453, 9574, 11964, 15978, 17344, 19691, 22495},
- { 1921, 2720, 4604, 6684, 11503, 12992, 14350, 15262, 16997, 20791},
- { 2052, 2759, 3897, 5246, 6638, 10267, 15834, 16814, 18149, 21675},
- { 1798, 2497, 5617, 11449, 13189, 14711, 17050, 18195, 20307, 21182},
- { 1009, 1647, 2889, 5709, 9541, 12354, 15231, 18494, 20966, 22033},
- { 3016, 3794, 5406, 7469, 12488, 13984, 15328, 16334, 19952, 20791},
- { 2203, 3040, 3796, 5442, 11987, 13512, 14931, 16370, 17856, 18803},
- { 2912, 4292, 7988, 9572, 11562, 13244, 14556, 16529, 20004, 21073},
- { 2861, 3607, 5923, 7034, 9234, 12054, 13729, 18056, 20262, 20974},
- { 3069, 4311, 5967, 7367, 11482, 12699, 14309, 16233, 18333, 19172},
- { 2434, 3661, 4866, 5798, 10383, 11722, 13049, 15668, 18862, 19831},
- { 2020, 2605, 3860, 9241, 13275, 14644, 16010, 17099, 19268, 20251},
- { 1877, 2809, 3590, 4707, 11056, 12441, 15622, 17168, 18761, 19907},
- { 2107, 2873, 3673, 5799, 13579, 14687, 15938, 17077, 18890, 19831},
- { 1612, 2284, 2944, 3572, 8219, 13959, 15924, 17239, 18592, 20117},
- { 2420, 3156, 6542, 10215, 12061, 13534, 15305, 16452, 18717, 19880},
- { 1667, 2612, 3534, 5237, 10513, 11696, 12940, 16798, 18058, 19378},
- { 2388, 3017, 4839, 9333, 11413, 12730, 15024, 16248, 17449, 18677},
- { 1875, 2786, 4231, 6320, 8694, 10149, 11785, 17013, 18608, 19960},
- { 679, 1411, 4654, 8006, 11446, 13249, 15763, 18127, 20361, 21567},
- { 1838, 2596, 3578, 4608, 5650, 11274, 14355, 15886, 20579, 21754},
- { 1303, 1955, 2395, 3322, 12023, 13764, 15883, 18077, 20180, 21232},
- { 1438, 2102, 2663, 3462, 8328, 10362, 13763, 17248, 19732, 22344},
- { 860, 1904, 6098, 7775, 9815, 12007, 14821, 16709, 19787, 21132},
- { 1673, 2723, 3704, 6125, 7668, 9447, 13683, 14443, 20538, 21731},
- { 1246, 1849, 2902, 4508, 7221, 12710, 14835, 16314, 19335, 22720},
- { 1525, 2260, 3862, 5659, 7342, 11748, 13370, 14442, 18044, 21334},
- { 1196, 1846, 3104, 7063, 10972, 12905, 14814, 17037, 19922, 22636},
- { 2147, 3106, 4475, 6511, 8227, 9765, 10984, 12161, 18971, 21300},
- { 1585, 2405, 2994, 4036, 11481, 13177, 14519, 15431, 19967, 21275},
- { 1778, 2688, 3614, 4680, 9465, 11064, 12473, 16320, 19742, 20800},
- { 1862, 2586, 3492, 6719, 11708, 13012, 14364, 16128, 19610, 20425},
- { 1395, 2156, 2669, 3386, 10607, 12125, 13614, 16705, 18976, 21367},
- { 1444, 2117, 3286, 6233, 9423, 12981, 14998, 15853, 17188, 21857},
- { 2004, 2895, 3783, 4897, 6168, 7297, 12609, 16445, 19297, 21465},
- { 1495, 2863, 6360, 8100, 11399, 14271, 15902, 17711, 20479, 22061},
- { 2484, 3114, 5718, 7097, 8400, 12616, 14073, 14847, 20535, 21396},
- { 2424, 3277, 5296, 6284, 11290, 12903, 16022, 17508, 19333, 20283},
- { 2565, 3778, 5360, 6989, 8782, 10428, 14390, 15742, 17770, 21734},
- { 2727, 3384, 6613, 9254, 10542, 12236, 14651, 15687, 20074, 21102},
- { 1916, 2953, 6274, 8088, 9710, 10925, 12392, 16434, 20010, 21183},
- { 3384, 4366, 5349, 7667, 11180, 12605, 13921, 15324, 19901, 20754},
- { 3075, 4283, 5951, 7619, 9604, 11010, 12384, 14006, 20658, 21497},
- { 1751, 2455, 5147, 9966, 11621, 13176, 14739, 16470, 20788, 21756},
- { 1442, 2188, 3330, 6813, 8929, 12135, 14476, 15306, 19635, 20544},
- { 2294, 2895, 4070, 8035, 12233, 13416, 14762, 17367, 18952, 19688},
- { 1937, 2659, 4602, 6697, 9071, 12863, 14197, 15230, 16047, 18877},
- { 2071, 2663, 4216, 9445, 10887, 12292, 13949, 14909, 19236, 20341},
- { 1740, 2491, 3488, 8138, 9656, 11153, 13206, 14688, 20896, 21907},
- { 2199, 2881, 4675, 8527, 10051, 11408, 14435, 15463, 17190, 20597},
- { 1943, 2988, 4177, 6039, 7478, 8536, 14181, 15551, 17622, 21579},
- { 1825, 3175, 7062, 9818, 12824, 15450, 18330, 19856, 21830, 22412},
- { 2464, 3046, 4822, 5977, 7696, 15398, 16730, 17646, 20588, 21320},
- { 2550, 3393, 5305, 6920, 10235, 14083, 18143, 19195, 20681, 21336},
- { 3003, 3799, 5321, 6437, 7919, 11643, 15810, 16846, 18119, 18980},
- { 3455, 4157, 6838, 8199, 9877, 12314, 15905, 16826, 19949, 20892},
- { 3052, 3769, 4891, 5810, 6977, 10126, 14788, 15990, 19773, 20904},
- { 3671, 4356, 5827, 6997, 8460, 12084, 14154, 14939, 19247, 20423},
- { 2716, 3684, 5246, 6686, 8463, 10001, 12394, 14131, 16150, 19776},
- { 1945, 2638, 4130, 7995, 14338, 15576, 17057, 18206, 20225, 20997},
- { 2304, 2928, 4122, 4824, 5640, 13139, 15825, 16938, 20108, 21054},
- { 1800, 2516, 3350, 5219, 13406, 15948, 17618, 18540, 20531, 21252},
- { 1436, 2224, 2753, 4546, 9657, 11245, 15177, 16317, 17489, 19135},
- { 2319, 2899, 4980, 6936, 8404, 13489, 15554, 16281, 20270, 20911},
- { 2187, 2919, 4610, 5875, 7390, 12556, 14033, 16794, 20998, 21769},
- { 2235, 2923, 5121, 6259, 8099, 13589, 15340, 16340, 17927, 20159},
- { 1765, 2638, 3751, 5730, 7883, 10108, 13633, 15419, 16808, 18574},
- { 3460, 5741, 9596, 11742, 14413, 16080, 18173, 19090, 20845, 21601},
- { 3735, 4426, 6199, 7363, 9250, 14489, 16035, 17026, 19873, 20876},
- { 3521, 4778, 6887, 8680, 12717, 14322, 15950, 18050, 20166, 21145},
- { 2141, 2968, 6865, 8051, 10010, 13159, 14813, 15861, 17528, 18655},
- { 4148, 6128, 9028, 10871, 12686, 14005, 15976, 17208, 19587, 20595},
- { 4403, 5367, 6634, 8371, 10163, 11599, 14963, 16331, 17982, 18768},
- { 4091, 5386, 6852, 8770, 11563, 13290, 15728, 16930, 19056, 20102},
- { 2746, 3625, 5299, 7504, 10262, 11432, 13172, 15490, 16875, 17514},
- { 2248, 3556, 8539, 10590, 12665, 14696, 16515, 17824, 20268, 21247},
- { 1279, 1960, 3920, 7793, 10153, 14753, 16646, 18139, 20679, 21466},
- { 2440, 3475, 6737, 8654, 12190, 14588, 17119, 17925, 19110, 19979},
- { 1879, 2514, 4497, 7572, 10017, 14948, 16141, 16897, 18397, 19376},
- { 2804, 3688, 7490, 10086, 11218, 12711, 16307, 17470, 20077, 21126},
- { 2023, 2682, 3873, 8268, 10255, 11645, 15187, 17102, 18965, 19788},
- { 2823, 3605, 5815, 8595, 10085, 11469, 16568, 17462, 18754, 19876},
- { 2851, 3681, 5280, 7648, 9173, 10338, 14961, 16148, 17559, 18474},
- { 1348, 2645, 5826, 8785, 10620, 12831, 16255, 18319, 21133, 22586},
- { 2141, 3036, 4293, 6082, 7593, 10629, 17158, 18033, 21466, 22084},
- { 1608, 2375, 3384, 6878, 9970, 11227, 16928, 17650, 20185, 21120},
- { 2774, 3616, 5014, 6557, 7788, 8959, 17068, 18302, 19537, 20542},
- { 1934, 4813, 6204, 7212, 8979, 11665, 15989, 17811, 20426, 21703},
- { 2288, 3507, 5037, 6841, 8278, 9638, 15066, 16481, 21653, 22214},
- { 2951, 3771, 4878, 7578, 9016, 10298, 14490, 15242, 20223, 20990},
- { 3256, 4791, 6601, 7521, 8644, 9707, 13398, 16078, 19102, 20249},
- { 1827, 2614, 3486, 6039, 12149, 13823, 16191, 17282, 21423, 22041},
- { 1000, 1704, 3002, 6335, 8471, 10500, 14878, 16979, 20026, 22427},
- { 1646, 2286, 3109, 7245, 11493, 12791, 16824, 17667, 18981, 20222},
- { 1708, 2501, 3315, 6737, 8729, 9924, 16089, 17097, 18374, 19917},
- { 2623, 3510, 4478, 5645, 9862, 11115, 15219, 18067, 19583, 20382},
- { 2518, 3434, 4728, 6388, 8082, 9285, 13162, 18383, 19819, 20552},
- { 1726, 2383, 4090, 6303, 7805, 12845, 14612, 17608, 19269, 20181},
- { 2860, 3735, 4838, 6044, 7254, 8402, 14031, 16381, 18037, 19410},
- { 4247, 5993, 7952, 9792, 12342, 14653, 17527, 18774, 20831, 21699},
- { 3502, 4051, 5680, 6805, 8146, 11945, 16649, 17444, 20390, 21564},
- { 3151, 4893, 5899, 7198, 11418, 13073, 15124, 17673, 20520, 21861},
- { 3960, 4848, 5926, 7259, 8811, 10529, 15661, 16560, 18196, 20183},
- { 4499, 6604, 8036, 9251, 10804, 12627, 15880, 17512, 20020, 21046},
- { 4251, 5541, 6654, 8318, 9900, 11686, 15100, 17093, 20572, 21687},
- { 3769, 5327, 7865, 9360, 10684, 11818, 13660, 15366, 18733, 19882},
- { 3083, 3969, 6248, 8121, 9798, 10994, 12393, 13686, 17888, 19105},
- { 2731, 4670, 7063, 9201, 11346, 13735, 16875, 18797, 20787, 22360},
- { 1187, 2227, 4737, 7214, 9622, 12633, 15404, 17968, 20262, 23533},
- { 1911, 2477, 3915, 10098, 11616, 12955, 16223, 17138, 19270, 20729},
- { 1764, 2519, 3887, 6944, 9150, 12590, 16258, 16984, 17924, 18435},
- { 1400, 3674, 7131, 8718, 10688, 12508, 15708, 17711, 19720, 21068},
- { 2322, 3073, 4287, 8108, 9407, 10628, 15862, 16693, 19714, 21474},
- { 2630, 3339, 4758, 8360, 10274, 11333, 12880, 17374, 19221, 19936},
- { 1721, 2577, 5553, 7195, 8651, 10686, 15069, 16953, 18703, 19929}
-};
-
-/**
- * second stage LSP codebook, high and low parts
- (both 5-dimensional, with 32 entries (3.2.4 of G.729)
- */
-static const int16_t cb_lsp_2nd[1<<VQ_2ND_BITS][10] = { /* (2.13) */
- { -435, -815, -742, 1033, -518, 582, -1201, 829, 86, 385},
- { -833, -891, 463, -8, -1251, 1450, 72, -231, 864, 661},
- {-1021, 231, -306, 321, -220, -163, -526, -754, -1633, 267},
- { 57, -198, -339, -33, -1468, 573, 796, -169, -631, 816},
- { 171, -350, 294, 1660, 453, 519, 291, 159, -640, -1296},
- { -701, -842, -58, 950, 892, 1549, 715, 527, -714, -193},
- { 584, 31, -289, 356, -333, -457, 612, -283, -1381, -741},
- { -109, -808, 231, 77, -87, -344, 1341, 1087, -654, -569},
- { -859, 1236, 550, 854, 714, -543, -1752, -195, -98, -276},
- { -877, -954, -1248, -299, 212, -235, -728, 949, 1517, 895},
- { -77, 344, -620, 763, 413, 502, -362, -960, -483, 1386},
- { -314, -307, -256, -1260, -429, 450, -466, -108, 1010, 2223},
- { 711, 693, 521, 650, 1305, -28, -378, 744, -1005, 240},
- { -112, -271, -500, 946, 1733, 271, -15, 909, -259, 1688},
- { 575, -10, -468, -199, 1101, -1011, 581, -53, -747, 878},
- { 145, -285, -1280, -398, 36, -498, -1377, 18, -444, 1483},
- {-1133, -835, 1350, 1284, -95, 1015, -222, 443, 372, -354},
- {-1459, -1237, 416, -213, 466, 669, 659, 1640, 932, 534},
- { -15, 66, 468, 1019, -748, 1385, -182, -907, -721, -262},
- { -338, 148, 1445, 75, -760, 569, 1247, 337, 416, -121},
- { 389, 239, 1568, 981, 113, 369, -1003, -507, -587, -904},
- { -312, -98, 949, 31, 1104, 72, -141, 1465, 63, -785},
- { 1127, 584, 835, 277, -1159, 208, 301, -882, 117, -404},
- { 539, -114, 856, -493, 223, -912, 623, -76, 276, -440},
- { 2197, 2337, 1268, 670, 304, -267, -525, 140, 882, -139},
- {-1596, 550, 801, -456, -56, -697, 865, 1060, 413, 446},
- { 1154, 593, -77, 1237, -31, 581, -1037, -895, 669, 297},
- { 397, 558, 203, -797, -919, 3, 692, -292, 1050, 782},
- { 334, 1475, 632, -80, 48, -1061, -484, 362, -597, -852},
- { -545, -330, -429, -680, 1133, -1182, -744, 1340, 262, 63},
- { 1320, 827, -398, -576, 341, -774, -483, -1247, -70, 98},
- { -163, 674, -11, -886, 531, -1125, -265, -242, 724, 934}
-};
-
-/**
- * gain codebook (first stage), 8k mode (3.9.2 of G.729)
- */
-static const int16_t cb_gain_1st_8k[1<<GC_1ST_IDX_BITS_8K][2] = { /*(0.14) (2.13) */
- { 3242 , 9949 },
- { 1551 , 2425 },
- { 2678 , 27162 },
- { 1921 , 9291 },
- { 1831 , 5022 },
- { 1 , 1516 },
- { 356 , 14756 },
- { 57 , 5404 },
-};
-
-/**
- * gain codebook (second stage), 8k mode (3.9.2 of G.729)
- */
-static const int16_t cb_gain_2nd_8k[1<<GC_2ND_IDX_BITS_8K][2] = { /*(1.14) (1.13) */
- { 5142 , 592 },
- { 17299 , 1861 },
- { 6160 , 2395 },
- { 16112 , 3392 },
- { 826 , 2005 },
- { 18973 , 5935 },
- { 1994 , 0 },
- { 15434 , 237 },
- { 10573 , 2966 },
- { 15132 , 4914 },
- { 11569 , 1196 },
- { 14194 , 1630 },
- { 8091 , 4861 },
- { 15161 , 14276 },
- { 9120 , 525 },
- { 13260 , 3256 },
-};
-
-/**
- * 4th order Moving Average (MA) Predictor codebook (3.2.4 of G.729)
- */
-static const int16_t cb_ma_predictor[2][MA_NP][10] = { /* (0.15) */
- {
- { 8421, 9109, 9175, 8965, 9034, 9057, 8765, 8775, 9106, 8673},
- { 7018, 7189, 7638, 7307, 7444, 7379, 7038, 6956, 6930, 6868},
- { 5472, 4990, 5134, 5177, 5246, 5141, 5206, 5095, 4830, 5147},
- { 4056, 3031, 2614, 3024, 2916, 2713, 3309, 3237, 2857, 3473}
- },
- {
- { 7733, 7880, 8188, 8175, 8247, 8490, 8637, 8601, 8359, 7569},
- { 4210, 3031, 2552, 3473, 3876, 3853, 4184, 4154, 3909, 3968},
- { 3214, 1930, 1313, 2143, 2493, 2385, 2755, 2706, 2542, 2919},
- { 3024, 1592, 940, 1631, 1723, 1579, 2034, 2084, 1913, 2601}
- }
-};
-
-static const int16_t cb_ma_predictor_sum[2][10] = { /* (0.15) */
- { 7798, 8447, 8205, 8293, 8126, 8477, 8447, 8703, 9043, 8604},
- {14585, 18333, 19772, 17344, 16426, 16459, 15155, 15220, 16043, 15708}
-};
-
-/**
- * initial LSP coefficients belongs to virtual frame preceding the
- * first frame of the stream
- */
-static const int16_t lsp_init[10]= { /* (0.15) */
- 30000, 26000, 21000, 15000, 8000, 0, -8000,-15000,-21000,-26000
-};
-#endif /* AVCODEC_G729DATA_H */
diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c
deleted file mode 100644
index 979b87f..0000000
--- a/libavcodec/g729dec.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * G.729 decoder
- * Copyright (c) 2008 Vladimir Voroshilov
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include <stdlib.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <assert.h>
-
-#include "avcodec.h"
-#include "libavutil/avutil.h"
-#include "get_bits.h"
-
-#include "lsp.h"
-#include "celp_math.h"
-#include "acelp_filters.h"
-#include "acelp_pitch_delay.h"
-#include "acelp_vectors.h"
-#include "g729data.h"
-
-/**
- * minimum quantized LSF value (3.2.4)
- * 0.005 in Q13
- */
-#define LSFQ_MIN 40
-
-/**
- * maximum quantized LSF value (3.2.4)
- * 3.135 in Q13
- */
-#define LSFQ_MAX 25681
-
-/**
- * minimum LSF distance (3.2.4)
- * 0.0391 in Q13
- */
-#define LSFQ_DIFF_MIN 321
-
-/**
- * minimum gain pitch value (3.8, Equation 47)
- * 0.2 in (1.14)
- */
-#define SHARP_MIN 3277
-
-/**
- * maximum gain pitch value (3.8, Equation 47)
- * (EE) This does not comply with the specification.
- * Specification says about 0.8, which should be
- * 13107 in (1.14), but reference C code uses
- * 13017 (equals to 0.7945) instead of it.
- */
-#define SHARP_MAX 13017
-
-/**
- * subframe size
- */
-#define SUBFRAME_SIZE 40
-
-
-typedef struct {
- uint8_t ac_index_bits[2]; ///< adaptive codebook index for second subframe (size in bits)
- uint8_t parity_bit; ///< parity bit for pitch delay
- uint8_t gc_1st_index_bits; ///< gain codebook (first stage) index (size in bits)
- uint8_t gc_2nd_index_bits; ///< gain codebook (second stage) index (size in bits)
- uint8_t fc_signs_bits; ///< number of pulses in fixed-codebook vector
- uint8_t fc_indexes_bits; ///< size (in bits) of fixed-codebook index entry
-} G729FormatDescription;
-
-typedef struct {
- int pitch_delay_int_prev; ///< integer part of previous subframe's pitch delay (4.1.3)
-
- /// (2.13) LSP quantizer outputs
- int16_t past_quantizer_output_buf[MA_NP + 1][10];
- int16_t* past_quantizer_outputs[MA_NP + 1];
-
- int16_t lsfq[10]; ///< (2.13) quantized LSF coefficients from previous frame
- int16_t lsp_buf[2][10]; ///< (0.15) LSP coefficients (previous and current frames) (3.2.5)
- int16_t *lsp[2]; ///< pointers to lsp_buf
-} G729Context;
-
-static const G729FormatDescription format_g729_8k = {
- .ac_index_bits = {8,5},
- .parity_bit = 1,
- .gc_1st_index_bits = GC_1ST_IDX_BITS_8K,
- .gc_2nd_index_bits = GC_2ND_IDX_BITS_8K,
- .fc_signs_bits = 4,
- .fc_indexes_bits = 13,
-};
-
-static const G729FormatDescription format_g729d_6k4 = {
- .ac_index_bits = {8,4},
- .parity_bit = 0,
- .gc_1st_index_bits = GC_1ST_IDX_BITS_6K4,
- .gc_2nd_index_bits = GC_2ND_IDX_BITS_6K4,
- .fc_signs_bits = 2,
- .fc_indexes_bits = 9,
-};
-
-/**
- * \brief pseudo random number generator
- */
-static inline uint16_t g729_prng(uint16_t value)
-{
- return 31821 * value + 13849;
-}
-
-/**
- * Get parity bit of bit 2..7
- */
-static inline int get_parity(uint8_t value)
-{
- return (0x6996966996696996ULL >> (value >> 2)) & 1;
-}
-
-static void lsf_decode(int16_t* lsfq, int16_t* past_quantizer_outputs[MA_NP + 1],
- int16_t ma_predictor,
- int16_t vq_1st, int16_t vq_2nd_low, int16_t vq_2nd_high)
-{
- int i,j;
- static const uint8_t min_distance[2]={10, 5}; //(2.13)
- int16_t* quantizer_output = past_quantizer_outputs[MA_NP];
-
- for (i = 0; i < 5; i++) {
- quantizer_output[i] = cb_lsp_1st[vq_1st][i ] + cb_lsp_2nd[vq_2nd_low ][i ];
- quantizer_output[i + 5] = cb_lsp_1st[vq_1st][i + 5] + cb_lsp_2nd[vq_2nd_high][i + 5];
- }
-
- for (j = 0; j < 2; j++) {
- for (i = 1; i < 10; i++) {
- int diff = (quantizer_output[i - 1] - quantizer_output[i] + min_distance[j]) >> 1;
- if (diff > 0) {
- quantizer_output[i - 1] -= diff;
- quantizer_output[i ] += diff;
- }
- }
- }
-
- for (i = 0; i < 10; i++) {
- int sum = quantizer_output[i] * cb_ma_predictor_sum[ma_predictor][i];
- for (j = 0; j < MA_NP; j++)
- sum += past_quantizer_outputs[j][i] * cb_ma_predictor[ma_predictor][j][i];
-
- lsfq[i] = sum >> 15;
- }
-
- /* Rotate past_quantizer_outputs. */
- memmove(past_quantizer_outputs + 1, past_quantizer_outputs, MA_NP * sizeof(int16_t*));
- past_quantizer_outputs[0] = quantizer_output;
-
- ff_acelp_reorder_lsf(lsfq, LSFQ_DIFF_MIN, LSFQ_MIN, LSFQ_MAX, 10);
-}
-
-static av_cold int decoder_init(AVCodecContext * avctx)
-{
- G729Context* ctx = avctx->priv_data;
- int i,k;
-
- if (avctx->channels != 1) {
- av_log(avctx, AV_LOG_ERROR, "Only mono sound is supported (requested channels: %d).\n", avctx->channels);
- return AVERROR(EINVAL);
- }
-
- /* Both 8kbit/s and 6.4kbit/s modes uses two subframes per frame. */
- avctx->frame_size = SUBFRAME_SIZE << 1;
-
- for (k = 0; k < MA_NP + 1; k++) {
- ctx->past_quantizer_outputs[k] = ctx->past_quantizer_output_buf[k];
- for (i = 1; i < 11; i++)
- ctx->past_quantizer_outputs[k][i - 1] = (18717 * i) >> 3;
- }
-
- ctx->lsp[0] = ctx->lsp_buf[0];
- ctx->lsp[1] = ctx->lsp_buf[1];
- memcpy(ctx->lsp[0], lsp_init, 10 * sizeof(int16_t));
-
- return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- int16_t *out_frame = data;
- GetBitContext gb;
- G729FormatDescription format;
- int frame_erasure = 0; ///< frame erasure detected during decoding
- int bad_pitch = 0; ///< parity check failed
- int i;
- G729Context *ctx = avctx->priv_data;
- int16_t lp[2][11]; // (3.12)
- uint8_t ma_predictor; ///< switched MA predictor of LSP quantizer
- uint8_t quantizer_1st; ///< first stage vector of quantizer
- uint8_t quantizer_2nd_lo; ///< second stage lower vector of quantizer (size in bits)
- uint8_t quantizer_2nd_hi; ///< second stage higher vector of quantizer (size in bits)
-
- int pitch_delay_int; // pitch delay, integer part
- int pitch_delay_3x; // pitch delay, multiplied by 3
-
- if (*data_size < SUBFRAME_SIZE << 2) {
- av_log(avctx, AV_LOG_ERROR, "Error processing packet: output buffer too small\n");
- return AVERROR(EIO);
- }
-
- if (buf_size == 10) {
- format = format_g729_8k;
- av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729 @ 8kbit/s");
- } else if (buf_size == 8) {
- format = format_g729d_6k4;
- av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729D @ 6.4kbit/s");
- } else {
- av_log(avctx, AV_LOG_ERROR, "Packet size %d is unknown.\n", buf_size);
- return AVERROR_INVALIDDATA;
- }
-
- for (i=0; i < buf_size; i++)
- frame_erasure |= buf[i];
- frame_erasure = !frame_erasure;
-
- init_get_bits(&gb, buf, buf_size);
-
- ma_predictor = get_bits(&gb, 1);
- quantizer_1st = get_bits(&gb, VQ_1ST_BITS);
- quantizer_2nd_lo = get_bits(&gb, VQ_2ND_BITS);
- quantizer_2nd_hi = get_bits(&gb, VQ_2ND_BITS);
-
- lsf_decode(ctx->lsfq, ctx->past_quantizer_outputs,
- ma_predictor,
- quantizer_1st, quantizer_2nd_lo, quantizer_2nd_hi);
-
- ff_acelp_lsf2lsp(ctx->lsp[1], ctx->lsfq, 10);
-
- ff_acelp_lp_decode(&lp[0][0], &lp[1][0], ctx->lsp[1], ctx->lsp[0], 10);
-
- FFSWAP(int16_t*, ctx->lsp[1], ctx->lsp[0]);
-
- for (i = 0; i < 2; i++) {
- uint8_t ac_index; ///< adaptive codebook index
- uint8_t pulses_signs; ///< fixed-codebook vector pulse signs
- int fc_indexes; ///< fixed-codebook indexes
- uint8_t gc_1st_index; ///< gain codebook (first stage) index
- uint8_t gc_2nd_index; ///< gain codebook (second stage) index
-
- ac_index = get_bits(&gb, format.ac_index_bits[i]);
- if(!i && format.parity_bit)
- bad_pitch = get_parity(ac_index) == get_bits1(&gb);
- fc_indexes = get_bits(&gb, format.fc_indexes_bits);
- pulses_signs = get_bits(&gb, format.fc_signs_bits);
- gc_1st_index = get_bits(&gb, format.gc_1st_index_bits);
- gc_2nd_index = get_bits(&gb, format.gc_2nd_index_bits);
-
- if(!i) {
- if (bad_pitch)
- pitch_delay_3x = 3 * ctx->pitch_delay_int_prev;
- else
- pitch_delay_3x = ff_acelp_decode_8bit_to_1st_delay3(ac_index);
- } else {
- int pitch_delay_min = av_clip(ctx->pitch_delay_int_prev - 5,
- PITCH_DELAY_MIN, PITCH_DELAY_MAX - 9);
-
- if(packet_type == FORMAT_G729D_6K4)
- pitch_delay_3x = ff_acelp_decode_4bit_to_2nd_delay3(ac_index, pitch_delay_min);
- else
- pitch_delay_3x = ff_acelp_decode_5_6_bit_to_2nd_delay3(ac_index, pitch_delay_min);
- }
-
- /* Round pitch delay to nearest (used everywhere except ff_acelp_interpolate). */
- pitch_delay_int = (pitch_delay_3x + 1) / 3;
-
- ff_acelp_weighted_vector_sum(fc + pitch_delay_int,
- fc + pitch_delay_int,
- fc, 1 << 14,
- av_clip(ctx->gain_pitch, SHARP_MIN, SHARP_MAX),
- 0, 14,
- SUBFRAME_SIZE - pitch_delay_int);
-
- if (frame_erasure) {
- ctx->gain_pitch = (29491 * ctx->gain_pitch) >> 15; // 0.90 (0.15)
- ctx->gain_code = ( 2007 * ctx->gain_code ) >> 11; // 0.98 (0.11)
-
- gain_corr_factor = 0;
- } else {
- ctx->gain_pitch = cb_gain_1st_8k[gc_1st_index][0] +
- cb_gain_2nd_8k[gc_2nd_index][0];
- gain_corr_factor = cb_gain_1st_8k[gc_1st_index][1] +
- cb_gain_2nd_8k[gc_2nd_index][1];
-
- ff_acelp_weighted_vector_sum(ctx->exc + i * SUBFRAME_SIZE,
- ctx->exc + i * SUBFRAME_SIZE, fc,
- (!voicing && frame_erasure) ? 0 : ctx->gain_pitch,
- ( voicing && frame_erasure) ? 0 : ctx->gain_code,
- 1 << 13, 14, SUBFRAME_SIZE);
-
- ctx->pitch_delay_int_prev = pitch_delay_int;
- }
-
- *data_size = SUBFRAME_SIZE << 2;
- return buf_size;
-}
-
-AVCodec ff_g729_decoder =
-{
- "g729",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_G729,
- sizeof(G729Context),
- decoder_init,
- NULL,
- NULL,
- decode_frame,
- .long_name = NULL_IF_CONFIG_SMALL("G.729"),
-};
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index 4136498..1668600 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -27,40 +27,35 @@
#define AVCODEC_GET_BITS_H
#include <stdint.h>
-#include <stdlib.h>
-#include <assert.h>
-#include "libavutil/bswap.h"
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "mathops.h"
-#if defined(ALT_BITSTREAM_READER_LE) && !defined(ALT_BITSTREAM_READER)
-# define ALT_BITSTREAM_READER
-#endif
-
-#if !defined(A32_BITSTREAM_READER) && !defined(ALT_BITSTREAM_READER)
-# if ARCH_ARM && !HAVE_FAST_UNALIGNED
-# define A32_BITSTREAM_READER
-# else
-# define ALT_BITSTREAM_READER
-//#define A32_BITSTREAM_READER
-# endif
+/*
+ * Safe bitstream reading:
+ * optionally, the get_bits API can check to ensure that we
+ * don't read past input buffer boundaries. This is protected
+ * with CONFIG_SAFE_BITSTREAM_READER at the global level, and
+ * then below that with UNCHECKED_BITSTREAM_READER at the per-
+ * decoder level. This means that decoders that check internally
+ * can "#define UNCHECKED_BITSTREAM_READER 1" to disable
+ * overread checks.
+ * Boundary checking causes a minor performance penalty so for
+ * applications that won't want/need this, it can be disabled
+ * globally using "#define CONFIG_SAFE_BITSTREAM_READER 0".
+ */
+#ifndef UNCHECKED_BITSTREAM_READER
+#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER
#endif
-/* bit input */
-/* buffer, buffer_end and size_in_bits must be present and used by every reader */
typedef struct GetBitContext {
const uint8_t *buffer, *buffer_end;
-#ifdef ALT_BITSTREAM_READER
int index;
-#elif defined A32_BITSTREAM_READER
- uint32_t *buffer_ptr;
- uint32_t cache0;
- uint32_t cache1;
- int bit_count;
-#endif
int size_in_bits;
+#if !UNCHECKED_BITSTREAM_READER
+ int size_in_bits_plus8;
+#endif
} GetBitContext;
#define VLC_TYPE int16_t
@@ -85,13 +80,13 @@ gb
getbitcontext
OPEN_READER(name, gb)
- loads gb into local variables
+ load gb into local variables
CLOSE_READER(name, gb)
- stores local vars in gb
+ store local vars in gb
UPDATE_CACHE(name, gb)
- refills the internal cache from the bitstream
+ refill the internal cache from the bitstream
after this call at least MIN_CACHE_BITS will be available,
GET_CACHE(name, gb)
@@ -113,148 +108,94 @@ SKIP_CACHE(name, gb, num)
SKIP_COUNTER(name, gb, num)
will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS)
-LAST_SKIP_CACHE(name, gb, num)
- will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing
-
LAST_SKIP_BITS(name, gb, num)
- is equivalent to LAST_SKIP_CACHE; SKIP_COUNTER
+ like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER
for examples see get_bits, show_bits, skip_bits, get_vlc
*/
-#ifdef ALT_BITSTREAM_READER
+#ifdef LONG_BITSTREAM_READER
+# define MIN_CACHE_BITS 32
+#else
# define MIN_CACHE_BITS 25
+#endif
-# define OPEN_READER(name, gb) \
+#define OPEN_READER(name, gb) \
unsigned int name##_index = (gb)->index; \
unsigned int av_unused name##_cache = 0
-# define CLOSE_READER(name, gb) (gb)->index = name##_index
+#define CLOSE_READER(name, gb) (gb)->index = name##_index
-# ifdef ALT_BITSTREAM_READER_LE
-# define UPDATE_CACHE(name, gb) \
- name##_cache = AV_RL32(((const uint8_t *)(gb)->buffer)+(name##_index>>3)) >> (name##_index&0x07)
+#ifdef BITSTREAM_READER_LE
-# define SKIP_CACHE(name, gb, num) name##_cache >>= (num)
+# ifdef LONG_BITSTREAM_READER
+# define UPDATE_CACHE(name, gb) name##_cache = \
+ AV_RL64((gb)->buffer + (name##_index >> 3)) >> (name##_index & 7)
# else
-# define UPDATE_CACHE(name, gb) \
- name##_cache = AV_RB32(((const uint8_t *)(gb)->buffer)+(name##_index>>3)) << (name##_index&0x07)
+# define UPDATE_CACHE(name, gb) name##_cache = \
+ AV_RL32((gb)->buffer + (name##_index >> 3)) >> (name##_index & 7)
+# endif
+
+# define SKIP_CACHE(name, gb, num) name##_cache >>= (num)
-# define SKIP_CACHE(name, gb, num) name##_cache <<= (num)
+#else
+
+# ifdef LONG_BITSTREAM_READER
+# define UPDATE_CACHE(name, gb) name##_cache = \
+ AV_RB64((gb)->buffer + (name##_index >> 3)) >> (32 - (name##_index & 7))
+# else
+# define UPDATE_CACHE(name, gb) name##_cache = \
+ AV_RB32((gb)->buffer + (name##_index >> 3)) << (name##_index & 7)
# endif
-// FIXME name?
+# define SKIP_CACHE(name, gb, num) name##_cache <<= (num)
+
+#endif
+
+#if UNCHECKED_BITSTREAM_READER
# define SKIP_COUNTER(name, gb, num) name##_index += (num)
+#else
+# define SKIP_COUNTER(name, gb, num) \
+ name##_index = FFMIN((gb)->size_in_bits_plus8, name##_index + (num))
+#endif
-# define SKIP_BITS(name, gb, num) do { \
+#define SKIP_BITS(name, gb, num) do { \
SKIP_CACHE(name, gb, num); \
SKIP_COUNTER(name, gb, num); \
} while (0)
-# define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
-# define LAST_SKIP_CACHE(name, gb, num)
+#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
-# ifdef ALT_BITSTREAM_READER_LE
+#ifdef BITSTREAM_READER_LE
# define SHOW_UBITS(name, gb, num) zero_extend(name##_cache, num)
-
# define SHOW_SBITS(name, gb, num) sign_extend(name##_cache, num)
-# else
+#else
# define SHOW_UBITS(name, gb, num) NEG_USR32(name##_cache, num)
-
# define SHOW_SBITS(name, gb, num) NEG_SSR32(name##_cache, num)
-# endif
+#endif
-# define GET_CACHE(name, gb) ((uint32_t)name##_cache)
+#define GET_CACHE(name, gb) ((uint32_t)name##_cache)
-static inline int get_bits_count(const GetBitContext *s){
+static inline int get_bits_count(const GetBitContext *s)
+{
return s->index;
}
static inline void skip_bits_long(GetBitContext *s, int n){
+#if UNCHECKED_BITSTREAM_READER
s->index += n;
-}
-
-#elif defined A32_BITSTREAM_READER
-
-# define MIN_CACHE_BITS 32
-
-# define OPEN_READER(name, gb) \
- int name##_bit_count = (gb)->bit_count; \
- uint32_t name##_cache0 = (gb)->cache0; \
- uint32_t name##_cache1 = (gb)->cache1; \
- uint32_t *name##_buffer_ptr = (gb)->buffer_ptr
-
-# define CLOSE_READER(name, gb) do { \
- (gb)->bit_count = name##_bit_count; \
- (gb)->cache0 = name##_cache0; \
- (gb)->cache1 = name##_cache1; \
- (gb)->buffer_ptr = name##_buffer_ptr; \
- } while (0)
-
-# define UPDATE_CACHE(name, gb) do { \
- if(name##_bit_count > 0){ \
- const uint32_t next = av_be2ne32(*name##_buffer_ptr); \
- name##_cache0 |= NEG_USR32(next, name##_bit_count); \
- name##_cache1 |= next << name##_bit_count; \
- name##_buffer_ptr++; \
- name##_bit_count -= 32; \
- } \
- } while (0)
-
-#if ARCH_X86
-# define SKIP_CACHE(name, gb, num) \
- __asm__("shldl %2, %1, %0 \n\t" \
- "shll %2, %1 \n\t" \
- : "+r" (name##_cache0), "+r" (name##_cache1) \
- : "Ic" ((uint8_t)(num)))
#else
-# define SKIP_CACHE(name, gb, num) do { \
- name##_cache0 <<= (num); \
- name##_cache0 |= NEG_USR32(name##_cache1,num); \
- name##_cache1 <<= (num); \
- } while (0)
+ s->index += av_clip(n, -s->index, s->size_in_bits_plus8 - s->index);
#endif
-
-# define SKIP_COUNTER(name, gb, num) name##_bit_count += (num)
-
-# define SKIP_BITS(name, gb, num) do { \
- SKIP_CACHE(name, gb, num); \
- SKIP_COUNTER(name, gb, num); \
- } while (0)
-
-# define LAST_SKIP_BITS(name, gb, num) SKIP_BITS(name, gb, num)
-# define LAST_SKIP_CACHE(name, gb, num) SKIP_CACHE(name, gb, num)
-
-# define SHOW_UBITS(name, gb, num) NEG_USR32(name##_cache0, num)
-
-# define SHOW_SBITS(name, gb, num) NEG_SSR32(name##_cache0, num)
-
-# define GET_CACHE(name, gb) name##_cache0
-
-static inline int get_bits_count(const GetBitContext *s) {
- return ((uint8_t*)s->buffer_ptr - s->buffer)*8 - 32 + s->bit_count;
-}
-
-static inline void skip_bits_long(GetBitContext *s, int n){
- OPEN_READER(re, s);
- re_bit_count += n;
- re_buffer_ptr += re_bit_count>>5;
- re_bit_count &= 31;
- re_cache0 = av_be2ne32(re_buffer_ptr[-1]) << re_bit_count;
- re_cache1 = 0;
- UPDATE_CACHE(re, s);
- CLOSE_READER(re, s);
}
-#endif
-
/**
* read mpeg1 dc style vlc (sign bit + mantisse with no MSB).
* if MSB not set it is negative
* @param n length in bits
- * @author BERO
*/
-static inline int get_xbits(GetBitContext *s, int n){
+static inline int get_xbits(GetBitContext *s, int n)
+{
register int sign;
register int32_t cache;
OPEN_READER(re, s);
@@ -266,7 +207,8 @@ static inline int get_xbits(GetBitContext *s, int n){
return (NEG_USR32(sign ^ cache, n) ^ sign) - sign;
}
-static inline int get_sbits(GetBitContext *s, int n){
+static inline int get_sbits(GetBitContext *s, int n)
+{
register int tmp;
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
@@ -279,7 +221,8 @@ static inline int get_sbits(GetBitContext *s, int n){
/**
* Read 1-25 bits.
*/
-static inline unsigned int get_bits(GetBitContext *s, int n){
+static inline unsigned int get_bits(GetBitContext *s, int n)
+{
register int tmp;
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
@@ -290,9 +233,10 @@ static inline unsigned int get_bits(GetBitContext *s, int n){
}
/**
- * Shows 1-25 bits.
+ * Show 1-25 bits.
*/
-static inline unsigned int show_bits(GetBitContext *s, int n){
+static inline unsigned int show_bits(GetBitContext *s, int n)
+{
register int tmp;
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
@@ -300,49 +244,53 @@ static inline unsigned int show_bits(GetBitContext *s, int n){
return tmp;
}
-static inline void skip_bits(GetBitContext *s, int n){
- //Note gcc seems to optimize this to s->index+=n for the ALT_READER :))
+static inline void skip_bits(GetBitContext *s, int n)
+{
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
}
-static inline unsigned int get_bits1(GetBitContext *s){
-#ifdef ALT_BITSTREAM_READER
+static inline unsigned int get_bits1(GetBitContext *s)
+{
unsigned int index = s->index;
uint8_t result = s->buffer[index>>3];
-#ifdef ALT_BITSTREAM_READER_LE
+#ifdef BITSTREAM_READER_LE
result >>= index & 7;
result &= 1;
#else
result <<= index & 7;
result >>= 8 - 1;
#endif
- index++;
+#if !UNCHECKED_BITSTREAM_READER
+ if (s->index < s->size_in_bits_plus8)
+#endif
+ index++;
s->index = index;
return result;
-#else
- return get_bits(s, 1);
-#endif
}
-static inline unsigned int show_bits1(GetBitContext *s){
+static inline unsigned int show_bits1(GetBitContext *s)
+{
return show_bits(s, 1);
}
-static inline void skip_bits1(GetBitContext *s){
+static inline void skip_bits1(GetBitContext *s)
+{
skip_bits(s, 1);
}
/**
- * reads 0-32 bits.
+ * Read 0-32 bits.
*/
-static inline unsigned int get_bits_long(GetBitContext *s, int n){
- if (n <= MIN_CACHE_BITS) return get_bits(s, n);
+static inline unsigned int get_bits_long(GetBitContext *s, int n)
+{
+ if (n <= MIN_CACHE_BITS)
+ return get_bits(s, n);
else {
-#ifdef ALT_BITSTREAM_READER_LE
+#ifdef BITSTREAM_READER_LE
int ret = get_bits(s, 16);
return ret | (get_bits(s, n-16) << 16);
#else
@@ -353,17 +301,20 @@ static inline unsigned int get_bits_long(GetBitContext *s, int n){
}
/**
- * reads 0-32 bits as a signed integer.
+ * Read 0-32 bits as a signed integer.
*/
-static inline int get_sbits_long(GetBitContext *s, int n) {
+static inline int get_sbits_long(GetBitContext *s, int n)
+{
return sign_extend(get_bits_long(s, n), n);
}
/**
- * shows 0-32 bits.
+ * Show 0-32 bits.
*/
-static inline unsigned int show_bits_long(GetBitContext *s, int n){
- if (n <= MIN_CACHE_BITS) return show_bits(s, n);
+static inline unsigned int show_bits_long(GetBitContext *s, int n)
+{
+ if (n <= MIN_CACHE_BITS)
+ return show_bits(s, n);
else {
GetBitContext gb = *s;
return get_bits_long(&gb, n);
@@ -380,16 +331,13 @@ static inline int check_marker(GetBitContext *s, const char *msg)
}
/**
- * init GetBitContext.
- * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits
+ * Inititalize GetBitContext.
+ * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger than the actual read bits
* because some optimized bitstream readers read 32 or 64 bit at once and could read over the end
* @param bit_size the size of the buffer in bits
- *
- * While GetBitContext stores the buffer size, for performance reasons you are
- * responsible for checking for the buffer end yourself (take advantage of the padding)!
*/
-static inline void init_get_bits(GetBitContext *s,
- const uint8_t *buffer, int bit_size)
+static inline void init_get_bits(GetBitContext *s, const uint8_t *buffer,
+ int bit_size)
{
int buffer_size = (bit_size+7)>>3;
if (buffer_size < 0 || bit_size < 0) {
@@ -399,14 +347,11 @@ static inline void init_get_bits(GetBitContext *s,
s->buffer = buffer;
s->size_in_bits = bit_size;
+#if !UNCHECKED_BITSTREAM_READER
+ s->size_in_bits_plus8 = bit_size + 8;
+#endif
s->buffer_end = buffer + buffer_size;
-#ifdef ALT_BITSTREAM_READER
s->index = 0;
-#elif defined A32_BITSTREAM_READER
- s->buffer_ptr = (uint32_t*)((intptr_t)buffer & ~3);
- s->bit_count = 32 + 8*((intptr_t)buffer & 3);
- skip_bits_long(s, 0);
-#endif
}
static inline void align_get_bits(GetBitContext *s)
@@ -442,12 +387,12 @@ void free_vlc(VLC *vlc);
/**
- *
* If the vlc code is invalid and max_depth=1, then no bits will be removed.
* If the vlc code is invalid and max_depth>1, then the number of bits removed
* is undefined.
*/
-#define GET_VLC(code, name, gb, table, bits, max_depth) do { \
+#define GET_VLC(code, name, gb, table, bits, max_depth) \
+ do { \
int n, nb_bits; \
unsigned int index; \
\
@@ -478,7 +423,8 @@ void free_vlc(VLC *vlc);
SKIP_BITS(name, gb, n); \
} while (0)
-#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth, need_update) do { \
+#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth, need_update) \
+ do { \
int n, nb_bits; \
unsigned int index; \
\
@@ -504,7 +450,7 @@ void free_vlc(VLC *vlc);
/**
- * parses a vlc code, faster then get_vlc()
+ * Parse a vlc code.
* @param bits is the number of bits which will be read at once, must be
* identical to nb_bits in init_vlc()
* @param max_depth is the number of times bits bits must be read to completely
@@ -512,7 +458,7 @@ void free_vlc(VLC *vlc);
* = (max_vlc_length + bits - 1) / bits
*/
static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2],
- int bits, int max_depth)
+ int bits, int max_depth)
{
int code;
@@ -525,7 +471,8 @@ static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2],
return code;
}
-static inline int decode012(GetBitContext *gb){
+static inline int decode012(GetBitContext *gb)
+{
int n;
n = get_bits1(gb);
if (n == 0)
@@ -534,7 +481,8 @@ static inline int decode012(GetBitContext *gb){
return get_bits1(gb) + 1;
}
-static inline int decode210(GetBitContext *gb){
+static inline int decode210(GetBitContext *gb)
+{
if (get_bits1(gb))
return 0;
else
@@ -549,7 +497,8 @@ static inline int get_bits_left(GetBitContext *gb)
//#define TRACE
#ifdef TRACE
-static inline void print_bin(int bits, int n){
+static inline void print_bin(int bits, int n)
+{
int i;
for (i = n-1; i >= 0; i--) {
@@ -560,7 +509,8 @@ static inline void print_bin(int bits, int n){
}
static inline int get_bits_trace(GetBitContext *s, int n, char *file,
- const char *func, int line){
+ const char *func, int line)
+{
int r = get_bits(s, n);
print_bin(r, n);
@@ -570,7 +520,8 @@ static inline int get_bits_trace(GetBitContext *s, int n, char *file,
}
static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2],
int bits, int max_depth, char *file,
- const char *func, int line){
+ const char *func, int line)
+{
int show = show_bits(s, 24);
int pos = get_bits_count(s);
int r = get_vlc2(s, table, bits, max_depth);
@@ -584,7 +535,8 @@ static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2],
return r;
}
static inline int get_xbits_trace(GetBitContext *s, int n, char *file,
- const char *func, int line){
+ const char *func, int line)
+{
int show = show_bits(s, n);
int r = get_xbits(s, n);
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index a34d710..c7e7bcd 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -167,13 +167,13 @@ static int gif_encode_close(AVCodecContext *avctx)
}
AVCodec ff_gif_encoder = {
- "gif",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_GIF,
- sizeof(GIFContext),
- gif_encode_init,
- gif_encode_frame,
- gif_encode_close,
+ .name = "gif",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_GIF,
+ .priv_data_size = sizeof(GIFContext),
+ .init = gif_encode_init,
+ .encode = gif_encode_frame,
+ .close = gif_encode_close,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, PIX_FMT_GRAY8, PIX_FMT_PAL8, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"),
};
diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c
index 934c944..9bac254 100644
--- a/libavcodec/gifdec.c
+++ b/libavcodec/gifdec.c
@@ -96,11 +96,11 @@ static int gif_read_image(GifState *s)
n = (1 << bits_per_pixel);
spal = palette;
for(i = 0; i < n; i++) {
- s->image_palette[i] = (0xff << 24) | AV_RB24(spal);
+ s->image_palette[i] = (0xffu << 24) | AV_RB24(spal);
spal += 3;
}
for(; i < 256; i++)
- s->image_palette[i] = (0xff << 24);
+ s->image_palette[i] = (0xffu << 24);
/* handle transparency */
if (s->transparent_color_index >= 0)
s->image_palette[s->transparent_color_index] = 0;
@@ -326,14 +326,13 @@ static av_cold int gif_decode_close(AVCodecContext *avctx)
}
AVCodec ff_gif_decoder = {
- "gif",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_GIF,
- sizeof(GifState),
- gif_decode_init,
- NULL,
- gif_decode_close,
- gif_decode_frame,
- CODEC_CAP_DR1,
+ .name = "gif",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_GIF,
+ .priv_data_size = sizeof(GifState),
+ .init = gif_decode_init,
+ .close = gif_decode_close,
+ .decode = gif_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"),
};
diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
index 83d277f..503aa14 100644
--- a/libavcodec/golomb.h
+++ b/libavcodec/golomb.h
@@ -75,6 +75,20 @@ static inline int get_ue_golomb(GetBitContext *gb){
}
}
+/**
+ * Read an unsigned Exp-Golomb code in the range 0 to UINT32_MAX-1.
+ */
+static inline unsigned get_ue_golomb_long(GetBitContext *gb)
+{
+ unsigned buf, log;
+
+ buf = show_bits_long(gb, 32);
+ log = 31 - av_log2(buf);
+ skip_bits_long(gb, log);
+
+ return get_bits_long(gb, log + 1) - 1;
+}
+
/**
* read unsigned exp golomb code, constraint to a max of 31.
* the return value is undefined if the stored value exceeds 31.
diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c
index 693febd..97b6fe8 100644
--- a/libavcodec/gsmdec.c
+++ b/libavcodec/gsmdec.c
@@ -32,6 +32,8 @@
static av_cold int gsm_init(AVCodecContext *avctx)
{
+ GSMContext *s = avctx->priv_data;
+
avctx->channels = 1;
if (!avctx->sample_rate)
avctx->sample_rate = 8000;
@@ -47,24 +49,34 @@ static av_cold int gsm_init(AVCodecContext *avctx)
avctx->block_align = GSM_MS_BLOCK_SIZE;
}
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
static int gsm_decode_frame(AVCodecContext *avctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame_ptr, AVPacket *avpkt)
{
+ GSMContext *s = avctx->priv_data;
int res;
GetBitContext gb;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- int16_t *samples = data;
- int frame_bytes = 2 * avctx->frame_size;
+ int16_t *samples;
- if (*data_size < frame_bytes)
- return -1;
- *data_size = 0;
- if(buf_size < avctx->block_align)
+ if (buf_size < avctx->block_align) {
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
return AVERROR_INVALIDDATA;
+ }
+
+ /* get output buffer */
+ s->frame.nb_samples = avctx->frame_size;
+ if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return res;
+ }
+ samples = (int16_t *)s->frame.data[0];
switch (avctx->codec_id) {
case CODEC_ID_GSM:
@@ -80,30 +92,39 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data,
if (res < 0)
return res;
}
- *data_size = frame_bytes;
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return avctx->block_align;
}
+static void gsm_flush(AVCodecContext *avctx)
+{
+ GSMContext *s = avctx->priv_data;
+ memset(s, 0, sizeof(*s));
+}
+
AVCodec ff_gsm_decoder = {
- "gsm",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_GSM,
- sizeof(GSMContext),
- gsm_init,
- NULL,
- NULL,
- gsm_decode_frame,
+ .name = "gsm",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_GSM,
+ .priv_data_size = sizeof(GSMContext),
+ .init = gsm_init,
+ .decode = gsm_decode_frame,
+ .flush = gsm_flush,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("GSM"),
};
AVCodec ff_gsm_ms_decoder = {
- "gsm_ms",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_GSM_MS,
- sizeof(GSMContext),
- gsm_init,
- NULL,
- NULL,
- gsm_decode_frame,
+ .name = "gsm_ms",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_GSM_MS,
+ .priv_data_size = sizeof(GSMContext),
+ .init = gsm_init,
+ .decode = gsm_decode_frame,
+ .flush = gsm_flush,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"),
};
diff --git a/libavcodec/gsmdec_data.h b/libavcodec/gsmdec_data.h
index b78daa7..21789f7 100644
--- a/libavcodec/gsmdec_data.h
+++ b/libavcodec/gsmdec_data.h
@@ -23,6 +23,7 @@
#define AVCODEC_GSMDEC_DATA
#include <stdint.h>
+#include "avcodec.h"
// input and output sizes in byte
#define GSM_BLOCK_SIZE 33
@@ -30,6 +31,7 @@
#define GSM_FRAME_SIZE 160
typedef struct {
+ AVFrame frame;
// Contains first 120 elements from the previous frame
// (used by long_term_synth according to the "lag"),
// then in the following 160 elements the current
diff --git a/libavcodec/h261_parser.c b/libavcodec/h261_parser.c
index 20c2862..fb50acf 100644
--- a/libavcodec/h261_parser.c
+++ b/libavcodec/h261_parser.c
@@ -82,9 +82,8 @@ static int h261_parse(AVCodecParserContext *s,
}
AVCodecParser ff_h261_parser = {
- { CODEC_ID_H261 },
- sizeof(ParseContext),
- NULL,
- h261_parse,
- ff_parse_close,
+ .codec_ids = { CODEC_ID_H261 },
+ .priv_data_size = sizeof(ParseContext),
+ .parser_parse = h261_parse,
+ .parser_close = ff_parse_close,
};
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index a335d68..66ea4be 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -97,7 +97,7 @@ static av_cold int h261_decode_init(AVCodecContext *avctx){
}
/**
- * decodes the group of blocks header or slice header.
+ * Decode the group of blocks header or slice header.
* @return <0 if an error occurred
*/
static int h261_decode_gob_header(H261Context *h){
@@ -136,7 +136,7 @@ static int h261_decode_gob_header(H261Context *h){
if(s->qscale==0) {
av_log(s->avctx, AV_LOG_ERROR, "qscale has forbidden 0 value\n");
- if (s->avctx->error_recognition >= FF_ER_COMPLIANT)
+ if (s->avctx->err_recognition & AV_EF_BITSTREAM)
return -1;
}
@@ -150,7 +150,7 @@ static int h261_decode_gob_header(H261Context *h){
}
/**
- * decodes the group of blocks / video packet header.
+ * Decode the group of blocks / video packet header.
* @return <0 if no resync found
*/
static int ff_h261_resync(H261Context *h){
@@ -191,7 +191,7 @@ static int ff_h261_resync(H261Context *h){
}
/**
- * decodes skipped macroblocks
+ * Decode skipped macroblocks.
* @return 0
*/
static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 )
@@ -215,7 +215,7 @@ static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 )
s->mv_dir = MV_DIR_FORWARD;
s->mv_type = MV_TYPE_16X16;
- s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
s->mv[0][0][0] = 0;
s->mv[0][0][1] = 0;
s->mb_skipped = 1;
@@ -323,14 +323,14 @@ static int h261_decode_mb(H261Context *h){
}
if(s->mb_intra){
- s->current_picture.mb_type[xy]= MB_TYPE_INTRA;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
goto intra;
}
//set motion vectors
s->mv_dir = MV_DIR_FORWARD;
s->mv_type = MV_TYPE_16X16;
- s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
s->mv[0][0][0] = h->current_mv_x * 2;//gets divided by 2 in motion compensation
s->mv[0][0][1] = h->current_mv_y * 2;
@@ -355,7 +355,7 @@ intra:
}
/**
- * decodes a macroblock
+ * Decode a macroblock.
* @return <0 if an error occurred
*/
static int h261_decode_block(H261Context * h, DCTELEM * block,
@@ -437,7 +437,7 @@ static int h261_decode_block(H261Context * h, DCTELEM * block,
}
/**
- * decodes the H261 picture header.
+ * Decode the H.261 picture header.
* @return <0 if no startcode found
*/
static int h261_decode_picture_header(H261Context *h){
@@ -464,7 +464,7 @@ static int h261_decode_picture_header(H261Context *h){
s->picture_number = (s->picture_number&~31) + i;
s->avctx->time_base= (AVRational){1001, 30000};
- s->current_picture.pts= s->picture_number;
+ s->current_picture.f.pts = s->picture_number;
/* PTYPE starts here */
@@ -570,8 +570,10 @@ retry:
}
//we need to set current_picture_ptr before reading the header, otherwise we cannot store anyting im there
- if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){
+ if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) {
int i= ff_find_unused_picture(s, 0);
+ if (i < 0)
+ return i;
s->current_picture_ptr= &s->picture[i];
}
@@ -596,8 +598,8 @@ retry:
}
// for skipping the frame
- s->current_picture.pict_type= s->pict_type;
- s->current_picture.key_frame= s->pict_type == AV_PICTURE_TYPE_I;
+ s->current_picture.f.pict_type = s->pict_type;
+ s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B)
||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I)
@@ -620,8 +622,8 @@ retry:
}
MPV_frame_end(s);
-assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);
-assert(s->current_picture.pict_type == s->pict_type);
+assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
+assert(s->current_picture.f.pict_type == s->pict_type);
*pict= *(AVFrame*)s->current_picture_ptr;
ff_print_debug_info(s, pict);
@@ -640,15 +642,14 @@ static av_cold int h261_decode_end(AVCodecContext *avctx)
}
AVCodec ff_h261_decoder = {
- "h261",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_H261,
- sizeof(H261Context),
- h261_decode_init,
- NULL,
- h261_decode_end,
- h261_decode_frame,
- CODEC_CAP_DR1,
+ .name = "h261",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_H261,
+ .priv_data_size = sizeof(H261Context),
+ .init = h261_decode_init,
+ .close = h261_decode_end,
+ .decode = h261_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("H.261"),
};
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index 27746d5..c758ec0 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -53,7 +53,7 @@ void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){
H261Context * h = (H261Context *) s;
int format, temp_ref;
- align_put_bits(&s->pb);
+ avpriv_align_put_bits(&s->pb);
/* Update the pointer to last GOB */
s->ptr_lastgob = put_bits_ptr(&s->pb);
@@ -251,7 +251,7 @@ void ff_h261_encode_init(MpegEncContext *s){
/**
- * encodes a 8x8 block.
+ * Encode an 8x8 block.
* @param block the 8x8 block
* @param n block index (0-3 are luma, 4-5 are chroma)
*/
@@ -322,13 +322,13 @@ static void h261_encode_block(H261Context * h, DCTELEM * block, int n){
}
AVCodec ff_h261_encoder = {
- "h261",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_H261,
- sizeof(H261Context),
- MPV_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "h261",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_H261,
+ .priv_data_size = sizeof(H261Context),
+ .init = MPV_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("H.261"),
};
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index 5c25df2..77a1bb8 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -1,5 +1,5 @@
/*
- * H263/MPEG4 backend for ffmpeg encoder and decoder
+ * H263/MPEG4 backend for encoder and decoder
* Copyright (c) 2000,2001 Fabrice Bellard
* H263+ support.
* Copyright (c) 2001 Juan J. Sierralta P
@@ -52,7 +52,7 @@ void ff_h263_update_motion_val(MpegEncContext * s){
const int wrap = s->b8_stride;
const int xy = s->block_index[0];
- s->current_picture.mbskip_table[mb_xy]= s->mb_skipped;
+ s->current_picture.f.mbskip_table[mb_xy] = s->mb_skipped;
if(s->mv_type != MV_TYPE_8X8){
int motion_x, motion_y;
@@ -71,30 +71,30 @@ void ff_h263_update_motion_val(MpegEncContext * s){
s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0];
s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1];
}
- s->current_picture.ref_index[0][4*mb_xy ]=
- s->current_picture.ref_index[0][4*mb_xy + 1]= s->field_select[0][0];
- s->current_picture.ref_index[0][4*mb_xy + 2]=
- s->current_picture.ref_index[0][4*mb_xy + 3]= s->field_select[0][1];
+ s->current_picture.f.ref_index[0][4*mb_xy ] =
+ s->current_picture.f.ref_index[0][4*mb_xy + 1] = s->field_select[0][0];
+ s->current_picture.f.ref_index[0][4*mb_xy + 2] =
+ s->current_picture.f.ref_index[0][4*mb_xy + 3] = s->field_select[0][1];
}
/* no update if 8X8 because it has been done during parsing */
- s->current_picture.motion_val[0][xy][0] = motion_x;
- s->current_picture.motion_val[0][xy][1] = motion_y;
- s->current_picture.motion_val[0][xy + 1][0] = motion_x;
- s->current_picture.motion_val[0][xy + 1][1] = motion_y;
- s->current_picture.motion_val[0][xy + wrap][0] = motion_x;
- s->current_picture.motion_val[0][xy + wrap][1] = motion_y;
- s->current_picture.motion_val[0][xy + 1 + wrap][0] = motion_x;
- s->current_picture.motion_val[0][xy + 1 + wrap][1] = motion_y;
+ s->current_picture.f.motion_val[0][xy][0] = motion_x;
+ s->current_picture.f.motion_val[0][xy][1] = motion_y;
+ s->current_picture.f.motion_val[0][xy + 1][0] = motion_x;
+ s->current_picture.f.motion_val[0][xy + 1][1] = motion_y;
+ s->current_picture.f.motion_val[0][xy + wrap][0] = motion_x;
+ s->current_picture.f.motion_val[0][xy + wrap][1] = motion_y;
+ s->current_picture.f.motion_val[0][xy + 1 + wrap][0] = motion_x;
+ s->current_picture.f.motion_val[0][xy + 1 + wrap][1] = motion_y;
}
if(s->encoding){ //FIXME encoding MUST be cleaned up
if (s->mv_type == MV_TYPE_8X8)
- s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_8x8;
+ s->current_picture.f.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_8x8;
else if(s->mb_intra)
- s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA;
+ s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA;
else
- s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_16x16;
+ s->current_picture.f.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_16x16;
}
}
@@ -154,7 +154,7 @@ void ff_h263_loop_filter(MpegEncContext * s){
Diag Top
Left Center
*/
- if(!IS_SKIP(s->current_picture.mb_type[xy])){
+ if (!IS_SKIP(s->current_picture.f.mb_type[xy])) {
qp_c= s->qscale;
s->dsp.h263_v_loop_filter(dest_y+8*linesize , linesize, qp_c);
s->dsp.h263_v_loop_filter(dest_y+8*linesize+8, linesize, qp_c);
@@ -164,10 +164,10 @@ void ff_h263_loop_filter(MpegEncContext * s){
if(s->mb_y){
int qp_dt, qp_tt, qp_tc;
- if(IS_SKIP(s->current_picture.mb_type[xy-s->mb_stride]))
+ if (IS_SKIP(s->current_picture.f.mb_type[xy - s->mb_stride]))
qp_tt=0;
else
- qp_tt= s->current_picture.qscale_table[xy-s->mb_stride];
+ qp_tt = s->current_picture.f.qscale_table[xy - s->mb_stride];
if(qp_c)
qp_tc= qp_c;
@@ -187,10 +187,10 @@ void ff_h263_loop_filter(MpegEncContext * s){
s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_tt);
if(s->mb_x){
- if(qp_tt || IS_SKIP(s->current_picture.mb_type[xy-1-s->mb_stride]))
+ if (qp_tt || IS_SKIP(s->current_picture.f.mb_type[xy - 1 - s->mb_stride]))
qp_dt= qp_tt;
else
- qp_dt= s->current_picture.qscale_table[xy-1-s->mb_stride];
+ qp_dt = s->current_picture.f.qscale_table[xy - 1 - s->mb_stride];
if(qp_dt){
const int chroma_qp= s->chroma_qscale_table[qp_dt];
@@ -209,10 +209,10 @@ void ff_h263_loop_filter(MpegEncContext * s){
if(s->mb_x){
int qp_lc;
- if(qp_c || IS_SKIP(s->current_picture.mb_type[xy-1]))
+ if (qp_c || IS_SKIP(s->current_picture.f.mb_type[xy - 1]))
qp_lc= qp_c;
else
- qp_lc= s->current_picture.qscale_table[xy-1];
+ qp_lc = s->current_picture.f.qscale_table[xy - 1];
if(qp_lc){
s->dsp.h263_h_loop_filter(dest_y, linesize, qp_lc);
@@ -321,7 +321,7 @@ int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir,
static const int off[4]= {2, 1, 1, -1};
wrap = s->b8_stride;
- mot_val = s->current_picture.motion_val[dir] + s->block_index[block];
+ mot_val = s->current_picture.f.motion_val[dir] + s->block_index[block];
A = mot_val[ - 1];
/* special case for first (slice) line */
diff --git a/libavcodec/h263.h b/libavcodec/h263.h
index 1dc3007..73c5966 100644
--- a/libavcodec/h263.h
+++ b/libavcodec/h263.h
@@ -200,48 +200,6 @@ static inline int get_p_cbp(MpegEncContext * s,
return cbp;
}
-static inline int get_b_cbp(MpegEncContext * s, DCTELEM block[6][64],
- int motion_x, int motion_y, int mb_type){
- int cbp=0, i;
-
- if(s->flags & CODEC_FLAG_CBP_RD){
- int score=0;
- const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
-
- for(i=0; i<6; i++){
- if(s->coded_score[i] < 0){
- score += s->coded_score[i];
- cbp |= 1 << (5 - i);
- }
- }
-
- if(cbp){
- int zero_score= -6;
- if ((motion_x | motion_y | s->dquant | mb_type) == 0){
- zero_score-= 4; //2*MV + mb_type + cbp bit
- }
-
- zero_score*= lambda;
- if(zero_score <= score){
- cbp=0;
- }
- }
-
- for (i = 0; i < 6; i++) {
- if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i))&1)==0 ){
- s->block_last_index[i]= -1;
- s->dsp.clear_block(s->block[i]);
- }
- }
- }else{
- for (i = 0; i < 6; i++) {
- if (s->block_last_index[i] >= 0)
- cbp |= 1 << (5 - i);
- }
- }
- return cbp;
-}
-
static inline void memsetw(short *tab, int val, int n)
{
int i;
diff --git a/libavcodec/h263_parser.c b/libavcodec/h263_parser.c
index 4b9fc11..98a72d9 100644
--- a/libavcodec/h263_parser.c
+++ b/libavcodec/h263_parser.c
@@ -84,9 +84,8 @@ static int h263_parse(AVCodecParserContext *s,
}
AVCodecParser ff_h263_parser = {
- { CODEC_ID_H263 },
- sizeof(ParseContext),
- NULL,
- h263_parse,
- ff_parse_close,
+ .codec_ids = { CODEC_ID_H263 },
+ .priv_data_size = sizeof(ParseContext),
+ .parser_parse = h263_parse,
+ .parser_close = ff_parse_close,
};
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index bc6d613..f056d1f 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -91,6 +91,8 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
break;
case CODEC_ID_VC1:
case CODEC_ID_WMV3:
+ case CODEC_ID_VC1IMAGE:
+ case CODEC_ID_WMV3IMAGE:
s->h263_pred = 1;
s->msmpeg4_version=6;
avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
@@ -125,7 +127,7 @@ av_cold int ff_h263_decode_end(AVCodecContext *avctx)
}
/**
- * returns the number of bytes consumed for building the current frame
+ * Return the number of bytes consumed for building the current frame.
*/
static int get_consumed_bytes(MpegEncContext *s, int buf_size){
int pos= (get_bits_count(&s->gb)+7)>>3;
@@ -146,7 +148,7 @@ static int get_consumed_bytes(MpegEncContext *s, int buf_size){
}
static int decode_slice(MpegEncContext *s){
- const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F;
+ const int part_mask= s->partitioned_frame ? (ER_AC_END|ER_AC_ERROR) : 0x7F;
const int mb_size= 16>>s->avctx->lowres;
s->last_resync_gb= s->gb;
s->first_slice_line= 1;
@@ -182,7 +184,7 @@ static int decode_slice(MpegEncContext *s){
/* per-row end of slice checks */
if(s->msmpeg4_version){
if(s->resync_mb_y + s->slice_height == s->mb_y){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
return 0;
}
@@ -223,7 +225,7 @@ static int decode_slice(MpegEncContext *s){
ff_h263_loop_filter(s);
//printf("%d %d %d %06X\n", s->mb_x, s->mb_y, s->gb.size*8 - get_bits_count(&s->gb), show_bits(&s->gb, 24));
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
s->padding_bug_score--;
@@ -236,11 +238,11 @@ static int decode_slice(MpegEncContext *s){
return 0;
}else if(ret==SLICE_NOEND){
av_log(s->avctx, AV_LOG_ERROR, "Slice mismatch at MB: %d\n", xy);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, ER_MB_END&part_mask);
return -1;
}
av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", xy);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
return -1;
}
@@ -308,7 +310,7 @@ static int decode_slice(MpegEncContext *s){
max_extra+= 17;
/* buggy padding but the frame should still end approximately at the bitstream end */
- if((s->workaround_bugs&FF_BUG_NO_PADDING) && s->error_recognition>=3)
+ if((s->workaround_bugs&FF_BUG_NO_PADDING) && (s->err_recognition&AV_EF_BUFFER))
max_extra+= 48;
else if((s->workaround_bugs&FF_BUG_NO_PADDING))
max_extra+= 256*256*256*64;
@@ -319,7 +321,7 @@ static int decode_slice(MpegEncContext *s){
else if(left<0){
av_log(s->avctx, AV_LOG_ERROR, "overreading %d bits\n", -left);
}else
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
return 0;
}
@@ -328,7 +330,7 @@ static int decode_slice(MpegEncContext *s){
get_bits_left(&s->gb),
show_bits(&s->gb, 24), s->padding_bug_score);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
return -1;
}
@@ -394,8 +396,10 @@ retry:
/* We need to set current_picture_ptr before reading the header,
* otherwise we cannot store anyting in there */
- if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){
+ if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) {
int i= ff_find_unused_picture(s, 0);
+ if (i < 0)
+ return i;
s->current_picture_ptr= &s->picture[i];
}
@@ -581,8 +585,8 @@ retry:
s->gob_index = ff_h263_get_gob_height(s);
// for skipping the frame
- s->current_picture.pict_type= s->pict_type;
- s->current_picture.key_frame= s->pict_type == AV_PICTURE_TYPE_I;
+ s->current_picture.f.pict_type = s->pict_type;
+ s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
/* skip B-frames if we don't have reference frames */
if(s->last_picture_ptr==NULL && (s->pict_type==AV_PICTURE_TYPE_B || s->dropable)) return get_consumed_bytes(s, buf_size);
@@ -638,7 +642,7 @@ retry:
s->mb_x=0;
s->mb_y=0;
- decode_slice(s);
+ ret = decode_slice(s);
while(s->mb_y<s->mb_height){
if(s->msmpeg4_version){
if(s->slice_height==0 || s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_count(&s->gb) > s->gb.size_in_bits)
@@ -654,12 +658,12 @@ retry:
if(s->msmpeg4_version<4 && s->h263_pred)
ff_mpeg4_clean_buffers(s);
- decode_slice(s);
+ if (decode_slice(s) < 0) ret = AVERROR_INVALIDDATA;
}
if (s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type==AV_PICTURE_TYPE_I)
if(!CONFIG_MSMPEG4_DECODER || msmpeg4_decode_ext_header(s, buf_size) < 0){
- s->error_status_table[s->mb_num-1]= AC_ERROR|DC_ERROR|MV_ERROR;
+ s->error_status_table[s->mb_num-1]= ER_MB_ERROR;
}
assert(s->bitstream_buffer_size==0);
@@ -705,8 +709,8 @@ intrax8_decoded:
MPV_frame_end(s);
-assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);
-assert(s->current_picture.pict_type == s->pict_type);
+ assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
+ assert(s->current_picture.f.pict_type == s->pict_type);
if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
*pict= *(AVFrame*)s->current_picture_ptr;
} else if (s->last_picture_ptr != NULL) {
@@ -722,19 +726,18 @@ assert(s->current_picture.pict_type == s->pict_type);
av_log(avctx, AV_LOG_DEBUG, "%"PRId64"\n", rdtsc()-time);
#endif
- return get_consumed_bytes(s, buf_size);
+ return (ret && (avctx->err_recognition & AV_EF_EXPLODE))?ret:get_consumed_bytes(s, buf_size);
}
AVCodec ff_h263_decoder = {
- "h263",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_H263,
- sizeof(MpegEncContext),
- ff_h263_decode_init,
- NULL,
- ff_h263_decode_end,
- ff_h263_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
+ .name = "h263",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_H263,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_h263_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
.flush= ff_mpeg_flush,
.max_lowres= 3,
.long_name= NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 75075f6..2bde0fe 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -56,21 +56,14 @@ static const uint8_t div6[QP_MAX_NUM+1]={
static const enum PixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = {
PIX_FMT_DXVA2_VLD,
PIX_FMT_VAAPI_VLD,
+ PIX_FMT_VDA_VLD,
PIX_FMT_YUVJ420P,
PIX_FMT_NONE
};
-void ff_h264_write_back_intra_pred_mode(H264Context *h){
- int8_t *mode= h->intra4x4_pred_mode + h->mb2br_xy[h->mb_xy];
-
- AV_COPY32(mode, h->intra4x4_pred_mode_cache + 4 + 8*4);
- mode[4]= h->intra4x4_pred_mode_cache[7+8*3];
- mode[5]= h->intra4x4_pred_mode_cache[7+8*2];
- mode[6]= h->intra4x4_pred_mode_cache[7+8*1];
-}
-
/**
- * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks.
+ * Check if the top & left blocks are available if needed and
+ * change the dc mode so it only uses the available blocks.
*/
int ff_h264_check_intra4x4_pred_mode(H264Context *h){
MpegEncContext * const s = &h->s;
@@ -109,7 +102,8 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h){
} //FIXME cleanup like ff_h264_check_intra_pred_mode
/**
- * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks.
+ * Check if the top & left blocks are available if needed and
+ * change the dc mode so it only uses the available blocks.
*/
int ff_h264_check_intra_pred_mode(H264Context *h, int mode){
MpegEncContext * const s = &h->s;
@@ -270,8 +264,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, int
// Error resilience puts the current picture in the ref list.
// Don't try to wait on these as it will cause a deadlock.
// Fields can wait on each other, though.
- if(ref->thread_opaque != s->current_picture.thread_opaque ||
- (ref->reference&3) != s->picture_structure) {
+ if (ref->f.thread_opaque != s->current_picture.f.thread_opaque ||
+ (ref->f.reference & 3) != s->picture_structure) {
my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0);
if (refs[0][ref_n] < 0) nrefs[0] += 1;
refs[0][ref_n] = FFMAX(refs[0][ref_n], my);
@@ -282,8 +276,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, int
int ref_n = h->ref_cache[1][ scan8[n] ];
Picture *ref= &h->ref_list[1][ref_n];
- if(ref->thread_opaque != s->current_picture.thread_opaque ||
- (ref->reference&3) != s->picture_structure) {
+ if (ref->f.thread_opaque != s->current_picture.f.thread_opaque ||
+ (ref->f.reference & 3) != s->picture_structure) {
my = get_lowest_part_list_y(h, ref, n, height, y_offset, 1);
if (refs[1][ref_n] < 0) nrefs[1] += 1;
refs[1][ref_n] = FFMAX(refs[1][ref_n], my);
@@ -299,7 +293,7 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, int
static void await_references(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];
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
int refs[2][48];
int nrefs[2] = {0};
int ref, list;
@@ -359,7 +353,7 @@ static void await_references(H264Context *h){
int row = refs[list][ref];
if(row >= 0){
Picture *ref_pic = &h->ref_list[list][ref];
- int ref_field = ref_pic->reference - 1;
+ int ref_field = ref_pic->f.reference - 1;
int ref_field_picture = ref_pic->field_picture;
int pic_height = 16*s->mb_height >> ref_field_picture;
@@ -447,17 +441,20 @@ static void chroma_dc_dct_c(DCTELEM *block){
}
#endif
-static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square, int chroma_height, int delta, int list,
- uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
- int src_x_offset, int src_y_offset,
- qpel_mc_func *qpix_op, h264_chroma_mc_func chroma_op,
- int pixel_shift, int chroma444){
+static av_always_inline void
+mc_dir_part(H264Context *h, Picture *pic, int n, int square,
+ int height, int delta, int list,
+ uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+ int src_x_offset, int src_y_offset,
+ qpel_mc_func *qpix_op, h264_chroma_mc_func chroma_op,
+ int pixel_shift, int chroma_idc)
+{
MpegEncContext * const s = &h->s;
const int mx= h->mv_cache[list][ scan8[n] ][0] + src_x_offset*8;
int my= h->mv_cache[list][ scan8[n] ][1] + src_y_offset*8;
const int luma_xy= (mx&3) + ((my&3)<<2);
int offset = ((mx>>2) << pixel_shift) + (my>>2)*h->mb_linesize;
- uint8_t * src_y = pic->data[0] + offset;
+ uint8_t * src_y = pic->f.data[0] + offset;
uint8_t * src_cb, * src_cr;
int extra_width= h->emu_edge_width;
int extra_height= h->emu_edge_height;
@@ -466,6 +463,7 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
const int full_my= my>>2;
const int pic_width = 16*s->mb_width;
const int pic_height = 16*s->mb_height >> MB_FIELD;
+ int ysh;
if(mx&7) extra_width -= 3;
if(my&7) extra_height -= 3;
@@ -474,7 +472,8 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
|| full_my < 0-extra_height
|| full_mx + 16/*FIXME*/ > pic_width + extra_width
|| full_my + 16/*FIXME*/ > pic_height + extra_height){
- s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_y - (2 << pixel_shift) - 2*h->mb_linesize, h->mb_linesize, 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height);
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_y - (2 << pixel_shift) - 2*h->mb_linesize, h->mb_linesize,
+ 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height);
src_y= s->edge_emu_buffer + (2 << pixel_shift) + 2*h->mb_linesize;
emu=1;
}
@@ -486,8 +485,8 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return;
- if(chroma444){
- src_cb = pic->data[1] + offset;
+ if(chroma_idc == 3 /* yuv444 */){
+ src_cb = pic->f.data[1] + offset;
if(emu){
s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cb - (2 << pixel_shift) - 2*h->mb_linesize, h->mb_linesize,
16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height);
@@ -498,7 +497,7 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
qpix_op[luma_xy](dest_cb + delta, src_cb + delta, h->mb_linesize);
}
- src_cr = pic->data[2] + offset;
+ src_cr = pic->f.data[2] + offset;
if(emu){
s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cr - (2 << pixel_shift) - 2*h->mb_linesize, h->mb_linesize,
16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height);
@@ -511,42 +510,55 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
return;
}
- if(MB_FIELD){
+ ysh = 3 - (chroma_idc == 2 /* yuv422 */);
+ if(chroma_idc == 1 /* yuv420 */ && MB_FIELD){
// chroma offset when predicting from a field of opposite parity
- my += 2 * ((s->mb_y & 1) - (pic->reference - 1));
+ my += 2 * ((s->mb_y & 1) - (pic->f.reference - 1));
emu |= (my>>3) < 0 || (my>>3) + 8 >= (pic_height>>1);
}
- src_cb= pic->data[1] + ((mx>>3) << pixel_shift) + (my>>3)*h->mb_uvlinesize;
- src_cr= pic->data[2] + ((mx>>3) << pixel_shift) + (my>>3)*h->mb_uvlinesize;
+
+ src_cb = pic->f.data[1] + ((mx >> 3) << pixel_shift) + (my >> ysh) * h->mb_uvlinesize;
+ src_cr = pic->f.data[2] + ((mx >> 3) << pixel_shift) + (my >> ysh) * h->mb_uvlinesize;
if(emu){
- s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cb, h->mb_uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cb, h->mb_uvlinesize,
+ 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
+ pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
src_cb= s->edge_emu_buffer;
}
- chroma_op(dest_cb, src_cb, h->mb_uvlinesize, chroma_height, mx&7, my&7);
+ chroma_op(dest_cb, src_cb, h->mb_uvlinesize, height >> (chroma_idc == 1 /* yuv420 */),
+ mx&7, (my << (chroma_idc == 2 /* yuv422 */)) &7);
if(emu){
- s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cr, h->mb_uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, src_cr, h->mb_uvlinesize,
+ 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
+ pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
src_cr= s->edge_emu_buffer;
}
- chroma_op(dest_cr, src_cr, h->mb_uvlinesize, chroma_height, mx&7, my&7);
+ chroma_op(dest_cr, src_cr, h->mb_uvlinesize, height >> (chroma_idc == 1 /* yuv420 */),
+ mx&7, (my << (chroma_idc == 2 /* yuv422 */)) &7);
}
-static inline void mc_part_std(H264Context *h, int n, int square, int chroma_height, int delta,
- uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
- int x_offset, int y_offset,
- qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put,
- qpel_mc_func *qpix_avg, h264_chroma_mc_func chroma_avg,
- int list0, int list1, int pixel_shift, int chroma444){
+static av_always_inline void
+mc_part_std(H264Context *h, int n, int square, int height, int delta,
+ uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+ int x_offset, int y_offset,
+ qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put,
+ qpel_mc_func *qpix_avg, h264_chroma_mc_func chroma_avg,
+ int list0, int list1, int pixel_shift, int chroma_idc)
+{
MpegEncContext * const s = &h->s;
qpel_mc_func *qpix_op= qpix_put;
h264_chroma_mc_func chroma_op= chroma_put;
dest_y += (2*x_offset << pixel_shift) + 2*y_offset*h->mb_linesize;
- if(chroma444){
+ if (chroma_idc == 3 /* yuv444 */) {
dest_cb += (2*x_offset << pixel_shift) + 2*y_offset*h->mb_linesize;
dest_cr += (2*x_offset << pixel_shift) + 2*y_offset*h->mb_linesize;
- }else{
+ } else if (chroma_idc == 2 /* yuv422 */) {
+ dest_cb += ( x_offset << pixel_shift) + 2*y_offset*h->mb_uvlinesize;
+ dest_cr += ( x_offset << pixel_shift) + 2*y_offset*h->mb_uvlinesize;
+ } else /* yuv420 */ {
dest_cb += ( x_offset << pixel_shift) + y_offset*h->mb_uvlinesize;
dest_cr += ( x_offset << pixel_shift) + y_offset*h->mb_uvlinesize;
}
@@ -555,9 +567,9 @@ static inline void mc_part_std(H264Context *h, int n, int square, int chroma_hei
if(list0){
Picture *ref= &h->ref_list[0][ h->ref_cache[0][ scan8[n] ] ];
- mc_dir_part(h, ref, n, square, chroma_height, delta, 0,
+ mc_dir_part(h, ref, n, square, height, delta, 0,
dest_y, dest_cb, dest_cr, x_offset, y_offset,
- qpix_op, chroma_op, pixel_shift, chroma444);
+ qpix_op, chroma_op, pixel_shift, chroma_idc);
qpix_op= qpix_avg;
chroma_op= chroma_avg;
@@ -565,28 +577,36 @@ static inline void mc_part_std(H264Context *h, int n, int square, int chroma_hei
if(list1){
Picture *ref= &h->ref_list[1][ h->ref_cache[1][ scan8[n] ] ];
- mc_dir_part(h, ref, n, square, chroma_height, delta, 1,
+ mc_dir_part(h, ref, n, square, height, delta, 1,
dest_y, dest_cb, dest_cr, x_offset, y_offset,
- qpix_op, chroma_op, pixel_shift, chroma444);
+ qpix_op, chroma_op, pixel_shift, chroma_idc);
}
}
-static inline void mc_part_weighted(H264Context *h, int n, int square, int chroma_height, int delta,
- uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
- int x_offset, int y_offset,
- qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put,
- h264_weight_func luma_weight_op, h264_weight_func chroma_weight_op,
- h264_biweight_func luma_weight_avg, h264_biweight_func chroma_weight_avg,
- int list0, int list1, int pixel_shift, int chroma444){
+static av_always_inline void
+mc_part_weighted(H264Context *h, int n, int square, int height, int delta,
+ uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+ int x_offset, int y_offset,
+ qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put,
+ h264_weight_func luma_weight_op, h264_weight_func chroma_weight_op,
+ h264_biweight_func luma_weight_avg, h264_biweight_func chroma_weight_avg,
+ int list0, int list1, int pixel_shift, int chroma_idc){
MpegEncContext * const s = &h->s;
+ int chroma_height;
dest_y += (2*x_offset << pixel_shift) + 2*y_offset*h->mb_linesize;
- if(chroma444){
+ if (chroma_idc == 3 /* yuv444 */) {
+ chroma_height = height;
chroma_weight_avg = luma_weight_avg;
chroma_weight_op = luma_weight_op;
dest_cb += (2*x_offset << pixel_shift) + 2*y_offset*h->mb_linesize;
dest_cr += (2*x_offset << pixel_shift) + 2*y_offset*h->mb_linesize;
- }else{
+ } else if (chroma_idc == 2 /* yuv422 */) {
+ chroma_height = height;
+ dest_cb += ( x_offset << pixel_shift) + 2*y_offset*h->mb_uvlinesize;
+ dest_cr += ( x_offset << pixel_shift) + 2*y_offset*h->mb_uvlinesize;
+ } else /* yuv420 */ {
+ chroma_height = height >> 1;
dest_cb += ( x_offset << pixel_shift) + y_offset*h->mb_uvlinesize;
dest_cr += ( x_offset << pixel_shift) + y_offset*h->mb_uvlinesize;
}
@@ -602,27 +622,32 @@ static inline void mc_part_weighted(H264Context *h, int n, int square, int chrom
int refn0 = h->ref_cache[0][ scan8[n] ];
int refn1 = h->ref_cache[1][ scan8[n] ];
- mc_dir_part(h, &h->ref_list[0][refn0], n, square, chroma_height, delta, 0,
+ mc_dir_part(h, &h->ref_list[0][refn0], n, square, height, delta, 0,
dest_y, dest_cb, dest_cr,
- x_offset, y_offset, qpix_put, chroma_put, pixel_shift, chroma444);
- mc_dir_part(h, &h->ref_list[1][refn1], n, square, chroma_height, delta, 1,
+ x_offset, y_offset, qpix_put, chroma_put,
+ pixel_shift, chroma_idc);
+ mc_dir_part(h, &h->ref_list[1][refn1], n, square, height, delta, 1,
tmp_y, tmp_cb, tmp_cr,
- x_offset, y_offset, qpix_put, chroma_put, pixel_shift, chroma444);
+ x_offset, y_offset, qpix_put, chroma_put,
+ pixel_shift, chroma_idc);
if(h->use_weight == 2){
int weight0 = h->implicit_weight[refn0][refn1][s->mb_y&1];
int weight1 = 64 - weight0;
- luma_weight_avg( dest_y, tmp_y, h-> mb_linesize, 5, weight0, weight1, 0);
- chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, 5, weight0, weight1, 0);
- chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, 5, weight0, weight1, 0);
+ luma_weight_avg( dest_y, tmp_y, h-> mb_linesize,
+ height, 5, weight0, weight1, 0);
+ chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize,
+ chroma_height, 5, weight0, weight1, 0);
+ chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize,
+ chroma_height, 5, weight0, weight1, 0);
}else{
- luma_weight_avg(dest_y, tmp_y, h->mb_linesize, h->luma_log2_weight_denom,
+ luma_weight_avg(dest_y, tmp_y, h->mb_linesize, height, h->luma_log2_weight_denom,
h->luma_weight[refn0][0][0] , h->luma_weight[refn1][1][0],
h->luma_weight[refn0][0][1] + h->luma_weight[refn1][1][1]);
- chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, h->chroma_log2_weight_denom,
+ chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, chroma_height, h->chroma_log2_weight_denom,
h->chroma_weight[refn0][0][0][0] , h->chroma_weight[refn1][1][0][0],
h->chroma_weight[refn0][0][0][1] + h->chroma_weight[refn1][1][0][1]);
- chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, h->chroma_log2_weight_denom,
+ chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, chroma_height, h->chroma_log2_weight_denom,
h->chroma_weight[refn0][0][1][0] , h->chroma_weight[refn1][1][1][0],
h->chroma_weight[refn0][0][1][1] + h->chroma_weight[refn1][1][1][1]);
}
@@ -630,42 +655,46 @@ static inline void mc_part_weighted(H264Context *h, int n, int square, int chrom
int list = list1 ? 1 : 0;
int refn = h->ref_cache[list][ scan8[n] ];
Picture *ref= &h->ref_list[list][refn];
- mc_dir_part(h, ref, n, square, chroma_height, delta, list,
+ mc_dir_part(h, ref, n, square, height, delta, list,
dest_y, dest_cb, dest_cr, x_offset, y_offset,
- qpix_put, chroma_put, pixel_shift, chroma444);
+ qpix_put, chroma_put, pixel_shift, chroma_idc);
- luma_weight_op(dest_y, h->mb_linesize, h->luma_log2_weight_denom,
+ luma_weight_op(dest_y, h->mb_linesize, height, h->luma_log2_weight_denom,
h->luma_weight[refn][list][0], h->luma_weight[refn][list][1]);
if(h->use_weight_chroma){
- chroma_weight_op(dest_cb, h->mb_uvlinesize, h->chroma_log2_weight_denom,
+ chroma_weight_op(dest_cb, h->mb_uvlinesize, chroma_height, h->chroma_log2_weight_denom,
h->chroma_weight[refn][list][0][0], h->chroma_weight[refn][list][0][1]);
- chroma_weight_op(dest_cr, h->mb_uvlinesize, h->chroma_log2_weight_denom,
+ chroma_weight_op(dest_cr, h->mb_uvlinesize, chroma_height, h->chroma_log2_weight_denom,
h->chroma_weight[refn][list][1][0], h->chroma_weight[refn][list][1][1]);
}
}
}
-static inline void mc_part(H264Context *h, int n, int square, int chroma_height, int delta,
- uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
- int x_offset, int y_offset,
- qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put,
- qpel_mc_func *qpix_avg, h264_chroma_mc_func chroma_avg,
- h264_weight_func *weight_op, h264_biweight_func *weight_avg,
- int list0, int list1, int pixel_shift, int chroma444){
+static av_always_inline void
+mc_part(H264Context *h, int n, int square, int height, int delta,
+ uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+ int x_offset, int y_offset,
+ qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put,
+ qpel_mc_func *qpix_avg, h264_chroma_mc_func chroma_avg,
+ h264_weight_func *weight_op, h264_biweight_func *weight_avg,
+ int list0, int list1, int pixel_shift, int chroma_idc)
+{
if((h->use_weight==2 && list0 && list1
&& (h->implicit_weight[ h->ref_cache[0][scan8[n]] ][ h->ref_cache[1][scan8[n]] ][h->s.mb_y&1] != 32))
|| h->use_weight==1)
- mc_part_weighted(h, n, square, chroma_height, delta, dest_y, dest_cb, dest_cr,
+ mc_part_weighted(h, n, square, height, delta, dest_y, dest_cb, dest_cr,
x_offset, y_offset, qpix_put, chroma_put,
- weight_op[0], weight_op[3], weight_avg[0],
- weight_avg[3], list0, list1, pixel_shift, chroma444);
+ weight_op[0], weight_op[1], weight_avg[0],
+ weight_avg[1], list0, list1, pixel_shift, chroma_idc);
else
- mc_part_std(h, n, square, chroma_height, delta, dest_y, dest_cb, dest_cr,
+ mc_part_std(h, n, square, height, delta, dest_y, dest_cb, dest_cr,
x_offset, y_offset, qpix_put, chroma_put, qpix_avg,
- chroma_avg, list0, list1, pixel_shift, chroma444);
+ chroma_avg, list0, list1, pixel_shift, chroma_idc);
}
-static inline void prefetch_motion(H264Context *h, int list, int pixel_shift, int chroma444){
+static av_always_inline void
+prefetch_motion(H264Context *h, int list, int pixel_shift, int chroma_idc)
+{
/* fetch pixels for estimated mv 4 macroblocks ahead
* optimized for 64byte cache lines */
MpegEncContext * const s = &h->s;
@@ -673,10 +702,10 @@ static inline void prefetch_motion(H264Context *h, int list, int pixel_shift, in
if(refn >= 0){
const int mx= (h->mv_cache[list][scan8[0]][0]>>2) + 16*s->mb_x + 8;
const int my= (h->mv_cache[list][scan8[0]][1]>>2) + 16*s->mb_y;
- uint8_t **src= h->ref_list[list][refn].data;
+ uint8_t **src = h->ref_list[list][refn].f.data;
int off= (mx << pixel_shift) + (my + (s->mb_x&3)*4)*h->mb_linesize + (64 << pixel_shift);
s->dsp.prefetch(src[0]+off, s->linesize, 4);
- if(chroma444){
+ if (chroma_idc == 3 /* yuv444 */) {
s->dsp.prefetch(src[1]+off, s->linesize, 4);
s->dsp.prefetch(src[2]+off, s->linesize, 4);
}else{
@@ -690,45 +719,46 @@ static av_always_inline void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t
qpel_mc_func (*qpix_put)[16], h264_chroma_mc_func (*chroma_put),
qpel_mc_func (*qpix_avg)[16], h264_chroma_mc_func (*chroma_avg),
h264_weight_func *weight_op, h264_biweight_func *weight_avg,
- int pixel_shift, int chroma444){
+ int pixel_shift, int chroma_idc)
+{
MpegEncContext * const s = &h->s;
const int mb_xy= h->mb_xy;
- const int mb_type= s->current_picture.mb_type[mb_xy];
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
assert(IS_INTER(mb_type));
- if(HAVE_PTHREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
+ if(HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
await_references(h);
- prefetch_motion(h, 0, pixel_shift, chroma444);
+ prefetch_motion(h, 0, pixel_shift, chroma_idc);
if(IS_16X16(mb_type)){
- mc_part(h, 0, 1, 8, 0, dest_y, dest_cb, dest_cr, 0, 0,
+ mc_part(h, 0, 1, 16, 0, dest_y, dest_cb, dest_cr, 0, 0,
qpix_put[0], chroma_put[0], qpix_avg[0], chroma_avg[0],
weight_op, weight_avg,
IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1),
- pixel_shift, chroma444);
+ pixel_shift, chroma_idc);
}else if(IS_16X8(mb_type)){
- mc_part(h, 0, 0, 4, 8 << pixel_shift, dest_y, dest_cb, dest_cr, 0, 0,
+ mc_part(h, 0, 0, 8, 8 << pixel_shift, dest_y, dest_cb, dest_cr, 0, 0,
qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0],
- &weight_op[1], &weight_avg[1],
+ weight_op, weight_avg,
IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1),
- pixel_shift, chroma444);
- mc_part(h, 8, 0, 4, 8 << pixel_shift, dest_y, dest_cb, dest_cr, 0, 4,
+ pixel_shift, chroma_idc);
+ mc_part(h, 8, 0, 8, 8 << pixel_shift, dest_y, dest_cb, dest_cr, 0, 4,
qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0],
- &weight_op[1], &weight_avg[1],
+ weight_op, weight_avg,
IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1),
- pixel_shift, chroma444);
+ pixel_shift, chroma_idc);
}else if(IS_8X16(mb_type)){
- mc_part(h, 0, 0, 8, 8*h->mb_linesize, dest_y, dest_cb, dest_cr, 0, 0,
+ mc_part(h, 0, 0, 16, 8*h->mb_linesize, dest_y, dest_cb, dest_cr, 0, 0,
qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
- &weight_op[2], &weight_avg[2],
+ &weight_op[1], &weight_avg[1],
IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1),
- pixel_shift, chroma444);
- mc_part(h, 4, 0, 8, 8*h->mb_linesize, dest_y, dest_cb, dest_cr, 4, 0,
+ pixel_shift, chroma_idc);
+ mc_part(h, 4, 0, 16, 8*h->mb_linesize, dest_y, dest_cb, dest_cr, 4, 0,
qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
- &weight_op[2], &weight_avg[2],
+ &weight_op[1], &weight_avg[1],
IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1),
- pixel_shift, chroma444);
+ pixel_shift, chroma_idc);
}else{
int i;
@@ -741,69 +771,73 @@ static av_always_inline void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t
int y_offset= (i&2)<<1;
if(IS_SUB_8X8(sub_mb_type)){
- mc_part(h, n, 1, 4, 0, dest_y, dest_cb, dest_cr, x_offset, y_offset,
+ mc_part(h, n, 1, 8, 0, dest_y, dest_cb, dest_cr, x_offset, y_offset,
qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
- &weight_op[3], &weight_avg[3],
+ &weight_op[1], &weight_avg[1],
IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma444);
+ pixel_shift, chroma_idc);
}else if(IS_SUB_8X4(sub_mb_type)){
- mc_part(h, n , 0, 2, 4 << pixel_shift, dest_y, dest_cb, dest_cr, x_offset, y_offset,
+ mc_part(h, n , 0, 4, 4 << pixel_shift, dest_y, dest_cb, dest_cr, x_offset, y_offset,
qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1],
- &weight_op[4], &weight_avg[4],
+ &weight_op[1], &weight_avg[1],
IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma444);
- mc_part(h, n+2, 0, 2, 4 << pixel_shift, dest_y, dest_cb, dest_cr, x_offset, y_offset+2,
+ pixel_shift, chroma_idc);
+ mc_part(h, n+2, 0, 4, 4 << pixel_shift, dest_y, dest_cb, dest_cr, x_offset, y_offset+2,
qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1],
- &weight_op[4], &weight_avg[4],
+ &weight_op[1], &weight_avg[1],
IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma444);
+ pixel_shift, chroma_idc);
}else if(IS_SUB_4X8(sub_mb_type)){
- mc_part(h, n , 0, 4, 4*h->mb_linesize, dest_y, dest_cb, dest_cr, x_offset, y_offset,
+ mc_part(h, n , 0, 8, 4*h->mb_linesize, dest_y, dest_cb, dest_cr, x_offset, y_offset,
qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
- &weight_op[5], &weight_avg[5],
+ &weight_op[2], &weight_avg[2],
IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma444);
- mc_part(h, n+1, 0, 4, 4*h->mb_linesize, dest_y, dest_cb, dest_cr, x_offset+2, y_offset,
+ pixel_shift, chroma_idc);
+ mc_part(h, n+1, 0, 8, 4*h->mb_linesize, dest_y, dest_cb, dest_cr, x_offset+2, y_offset,
qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
- &weight_op[5], &weight_avg[5],
+ &weight_op[2], &weight_avg[2],
IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma444);
+ pixel_shift, chroma_idc);
}else{
int j;
assert(IS_SUB_4X4(sub_mb_type));
for(j=0; j<4; j++){
int sub_x_offset= x_offset + 2*(j&1);
int sub_y_offset= y_offset + (j&2);
- mc_part(h, n+j, 1, 2, 0, dest_y, dest_cb, dest_cr, sub_x_offset, sub_y_offset,
+ mc_part(h, n+j, 1, 4, 0, dest_y, dest_cb, dest_cr, sub_x_offset, sub_y_offset,
qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
- &weight_op[6], &weight_avg[6],
+ &weight_op[2], &weight_avg[2],
IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1),
- pixel_shift, chroma444);
+ pixel_shift, chroma_idc);
}
}
}
}
- prefetch_motion(h, 1, pixel_shift, chroma444);
+ prefetch_motion(h, 1, pixel_shift, chroma_idc);
}
-#define hl_motion_fn(sh, bits) \
-static av_always_inline void hl_motion_ ## bits(H264Context *h, \
- uint8_t *dest_y, \
- uint8_t *dest_cb, uint8_t *dest_cr, \
- qpel_mc_func (*qpix_put)[16], \
- h264_chroma_mc_func (*chroma_put), \
- qpel_mc_func (*qpix_avg)[16], \
- h264_chroma_mc_func (*chroma_avg), \
- h264_weight_func *weight_op, \
- h264_biweight_func *weight_avg, \
- int chroma444) \
-{ \
- hl_motion(h, dest_y, dest_cb, dest_cr, qpix_put, chroma_put, \
- qpix_avg, chroma_avg, weight_op, weight_avg, sh, chroma444); \
+static av_always_inline void
+hl_motion_420(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+ qpel_mc_func (*qpix_put)[16], h264_chroma_mc_func (*chroma_put),
+ qpel_mc_func (*qpix_avg)[16], h264_chroma_mc_func (*chroma_avg),
+ h264_weight_func *weight_op, h264_biweight_func *weight_avg,
+ int pixel_shift)
+{
+ hl_motion(h, dest_y, dest_cb, dest_cr, qpix_put, chroma_put,
+ qpix_avg, chroma_avg, weight_op, weight_avg, pixel_shift, 1);
+}
+
+static av_always_inline void
+hl_motion_422(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+ qpel_mc_func (*qpix_put)[16], h264_chroma_mc_func (*chroma_put),
+ qpel_mc_func (*qpix_avg)[16], h264_chroma_mc_func (*chroma_avg),
+ h264_weight_func *weight_op, h264_biweight_func *weight_avg,
+ int pixel_shift)
+{
+ hl_motion(h, dest_y, dest_cb, dest_cr, qpix_put, chroma_put,
+ qpix_avg, chroma_avg, weight_op, weight_avg, pixel_shift, 2);
}
-hl_motion_fn(0, 8);
-hl_motion_fn(1, 16);
static void free_tables(H264Context *h, int free_rbsp){
int i;
@@ -969,7 +1003,7 @@ static void clone_tables(H264Context *dst, H264Context *src, int i){
dst->list_counts = src->list_counts;
dst->s.obmc_scratchpad = NULL;
- ff_h264_pred_init(&dst->hpc, src->s.codec_id, src->sps.bit_depth_luma);
+ ff_h264_pred_init(&dst->hpc, src->s.codec_id, src->sps.bit_depth_luma, src->sps.chroma_format_idc);
}
/**
@@ -997,12 +1031,11 @@ static av_cold void common_init(H264Context *h){
s->height = s->avctx->height;
s->codec_id= s->avctx->codec->id;
- ff_h264dsp_init(&h->h264dsp, 8);
- ff_h264_pred_init(&h->hpc, s->codec_id, 8);
+ ff_h264dsp_init(&h->h264dsp, 8, 1);
+ ff_h264_pred_init(&h->hpc, s->codec_id, 8, 1);
h->dequant_coeff_pps= -1;
s->unrestricted_mv=1;
- s->decode=1; //FIXME
dsputil_init(&s->dsp, s->avctx); // needed so that idct permutation is known early
@@ -1032,6 +1065,8 @@ int ff_h264_decode_extradata(H264Context *h)
p += 6;
for (i = 0; i < cnt; i++) {
nalsize = AV_RB16(p) + 2;
+ if (p - avctx->extradata + nalsize > avctx->extradata_size)
+ return -1;
if(decode_nal_units(h, p, nalsize) < 0) {
av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i);
return -1;
@@ -1042,6 +1077,8 @@ int ff_h264_decode_extradata(H264Context *h)
cnt = *(p++); // Number of pps
for (i = 0; i < cnt; i++) {
nalsize = AV_RB16(p) + 2;
+ if (p - avctx->extradata + nalsize > avctx->extradata_size)
+ return -1;
if (decode_nal_units(h, p, nalsize) < 0) {
av_log(avctx, AV_LOG_ERROR, "Decoding pps %d from avcC failed\n", i);
return -1;
@@ -1061,6 +1098,7 @@ int ff_h264_decode_extradata(H264Context *h)
av_cold int ff_h264_decode_init(AVCodecContext *avctx){
H264Context *h= avctx->priv_data;
MpegEncContext * const s = &h->s;
+ int i;
MPV_decode_defaults(s);
@@ -1085,6 +1123,8 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){
h->thread_context[0] = h;
h->outputed_poc = h->next_outputed_poc = INT_MIN;
+ for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
+ h->last_pocs[i] = INT_MIN;
h->prev_poc_msb= 1<<16;
h->x264_build = -1;
ff_h264_reset_sei(h);
@@ -1135,7 +1175,8 @@ static void copy_parameter_set(void **to, void **from, int count, int size)
static int decode_init_thread_copy(AVCodecContext *avctx){
H264Context *h= avctx->priv_data;
- if (!avctx->is_copy) return 0;
+ if (!avctx->internal->is_copy)
+ return 0;
memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
@@ -1224,7 +1265,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex
if(!s->current_picture_ptr) return 0;
if(!s->dropable) {
- ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
+ err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
h->prev_poc_msb = h->poc_msb;
h->prev_poc_lsb = h->poc_lsb;
}
@@ -1232,7 +1273,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex
h->prev_frame_num = h->frame_num;
h->outputed_poc = h->next_outputed_poc;
- return 0;
+ return err;
}
int ff_h264_frame_start(H264Context *h){
@@ -1250,7 +1291,7 @@ int ff_h264_frame_start(H264Context *h){
* Zero here; IDR markings per slice in frame or fields are ORed in later.
* See decode_nal_units().
*/
- s->current_picture_ptr->key_frame= 0;
+ s->current_picture_ptr->f.key_frame = 0;
s->current_picture_ptr->mmco_reset= 0;
assert(s->linesize && s->uvlinesize);
@@ -1275,7 +1316,7 @@ int ff_h264_frame_start(H264Context *h){
/* some macroblocks can be accessed before they're available in case of lost slices, mbaff or threading*/
memset(h->slice_table, -1, (s->mb_height*s->mb_stride-1) * sizeof(*h->slice_table));
-// s->decode= (s->flags&CODEC_FLAG_PSNR) || !s->encoding || s->current_picture.reference /*|| h->contains_intra*/ || 1;
+// s->decode = (s->flags & CODEC_FLAG_PSNR) || !s->encoding || s->current_picture.f.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
@@ -1284,7 +1325,7 @@ int ff_h264_frame_start(H264Context *h){
// 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;
+ s->current_picture_ptr->f.reference = 0;
s->current_picture_ptr->field_poc[0]=
s->current_picture_ptr->field_poc[1]= INT_MAX;
@@ -1309,9 +1350,10 @@ static void decode_postinit(H264Context *h, int setup_finished){
Picture *out = s->current_picture_ptr;
Picture *cur = s->current_picture_ptr;
int i, pics, out_of_order, out_idx;
+ int invalid = 0, cnt = 0;
- s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_H264;
- s->current_picture_ptr->pict_type= s->pict_type;
+ s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
+ s->current_picture_ptr->f.pict_type = s->pict_type;
if (h->next_output_pic) return;
@@ -1324,8 +1366,8 @@ static void decode_postinit(H264Context *h, int setup_finished){
return;
}
- cur->interlaced_frame = 0;
- cur->repeat_pict = 0;
+ cur->f.interlaced_frame = 0;
+ cur->f.repeat_pict = 0;
/* Signal interlacing information externally. */
/* Prioritize picture timing SEI information over used decoding process if it exists. */
@@ -1337,53 +1379,53 @@ static void decode_postinit(H264Context *h, int setup_finished){
break;
case SEI_PIC_STRUCT_TOP_FIELD:
case SEI_PIC_STRUCT_BOTTOM_FIELD:
- cur->interlaced_frame = 1;
+ cur->f.interlaced_frame = 1;
break;
case SEI_PIC_STRUCT_TOP_BOTTOM:
case SEI_PIC_STRUCT_BOTTOM_TOP:
if (FIELD_OR_MBAFF_PICTURE)
- cur->interlaced_frame = 1;
+ cur->f.interlaced_frame = 1;
else
// try to flag soft telecine progressive
- cur->interlaced_frame = h->prev_interlaced_frame;
+ cur->f.interlaced_frame = h->prev_interlaced_frame;
break;
case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
// Signal the possibility of telecined film externally (pic_struct 5,6)
// From these hints, let the applications decide if they apply deinterlacing.
- cur->repeat_pict = 1;
+ cur->f.repeat_pict = 1;
break;
case SEI_PIC_STRUCT_FRAME_DOUBLING:
// Force progressive here, as doubling interlaced frame is a bad idea.
- cur->repeat_pict = 2;
+ cur->f.repeat_pict = 2;
break;
case SEI_PIC_STRUCT_FRAME_TRIPLING:
- cur->repeat_pict = 4;
+ cur->f.repeat_pict = 4;
break;
}
if ((h->sei_ct_type & 3) && h->sei_pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP)
- cur->interlaced_frame = (h->sei_ct_type & (1<<1)) != 0;
+ cur->f.interlaced_frame = (h->sei_ct_type & (1 << 1)) != 0;
}else{
/* Derive interlacing flag from used decoding process. */
- cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
+ cur->f.interlaced_frame = FIELD_OR_MBAFF_PICTURE;
}
- h->prev_interlaced_frame = cur->interlaced_frame;
+ h->prev_interlaced_frame = cur->f.interlaced_frame;
if (cur->field_poc[0] != cur->field_poc[1]){
/* Derive top_field_first from field pocs. */
- cur->top_field_first = cur->field_poc[0] < cur->field_poc[1];
+ cur->f.top_field_first = cur->field_poc[0] < cur->field_poc[1];
}else{
- if(cur->interlaced_frame || h->sps.pic_struct_present_flag){
+ if (cur->f.interlaced_frame || h->sps.pic_struct_present_flag) {
/* Use picture timing SEI information. Even if it is a information of a past frame, better than nothing. */
if(h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM
|| h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
- cur->top_field_first = 1;
+ cur->f.top_field_first = 1;
else
- cur->top_field_first = 0;
+ cur->f.top_field_first = 0;
}else{
/* Most likely progressive */
- cur->top_field_first = 0;
+ cur->f.top_field_first = 0;
}
}
@@ -1399,7 +1441,7 @@ static void decode_postinit(H264Context *h, int setup_finished){
if( s->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT
&& !h->sps.bitstream_restriction_flag){
- s->avctx->has_b_frames= MAX_DELAYED_PIC_COUNT;
+ s->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
s->low_delay= 0;
}
@@ -1409,44 +1451,92 @@ static void decode_postinit(H264Context *h, int setup_finished){
assert(pics <= MAX_DELAYED_PIC_COUNT);
h->delayed_pic[pics++] = cur;
- if(cur->reference == 0)
- cur->reference = DELAYED_PIC_REF;
-
+ if (cur->f.reference == 0)
+ cur->f.reference = DELAYED_PIC_REF;
+
+ /* Frame reordering. This code takes pictures from coding order and sorts
+ * them by their incremental POC value into display order. It supports POC
+ * gaps, MMCO reset codes and random resets.
+ * A "display group" can start either with a IDR frame (f.key_frame = 1),
+ * and/or can be closed down with a MMCO reset code. In sequences where
+ * there is no delay, we can't detect that (since the frame was already
+ * output to the user), so we also set h->mmco_reset to detect the MMCO
+ * reset code.
+ * FIXME: if we detect insufficient delays (as per s->avctx->has_b_frames),
+ * we increase the delay between input and output. All frames affected by
+ * the lag (e.g. those that should have been output before another frame
+ * that we already returned to the user) will be dropped. This is a bug
+ * that we will fix later. */
+ for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) {
+ cnt += out->poc < h->last_pocs[i];
+ invalid += out->poc == INT_MIN;
+ }
+ if (!h->mmco_reset && !cur->f.key_frame && cnt + invalid == MAX_DELAYED_PIC_COUNT && cnt > 0) {
+ h->mmco_reset = 2;
+ if (pics > 1)
+ h->delayed_pic[pics - 2]->mmco_reset = 2;
+ }
+ if (h->mmco_reset || cur->f.key_frame) {
+ for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
+ h->last_pocs[i] = INT_MIN;
+ cnt = 0;
+ invalid = MAX_DELAYED_PIC_COUNT;
+ }
out = h->delayed_pic[0];
out_idx = 0;
- for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame && !h->delayed_pic[i]->mmco_reset; i++)
+ for (i = 1; i < MAX_DELAYED_PIC_COUNT && h->delayed_pic[i] &&
+ !h->delayed_pic[i-1]->mmco_reset && !h->delayed_pic[i]->f.key_frame; i++)
+ {
if(h->delayed_pic[i]->poc < out->poc){
out = h->delayed_pic[i];
out_idx = i;
}
- if(s->avctx->has_b_frames == 0 && (h->delayed_pic[0]->key_frame || h->delayed_pic[0]->mmco_reset))
- h->next_outputed_poc= INT_MIN;
- out_of_order = out->poc < h->next_outputed_poc;
+ }
+ if (s->avctx->has_b_frames == 0 && (h->delayed_pic[0]->f.key_frame || h->mmco_reset))
+ h->next_outputed_poc = INT_MIN;
+ out_of_order = !out->f.key_frame && !h->mmco_reset && (out->poc < h->next_outputed_poc);
if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >= h->sps.num_reorder_frames)
{ }
- else if((out_of_order && pics-1 == s->avctx->has_b_frames && s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT)
- || (s->low_delay &&
- ((h->next_outputed_poc != INT_MIN && out->poc > h->next_outputed_poc + 2)
- || cur->pict_type == AV_PICTURE_TYPE_B)))
- {
+ else if (out_of_order && pics-1 == s->avctx->has_b_frames &&
+ s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) {
+ if (invalid + cnt < MAX_DELAYED_PIC_COUNT) {
+ s->avctx->has_b_frames = FFMAX(s->avctx->has_b_frames, cnt);
+ }
+ s->low_delay = 0;
+ } else if (s->low_delay &&
+ ((h->next_outputed_poc != INT_MIN && out->poc > h->next_outputed_poc + 2) ||
+ cur->f.pict_type == AV_PICTURE_TYPE_B)) {
s->low_delay = 0;
s->avctx->has_b_frames++;
}
- if(out_of_order || pics > s->avctx->has_b_frames){
- out->reference &= ~DELAYED_PIC_REF;
+ if(pics > s->avctx->has_b_frames){
+ out->f.reference &= ~DELAYED_PIC_REF;
out->owner2 = s; // for frame threading, the owner must be the second field's thread
// or else the first thread can release the picture and reuse it unsafely
for(i=out_idx; h->delayed_pic[i]; i++)
h->delayed_pic[i] = h->delayed_pic[i+1];
}
+ memmove(h->last_pocs, &h->last_pocs[1], sizeof(*h->last_pocs) * (MAX_DELAYED_PIC_COUNT - 1));
+ h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = cur->poc;
if(!out_of_order && pics > s->avctx->has_b_frames){
h->next_output_pic = out;
- if(out_idx==0 && h->delayed_pic[0] && (h->delayed_pic[0]->key_frame || h->delayed_pic[0]->mmco_reset)) {
- h->next_outputed_poc = INT_MIN;
- } else
- h->next_outputed_poc = out->poc;
+ if (out->mmco_reset) {
+ if (out_idx > 0) {
+ h->next_outputed_poc = out->poc;
+ h->delayed_pic[out_idx - 1]->mmco_reset = out->mmco_reset;
+ } else {
+ h->next_outputed_poc = INT_MIN;
+ }
+ } else {
+ if (out_idx == 0 && pics > 1 && h->delayed_pic[0]->f.key_frame) {
+ h->next_outputed_poc = INT_MIN;
+ } else {
+ h->next_outputed_poc = out->poc;
+ }
+ }
+ h->mmco_reset = 0;
}else{
av_log(s->avctx, AV_LOG_DEBUG, "no picture\n");
}
@@ -1455,11 +1545,16 @@ static void decode_postinit(H264Context *h, int setup_finished){
ff_thread_finish_setup(s->avctx);
}
-static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int chroma444, int simple){
+static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
+ uint8_t *src_cb, uint8_t *src_cr,
+ int linesize, int uvlinesize, int simple)
+{
MpegEncContext * const s = &h->s;
uint8_t *top_border;
int top_idx = 1;
const int pixel_shift = h->pixel_shift;
+ int chroma444 = CHROMA444;
+ int chroma422 = CHROMA422;
src_y -= linesize;
src_cb -= uvlinesize;
@@ -1483,6 +1578,14 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src
AV_COPY128(top_border+16, src_cb + 15*uvlinesize);
AV_COPY128(top_border+32, src_cr + 15*uvlinesize);
}
+ } else if(chroma422) {
+ if (pixel_shift) {
+ AV_COPY128(top_border+32, src_cb + 15*uvlinesize);
+ AV_COPY128(top_border+48, src_cr + 15*uvlinesize);
+ } else {
+ AV_COPY64(top_border+16, src_cb + 15*uvlinesize);
+ AV_COPY64(top_border+24, src_cr + 15*uvlinesize);
+ }
} else {
if (pixel_shift) {
AV_COPY128(top_border+32, src_cb+7*uvlinesize);
@@ -1518,6 +1621,14 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src
AV_COPY128(top_border+16, src_cb + 16*linesize);
AV_COPY128(top_border+32, src_cr + 16*linesize);
}
+ } else if(chroma422) {
+ if (pixel_shift) {
+ AV_COPY128(top_border+32, src_cb+16*uvlinesize);
+ AV_COPY128(top_border+48, src_cr+16*uvlinesize);
+ } else {
+ AV_COPY64(top_border+16, src_cb+16*uvlinesize);
+ AV_COPY64(top_border+24, src_cr+16*uvlinesize);
+ }
} else {
if (pixel_shift) {
AV_COPY128(top_border+32, src_cb+8*uvlinesize);
@@ -1530,7 +1641,7 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src
}
}
-static inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
+static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
uint8_t *src_cb, uint8_t *src_cr,
int linesize, int uvlinesize,
int xchg, int chroma444,
@@ -1691,7 +1802,7 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h, int mb_ty
tr_high= ((uint16_t*)ptr)[3 - linesize/2]*0x0001000100010001ULL;
topright= (uint8_t*) &tr_high;
} else {
- tr= ptr[3 - linesize]*0x01010101;
+ tr= ptr[3 - linesize]*0x01010101u;
topright= (uint8_t*) &tr;
}
}else
@@ -1724,7 +1835,7 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h, int mb_ty
static const uint8_t dc_mapping[16] = { 0*16, 1*16, 4*16, 5*16, 2*16, 3*16, 6*16, 7*16,
8*16, 9*16,12*16,13*16,10*16,11*16,14*16,15*16};
for(i = 0; i < 16; i++)
- dctcoef_set(h->mb+p*256, pixel_shift, dc_mapping[i], dctcoef_get(h->mb_luma_dc[p], pixel_shift, i));
+ dctcoef_set(h->mb+(p*256 << pixel_shift), pixel_shift, dc_mapping[i], dctcoef_get(h->mb_luma_dc[p], pixel_shift, i));
}
}
}else
@@ -1782,12 +1893,13 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
}
}
-static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, int pixel_shift){
+static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, int pixel_shift)
+{
MpegEncContext * const s = &h->s;
const int mb_x= s->mb_x;
const int mb_y= s->mb_y;
const int mb_xy= h->mb_xy;
- const int mb_type= s->current_picture.mb_type[mb_xy];
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
uint8_t *dest_y, *dest_cb, *dest_cr;
int linesize, uvlinesize /*dct_offset*/;
int i, j;
@@ -1796,10 +1908,12 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i
/* is_h264 should always be true if SVQ3 is disabled. */
const int is_h264 = !CONFIG_SVQ3_DECODER || simple || s->codec_id == CODEC_ID_H264;
void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
+ const int block_h = 16 >> s->chroma_y_shift;
+ const int chroma422 = CHROMA422;
- dest_y = s->current_picture.data[0] + ((mb_x << pixel_shift) + mb_y * s->linesize ) * 16;
- dest_cb = s->current_picture.data[1] + ((mb_x << pixel_shift) + mb_y * s->uvlinesize) * 8;
- dest_cr = s->current_picture.data[2] + ((mb_x << pixel_shift) + mb_y * s->uvlinesize) * 8;
+ dest_y = s->current_picture.f.data[0] + ((mb_x << pixel_shift) + mb_y * s->linesize ) * 16;
+ dest_cb = s->current_picture.f.data[1] + (mb_x << pixel_shift)*8 + mb_y * s->uvlinesize * block_h;
+ dest_cr = s->current_picture.f.data[2] + (mb_x << pixel_shift)*8 + mb_y * s->uvlinesize * block_h;
s->dsp.prefetch(dest_y + (s->mb_x&3)*4*s->linesize + (64 << pixel_shift), s->linesize, 4);
s->dsp.prefetch(dest_cb + (s->mb_x&7)*s->uvlinesize + (64 << pixel_shift), dest_cr - dest_cb, 2);
@@ -1812,8 +1926,8 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i
block_offset = &h->block_offset[48];
if(mb_y&1){ //FIXME move out of this function?
dest_y -= s->linesize*15;
- dest_cb-= s->uvlinesize*7;
- dest_cr-= s->uvlinesize*7;
+ dest_cb-= s->uvlinesize * (block_h - 1);
+ dest_cr-= s->uvlinesize * (block_h - 1);
}
if(FRAME_MBAFF) {
int list;
@@ -1852,25 +1966,25 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i
}
if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
if (!h->sps.chroma_format_idc) {
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < block_h; i++) {
uint16_t *tmp_cb = (uint16_t*)(dest_cb + i*uvlinesize);
for (j = 0; j < 8; j++) {
tmp_cb[j] = 1 << (bit_depth - 1);
}
}
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < block_h; i++) {
uint16_t *tmp_cr = (uint16_t*)(dest_cr + i*uvlinesize);
for (j = 0; j < 8; j++) {
tmp_cr[j] = 1 << (bit_depth - 1);
}
}
} else {
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < block_h; i++) {
uint16_t *tmp_cb = (uint16_t*)(dest_cb + i*uvlinesize);
for (j = 0; j < 8; j++)
tmp_cb[j] = get_bits(&gb, bit_depth);
}
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < block_h; i++) {
uint16_t *tmp_cr = (uint16_t*)(dest_cr + i*uvlinesize);
for (j = 0; j < 8; j++)
tmp_cr[j] = get_bits(&gb, bit_depth);
@@ -1883,12 +1997,12 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i
}
if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
if (!h->sps.chroma_format_idc) {
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < block_h; i++) {
memset(dest_cb + i*uvlinesize, 128, 8);
memset(dest_cr + i*uvlinesize, 128, 8);
}
} else {
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < block_h; i++) {
memcpy(dest_cb + i*uvlinesize, h->mb + 128 + i*4, 8);
memcpy(dest_cr + i*uvlinesize, h->mb + 160 + i*4, 8);
}
@@ -1910,18 +2024,21 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i
if(h->deblocking_filter)
xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0, 0, simple, pixel_shift);
}else if(is_h264){
- if (pixel_shift) {
- hl_motion_16(h, dest_y, dest_cb, dest_cr,
- s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
- s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
- h->h264dsp.weight_h264_pixels_tab,
- h->h264dsp.biweight_h264_pixels_tab, 0);
- } else
- hl_motion_8(h, dest_y, dest_cb, dest_cr,
- s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
- s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
- h->h264dsp.weight_h264_pixels_tab,
- h->h264dsp.biweight_h264_pixels_tab, 0);
+ if (chroma422) {
+ hl_motion_422(h, dest_y, dest_cb, dest_cr,
+ s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
+ s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+ h->h264dsp.weight_h264_pixels_tab,
+ h->h264dsp.biweight_h264_pixels_tab,
+ pixel_shift);
+ } else {
+ hl_motion_420(h, dest_y, dest_cb, dest_cr,
+ s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
+ s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+ h->h264dsp.weight_h264_pixels_tab,
+ h->h264dsp.biweight_h264_pixels_tab,
+ pixel_shift);
+ }
}
hl_decode_mb_idct_luma(h, mb_type, is_h264, simple, transform_bypass, pixel_shift, block_offset, linesize, dest_y, 0);
@@ -1939,14 +2056,28 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i
if(h->non_zero_count_cache[ scan8[i] ] || dctcoef_get(h->mb, pixel_shift, i*16))
idct_add (dest[j-1] + block_offset[i], h->mb + (i*16 << pixel_shift), uvlinesize);
}
+ if (chroma422) {
+ for(i=j*16+4; i<j*16+8; i++){
+ if(h->non_zero_count_cache[ scan8[i+4] ] || dctcoef_get(h->mb, pixel_shift, i*16))
+ idct_add (dest[j-1] + block_offset[i+4], h->mb + (i*16 << pixel_shift), uvlinesize);
+ }
+ }
}
}
}else{
if(is_h264){
+ int qp[2];
+ if (chroma422) {
+ qp[0] = h->chroma_qp[0] + 3;
+ qp[1] = h->chroma_qp[1] + 3;
+ } else {
+ qp[0] = h->chroma_qp[0];
+ qp[1] = h->chroma_qp[1];
+ }
if(h->non_zero_count_cache[ scan8[CHROMA_DC_BLOCK_INDEX+0] ])
- h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + (16*16*1 << pixel_shift), h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][h->chroma_qp[0]][0]);
+ h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + (16*16*1 << pixel_shift), h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][qp[0]][0]);
if(h->non_zero_count_cache[ scan8[CHROMA_DC_BLOCK_INDEX+1] ])
- h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + (16*16*2 << pixel_shift), h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][h->chroma_qp[1]][0]);
+ h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + (16*16*2 << pixel_shift), h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][qp[1]][0]);
h->h264dsp.h264_idct_add8(dest, block_offset,
h->mb, uvlinesize,
h->non_zero_count_cache);
@@ -1977,7 +2108,7 @@ static av_always_inline void hl_decode_mb_444_internal(H264Context *h, int simpl
const int mb_x= s->mb_x;
const int mb_y= s->mb_y;
const int mb_xy= h->mb_xy;
- const int mb_type= s->current_picture.mb_type[mb_xy];
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
uint8_t *dest[3];
int linesize;
int i, j, p;
@@ -1987,7 +2118,7 @@ static av_always_inline void hl_decode_mb_444_internal(H264Context *h, int simpl
for (p = 0; p < plane_count; p++)
{
- dest[p] = s->current_picture.data[p] + ((mb_x << pixel_shift) + mb_y * s->linesize) * 16;
+ dest[p] = s->current_picture.f.data[p] + ((mb_x << pixel_shift) + mb_y * s->linesize) * 16;
s->dsp.prefetch(dest[p] + (s->mb_x&3)*4*s->linesize + (64 << pixel_shift), s->linesize, 4);
}
@@ -2051,18 +2182,11 @@ static av_always_inline void hl_decode_mb_444_internal(H264Context *h, int simpl
if(h->deblocking_filter)
xchg_mb_border(h, dest[0], dest[1], dest[2], linesize, linesize, 0, 1, simple, pixel_shift);
}else{
- if (pixel_shift) {
- hl_motion_16(h, dest[0], dest[1], dest[2],
- s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
- s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
- h->h264dsp.weight_h264_pixels_tab,
- h->h264dsp.biweight_h264_pixels_tab, 1);
- } else
- hl_motion_8(h, dest[0], dest[1], dest[2],
- s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
- s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
- h->h264dsp.weight_h264_pixels_tab,
- h->h264dsp.biweight_h264_pixels_tab, 1);
+ hl_motion(h, dest[0], dest[1], dest[2],
+ s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
+ s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+ h->h264dsp.weight_h264_pixels_tab,
+ h->h264dsp.biweight_h264_pixels_tab, pixel_shift, 3);
}
for (p = 0; p < plane_count; p++)
@@ -2082,8 +2206,8 @@ static av_always_inline void hl_decode_mb_444_internal(H264Context *h, int simpl
static void hl_decode_mb_simple_ ## bits(H264Context *h){ \
hl_decode_mb_internal(h, 1, sh); \
}
-hl_decode_mb_simple(0, 8);
-hl_decode_mb_simple(1, 16);
+hl_decode_mb_simple(0, 8)
+hl_decode_mb_simple(1, 16)
/**
* Process a macroblock; this handles edge cases, such as interlacing.
@@ -2103,7 +2227,7 @@ static void av_noinline hl_decode_mb_444_simple(H264Context *h){
void ff_h264_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];
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
int is_complex = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || s->qscale == 0;
if (CHROMA444) {
@@ -2195,7 +2319,11 @@ static void implicit_weight_table(H264Context *h, int field){
}
if(field < 0){
- cur_poc = s->current_picture_ptr->poc;
+ if (s->picture_structure == PICT_FRAME) {
+ cur_poc = s->current_picture_ptr->poc;
+ } else {
+ cur_poc = s->current_picture_ptr->field_poc[s->picture_structure - 1];
+ }
if( h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF
&& h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2*cur_poc){
h->use_weight= 0;
@@ -2259,14 +2387,16 @@ static void flush_dpb(AVCodecContext *avctx){
int 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]->f.reference = 0;
h->delayed_pic[i]= NULL;
}
+ for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
+ h->last_pocs[i] = INT_MIN;
h->outputed_poc=h->next_outputed_poc= INT_MIN;
h->prev_interlaced_frame = 1;
idr(h);
if(h->s.current_picture_ptr)
- h->s.current_picture_ptr->reference= 0;
+ h->s.current_picture_ptr->f.reference = 0;
h->s.first_field= 0;
ff_h264_reset_sei(h);
ff_mpeg_flush(avctx);
@@ -2386,9 +2516,10 @@ static void init_scan_tables(H264Context *h){
}
}
-static void field_end(H264Context *h, int in_setup){
+static int field_end(H264Context *h, int in_setup){
MpegEncContext * const s = &h->s;
AVCodecContext * const avctx= s->avctx;
+ int err = 0;
s->mb_y= 0;
if (!in_setup && !s->dropable)
@@ -2400,7 +2531,7 @@ static void field_end(H264Context *h, int in_setup){
if(in_setup || !(avctx->active_thread_type&FF_THREAD_FRAME)){
if(!s->dropable) {
- ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
+ err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
h->prev_poc_msb= h->poc_msb;
h->prev_poc_lsb= h->poc_lsb;
}
@@ -2435,6 +2566,8 @@ static void field_end(H264Context *h, int in_setup){
MPV_frame_end(s);
h->current_slice=0;
+
+ return err;
}
/**
@@ -2465,7 +2598,7 @@ static void clone_slice(H264Context *dst, H264Context *src)
}
/**
- * computes profile from profile_idc and constraint_set?_flags
+ * Compute profile from profile_idc and constraint_set?_flags.
*
* @param sps SPS
*
@@ -2492,7 +2625,7 @@ int ff_h264_get_profile(SPS *sps)
}
/**
- * decodes a slice header.
+ * Decode a slice header.
* This will also call MPV_common_init() and frame_start() as needed.
*
* @param h h264context
@@ -2585,11 +2718,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
h->b_stride= s->mb_width*4;
+ s->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
+
s->width = 16*s->mb_width - (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
if(h->sps.frame_mbs_only_flag)
- s->height= 16*s->mb_height - (2>>CHROMA444)*FFMIN(h->sps.crop_bottom, (8<<CHROMA444)-1);
+ s->height= 16*s->mb_height - (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1);
else
- s->height= 16*s->mb_height - (4>>CHROMA444)*FFMIN(h->sps.crop_bottom, (8<<CHROMA444)-1);
+ s->height= 16*s->mb_height - (2<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1);
if (s->context_initialized
&& ( s->width != s->avctx->width || s->height != s->avctx->height
@@ -2612,9 +2747,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
s->avctx->sample_aspect_ratio= h->sps.sar;
av_assert0(s->avctx->sample_aspect_ratio.den);
- h->s.avctx->coded_width = 16*s->mb_width;
- h->s.avctx->coded_height = 16*s->mb_height;
-
if(h->sps.video_signal_type_present_flag){
s->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
if(h->sps.colour_description_present_flag){
@@ -2634,14 +2766,35 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
switch (h->sps.bit_depth_luma) {
case 9 :
- s->avctx->pix_fmt = CHROMA444 ? PIX_FMT_YUV444P9 : PIX_FMT_YUV420P9;
+ if (CHROMA444) {
+ if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+ s->avctx->pix_fmt = PIX_FMT_GBRP9;
+ } else
+ s->avctx->pix_fmt = PIX_FMT_YUV444P9;
+ } else if (CHROMA422)
+ s->avctx->pix_fmt = PIX_FMT_YUV422P9;
+ else
+ s->avctx->pix_fmt = PIX_FMT_YUV420P9;
break;
case 10 :
- s->avctx->pix_fmt = CHROMA444 ? PIX_FMT_YUV444P10 : PIX_FMT_YUV420P10;
+ if (CHROMA444) {
+ if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+ s->avctx->pix_fmt = PIX_FMT_GBRP10;
+ } else
+ s->avctx->pix_fmt = PIX_FMT_YUV444P10;
+ } else if (CHROMA422)
+ s->avctx->pix_fmt = PIX_FMT_YUV422P10;
+ else
+ s->avctx->pix_fmt = PIX_FMT_YUV420P10;
break;
default:
if (CHROMA444){
- s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? PIX_FMT_YUVJ444P : PIX_FMT_YUV444P;
+ if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+ s->avctx->pix_fmt = PIX_FMT_GBRP;
+ } else
+ s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? PIX_FMT_YUVJ444P : PIX_FMT_YUV444P;
+ } else if (CHROMA422) {
+ s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? PIX_FMT_YUVJ422P : PIX_FMT_YUV422P;
}else{
s->avctx->pix_fmt = s->avctx->get_format(s->avctx,
s->avctx->codec->pix_fmts ?
@@ -2739,17 +2892,19 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 0);
ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 1);
ff_generate_sliding_window_mmcos(h);
- ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
+ if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 &&
+ (s->avctx->err_recognition & AV_EF_EXPLODE))
+ return AVERROR_INVALIDDATA;
/* Error concealment: if a ref is missing, copy the previous ref in its place.
* FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions
* about there being no actual duplicates.
* FIXME: this doesn't copy padding for out-of-frame motion vectors. Given we're
- * concealing a lost frame, this probably isn't noticable by comparison, but it should
+ * concealing a lost frame, this probably isn't noticeable by comparison, but it should
* be fixed. */
if (h->short_ref_count) {
if (prev) {
- av_image_copy(h->short_ref[0]->data, h->short_ref[0]->linesize,
- (const uint8_t**)prev->data, prev->linesize,
+ av_image_copy(h->short_ref[0]->f.data, h->short_ref[0]->f.linesize,
+ (const uint8_t**)prev->f.data, prev->f.linesize,
s->avctx->pix_fmt, s->mb_width*16, s->mb_height*16);
h->short_ref[0]->poc = prev->poc+2;
}
@@ -2760,8 +2915,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
/* See if we have a decoded first field looking for a pair... */
if (s0->first_field) {
assert(s0->current_picture_ptr);
- assert(s0->current_picture_ptr->data[0]);
- assert(s0->current_picture_ptr->reference != DELAYED_PIC_REF);
+ assert(s0->current_picture_ptr->f.data[0]);
+ assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
/* figure out if we have a complementary field pair */
if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
@@ -2774,7 +2929,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
} else {
if (h->nal_ref_idc &&
- s0->current_picture_ptr->reference &&
+ s0->current_picture_ptr->f.reference &&
s0->current_picture_ptr->frame_num != h->frame_num) {
/*
* This and previous field were reference, but had
@@ -2888,8 +3043,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
ff_h264_fill_default_ref_list(h);
}
- if(h->slice_type_nos!=AV_PICTURE_TYPE_I && ff_h264_decode_ref_pic_list_reordering(h) < 0)
+ if(h->slice_type_nos!=AV_PICTURE_TYPE_I && ff_h264_decode_ref_pic_list_reordering(h) < 0) {
+ h->ref_count[1]= h->ref_count[0]= 0;
return -1;
+ }
if(h->slice_type_nos!=AV_PICTURE_TYPE_I){
s->last_picture_ptr= &h->ref_list[0][0];
@@ -2913,8 +3070,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
}
}
- if(h->nal_ref_idc)
- ff_h264_decode_ref_pic_marking(h0, &s->gb);
+ if(h->nal_ref_idc && ff_h264_decode_ref_pic_marking(h0, &s->gb) < 0 &&
+ (s->avctx->err_recognition & AV_EF_EXPLODE))
+ return AVERROR_INVALIDDATA;
if(FRAME_MBAFF){
ff_h264_fill_mbaff_ref_list(h);
@@ -3002,7 +3160,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
}
}
}
- h->qp_thresh= 15 + 52 - FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) - FFMAX3(0, h->pps.chroma_qp_index_offset[0], h->pps.chroma_qp_index_offset[1]);
+ h->qp_thresh = 15 + 52 - FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset)
+ - FFMAX3(0, h->pps.chroma_qp_index_offset[0], h->pps.chroma_qp_index_offset[1])
+ + 6 * (h->sps.bit_depth_luma - 8);
#if 0 //FMO
if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5)
@@ -3020,16 +3180,16 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
int *ref2frm= h->ref2frm[h->slice_num&(MAX_SLICES-1)][j];
for(i=0; i<16; i++){
id_list[i]= 60;
- if(h->ref_list[j][i].data[0]){
+ if (h->ref_list[j][i].f.data[0]) {
int k;
- uint8_t *base= h->ref_list[j][i].base[0];
+ uint8_t *base = h->ref_list[j][i].f.base[0];
for(k=0; k<h->short_ref_count; k++)
- if(h->short_ref[k]->base[0] == base){
+ if (h->short_ref[k]->f.base[0] == base) {
id_list[i]= k;
break;
}
for(k=0; k<h->long_ref_count; k++)
- if(h->long_ref[k] && h->long_ref[k]->base[0] == base){
+ if (h->long_ref[k] && h->long_ref[k]->f.base[0] == base) {
id_list[i]= h->short_ref_count + k;
break;
}
@@ -3040,12 +3200,12 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
ref2frm[1]= -1;
for(i=0; i<16; i++)
ref2frm[i+2]= 4*id_list[i]
- +(h->ref_list[j][i].reference&3);
+ + (h->ref_list[j][i].f.reference & 3);
ref2frm[18+0]=
ref2frm[18+1]= -1;
for(i=16; i<48; i++)
ref2frm[i+4]= 4*id_list[(i-16)>>1]
- +(h->ref_list[j][i].reference&3);
+ + (h->ref_list[j][i].f.reference & 3);
}
//FIXME: fix draw_edges+PAFF+frame threads
@@ -3084,215 +3244,207 @@ int ff_h264_get_slice_type(const H264Context *h)
}
}
+static av_always_inline void fill_filter_caches_inter(H264Context *h, MpegEncContext * const s, int mb_type, int top_xy,
+ int left_xy[LEFT_MBS], int top_type, int left_type[LEFT_MBS], int mb_xy, int list)
+{
+ int b_stride = h->b_stride;
+ int16_t (*mv_dst)[2] = &h->mv_cache[list][scan8[0]];
+ int8_t *ref_cache = &h->ref_cache[list][scan8[0]];
+ if(IS_INTER(mb_type) || IS_DIRECT(mb_type)){
+ if(USES_LIST(top_type, list)){
+ const int b_xy= h->mb2b_xy[top_xy] + 3*b_stride;
+ const int b8_xy= 4*top_xy + 2;
+ int (*ref2frm)[64] = h->ref2frm[ h->slice_table[top_xy]&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
+ AV_COPY128(mv_dst - 1*8, s->current_picture.f.motion_val[list][b_xy + 0]);
+ ref_cache[0 - 1*8]=
+ ref_cache[1 - 1*8]= ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 0]];
+ ref_cache[2 - 1*8]=
+ ref_cache[3 - 1*8]= ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 1]];
+ }else{
+ AV_ZERO128(mv_dst - 1*8);
+ AV_WN32A(&ref_cache[0 - 1*8], ((LIST_NOT_USED)&0xFF)*0x01010101u);
+ }
+
+ if(!IS_INTERLACED(mb_type^left_type[LTOP])){
+ if(USES_LIST(left_type[LTOP], list)){
+ const int b_xy= h->mb2b_xy[left_xy[LTOP]] + 3;
+ const int b8_xy= 4*left_xy[LTOP] + 1;
+ int (*ref2frm)[64] = h->ref2frm[ h->slice_table[left_xy[LTOP]]&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
+ AV_COPY32(mv_dst - 1 + 0, s->current_picture.f.motion_val[list][b_xy + b_stride*0]);
+ AV_COPY32(mv_dst - 1 + 8, s->current_picture.f.motion_val[list][b_xy + b_stride*1]);
+ AV_COPY32(mv_dst - 1 + 16, s->current_picture.f.motion_val[list][b_xy + b_stride*2]);
+ AV_COPY32(mv_dst - 1 + 24, s->current_picture.f.motion_val[list][b_xy + b_stride*3]);
+ ref_cache[-1 + 0]=
+ ref_cache[-1 + 8]= ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 2*0]];
+ ref_cache[-1 + 16]=
+ ref_cache[-1 + 24]= ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 2*1]];
+ }else{
+ AV_ZERO32(mv_dst - 1 + 0);
+ AV_ZERO32(mv_dst - 1 + 8);
+ AV_ZERO32(mv_dst - 1 +16);
+ AV_ZERO32(mv_dst - 1 +24);
+ ref_cache[-1 + 0]=
+ ref_cache[-1 + 8]=
+ ref_cache[-1 + 16]=
+ ref_cache[-1 + 24]= LIST_NOT_USED;
+ }
+ }
+ }
+
+ if(!USES_LIST(mb_type, list)){
+ fill_rectangle(mv_dst, 4, 4, 8, pack16to32(0,0), 4);
+ AV_WN32A(&ref_cache[0*8], ((LIST_NOT_USED)&0xFF)*0x01010101u);
+ AV_WN32A(&ref_cache[1*8], ((LIST_NOT_USED)&0xFF)*0x01010101u);
+ AV_WN32A(&ref_cache[2*8], ((LIST_NOT_USED)&0xFF)*0x01010101u);
+ AV_WN32A(&ref_cache[3*8], ((LIST_NOT_USED)&0xFF)*0x01010101u);
+ return;
+ }
+
+ {
+ int8_t *ref = &s->current_picture.f.ref_index[list][4*mb_xy];
+ int (*ref2frm)[64] = h->ref2frm[ h->slice_num&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
+ uint32_t ref01 = (pack16to32(ref2frm[list][ref[0]],ref2frm[list][ref[1]])&0x00FF00FF)*0x0101;
+ uint32_t ref23 = (pack16to32(ref2frm[list][ref[2]],ref2frm[list][ref[3]])&0x00FF00FF)*0x0101;
+ AV_WN32A(&ref_cache[0*8], ref01);
+ AV_WN32A(&ref_cache[1*8], ref01);
+ AV_WN32A(&ref_cache[2*8], ref23);
+ AV_WN32A(&ref_cache[3*8], ref23);
+ }
+
+ {
+ int16_t (*mv_src)[2] = &s->current_picture.f.motion_val[list][4*s->mb_x + 4*s->mb_y*b_stride];
+ AV_COPY128(mv_dst + 8*0, mv_src + 0*b_stride);
+ AV_COPY128(mv_dst + 8*1, mv_src + 1*b_stride);
+ AV_COPY128(mv_dst + 8*2, mv_src + 2*b_stride);
+ AV_COPY128(mv_dst + 8*3, mv_src + 3*b_stride);
+ }
+}
+
/**
*
- * @return non zero if the loop filter can be skiped
+ * @return non zero if the loop filter can be skipped
*/
static int fill_filter_caches(H264Context *h, int mb_type){
MpegEncContext * const s = &h->s;
const int mb_xy= h->mb_xy;
- int top_xy, left_xy[2];
- int top_type, left_type[2];
+ int top_xy, left_xy[LEFT_MBS];
+ int top_type, left_type[LEFT_MBS];
+ uint8_t *nnz;
+ uint8_t *nnz_cache;
top_xy = mb_xy - (s->mb_stride << MB_FIELD);
- //FIXME deblocking could skip the intra and nnz parts.
-
/* Wow, what a mess, why didn't they simplify the interlacing & intra
* stuff, I can't imagine that these complex rules are worth it. */
- left_xy[1] = left_xy[0] = mb_xy-1;
+ left_xy[LBOT] = left_xy[LTOP] = mb_xy-1;
if(FRAME_MBAFF){
- const int left_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[mb_xy-1]);
+ const int left_mb_field_flag = IS_INTERLACED(s->current_picture.f.mb_type[mb_xy - 1]);
const int curr_mb_field_flag = IS_INTERLACED(mb_type);
if(s->mb_y&1){
if (left_mb_field_flag != curr_mb_field_flag) {
- left_xy[0] -= s->mb_stride;
+ left_xy[LTOP] -= s->mb_stride;
}
}else{
if(curr_mb_field_flag){
- top_xy += s->mb_stride & (((s->current_picture.mb_type[top_xy ]>>7)&1)-1);
+ top_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy] >> 7) & 1) - 1);
}
if (left_mb_field_flag != curr_mb_field_flag) {
- left_xy[1] += s->mb_stride;
+ left_xy[LBOT] += s->mb_stride;
}
}
}
h->top_mb_xy = top_xy;
- h->left_mb_xy[0] = left_xy[0];
- h->left_mb_xy[1] = left_xy[1];
+ h->left_mb_xy[LTOP] = left_xy[LTOP];
+ h->left_mb_xy[LBOT] = left_xy[LBOT];
{
//for sufficiently low qp, filtering wouldn't do anything
//this is a conservative estimate: could also check beta_offset and more accurate chroma_qp
int qp_thresh = h->qp_thresh; //FIXME strictly we should store qp_thresh for each mb of a slice
- int qp = s->current_picture.qscale_table[mb_xy];
+ int qp = s->current_picture.f.qscale_table[mb_xy];
if(qp <= qp_thresh
- && (left_xy[0]<0 || ((qp + s->current_picture.qscale_table[left_xy[0]] + 1)>>1) <= qp_thresh)
- && (top_xy < 0 || ((qp + s->current_picture.qscale_table[top_xy ] + 1)>>1) <= qp_thresh)){
+ && (left_xy[LTOP] < 0 || ((qp + s->current_picture.f.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh)
+ && (top_xy < 0 || ((qp + s->current_picture.f.qscale_table[top_xy ] + 1) >> 1) <= qp_thresh)) {
if(!FRAME_MBAFF)
return 1;
- if( (left_xy[0]< 0 || ((qp + s->current_picture.qscale_table[left_xy[1] ] + 1)>>1) <= qp_thresh)
- && (top_xy < s->mb_stride || ((qp + s->current_picture.qscale_table[top_xy -s->mb_stride] + 1)>>1) <= qp_thresh))
+ if ((left_xy[LTOP] < 0 || ((qp + s->current_picture.f.qscale_table[left_xy[LBOT] ] + 1) >> 1) <= qp_thresh) &&
+ (top_xy < s->mb_stride || ((qp + s->current_picture.f.qscale_table[top_xy - s->mb_stride] + 1) >> 1) <= qp_thresh))
return 1;
}
}
- top_type = s->current_picture.mb_type[top_xy] ;
- left_type[0] = s->current_picture.mb_type[left_xy[0]];
- left_type[1] = s->current_picture.mb_type[left_xy[1]];
+ top_type = s->current_picture.f.mb_type[top_xy];
+ left_type[LTOP] = s->current_picture.f.mb_type[left_xy[LTOP]];
+ left_type[LBOT] = s->current_picture.f.mb_type[left_xy[LBOT]];
if(h->deblocking_filter == 2){
- if(h->slice_table[top_xy ] != h->slice_num) top_type= 0;
- if(h->slice_table[left_xy[0] ] != h->slice_num) left_type[0]= left_type[1]= 0;
+ if(h->slice_table[top_xy ] != h->slice_num) top_type= 0;
+ if(h->slice_table[left_xy[LBOT]] != h->slice_num) left_type[LTOP]= left_type[LBOT]= 0;
}else{
- if(h->slice_table[top_xy ] == 0xFFFF) top_type= 0;
- if(h->slice_table[left_xy[0] ] == 0xFFFF) left_type[0]= left_type[1] =0;
+ if(h->slice_table[top_xy ] == 0xFFFF) top_type= 0;
+ if(h->slice_table[left_xy[LBOT]] == 0xFFFF) left_type[LTOP]= left_type[LBOT] =0;
}
- h->top_type = top_type ;
- h->left_type[0]= left_type[0];
- h->left_type[1]= left_type[1];
+ h->top_type = top_type;
+ h->left_type[LTOP]= left_type[LTOP];
+ h->left_type[LBOT]= left_type[LBOT];
if(IS_INTRA(mb_type))
return 0;
- AV_COPY32(&h->non_zero_count_cache[4+8* 1], &h->non_zero_count[mb_xy][ 0]);
- AV_COPY32(&h->non_zero_count_cache[4+8* 2], &h->non_zero_count[mb_xy][ 4]);
- AV_COPY32(&h->non_zero_count_cache[4+8* 3], &h->non_zero_count[mb_xy][ 8]);
- AV_COPY32(&h->non_zero_count_cache[4+8* 4], &h->non_zero_count[mb_xy][12]);
+ fill_filter_caches_inter(h, s, mb_type, top_xy, left_xy, top_type, left_type, mb_xy, 0);
+ if(h->list_count == 2)
+ fill_filter_caches_inter(h, s, mb_type, top_xy, left_xy, top_type, left_type, mb_xy, 1);
+ nnz = h->non_zero_count[mb_xy];
+ nnz_cache = h->non_zero_count_cache;
+ AV_COPY32(&nnz_cache[4+8*1], &nnz[ 0]);
+ AV_COPY32(&nnz_cache[4+8*2], &nnz[ 4]);
+ AV_COPY32(&nnz_cache[4+8*3], &nnz[ 8]);
+ AV_COPY32(&nnz_cache[4+8*4], &nnz[12]);
h->cbp= h->cbp_table[mb_xy];
- {
- int list;
- for(list=0; list<h->list_count; list++){
- int8_t *ref;
- int y, b_stride;
- int16_t (*mv_dst)[2];
- int16_t (*mv_src)[2];
-
- if(!USES_LIST(mb_type, list)){
- fill_rectangle( h->mv_cache[list][scan8[0]], 4, 4, 8, pack16to32(0,0), 4);
- AV_WN32A(&h->ref_cache[list][scan8[ 0]], ((LIST_NOT_USED)&0xFF)*0x01010101u);
- AV_WN32A(&h->ref_cache[list][scan8[ 2]], ((LIST_NOT_USED)&0xFF)*0x01010101u);
- AV_WN32A(&h->ref_cache[list][scan8[ 8]], ((LIST_NOT_USED)&0xFF)*0x01010101u);
- AV_WN32A(&h->ref_cache[list][scan8[10]], ((LIST_NOT_USED)&0xFF)*0x01010101u);
- continue;
- }
-
- ref = &s->current_picture.ref_index[list][4*mb_xy];
- {
- int (*ref2frm)[64] = h->ref2frm[ h->slice_num&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
- AV_WN32A(&h->ref_cache[list][scan8[ 0]], (pack16to32(ref2frm[list][ref[0]],ref2frm[list][ref[1]])&0x00FF00FF)*0x0101);
- AV_WN32A(&h->ref_cache[list][scan8[ 2]], (pack16to32(ref2frm[list][ref[0]],ref2frm[list][ref[1]])&0x00FF00FF)*0x0101);
- ref += 2;
- AV_WN32A(&h->ref_cache[list][scan8[ 8]], (pack16to32(ref2frm[list][ref[0]],ref2frm[list][ref[1]])&0x00FF00FF)*0x0101);
- AV_WN32A(&h->ref_cache[list][scan8[10]], (pack16to32(ref2frm[list][ref[0]],ref2frm[list][ref[1]])&0x00FF00FF)*0x0101);
- }
-
- b_stride = h->b_stride;
- mv_dst = &h->mv_cache[list][scan8[0]];
- mv_src = &s->current_picture.motion_val[list][4*s->mb_x + 4*s->mb_y*b_stride];
- for(y=0; y<4; y++){
- AV_COPY128(mv_dst + 8*y, mv_src + y*b_stride);
- }
-
- }
- }
-
-
-/*
-0 . T T. T T T T
-1 L . .L . . . .
-2 L . .L . . . .
-3 . T TL . . . .
-4 L . .L . . . .
-5 L . .. . . . .
-*/
-//FIXME constraint_intra_pred & partitioning & nnz (let us hope this is just a typo in the spec)
if(top_type){
- AV_COPY32(&h->non_zero_count_cache[4+8*0], &h->non_zero_count[top_xy][3*4]);
+ nnz = h->non_zero_count[top_xy];
+ AV_COPY32(&nnz_cache[4+8*0], &nnz[3*4]);
}
- if(left_type[0]){
- h->non_zero_count_cache[3+8*1]= h->non_zero_count[left_xy[0]][3+0*4];
- h->non_zero_count_cache[3+8*2]= h->non_zero_count[left_xy[0]][3+1*4];
- h->non_zero_count_cache[3+8*3]= h->non_zero_count[left_xy[0]][3+2*4];
- h->non_zero_count_cache[3+8*4]= h->non_zero_count[left_xy[0]][3+3*4];
+ if(left_type[LTOP]){
+ nnz = h->non_zero_count[left_xy[LTOP]];
+ nnz_cache[3+8*1]= nnz[3+0*4];
+ nnz_cache[3+8*2]= nnz[3+1*4];
+ nnz_cache[3+8*3]= nnz[3+2*4];
+ nnz_cache[3+8*4]= nnz[3+3*4];
}
// CAVLC 8x8dct requires NNZ values for residual decoding that differ from what the loop filter needs
if(!CABAC && h->pps.transform_8x8_mode){
if(IS_8x8DCT(top_type)){
- h->non_zero_count_cache[4+8*0]=
- h->non_zero_count_cache[5+8*0]= (h->cbp_table[top_xy] & 0x4000) >> 12;
- h->non_zero_count_cache[6+8*0]=
- h->non_zero_count_cache[7+8*0]= (h->cbp_table[top_xy] & 0x8000) >> 12;
+ nnz_cache[4+8*0]=
+ nnz_cache[5+8*0]= (h->cbp_table[top_xy] & 0x4000) >> 12;
+ nnz_cache[6+8*0]=
+ nnz_cache[7+8*0]= (h->cbp_table[top_xy] & 0x8000) >> 12;
}
- if(IS_8x8DCT(left_type[0])){
- h->non_zero_count_cache[3+8*1]=
- h->non_zero_count_cache[3+8*2]= (h->cbp_table[left_xy[0]]&0x2000) >> 12; //FIXME check MBAFF
+ if(IS_8x8DCT(left_type[LTOP])){
+ nnz_cache[3+8*1]=
+ nnz_cache[3+8*2]= (h->cbp_table[left_xy[LTOP]]&0x2000) >> 12; //FIXME check MBAFF
}
- if(IS_8x8DCT(left_type[1])){
- h->non_zero_count_cache[3+8*3]=
- h->non_zero_count_cache[3+8*4]= (h->cbp_table[left_xy[1]]&0x8000) >> 12; //FIXME check MBAFF
+ if(IS_8x8DCT(left_type[LBOT])){
+ nnz_cache[3+8*3]=
+ nnz_cache[3+8*4]= (h->cbp_table[left_xy[LBOT]]&0x8000) >> 12; //FIXME check MBAFF
}
if(IS_8x8DCT(mb_type)){
- h->non_zero_count_cache[scan8[0 ]]= h->non_zero_count_cache[scan8[1 ]]=
- h->non_zero_count_cache[scan8[2 ]]= h->non_zero_count_cache[scan8[3 ]]= (h->cbp & 0x1000) >> 12;
+ nnz_cache[scan8[0 ]]= nnz_cache[scan8[1 ]]=
+ nnz_cache[scan8[2 ]]= nnz_cache[scan8[3 ]]= (h->cbp & 0x1000) >> 12;
- h->non_zero_count_cache[scan8[0+ 4]]= h->non_zero_count_cache[scan8[1+ 4]]=
- h->non_zero_count_cache[scan8[2+ 4]]= h->non_zero_count_cache[scan8[3+ 4]]= (h->cbp & 0x2000) >> 12;
-
- h->non_zero_count_cache[scan8[0+ 8]]= h->non_zero_count_cache[scan8[1+ 8]]=
- h->non_zero_count_cache[scan8[2+ 8]]= h->non_zero_count_cache[scan8[3+ 8]]= (h->cbp & 0x4000) >> 12;
-
- h->non_zero_count_cache[scan8[0+12]]= h->non_zero_count_cache[scan8[1+12]]=
- h->non_zero_count_cache[scan8[2+12]]= h->non_zero_count_cache[scan8[3+12]]= (h->cbp & 0x8000) >> 12;
- }
- }
+ nnz_cache[scan8[0+ 4]]= nnz_cache[scan8[1+ 4]]=
+ nnz_cache[scan8[2+ 4]]= nnz_cache[scan8[3+ 4]]= (h->cbp & 0x2000) >> 12;
- if(IS_INTER(mb_type) || IS_DIRECT(mb_type)){
- int list;
- for(list=0; list<h->list_count; list++){
- if(USES_LIST(top_type, list)){
- const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride;
- const int b8_xy= 4*top_xy + 2;
- int (*ref2frm)[64] = h->ref2frm[ h->slice_table[top_xy]&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
- AV_COPY128(h->mv_cache[list][scan8[0] + 0 - 1*8], s->current_picture.motion_val[list][b_xy + 0]);
- h->ref_cache[list][scan8[0] + 0 - 1*8]=
- h->ref_cache[list][scan8[0] + 1 - 1*8]= ref2frm[list][s->current_picture.ref_index[list][b8_xy + 0]];
- h->ref_cache[list][scan8[0] + 2 - 1*8]=
- h->ref_cache[list][scan8[0] + 3 - 1*8]= ref2frm[list][s->current_picture.ref_index[list][b8_xy + 1]];
- }else{
- AV_ZERO128(h->mv_cache[list][scan8[0] + 0 - 1*8]);
- AV_WN32A(&h->ref_cache[list][scan8[0] + 0 - 1*8], ((LIST_NOT_USED)&0xFF)*0x01010101u);
- }
+ nnz_cache[scan8[0+ 8]]= nnz_cache[scan8[1+ 8]]=
+ nnz_cache[scan8[2+ 8]]= nnz_cache[scan8[3+ 8]]= (h->cbp & 0x4000) >> 12;
- if(!IS_INTERLACED(mb_type^left_type[0])){
- if(USES_LIST(left_type[0], list)){
- const int b_xy= h->mb2b_xy[left_xy[0]] + 3;
- const int b8_xy= 4*left_xy[0] + 1;
- int (*ref2frm)[64] = h->ref2frm[ h->slice_table[left_xy[0]]&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
- AV_COPY32(h->mv_cache[list][scan8[0] - 1 + 0 ], s->current_picture.motion_val[list][b_xy + h->b_stride*0]);
- AV_COPY32(h->mv_cache[list][scan8[0] - 1 + 8 ], s->current_picture.motion_val[list][b_xy + h->b_stride*1]);
- AV_COPY32(h->mv_cache[list][scan8[0] - 1 +16 ], s->current_picture.motion_val[list][b_xy + h->b_stride*2]);
- AV_COPY32(h->mv_cache[list][scan8[0] - 1 +24 ], s->current_picture.motion_val[list][b_xy + h->b_stride*3]);
- h->ref_cache[list][scan8[0] - 1 + 0 ]=
- h->ref_cache[list][scan8[0] - 1 + 8 ]= ref2frm[list][s->current_picture.ref_index[list][b8_xy + 2*0]];
- h->ref_cache[list][scan8[0] - 1 +16 ]=
- h->ref_cache[list][scan8[0] - 1 +24 ]= ref2frm[list][s->current_picture.ref_index[list][b8_xy + 2*1]];
- }else{
- AV_ZERO32(h->mv_cache [list][scan8[0] - 1 + 0 ]);
- AV_ZERO32(h->mv_cache [list][scan8[0] - 1 + 8 ]);
- AV_ZERO32(h->mv_cache [list][scan8[0] - 1 +16 ]);
- AV_ZERO32(h->mv_cache [list][scan8[0] - 1 +24 ]);
- h->ref_cache[list][scan8[0] - 1 + 0 ]=
- h->ref_cache[list][scan8[0] - 1 + 8 ]=
- h->ref_cache[list][scan8[0] - 1 + 16 ]=
- h->ref_cache[list][scan8[0] - 1 + 24 ]= LIST_NOT_USED;
- }
- }
+ nnz_cache[scan8[0+12]]= nnz_cache[scan8[1+12]]=
+ nnz_cache[scan8[2+12]]= nnz_cache[scan8[3+12]]= (h->cbp & 0x8000) >> 12;
}
}
@@ -3306,6 +3458,7 @@ static void loop_filter(H264Context *h, int start_x, int end_x){
const int end_mb_y= s->mb_y + FRAME_MBAFF;
const int old_slice_type= h->slice_type;
const int pixel_shift = h->pixel_shift;
+ const int block_h = 16 >> s->chroma_y_shift;
if(h->deblocking_filter) {
for(mb_x= start_x; mb_x<end_x; mb_x++){
@@ -3313,7 +3466,7 @@ static void loop_filter(H264Context *h, int start_x, int end_x){
int mb_xy, mb_type;
mb_xy = h->mb_xy = mb_x + mb_y*s->mb_stride;
h->slice_num= h->slice_table[mb_xy];
- mb_type= s->current_picture.mb_type[mb_xy];
+ mb_type = s->current_picture.f.mb_type[mb_xy];
h->list_count= h->list_counts[mb_xy];
if(FRAME_MBAFF)
@@ -3321,9 +3474,9 @@ static void loop_filter(H264Context *h, int start_x, int end_x){
s->mb_x= mb_x;
s->mb_y= mb_y;
- dest_y = s->current_picture.data[0] + ((mb_x << pixel_shift) + mb_y * s->linesize ) * 16;
- dest_cb = s->current_picture.data[1] + ((mb_x << pixel_shift) + mb_y * s->uvlinesize) * (8 << CHROMA444);
- dest_cr = s->current_picture.data[2] + ((mb_x << pixel_shift) + mb_y * s->uvlinesize) * (8 << CHROMA444);
+ dest_y = s->current_picture.f.data[0] + ((mb_x << pixel_shift) + mb_y * s->linesize ) * 16;
+ dest_cb = s->current_picture.f.data[1] + (mb_x << pixel_shift) * (8 << CHROMA444) + mb_y * s->uvlinesize * block_h;
+ dest_cr = s->current_picture.f.data[2] + (mb_x << pixel_shift) * (8 << CHROMA444) + mb_y * s->uvlinesize * block_h;
//FIXME simplify above
if (MB_FIELD) {
@@ -3331,18 +3484,18 @@ static void loop_filter(H264Context *h, int start_x, int end_x){
uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2;
if(mb_y&1){ //FIXME move out of this function?
dest_y -= s->linesize*15;
- dest_cb-= s->uvlinesize*((8 << CHROMA444)-1);
- dest_cr-= s->uvlinesize*((8 << CHROMA444)-1);
+ dest_cb-= s->uvlinesize * (block_h - 1);
+ dest_cr-= s->uvlinesize * (block_h - 1);
}
} else {
linesize = h->mb_linesize = s->linesize;
uvlinesize = h->mb_uvlinesize = s->uvlinesize;
}
- backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, CHROMA444, 0);
+ backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0);
if(fill_filter_caches(h, mb_type))
continue;
- h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]);
- h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]);
+ h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mb_xy]);
+ h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mb_xy]);
if (FRAME_MBAFF) {
ff_h264_filter_mb (h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);
@@ -3363,9 +3516,9 @@ static void predict_field_decoding_flag(H264Context *h){
MpegEncContext * const s = &h->s;
const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;
int mb_type = (h->slice_table[mb_xy-1] == h->slice_num)
- ? s->current_picture.mb_type[mb_xy-1]
+ ? s->current_picture.f.mb_type[mb_xy - 1]
: (h->slice_table[mb_xy-s->mb_stride] == h->slice_num)
- ? s->current_picture.mb_type[mb_xy-s->mb_stride]
+ ? s->current_picture.f.mb_type[mb_xy - s->mb_stride]
: 0;
h->mb_mbaff = h->mb_field_decoding_flag = IS_INTERLACED(mb_type) ? 1 : 0;
}
@@ -3407,7 +3560,7 @@ static void decode_finish_row(H264Context *h){
static int decode_slice(struct AVCodecContext *avctx, void *arg){
H264Context *h = *(void**)arg;
MpegEncContext * const s = &h->s;
- const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F;
+ const int part_mask= s->partitioned_frame ? (ER_AC_END|ER_AC_ERROR) : 0x7F;
int lf_x_start = s->mb_x;
s->mb_skip_run= -1;
@@ -3446,13 +3599,13 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){
eos = get_cabac_terminate( &h->cabac );
if((s->workaround_bugs & FF_BUG_TRUNCATED) && h->cabac.bytestream > h->cabac.bytestream_end + 2){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask);
if (s->mb_x >= lf_x_start) loop_filter(h, lf_x_start, s->mb_x + 1);
return 0;
}
if( ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%td)\n", s->mb_x, s->mb_y, h->cabac.bytestream_end - h->cabac.bytestream);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
return -1;
}
@@ -3470,7 +3623,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){
if( eos || s->mb_y >= s->mb_height ) {
tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask);
if (s->mb_x > lf_x_start) loop_filter(h, lf_x_start, s->mb_x);
return 0;
}
@@ -3492,7 +3645,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){
if(ret<0){
av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
return -1;
}
@@ -3510,11 +3663,11 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){
tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
if(get_bits_count(&s->gb) == s->gb.size_in_bits ) {
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask);
return 0;
}else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
return -1;
}
@@ -3524,65 +3677,18 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){
if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->mb_skip_run<=0){
tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
if(get_bits_count(&s->gb) == s->gb.size_in_bits ){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask);
if (s->mb_x > lf_x_start) loop_filter(h, lf_x_start, s->mb_x);
return 0;
}else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
-
- return -1;
- }
- }
- }
- }
-
-#if 0
- for(;s->mb_y < s->mb_height; s->mb_y++){
- for(;s->mb_x < s->mb_width; s->mb_x++){
- int ret= decode_mb(h);
-
- ff_h264_hl_decode_mb(h);
-
- if(ret<0){
- av_log(s->avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
-
- return -1;
- }
-
- if(++s->mb_x >= s->mb_width){
- s->mb_x=0;
- if(++s->mb_y >= s->mb_height){
- if(get_bits_count(s->gb) == s->gb.size_in_bits){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
-
- return 0;
- }else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
-
- return -1;
- }
- }
- }
-
- if(get_bits_count(s->?gb) >= s->gb?.size_in_bits){
- if(get_bits_count(s->gb) == s->gb.size_in_bits){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
-
- return 0;
- }else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
return -1;
}
}
}
- s->mb_x=0;
- ff_draw_horiz_band(s, 16*s->mb_y, 16);
}
-#endif
- return -1; //not reached
}
/**
@@ -3591,26 +3697,24 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){
* @param h h264 master context
* @param context_count number of contexts to execute
*/
-static void execute_decode_slices(H264Context *h, int context_count){
+static int execute_decode_slices(H264Context *h, int context_count){
MpegEncContext * const s = &h->s;
AVCodecContext * const avctx= s->avctx;
H264Context *hx;
int i;
- if (s->avctx->hwaccel)
- return;
- if(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
- return;
+ if (s->avctx->hwaccel || s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
+ return 0;
if(context_count == 1) {
- decode_slice(avctx, &h);
+ return decode_slice(avctx, &h);
} else {
for(i = 1; i < context_count; i++) {
hx = h->thread_context[i];
- hx->s.error_recognition = avctx->error_recognition;
+ hx->s.err_recognition = avctx->err_recognition;
hx->s.error_count = 0;
}
- avctx->execute(avctx, (void *)decode_slice,
+ avctx->execute(avctx, decode_slice,
h->thread_context, NULL, context_count, sizeof(void*));
/* pull back stuff from slices to master context */
@@ -3622,6 +3726,8 @@ static void execute_decode_slices(H264Context *h, int context_count){
for(i = 1; i < context_count; i++)
h->s.error_count += h->thread_context[i]->s.error_count;
}
+
+ return 0;
}
@@ -3653,12 +3759,12 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
int consumed;
int dst_length;
int bit_length;
- const uint8_t *ptr;
+ uint8_t *ptr;
int i, nalsize = 0;
int err;
if(buf_index >= next_avc) {
- if(buf_index >= buf_size) break;
+ if (buf_index >= buf_size - h->nal_length_size) break;
nalsize = 0;
for(i = 0; i < h->nal_length_size; i++)
nalsize = (nalsize << 8) | buf[buf_index++];
@@ -3703,6 +3809,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
}
if (h->is_avc && (nalsize != consumed) && nalsize){
+ // set trailing bits in the last partial byte to zero
+ if (bit_length & 7)
+ ptr[bit_length >> 3] = ptr[bit_length >> 3] & (0xff << 8 - (bit_length & 7));
av_log(h->s.avctx, AV_LOG_DEBUG, "AVC: Consumed only %d bytes instead of %d\n", consumed, nalsize);
}
@@ -3716,9 +3825,13 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
switch (hx->nal_unit_type) {
case NAL_SPS:
case NAL_PPS:
+ nals_needed = nal_index;
+ break;
case NAL_IDR_SLICE:
case NAL_SLICE:
- nals_needed = nal_index;
+ init_get_bits(&hx->s.gb, ptr, bit_length);
+ if (!get_ue_golomb(&hx->s.gb))
+ nals_needed = nal_index;
}
continue;
}
@@ -3735,7 +3848,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
av_log(h->s.avctx, AV_LOG_ERROR, "Invalid mix of idr and non-idr slices");
return -1;
}
- idr(h); //FIXME ensure we don't loose some frames if there is reordering
+ idr(h); // FIXME ensure we don't lose some frames if there is reordering
case NAL_SLICE:
init_get_bits(&hx->s.gb, ptr, bit_length);
hx->intra_gb_ptr=
@@ -3745,7 +3858,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
if((err = decode_slice_header(hx, h)))
break;
- s->current_picture_ptr->key_frame |=
+ s->current_picture_ptr->f.key_frame |=
(hx->nal_unit_type == NAL_IDR_SLICE) ||
(h->sei_recovery_frame_cnt >= 0);
@@ -3819,16 +3932,19 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
if(avctx->has_b_frames < 2)
avctx->has_b_frames= !s->low_delay;
- if (avctx->bits_per_raw_sample != h->sps.bit_depth_luma) {
+ if (avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
+ h->cur_chroma_format_idc != h->sps.chroma_format_idc) {
if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 10) {
avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
+ h->cur_chroma_format_idc = h->sps.chroma_format_idc;
h->pixel_shift = h->sps.bit_depth_luma > 8;
- ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma);
- ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma);
+ ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma, h->sps.chroma_format_idc);
+ ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma, h->sps.chroma_format_idc);
+ s->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16;
dsputil_init(&s->dsp, s->avctx);
} else {
- av_log(avctx, AV_LOG_DEBUG, "Unsupported bit depth: %d\n", h->sps.bit_depth_luma);
+ av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", h->sps.bit_depth_luma);
return -1;
}
}
@@ -3875,7 +3991,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
}
/**
- * returns the number of bytes consumed for building the current frame
+ * Return the number of bytes consumed for building the current frame.
*/
static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size){
if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...)
@@ -3909,7 +4025,7 @@ static int decode_frame(AVCodecContext *avctx,
//FIXME factorize this with the output code below
out = h->delayed_pic[0];
out_idx = 0;
- for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame && !h->delayed_pic[i]->mmco_reset; i++)
+ for (i = 1; h->delayed_pic[i] && !h->delayed_pic[i]->f.key_frame && !h->delayed_pic[i]->mmco_reset; i++)
if(h->delayed_pic[i]->poc < out->poc){
out = h->delayed_pic[i];
out_idx = i;
@@ -4049,109 +4165,6 @@ int main(void){
STOP_TIMER("get_se_golomb");
}
-#if 0
- printf("testing 4x4 (I)DCT\n");
-
- DCTELEM block[16];
- uint8_t src[16], ref[16];
- uint64_t error= 0, max_error=0;
-
- for(i=0; i<COUNT; i++){
- int j;
-// printf("%d %d %d\n", r1, r2, (r2-r1)*16);
- for(j=0; j<16; j++){
- ref[j]= random()%255;
- src[j]= random()%255;
- }
-
- h264_diff_dct_c(block, src, ref, 4);
-
- //normalize
- for(j=0; j<16; j++){
-// printf("%d ", block[j]);
- block[j]= block[j]*4;
- if(j&1) block[j]= (block[j]*4 + 2)/5;
- if(j&4) block[j]= (block[j]*4 + 2)/5;
- }
-// printf("\n");
-
- h->h264dsp.h264_idct_add(ref, block, 4);
-/* for(j=0; j<16; j++){
- printf("%d ", ref[j]);
- }
- printf("\n");*/
-
- for(j=0; j<16; j++){
- int diff= FFABS(src[j] - ref[j]);
-
- error+= diff*diff;
- max_error= FFMAX(max_error, diff);
- }
- }
- printf("error=%f max_error=%d\n", ((float)error)/COUNT/16, (int)max_error );
- printf("testing quantizer\n");
- for(qp=0; qp<52; qp++){
- for(i=0; i<16; i++)
- src1_block[i]= src2_block[i]= random()%255;
-
- }
- printf("Testing NAL layer\n");
-
- uint8_t bitstream[COUNT];
- uint8_t nal[COUNT*2];
- H264Context h;
- memset(&h, 0, sizeof(H264Context));
-
- for(i=0; i<COUNT; i++){
- int zeros= i;
- int nal_length;
- int consumed;
- int out_length;
- uint8_t *out;
- int j;
-
- for(j=0; j<COUNT; j++){
- bitstream[j]= (random() % 255) + 1;
- }
-
- for(j=0; j<zeros; j++){
- int pos= random() % COUNT;
- while(bitstream[pos] == 0){
- pos++;
- pos %= COUNT;
- }
- bitstream[pos]=0;
- }
-
- START_TIMER
-
- nal_length= encode_nal(&h, nal, bitstream, COUNT, COUNT*2);
- if(nal_length<0){
- printf("encoding failed\n");
- return -1;
- }
-
- out= ff_h264_decode_nal(&h, nal, &out_length, &consumed, nal_length);
-
- STOP_TIMER("NAL")
-
- if(out_length != COUNT){
- printf("incorrect length %d %d\n", out_length, COUNT);
- return -1;
- }
-
- if(consumed != nal_length){
- printf("incorrect consumed length %d %d\n", nal_length, consumed);
- return -1;
- }
-
- if(memcmp(bitstream, out, COUNT)){
- printf("mismatch\n");
- return -1;
- }
- }
-#endif
-
printf("Testing RBSP\n");
@@ -4205,16 +4218,15 @@ static const AVProfile profiles[] = {
};
AVCodec ff_h264_decoder = {
- "h264",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_H264,
- sizeof(H264Context),
- ff_h264_decode_init,
- NULL,
- ff_h264_decode_end,
- decode_frame,
- /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY |
- CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS,
+ .name = "h264",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_H264,
+ .priv_data_size = sizeof(H264Context),
+ .init = ff_h264_decode_init,
+ .close = ff_h264_decode_end,
+ .decode = decode_frame,
+ .capabilities = /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY |
+ CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS,
.flush= flush_dpb,
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
@@ -4224,15 +4236,14 @@ AVCodec ff_h264_decoder = {
#if CONFIG_H264_VDPAU_DECODER
AVCodec ff_h264_vdpau_decoder = {
- "h264_vdpau",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_H264,
- sizeof(H264Context),
- ff_h264_decode_init,
- NULL,
- ff_h264_decode_end,
- decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
+ .name = "h264_vdpau",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_H264,
+ .priv_data_size = sizeof(H264Context),
+ .init = ff_h264_decode_init,
+ .close = ff_h264_decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
.flush= flush_dpb,
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"),
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_H264, PIX_FMT_NONE},
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index e3cc815..5025538 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -39,13 +39,6 @@
#define interlaced_dct interlaced_dct_is_a_bad_name
#define mb_intra mb_intra_is_not_initialized_see_mb_type
-#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8
-#define COEFF_TOKEN_VLC_BITS 8
-#define TOTAL_ZEROS_VLC_BITS 9
-#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3
-#define RUN_VLC_BITS 3
-#define RUN7_VLC_BITS 6
-
#define MAX_SPS_COUNT 32
#define MAX_PPS_COUNT 256
@@ -70,6 +63,10 @@
#define MB_FIELD h->mb_field_decoding_flag
#define FRAME_MBAFF h->mb_aff_frame
#define FIELD_PICTURE (s->picture_structure != PICT_FRAME)
+#define LEFT_MBS 2
+#define LTOP 0
+#define LBOT 1
+#define LEFT(i) (i)
#else
#define MB_MBAFF 0
#define MB_FIELD 0
@@ -77,6 +74,10 @@
#define FIELD_PICTURE 0
#undef IS_INTERLACED
#define IS_INTERLACED(mb_type) 0
+#define LEFT_MBS 1
+#define LTOP 0
+#define LBOT 0
+#define LEFT(i) 0
#endif
#define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE)
@@ -84,6 +85,7 @@
#define CABAC h->pps.cabac
#endif
+#define CHROMA422 (h->sps.chroma_format_idc == 2)
#define CHROMA444 (h->sps.chroma_format_idc == 3)
#define EXTENDED_SAR 255
@@ -272,12 +274,12 @@ typedef struct H264Context{
int topleft_mb_xy;
int top_mb_xy;
int topright_mb_xy;
- int left_mb_xy[2];
+ int left_mb_xy[LEFT_MBS];
int topleft_type;
int top_type;
int topright_type;
- int left_type[2];
+ int left_type[LEFT_MBS];
const uint8_t * left_block;
int topleft_partition;
@@ -308,11 +310,6 @@ typedef struct H264Context{
#define PART_NOT_AVAILABLE -2
/**
- * is 1 if the specific list MV&references are set to 0,0,-2.
- */
- int mv_cache_clean[2];
-
- /**
* number of neighbors (top and/or left) that used 8x8 dct
*/
int neighbor_transform_size;
@@ -491,6 +488,7 @@ typedef struct H264Context{
Picture *long_ref[32];
Picture default_ref_list[2][32]; ///< base reference list for all slices of a coded picture
Picture *delayed_pic[MAX_DELAYED_PIC_COUNT+2]; //FIXME size?
+ int last_pocs[MAX_DELAYED_PIC_COUNT];
Picture *next_output_pic;
int outputed_poc;
int next_outputed_poc;
@@ -500,6 +498,7 @@ typedef struct H264Context{
*/
MMCO mmco[MAX_MMCO_COUNT];
int mmco_index;
+ int mmco_reset;
int long_ref_count; ///< number of actual long term references
int short_ref_count; ///< number of actual short term references
@@ -579,6 +578,8 @@ typedef struct H264Context{
// Timestamp stuff
int sei_buffering_period_present; ///< Buffering period SEI flag
int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs
+
+ int cur_chroma_format_idc;
}H264Context;
@@ -658,7 +659,6 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h);
*/
int ff_h264_check_intra_pred_mode(H264Context *h, int mode);
-void ff_h264_write_back_intra_pred_mode(H264Context *h);
void ff_h264_hl_decode_mb(H264Context *h);
int ff_h264_frame_start(H264Context *h);
int ff_h264_decode_extradata(H264Context *h);
@@ -668,13 +668,13 @@ av_cold void ff_h264_decode_init_vlc(void);
/**
* Decode a macroblock
- * @return 0 if OK, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed
+ * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
*/
int ff_h264_decode_mb_cavlc(H264Context *h);
/**
* Decode a CABAC coded macroblock
- * @return 0 if OK, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed
+ * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
*/
int ff_h264_decode_mb_cabac(H264Context *h);
@@ -762,430 +762,16 @@ static av_always_inline uint16_t pack8to16(int a, int b){
}
/**
- * gets the chroma qp.
+ * Get the chroma qp.
*/
-static inline int get_chroma_qp(H264Context *h, int t, int qscale){
+static av_always_inline int get_chroma_qp(H264Context *h, int t, int qscale){
return h->pps.chroma_qp_table[t][qscale];
}
-static inline void pred_pskip_motion(H264Context * const h, int * const mx, int * const my);
-
-static void fill_decode_neighbors(H264Context *h, int mb_type){
- MpegEncContext * const s = &h->s;
- const int mb_xy= h->mb_xy;
- int topleft_xy, top_xy, topright_xy, left_xy[2];
- static const uint8_t left_block_options[4][32]={
- {0,1,2,3,7,10,8,11,3+0*4, 3+1*4, 3+2*4, 3+3*4, 1+4*4, 1+8*4, 1+5*4, 1+9*4},
- {2,2,3,3,8,11,8,11,3+2*4, 3+2*4, 3+3*4, 3+3*4, 1+5*4, 1+9*4, 1+5*4, 1+9*4},
- {0,0,1,1,7,10,7,10,3+0*4, 3+0*4, 3+1*4, 3+1*4, 1+4*4, 1+8*4, 1+4*4, 1+8*4},
- {0,2,0,2,7,10,7,10,3+0*4, 3+2*4, 3+0*4, 3+2*4, 1+4*4, 1+8*4, 1+4*4, 1+8*4}
- };
-
- h->topleft_partition= -1;
-
- top_xy = mb_xy - (s->mb_stride << MB_FIELD);
-
- /* Wow, what a mess, why didn't they simplify the interlacing & intra
- * stuff, I can't imagine that these complex rules are worth it. */
-
- topleft_xy = top_xy - 1;
- topright_xy= top_xy + 1;
- left_xy[1] = left_xy[0] = mb_xy-1;
- h->left_block = left_block_options[0];
- if(FRAME_MBAFF){
- const int left_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[mb_xy-1]);
- const int curr_mb_field_flag = IS_INTERLACED(mb_type);
- if(s->mb_y&1){
- if (left_mb_field_flag != curr_mb_field_flag) {
- left_xy[1] = left_xy[0] = mb_xy - s->mb_stride - 1;
- if (curr_mb_field_flag) {
- left_xy[1] += s->mb_stride;
- h->left_block = left_block_options[3];
- } else {
- topleft_xy += s->mb_stride;
- // take top left mv from the middle of the mb, as opposed to all other modes which use the bottom right partition
- h->topleft_partition = 0;
- h->left_block = left_block_options[1];
- }
- }
- }else{
- if(curr_mb_field_flag){
- topleft_xy += s->mb_stride & (((s->current_picture.mb_type[top_xy - 1]>>7)&1)-1);
- topright_xy += s->mb_stride & (((s->current_picture.mb_type[top_xy + 1]>>7)&1)-1);
- top_xy += s->mb_stride & (((s->current_picture.mb_type[top_xy ]>>7)&1)-1);
- }
- if (left_mb_field_flag != curr_mb_field_flag) {
- if (curr_mb_field_flag) {
- left_xy[1] += s->mb_stride;
- h->left_block = left_block_options[3];
- } else {
- h->left_block = left_block_options[2];
- }
- }
- }
- }
-
- h->topleft_mb_xy = topleft_xy;
- h->top_mb_xy = top_xy;
- h->topright_mb_xy= topright_xy;
- h->left_mb_xy[0] = left_xy[0];
- h->left_mb_xy[1] = left_xy[1];
- //FIXME do we need all in the context?
-
- h->topleft_type = s->current_picture.mb_type[topleft_xy] ;
- h->top_type = s->current_picture.mb_type[top_xy] ;
- h->topright_type= s->current_picture.mb_type[topright_xy];
- h->left_type[0] = s->current_picture.mb_type[left_xy[0]] ;
- h->left_type[1] = s->current_picture.mb_type[left_xy[1]] ;
-
- if(FMO){
- if(h->slice_table[topleft_xy ] != h->slice_num) h->topleft_type = 0;
- if(h->slice_table[top_xy ] != h->slice_num) h->top_type = 0;
- if(h->slice_table[left_xy[0] ] != h->slice_num) h->left_type[0] = h->left_type[1] = 0;
- }else{
- if(h->slice_table[topleft_xy ] != h->slice_num){
- h->topleft_type = 0;
- if(h->slice_table[top_xy ] != h->slice_num) h->top_type = 0;
- if(h->slice_table[left_xy[0] ] != h->slice_num) h->left_type[0] = h->left_type[1] = 0;
- }
- }
- if(h->slice_table[topright_xy] != h->slice_num) h->topright_type= 0;
-}
-
-static void fill_decode_caches(H264Context *h, int mb_type){
- MpegEncContext * const s = &h->s;
- int topleft_xy, top_xy, topright_xy, left_xy[2];
- int topleft_type, top_type, topright_type, left_type[2];
- const uint8_t * left_block= h->left_block;
- int i;
-
- topleft_xy = h->topleft_mb_xy ;
- top_xy = h->top_mb_xy ;
- topright_xy = h->topright_mb_xy;
- left_xy[0] = h->left_mb_xy[0] ;
- left_xy[1] = h->left_mb_xy[1] ;
- topleft_type = h->topleft_type ;
- top_type = h->top_type ;
- topright_type= h->topright_type ;
- left_type[0] = h->left_type[0] ;
- left_type[1] = h->left_type[1] ;
-
- if(!IS_SKIP(mb_type)){
- if(IS_INTRA(mb_type)){
- int type_mask= h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1;
- h->topleft_samples_available=
- h->top_samples_available=
- h->left_samples_available= 0xFFFF;
- h->topright_samples_available= 0xEEEA;
-
- if(!(top_type & type_mask)){
- h->topleft_samples_available= 0xB3FF;
- h->top_samples_available= 0x33FF;
- h->topright_samples_available= 0x26EA;
- }
- if(IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[0])){
- if(IS_INTERLACED(mb_type)){
- if(!(left_type[0] & type_mask)){
- h->topleft_samples_available&= 0xDFFF;
- h->left_samples_available&= 0x5FFF;
- }
- if(!(left_type[1] & type_mask)){
- h->topleft_samples_available&= 0xFF5F;
- h->left_samples_available&= 0xFF5F;
- }
- }else{
- int left_typei = s->current_picture.mb_type[left_xy[0] + s->mb_stride];
-
- assert(left_xy[0] == left_xy[1]);
- if(!((left_typei & type_mask) && (left_type[0] & type_mask))){
- h->topleft_samples_available&= 0xDF5F;
- h->left_samples_available&= 0x5F5F;
- }
- }
- }else{
- if(!(left_type[0] & type_mask)){
- h->topleft_samples_available&= 0xDF5F;
- h->left_samples_available&= 0x5F5F;
- }
- }
-
- if(!(topleft_type & type_mask))
- h->topleft_samples_available&= 0x7FFF;
-
- if(!(topright_type & type_mask))
- h->topright_samples_available&= 0xFBFF;
-
- if(IS_INTRA4x4(mb_type)){
- if(IS_INTRA4x4(top_type)){
- AV_COPY32(h->intra4x4_pred_mode_cache+4+8*0, h->intra4x4_pred_mode + h->mb2br_xy[top_xy]);
- }else{
- h->intra4x4_pred_mode_cache[4+8*0]=
- h->intra4x4_pred_mode_cache[5+8*0]=
- h->intra4x4_pred_mode_cache[6+8*0]=
- h->intra4x4_pred_mode_cache[7+8*0]= 2 - 3*!(top_type & type_mask);
- }
- for(i=0; i<2; i++){
- if(IS_INTRA4x4(left_type[i])){
- int8_t *mode= h->intra4x4_pred_mode + h->mb2br_xy[left_xy[i]];
- h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= mode[6-left_block[0+2*i]];
- h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= mode[6-left_block[1+2*i]];
- }else{
- h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]=
- h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= 2 - 3*!(left_type[i] & type_mask);
- }
- }
- }
- }
-
-
-/*
-0 . T T. T T T T
-1 L . .L . . . .
-2 L . .L . . . .
-3 . T TL . . . .
-4 L . .L . . . .
-5 L . .. . . . .
-*/
-//FIXME constraint_intra_pred & partitioning & nnz (let us hope this is just a typo in the spec)
- if(top_type){
- AV_COPY32(&h->non_zero_count_cache[4+8* 0], &h->non_zero_count[top_xy][4*3]);
- if(CHROMA444){
- AV_COPY32(&h->non_zero_count_cache[4+8* 5], &h->non_zero_count[top_xy][4* 7]);
- AV_COPY32(&h->non_zero_count_cache[4+8*10], &h->non_zero_count[top_xy][4*11]);
- }else{
- AV_COPY32(&h->non_zero_count_cache[4+8* 5], &h->non_zero_count[top_xy][4* 5]);
- AV_COPY32(&h->non_zero_count_cache[4+8*10], &h->non_zero_count[top_xy][4* 9]);
- }
- }else{
- uint32_t top_empty = CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040;
- AV_WN32A(&h->non_zero_count_cache[4+8* 0], top_empty);
- AV_WN32A(&h->non_zero_count_cache[4+8* 5], top_empty);
- AV_WN32A(&h->non_zero_count_cache[4+8*10], top_empty);
- }
-
- for (i=0; i<2; i++) {
- if(left_type[i]){
- h->non_zero_count_cache[3+8* 1 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]];
- h->non_zero_count_cache[3+8* 2 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]];
- if(CHROMA444){
- h->non_zero_count_cache[3+8* 6 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]+4*4];
- h->non_zero_count_cache[3+8* 7 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]+4*4];
- h->non_zero_count_cache[3+8*11 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]+8*4];
- h->non_zero_count_cache[3+8*12 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]+8*4];
- }else{
- h->non_zero_count_cache[3+8* 6 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+4+2*i]];
- h->non_zero_count_cache[3+8*11 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+5+2*i]];
- }
- }else{
- h->non_zero_count_cache[3+8* 1 + 2*8*i]=
- h->non_zero_count_cache[3+8* 2 + 2*8*i]=
- h->non_zero_count_cache[3+8* 6 + 2*8*i]=
- h->non_zero_count_cache[3+8* 7 + 2*8*i]=
- h->non_zero_count_cache[3+8*11 + 2*8*i]=
- h->non_zero_count_cache[3+8*12 + 2*8*i]= CABAC && !IS_INTRA(mb_type) ? 0 : 64;
- }
- }
-
- if( CABAC ) {
- // top_cbp
- if(top_type) {
- h->top_cbp = h->cbp_table[top_xy];
- } else {
- h->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
- }
- // left_cbp
- if (left_type[0]) {
- h->left_cbp = (h->cbp_table[left_xy[0]] & 0x7F0)
- | ((h->cbp_table[left_xy[0]]>>(left_block[0]&(~1)))&2)
- | (((h->cbp_table[left_xy[1]]>>(left_block[2]&(~1)))&2) << 2);
- } else {
- h->left_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
- }
- }
- }
-
- if(IS_INTER(mb_type) || (IS_DIRECT(mb_type) && h->direct_spatial_mv_pred)){
- int list;
- for(list=0; list<h->list_count; list++){
- if(!USES_LIST(mb_type, list)){
- /*if(!h->mv_cache_clean[list]){
- memset(h->mv_cache [list], 0, 8*5*2*sizeof(int16_t)); //FIXME clean only input? clean at all?
- memset(h->ref_cache[list], PART_NOT_AVAILABLE, 8*5*sizeof(int8_t));
- h->mv_cache_clean[list]= 1;
- }*/
- continue;
- }
- assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
-
- h->mv_cache_clean[list]= 0;
-
- if(USES_LIST(top_type, list)){
- const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride;
- AV_COPY128(h->mv_cache[list][scan8[0] + 0 - 1*8], s->current_picture.motion_val[list][b_xy + 0]);
- h->ref_cache[list][scan8[0] + 0 - 1*8]=
- h->ref_cache[list][scan8[0] + 1 - 1*8]= s->current_picture.ref_index[list][4*top_xy + 2];
- h->ref_cache[list][scan8[0] + 2 - 1*8]=
- h->ref_cache[list][scan8[0] + 3 - 1*8]= s->current_picture.ref_index[list][4*top_xy + 3];
- }else{
- AV_ZERO128(h->mv_cache[list][scan8[0] + 0 - 1*8]);
- AV_WN32A(&h->ref_cache[list][scan8[0] + 0 - 1*8], ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE)&0xFF)*0x01010101);
- }
-
- if(mb_type & (MB_TYPE_16x8|MB_TYPE_8x8)){
- for(i=0; i<2; i++){
- int cache_idx = scan8[0] - 1 + i*2*8;
- if(USES_LIST(left_type[i], list)){
- const int b_xy= h->mb2b_xy[left_xy[i]] + 3;
- const int b8_xy= 4*left_xy[i] + 1;
- AV_COPY32(h->mv_cache[list][cache_idx ], s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[0+i*2]]);
- AV_COPY32(h->mv_cache[list][cache_idx+8], s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[1+i*2]]);
- h->ref_cache[list][cache_idx ]= s->current_picture.ref_index[list][b8_xy + (left_block[0+i*2]&~1)];
- h->ref_cache[list][cache_idx+8]= s->current_picture.ref_index[list][b8_xy + (left_block[1+i*2]&~1)];
- }else{
- AV_ZERO32(h->mv_cache [list][cache_idx ]);
- AV_ZERO32(h->mv_cache [list][cache_idx+8]);
- h->ref_cache[list][cache_idx ]=
- h->ref_cache[list][cache_idx+8]= (left_type[i]) ? LIST_NOT_USED : PART_NOT_AVAILABLE;
- }
- }
- }else{
- if(USES_LIST(left_type[0], list)){
- const int b_xy= h->mb2b_xy[left_xy[0]] + 3;
- const int b8_xy= 4*left_xy[0] + 1;
- AV_COPY32(h->mv_cache[list][scan8[0] - 1], s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[0]]);
- h->ref_cache[list][scan8[0] - 1]= s->current_picture.ref_index[list][b8_xy + (left_block[0]&~1)];
- }else{
- AV_ZERO32(h->mv_cache [list][scan8[0] - 1]);
- h->ref_cache[list][scan8[0] - 1]= left_type[0] ? LIST_NOT_USED : PART_NOT_AVAILABLE;
- }
- }
-
- if(USES_LIST(topright_type, list)){
- const int b_xy= h->mb2b_xy[topright_xy] + 3*h->b_stride;
- AV_COPY32(h->mv_cache[list][scan8[0] + 4 - 1*8], s->current_picture.motion_val[list][b_xy]);
- h->ref_cache[list][scan8[0] + 4 - 1*8]= s->current_picture.ref_index[list][4*topright_xy + 2];
- }else{
- AV_ZERO32(h->mv_cache [list][scan8[0] + 4 - 1*8]);
- h->ref_cache[list][scan8[0] + 4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;
- }
- if(h->ref_cache[list][scan8[0] + 4 - 1*8] < 0){
- if(USES_LIST(topleft_type, list)){
- const int b_xy = h->mb2b_xy [topleft_xy] + 3 + h->b_stride + (h->topleft_partition & 2*h->b_stride);
- const int b8_xy= 4*topleft_xy + 1 + (h->topleft_partition & 2);
- AV_COPY32(h->mv_cache[list][scan8[0] - 1 - 1*8], s->current_picture.motion_val[list][b_xy]);
- h->ref_cache[list][scan8[0] - 1 - 1*8]= s->current_picture.ref_index[list][b8_xy];
- }else{
- AV_ZERO32(h->mv_cache[list][scan8[0] - 1 - 1*8]);
- h->ref_cache[list][scan8[0] - 1 - 1*8]= topleft_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;
- }
- }
-
- if((mb_type&(MB_TYPE_SKIP|MB_TYPE_DIRECT2)) && !FRAME_MBAFF)
- continue;
-
- if(!(mb_type&(MB_TYPE_SKIP|MB_TYPE_DIRECT2))) {
- h->ref_cache[list][scan8[4 ]] =
- h->ref_cache[list][scan8[12]] = PART_NOT_AVAILABLE;
- AV_ZERO32(h->mv_cache [list][scan8[4 ]]);
- AV_ZERO32(h->mv_cache [list][scan8[12]]);
-
- if( CABAC ) {
- /* XXX beurk, Load mvd */
- if(USES_LIST(top_type, list)){
- const int b_xy= h->mb2br_xy[top_xy];
- AV_COPY64(h->mvd_cache[list][scan8[0] + 0 - 1*8], h->mvd_table[list][b_xy + 0]);
- }else{
- AV_ZERO64(h->mvd_cache[list][scan8[0] + 0 - 1*8]);
- }
- if(USES_LIST(left_type[0], list)){
- const int b_xy= h->mb2br_xy[left_xy[0]] + 6;
- AV_COPY16(h->mvd_cache[list][scan8[0] - 1 + 0*8], h->mvd_table[list][b_xy - left_block[0]]);
- AV_COPY16(h->mvd_cache[list][scan8[0] - 1 + 1*8], h->mvd_table[list][b_xy - left_block[1]]);
- }else{
- AV_ZERO16(h->mvd_cache [list][scan8[0] - 1 + 0*8]);
- AV_ZERO16(h->mvd_cache [list][scan8[0] - 1 + 1*8]);
- }
- if(USES_LIST(left_type[1], list)){
- const int b_xy= h->mb2br_xy[left_xy[1]] + 6;
- AV_COPY16(h->mvd_cache[list][scan8[0] - 1 + 2*8], h->mvd_table[list][b_xy - left_block[2]]);
- AV_COPY16(h->mvd_cache[list][scan8[0] - 1 + 3*8], h->mvd_table[list][b_xy - left_block[3]]);
- }else{
- AV_ZERO16(h->mvd_cache [list][scan8[0] - 1 + 2*8]);
- AV_ZERO16(h->mvd_cache [list][scan8[0] - 1 + 3*8]);
- }
- AV_ZERO16(h->mvd_cache [list][scan8[4 ]]);
- AV_ZERO16(h->mvd_cache [list][scan8[12]]);
- if(h->slice_type_nos == AV_PICTURE_TYPE_B){
- fill_rectangle(&h->direct_cache[scan8[0]], 4, 4, 8, MB_TYPE_16x16>>1, 1);
-
- if(IS_DIRECT(top_type)){
- AV_WN32A(&h->direct_cache[scan8[0] - 1*8], 0x01010101u*(MB_TYPE_DIRECT2>>1));
- }else if(IS_8X8(top_type)){
- int b8_xy = 4*top_xy;
- h->direct_cache[scan8[0] + 0 - 1*8]= h->direct_table[b8_xy + 2];
- h->direct_cache[scan8[0] + 2 - 1*8]= h->direct_table[b8_xy + 3];
- }else{
- AV_WN32A(&h->direct_cache[scan8[0] - 1*8], 0x01010101*(MB_TYPE_16x16>>1));
- }
-
- if(IS_DIRECT(left_type[0]))
- h->direct_cache[scan8[0] - 1 + 0*8]= MB_TYPE_DIRECT2>>1;
- else if(IS_8X8(left_type[0]))
- h->direct_cache[scan8[0] - 1 + 0*8]= h->direct_table[4*left_xy[0] + 1 + (left_block[0]&~1)];
- else
- h->direct_cache[scan8[0] - 1 + 0*8]= MB_TYPE_16x16>>1;
-
- if(IS_DIRECT(left_type[1]))
- h->direct_cache[scan8[0] - 1 + 2*8]= MB_TYPE_DIRECT2>>1;
- else if(IS_8X8(left_type[1]))
- h->direct_cache[scan8[0] - 1 + 2*8]= h->direct_table[4*left_xy[1] + 1 + (left_block[2]&~1)];
- else
- h->direct_cache[scan8[0] - 1 + 2*8]= MB_TYPE_16x16>>1;
- }
- }
- }
- if(FRAME_MBAFF){
-#define MAP_MVS\
- MAP_F2F(scan8[0] - 1 - 1*8, topleft_type)\
- MAP_F2F(scan8[0] + 0 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 1 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 2 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 3 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 4 - 1*8, topright_type)\
- MAP_F2F(scan8[0] - 1 + 0*8, left_type[0])\
- MAP_F2F(scan8[0] - 1 + 1*8, left_type[0])\
- MAP_F2F(scan8[0] - 1 + 2*8, left_type[1])\
- MAP_F2F(scan8[0] - 1 + 3*8, left_type[1])
- if(MB_FIELD){
-#define MAP_F2F(idx, mb_type)\
- if(!IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0){\
- h->ref_cache[list][idx] <<= 1;\
- h->mv_cache[list][idx][1] /= 2;\
- h->mvd_cache[list][idx][1] >>=1;\
- }
- MAP_MVS
-#undef MAP_F2F
- }else{
-#define MAP_F2F(idx, mb_type)\
- if(IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0){\
- h->ref_cache[list][idx] >>= 1;\
- h->mv_cache[list][idx][1] <<= 1;\
- h->mvd_cache[list][idx][1] <<= 1;\
- }
- MAP_MVS
-#undef MAP_F2F
- }
- }
- }
- }
-
- h->neighbor_transform_size= !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[0]);
-}
-
/**
- * gets the predicted intra4x4 prediction mode.
+ * Get the predicted intra4x4 prediction mode.
*/
-static inline int pred_intra_mode(H264Context *h, int n){
+static av_always_inline int pred_intra_mode(H264Context *h, int n){
const int index8= scan8[n];
const int left= h->intra4x4_pred_mode_cache[index8 - 1];
const int top = h->intra4x4_pred_mode_cache[index8 - 8];
@@ -1197,69 +783,84 @@ static inline int pred_intra_mode(H264Context *h, int n){
else return min;
}
-static inline void write_back_non_zero_count(H264Context *h){
+static av_always_inline void write_back_intra_pred_mode(H264Context *h){
+ int8_t *i4x4= h->intra4x4_pred_mode + h->mb2br_xy[h->mb_xy];
+ int8_t *i4x4_cache= h->intra4x4_pred_mode_cache;
+
+ AV_COPY32(i4x4, i4x4_cache + 4 + 8*4);
+ i4x4[4]= i4x4_cache[7+8*3];
+ i4x4[5]= i4x4_cache[7+8*2];
+ i4x4[6]= i4x4_cache[7+8*1];
+}
+
+static av_always_inline void write_back_non_zero_count(H264Context *h){
const int mb_xy= h->mb_xy;
+ uint8_t *nnz = h->non_zero_count[mb_xy];
+ uint8_t *nnz_cache = h->non_zero_count_cache;
+
+ AV_COPY32(&nnz[ 0], &nnz_cache[4+8* 1]);
+ AV_COPY32(&nnz[ 4], &nnz_cache[4+8* 2]);
+ AV_COPY32(&nnz[ 8], &nnz_cache[4+8* 3]);
+ AV_COPY32(&nnz[12], &nnz_cache[4+8* 4]);
+ AV_COPY32(&nnz[16], &nnz_cache[4+8* 6]);
+ AV_COPY32(&nnz[20], &nnz_cache[4+8* 7]);
+ AV_COPY32(&nnz[32], &nnz_cache[4+8*11]);
+ AV_COPY32(&nnz[36], &nnz_cache[4+8*12]);
+
+ if(!h->s.chroma_y_shift){
+ AV_COPY32(&nnz[24], &nnz_cache[4+8* 8]);
+ AV_COPY32(&nnz[28], &nnz_cache[4+8* 9]);
+ AV_COPY32(&nnz[40], &nnz_cache[4+8*13]);
+ AV_COPY32(&nnz[44], &nnz_cache[4+8*14]);
+ }
+}
+
+static av_always_inline void write_back_motion_list(H264Context *h, MpegEncContext * const s, int b_stride,
+ int b_xy, int b8_xy, int mb_type, int list )
+{
+ int16_t (*mv_dst)[2] = &s->current_picture.f.motion_val[list][b_xy];
+ int16_t (*mv_src)[2] = &h->mv_cache[list][scan8[0]];
+ AV_COPY128(mv_dst + 0*b_stride, mv_src + 8*0);
+ AV_COPY128(mv_dst + 1*b_stride, mv_src + 8*1);
+ AV_COPY128(mv_dst + 2*b_stride, mv_src + 8*2);
+ AV_COPY128(mv_dst + 3*b_stride, mv_src + 8*3);
+ if( CABAC ) {
+ uint8_t (*mvd_dst)[2] = &h->mvd_table[list][FMO ? 8*h->mb_xy : h->mb2br_xy[h->mb_xy]];
+ uint8_t (*mvd_src)[2] = &h->mvd_cache[list][scan8[0]];
+ if(IS_SKIP(mb_type))
+ AV_ZERO128(mvd_dst);
+ else{
+ AV_COPY64(mvd_dst, mvd_src + 8*3);
+ AV_COPY16(mvd_dst + 3 + 3, mvd_src + 3 + 8*0);
+ AV_COPY16(mvd_dst + 3 + 2, mvd_src + 3 + 8*1);
+ AV_COPY16(mvd_dst + 3 + 1, mvd_src + 3 + 8*2);
+ }
+ }
- AV_COPY32(&h->non_zero_count[mb_xy][ 0], &h->non_zero_count_cache[4+8* 1]);
- AV_COPY32(&h->non_zero_count[mb_xy][ 4], &h->non_zero_count_cache[4+8* 2]);
- AV_COPY32(&h->non_zero_count[mb_xy][ 8], &h->non_zero_count_cache[4+8* 3]);
- AV_COPY32(&h->non_zero_count[mb_xy][12], &h->non_zero_count_cache[4+8* 4]);
- AV_COPY32(&h->non_zero_count[mb_xy][16], &h->non_zero_count_cache[4+8* 6]);
- AV_COPY32(&h->non_zero_count[mb_xy][20], &h->non_zero_count_cache[4+8* 7]);
- AV_COPY32(&h->non_zero_count[mb_xy][32], &h->non_zero_count_cache[4+8*11]);
- AV_COPY32(&h->non_zero_count[mb_xy][36], &h->non_zero_count_cache[4+8*12]);
-
- if(CHROMA444){
- AV_COPY32(&h->non_zero_count[mb_xy][24], &h->non_zero_count_cache[4+8* 8]);
- AV_COPY32(&h->non_zero_count[mb_xy][28], &h->non_zero_count_cache[4+8* 9]);
- AV_COPY32(&h->non_zero_count[mb_xy][40], &h->non_zero_count_cache[4+8*13]);
- AV_COPY32(&h->non_zero_count[mb_xy][44], &h->non_zero_count_cache[4+8*14]);
+ {
+ int8_t *ref_index = &s->current_picture.f.ref_index[list][b8_xy];
+ int8_t *ref_cache = h->ref_cache[list];
+ ref_index[0+0*2]= ref_cache[scan8[0]];
+ ref_index[1+0*2]= ref_cache[scan8[4]];
+ ref_index[0+1*2]= ref_cache[scan8[8]];
+ ref_index[1+1*2]= ref_cache[scan8[12]];
}
}
-static inline void write_back_motion(H264Context *h, int mb_type){
+static av_always_inline void write_back_motion(H264Context *h, int mb_type){
MpegEncContext * const s = &h->s;
+ const int b_stride = h->b_stride;
const int b_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; //try mb2b(8)_xy
const int b8_xy= 4*h->mb_xy;
- int list;
-
- if(!USES_LIST(mb_type, 0))
- fill_rectangle(&s->current_picture.ref_index[0][b8_xy], 2, 2, 2, (uint8_t)LIST_NOT_USED, 1);
-
- for(list=0; list<h->list_count; list++){
- int y, b_stride;
- int16_t (*mv_dst)[2];
- int16_t (*mv_src)[2];
-
- if(!USES_LIST(mb_type, list))
- continue;
- b_stride = h->b_stride;
- mv_dst = &s->current_picture.motion_val[list][b_xy];
- mv_src = &h->mv_cache[list][scan8[0]];
- for(y=0; y<4; y++){
- AV_COPY128(mv_dst + y*b_stride, mv_src + 8*y);
- }
- if( CABAC ) {
- uint8_t (*mvd_dst)[2] = &h->mvd_table[list][FMO ? 8*h->mb_xy : h->mb2br_xy[h->mb_xy]];
- uint8_t (*mvd_src)[2] = &h->mvd_cache[list][scan8[0]];
- if(IS_SKIP(mb_type))
- AV_ZERO128(mvd_dst);
- else{
- AV_COPY64(mvd_dst, mvd_src + 8*3);
- AV_COPY16(mvd_dst + 3 + 3, mvd_src + 3 + 8*0);
- AV_COPY16(mvd_dst + 3 + 2, mvd_src + 3 + 8*1);
- AV_COPY16(mvd_dst + 3 + 1, mvd_src + 3 + 8*2);
- }
- }
-
- {
- int8_t *ref_index = &s->current_picture.ref_index[list][b8_xy];
- ref_index[0+0*2]= h->ref_cache[list][scan8[0]];
- ref_index[1+0*2]= h->ref_cache[list][scan8[4]];
- ref_index[0+1*2]= h->ref_cache[list][scan8[8]];
- ref_index[1+1*2]= h->ref_cache[list][scan8[12]];
- }
+ if(USES_LIST(mb_type, 0)){
+ write_back_motion_list(h, s, b_stride, b_xy, b8_xy, mb_type, 0);
+ }else{
+ fill_rectangle(&s->current_picture.f.ref_index[0][b8_xy],
+ 2, 2, 2, (uint8_t)LIST_NOT_USED, 1);
+ }
+ if(USES_LIST(mb_type, 1)){
+ write_back_motion_list(h, s, b_stride, b_xy, b8_xy, mb_type, 1);
}
if(h->slice_type_nos == AV_PICTURE_TYPE_B && CABAC){
@@ -1272,56 +873,11 @@ static inline void write_back_motion(H264Context *h, int mb_type){
}
}
-static inline int get_dct8x8_allowed(H264Context *h){
+static av_always_inline int get_dct8x8_allowed(H264Context *h){
if(h->sps.direct_8x8_inference_flag)
return !(AV_RN64A(h->sub_mb_type) & ((MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8 )*0x0001000100010001ULL));
else
return !(AV_RN64A(h->sub_mb_type) & ((MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8|MB_TYPE_DIRECT2)*0x0001000100010001ULL));
}
-/**
- * decodes a P_SKIP or B_SKIP macroblock
- */
-static void av_unused decode_mb_skip(H264Context *h){
- MpegEncContext * const s = &h->s;
- const int mb_xy= h->mb_xy;
- int mb_type=0;
-
- memset(h->non_zero_count[mb_xy], 0, 48);
-
- if(MB_FIELD)
- mb_type|= MB_TYPE_INTERLACED;
-
- if( h->slice_type_nos == AV_PICTURE_TYPE_B )
- {
- // just for fill_caches. pred_direct_motion will set the real mb_type
- mb_type|= MB_TYPE_L0L1|MB_TYPE_DIRECT2|MB_TYPE_SKIP;
- if(h->direct_spatial_mv_pred){
- fill_decode_neighbors(h, mb_type);
- fill_decode_caches(h, mb_type); //FIXME check what is needed and what not ...
- }
- ff_h264_pred_direct_motion(h, &mb_type);
- mb_type|= MB_TYPE_SKIP;
- }
- else
- {
- int mx, my;
- mb_type|= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P1L0|MB_TYPE_SKIP;
-
- fill_decode_neighbors(h, mb_type);
- fill_decode_caches(h, mb_type); //FIXME check what is needed and what not ...
- pred_pskip_motion(h, &mx, &my);
- fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
- fill_rectangle( h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx,my), 4);
- }
-
- write_back_motion(h, mb_type);
- s->current_picture.mb_type[mb_xy]= mb_type;
- s->current_picture.qscale_table[mb_xy]= s->qscale;
- h->slice_table[ mb_xy ]= h->slice_num;
- h->prev_mb_skipped= 1;
-}
-
-#include "h264_mvpred.h" //For pred_pskip_motion()
-
#endif /* AVCODEC_H264_H */
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index f30f4e1..feadf49 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -1284,8 +1284,8 @@ static int decode_cabac_field_decoding_flag(H264Context *h) {
unsigned long ctx = 0;
- ctx += h->mb_field_decoding_flag & !!s->mb_x; //for FMO:(s->current_picture.mb_type[mba_xy]>>7)&(h->slice_table[mba_xy] == h->slice_num);
- ctx += (s->current_picture.mb_type[mbb_xy]>>7)&(h->slice_table[mbb_xy] == h->slice_num);
+ ctx += h->mb_field_decoding_flag & !!s->mb_x; //for FMO:(s->current_picture.f.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
+ ctx += (s->current_picture.f.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num);
return get_cabac_noinline( &h->cabac, &(h->cabac_state+70)[ctx] );
}
@@ -1296,9 +1296,9 @@ static int decode_cabac_intra_mb_type(H264Context *h, int ctx_base, int intra_sl
if(intra_slice){
int ctx=0;
- if( h->left_type[0] & (MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM))
+ if( h->left_type[LTOP] & (MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM))
ctx++;
- if( h->top_type & (MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM))
+ if( h->top_type & (MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM))
ctx++;
if( get_cabac_noinline( &h->cabac, &state[ctx] ) == 0 )
return 0; /* I4x4 */
@@ -1330,13 +1330,13 @@ static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) {
mba_xy = mb_xy - 1;
if( (mb_y&1)
&& h->slice_table[mba_xy] == h->slice_num
- && MB_FIELD == !!IS_INTERLACED( s->current_picture.mb_type[mba_xy] ) )
+ && MB_FIELD == !!IS_INTERLACED( s->current_picture.f.mb_type[mba_xy] ) )
mba_xy += s->mb_stride;
if( MB_FIELD ){
mbb_xy = mb_xy - s->mb_stride;
if( !(mb_y&1)
&& h->slice_table[mbb_xy] == h->slice_num
- && IS_INTERLACED( s->current_picture.mb_type[mbb_xy] ) )
+ && IS_INTERLACED( s->current_picture.f.mb_type[mbb_xy] ) )
mbb_xy -= s->mb_stride;
}else
mbb_xy = mb_x + (mb_y-1)*s->mb_stride;
@@ -1346,9 +1346,9 @@ static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) {
mbb_xy = mb_xy - (s->mb_stride << FIELD_PICTURE);
}
- if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mba_xy] ))
+ if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP( s->current_picture.f.mb_type[mba_xy] ))
ctx++;
- if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mbb_xy] ))
+ if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP( s->current_picture.f.mb_type[mbb_xy] ))
ctx++;
if( h->slice_type_nos == AV_PICTURE_TYPE_B )
@@ -1376,10 +1376,10 @@ static int decode_cabac_mb_chroma_pre_mode( H264Context *h) {
int ctx = 0;
/* No need to test for IS_INTRA4x4 and IS_INTRA16x16, as we set chroma_pred_mode_table to 0 */
- if( h->left_type[0] && h->chroma_pred_mode_table[mba_xy] != 0 )
+ if( h->left_type[LTOP] && h->chroma_pred_mode_table[mba_xy] != 0 )
ctx++;
- if( h->top_type && h->chroma_pred_mode_table[mbb_xy] != 0 )
+ if( h->top_type && h->chroma_pred_mode_table[mbb_xy] != 0 )
ctx++;
if( get_cabac_noinline( &h->cabac, &h->cabac_state[64+ctx] ) == 0 )
@@ -1565,7 +1565,12 @@ 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 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 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, int chroma422)
+{
static const int significant_coeff_flag_offset[2][14] = {
{ 105+0, 105+15, 105+29, 105+44, 105+47, 402, 484+0, 484+15, 484+29, 660, 528+0, 528+15, 528+29, 718 },
{ 277+0, 277+15, 277+29, 277+44, 277+47, 436, 776+0, 776+15, 776+29, 675, 820+0, 820+15, 820+29, 733 }
@@ -1587,12 +1592,16 @@ static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCT
9, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,13,13, 9,
9,10,10, 8,13,13, 9, 9,10,10,14,14,14,14,14 }
};
+ static const uint8_t sig_coeff_offset_dc[7] = { 0, 0, 1, 1, 2, 2, 2 };
/* node ctx: 0..3: abslevel1 (with abslevelgt1 == 0).
* 4..7: abslevelgt1 + 3 (and abslevel1 doesn't matter).
* map node ctx => cabac ctx for level=1 */
static const uint8_t coeff_abs_level1_ctx[8] = { 1, 2, 3, 4, 0, 0, 0, 0 };
/* map node ctx => cabac ctx for level>1 */
- static const uint8_t coeff_abs_levelgt1_ctx[8] = { 5, 5, 5, 5, 6, 7, 8, 9 };
+ static const uint8_t coeff_abs_levelgt1_ctx[2][8] = {
+ { 5, 5, 5, 5, 6, 7, 8, 9 },
+ { 5, 5, 5, 5, 6, 7, 8, 8 }, // 422/dc case
+ };
static const uint8_t coeff_abs_level_transition[2][8] = {
/* update node ctx after decoding a level=1 */
{ 1, 2, 3, 3, 4, 5, 6, 7 },
@@ -1647,16 +1656,24 @@ static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCT
index[coeff_count++] = last;\
}
const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD];
-#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS)
+#if ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS)
coeff_count= decode_significance_8x8_x86(CC, significant_coeff_ctx_base, index,
- last_coeff_ctx_base-significant_coeff_ctx_base, sig_off);
+ last_coeff_ctx_base, sig_off);
} else {
- coeff_count= decode_significance_x86(CC, max_coeff, significant_coeff_ctx_base, index,
- last_coeff_ctx_base-significant_coeff_ctx_base);
+ if (is_dc && chroma422) { // dc 422
+ DECODE_SIGNIFICANCE(7, sig_coeff_offset_dc[last], sig_coeff_offset_dc[last]);
+ } else {
+ coeff_count= decode_significance_x86(CC, max_coeff, significant_coeff_ctx_base, index,
+ last_coeff_ctx_base-significant_coeff_ctx_base);
+ }
#else
DECODE_SIGNIFICANCE( 63, sig_off[last], last_coeff_flag_offset_8x8[last] );
} else {
- DECODE_SIGNIFICANCE( max_coeff - 1, last, last );
+ if (is_dc && chroma422) { // dc 422
+ DECODE_SIGNIFICANCE(7, sig_coeff_offset_dc[last], sig_coeff_offset_dc[last]);
+ } else {
+ DECODE_SIGNIFICANCE(max_coeff - 1, last, last);
+ }
#endif
}
assert(coeff_count > 0);
@@ -1691,7 +1708,7 @@ static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCT
} \
} else { \
int coeff_abs = 2; \
- ctx = coeff_abs_levelgt1_ctx[node_ctx] + abs_level_m1_ctx_base; \
+ ctx = coeff_abs_levelgt1_ctx[is_dc && chroma422][node_ctx] + abs_level_m1_ctx_base; \
node_ctx = coeff_abs_level_transition[1][node_ctx]; \
\
while( coeff_abs < 15 && get_cabac( CC, ctx ) ) { \
@@ -1733,11 +1750,18 @@ static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCT
}
static void decode_cabac_residual_dc_internal( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, int max_coeff ) {
- decode_cabac_residual_internal(h, block, cat, n, scantable, NULL, max_coeff, 1);
+ decode_cabac_residual_internal(h, block, cat, n, scantable, NULL, max_coeff, 1, 0);
+}
+
+static void decode_cabac_residual_dc_internal_422(H264Context *h, DCTELEM *block,
+ int cat, int n, const uint8_t *scantable,
+ int max_coeff)
+{
+ decode_cabac_residual_internal(h, block, cat, n, scantable, NULL, max_coeff, 1, 1);
}
static void decode_cabac_residual_nondc_internal( 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);
+ decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 0, 0);
}
/* cat: 0-> DC 16x16 n = 0
@@ -1761,6 +1785,19 @@ static av_always_inline void decode_cabac_residual_dc( H264Context *h, DCTELEM *
decode_cabac_residual_dc_internal( h, block, cat, n, scantable, max_coeff );
}
+static av_always_inline void
+decode_cabac_residual_dc_422(H264Context *h, DCTELEM *block,
+ int cat, int n, const uint8_t *scantable,
+ int max_coeff)
+{
+ /* read coded block flag */
+ if (get_cabac(&h->cabac, &h->cabac_state[get_cabac_cbf_ctx(h, cat, n, max_coeff, 1)]) == 0) {
+ h->non_zero_count_cache[scan8[n]] = 0;
+ return;
+ }
+ decode_cabac_residual_dc_internal_422(h, block, cat, n, scantable, max_coeff);
+}
+
static av_always_inline void decode_cabac_residual_nondc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) {
/* read coded block flag */
if( (cat != 5 || CHROMA444) && get_cabac( &h->cabac, &h->cabac_state[get_cabac_cbf_ctx( h, cat, n, max_coeff, 0 ) ] ) == 0 ) {
@@ -1818,16 +1855,15 @@ static av_always_inline void decode_cabac_luma_residual( H264Context *h, const u
}
}
} else {
- uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8+16*p] ];
- nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0;
+ fill_rectangle(&h->non_zero_count_cache[scan8[4*i8x8+16*p]], 2, 2, 8, 0, 1);
}
}
}
}
/**
- * decodes a macroblock
- * @return 0 if OK, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed
+ * Decode a macroblock.
+ * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
*/
int ff_h264_decode_mb_cabac(H264Context *h) {
MpegEncContext * const s = &h->s;
@@ -1850,7 +1886,7 @@ int ff_h264_decode_mb_cabac(H264Context *h) {
/* read skip flags */
if( skip ) {
if( FRAME_MBAFF && (s->mb_y&1)==0 ){
- s->current_picture.mb_type[mb_xy] = MB_TYPE_SKIP;
+ s->current_picture.f.mb_type[mb_xy] = MB_TYPE_SKIP;
h->next_mb_skipped = decode_cabac_mb_skip( h, s->mb_x, s->mb_y+1 );
if(!h->next_mb_skipped)
h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
@@ -1880,7 +1916,7 @@ int ff_h264_decode_mb_cabac(H264Context *h) {
int ctx = 0;
assert(h->slice_type_nos == AV_PICTURE_TYPE_B);
- if( !IS_DIRECT( h->left_type[0]-1 ) )
+ if( !IS_DIRECT( h->left_type[LTOP]-1 ) )
ctx++;
if( !IS_DIRECT( h->top_type-1 ) )
ctx++;
@@ -1966,10 +2002,10 @@ decode_intra_mb:
h->cbp_table[mb_xy] = 0xf7ef;
h->chroma_pred_mode_table[mb_xy] = 0;
// In deblocking, the quantizer is 0
- s->current_picture.qscale_table[mb_xy]= 0;
+ s->current_picture.f.qscale_table[mb_xy] = 0;
// All coeffs are present
memset(h->non_zero_count[mb_xy], 16, 48);
- s->current_picture.mb_type[mb_xy]= mb_type;
+ s->current_picture.f.mb_type[mb_xy] = mb_type;
h->last_qscale_diff = 0;
return 0;
}
@@ -1999,7 +2035,7 @@ decode_intra_mb:
//av_log( s->avctx, AV_LOG_ERROR, "i4x4 pred=%d mode=%d\n", pred, h->intra4x4_pred_mode_cache[ scan8[i] ] );
}
}
- ff_h264_write_back_intra_pred_mode(h);
+ write_back_intra_pred_mode(h);
if( ff_h264_check_intra4x4_pred_mode(h) < 0 ) return -1;
} else {
h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode );
@@ -2248,24 +2284,25 @@ decode_intra_mb:
* the transform mode of the current macroblock there. */
if (CHROMA444 && IS_8x8DCT(mb_type)){
int i;
+ uint8_t *nnz_cache = h->non_zero_count_cache;
for (i = 0; i < 2; i++){
- if (h->left_type[i] && !IS_8x8DCT(h->left_type[i])){
- h->non_zero_count_cache[3+8* 1 + 2*8*i]=
- h->non_zero_count_cache[3+8* 2 + 2*8*i]=
- h->non_zero_count_cache[3+8* 6 + 2*8*i]=
- h->non_zero_count_cache[3+8* 7 + 2*8*i]=
- h->non_zero_count_cache[3+8*11 + 2*8*i]=
- h->non_zero_count_cache[3+8*12 + 2*8*i]= IS_INTRA(mb_type) ? 64 : 0;
+ if (h->left_type[LEFT(i)] && !IS_8x8DCT(h->left_type[LEFT(i)])){
+ nnz_cache[3+8* 1 + 2*8*i]=
+ nnz_cache[3+8* 2 + 2*8*i]=
+ nnz_cache[3+8* 6 + 2*8*i]=
+ nnz_cache[3+8* 7 + 2*8*i]=
+ nnz_cache[3+8*11 + 2*8*i]=
+ nnz_cache[3+8*12 + 2*8*i]= IS_INTRA(mb_type) ? 64 : 0;
}
}
if (h->top_type && !IS_8x8DCT(h->top_type)){
uint32_t top_empty = CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040;
- AV_WN32A(&h->non_zero_count_cache[4+8* 0], top_empty);
- AV_WN32A(&h->non_zero_count_cache[4+8* 5], top_empty);
- AV_WN32A(&h->non_zero_count_cache[4+8*10], top_empty);
+ AV_WN32A(&nnz_cache[4+8* 0], top_empty);
+ AV_WN32A(&nnz_cache[4+8* 5], top_empty);
+ AV_WN32A(&nnz_cache[4+8*10], top_empty);
}
}
- s->current_picture.mb_type[mb_xy]= mb_type;
+ s->current_picture.f.mb_type[mb_xy] = mb_type;
if( cbp || IS_INTRA16x16( mb_type ) ) {
const uint8_t *scan, *scan8x8;
@@ -2313,7 +2350,36 @@ decode_intra_mb:
if(CHROMA444){
decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 1);
decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 2);
- } else {
+ } else if (CHROMA422) {
+ if( cbp&0x30 ){
+ int c;
+ for( c = 0; c < 2; c++ ) {
+ //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c );
+ decode_cabac_residual_dc_422(h, h->mb + ((256 + 16*16*c) << pixel_shift), 3,
+ CHROMA_DC_BLOCK_INDEX + c,
+ chroma422_dc_scan, 8);
+ }
+ }
+
+ if( cbp&0x20 ) {
+ int c, i, i8x8;
+ for( c = 0; c < 2; c++ ) {
+ DCTELEM *mb = h->mb + (16*(16 + 16*c) << pixel_shift);
+ qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[c]];
+ for (i8x8 = 0; i8x8 < 2; i8x8++) {
+ for (i = 0; i < 4; i++) {
+ const int index = 16 + 16 * c + 8*i8x8 + i;
+ //av_log(s->avctx, AV_LOG_ERROR, "INTRA C%d-AC %d\n",c, index - 16);
+ decode_cabac_residual_nondc(h, mb, 4, index, scan + 1, qmul, 15);
+ mb += 16<<pixel_shift;
+ }
+ }
+ }
+ } else {
+ fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
+ fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
+ }
+ } else /* yuv420 */ {
if( cbp&0x30 ){
int c;
for( c = 0; c < 2; c++ ) {
@@ -2344,7 +2410,7 @@ decode_intra_mb:
h->last_qscale_diff = 0;
}
- s->current_picture.qscale_table[mb_xy]= s->qscale;
+ s->current_picture.f.qscale_table[mb_xy] = s->qscale;
write_back_non_zero_count(h);
if(MB_MBAFF){
diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c
index 497166b..db74602 100644
--- a/libavcodec/h264_cavlc.c
+++ b/libavcodec/h264_cavlc.c
@@ -62,6 +62,30 @@ static const uint8_t chroma_dc_coeff_token_bits[4*5]={
2, 3, 2, 0,
};
+static const uint8_t chroma422_dc_coeff_token_len[4*9]={
+ 1, 0, 0, 0,
+ 7, 2, 0, 0,
+ 7, 7, 3, 0,
+ 9, 7, 7, 5,
+ 9, 9, 7, 6,
+ 10, 10, 9, 7,
+ 11, 11, 10, 7,
+ 12, 12, 11, 10,
+ 13, 12, 12, 11,
+};
+
+static const uint8_t chroma422_dc_coeff_token_bits[4*9]={
+ 1, 0, 0, 0,
+ 15, 1, 0, 0,
+ 14, 13, 1, 0,
+ 7, 12, 11, 1,
+ 6, 5, 10, 1,
+ 7, 6, 4, 9,
+ 7, 6, 5, 8,
+ 7, 6, 5, 4,
+ 7, 5, 4, 4,
+};
+
static const uint8_t coeff_token_len[4][4*17]={
{
1, 0, 0, 0,
@@ -172,6 +196,26 @@ static const uint8_t chroma_dc_total_zeros_bits[3][4]= {
{ 1, 0, 0, 0,},
};
+static const uint8_t chroma422_dc_total_zeros_len[7][8]= {
+ { 1, 3, 3, 4, 4, 4, 5, 5 },
+ { 3, 2, 3, 3, 3, 3, 3 },
+ { 3, 3, 2, 2, 3, 3 },
+ { 3, 2, 2, 2, 3 },
+ { 2, 2, 2, 2 },
+ { 2, 2, 1 },
+ { 1, 1 },
+};
+
+static const uint8_t chroma422_dc_total_zeros_bits[7][8]= {
+ { 1, 2, 3, 2, 3, 1, 1, 0 },
+ { 0, 1, 1, 4, 5, 6, 7 },
+ { 0, 1, 1, 2, 6, 7 },
+ { 6, 0, 1, 2, 7 },
+ { 0, 1, 2, 3 },
+ { 0, 1, 1 },
+ { 0, 1 },
+};
+
static const uint8_t run_len[7][16]={
{1,1},
{1,2,2},
@@ -200,6 +244,10 @@ static VLC chroma_dc_coeff_token_vlc;
static VLC_TYPE chroma_dc_coeff_token_vlc_table[256][2];
static const int chroma_dc_coeff_token_vlc_table_size = 256;
+static VLC chroma422_dc_coeff_token_vlc;
+static VLC_TYPE chroma422_dc_coeff_token_vlc_table[8192][2];
+static const int chroma422_dc_coeff_token_vlc_table_size = 8192;
+
static VLC total_zeros_vlc[15];
static VLC_TYPE total_zeros_vlc_tables[15][512][2];
static const int total_zeros_vlc_tables_size = 512;
@@ -208,6 +256,10 @@ static VLC chroma_dc_total_zeros_vlc[3];
static VLC_TYPE chroma_dc_total_zeros_vlc_tables[3][8][2];
static const int chroma_dc_total_zeros_vlc_tables_size = 8;
+static VLC chroma422_dc_total_zeros_vlc[7];
+static VLC_TYPE chroma422_dc_total_zeros_vlc_tables[7][32][2];
+static const int chroma422_dc_total_zeros_vlc_tables_size = 32;
+
static VLC run_vlc[6];
static VLC_TYPE run_vlc_tables[6][8][2];
static const int run_vlc_tables_size = 8;
@@ -219,9 +271,17 @@ static const int run7_vlc_table_size = 96;
#define LEVEL_TAB_BITS 8
static int8_t cavlc_level_tab[7][1<<LEVEL_TAB_BITS][2];
+#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8
+#define CHROMA422_DC_COEFF_TOKEN_VLC_BITS 13
+#define COEFF_TOKEN_VLC_BITS 8
+#define TOTAL_ZEROS_VLC_BITS 9
+#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3
+#define CHROMA422_DC_TOTAL_ZEROS_VLC_BITS 5
+#define RUN_VLC_BITS 3
+#define RUN7_VLC_BITS 6
/**
- * gets the predicted number of non-zero coefficients.
+ * Get the predicted number of non-zero coefficients.
* @param n block index
*/
static inline int pred_non_zero_count(H264Context *h, int n){
@@ -238,17 +298,18 @@ static inline int pred_non_zero_count(H264Context *h, int n){
}
static av_cold void init_cavlc_level_tab(void){
- int suffix_length, mask;
+ int suffix_length;
unsigned int i;
for(suffix_length=0; suffix_length<7; suffix_length++){
for(i=0; i<(1<<LEVEL_TAB_BITS); i++){
int prefix= LEVEL_TAB_BITS - av_log2(2*i);
- int level_code= (prefix<<suffix_length) + (i>>(LEVEL_TAB_BITS-prefix-1-suffix_length)) - (1<<suffix_length);
- mask= -(level_code&1);
- level_code= (((2+level_code)>>1) ^ mask) - mask;
if(prefix + 1 + suffix_length <= LEVEL_TAB_BITS){
+ int level_code = (prefix << suffix_length) +
+ (i >> (av_log2(i) - suffix_length)) - (1 << suffix_length);
+ int mask = -(level_code&1);
+ level_code = (((2 + level_code) >> 1) ^ mask) - mask;
cavlc_level_tab[suffix_length][i][0]= level_code;
cavlc_level_tab[suffix_length][i][1]= prefix + 1 + suffix_length;
}else if(prefix + 1 <= LEVEL_TAB_BITS){
@@ -277,6 +338,13 @@ av_cold void ff_h264_decode_init_vlc(void){
&chroma_dc_coeff_token_bits[0], 1, 1,
INIT_VLC_USE_NEW_STATIC);
+ chroma422_dc_coeff_token_vlc.table = chroma422_dc_coeff_token_vlc_table;
+ chroma422_dc_coeff_token_vlc.table_allocated = chroma422_dc_coeff_token_vlc_table_size;
+ init_vlc(&chroma422_dc_coeff_token_vlc, CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 4*9,
+ &chroma422_dc_coeff_token_len [0], 1, 1,
+ &chroma422_dc_coeff_token_bits[0], 1, 1,
+ INIT_VLC_USE_NEW_STATIC);
+
offset = 0;
for(i=0; i<4; i++){
coeff_token_vlc[i].table = coeff_token_vlc_tables+offset;
@@ -303,6 +371,17 @@ av_cold void ff_h264_decode_init_vlc(void){
&chroma_dc_total_zeros_bits[i][0], 1, 1,
INIT_VLC_USE_NEW_STATIC);
}
+
+ for(i=0; i<7; i++){
+ chroma422_dc_total_zeros_vlc[i].table = chroma422_dc_total_zeros_vlc_tables[i];
+ chroma422_dc_total_zeros_vlc[i].table_allocated = chroma422_dc_total_zeros_vlc_tables_size;
+ init_vlc(&chroma422_dc_total_zeros_vlc[i],
+ CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 8,
+ &chroma422_dc_total_zeros_len [i][0], 1, 1,
+ &chroma422_dc_total_zeros_bits[i][0], 1, 1,
+ INIT_VLC_USE_NEW_STATIC);
+ }
+
for(i=0; i<15; i++){
total_zeros_vlc[i].table = total_zeros_vlc_tables[i];
total_zeros_vlc[i].table_allocated = total_zeros_vlc_tables_size;
@@ -357,7 +436,7 @@ static inline int get_level_prefix(GetBitContext *gb){
}
/**
- * decodes a residual block.
+ * Decode a residual block.
* @param n block index
* @param scantable scantable
* @param max_coeff number of coefficients in the block
@@ -372,7 +451,10 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
//FIXME put trailing_onex into the context
if(max_coeff <= 8){
- coeff_token= get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1);
+ if (max_coeff == 4)
+ coeff_token = get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1);
+ else
+ coeff_token = get_vlc2(gb, chroma422_dc_coeff_token_vlc.table, CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 1);
total_coeff= coeff_token>>2;
}else{
if(n >= LUMA_DC_BLOCK_INDEX){
@@ -482,11 +564,16 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
if(total_coeff == max_coeff)
zeros_left=0;
else{
- /* FIXME: we don't actually support 4:2:2 yet. */
- if(max_coeff <= 8)
- zeros_left= get_vlc2(gb, (chroma_dc_total_zeros_vlc-1)[ total_coeff ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1);
- else
+ if (max_coeff <= 8) {
+ if (max_coeff == 4)
+ zeros_left = get_vlc2(gb, (chroma_dc_total_zeros_vlc-1)[total_coeff].table,
+ CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1);
+ else
+ zeros_left = get_vlc2(gb, (chroma422_dc_total_zeros_vlc-1)[total_coeff].table,
+ CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 1);
+ } else {
zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1);
+ }
}
#define STORE_BLOCK(type) \
@@ -689,11 +776,11 @@ decode_intra_mb:
}
// In deblocking, the quantizer is 0
- s->current_picture.qscale_table[mb_xy]= 0;
+ s->current_picture.f.qscale_table[mb_xy] = 0;
// All coeffs are present
memset(h->non_zero_count[mb_xy], 16, 48);
- s->current_picture.mb_type[mb_xy]= mb_type;
+ s->current_picture.f.mb_type[mb_xy] = mb_type;
return 0;
}
@@ -731,7 +818,7 @@ decode_intra_mb:
else
h->intra4x4_pred_mode_cache[ scan8[i] ] = mode;
}
- ff_h264_write_back_intra_pred_mode(h);
+ write_back_intra_pred_mode(h);
if( ff_h264_check_intra4x4_pred_mode(h) < 0)
return -1;
}else{
@@ -990,10 +1077,10 @@ decode_intra_mb:
}
h->cbp=
h->cbp_table[mb_xy]= cbp;
- s->current_picture.mb_type[mb_xy]= mb_type;
+ s->current_picture.f.mb_type[mb_xy] = mb_type;
if(cbp || IS_INTRA16x16(mb_type)){
- int i4x4, chroma_idx;
+ int i4x4, i8x8, chroma_idx;
int dquant;
int ret;
GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr;
@@ -1035,7 +1122,34 @@ decode_intra_mb:
if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ){
return -1;
}
- } else {
+ } else if (CHROMA422) {
+ if(cbp&0x30){
+ for(chroma_idx=0; chroma_idx<2; chroma_idx++)
+ if (decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift),
+ CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma422_dc_scan,
+ NULL, 8) < 0) {
+ return -1;
+ }
+ }
+
+ if(cbp&0x20){
+ for(chroma_idx=0; chroma_idx<2; chroma_idx++){
+ const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];
+ DCTELEM *mb = h->mb + (16*(16 + 16*chroma_idx) << pixel_shift);
+ for (i8x8 = 0; i8x8 < 2; i8x8++) {
+ for (i4x4 = 0; i4x4 < 4; i4x4++) {
+ const int index = 16 + 16*chroma_idx + 8*i8x8 + i4x4;
+ if (decode_residual(h, gb, mb, index, scan + 1, qmul, 15) < 0)
+ return -1;
+ mb += 16 << pixel_shift;
+ }
+ }
+ }
+ }else{
+ fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
+ fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
+ }
+ } else /* yuv420 */ {
if(cbp&0x30){
for(chroma_idx=0; chroma_idx<2; chroma_idx++)
if( decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift), CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma_dc_scan, NULL, 4) < 0){
@@ -1063,7 +1177,7 @@ decode_intra_mb:
fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
}
- s->current_picture.qscale_table[mb_xy]= s->qscale;
+ s->current_picture.f.qscale_table[mb_xy] = s->qscale;
write_back_non_zero_count(h);
if(MB_MBAFF){
diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c
index a7e6853..a953728 100644
--- a/libavcodec/h264_direct.c
+++ b/libavcodec/h264_direct.c
@@ -87,7 +87,7 @@ static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field,
poc= (poc&~3) + rfield + 1;
for(j=start; j<end; j++){
- if(4*h->ref_list[0][j].frame_num + (h->ref_list[0][j].reference&3) == poc){
+ if (4 * h->ref_list[0][j].frame_num + (h->ref_list[0][j].f.reference & 3) == poc) {
int cur_ref= mbafi ? (j-16)^field : j;
map[list][2*old_ref + (rfield^field) + 16] = cur_ref;
if(rfield == field || !interl)
@@ -105,12 +105,12 @@ void ff_h264_direct_ref_list_init(H264Context * const h){
Picture * const cur = s->current_picture_ptr;
int list, j, field;
int sidx= (s->picture_structure&1)^1;
- int ref1sidx= (ref1->reference&1)^1;
+ int ref1sidx = (ref1->f.reference&1)^1;
for(list=0; list<2; list++){
cur->ref_count[sidx][list] = h->ref_count[list];
for(j=0; j<h->ref_count[list]; j++)
- cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3);
+ cur->ref_poc[sidx][list][j] = 4 * h->ref_list[list][j].frame_num + (h->ref_list[list][j].f.reference & 3);
}
if(s->picture_structure == PICT_FRAME){
@@ -126,11 +126,11 @@ void ff_h264_direct_ref_list_init(H264Context * const h){
int *col_poc = h->ref_list[1]->field_poc;
h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc));
ref1sidx=sidx= h->col_parity;
- }else if(!(s->picture_structure & h->ref_list[1][0].reference) && !h->ref_list[1][0].mbaff){ // FL -> FL & differ parity
- h->col_fieldoff= 2*(h->ref_list[1][0].reference) - 3;
+ } else if (!(s->picture_structure & h->ref_list[1][0].f.reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity
+ h->col_fieldoff = 2 * h->ref_list[1][0].f.reference - 3;
}
- if(cur->pict_type != AV_PICTURE_TYPE_B || h->direct_spatial_mv_pred)
+ if (cur->f.pict_type != AV_PICTURE_TYPE_B || h->direct_spatial_mv_pred)
return;
for(list=0; list<2; list++){
@@ -143,11 +143,11 @@ void ff_h264_direct_ref_list_init(H264Context * const h){
static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y)
{
- int ref_field = ref->reference - 1;
+ int ref_field = ref->f.reference - 1;
int ref_field_picture = ref->field_picture;
int ref_height = 16*h->s.mb_height >> ref_field_picture;
- if(!HAVE_PTHREADS || !(h->s.avctx->active_thread_type&FF_THREAD_FRAME))
+ if(!HAVE_THREADS || !(h->s.avctx->active_thread_type&FF_THREAD_FRAME))
return;
//FIXME it can be safe to access mb stuff
@@ -172,7 +172,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
int mv[2];
int list;
- assert(h->ref_list[1][0].reference&3);
+ assert(h->ref_list[1][0].f.reference & 3);
await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type));
@@ -234,8 +234,8 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
return;
}
- if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL
- if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL/FL
+ if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
+ if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL
mb_y = (s->mb_y&~1) + h->col_parity;
mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
b8_stride = 0;
@@ -248,8 +248,8 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR
mb_y = s->mb_y&~1;
mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
- mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy];
- mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride];
+ mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy];
+ mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride];
b8_stride = 2+4*s->mb_stride;
b4_stride *= 6;
@@ -264,7 +264,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
}else{ // AFR/FR -> AFR/FR
single_col:
mb_type_col[0] =
- mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy];
+ mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy];
sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){
@@ -284,10 +284,10 @@ single_col:
await_reference_mb_row(h, &h->ref_list[1][0], mb_y);
- l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
- l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]];
- l1ref0 = &h->ref_list[1][0].ref_index [0][4*mb_xy];
- l1ref1 = &h->ref_list[1][0].ref_index [1][4*mb_xy];
+ l1mv0 = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
+ l1mv1 = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]];
+ l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy];
+ l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy];
if(!b8_stride){
if(s->mb_y&1){
l1ref0 += 2;
@@ -416,12 +416,12 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
unsigned int sub_mb_type;
int i8, i4;
- assert(h->ref_list[1][0].reference&3);
+ assert(h->ref_list[1][0].f.reference & 3);
await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type));
- if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL
- if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL/FL
+ if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
+ if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL
mb_y = (s->mb_y&~1) + h->col_parity;
mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
b8_stride = 0;
@@ -434,8 +434,8 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR
mb_y = s->mb_y&~1;
mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
- mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy];
- mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride];
+ mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy];
+ mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride];
b8_stride = 2+4*s->mb_stride;
b4_stride *= 6;
@@ -451,7 +451,7 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
}else{ // AFR/FR -> AFR/FR
single_col:
mb_type_col[0] =
- mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy];
+ mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy];
sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){
@@ -471,10 +471,10 @@ single_col:
await_reference_mb_row(h, &h->ref_list[1][0], mb_y);
- l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
- l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]];
- l1ref0 = &h->ref_list[1][0].ref_index [0][4*mb_xy];
- l1ref1 = &h->ref_list[1][0].ref_index [1][4*mb_xy];
+ l1mv0 = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
+ l1mv1 = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]];
+ l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy];
+ l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy];
if(!b8_stride){
if(s->mb_y&1){
l1ref0 += 2;
diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c
index 86ecb27..64b07e9 100644
--- a/libavcodec/h264_loopfilter.c
+++ b/libavcodec/h264_loopfilter.c
@@ -100,14 +100,14 @@ static const uint8_t tc0_table[52*3][4] = {
{-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
};
-static void av_always_inline filter_mb_edgev( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h) {
- const int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
- const unsigned int index_a = qp - qp_bd_offset + h->slice_alpha_c0_offset;
+/* intra: 0 if this loopfilter call is guaranteed to be inter (bS < 4), 1 if it might be intra (bS == 4) */
+static void av_always_inline filter_mb_edgev( uint8_t *pix, int stride, const int16_t bS[4], unsigned int qp, int a, int b, H264Context *h, int intra ) {
+ const unsigned int index_a = qp + a;
const int alpha = alpha_table[index_a];
- const int beta = beta_table[qp - qp_bd_offset + h->slice_beta_offset];
+ const int beta = beta_table[qp + b];
if (alpha ==0 || beta == 0) return;
- if( bS[0] < 4 ) {
+ if( bS[0] < 4 || !intra ) {
int8_t tc[4];
tc[0] = tc0_table[index_a][bS[0]];
tc[1] = tc0_table[index_a][bS[1]];
@@ -118,14 +118,13 @@ static void av_always_inline filter_mb_edgev( uint8_t *pix, int stride, int16_t
h->h264dsp.h264_h_loop_filter_luma_intra(pix, stride, alpha, beta);
}
}
-static void av_always_inline filter_mb_edgecv( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h ) {
- const int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
- const unsigned int index_a = qp - qp_bd_offset + h->slice_alpha_c0_offset;
+static void av_always_inline filter_mb_edgecv( uint8_t *pix, int stride, const int16_t bS[4], unsigned int qp, int a, int b, H264Context *h, int intra ) {
+ const unsigned int index_a = qp + a;
const int alpha = alpha_table[index_a];
- const int beta = beta_table[qp - qp_bd_offset + h->slice_beta_offset];
+ const int beta = beta_table[qp + b];
if (alpha ==0 || beta == 0) return;
- if( bS[0] < 4 ) {
+ if( bS[0] < 4 || !intra ) {
int8_t tc[4];
tc[0] = tc0_table[index_a][bS[0]]+1;
tc[1] = tc0_table[index_a][bS[1]]+1;
@@ -137,14 +136,13 @@ static void av_always_inline filter_mb_edgecv( uint8_t *pix, int stride, int16_t
}
}
-static void filter_mb_mbaff_edgev( H264Context *h, uint8_t *pix, int stride, int16_t bS[7], int bsi, int qp ) {
- const int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
- int index_a = qp - qp_bd_offset + h->slice_alpha_c0_offset;
- int alpha = alpha_table[index_a];
- int beta = beta_table[qp - qp_bd_offset + h->slice_beta_offset];
+static void av_always_inline filter_mb_mbaff_edgev( H264Context *h, uint8_t *pix, int stride, const int16_t bS[7], int bsi, int qp, int a, int b, int intra ) {
+ const unsigned int index_a = qp + a;
+ const int alpha = alpha_table[index_a];
+ const int beta = beta_table[qp + b];
if (alpha ==0 || beta == 0) return;
- if( bS[0] < 4 ) {
+ if( bS[0] < 4 || !intra ) {
int8_t tc[4];
tc[0] = tc0_table[index_a][bS[0*bsi]];
tc[1] = tc0_table[index_a][bS[1*bsi]];
@@ -155,14 +153,13 @@ static void filter_mb_mbaff_edgev( H264Context *h, uint8_t *pix, int stride, int
h->h264dsp.h264_h_loop_filter_luma_mbaff_intra(pix, stride, alpha, beta);
}
}
-static void filter_mb_mbaff_edgecv( H264Context *h, uint8_t *pix, int stride, int16_t bS[7], int bsi, int qp ) {
- const int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
- int index_a = qp - qp_bd_offset + h->slice_alpha_c0_offset;
- int alpha = alpha_table[index_a];
- int beta = beta_table[qp - qp_bd_offset + h->slice_beta_offset];
+static void av_always_inline filter_mb_mbaff_edgecv( H264Context *h, uint8_t *pix, int stride, const int16_t bS[7], int bsi, int qp, int a, int b, int intra ) {
+ const unsigned int index_a = qp + a;
+ const int alpha = alpha_table[index_a];
+ const int beta = beta_table[qp + b];
if (alpha ==0 || beta == 0) return;
- if( bS[0] < 4 ) {
+ if( bS[0] < 4 || !intra ) {
int8_t tc[4];
tc[0] = tc0_table[index_a][bS[0*bsi]] + 1;
tc[1] = tc0_table[index_a][bS[1*bsi]] + 1;
@@ -174,14 +171,13 @@ static void filter_mb_mbaff_edgecv( H264Context *h, uint8_t *pix, int stride, in
}
}
-static void av_always_inline filter_mb_edgeh( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h ) {
- const int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
- const unsigned int index_a = qp - qp_bd_offset + h->slice_alpha_c0_offset;
+static void av_always_inline filter_mb_edgeh( uint8_t *pix, int stride, const int16_t bS[4], unsigned int qp, int a, int b, H264Context *h, int intra ) {
+ const unsigned int index_a = qp + a;
const int alpha = alpha_table[index_a];
- const int beta = beta_table[qp - qp_bd_offset + h->slice_beta_offset];
+ const int beta = beta_table[qp + b];
if (alpha ==0 || beta == 0) return;
- if( bS[0] < 4 ) {
+ if( bS[0] < 4 || !intra ) {
int8_t tc[4];
tc[0] = tc0_table[index_a][bS[0]];
tc[1] = tc0_table[index_a][bS[1]];
@@ -193,14 +189,13 @@ static void av_always_inline filter_mb_edgeh( uint8_t *pix, int stride, int16_t
}
}
-static void av_always_inline filter_mb_edgech( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h ) {
- const int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
- const unsigned int index_a = qp - qp_bd_offset + h->slice_alpha_c0_offset;
+static void av_always_inline filter_mb_edgech( uint8_t *pix, int stride, const int16_t bS[4], unsigned int qp, int a, int b, H264Context *h, int intra ) {
+ const unsigned int index_a = qp + a;
const int alpha = alpha_table[index_a];
- const int beta = beta_table[qp - qp_bd_offset + h->slice_beta_offset];
+ const int beta = beta_table[qp + b];
if (alpha ==0 || beta == 0) return;
- if( bS[0] < 4 ) {
+ if( bS[0] < 4 || !intra ) {
int8_t tc[4];
tc[0] = tc0_table[index_a][bS[0]]+1;
tc[1] = tc0_table[index_a][bS[1]]+1;
@@ -212,74 +207,126 @@ static void av_always_inline filter_mb_edgech( uint8_t *pix, int stride, int16_t
}
}
-void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
+static void av_always_inline h264_filter_mb_fast_internal( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,
+ unsigned int linesize, unsigned int uvlinesize, int pixel_shift) {
MpegEncContext * const s = &h->s;
- int mb_xy;
- int mb_type, left_type;
- int qp, qp0, qp1, qpc, qpc0, qpc1, qp_thresh;
int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
-
- mb_xy = h->mb_xy;
-
- if(!h->top_type || !h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff || CHROMA444) {
- ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);
- return;
- }
- assert(!FRAME_MBAFF);
- left_type= h->left_type[0];
-
- mb_type = s->current_picture.mb_type[mb_xy];
- qp = s->current_picture.qscale_table[mb_xy];
- qp0 = s->current_picture.qscale_table[mb_xy-1];
- qp1 = s->current_picture.qscale_table[h->top_mb_xy];
- qpc = get_chroma_qp( h, 0, qp );
- qpc0 = get_chroma_qp( h, 0, qp0 );
- qpc1 = get_chroma_qp( h, 0, qp1 );
+ int chroma444 = CHROMA444;
+ int chroma422 = CHROMA422;
+
+ int mb_xy = h->mb_xy;
+ int left_type= h->left_type[LTOP];
+ int top_type= h->top_type;
+
+ int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
+ int a = h->slice_alpha_c0_offset - qp_bd_offset;
+ int b = h->slice_beta_offset - qp_bd_offset;
+
+ int mb_type = s->current_picture.f.mb_type[mb_xy];
+ int qp = s->current_picture.f.qscale_table[mb_xy];
+ int qp0 = s->current_picture.f.qscale_table[mb_xy - 1];
+ int qp1 = s->current_picture.f.qscale_table[h->top_mb_xy];
+ int qpc = get_chroma_qp( h, 0, qp );
+ int qpc0 = get_chroma_qp( h, 0, qp0 );
+ int qpc1 = get_chroma_qp( h, 0, qp1 );
qp0 = (qp + qp0 + 1) >> 1;
qp1 = (qp + qp1 + 1) >> 1;
qpc0 = (qpc + qpc0 + 1) >> 1;
qpc1 = (qpc + qpc1 + 1) >> 1;
- qp_thresh = 15+52 - h->slice_alpha_c0_offset;
- if(qp <= qp_thresh && qp0 <= qp_thresh && qp1 <= qp_thresh &&
- qpc <= qp_thresh && qpc0 <= qp_thresh && qpc1 <= qp_thresh)
- return;
if( IS_INTRA(mb_type) ) {
- int16_t bS4[4] = {4,4,4,4};
- int16_t bS3[4] = {3,3,3,3};
- int16_t *bSH = FIELD_PICTURE ? bS3 : bS4;
+ static const int16_t bS4[4] = {4,4,4,4};
+ static const int16_t bS3[4] = {3,3,3,3};
+ const int16_t *bSH = FIELD_PICTURE ? bS3 : bS4;
if(left_type)
- filter_mb_edgev( &img_y[4*0], linesize, bS4, qp0, h);
+ filter_mb_edgev( &img_y[4*0<<pixel_shift], linesize, bS4, qp0, a, b, h, 1);
if( IS_8x8DCT(mb_type) ) {
- filter_mb_edgev( &img_y[4*2], linesize, bS3, qp, h);
- filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, h);
- filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, h);
+ filter_mb_edgev( &img_y[4*2<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
+ if(top_type){
+ filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, a, b, h, 1);
+ }
+ filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, a, b, h, 0);
} else {
- filter_mb_edgev( &img_y[4*1], linesize, bS3, qp, h);
- filter_mb_edgev( &img_y[4*2], linesize, bS3, qp, h);
- filter_mb_edgev( &img_y[4*3], linesize, bS3, qp, h);
- filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, h);
- filter_mb_edgeh( &img_y[4*1*linesize], linesize, bS3, qp, h);
- filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, h);
- filter_mb_edgeh( &img_y[4*3*linesize], linesize, bS3, qp, h);
+ filter_mb_edgev( &img_y[4*1<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
+ filter_mb_edgev( &img_y[4*2<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
+ filter_mb_edgev( &img_y[4*3<<pixel_shift], linesize, bS3, qp, a, b, h, 0);
+ if(top_type){
+ filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, a, b, h, 1);
+ }
+ filter_mb_edgeh( &img_y[4*1*linesize], linesize, bS3, qp, a, b, h, 0);
+ filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, a, b, h, 0);
+ filter_mb_edgeh( &img_y[4*3*linesize], linesize, bS3, qp, a, b, h, 0);
}
if(chroma){
- if(left_type){
- filter_mb_edgecv( &img_cb[2*0], uvlinesize, bS4, qpc0, h);
- filter_mb_edgecv( &img_cr[2*0], uvlinesize, bS4, qpc0, h);
+ if(chroma444){
+ if(left_type){
+ filter_mb_edgev( &img_cb[4*0<<pixel_shift], linesize, bS4, qpc0, a, b, h, 1);
+ filter_mb_edgev( &img_cr[4*0<<pixel_shift], linesize, bS4, qpc0, a, b, h, 1);
+ }
+ if( IS_8x8DCT(mb_type) ) {
+ filter_mb_edgev( &img_cb[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgev( &img_cr[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
+ if(top_type){
+ filter_mb_edgeh( &img_cb[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1 );
+ filter_mb_edgeh( &img_cr[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1 );
+ }
+ filter_mb_edgeh( &img_cb[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgeh( &img_cr[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
+ } else {
+ filter_mb_edgev( &img_cb[4*1<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgev( &img_cr[4*1<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgev( &img_cb[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgev( &img_cr[4*2<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgev( &img_cb[4*3<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgev( &img_cr[4*3<<pixel_shift], linesize, bS3, qpc, a, b, h, 0);
+ if(top_type){
+ filter_mb_edgeh( &img_cb[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1);
+ filter_mb_edgeh( &img_cr[4*0*linesize], linesize, bSH, qpc1, a, b, h, 1);
+ }
+ filter_mb_edgeh( &img_cb[4*1*linesize], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgeh( &img_cr[4*1*linesize], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgeh( &img_cb[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgeh( &img_cr[4*2*linesize], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgeh( &img_cb[4*3*linesize], linesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgeh( &img_cr[4*3*linesize], linesize, bS3, qpc, a, b, h, 0);
+ }
+ }else if(chroma422){
+ if(left_type){
+ filter_mb_edgecv(&img_cb[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
+ filter_mb_edgecv(&img_cr[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
+ }
+ filter_mb_edgecv(&img_cb[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgecv(&img_cr[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
+ if(top_type){
+ filter_mb_edgech(&img_cb[4*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
+ filter_mb_edgech(&img_cr[4*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
+ }
+ filter_mb_edgech(&img_cb[4*1*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgech(&img_cr[4*1*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgech(&img_cb[4*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgech(&img_cr[4*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgech(&img_cb[4*3*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgech(&img_cr[4*3*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
+ }else{
+ if(left_type){
+ filter_mb_edgecv( &img_cb[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
+ filter_mb_edgecv( &img_cr[2*0<<pixel_shift], uvlinesize, bS4, qpc0, a, b, h, 1);
+ }
+ filter_mb_edgecv( &img_cb[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgecv( &img_cr[2*2<<pixel_shift], uvlinesize, bS3, qpc, a, b, h, 0);
+ if(top_type){
+ filter_mb_edgech( &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
+ filter_mb_edgech( &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1, a, b, h, 1);
+ }
+ filter_mb_edgech( &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
+ filter_mb_edgech( &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc, a, b, h, 0);
}
- filter_mb_edgecv( &img_cb[2*2], uvlinesize, bS3, qpc, h);
- filter_mb_edgecv( &img_cr[2*2], uvlinesize, bS3, qpc, h);
- filter_mb_edgech( &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1, h);
- filter_mb_edgech( &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc, h);
- filter_mb_edgech( &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1, h);
- filter_mb_edgech( &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc, h);
}
return;
} else {
LOCAL_ALIGNED_8(int16_t, bS, [2], [4][4]);
int edges;
- if( IS_8x8DCT(mb_type) && (h->cbp&7) == 7 ) {
+ if( IS_8x8DCT(mb_type) && (h->cbp&7) == 7 && !chroma444 ) {
edges = 4;
AV_WN64A(bS[0][0], 0x0002000200020002ULL);
AV_WN64A(bS[0][2], 0x0002000200020002ULL);
@@ -287,7 +334,7 @@ void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y,
AV_WN64A(bS[1][2], 0x0002000200020002ULL);
} else {
int mask_edge1 = (3*(((5*mb_type)>>5)&1)) | (mb_type>>4); //(mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : (mb_type & MB_TYPE_16x8) ? 1 : 0;
- int mask_edge0 = 3*((mask_edge1>>1) & ((5*left_type)>>5)&1); // (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) && (h->left_type[0] & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : 0;
+ int mask_edge0 = 3*((mask_edge1>>1) & ((5*left_type)>>5)&1); // (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) && (h->left_type[LTOP] & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : 0;
int step = 1+(mb_type>>24); //IS_8x8DCT(mb_type) ? 2 : 1;
edges = 4 - 3*((mb_type>>3) & !(h->cbp & 15)); //(mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4;
h->h264dsp.h264_loop_filter_strength( bS, h->non_zero_count_cache, h->ref_cache, h->mv_cache,
@@ -295,38 +342,64 @@ void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y,
}
if( IS_INTRA(left_type) )
AV_WN64A(bS[0][0], 0x0004000400040004ULL);
- if( IS_INTRA(h->top_type) )
+ if( IS_INTRA(top_type) )
AV_WN64A(bS[1][0], FIELD_PICTURE ? 0x0003000300030003ULL : 0x0004000400040004ULL);
-#define FILTER(hv,dir,edge)\
+#define FILTER(hv,dir,edge,intra)\
if(AV_RN64A(bS[dir][edge])) { \
- filter_mb_edge##hv( &img_y[4*edge*(dir?linesize:1)], linesize, bS[dir][edge], edge ? qp : qp##dir, h );\
- if(chroma && !(edge&1)) {\
- filter_mb_edgec##hv( &img_cb[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, h );\
- filter_mb_edgec##hv( &img_cr[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, h );\
+ filter_mb_edge##hv( &img_y[4*edge*(dir?linesize:1<<pixel_shift)], linesize, bS[dir][edge], edge ? qp : qp##dir, a, b, h, intra );\
+ if(chroma){\
+ if(chroma444){\
+ filter_mb_edge##hv( &img_cb[4*edge*(dir?linesize:1<<pixel_shift)], linesize, bS[dir][edge], edge ? qpc : qpc##dir, a, b, h, intra );\
+ filter_mb_edge##hv( &img_cr[4*edge*(dir?linesize:1<<pixel_shift)], linesize, bS[dir][edge], edge ? qpc : qpc##dir, a, b, h, intra );\
+ } else if(!(edge&1)) {\
+ filter_mb_edgec##hv( &img_cb[2*edge*(dir?uvlinesize:1<<pixel_shift)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, a, b, h, intra );\
+ filter_mb_edgec##hv( &img_cr[2*edge*(dir?uvlinesize:1<<pixel_shift)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, a, b, h, intra );\
+ }\
}\
}
if(left_type)
- FILTER(v,0,0);
+ FILTER(v,0,0,1);
if( edges == 1 ) {
- FILTER(h,1,0);
+ if(top_type)
+ FILTER(h,1,0,1);
} else if( IS_8x8DCT(mb_type) ) {
- FILTER(v,0,2);
- FILTER(h,1,0);
- FILTER(h,1,2);
+ FILTER(v,0,2,0);
+ if(top_type)
+ FILTER(h,1,0,1);
+ FILTER(h,1,2,0);
} else {
- FILTER(v,0,1);
- FILTER(v,0,2);
- FILTER(v,0,3);
- FILTER(h,1,0);
- FILTER(h,1,1);
- FILTER(h,1,2);
- FILTER(h,1,3);
+ FILTER(v,0,1,0);
+ FILTER(v,0,2,0);
+ FILTER(v,0,3,0);
+ if(top_type)
+ FILTER(h,1,0,1);
+ FILTER(h,1,1,0);
+ FILTER(h,1,2,0);
+ FILTER(h,1,3,0);
}
#undef FILTER
}
}
+void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
+ assert(!FRAME_MBAFF);
+ if(!h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff) {
+ ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);
+ return;
+ }
+
+#if CONFIG_SMALL
+ h264_filter_mb_fast_internal(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, h->pixel_shift);
+#else
+ if(h->pixel_shift){
+ h264_filter_mb_fast_internal(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, 1);
+ }else{
+ h264_filter_mb_fast_internal(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, 0);
+ }
+#endif
+}
+
static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){
int v;
@@ -356,12 +429,14 @@ static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){
return v;
}
-static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int chroma, int chroma444, int dir) {
+static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int a, int b, int chroma, int dir) {
MpegEncContext * const s = &h->s;
int edge;
int chroma_qp_avg[2];
+ int chroma444 = CHROMA444;
+ int chroma422 = CHROMA422;
const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy;
- const int mbm_type = dir == 0 ? h->left_type[0] : h->top_type;
+ const int mbm_type = dir == 0 ? h->left_type[LTOP] : h->top_type;
// how often to recheck mv-based bS when iterating between edges
static const uint8_t mask_edge_tab[2][8]={{0,3,3,3,1,1,1,1},
@@ -389,10 +464,10 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
for(j=0; j<2; j++, mbn_xy += s->mb_stride){
DECLARE_ALIGNED(8, int16_t, bS)[4];
int qp;
- if( IS_INTRA(mb_type|s->current_picture.mb_type[mbn_xy]) ) {
+ if (IS_INTRA(mb_type | s->current_picture.f.mb_type[mbn_xy])) {
AV_WN64A(bS, 0x0003000300030003ULL);
} else {
- if(!CABAC && IS_8x8DCT(s->current_picture.mb_type[mbn_xy])){
+ if (!CABAC && IS_8x8DCT(s->current_picture.f.mb_type[mbn_xy])) {
bS[0]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+0]);
bS[1]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+1]);
bS[2]= 1+((h->cbp_table[mbn_xy] & 0x8000)||h->non_zero_count_cache[scan8[0]+2]);
@@ -407,19 +482,19 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
}
// Do not use s->qscale as luma quantizer because it has not the same
// value in IPCM macroblocks.
- qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1;
+ qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbn_xy] + 1) >> 1;
tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
- filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, h );
- chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1;
- chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1;
+ filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, a, b, h, 0 );
+ chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbn_xy]) + 1) >> 1;
+ chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbn_xy]) + 1) >> 1;
if (chroma) {
if (chroma444) {
- filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], h);
- filter_mb_edgeh (&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], h);
+ filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
+ filter_mb_edgeh (&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], a, b, h, 0);
} else {
- filter_mb_edgech(&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], h);
- filter_mb_edgech(&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], h);
+ filter_mb_edgech(&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
+ filter_mb_edgech(&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], a, b, h, 0);
}
}
}
@@ -472,32 +547,32 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
// Do not use s->qscale as luma quantizer because it has not the same
// value in IPCM macroblocks.
if(bS[0]+bS[1]+bS[2]+bS[3]){
- qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbm_xy] + 1 ) >> 1;
+ qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbm_xy] + 1) >> 1;
//tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], s->current_picture.qscale_table[mbn_xy]);
tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
//{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
- chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
- chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
+ chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
+ chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
if( dir == 0 ) {
- filter_mb_edgev( &img_y[0], linesize, bS, qp, h );
+ filter_mb_edgev( &img_y[0], linesize, bS, qp, a, b, h, 1 );
if (chroma) {
if (chroma444) {
- filter_mb_edgev ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h);
- filter_mb_edgev ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h);
+ filter_mb_edgev ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
+ filter_mb_edgev ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
} else {
- filter_mb_edgecv( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h);
- filter_mb_edgecv( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h);
+ filter_mb_edgecv( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
+ filter_mb_edgecv( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
}
}
} else {
- filter_mb_edgeh( &img_y[0], linesize, bS, qp, h );
+ filter_mb_edgeh( &img_y[0], linesize, bS, qp, a, b, h, 1 );
if (chroma) {
if (chroma444) {
- filter_mb_edgeh ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h);
- filter_mb_edgeh ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h);
+ filter_mb_edgeh ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
+ filter_mb_edgeh ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
} else {
- filter_mb_edgech( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h);
- filter_mb_edgech( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h);
+ filter_mb_edgech( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], a, b, h, 1);
+ filter_mb_edgech( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], a, b, h, 1);
}
}
}
@@ -509,8 +584,9 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
for( edge = 1; edge < edges; edge++ ) {
DECLARE_ALIGNED(8, int16_t, bS)[4];
int qp;
+ const int deblock_edge = !IS_8x8DCT(mb_type & (edge<<24)); // (edge&1) && IS_8x8DCT(mb_type)
- if( IS_8x8DCT(mb_type & (edge<<24)) ) // (edge&1) && IS_8x8DCT(mb_type)
+ if (!deblock_edge && (!chroma422 || dir == 0))
continue;
if( IS_INTRA(mb_type)) {
@@ -556,30 +632,39 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
/* Filter edge */
// Do not use s->qscale as luma quantizer because it has not the same
// value in IPCM macroblocks.
- qp = s->current_picture.qscale_table[mb_xy];
+ qp = s->current_picture.f.qscale_table[mb_xy];
//tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], s->current_picture.qscale_table[mbn_xy]);
tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
//{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
if( dir == 0 ) {
- filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, h );
+ filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 );
if (chroma) {
if (chroma444) {
- filter_mb_edgev ( &img_cb[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], h);
- filter_mb_edgev ( &img_cr[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], h);
+ filter_mb_edgev ( &img_cb[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
+ filter_mb_edgev ( &img_cr[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
} else if( (edge&1) == 0 ) {
- filter_mb_edgecv( &img_cb[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], h);
- filter_mb_edgecv( &img_cr[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], h);
+ filter_mb_edgecv( &img_cb[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
+ filter_mb_edgecv( &img_cr[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
}
}
} else {
- filter_mb_edgeh( &img_y[4*edge*linesize], linesize, bS, qp, h );
- if (chroma) {
- if (chroma444) {
- filter_mb_edgeh ( &img_cb[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], h);
- filter_mb_edgeh ( &img_cr[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], h);
- } else if( (edge&1) == 0 ) {
- filter_mb_edgech( &img_cb[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], h);
- filter_mb_edgech( &img_cr[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], h);
+ if (chroma422) {
+ if (deblock_edge)
+ filter_mb_edgeh(&img_y[4*edge*linesize], linesize, bS, qp, a, b, h, 0);
+ if (chroma) {
+ filter_mb_edgech(&img_cb[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
+ filter_mb_edgech(&img_cr[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
+ }
+ } else {
+ filter_mb_edgeh(&img_y[4*edge*linesize], linesize, bS, qp, a, b, h, 0);
+ if (chroma) {
+ if (chroma444) {
+ filter_mb_edgeh (&img_cb[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
+ filter_mb_edgeh (&img_cr[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
+ } else if ((edge&1) == 0) {
+ filter_mb_edgech(&img_cb[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], a, b, h, 0);
+ filter_mb_edgech(&img_cr[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], a, b, h, 0);
+ }
}
}
}
@@ -589,17 +674,20 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
MpegEncContext * const s = &h->s;
const int mb_xy= mb_x + mb_y*s->mb_stride;
- const int mb_type = s->current_picture.mb_type[mb_xy];
+ const int mb_type = s->current_picture.f.mb_type[mb_xy];
const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
int first_vertical_edge_done = 0;
av_unused int dir;
int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
+ int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
+ int a = h->slice_alpha_c0_offset - qp_bd_offset;
+ int b = h->slice_beta_offset - qp_bd_offset;
if (FRAME_MBAFF
// and current and left pair do not have the same interlaced type
- && IS_INTERLACED(mb_type^h->left_type[0])
+ && IS_INTERLACED(mb_type^h->left_type[LTOP])
// and left mb is in available to us
- && h->left_type[0]) {
+ && h->left_type[LTOP]) {
/* First vertical edge is different in MBAFF frames
* There are 8 different bS to compute and 2 different Qp
*/
@@ -627,8 +715,8 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
const uint8_t *off= offset[MB_FIELD][mb_y&1];
for( i = 0; i < 8; i++ ) {
int j= MB_FIELD ? i>>2 : i&1;
- int mbn_xy = h->left_mb_xy[j];
- int mbn_type= h->left_type[j];
+ int mbn_xy = h->left_mb_xy[LEFT(j)];
+ int mbn_type= h->left_type[LEFT(j)];
if( IS_INTRA( mbn_type ) )
bS[i] = 4;
@@ -642,9 +730,9 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
}
}
- mb_qp = s->current_picture.qscale_table[mb_xy];
- mbn0_qp = s->current_picture.qscale_table[h->left_mb_xy[0]];
- mbn1_qp = s->current_picture.qscale_table[h->left_mb_xy[1]];
+ mb_qp = s->current_picture.f.qscale_table[mb_xy];
+ mbn0_qp = s->current_picture.f.qscale_table[h->left_mb_xy[0]];
+ mbn1_qp = s->current_picture.f.qscale_table[h->left_mb_xy[1]];
qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1;
bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) +
get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1;
@@ -660,35 +748,40 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
tprintf(s->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize);
{ int i; for (i = 0; i < 8; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
if(MB_FIELD){
- filter_mb_mbaff_edgev ( h, img_y , linesize, bS , 1, qp [0] );
- filter_mb_mbaff_edgev ( h, img_y + 8* linesize, linesize, bS+4, 1, qp [1] );
+ filter_mb_mbaff_edgev ( h, img_y , linesize, bS , 1, qp [0], a, b, 1 );
+ filter_mb_mbaff_edgev ( h, img_y + 8* linesize, linesize, bS+4, 1, qp [1], a, b, 1 );
if (chroma){
if (CHROMA444) {
- filter_mb_mbaff_edgev ( h, img_cb, uvlinesize, bS , 1, bqp[0] );
- filter_mb_mbaff_edgev ( h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1] );
- filter_mb_mbaff_edgev ( h, img_cr, uvlinesize, bS , 1, rqp[0] );
- filter_mb_mbaff_edgev ( h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1] );
+ filter_mb_mbaff_edgev ( h, img_cb, uvlinesize, bS , 1, bqp[0], a, b, 1 );
+ filter_mb_mbaff_edgev ( h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1 );
+ filter_mb_mbaff_edgev ( h, img_cr, uvlinesize, bS , 1, rqp[0], a, b, 1 );
+ filter_mb_mbaff_edgev ( h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1 );
+ } else if (CHROMA422) {
+ filter_mb_mbaff_edgecv(h, img_cb, uvlinesize, bS , 1, bqp[0], a, b, 1);
+ filter_mb_mbaff_edgecv(h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1);
+ filter_mb_mbaff_edgecv(h, img_cr, uvlinesize, bS , 1, rqp[0], a, b, 1);
+ filter_mb_mbaff_edgecv(h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1);
}else{
- filter_mb_mbaff_edgecv( h, img_cb, uvlinesize, bS , 1, bqp[0] );
- filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1] );
- filter_mb_mbaff_edgecv( h, img_cr, uvlinesize, bS , 1, rqp[0] );
- filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1] );
+ filter_mb_mbaff_edgecv( h, img_cb, uvlinesize, bS , 1, bqp[0], a, b, 1 );
+ filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1 );
+ filter_mb_mbaff_edgecv( h, img_cr, uvlinesize, bS , 1, rqp[0], a, b, 1 );
+ filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1 );
}
}
}else{
- filter_mb_mbaff_edgev ( h, img_y , 2* linesize, bS , 2, qp [0] );
- filter_mb_mbaff_edgev ( h, img_y + linesize, 2* linesize, bS+1, 2, qp [1] );
+ filter_mb_mbaff_edgev ( h, img_y , 2* linesize, bS , 2, qp [0], a, b, 1 );
+ filter_mb_mbaff_edgev ( h, img_y + linesize, 2* linesize, bS+1, 2, qp [1], a, b, 1 );
if (chroma){
if (CHROMA444) {
- filter_mb_mbaff_edgev ( h, img_cb, 2*uvlinesize, bS , 2, bqp[0] );
- filter_mb_mbaff_edgev ( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1] );
- filter_mb_mbaff_edgev ( h, img_cr, 2*uvlinesize, bS , 2, rqp[0] );
- filter_mb_mbaff_edgev ( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1] );
+ filter_mb_mbaff_edgev ( h, img_cb, 2*uvlinesize, bS , 2, bqp[0], a, b, 1 );
+ filter_mb_mbaff_edgev ( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1], a, b, 1 );
+ filter_mb_mbaff_edgev ( h, img_cr, 2*uvlinesize, bS , 2, rqp[0], a, b, 1 );
+ filter_mb_mbaff_edgev ( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1], a, b, 1 );
}else{
- filter_mb_mbaff_edgecv( h, img_cb, 2*uvlinesize, bS , 2, bqp[0] );
- filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1] );
- filter_mb_mbaff_edgecv( h, img_cr, 2*uvlinesize, bS , 2, rqp[0] );
- filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1] );
+ filter_mb_mbaff_edgecv( h, img_cb, 2*uvlinesize, bS , 2, bqp[0], a, b, 1 );
+ filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1], a, b, 1 );
+ filter_mb_mbaff_edgecv( h, img_cr, 2*uvlinesize, bS , 2, rqp[0], a, b, 1 );
+ filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1], a, b, 1 );
}
}
}
@@ -696,9 +789,9 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
#if CONFIG_SMALL
for( dir = 0; dir < 2; dir++ )
- filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, dir ? 0 : first_vertical_edge_done, chroma, CHROMA444, dir);
+ filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, dir ? 0 : first_vertical_edge_done, a, b, chroma, dir);
#else
- filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, chroma, CHROMA444, 0);
- filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, chroma, CHROMA444, 1);
+ filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, a, b, chroma, 0);
+ filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, a, b, chroma, 1);
#endif
}
diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h
index 1359072..2bd4458 100644
--- a/libavcodec/h264_mvpred.h
+++ b/libavcodec/h264_mvpred.h
@@ -35,7 +35,7 @@
//#undef NDEBUG
#include <assert.h>
-static inline int fetch_diagonal_mv(H264Context *h, const int16_t **C, int i, int list, int part_width){
+static av_always_inline int fetch_diagonal_mv(H264Context *h, const int16_t **C, int i, int list, int part_width){
const int topright_ref= h->ref_cache[list][ i - 8 + part_width ];
MpegEncContext *s = &h->s;
@@ -48,15 +48,15 @@ static inline int fetch_diagonal_mv(H264Context *h, const int16_t **C, int i, in
const int mb_type = mb_types[xy+(y4>>2)*s->mb_stride];\
if(!USES_LIST(mb_type,list))\
return LIST_NOT_USED;\
- mv = s->current_picture_ptr->motion_val[list][h->mb2b_xy[xy]+3 + y4*h->b_stride];\
+ mv = s->current_picture_ptr->f.motion_val[list][h->mb2b_xy[xy] + 3 + y4*h->b_stride];\
h->mv_cache[list][scan8[0]-2][0] = mv[0];\
h->mv_cache[list][scan8[0]-2][1] = mv[1] MV_OP;\
- return s->current_picture_ptr->ref_index[list][4*xy+1 + (y4&~1)] REF_OP;
+ return s->current_picture_ptr->f.ref_index[list][4*xy + 1 + (y4 & ~1)] REF_OP;
if(topright_ref == PART_NOT_AVAILABLE
&& i >= scan8[0]+8 && (i&7)==4
&& h->ref_cache[list][scan8[0]-1] != PART_NOT_AVAILABLE){
- const uint32_t *mb_types = s->current_picture_ptr->mb_type;
+ const uint32_t *mb_types = s->current_picture_ptr->f.mb_type;
const int16_t *mv;
AV_ZERO32(h->mv_cache[list][scan8[0]-2]);
*C = h->mv_cache[list][scan8[0]-2];
@@ -64,7 +64,6 @@ static inline int fetch_diagonal_mv(H264Context *h, const int16_t **C, int i, in
if(!MB_FIELD
&& IS_INTERLACED(h->left_type[0])){
SET_DIAG_MV(*2, >>1, h->left_mb_xy[0]+s->mb_stride, (s->mb_y&1)*2+(i>>5));
- assert(h->left_mb_xy[0] == h->left_mb_xy[1]);
}
if(MB_FIELD
&& !IS_INTERLACED(h->left_type[0])){
@@ -87,13 +86,13 @@ static inline int fetch_diagonal_mv(H264Context *h, const int16_t **C, int i, in
}
/**
- * gets the predicted MV.
+ * Get the predicted MV.
* @param n the block index
* @param part_width the width of the partition (4, 8,16) -> (1, 2, 4)
* @param mx the x component of the predicted motion vector
* @param my the y component of the predicted motion vector
*/
-static inline void pred_motion(H264Context * const h, int n, int part_width, int list, int ref, int * const mx, int * const my){
+static av_always_inline void pred_motion(H264Context * const h, int n, int part_width, int list, int ref, int * const mx, int * const my){
const int index8= scan8[n];
const int top_ref= h->ref_cache[list][ index8 - 8 ];
const int left_ref= h->ref_cache[list][ index8 - 1 ];
@@ -143,12 +142,12 @@ static inline void pred_motion(H264Context * const h, int n, int part_width, int
}
/**
- * gets the directionally predicted 16x8 MV.
+ * Get the directionally predicted 16x8 MV.
* @param n the block index
* @param mx the x component of the predicted motion vector
* @param my the y component of the predicted motion vector
*/
-static inline void pred_16x8_motion(H264Context * const h, int n, int list, int ref, int * const mx, int * const my){
+static av_always_inline void pred_16x8_motion(H264Context * const h, int n, int list, int ref, int * const mx, int * const my){
if(n==0){
const int top_ref= h->ref_cache[list][ scan8[0] - 8 ];
const int16_t * const B= h->mv_cache[list][ scan8[0] - 8 ];
@@ -178,12 +177,12 @@ static inline void pred_16x8_motion(H264Context * const h, int n, int list, int
}
/**
- * gets the directionally predicted 8x16 MV.
+ * Get the directionally predicted 8x16 MV.
* @param n the block index
* @param mx the x component of the predicted motion vector
* @param my the y component of the predicted motion vector
*/
-static inline void pred_8x16_motion(H264Context * const h, int n, int list, int ref, int * const mx, int * const my){
+static av_always_inline void pred_8x16_motion(H264Context * const h, int n, int list, int ref, int * const mx, int * const my){
if(n==0){
const int left_ref= h->ref_cache[list][ scan8[0] - 1 ];
const int16_t * const A= h->mv_cache[list][ scan8[0] - 1 ];
@@ -214,23 +213,580 @@ static inline void pred_8x16_motion(H264Context * const h, int n, int list, int
pred_motion(h, n, 2, list, ref, mx, my);
}
-static inline void pred_pskip_motion(H264Context * const h, int * const mx, int * const my){
- const int top_ref = h->ref_cache[0][ scan8[0] - 8 ];
- const int left_ref= h->ref_cache[0][ scan8[0] - 1 ];
+#define FIX_MV_MBAFF(type, refn, mvn, idx)\
+ if(FRAME_MBAFF){\
+ if(MB_FIELD){\
+ if(!IS_INTERLACED(type)){\
+ refn <<= 1;\
+ AV_COPY32(mvbuf[idx], mvn);\
+ mvbuf[idx][1] /= 2;\
+ mvn = mvbuf[idx];\
+ }\
+ }else{\
+ if(IS_INTERLACED(type)){\
+ refn >>= 1;\
+ AV_COPY32(mvbuf[idx], mvn);\
+ mvbuf[idx][1] <<= 1;\
+ mvn = mvbuf[idx];\
+ }\
+ }\
+ }
- tprintf(h->s.avctx, "pred_pskip: (%d) (%d) at %2d %2d\n", top_ref, left_ref, h->s.mb_x, h->s.mb_y);
+static av_always_inline void pred_pskip_motion(H264Context * const h){
+ DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = {0};
+ DECLARE_ALIGNED(4, int16_t, mvbuf)[3][2];
+ MpegEncContext * const s = &h->s;
+ int8_t *ref = s->current_picture.f.ref_index[0];
+ int16_t (*mv)[2] = s->current_picture.f.motion_val[0];
+ int top_ref, left_ref, diagonal_ref, match_count, mx, my;
+ const int16_t *A, *B, *C;
+ int b_stride = h->b_stride;
+
+ fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
+
+ /* To avoid doing an entire fill_decode_caches, we inline the relevant parts here.
+ * FIXME: this is a partial duplicate of the logic in fill_decode_caches, but it's
+ * faster this way. Is there a way to avoid this duplication?
+ */
+ if(USES_LIST(h->left_type[LTOP], 0)){
+ left_ref = ref[4*h->left_mb_xy[LTOP] + 1 + (h->left_block[0]&~1)];
+ A = mv[h->mb2b_xy[h->left_mb_xy[LTOP]] + 3 + b_stride*h->left_block[0]];
+ FIX_MV_MBAFF(h->left_type[LTOP], left_ref, A, 0);
+ if(!(left_ref | AV_RN32A(A))){
+ goto zeromv;
+ }
+ }else if(h->left_type[LTOP]){
+ left_ref = LIST_NOT_USED;
+ A = zeromv;
+ }else{
+ goto zeromv;
+ }
- if(top_ref == PART_NOT_AVAILABLE || left_ref == PART_NOT_AVAILABLE
- || !( top_ref | AV_RN32A(h->mv_cache[0][ scan8[0] - 8 ]))
- || !(left_ref | AV_RN32A(h->mv_cache[0][ scan8[0] - 1 ]))){
+ if(USES_LIST(h->top_type, 0)){
+ top_ref = ref[4*h->top_mb_xy + 2];
+ B = mv[h->mb2b_xy[h->top_mb_xy] + 3*b_stride];
+ FIX_MV_MBAFF(h->top_type, top_ref, B, 1);
+ if(!(top_ref | AV_RN32A(B))){
+ goto zeromv;
+ }
+ }else if(h->top_type){
+ top_ref = LIST_NOT_USED;
+ B = zeromv;
+ }else{
+ goto zeromv;
+ }
- *mx = *my = 0;
- return;
+ tprintf(h->s.avctx, "pred_pskip: (%d) (%d) at %2d %2d\n", top_ref, left_ref, h->s.mb_x, h->s.mb_y);
+
+ if(USES_LIST(h->topright_type, 0)){
+ diagonal_ref = ref[4*h->topright_mb_xy + 2];
+ C = mv[h->mb2b_xy[h->topright_mb_xy] + 3*b_stride];
+ FIX_MV_MBAFF(h->topright_type, diagonal_ref, C, 2);
+ }else if(h->topright_type){
+ diagonal_ref = LIST_NOT_USED;
+ C = zeromv;
+ }else{
+ if(USES_LIST(h->topleft_type, 0)){
+ diagonal_ref = ref[4*h->topleft_mb_xy + 1 + (h->topleft_partition & 2)];
+ C = mv[h->mb2b_xy[h->topleft_mb_xy] + 3 + b_stride + (h->topleft_partition & 2*b_stride)];
+ FIX_MV_MBAFF(h->topleft_type, diagonal_ref, C, 2);
+ }else if(h->topleft_type){
+ diagonal_ref = LIST_NOT_USED;
+ C = zeromv;
+ }else{
+ diagonal_ref = PART_NOT_AVAILABLE;
+ C = zeromv;
+ }
}
- pred_motion(h, 0, 4, 0, 0, mx, my);
+ match_count= !diagonal_ref + !top_ref + !left_ref;
+ tprintf(h->s.avctx, "pred_pskip_motion match_count=%d\n", match_count);
+ if(match_count > 1){
+ mx = mid_pred(A[0], B[0], C[0]);
+ my = mid_pred(A[1], B[1], C[1]);
+ }else if(match_count==1){
+ if(!left_ref){
+ mx = A[0];
+ my = A[1];
+ }else if(!top_ref){
+ mx = B[0];
+ my = B[1];
+ }else{
+ mx = C[0];
+ my = C[1];
+ }
+ }else{
+ mx = mid_pred(A[0], B[0], C[0]);
+ my = mid_pred(A[1], B[1], C[1]);
+ }
+ fill_rectangle( h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx,my), 4);
+ return;
+zeromv:
+ fill_rectangle( h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
return;
}
+static void fill_decode_neighbors(H264Context *h, int mb_type){
+ MpegEncContext * const s = &h->s;
+ const int mb_xy= h->mb_xy;
+ int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
+ static const uint8_t left_block_options[4][32]={
+ {0,1,2,3,7,10,8,11,3+0*4, 3+1*4, 3+2*4, 3+3*4, 1+4*4, 1+8*4, 1+5*4, 1+9*4},
+ {2,2,3,3,8,11,8,11,3+2*4, 3+2*4, 3+3*4, 3+3*4, 1+5*4, 1+9*4, 1+5*4, 1+9*4},
+ {0,0,1,1,7,10,7,10,3+0*4, 3+0*4, 3+1*4, 3+1*4, 1+4*4, 1+8*4, 1+4*4, 1+8*4},
+ {0,2,0,2,7,10,7,10,3+0*4, 3+2*4, 3+0*4, 3+2*4, 1+4*4, 1+8*4, 1+4*4, 1+8*4}
+ };
+
+ h->topleft_partition= -1;
+
+ top_xy = mb_xy - (s->mb_stride << MB_FIELD);
+
+ /* Wow, what a mess, why didn't they simplify the interlacing & intra
+ * stuff, I can't imagine that these complex rules are worth it. */
+
+ topleft_xy = top_xy - 1;
+ topright_xy= top_xy + 1;
+ left_xy[LBOT] = left_xy[LTOP] = mb_xy-1;
+ h->left_block = left_block_options[0];
+ if(FRAME_MBAFF){
+ const int left_mb_field_flag = IS_INTERLACED(s->current_picture.f.mb_type[mb_xy - 1]);
+ const int curr_mb_field_flag = IS_INTERLACED(mb_type);
+ if(s->mb_y&1){
+ if (left_mb_field_flag != curr_mb_field_flag) {
+ left_xy[LBOT] = left_xy[LTOP] = mb_xy - s->mb_stride - 1;
+ if (curr_mb_field_flag) {
+ left_xy[LBOT] += s->mb_stride;
+ h->left_block = left_block_options[3];
+ } else {
+ topleft_xy += s->mb_stride;
+ // take top left mv from the middle of the mb, as opposed to all other modes which use the bottom right partition
+ h->topleft_partition = 0;
+ h->left_block = left_block_options[1];
+ }
+ }
+ }else{
+ if(curr_mb_field_flag){
+ topleft_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy - 1] >> 7) & 1) - 1);
+ topright_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy + 1] >> 7) & 1) - 1);
+ top_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy ] >> 7) & 1) - 1);
+ }
+ if (left_mb_field_flag != curr_mb_field_flag) {
+ if (curr_mb_field_flag) {
+ left_xy[LBOT] += s->mb_stride;
+ h->left_block = left_block_options[3];
+ } else {
+ h->left_block = left_block_options[2];
+ }
+ }
+ }
+ }
+
+ h->topleft_mb_xy = topleft_xy;
+ h->top_mb_xy = top_xy;
+ h->topright_mb_xy= topright_xy;
+ h->left_mb_xy[LTOP] = left_xy[LTOP];
+ h->left_mb_xy[LBOT] = left_xy[LBOT];
+ //FIXME do we need all in the context?
+
+ h->topleft_type = s->current_picture.f.mb_type[topleft_xy];
+ h->top_type = s->current_picture.f.mb_type[top_xy];
+ h->topright_type = s->current_picture.f.mb_type[topright_xy];
+ h->left_type[LTOP] = s->current_picture.f.mb_type[left_xy[LTOP]];
+ h->left_type[LBOT] = s->current_picture.f.mb_type[left_xy[LBOT]];
+
+ if(FMO){
+ if(h->slice_table[topleft_xy ] != h->slice_num) h->topleft_type = 0;
+ if(h->slice_table[top_xy ] != h->slice_num) h->top_type = 0;
+ if(h->slice_table[left_xy[LTOP] ] != h->slice_num) h->left_type[LTOP] = h->left_type[LBOT] = 0;
+ }else{
+ if(h->slice_table[topleft_xy ] != h->slice_num){
+ h->topleft_type = 0;
+ if(h->slice_table[top_xy ] != h->slice_num) h->top_type = 0;
+ if(h->slice_table[left_xy[LTOP] ] != h->slice_num) h->left_type[LTOP] = h->left_type[LBOT] = 0;
+ }
+ }
+ if(h->slice_table[topright_xy] != h->slice_num) h->topright_type= 0;
+}
+
+static void fill_decode_caches(H264Context *h, int mb_type){
+ MpegEncContext * const s = &h->s;
+ int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
+ int topleft_type, top_type, topright_type, left_type[LEFT_MBS];
+ const uint8_t * left_block= h->left_block;
+ int i;
+ uint8_t *nnz;
+ uint8_t *nnz_cache;
+
+ topleft_xy = h->topleft_mb_xy;
+ top_xy = h->top_mb_xy;
+ topright_xy = h->topright_mb_xy;
+ left_xy[LTOP] = h->left_mb_xy[LTOP];
+ left_xy[LBOT] = h->left_mb_xy[LBOT];
+ topleft_type = h->topleft_type;
+ top_type = h->top_type;
+ topright_type = h->topright_type;
+ left_type[LTOP]= h->left_type[LTOP];
+ left_type[LBOT]= h->left_type[LBOT];
+
+ if(!IS_SKIP(mb_type)){
+ if(IS_INTRA(mb_type)){
+ int type_mask= h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1;
+ h->topleft_samples_available=
+ h->top_samples_available=
+ h->left_samples_available= 0xFFFF;
+ h->topright_samples_available= 0xEEEA;
+
+ if(!(top_type & type_mask)){
+ h->topleft_samples_available= 0xB3FF;
+ h->top_samples_available= 0x33FF;
+ h->topright_samples_available= 0x26EA;
+ }
+ if(IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[LTOP])){
+ if(IS_INTERLACED(mb_type)){
+ if(!(left_type[LTOP] & type_mask)){
+ h->topleft_samples_available&= 0xDFFF;
+ h->left_samples_available&= 0x5FFF;
+ }
+ if(!(left_type[LBOT] & type_mask)){
+ h->topleft_samples_available&= 0xFF5F;
+ h->left_samples_available&= 0xFF5F;
+ }
+ }else{
+ int left_typei = s->current_picture.f.mb_type[left_xy[LTOP] + s->mb_stride];
+
+ assert(left_xy[LTOP] == left_xy[LBOT]);
+ if(!((left_typei & type_mask) && (left_type[LTOP] & type_mask))){
+ h->topleft_samples_available&= 0xDF5F;
+ h->left_samples_available&= 0x5F5F;
+ }
+ }
+ }else{
+ if(!(left_type[LTOP] & type_mask)){
+ h->topleft_samples_available&= 0xDF5F;
+ h->left_samples_available&= 0x5F5F;
+ }
+ }
+
+ if(!(topleft_type & type_mask))
+ h->topleft_samples_available&= 0x7FFF;
+
+ if(!(topright_type & type_mask))
+ h->topright_samples_available&= 0xFBFF;
+
+ if(IS_INTRA4x4(mb_type)){
+ if(IS_INTRA4x4(top_type)){
+ AV_COPY32(h->intra4x4_pred_mode_cache+4+8*0, h->intra4x4_pred_mode + h->mb2br_xy[top_xy]);
+ }else{
+ h->intra4x4_pred_mode_cache[4+8*0]=
+ h->intra4x4_pred_mode_cache[5+8*0]=
+ h->intra4x4_pred_mode_cache[6+8*0]=
+ h->intra4x4_pred_mode_cache[7+8*0]= 2 - 3*!(top_type & type_mask);
+ }
+ for(i=0; i<2; i++){
+ if(IS_INTRA4x4(left_type[LEFT(i)])){
+ int8_t *mode= h->intra4x4_pred_mode + h->mb2br_xy[left_xy[LEFT(i)]];
+ h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= mode[6-left_block[0+2*i]];
+ h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= mode[6-left_block[1+2*i]];
+ }else{
+ h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]=
+ h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= 2 - 3*!(left_type[LEFT(i)] & type_mask);
+ }
+ }
+ }
+ }
+
+
+/*
+0 . T T. T T T T
+1 L . .L . . . .
+2 L . .L . . . .
+3 . T TL . . . .
+4 L . .L . . . .
+5 L . .. . . . .
+*/
+//FIXME constraint_intra_pred & partitioning & nnz (let us hope this is just a typo in the spec)
+ nnz_cache = h->non_zero_count_cache;
+ if(top_type){
+ nnz = h->non_zero_count[top_xy];
+ AV_COPY32(&nnz_cache[4+8* 0], &nnz[4*3]);
+ if(!s->chroma_y_shift){
+ AV_COPY32(&nnz_cache[4+8* 5], &nnz[4* 7]);
+ AV_COPY32(&nnz_cache[4+8*10], &nnz[4*11]);
+ }else{
+ AV_COPY32(&nnz_cache[4+8* 5], &nnz[4* 5]);
+ AV_COPY32(&nnz_cache[4+8*10], &nnz[4* 9]);
+ }
+ }else{
+ uint32_t top_empty = CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040;
+ AV_WN32A(&nnz_cache[4+8* 0], top_empty);
+ AV_WN32A(&nnz_cache[4+8* 5], top_empty);
+ AV_WN32A(&nnz_cache[4+8*10], top_empty);
+ }
+
+ for (i=0; i<2; i++) {
+ if(left_type[LEFT(i)]){
+ nnz = h->non_zero_count[left_xy[LEFT(i)]];
+ nnz_cache[3+8* 1 + 2*8*i]= nnz[left_block[8+0+2*i]];
+ nnz_cache[3+8* 2 + 2*8*i]= nnz[left_block[8+1+2*i]];
+ if(CHROMA444){
+ nnz_cache[3+8* 6 + 2*8*i]= nnz[left_block[8+0+2*i]+4*4];
+ nnz_cache[3+8* 7 + 2*8*i]= nnz[left_block[8+1+2*i]+4*4];
+ nnz_cache[3+8*11 + 2*8*i]= nnz[left_block[8+0+2*i]+8*4];
+ nnz_cache[3+8*12 + 2*8*i]= nnz[left_block[8+1+2*i]+8*4];
+ }else if(CHROMA422) {
+ nnz_cache[3+8* 6 + 2*8*i]= nnz[left_block[8+0+2*i]-2+4*4];
+ nnz_cache[3+8* 7 + 2*8*i]= nnz[left_block[8+1+2*i]-2+4*4];
+ nnz_cache[3+8*11 + 2*8*i]= nnz[left_block[8+0+2*i]-2+8*4];
+ nnz_cache[3+8*12 + 2*8*i]= nnz[left_block[8+1+2*i]-2+8*4];
+ }else{
+ nnz_cache[3+8* 6 + 8*i]= nnz[left_block[8+4+2*i]];
+ nnz_cache[3+8*11 + 8*i]= nnz[left_block[8+5+2*i]];
+ }
+ }else{
+ nnz_cache[3+8* 1 + 2*8*i]=
+ nnz_cache[3+8* 2 + 2*8*i]=
+ nnz_cache[3+8* 6 + 2*8*i]=
+ nnz_cache[3+8* 7 + 2*8*i]=
+ nnz_cache[3+8*11 + 2*8*i]=
+ nnz_cache[3+8*12 + 2*8*i]= CABAC && !IS_INTRA(mb_type) ? 0 : 64;
+ }
+ }
+
+ if( CABAC ) {
+ // top_cbp
+ if(top_type) {
+ h->top_cbp = h->cbp_table[top_xy];
+ } else {
+ h->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
+ }
+ // left_cbp
+ if (left_type[LTOP]) {
+ h->left_cbp = (h->cbp_table[left_xy[LTOP]] & 0x7F0)
+ | ((h->cbp_table[left_xy[LTOP]]>>(left_block[0]&(~1)))&2)
+ | (((h->cbp_table[left_xy[LBOT]]>>(left_block[2]&(~1)))&2) << 2);
+ } else {
+ h->left_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
+ }
+ }
+ }
+
+ if(IS_INTER(mb_type) || (IS_DIRECT(mb_type) && h->direct_spatial_mv_pred)){
+ int list;
+ int b_stride = h->b_stride;
+ for(list=0; list<h->list_count; list++){
+ int8_t *ref_cache = &h->ref_cache[list][scan8[0]];
+ int8_t *ref = s->current_picture.f.ref_index[list];
+ int16_t (*mv_cache)[2] = &h->mv_cache[list][scan8[0]];
+ int16_t (*mv)[2] = s->current_picture.f.motion_val[list];
+ if(!USES_LIST(mb_type, list)){
+ continue;
+ }
+ assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
+
+ if(USES_LIST(top_type, list)){
+ const int b_xy= h->mb2b_xy[top_xy] + 3*b_stride;
+ AV_COPY128(mv_cache[0 - 1*8], mv[b_xy + 0]);
+ ref_cache[0 - 1*8]=
+ ref_cache[1 - 1*8]= ref[4*top_xy + 2];
+ ref_cache[2 - 1*8]=
+ ref_cache[3 - 1*8]= ref[4*top_xy + 3];
+ }else{
+ AV_ZERO128(mv_cache[0 - 1*8]);
+ AV_WN32A(&ref_cache[0 - 1*8], ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE)&0xFF)*0x01010101u);
+ }
+
+ if(mb_type & (MB_TYPE_16x8|MB_TYPE_8x8)){
+ for(i=0; i<2; i++){
+ int cache_idx = -1 + i*2*8;
+ if(USES_LIST(left_type[LEFT(i)], list)){
+ const int b_xy= h->mb2b_xy[left_xy[LEFT(i)]] + 3;
+ const int b8_xy= 4*left_xy[LEFT(i)] + 1;
+ AV_COPY32(mv_cache[cache_idx ], mv[b_xy + b_stride*left_block[0+i*2]]);
+ AV_COPY32(mv_cache[cache_idx+8], mv[b_xy + b_stride*left_block[1+i*2]]);
+ ref_cache[cache_idx ]= ref[b8_xy + (left_block[0+i*2]&~1)];
+ ref_cache[cache_idx+8]= ref[b8_xy + (left_block[1+i*2]&~1)];
+ }else{
+ AV_ZERO32(mv_cache[cache_idx ]);
+ AV_ZERO32(mv_cache[cache_idx+8]);
+ ref_cache[cache_idx ]=
+ ref_cache[cache_idx+8]= (left_type[LEFT(i)]) ? LIST_NOT_USED : PART_NOT_AVAILABLE;
+ }
+ }
+ }else{
+ if(USES_LIST(left_type[LTOP], list)){
+ const int b_xy= h->mb2b_xy[left_xy[LTOP]] + 3;
+ const int b8_xy= 4*left_xy[LTOP] + 1;
+ AV_COPY32(mv_cache[-1], mv[b_xy + b_stride*left_block[0]]);
+ ref_cache[-1]= ref[b8_xy + (left_block[0]&~1)];
+ }else{
+ AV_ZERO32(mv_cache[-1]);
+ ref_cache[-1]= left_type[LTOP] ? LIST_NOT_USED : PART_NOT_AVAILABLE;
+ }
+ }
+
+ if(USES_LIST(topright_type, list)){
+ const int b_xy= h->mb2b_xy[topright_xy] + 3*b_stride;
+ AV_COPY32(mv_cache[4 - 1*8], mv[b_xy]);
+ ref_cache[4 - 1*8]= ref[4*topright_xy + 2];
+ }else{
+ AV_ZERO32(mv_cache[4 - 1*8]);
+ ref_cache[4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;
+ }
+ if(ref_cache[4 - 1*8] < 0){
+ if(USES_LIST(topleft_type, list)){
+ const int b_xy = h->mb2b_xy[topleft_xy] + 3 + b_stride + (h->topleft_partition & 2*b_stride);
+ const int b8_xy= 4*topleft_xy + 1 + (h->topleft_partition & 2);
+ AV_COPY32(mv_cache[-1 - 1*8], mv[b_xy]);
+ ref_cache[-1 - 1*8]= ref[b8_xy];
+ }else{
+ AV_ZERO32(mv_cache[-1 - 1*8]);
+ ref_cache[-1 - 1*8]= topleft_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;
+ }
+ }
+
+ if((mb_type&(MB_TYPE_SKIP|MB_TYPE_DIRECT2)) && !FRAME_MBAFF)
+ continue;
+
+ if(!(mb_type&(MB_TYPE_SKIP|MB_TYPE_DIRECT2))){
+ uint8_t (*mvd_cache)[2] = &h->mvd_cache[list][scan8[0]];
+ uint8_t (*mvd)[2] = h->mvd_table[list];
+ ref_cache[2+8*0] =
+ ref_cache[2+8*2] = PART_NOT_AVAILABLE;
+ AV_ZERO32(mv_cache[2+8*0]);
+ AV_ZERO32(mv_cache[2+8*2]);
+
+ if( CABAC ) {
+ if(USES_LIST(top_type, list)){
+ const int b_xy= h->mb2br_xy[top_xy];
+ AV_COPY64(mvd_cache[0 - 1*8], mvd[b_xy + 0]);
+ }else{
+ AV_ZERO64(mvd_cache[0 - 1*8]);
+ }
+ if(USES_LIST(left_type[LTOP], list)){
+ const int b_xy= h->mb2br_xy[left_xy[LTOP]] + 6;
+ AV_COPY16(mvd_cache[-1 + 0*8], mvd[b_xy - left_block[0]]);
+ AV_COPY16(mvd_cache[-1 + 1*8], mvd[b_xy - left_block[1]]);
+ }else{
+ AV_ZERO16(mvd_cache[-1 + 0*8]);
+ AV_ZERO16(mvd_cache[-1 + 1*8]);
+ }
+ if(USES_LIST(left_type[LBOT], list)){
+ const int b_xy= h->mb2br_xy[left_xy[LBOT]] + 6;
+ AV_COPY16(mvd_cache[-1 + 2*8], mvd[b_xy - left_block[2]]);
+ AV_COPY16(mvd_cache[-1 + 3*8], mvd[b_xy - left_block[3]]);
+ }else{
+ AV_ZERO16(mvd_cache[-1 + 2*8]);
+ AV_ZERO16(mvd_cache[-1 + 3*8]);
+ }
+ AV_ZERO16(mvd_cache[2+8*0]);
+ AV_ZERO16(mvd_cache[2+8*2]);
+ if(h->slice_type_nos == AV_PICTURE_TYPE_B){
+ uint8_t *direct_cache = &h->direct_cache[scan8[0]];
+ uint8_t *direct_table = h->direct_table;
+ fill_rectangle(direct_cache, 4, 4, 8, MB_TYPE_16x16>>1, 1);
+
+ if(IS_DIRECT(top_type)){
+ AV_WN32A(&direct_cache[-1*8], 0x01010101u*(MB_TYPE_DIRECT2>>1));
+ }else if(IS_8X8(top_type)){
+ int b8_xy = 4*top_xy;
+ direct_cache[0 - 1*8]= direct_table[b8_xy + 2];
+ direct_cache[2 - 1*8]= direct_table[b8_xy + 3];
+ }else{
+ AV_WN32A(&direct_cache[-1*8], 0x01010101*(MB_TYPE_16x16>>1));
+ }
+
+ if(IS_DIRECT(left_type[LTOP]))
+ direct_cache[-1 + 0*8]= MB_TYPE_DIRECT2>>1;
+ else if(IS_8X8(left_type[LTOP]))
+ direct_cache[-1 + 0*8]= direct_table[4*left_xy[LTOP] + 1 + (left_block[0]&~1)];
+ else
+ direct_cache[-1 + 0*8]= MB_TYPE_16x16>>1;
+
+ if(IS_DIRECT(left_type[LBOT]))
+ direct_cache[-1 + 2*8]= MB_TYPE_DIRECT2>>1;
+ else if(IS_8X8(left_type[LBOT]))
+ direct_cache[-1 + 2*8]= direct_table[4*left_xy[LBOT] + 1 + (left_block[2]&~1)];
+ else
+ direct_cache[-1 + 2*8]= MB_TYPE_16x16>>1;
+ }
+ }
+ }
+ if(FRAME_MBAFF){
+#define MAP_MVS\
+ MAP_F2F(scan8[0] - 1 - 1*8, topleft_type)\
+ MAP_F2F(scan8[0] + 0 - 1*8, top_type)\
+ MAP_F2F(scan8[0] + 1 - 1*8, top_type)\
+ MAP_F2F(scan8[0] + 2 - 1*8, top_type)\
+ MAP_F2F(scan8[0] + 3 - 1*8, top_type)\
+ MAP_F2F(scan8[0] + 4 - 1*8, topright_type)\
+ MAP_F2F(scan8[0] - 1 + 0*8, left_type[LTOP])\
+ MAP_F2F(scan8[0] - 1 + 1*8, left_type[LTOP])\
+ MAP_F2F(scan8[0] - 1 + 2*8, left_type[LBOT])\
+ MAP_F2F(scan8[0] - 1 + 3*8, left_type[LBOT])
+ if(MB_FIELD){
+#define MAP_F2F(idx, mb_type)\
+ if(!IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0){\
+ h->ref_cache[list][idx] <<= 1;\
+ h->mv_cache[list][idx][1] /= 2;\
+ h->mvd_cache[list][idx][1] >>=1;\
+ }
+ MAP_MVS
+#undef MAP_F2F
+ }else{
+#define MAP_F2F(idx, mb_type)\
+ if(IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0){\
+ h->ref_cache[list][idx] >>= 1;\
+ h->mv_cache[list][idx][1] <<= 1;\
+ h->mvd_cache[list][idx][1] <<= 1;\
+ }
+ MAP_MVS
+#undef MAP_F2F
+ }
+ }
+ }
+ }
+
+ h->neighbor_transform_size= !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[LTOP]);
+}
+
+/**
+ * decodes a P_SKIP or B_SKIP macroblock
+ */
+static void av_unused decode_mb_skip(H264Context *h){
+ MpegEncContext * const s = &h->s;
+ const int mb_xy= h->mb_xy;
+ int mb_type=0;
+
+ memset(h->non_zero_count[mb_xy], 0, 48);
+
+ if(MB_FIELD)
+ mb_type|= MB_TYPE_INTERLACED;
+
+ if( h->slice_type_nos == AV_PICTURE_TYPE_B )
+ {
+ // just for fill_caches. pred_direct_motion will set the real mb_type
+ mb_type|= MB_TYPE_L0L1|MB_TYPE_DIRECT2|MB_TYPE_SKIP;
+ if(h->direct_spatial_mv_pred){
+ fill_decode_neighbors(h, mb_type);
+ fill_decode_caches(h, mb_type); //FIXME check what is needed and what not ...
+ }
+ ff_h264_pred_direct_motion(h, &mb_type);
+ mb_type|= MB_TYPE_SKIP;
+ }
+ else
+ {
+ mb_type|= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P1L0|MB_TYPE_SKIP;
+
+ fill_decode_neighbors(h, mb_type);
+ pred_pskip_motion(h);
+ }
+
+ write_back_motion(h, mb_type);
+ s->current_picture.f.mb_type[mb_xy] = mb_type;
+ s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+ h->slice_table[ mb_xy ]= h->slice_num;
+ h->prev_mb_skipped= 1;
+}
+
#endif /* AVCODEC_H264_MVPRED_H */
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index c39baeb..826c17a 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -97,7 +97,7 @@ found:
return i-(state&5);
}
-/*!
+/**
* Parse NAL units of found picture and decode some basic information.
*
* @param s parser context.
@@ -131,7 +131,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
for(;;) {
int src_length, dst_length, consumed;
- buf = ff_find_start_code(buf, buf_end, &state);
+ buf = avpriv_mpv_find_start_code(buf, buf_end, &state);
if(buf >= buf_end)
break;
--buf;
@@ -334,10 +334,10 @@ static int init(AVCodecParserContext *s)
}
AVCodecParser ff_h264_parser = {
- { CODEC_ID_H264 },
- sizeof(H264Context),
- init,
- h264_parse,
- close,
- h264_split,
+ .codec_ids = { CODEC_ID_H264 },
+ .priv_data_size = sizeof(H264Context),
+ .parser_init = init,
+ .parser_parse = h264_parse,
+ .parser_close = close,
+ .split = h264_split,
};
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index 7491807..76bf116 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -130,8 +130,8 @@ static inline int decode_hrd_parameters(H264Context *h, SPS *sps){
get_bits(&s->gb, 4); /* bit_rate_scale */
get_bits(&s->gb, 4); /* cpb_size_scale */
for(i=0; i<cpb_count; i++){
- get_ue_golomb(&s->gb); /* bit_rate_value_minus1 */
- get_ue_golomb(&s->gb); /* cpb_size_value_minus1 */
+ get_ue_golomb_long(&s->gb); /* bit_rate_value_minus1 */
+ get_ue_golomb_long(&s->gb); /* cpb_size_value_minus1 */
get_bits1(&s->gb); /* cbr_flag */
}
sps->initial_cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
@@ -396,7 +396,8 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
#endif
sps->crop= get_bits1(&s->gb);
if(sps->crop){
- int crop_limit = sps->chroma_format_idc == 3 ? 16 : 8;
+ int crop_vertical_limit = sps->chroma_format_idc & 2 ? 16 : 8;
+ int crop_horizontal_limit = sps->chroma_format_idc == 3 ? 16 : 8;
sps->crop_left = get_ue_golomb(&s->gb);
sps->crop_right = get_ue_golomb(&s->gb);
sps->crop_top = get_ue_golomb(&s->gb);
@@ -404,7 +405,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
if(sps->crop_left || sps->crop_top){
av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n");
}
- if(sps->crop_right >= crop_limit || sps->crop_bottom >= crop_limit){
+ if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){
av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n");
}
}else{
@@ -462,6 +463,7 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
unsigned int pps_id= get_ue_golomb(&s->gb);
PPS *pps;
const int qp_bd_offset = 6*(h->sps.bit_depth_luma-8);
+ int bits_left;
if(pps_id >= MAX_PPS_COUNT) {
av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
@@ -538,7 +540,9 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4));
memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8));
- if(get_bits_count(&s->gb) < bit_length){
+ bits_left = bit_length - get_bits_count(&s->gb);
+ if (bits_left && (bits_left > 8 ||
+ show_bits(&s->gb, bits_left) != 1 << (bits_left - 1))) {
pps->transform_8x8_mode= get_bits1(&s->gb);
decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8);
pps->chroma_qp_index_offset[1]= get_se_golomb(&s->gb); //second_chroma_qp_index_offset
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index b1c27ec..273c52b 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -39,16 +39,16 @@ static void pic_as_field(Picture *pic, const int parity){
int i;
for (i = 0; i < 4; ++i) {
if (parity == PICT_BOTTOM_FIELD)
- pic->data[i] += pic->linesize[i];
- pic->reference = parity;
- pic->linesize[i] *= 2;
+ pic->f.data[i] += pic->f.linesize[i];
+ pic->f.reference = parity;
+ pic->f.linesize[i] *= 2;
}
pic->poc= pic->field_poc[parity == PICT_BOTTOM_FIELD];
}
static int split_field_copy(Picture *dest, Picture *src,
int parity, int id_add){
- int match = !!(src->reference & parity);
+ int match = !!(src->f.reference & parity);
if (match) {
*dest = *src;
@@ -67,9 +67,9 @@ static int build_def_list(Picture *def, Picture **in, int len, int is_long, int
int index=0;
while(i[0]<len || i[1]<len){
- while(i[0]<len && !(in[ i[0] ] && (in[ i[0] ]->reference & sel)))
+ while (i[0] < len && !(in[ i[0] ] && (in[ i[0] ]->f.reference & sel)))
i[0]++;
- while(i[1]<len && !(in[ i[1] ] && (in[ i[1] ]->reference & (sel^3))))
+ while (i[1] < len && !(in[ i[1] ] && (in[ i[1] ]->f.reference & (sel^3))))
i[1]++;
if(i[0] < len){
in[ i[0] ]->pic_id= is_long ? i[0] : in[ i[0] ]->frame_num;
@@ -133,7 +133,7 @@ int ff_h264_fill_default_ref_list(H264Context *h){
}
if(lens[0] == lens[1] && lens[1] > 1){
- for(i=0; h->default_ref_list[0][i].data[0] == h->default_ref_list[1][i].data[0] && i<lens[0]; i++);
+ for (i = 0; h->default_ref_list[0][i].f.data[0] == h->default_ref_list[1][i].f.data[0] && i < lens[0]; i++);
if(i == lens[0])
FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]);
}
@@ -229,11 +229,11 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
for(i= h->short_ref_count-1; i>=0; i--){
ref = h->short_ref[i];
- assert(ref->reference);
+ assert(ref->f.reference);
assert(!ref->long_ref);
if(
ref->frame_num == frame_num &&
- (ref->reference & pic_structure)
+ (ref->f.reference & pic_structure)
)
break;
}
@@ -250,8 +250,8 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
return -1;
}
ref = h->long_ref[long_idx];
- assert(!(ref && !ref->reference));
- if(ref && (ref->reference & pic_structure)){
+ assert(!(ref && !ref->f.reference));
+ if (ref && (ref->f.reference & pic_structure)) {
ref->pic_id= pic_id;
assert(ref->long_ref);
i=0;
@@ -285,9 +285,9 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
}
for(list=0; list<h->list_count; list++){
for(index= 0; index < h->ref_count[list]; index++){
- if(!h->ref_list[list][index].data[0]){
+ if (!h->ref_list[list][index].f.data[0]) {
av_log(h->s.avctx, AV_LOG_ERROR, "Missing reference picture\n");
- if(h->default_ref_list[list][0].data[0])
+ if (h->default_ref_list[list][0].f.data[0])
h->ref_list[list][index]= h->default_ref_list[list][0];
else
return -1;
@@ -306,13 +306,13 @@ void ff_h264_fill_mbaff_ref_list(H264Context *h){
Picture *field = &h->ref_list[list][16+2*i];
field[0] = *frame;
for(j=0; j<3; j++)
- field[0].linesize[j] <<= 1;
- field[0].reference = PICT_TOP_FIELD;
+ field[0].f.linesize[j] <<= 1;
+ field[0].f.reference = PICT_TOP_FIELD;
field[0].poc= field[0].field_poc[0];
field[1] = field[0];
for(j=0; j<3; j++)
- field[1].data[j] += frame->linesize[j];
- field[1].reference = PICT_BOTTOM_FIELD;
+ field[1].f.data[j] += frame->f.linesize[j];
+ field[1].f.reference = PICT_BOTTOM_FIELD;
field[1].poc= field[1].field_poc[1];
h->luma_weight[16+2*i][list][0] = h->luma_weight[16+2*i+1][list][0] = h->luma_weight[i][list][0];
@@ -338,12 +338,12 @@ void ff_h264_fill_mbaff_ref_list(H264Context *h){
*/
static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){
int i;
- if (pic->reference &= refmask) {
+ if (pic->f.reference &= refmask) {
return 0;
} else {
for(i = 0; h->delayed_pic[i]; i++)
if(pic == h->delayed_pic[i]){
- pic->reference=DELAYED_PIC_REF;
+ pic->f.reference = DELAYED_PIC_REF;
break;
}
return 1;
@@ -453,7 +453,8 @@ static void print_short_term(H264Context *h) {
av_log(h->s.avctx, AV_LOG_DEBUG, "short term list:\n");
for(i=0; i<h->short_ref_count; i++){
Picture *pic= h->short_ref[i];
- av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n", i, pic->frame_num, pic->poc, pic->data[0]);
+ av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n",
+ i, pic->frame_num, pic->poc, pic->f.data[0]);
}
}
}
@@ -468,7 +469,8 @@ static void print_long_term(H264Context *h) {
for(i = 0; i < 16; i++){
Picture *pic= h->long_ref[i];
if (pic) {
- av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n", i, pic->frame_num, pic->poc, pic->data[0]);
+ av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n",
+ i, pic->frame_num, pic->poc, pic->f.data[0]);
}
}
}
@@ -480,7 +482,7 @@ void ff_generate_sliding_window_mmcos(H264Context *h) {
h->mmco_index= 0;
if(h->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count &&
- !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->reference)) {
+ !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->f.reference)) {
h->mmco[0].opcode= MMCO_SHORT2UNUSED;
h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num;
h->mmco_index= 1;
@@ -496,7 +498,7 @@ void ff_generate_sliding_window_mmcos(H264Context *h) {
int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
MpegEncContext * const s = &h->s;
int i, av_uninit(j);
- int current_ref_assigned=0;
+ int current_ref_assigned=0, err=0;
Picture *av_uninit(pic);
if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0)
@@ -513,8 +515,10 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
pic = find_short(h, frame_num, &j);
if(!pic){
if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg]
- || h->long_ref[mmco[i].long_arg]->frame_num != frame_num)
- av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
+ || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
+ err = AVERROR_INVALIDDATA;
+ }
continue;
}
}
@@ -561,7 +565,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
h->long_ref_count++;
}
- s->current_picture_ptr->reference |= s->picture_structure;
+ s->current_picture_ptr->f.reference |= s->picture_structure;
current_ref_assigned=1;
break;
case MMCO_SET_MAX_LONG:
@@ -578,13 +582,9 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
for(j = 0; j < 16; j++) {
remove_long(h, j, 0);
}
- s->current_picture_ptr->poc=
- s->current_picture_ptr->field_poc[0]=
- s->current_picture_ptr->field_poc[1]=
- h->poc_lsb=
- h->poc_msb=
h->frame_num=
s->current_picture_ptr->frame_num= 0;
+ h->mmco_reset = 1;
s->current_picture_ptr->mmco_reset=1;
break;
default: assert(0);
@@ -600,16 +600,18 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
*/
if (h->short_ref_count && h->short_ref[0] == s->current_picture_ptr) {
/* Just mark the second field valid */
- s->current_picture_ptr->reference = PICT_FRAME;
+ s->current_picture_ptr->f.reference = PICT_FRAME;
} else if (s->current_picture_ptr->long_ref) {
av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term reference "
"assignment for second field "
"in complementary field pair "
"(first field is long term)\n");
+ err = AVERROR_INVALIDDATA;
} else {
pic= remove_short(h, s->current_picture_ptr->frame_num, 0);
if(pic){
av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n");
+ err = AVERROR_INVALIDDATA;
}
if(h->short_ref_count)
@@ -617,7 +619,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
h->short_ref[0]= s->current_picture_ptr;
h->short_ref_count++;
- s->current_picture_ptr->reference |= s->picture_structure;
+ s->current_picture_ptr->f.reference |= s->picture_structure;
}
}
@@ -632,6 +634,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
"number of reference frames (%d+%d) exceeds max (%d; probably "
"corrupt input), discarding one\n",
h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count);
+ err = AVERROR_INVALIDDATA;
if (h->long_ref_count && !h->short_ref_count) {
for (i = 0; i < 16; ++i)
@@ -648,7 +651,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
print_short_term(h);
print_long_term(h);
- return 0;
+ return (h->s.avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
}
int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){
diff --git a/libavcodec/h264data.h b/libavcodec/h264data.h
index 1851169..2cfa548 100644
--- a/libavcodec/h264data.h
+++ b/libavcodec/h264data.h
@@ -80,7 +80,14 @@ static const uint8_t luma_dc_field_scan[16]={
static const uint8_t chroma_dc_scan[4]={
(0+0*2)*16, (1+0*2)*16,
- (0+1*2)*16, (1+1*2)*16, //FIXME
+ (0+1*2)*16, (1+1*2)*16,
+};
+
+static const uint8_t chroma422_dc_scan[8]={
+ (0+0*2)*16, (0+1*2)*16,
+ (1+0*2)*16, (0+2*2)*16,
+ (0+3*2)*16, (1+1*2)*16,
+ (1+2*2)*16, (1+3*2)*16,
};
// zigzag_scan8x8_cavlc[i] = zigzag_scan8x8[(i/4) + 16*(i%4)]
diff --git a/libavcodec/h264dsp.c b/libavcodec/h264dsp.c
index 64f4856..ba96707 100644
--- a/libavcodec/h264dsp.c
+++ b/libavcodec/h264dsp.c
@@ -41,7 +41,7 @@
#include "h264dsp_template.c"
#undef BIT_DEPTH
-void ff_h264dsp_init(H264DSPContext *c, const int bit_depth)
+void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
{
#undef FUNC
#define FUNC(a, depth) a ## _ ## depth ## _c
@@ -53,31 +53,25 @@ void ff_h264dsp_init(H264DSPContext *c, const int bit_depth)
c->h264_idct8_dc_add= FUNC(ff_h264_idct8_dc_add, depth);\
c->h264_idct_add16 = FUNC(ff_h264_idct_add16, depth);\
c->h264_idct8_add4 = FUNC(ff_h264_idct8_add4, depth);\
- c->h264_idct_add8 = FUNC(ff_h264_idct_add8, depth);\
+ if (chroma_format_idc == 1)\
+ c->h264_idct_add8 = FUNC(ff_h264_idct_add8, depth);\
+ else\
+ c->h264_idct_add8 = FUNC(ff_h264_idct_add8_422, depth);\
c->h264_idct_add16intra= FUNC(ff_h264_idct_add16intra, depth);\
c->h264_luma_dc_dequant_idct= FUNC(ff_h264_luma_dc_dequant_idct, depth);\
- c->h264_chroma_dc_dequant_idct= FUNC(ff_h264_chroma_dc_dequant_idct, depth);\
+ if (chroma_format_idc == 1)\
+ c->h264_chroma_dc_dequant_idct= FUNC(ff_h264_chroma_dc_dequant_idct, depth);\
+ else\
+ c->h264_chroma_dc_dequant_idct= FUNC(ff_h264_chroma422_dc_dequant_idct, depth);\
\
- c->weight_h264_pixels_tab[0]= FUNC(weight_h264_pixels16x16, depth);\
- c->weight_h264_pixels_tab[1]= FUNC(weight_h264_pixels16x8, depth);\
- c->weight_h264_pixels_tab[2]= FUNC(weight_h264_pixels8x16, depth);\
- c->weight_h264_pixels_tab[3]= FUNC(weight_h264_pixels8x8, depth);\
- c->weight_h264_pixels_tab[4]= FUNC(weight_h264_pixels8x4, depth);\
- c->weight_h264_pixels_tab[5]= FUNC(weight_h264_pixels4x8, depth);\
- c->weight_h264_pixels_tab[6]= FUNC(weight_h264_pixels4x4, depth);\
- c->weight_h264_pixels_tab[7]= FUNC(weight_h264_pixels4x2, depth);\
- c->weight_h264_pixels_tab[8]= FUNC(weight_h264_pixels2x4, depth);\
- c->weight_h264_pixels_tab[9]= FUNC(weight_h264_pixels2x2, depth);\
- c->biweight_h264_pixels_tab[0]= FUNC(biweight_h264_pixels16x16, depth);\
- c->biweight_h264_pixels_tab[1]= FUNC(biweight_h264_pixels16x8, depth);\
- c->biweight_h264_pixels_tab[2]= FUNC(biweight_h264_pixels8x16, depth);\
- c->biweight_h264_pixels_tab[3]= FUNC(biweight_h264_pixels8x8, depth);\
- c->biweight_h264_pixels_tab[4]= FUNC(biweight_h264_pixels8x4, depth);\
- c->biweight_h264_pixels_tab[5]= FUNC(biweight_h264_pixels4x8, depth);\
- c->biweight_h264_pixels_tab[6]= FUNC(biweight_h264_pixels4x4, depth);\
- c->biweight_h264_pixels_tab[7]= FUNC(biweight_h264_pixels4x2, depth);\
- c->biweight_h264_pixels_tab[8]= FUNC(biweight_h264_pixels2x4, depth);\
- c->biweight_h264_pixels_tab[9]= FUNC(biweight_h264_pixels2x2, depth);\
+ c->weight_h264_pixels_tab[0]= FUNC(weight_h264_pixels16, depth);\
+ c->weight_h264_pixels_tab[1]= FUNC(weight_h264_pixels8, depth);\
+ c->weight_h264_pixels_tab[2]= FUNC(weight_h264_pixels4, depth);\
+ c->weight_h264_pixels_tab[3]= FUNC(weight_h264_pixels2, depth);\
+ c->biweight_h264_pixels_tab[0]= FUNC(biweight_h264_pixels16, depth);\
+ c->biweight_h264_pixels_tab[1]= FUNC(biweight_h264_pixels8, depth);\
+ c->biweight_h264_pixels_tab[2]= FUNC(biweight_h264_pixels4, depth);\
+ c->biweight_h264_pixels_tab[3]= FUNC(biweight_h264_pixels2, depth);\
\
c->h264_v_loop_filter_luma= FUNC(h264_v_loop_filter_luma, depth);\
c->h264_h_loop_filter_luma= FUNC(h264_h_loop_filter_luma, depth);\
@@ -86,11 +80,23 @@ void ff_h264dsp_init(H264DSPContext *c, const int bit_depth)
c->h264_h_loop_filter_luma_intra= FUNC(h264_h_loop_filter_luma_intra, depth);\
c->h264_h_loop_filter_luma_mbaff_intra= FUNC(h264_h_loop_filter_luma_mbaff_intra, depth);\
c->h264_v_loop_filter_chroma= FUNC(h264_v_loop_filter_chroma, depth);\
- c->h264_h_loop_filter_chroma= FUNC(h264_h_loop_filter_chroma, depth);\
- c->h264_h_loop_filter_chroma_mbaff= FUNC(h264_h_loop_filter_chroma_mbaff, depth);\
+ if (chroma_format_idc == 1)\
+ c->h264_h_loop_filter_chroma= FUNC(h264_h_loop_filter_chroma, depth);\
+ else\
+ c->h264_h_loop_filter_chroma= FUNC(h264_h_loop_filter_chroma422, depth);\
+ if (chroma_format_idc == 1)\
+ c->h264_h_loop_filter_chroma_mbaff= FUNC(h264_h_loop_filter_chroma_mbaff, depth);\
+ else\
+ c->h264_h_loop_filter_chroma_mbaff= FUNC(h264_h_loop_filter_chroma422_mbaff, depth);\
c->h264_v_loop_filter_chroma_intra= FUNC(h264_v_loop_filter_chroma_intra, depth);\
- c->h264_h_loop_filter_chroma_intra= FUNC(h264_h_loop_filter_chroma_intra, depth);\
- c->h264_h_loop_filter_chroma_mbaff_intra= FUNC(h264_h_loop_filter_chroma_mbaff_intra, depth);\
+ if (chroma_format_idc == 1)\
+ c->h264_h_loop_filter_chroma_intra= FUNC(h264_h_loop_filter_chroma_intra, depth);\
+ else\
+ c->h264_h_loop_filter_chroma_intra= FUNC(h264_h_loop_filter_chroma422_intra, depth);\
+ if (chroma_format_idc == 1)\
+ c->h264_h_loop_filter_chroma_mbaff_intra= FUNC(h264_h_loop_filter_chroma_mbaff_intra, depth);\
+ else\
+ c->h264_h_loop_filter_chroma_mbaff_intra= FUNC(h264_h_loop_filter_chroma422_mbaff_intra, depth);\
c->h264_loop_filter_strength= NULL;
switch (bit_depth) {
@@ -105,7 +111,7 @@ void ff_h264dsp_init(H264DSPContext *c, const int bit_depth)
break;
}
- if (ARCH_ARM) ff_h264dsp_init_arm(c, bit_depth);
- if (HAVE_ALTIVEC) ff_h264dsp_init_ppc(c, bit_depth);
- if (HAVE_MMX) ff_h264dsp_init_x86(c, bit_depth);
+ if (ARCH_ARM) ff_h264dsp_init_arm(c, bit_depth, chroma_format_idc);
+ if (HAVE_ALTIVEC) ff_h264dsp_init_ppc(c, bit_depth, chroma_format_idc);
+ if (HAVE_MMX) ff_h264dsp_init_x86(c, bit_depth, chroma_format_idc);
}
diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
index 6972725..7cae215 100644
--- a/libavcodec/h264dsp.h
+++ b/libavcodec/h264dsp.h
@@ -31,16 +31,18 @@
#include "dsputil.h"
//typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
-typedef void (*h264_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int offset);
-typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offset);
+typedef void (*h264_weight_func)(uint8_t *block, int stride, int height,
+ int log2_denom, int weight, int offset);
+typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src, int stride, int height,
+ int log2_denom, int weightd, int weights, int offset);
/**
* Context for storing H.264 DSP functions
*/
typedef struct H264DSPContext{
/* weighted MC */
- h264_weight_func weight_h264_pixels_tab[10];
- h264_biweight_func biweight_h264_pixels_tab[10];
+ h264_weight_func weight_h264_pixels_tab[4];
+ h264_biweight_func biweight_h264_pixels_tab[4];
/* loop filter */
void (*h264_v_loop_filter_luma)(uint8_t *pix/*align 16*/, int stride, int alpha, int beta, int8_t *tc0);
@@ -74,9 +76,9 @@ typedef struct H264DSPContext{
void (*h264_chroma_dc_dequant_idct)(DCTELEM *block, int qmul);
}H264DSPContext;
-void ff_h264dsp_init(H264DSPContext *c, const int bit_depth);
-void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth);
-void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth);
-void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth);
+void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_format_idc);
+void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth, const int chroma_format_idc);
+void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth, const int chroma_format_idc);
+void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chroma_format_idc);
#endif /* AVCODEC_H264DSP_H */
diff --git a/libavcodec/h264dsp_template.c b/libavcodec/h264dsp_template.c
index be88f74..3d99cfc 100644
--- a/libavcodec/h264dsp_template.c
+++ b/libavcodec/h264dsp_template.c
@@ -25,18 +25,20 @@
* @author Michael Niedermayer <michaelni at gmx.at>
*/
-#include "high_bit_depth.h"
+#include "bit_depth_template.c"
#define op_scale1(x) block[x] = av_clip_pixel( (block[x]*weight + offset) >> log2_denom )
#define op_scale2(x) dst[x] = av_clip_pixel( (src[x]*weights + dst[x]*weightd + offset) >> (log2_denom+1))
-#define H264_WEIGHT(W,H) \
-static void FUNCC(weight_h264_pixels ## W ## x ## H)(uint8_t *_block, int stride, int log2_denom, int weight, int offset){ \
+#define H264_WEIGHT(W) \
+static void FUNCC(weight_h264_pixels ## W)(uint8_t *_block, int stride, int height, \
+ int log2_denom, int weight, int offset) \
+{ \
int y; \
pixel *block = (pixel*)_block; \
stride /= sizeof(pixel); \
offset <<= (log2_denom + (BIT_DEPTH-8)); \
if(log2_denom) offset += 1<<(log2_denom-1); \
- for(y=0; y<H; y++, block += stride){ \
+ for (y = 0; y < height; y++, block += stride) { \
op_scale1(0); \
op_scale1(1); \
if(W==2) continue; \
@@ -58,14 +60,16 @@ static void FUNCC(weight_h264_pixels ## W ## x ## H)(uint8_t *_block, int stride
op_scale1(15); \
} \
} \
-static void FUNCC(biweight_h264_pixels ## W ## x ## H)(uint8_t *_dst, uint8_t *_src, int stride, int log2_denom, int weightd, int weights, int offset){ \
+static void FUNCC(biweight_h264_pixels ## W)(uint8_t *_dst, uint8_t *_src, int stride, int height, \
+ int log2_denom, int weightd, int weights, int offset) \
+{ \
int y; \
pixel *dst = (pixel*)_dst; \
pixel *src = (pixel*)_src; \
stride /= sizeof(pixel); \
offset <<= (BIT_DEPTH-8); \
offset = ((offset + 1) | 1) << log2_denom; \
- for(y=0; y<H; y++, dst += stride, src += stride){ \
+ for (y = 0; y < height; y++, dst += stride, src += stride) { \
op_scale2(0); \
op_scale2(1); \
if(W==2) continue; \
@@ -88,16 +92,10 @@ static void FUNCC(biweight_h264_pixels ## W ## x ## H)(uint8_t *_dst, uint8_t *_
} \
}
-H264_WEIGHT(16,16)
-H264_WEIGHT(16,8)
-H264_WEIGHT(8,16)
-H264_WEIGHT(8,8)
-H264_WEIGHT(8,4)
-H264_WEIGHT(4,8)
-H264_WEIGHT(4,4)
-H264_WEIGHT(4,2)
-H264_WEIGHT(2,4)
-H264_WEIGHT(2,2)
+H264_WEIGHT(16)
+H264_WEIGHT(8)
+H264_WEIGHT(4)
+H264_WEIGHT(2)
#undef op_scale1
#undef op_scale2
@@ -275,6 +273,14 @@ static void FUNCC(h264_h_loop_filter_chroma_mbaff)(uint8_t *pix, int stride, int
{
FUNCC(h264_loop_filter_chroma)(pix, sizeof(pixel), stride, 1, alpha, beta, tc0);
}
+static void FUNCC(h264_h_loop_filter_chroma422)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0)
+{
+ FUNCC(h264_loop_filter_chroma)(pix, sizeof(pixel), stride, 4, alpha, beta, tc0);
+}
+static void FUNCC(h264_h_loop_filter_chroma422_mbaff)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0)
+{
+ FUNCC(h264_loop_filter_chroma)(pix, sizeof(pixel), stride, 2, alpha, beta, tc0);
+}
static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma_intra)(uint8_t *_pix, int xstride, int ystride, int inner_iters, int alpha, int beta)
{
@@ -312,3 +318,11 @@ static void FUNCC(h264_h_loop_filter_chroma_mbaff_intra)(uint8_t *pix, int strid
{
FUNCC(h264_loop_filter_chroma_intra)(pix, sizeof(pixel), stride, 1, alpha, beta);
}
+static void FUNCC(h264_h_loop_filter_chroma422_intra)(uint8_t *pix, int stride, int alpha, int beta)
+{
+ FUNCC(h264_loop_filter_chroma_intra)(pix, sizeof(pixel), stride, 4, alpha, beta);
+}
+static void FUNCC(h264_h_loop_filter_chroma422_mbaff_intra)(uint8_t *pix, int stride, int alpha, int beta)
+{
+ FUNCC(h264_loop_filter_chroma_intra)(pix, sizeof(pixel), stride, 2, alpha, beta);
+}
diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c
index e288f9b..eba850a 100644
--- a/libavcodec/h264idct_template.c
+++ b/libavcodec/h264idct_template.c
@@ -25,7 +25,7 @@
* @author Michael Niedermayer <michaelni at gmx.at>
*/
-#include "high_bit_depth.h"
+#include "bit_depth_template.c"
#ifndef AVCODEC_H264IDCT_INTERNAL_H
#define AVCODEC_H264IDCT_INTERNAL_H
@@ -46,52 +46,41 @@ static const uint8_t scan8[16*3]={
};
#endif
-static av_always_inline void FUNCC(idct_internal)(uint8_t *_dst, DCTELEM *_block, int stride, int block_stride, int shift, int add){
+void FUNCC(ff_h264_idct_add)(uint8_t *_dst, DCTELEM *_block, int stride)
+{
int i;
INIT_CLIP
pixel *dst = (pixel*)_dst;
dctcoef *block = (dctcoef*)_block;
stride /= sizeof(pixel);
- block[0] += 1<<(shift-1);
+ block[0] += 1 << 5;
for(i=0; i<4; i++){
- const int z0= block[i + block_stride*0] + block[i + block_stride*2];
- const int z1= block[i + block_stride*0] - block[i + block_stride*2];
- const int z2= (block[i + block_stride*1]>>1) - block[i + block_stride*3];
- const int z3= block[i + block_stride*1] + (block[i + block_stride*3]>>1);
-
- block[i + block_stride*0]= z0 + z3;
- block[i + block_stride*1]= z1 + z2;
- block[i + block_stride*2]= z1 - z2;
- block[i + block_stride*3]= z0 - z3;
+ const int z0= block[i + 4*0] + block[i + 4*2];
+ const int z1= block[i + 4*0] - block[i + 4*2];
+ const int z2= (block[i + 4*1]>>1) - block[i + 4*3];
+ const int z3= block[i + 4*1] + (block[i + 4*3]>>1);
+
+ block[i + 4*0]= z0 + z3;
+ block[i + 4*1]= z1 + z2;
+ block[i + 4*2]= z1 - z2;
+ block[i + 4*3]= z0 - z3;
}
for(i=0; i<4; i++){
- const int z0= block[0 + block_stride*i] + block[2 + block_stride*i];
- const int z1= block[0 + block_stride*i] - block[2 + block_stride*i];
- const int z2= (block[1 + block_stride*i]>>1) - block[3 + block_stride*i];
- const int z3= block[1 + block_stride*i] + (block[3 + block_stride*i]>>1);
-
- dst[i + 0*stride]= CLIP(add*dst[i + 0*stride] + ((z0 + z3) >> shift));
- dst[i + 1*stride]= CLIP(add*dst[i + 1*stride] + ((z1 + z2) >> shift));
- dst[i + 2*stride]= CLIP(add*dst[i + 2*stride] + ((z1 - z2) >> shift));
- dst[i + 3*stride]= CLIP(add*dst[i + 3*stride] + ((z0 - z3) >> shift));
+ const int z0= block[0 + 4*i] + block[2 + 4*i];
+ const int z1= block[0 + 4*i] - block[2 + 4*i];
+ const int z2= (block[1 + 4*i]>>1) - block[3 + 4*i];
+ const int z3= block[1 + 4*i] + (block[3 + 4*i]>>1);
+
+ dst[i + 0*stride]= CLIP(dst[i + 0*stride] + ((z0 + z3) >> 6));
+ dst[i + 1*stride]= CLIP(dst[i + 1*stride] + ((z1 + z2) >> 6));
+ dst[i + 2*stride]= CLIP(dst[i + 2*stride] + ((z1 - z2) >> 6));
+ dst[i + 3*stride]= CLIP(dst[i + 3*stride] + ((z0 - z3) >> 6));
}
}
-void FUNCC(ff_h264_idct_add)(uint8_t *dst, DCTELEM *block, int stride){
- FUNCC(idct_internal)(dst, block, stride, 4, 6, 1);
-}
-
-void FUNCC(ff_h264_lowres_idct_add)(uint8_t *dst, int stride, DCTELEM *block){
- FUNCC(idct_internal)(dst, block, stride, 8, 3, 1);
-}
-
-void FUNCC(ff_h264_lowres_idct_put)(uint8_t *dst, int stride, DCTELEM *block){
- FUNCC(idct_internal)(dst, block, stride, 8, 3, 0);
-}
-
void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, DCTELEM *_block, int stride){
int i;
INIT_CLIP
@@ -200,7 +189,7 @@ void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *b
int nnz = nnzc[ scan8[i] ];
if(nnz){
if(nnz==1 && ((dctcoef*)block)[i*16]) FUNCC(ff_h264_idct_dc_add)(dst + block_offset[i], block + i*16*sizeof(pixel), stride);
- else FUNCC(idct_internal )(dst + block_offset[i], block + i*16*sizeof(pixel), stride, 4, 6, 1);
+ else FUNCC(ff_h264_idct_add )(dst + block_offset[i], block + i*16*sizeof(pixel), stride);
}
}
}
@@ -208,7 +197,7 @@ void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *b
void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
int i;
for(i=0; i<16; i++){
- if(nnzc[ scan8[i] ]) FUNCC(idct_internal )(dst + block_offset[i], block + i*16*sizeof(pixel), stride, 4, 6, 1);
+ if(nnzc[ scan8[i] ]) FUNCC(ff_h264_idct_add )(dst + block_offset[i], block + i*16*sizeof(pixel), stride);
else if(((dctcoef*)block)[i*16]) FUNCC(ff_h264_idct_dc_add)(dst + block_offset[i], block + i*16*sizeof(pixel), stride);
}
}
@@ -235,8 +224,32 @@ void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, DCTELEM *
}
}
}
+
+void FUNCC(ff_h264_idct_add8_422)(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+ int i, j;
+
+ for(j=1; j<3; j++){
+ for(i=j*16; i<j*16+4; i++){
+ if(nnzc[ scan8[i] ])
+ FUNCC(ff_h264_idct_add )(dest[j-1] + block_offset[i], block + i*16*sizeof(pixel), stride);
+ else if(((dctcoef*)block)[i*16])
+ FUNCC(ff_h264_idct_dc_add)(dest[j-1] + block_offset[i], block + i*16*sizeof(pixel), stride);
+ }
+ }
+
+ for(j=1; j<3; j++){
+ for(i=j*16+4; i<j*16+8; i++){
+ if(nnzc[ scan8[i+4] ])
+ FUNCC(ff_h264_idct_add )(dest[j-1] + block_offset[i+4], block + i*16*sizeof(pixel), stride);
+ else if(((dctcoef*)block)[i*16])
+ FUNCC(ff_h264_idct_dc_add)(dest[j-1] + block_offset[i+4], block + i*16*sizeof(pixel), stride);
+ }
+ }
+}
+
/**
* IDCT transforms the 16 dc values and dequantizes them.
+ * @param qmul quantization parameter
*/
void FUNCC(ff_h264_luma_dc_dequant_idct)(DCTELEM *_output, DCTELEM *_input, int qmul){
#define stride 16
@@ -273,6 +286,33 @@ void FUNCC(ff_h264_luma_dc_dequant_idct)(DCTELEM *_output, DCTELEM *_input, int
#undef stride
}
+void FUNCC(ff_h264_chroma422_dc_dequant_idct)(DCTELEM *_block, int qmul){
+ const int stride= 16*2;
+ const int xStride= 16;
+ int i;
+ int temp[8];
+ static const uint8_t x_offset[2]={0, 16};
+ dctcoef *block = (dctcoef*)_block;
+
+ for(i=0; i<4; i++){
+ temp[2*i+0] = block[stride*i + xStride*0] + block[stride*i + xStride*1];
+ temp[2*i+1] = block[stride*i + xStride*0] - block[stride*i + xStride*1];
+ }
+
+ for(i=0; i<2; i++){
+ const int offset= x_offset[i];
+ const int z0= temp[2*0+i] + temp[2*2+i];
+ const int z1= temp[2*0+i] - temp[2*2+i];
+ const int z2= temp[2*1+i] - temp[2*3+i];
+ const int z3= temp[2*1+i] + temp[2*3+i];
+
+ block[stride*0+offset]= ((z0 + z3)*qmul + 128) >> 8;
+ block[stride*1+offset]= ((z1 + z2)*qmul + 128) >> 8;
+ block[stride*2+offset]= ((z1 - z2)*qmul + 128) >> 8;
+ block[stride*3+offset]= ((z0 - z3)*qmul + 128) >> 8;
+ }
+}
+
void FUNCC(ff_h264_chroma_dc_dequant_idct)(DCTELEM *_block, int qmul){
const int stride= 16*2;
const int xStride= 16;
diff --git a/libavcodec/h264pred.c b/libavcodec/h264pred.c
index b3701ef..37a4cf1 100644
--- a/libavcodec/h264pred.c
+++ b/libavcodec/h264pred.c
@@ -40,7 +40,7 @@
#undef BIT_DEPTH
static void pred4x4_vertical_vp8_c(uint8_t *src, const uint8_t *topright, int stride){
- const int lt= src[-1-1*stride];
+ const unsigned lt = src[-1-1*stride];
LOAD_TOP_EDGE
LOAD_TOP_RIGHT_EDGE
uint32_t v = PACK_4U8((lt + 2*t0 + t1 + 2) >> 2,
@@ -55,7 +55,7 @@ static void pred4x4_vertical_vp8_c(uint8_t *src, const uint8_t *topright, int st
}
static void pred4x4_horizontal_vp8_c(uint8_t *src, const uint8_t *topright, int stride){
- const int lt= src[-1-1*stride];
+ const unsigned lt = src[-1-1*stride];
LOAD_LEFT_EDGE
AV_WN32A(src+0*stride, ((lt + 2*l0 + l1 + 2) >> 2)*0x01010101);
@@ -67,8 +67,6 @@ static void pred4x4_horizontal_vp8_c(uint8_t *src, const uint8_t *topright, int
static void pred4x4_down_left_svq3_c(uint8_t *src, const uint8_t *topright, int stride){
LOAD_TOP_EDGE
LOAD_LEFT_EDGE
- const av_unused int unu0= t0;
- const av_unused int unu1= l0;
src[0+0*stride]=(l1 + t1)>>1;
src[1+0*stride]=
@@ -292,7 +290,7 @@ static void pred16x16_tm_vp8_c(uint8_t *src, int stride){
static void pred8x8_left_dc_rv40_c(uint8_t *src, int stride){
int i;
- int dc0;
+ unsigned dc0;
dc0=0;
for(i=0;i<8; i++)
@@ -307,7 +305,7 @@ static void pred8x8_left_dc_rv40_c(uint8_t *src, int stride){
static void pred8x8_top_dc_rv40_c(uint8_t *src, int stride){
int i;
- int dc0;
+ unsigned dc0;
dc0=0;
for(i=0;i<8; i++)
@@ -322,7 +320,7 @@ static void pred8x8_top_dc_rv40_c(uint8_t *src, int stride){
static void pred8x8_dc_rv40_c(uint8_t *src, int stride){
int i;
- int dc0=0;
+ unsigned dc0 = 0;
for(i=0;i<4; i++){
dc0+= src[-1+i*stride] + src[i-stride];
@@ -363,7 +361,7 @@ static void pred8x8_tm_vp8_c(uint8_t *src, int stride){
/**
* Set the intra prediction function pointers.
*/
-void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth){
+void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc){
// MpegEncContext * const s = &h->s;
#undef FUNC
@@ -436,20 +434,39 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth){
h->pred8x8l[TOP_DC_PRED ]= FUNCC(pred8x8l_top_dc , depth);\
h->pred8x8l[DC_128_PRED ]= FUNCC(pred8x8l_128_dc , depth);\
\
- h->pred8x8[VERT_PRED8x8 ]= FUNCC(pred8x8_vertical , depth);\
- h->pred8x8[HOR_PRED8x8 ]= FUNCC(pred8x8_horizontal , depth);\
+ if (chroma_format_idc == 1) {\
+ h->pred8x8[VERT_PRED8x8 ]= FUNCC(pred8x8_vertical , depth);\
+ h->pred8x8[HOR_PRED8x8 ]= FUNCC(pred8x8_horizontal , depth);\
+ } else {\
+ h->pred8x8[VERT_PRED8x8 ]= FUNCC(pred8x16_vertical , depth);\
+ h->pred8x8[HOR_PRED8x8 ]= FUNCC(pred8x16_horizontal , depth);\
+ }\
if (codec_id != CODEC_ID_VP8) {\
- h->pred8x8[PLANE_PRED8x8]= FUNCC(pred8x8_plane , depth);\
+ if (chroma_format_idc == 1) {\
+ h->pred8x8[PLANE_PRED8x8]= FUNCC(pred8x8_plane , depth);\
+ } else {\
+ h->pred8x8[PLANE_PRED8x8]= FUNCC(pred8x16_plane , depth);\
+ }\
} else\
h->pred8x8[PLANE_PRED8x8]= FUNCD(pred8x8_tm_vp8);\
if(codec_id != CODEC_ID_RV40 && codec_id != CODEC_ID_VP8){\
- h->pred8x8[DC_PRED8x8 ]= FUNCC(pred8x8_dc , depth);\
- h->pred8x8[LEFT_DC_PRED8x8]= FUNCC(pred8x8_left_dc , depth);\
- h->pred8x8[TOP_DC_PRED8x8 ]= FUNCC(pred8x8_top_dc , depth);\
- h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_l0t, depth);\
- h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_0lt, depth);\
- h->pred8x8[ALZHEIMER_DC_L00_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_l00, depth);\
- h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_0l0, depth);\
+ if (chroma_format_idc == 1) {\
+ h->pred8x8[DC_PRED8x8 ]= FUNCC(pred8x8_dc , depth);\
+ h->pred8x8[LEFT_DC_PRED8x8]= FUNCC(pred8x8_left_dc , depth);\
+ h->pred8x8[TOP_DC_PRED8x8 ]= FUNCC(pred8x8_top_dc , depth);\
+ h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_l0t, depth);\
+ h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_0lt, depth);\
+ h->pred8x8[ALZHEIMER_DC_L00_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_l00, depth);\
+ h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8 ]= FUNC(pred8x8_mad_cow_dc_0l0, depth);\
+ } else {\
+ h->pred8x8[DC_PRED8x8 ]= FUNCC(pred8x16_dc , depth);\
+ h->pred8x8[LEFT_DC_PRED8x8]= FUNCC(pred8x16_left_dc , depth);\
+ h->pred8x8[TOP_DC_PRED8x8 ]= FUNCC(pred8x16_top_dc , depth);\
+ h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8 ]= FUNC(pred8x16_mad_cow_dc_l0t, depth);\
+ h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8 ]= FUNC(pred8x16_mad_cow_dc_0lt, depth);\
+ h->pred8x8[ALZHEIMER_DC_L00_PRED8x8 ]= FUNC(pred8x16_mad_cow_dc_l00, depth);\
+ h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8 ]= FUNC(pred8x16_mad_cow_dc_0l0, depth);\
+ }\
}else{\
h->pred8x8[DC_PRED8x8 ]= FUNCD(pred8x8_dc_rv40);\
h->pred8x8[LEFT_DC_PRED8x8]= FUNCD(pred8x8_left_dc_rv40);\
@@ -459,7 +476,11 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth){
h->pred8x8[DC_129_PRED8x8]= FUNCC(pred8x8_129_dc , depth);\
}\
}\
- h->pred8x8[DC_128_PRED8x8 ]= FUNCC(pred8x8_128_dc , depth);\
+ if (chroma_format_idc == 1) {\
+ h->pred8x8[DC_128_PRED8x8 ]= FUNCC(pred8x8_128_dc , depth);\
+ } else {\
+ h->pred8x8[DC_128_PRED8x8 ]= FUNCC(pred8x16_128_dc , depth);\
+ }\
\
h->pred16x16[DC_PRED8x8 ]= FUNCC(pred16x16_dc , depth);\
h->pred16x16[VERT_PRED8x8 ]= FUNCC(pred16x16_vertical , depth);\
@@ -489,8 +510,13 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth){
h->pred4x4_add [ HOR_PRED ]= FUNCC(pred4x4_horizontal_add , depth);\
h->pred8x8l_add [VERT_PRED ]= FUNCC(pred8x8l_vertical_add , depth);\
h->pred8x8l_add [ HOR_PRED ]= FUNCC(pred8x8l_horizontal_add , depth);\
+ if (chroma_format_idc == 1) {\
h->pred8x8_add [VERT_PRED8x8]= FUNCC(pred8x8_vertical_add , depth);\
h->pred8x8_add [ HOR_PRED8x8]= FUNCC(pred8x8_horizontal_add , depth);\
+ } else {\
+ h->pred8x8_add [VERT_PRED8x8]= FUNCC(pred8x16_vertical_add , depth);\
+ h->pred8x8_add [ HOR_PRED8x8]= FUNCC(pred8x16_horizontal_add , depth);\
+ }\
h->pred16x16_add[VERT_PRED8x8]= FUNCC(pred16x16_vertical_add , depth);\
h->pred16x16_add[ HOR_PRED8x8]= FUNCC(pred16x16_horizontal_add , depth);\
@@ -506,6 +532,6 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth){
break;
}
- if (ARCH_ARM) ff_h264_pred_init_arm(h, codec_id, bit_depth);
- if (HAVE_MMX) ff_h264_pred_init_x86(h, codec_id, bit_depth);
+ if (ARCH_ARM) ff_h264_pred_init_arm(h, codec_id, bit_depth, chroma_format_idc);
+ if (HAVE_MMX) ff_h264_pred_init_x86(h, codec_id, bit_depth, chroma_format_idc);
}
diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
index 34b1e90..b880446 100644
--- a/libavcodec/h264pred.h
+++ b/libavcodec/h264pred.h
@@ -101,8 +101,8 @@ typedef struct H264PredContext{
void (*pred16x16_add[3])(uint8_t *pix/*align 16*/, const int *block_offset, const DCTELEM *block/*align 16*/, int stride);
}H264PredContext;
-void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth);
-void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, const int bit_depth);
-void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth);
+void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc);
+void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc);
+void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc);
#endif /* AVCODEC_H264PRED_H */
diff --git a/libavcodec/h264pred_template.c b/libavcodec/h264pred_template.c
index 1c1fe0b..19100b6 100644
--- a/libavcodec/h264pred_template.c
+++ b/libavcodec/h264pred_template.c
@@ -26,7 +26,8 @@
*/
#include "mathops.h"
-#include "high_bit_depth.h"
+
+#include "bit_depth_template.c"
static void FUNCC(pred4x4_vertical)(uint8_t *_src, const uint8_t *topright, int _stride){
pixel *src = (pixel*)_src;
@@ -120,28 +121,28 @@ static void FUNCC(pred4x4_129_dc)(uint8_t *_src, const uint8_t *topright, int _s
#define LOAD_TOP_RIGHT_EDGE\
- const int av_unused t4= topright[0];\
- const int av_unused t5= topright[1];\
- const int av_unused t6= topright[2];\
- const int av_unused t7= topright[3];\
+ const unsigned av_unused t4 = topright[0];\
+ const unsigned av_unused t5 = topright[1];\
+ const unsigned av_unused t6 = topright[2];\
+ const unsigned av_unused t7 = topright[3];\
#define LOAD_DOWN_LEFT_EDGE\
- const int av_unused l4= src[-1+4*stride];\
- const int av_unused l5= src[-1+5*stride];\
- const int av_unused l6= src[-1+6*stride];\
- const int av_unused l7= src[-1+7*stride];\
+ const unsigned av_unused l4 = src[-1+4*stride];\
+ const unsigned av_unused l5 = src[-1+5*stride];\
+ const unsigned av_unused l6 = src[-1+6*stride];\
+ const unsigned av_unused l7 = src[-1+7*stride];\
#define LOAD_LEFT_EDGE\
- const int av_unused l0= src[-1+0*stride];\
- const int av_unused l1= src[-1+1*stride];\
- const int av_unused l2= src[-1+2*stride];\
- const int av_unused l3= src[-1+3*stride];\
+ const unsigned av_unused l0 = src[-1+0*stride];\
+ const unsigned av_unused l1 = src[-1+1*stride];\
+ const unsigned av_unused l2 = src[-1+2*stride];\
+ const unsigned av_unused l3 = src[-1+3*stride];\
#define LOAD_TOP_EDGE\
- const int av_unused t0= src[ 0-1*stride];\
- const int av_unused t1= src[ 1-1*stride];\
- const int av_unused t2= src[ 2-1*stride];\
- const int av_unused t3= src[ 3-1*stride];\
+ const unsigned av_unused t0 = src[ 0-1*stride];\
+ const unsigned av_unused t1 = src[ 1-1*stride];\
+ const unsigned av_unused t2 = src[ 2-1*stride];\
+ const unsigned av_unused t3 = src[ 3-1*stride];\
static void FUNCC(pred4x4_down_right)(uint8_t *_src, const uint8_t *topright, int _stride){
pixel *src = (pixel*)_src;
@@ -387,9 +388,9 @@ static void FUNCC(pred16x16_##n##_dc)(uint8_t *_src, int stride){\
PREDICT_16x16_DC(PIXEL_SPLAT_X4(v));\
}
-PRED16x16_X(127, (1<<(BIT_DEPTH-1))-1);
-PRED16x16_X(128, (1<<(BIT_DEPTH-1))+0);
-PRED16x16_X(129, (1<<(BIT_DEPTH-1))+1);
+PRED16x16_X(127, (1<<(BIT_DEPTH-1))-1)
+PRED16x16_X(128, (1<<(BIT_DEPTH-1))+0)
+PRED16x16_X(129, (1<<(BIT_DEPTH-1))+1)
static inline void FUNCC(pred16x16_plane_compat)(uint8_t *_src, int _stride, const int svq3, const int rv40){
int i, j, k;
@@ -453,6 +454,19 @@ static void FUNCC(pred8x8_vertical)(uint8_t *_src, int _stride){
}
}
+static void FUNCC(pred8x16_vertical)(uint8_t *_src, int _stride){
+ int i;
+ pixel *src = (pixel*)_src;
+ int stride = _stride>>(sizeof(pixel)-1);
+ const pixel4 a= AV_RN4PA(((pixel4*)(src-stride))+0);
+ const pixel4 b= AV_RN4PA(((pixel4*)(src-stride))+1);
+
+ for(i=0; i<16; i++){
+ AV_WN4PA(((pixel4*)(src+i*stride))+0, a);
+ AV_WN4PA(((pixel4*)(src+i*stride))+1, b);
+ }
+}
+
static void FUNCC(pred8x8_horizontal)(uint8_t *_src, int stride){
int i;
pixel *src = (pixel*)_src;
@@ -465,6 +479,17 @@ static void FUNCC(pred8x8_horizontal)(uint8_t *_src, int stride){
}
}
+static void FUNCC(pred8x16_horizontal)(uint8_t *_src, int stride){
+ int i;
+ pixel *src = (pixel*)_src;
+ stride >>= sizeof(pixel)-1;
+ for(i=0; i<16; i++){
+ const pixel4 a = PIXEL_SPLAT_X4(src[-1+i*stride]);
+ AV_WN4PA(((pixel4*)(src+i*stride))+0, a);
+ AV_WN4PA(((pixel4*)(src+i*stride))+1, a);
+ }
+}
+
#define PRED8x8_X(n, v)\
static void FUNCC(pred8x8_##n##_dc)(uint8_t *_src, int stride){\
int i;\
@@ -477,9 +502,14 @@ static void FUNCC(pred8x8_##n##_dc)(uint8_t *_src, int stride){\
}\
}
-PRED8x8_X(127, (1<<(BIT_DEPTH-1))-1);
-PRED8x8_X(128, (1<<(BIT_DEPTH-1))+0);
-PRED8x8_X(129, (1<<(BIT_DEPTH-1))+1);
+PRED8x8_X(127, (1<<(BIT_DEPTH-1))-1)
+PRED8x8_X(128, (1<<(BIT_DEPTH-1))+0)
+PRED8x8_X(129, (1<<(BIT_DEPTH-1))+1)
+
+static void FUNCC(pred8x16_128_dc)(uint8_t *_src, int stride){
+ FUNCC(pred8x8_128_dc)(_src, stride);
+ FUNCC(pred8x8_128_dc)(_src+8*stride, stride);
+}
static void FUNCC(pred8x8_left_dc)(uint8_t *_src, int stride){
int i;
@@ -506,6 +536,11 @@ static void FUNCC(pred8x8_left_dc)(uint8_t *_src, int stride){
}
}
+static void FUNCC(pred8x16_left_dc)(uint8_t *_src, int stride){
+ FUNCC(pred8x8_left_dc)(_src, stride);
+ FUNCC(pred8x8_left_dc)(_src+8*stride, stride);
+}
+
static void FUNCC(pred8x8_top_dc)(uint8_t *_src, int stride){
int i;
int dc0, dc1;
@@ -531,6 +566,27 @@ static void FUNCC(pred8x8_top_dc)(uint8_t *_src, int stride){
}
}
+static void FUNCC(pred8x16_top_dc)(uint8_t *_src, int stride){
+ int i;
+ int dc0, dc1;
+ pixel4 dc0splat, dc1splat;
+ pixel *src = (pixel*)_src;
+ stride >>= sizeof(pixel)-1;
+
+ dc0=dc1=0;
+ for(i=0;i<4; i++){
+ dc0+= src[i-stride];
+ dc1+= src[4+i-stride];
+ }
+ dc0splat = PIXEL_SPLAT_X4((dc0 + 2)>>2);
+ dc1splat = PIXEL_SPLAT_X4((dc1 + 2)>>2);
+
+ for(i=0; i<16; i++){
+ AV_WN4PA(((pixel4*)(src+i*stride))+0, dc0splat);
+ AV_WN4PA(((pixel4*)(src+i*stride))+1, dc1splat);
+ }
+}
+
static void FUNCC(pred8x8_dc)(uint8_t *_src, int stride){
int i;
int dc0, dc1, dc2;
@@ -559,29 +615,92 @@ static void FUNCC(pred8x8_dc)(uint8_t *_src, int stride){
}
}
-//the following 4 function should not be optimized!
+static void FUNCC(pred8x16_dc)(uint8_t *_src, int stride){
+ int i;
+ int dc0, dc1, dc2, dc3, dc4;
+ pixel4 dc0splat, dc1splat, dc2splat, dc3splat, dc4splat, dc5splat, dc6splat, dc7splat;
+ pixel *src = (pixel*)_src;
+ stride >>= sizeof(pixel)-1;
+
+ dc0=dc1=dc2=dc3=dc4=0;
+ for(i=0;i<4; i++){
+ dc0+= src[-1+i*stride] + src[i-stride];
+ dc1+= src[4+i-stride];
+ dc2+= src[-1+(i+4)*stride];
+ dc3+= src[-1+(i+8)*stride];
+ dc4+= src[-1+(i+12)*stride];
+ }
+ dc0splat = PIXEL_SPLAT_X4((dc0 + 4)>>3);
+ dc1splat = PIXEL_SPLAT_X4((dc1 + 2)>>2);
+ dc2splat = PIXEL_SPLAT_X4((dc2 + 2)>>2);
+ dc3splat = PIXEL_SPLAT_X4((dc1 + dc2 + 4)>>3);
+ dc4splat = PIXEL_SPLAT_X4((dc3 + 2)>>2);
+ dc5splat = PIXEL_SPLAT_X4((dc1 + dc3 + 4)>>3);
+ dc6splat = PIXEL_SPLAT_X4((dc4 + 2)>>2);
+ dc7splat = PIXEL_SPLAT_X4((dc1 + dc4 + 4)>>3);
+
+ for(i=0; i<4; i++){
+ AV_WN4PA(((pixel4*)(src+i*stride))+0, dc0splat);
+ AV_WN4PA(((pixel4*)(src+i*stride))+1, dc1splat);
+ }
+ for(i=4; i<8; i++){
+ AV_WN4PA(((pixel4*)(src+i*stride))+0, dc2splat);
+ AV_WN4PA(((pixel4*)(src+i*stride))+1, dc3splat);
+ }
+ for(i=8; i<12; i++){
+ AV_WN4PA(((pixel4*)(src+i*stride))+0, dc4splat);
+ AV_WN4PA(((pixel4*)(src+i*stride))+1, dc5splat);
+ }
+ for(i=12; i<16; i++){
+ AV_WN4PA(((pixel4*)(src+i*stride))+0, dc6splat);
+ AV_WN4PA(((pixel4*)(src+i*stride))+1, dc7splat);
+ }
+}
+
static void FUNC(pred8x8_mad_cow_dc_l0t)(uint8_t *src, int stride){
FUNCC(pred8x8_top_dc)(src, stride);
FUNCC(pred4x4_dc)(src, NULL, stride);
}
+static void FUNC(pred8x16_mad_cow_dc_l0t)(uint8_t *src, int stride){
+ FUNCC(pred8x16_top_dc)(src, stride);
+ FUNCC(pred4x4_dc)(src, NULL, stride);
+}
+
static void FUNC(pred8x8_mad_cow_dc_0lt)(uint8_t *src, int stride){
FUNCC(pred8x8_dc)(src, stride);
FUNCC(pred4x4_top_dc)(src, NULL, stride);
}
+static void FUNC(pred8x16_mad_cow_dc_0lt)(uint8_t *src, int stride){
+ FUNCC(pred8x16_dc)(src, stride);
+ FUNCC(pred4x4_top_dc)(src, NULL, stride);
+}
+
static void FUNC(pred8x8_mad_cow_dc_l00)(uint8_t *src, int stride){
FUNCC(pred8x8_left_dc)(src, stride);
FUNCC(pred4x4_128_dc)(src + 4*stride , NULL, stride);
FUNCC(pred4x4_128_dc)(src + 4*stride + 4*sizeof(pixel), NULL, stride);
}
+static void FUNC(pred8x16_mad_cow_dc_l00)(uint8_t *src, int stride){
+ FUNCC(pred8x16_left_dc)(src, stride);
+ FUNCC(pred4x4_128_dc)(src + 4*stride , NULL, stride);
+ FUNCC(pred4x4_128_dc)(src + 4*stride + 4*sizeof(pixel), NULL, stride);
+}
+
static void FUNC(pred8x8_mad_cow_dc_0l0)(uint8_t *src, int stride){
FUNCC(pred8x8_left_dc)(src, stride);
FUNCC(pred4x4_128_dc)(src , NULL, stride);
FUNCC(pred4x4_128_dc)(src + 4*sizeof(pixel), NULL, stride);
}
+static void FUNC(pred8x16_mad_cow_dc_0l0)(uint8_t *src, int stride){
+ FUNCC(pred8x16_left_dc)(src, stride);
+ FUNCC(pred4x4_128_dc)(src , NULL, stride);
+ FUNCC(pred4x4_128_dc)(src + 4*sizeof(pixel), NULL, stride);
+}
+
static void FUNCC(pred8x8_plane)(uint8_t *_src, int _stride){
int j, k;
int a;
@@ -617,6 +736,47 @@ static void FUNCC(pred8x8_plane)(uint8_t *_src, int _stride){
}
}
+static void FUNCC(pred8x16_plane)(uint8_t *_src, int _stride){
+ int j, k;
+ int a;
+ INIT_CLIP
+ pixel *src = (pixel*)_src;
+ int stride = _stride>>(sizeof(pixel)-1);
+ const pixel * const src0 = src +3-stride;
+ const pixel * src1 = src +8*stride-1;
+ const pixel * src2 = src1-2*stride; // == src+6*stride-1;
+ int H = src0[1] - src0[-1];
+ int V = src1[0] - src2[ 0];
+
+ for (k = 2; k <= 4; ++k) {
+ src1 += stride; src2 -= stride;
+ H += k*(src0[k] - src0[-k]);
+ V += k*(src1[0] - src2[ 0]);
+ }
+ for (; k <= 8; ++k) {
+ src1 += stride; src2 -= stride;
+ V += k*(src1[0] - src2[0]);
+ }
+
+ H = (17*H+16) >> 5;
+ V = (5*V+32) >> 6;
+
+ a = 16*(src1[0] + src2[8] + 1) - 7*V - 3*H;
+ for(j=16; j>0; --j) {
+ int b = a;
+ a += V;
+ src[0] = CLIP((b ) >> 5);
+ src[1] = CLIP((b+ H) >> 5);
+ src[2] = CLIP((b+2*H) >> 5);
+ src[3] = CLIP((b+3*H) >> 5);
+ src[4] = CLIP((b+4*H) >> 5);
+ src[5] = CLIP((b+5*H) >> 5);
+ src[6] = CLIP((b+6*H) >> 5);
+ src[7] = CLIP((b+7*H) >> 5);
+ src += stride;
+ }
+}
+
#define SRC(x,y) src[(x)+(y)*stride]
#define PL(y) \
const int l##y = (SRC(-1,y-1) + 2*SRC(-1,y) + SRC(-1,y+1) + 2) >> 2;
@@ -987,8 +1147,24 @@ static void FUNCC(pred8x8_vertical_add)(uint8_t *pix, const int *block_offset, c
FUNCC(pred4x4_vertical_add)(pix + block_offset[i], block + i*16*sizeof(pixel), stride);
}
+static void FUNCC(pred8x16_vertical_add)(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){
+ int i;
+ for(i=0; i<4; i++)
+ FUNCC(pred4x4_vertical_add)(pix + block_offset[i], block + i*16*sizeof(pixel), stride);
+ for(i=4; i<8; i++)
+ FUNCC(pred4x4_vertical_add)(pix + block_offset[i+4], block + i*16*sizeof(pixel), stride);
+}
+
static void FUNCC(pred8x8_horizontal_add)(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){
int i;
for(i=0; i<4; i++)
FUNCC(pred4x4_horizontal_add)(pix + block_offset[i], block + i*16*sizeof(pixel), stride);
}
+
+static void FUNCC(pred8x16_horizontal_add)(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){
+ int i;
+ for(i=0; i<4; i++)
+ FUNCC(pred4x4_horizontal_add)(pix + block_offset[i], block + i*16*sizeof(pixel), stride);
+ for(i=4; i<8; i++)
+ FUNCC(pred4x4_horizontal_add)(pix + block_offset[i+4], block + i*16*sizeof(pixel), stride);
+}
diff --git a/libavcodec/high_bit_depth.h b/libavcodec/high_bit_depth.h
deleted file mode 100644
index c0a6eaf..0000000
--- a/libavcodec/high_bit_depth.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "dsputil.h"
-
-#ifndef BIT_DEPTH
-#define BIT_DEPTH 8
-#endif
-
-#ifdef AVCODEC_H264_HIGH_DEPTH_H
-# undef pixel
-# undef pixel2
-# undef pixel4
-# undef dctcoef
-# undef INIT_CLIP
-# undef no_rnd_avg_pixel4
-# undef rnd_avg_pixel4
-# undef AV_RN2P
-# undef AV_RN4P
-# undef AV_RN4PA
-# undef AV_WN2P
-# undef AV_WN4P
-# undef AV_WN4PA
-# undef CLIP
-# undef FUNC
-# undef FUNCC
-# undef av_clip_pixel
-# undef PIXEL_SPLAT_X4
-#else
-# define AVCODEC_H264_HIGH_DEPTH_H
-# define CLIP_PIXEL(depth)\
- static inline uint16_t av_clip_pixel_ ## depth (int p)\
- {\
- const int pixel_max = (1 << depth)-1;\
- return (p & ~pixel_max) ? (-p)>>31 & pixel_max : p;\
- }
-
-CLIP_PIXEL( 9)
-CLIP_PIXEL(10)
-#endif
-
-#if BIT_DEPTH > 8
-# define pixel uint16_t
-# define pixel2 uint32_t
-# define pixel4 uint64_t
-# define dctcoef int32_t
-
-# define INIT_CLIP
-# define no_rnd_avg_pixel4 no_rnd_avg64
-# define rnd_avg_pixel4 rnd_avg64
-# define AV_RN2P AV_RN32
-# define AV_RN4P AV_RN64
-# define AV_RN4PA AV_RN64A
-# define AV_WN2P AV_WN32
-# define AV_WN4P AV_WN64
-# define AV_WN4PA AV_WN64A
-# define PIXEL_SPLAT_X4(x) ((x)*0x0001000100010001ULL)
-#else
-# define pixel uint8_t
-# define pixel2 uint16_t
-# define pixel4 uint32_t
-# define dctcoef int16_t
-
-# define INIT_CLIP uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
-# define no_rnd_avg_pixel4 no_rnd_avg32
-# define rnd_avg_pixel4 rnd_avg32
-# define AV_RN2P AV_RN16
-# define AV_RN4P AV_RN32
-# define AV_RN4PA AV_RN32A
-# define AV_WN2P AV_WN16
-# define AV_WN4P AV_WN32
-# define AV_WN4PA AV_WN32A
-# define PIXEL_SPLAT_X4(x) ((x)*0x01010101U)
-#endif
-
-#if BIT_DEPTH == 8
-# define av_clip_pixel(a) av_clip_uint8(a)
-# define CLIP(a) cm[a]
-# define FUNC(a) a ## _8
-# define FUNCC(a) a ## _8_c
-#elif BIT_DEPTH == 9
-# define av_clip_pixel(a) av_clip_pixel_9(a)
-# define CLIP(a) av_clip_pixel_9(a)
-# define FUNC(a) a ## _9
-# define FUNCC(a) a ## _9_c
-#elif BIT_DEPTH == 10
-# define av_clip_pixel(a) av_clip_pixel_10(a)
-# define CLIP(a) av_clip_pixel_10(a)
-# define FUNC(a) a ## _10
-# define FUNCC(a) a ## _10_c
-#endif
diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c
index 211ea63..4fb6530 100644
--- a/libavcodec/huffman.c
+++ b/libavcodec/huffman.c
@@ -1,6 +1,4 @@
-/**
- * @file
- * huffman tree builder and VLC generator
+/*
* Copyright (c) 2006 Konstantin Shishkov
*
* This file is part of Libav.
@@ -20,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * huffman tree builder and VLC generator
+ */
+
#include "avcodec.h"
#include "get_bits.h"
#include "huffman.h"
diff --git a/libavcodec/huffman.h b/libavcodec/huffman.h
index 4a60187..5625313 100644
--- a/libavcodec/huffman.h
+++ b/libavcodec/huffman.h
@@ -1,6 +1,4 @@
-/**
- * @file
- * huffman tree builder and VLC generator
+/*
* Copyright (C) 2007 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of Libav.
@@ -20,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * huffman tree builder and VLC generator
+ */
+
#ifndef AVCODEC_HUFFMAN_H
#define AVCODEC_HUFFMAN_H
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index a399142..57b5f32 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -921,8 +921,8 @@ static int encode_bgr_bitstream(HYuvContext *s, int count){
#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
static void draw_slice(HYuvContext *s, int y){
- int h, cy;
- int offset[4];
+ int h, cy, i;
+ int offset[AV_NUM_DATA_POINTERS];
if(s->avctx->draw_horiz_band==NULL)
return;
@@ -939,7 +939,8 @@ static void draw_slice(HYuvContext *s, int y){
offset[0] = s->picture.linesize[0]*y;
offset[1] = s->picture.linesize[1]*cy;
offset[2] = s->picture.linesize[2]*cy;
- offset[3] = 0;
+ for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
+ offset[i] = 0;
emms_c();
s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
@@ -1435,16 +1436,14 @@ static av_cold int encode_end(AVCodecContext *avctx)
#if CONFIG_HUFFYUV_DECODER
AVCodec ff_huffyuv_decoder = {
- "huffyuv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_HUFFYUV,
- sizeof(HYuvContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS,
- NULL,
+ .name = "huffyuv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_HUFFYUV,
+ .priv_data_size = sizeof(HYuvContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS,
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
};
@@ -1452,16 +1451,14 @@ AVCodec ff_huffyuv_decoder = {
#if CONFIG_FFVHUFF_DECODER
AVCodec ff_ffvhuff_decoder = {
- "ffvhuff",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FFVHUFF,
- sizeof(HYuvContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS,
- NULL,
+ .name = "ffvhuff",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FFVHUFF,
+ .priv_data_size = sizeof(HYuvContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS,
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
};
@@ -1469,13 +1466,13 @@ AVCodec ff_ffvhuff_decoder = {
#if CONFIG_HUFFYUV_ENCODER
AVCodec ff_huffyuv_encoder = {
- "huffyuv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_HUFFYUV,
- sizeof(HYuvContext),
- encode_init,
- encode_frame,
- encode_end,
+ .name = "huffyuv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_HUFFYUV,
+ .priv_data_size = sizeof(HYuvContext),
+ .init = encode_init,
+ .encode = encode_frame,
+ .close = encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
};
@@ -1483,13 +1480,13 @@ AVCodec ff_huffyuv_encoder = {
#if CONFIG_FFVHUFF_ENCODER
AVCodec ff_ffvhuff_encoder = {
- "ffvhuff",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FFVHUFF,
- sizeof(HYuvContext),
- encode_init,
- encode_frame,
- encode_end,
+ .name = "ffvhuff",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FFVHUFF,
+ .priv_data_size = sizeof(HYuvContext),
+ .init = encode_init,
+ .encode = encode_frame,
+ .close = encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
};
diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c
index ac56e19..8ae15eb 100644
--- a/libavcodec/idcinvideo.c
+++ b/libavcodec/idcinvideo.c
@@ -36,7 +36,7 @@
* a little more compression by exploiting the fact that adjacent pixels
* tend to be similar.
*
- * Note that this decoder could use ffmpeg's optimized VLC facilities
+ * Note that this decoder could use libavcodec's optimized VLC facilities
* rather than naive, tree-based Huffman decoding. However, there are 256
* Huffman tables. Plus, the VLC bit coding order is right -> left instead
* or left -> right, so all of the bits would have to be reversed. Further,
@@ -254,15 +254,14 @@ static av_cold int idcin_decode_end(AVCodecContext *avctx)
}
AVCodec ff_idcin_decoder = {
- "idcinvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_IDCIN,
- sizeof(IdcinContext),
- idcin_decode_init,
- NULL,
- idcin_decode_end,
- idcin_decode_frame,
- CODEC_CAP_DR1,
+ .name = "idcinvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_IDCIN,
+ .priv_data_size = sizeof(IdcinContext),
+ .init = idcin_decode_init,
+ .close = idcin_decode_end,
+ .decode = idcin_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("id Quake II CIN video"),
};
diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index 63e1f31..41e7b59 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -368,27 +368,25 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_iff_ilbm_decoder = {
- "iff_ilbm",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_IFF_ILBM,
- sizeof(IffContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame_ilbm,
- CODEC_CAP_DR1,
+ .name = "iff_ilbm",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_IFF_ILBM,
+ .priv_data_size = sizeof(IffContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame_ilbm,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
};
AVCodec ff_iff_byterun1_decoder = {
- "iff_byterun1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_IFF_BYTERUN1,
- sizeof(IffContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame_byterun1,
- CODEC_CAP_DR1,
+ .name = "iff_byterun1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_IFF_BYTERUN1,
+ .priv_data_size = sizeof(IffContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame_byterun1,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
};
diff --git a/libavcodec/iirfilter.c b/libavcodec/iirfilter.c
index a942068..34d3962 100644
--- a/libavcodec/iirfilter.c
+++ b/libavcodec/iirfilter.c
@@ -311,6 +311,9 @@ av_cold void ff_iir_filter_free_coeffs(struct FFIIRFilterCoeffs *coeffs)
}
#ifdef TEST
+#undef printf
+#include <stdio.h>
+
#define FILT_ORDER 4
#define SIZE 1024
int main(void)
@@ -320,7 +323,6 @@ int main(void)
float cutoff_coeff = 0.4;
int16_t x[SIZE], y[SIZE];
int i;
- FILE* fd;
fcoeffs = ff_iir_filter_init_coeffs(NULL, FF_FILTER_TYPE_BUTTERWORTH,
FF_FILTER_MODE_LOWPASS, FILT_ORDER,
@@ -333,13 +335,8 @@ int main(void)
ff_iir_filter(fcoeffs, fstate, SIZE, x, 1, y, 1);
- fd = fopen("in.bin", "w");
- fwrite(x, sizeof(x[0]), SIZE, fd);
- fclose(fd);
-
- fd = fopen("out.bin", "w");
- fwrite(y, sizeof(y[0]), SIZE, fd);
- fclose(fd);
+ for (i = 0; i < SIZE; i++)
+ printf("%6d %6d\n", x[i], y[i]);
ff_iir_filter_free_coeffs(fcoeffs);
ff_iir_filter_free_state(fstate);
diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index 07d6cad..ff8e31e 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -35,7 +35,6 @@
#include <stddef.h>
#include <stdio.h>
-#define ALT_BITSTREAM_READER
#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
@@ -51,6 +50,8 @@
#define COEFFS 256
typedef struct {
+ AVFrame frame;
+
float old_floor[BANDS];
float flcoeffs1[BANDS];
float flcoeffs2[BANDS];
@@ -104,10 +105,15 @@ static VLC_TYPE vlc_tables[VLC_TABLES_SIZE][2];
static av_cold int imc_decode_init(AVCodecContext * avctx)
{
- int i, j;
+ int i, j, ret;
IMCContext *q = avctx->priv_data;
double r1, r2;
+ if (avctx->channels != 1) {
+ av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
q->decoder_reset = 1;
for(i = 0; i < BANDS; i++)
@@ -156,10 +162,17 @@ static av_cold int imc_decode_init(AVCodecContext * avctx)
}
q->one_div_log2 = 1/log(2);
- ff_fft_init(&q->fft, 7, 1);
+ if ((ret = ff_fft_init(&q->fft, 7, 1))) {
+ av_log(avctx, AV_LOG_INFO, "FFT init failed\n");
+ return ret;
+ }
dsputil_init(&q->dsp, avctx);
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
- avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
+ avctx->channel_layout = AV_CH_LAYOUT_MONO;
+
+ avcodec_get_frame_defaults(&q->frame);
+ avctx->coded_frame = &q->frame;
+
return 0;
}
@@ -336,7 +349,7 @@ static int bit_allocation (IMCContext* q, int stream_format_code, int freebits,
indx = 2;
if (indx == -1)
- return -1;
+ return AVERROR_INVALIDDATA;
q->flcoeffs4[i] = q->flcoeffs4[i] + xTab[(indx*2 + (q->flcoeffs1[i] < highest)) * 2 + flag];
}
@@ -595,7 +608,7 @@ static int inverse_quant_coeff (IMCContext* q, int stream_format_code) {
middle_value = max_size >> 1;
if (q->codewords[j] >= max_size || q->codewords[j] < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
if (cw_len >= 4){
quantizer = imc_quantizer2[(stream_format_code & 2) >> 1];
@@ -628,7 +641,7 @@ static int imc_get_coeffs (IMCContext* q) {
if (get_bits_count(&q->gb) + cw_len > 512){
//av_log(NULL,0,"Band %i coeff %i cw_len %i\n",i,j,cw_len);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if(cw_len && (!q->bandFlagsBuf[i] || !q->skipFlags[j]))
@@ -641,9 +654,8 @@ static int imc_get_coeffs (IMCContext* q) {
return 0;
}
-static int imc_decode_frame(AVCodecContext * avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int imc_decode_frame(AVCodecContext * avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
@@ -651,20 +663,27 @@ static int imc_decode_frame(AVCodecContext * avctx,
IMCContext *q = avctx->priv_data;
int stream_format_code;
- int imc_hdr, i, j;
+ int imc_hdr, i, j, ret;
int flag;
int bits, summer;
int counter, bitscount;
- uint16_t buf16[IMC_BLOCK_SIZE / 2];
+ LOCAL_ALIGNED_16(uint16_t, buf16, [IMC_BLOCK_SIZE / 2]);
if (buf_size < IMC_BLOCK_SIZE) {
av_log(avctx, AV_LOG_ERROR, "imc frame too small!\n");
- return -1;
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* get output buffer */
+ q->frame.nb_samples = COEFFS;
+ if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
- for(i = 0; i < IMC_BLOCK_SIZE / 2; i++)
- buf16[i] = av_bswap16(((const uint16_t*)buf)[i]);
+ q->out_samples = (float *)q->frame.data[0];
+
+ q->dsp.bswap16_buf(buf16, (const uint16_t*)buf, IMC_BLOCK_SIZE / 2);
- q->out_samples = data;
init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8);
/* Check the frame header */
@@ -672,13 +691,13 @@ static int imc_decode_frame(AVCodecContext * avctx,
if (imc_hdr != IMC_FRAME_ID) {
av_log(avctx, AV_LOG_ERROR, "imc frame header check failed!\n");
av_log(avctx, AV_LOG_ERROR, "got %x instead of 0x21.\n", imc_hdr);
- return -1;
+ return AVERROR_INVALIDDATA;
}
stream_format_code = get_bits(&q->gb, 3);
if(stream_format_code & 1){
av_log(avctx, AV_LOG_ERROR, "Stream code format %X is not supported\n", stream_format_code);
- return -1;
+ return AVERROR_INVALIDDATA;
}
// av_log(avctx, AV_LOG_DEBUG, "stream_format_code = %d\n", stream_format_code);
@@ -738,10 +757,11 @@ static int imc_decode_frame(AVCodecContext * avctx,
}
}
- if(bit_allocation (q, stream_format_code, 512 - bitscount - get_bits_count(&q->gb), flag) < 0) {
+ if((ret = bit_allocation (q, stream_format_code,
+ 512 - bitscount - get_bits_count(&q->gb), flag)) < 0) {
av_log(avctx, AV_LOG_ERROR, "Bit allocations failed\n");
q->decoder_reset = 1;
- return -1;
+ return ret;
}
for(i = 0; i < BANDS; i++) {
@@ -795,20 +815,21 @@ static int imc_decode_frame(AVCodecContext * avctx,
if(imc_get_coeffs(q) < 0) {
av_log(avctx, AV_LOG_ERROR, "Read coefficients failed\n");
q->decoder_reset = 1;
- return 0;
+ return AVERROR_INVALIDDATA;
}
if(inverse_quant_coeff(q, stream_format_code) < 0) {
av_log(avctx, AV_LOG_ERROR, "Inverse quantization of coefficients failed\n");
q->decoder_reset = 1;
- return 0;
+ return AVERROR_INVALIDDATA;
}
memset(q->skipFlags, 0, sizeof(q->skipFlags));
imc_imdct256(q);
- *data_size = COEFFS * sizeof(float);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = q->frame;
return IMC_BLOCK_SIZE;
}
@@ -819,6 +840,7 @@ static av_cold int imc_decode_close(AVCodecContext * avctx)
IMCContext *q = avctx->priv_data;
ff_fft_end(&q->fft);
+
return 0;
}
@@ -831,5 +853,6 @@ AVCodec ff_imc_decoder = {
.init = imc_decode_init,
.close = imc_decode_close,
.decode = imc_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
};
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index 351ed7a..eb398f7 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -42,9 +42,6 @@
#include "x86/dsputil_mmx.h"
#endif
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-
#define FF_COLOR_RGB 0 /**< RGB color space */
#define FF_COLOR_GRAY 1 /**< gray color space */
#define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
@@ -865,6 +862,7 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
return 0;
}
+#if FF_API_GET_ALPHA_INFO
/* NOTE: we scan all the pixels to have an exact information */
static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
{
@@ -911,6 +909,7 @@ int img_get_alpha_info(const AVPicture *src,
}
return ret;
}
+#endif
#if !(HAVE_MMX && HAVE_YASM)
/* filter parameters: [-1 4 2 4 -1] // 8 */
diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c
index 544f476..ecf89cc 100644
--- a/libavcodec/indeo2.c
+++ b/libavcodec/indeo2.c
@@ -23,7 +23,7 @@
* @file
* Intel Indeo 2 decoder.
*/
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "get_bits.h"
#include "indeo2data.h"
@@ -166,7 +166,7 @@ static int ir2_decode_frame(AVCodecContext *avctx,
s->decode_delta = buf[18];
/* decide whether frame uses deltas or not */
-#ifndef ALT_BITSTREAM_READER_LE
+#ifndef BITSTREAM_READER_LE
for (i = 0; i < buf_size; i++)
buf[i] = av_reverse[buf[i]];
#endif
@@ -207,7 +207,7 @@ static av_cold int ir2_decode_init(AVCodecContext *avctx){
ir2_vlc.table = vlc_tables;
ir2_vlc.table_allocated = 1 << CODE_VLC_BITS;
-#ifdef ALT_BITSTREAM_READER_LE
+#ifdef BITSTREAM_READER_LE
init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES,
&ir2_codes[0][1], 4, 2,
&ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
@@ -231,14 +231,13 @@ static av_cold int ir2_decode_end(AVCodecContext *avctx){
}
AVCodec ff_indeo2_decoder = {
- "indeo2",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_INDEO2,
- sizeof(Ir2Context),
- ir2_decode_init,
- NULL,
- ir2_decode_end,
- ir2_decode_frame,
- CODEC_CAP_DR1,
+ .name = "indeo2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_INDEO2,
+ .priv_data_size = sizeof(Ir2Context),
+ .init = ir2_decode_init,
+ .close = ir2_decode_end,
+ .decode = ir2_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
};
diff --git a/libavcodec/indeo2data.h b/libavcodec/indeo2data.h
index ef85e32..ed8d83c 100644
--- a/libavcodec/indeo2data.h
+++ b/libavcodec/indeo2data.h
@@ -26,7 +26,7 @@
#define IR2_CODES 143
static const uint16_t ir2_codes[IR2_CODES][2] = {
-#ifdef ALT_BITSTREAM_READER_LE
+#ifdef BITSTREAM_READER_LE
{0x0000, 3}, {0x0004, 3}, {0x0006, 3}, {0x0001, 5},
{0x0009, 5}, {0x0019, 5}, {0x000D, 5}, {0x001D, 5},
{0x0023, 6}, {0x0013, 6}, {0x0033, 6}, {0x000B, 6},
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 30b7085..46efbd8 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -1,6 +1,6 @@
/*
- * Intel Indeo 3 (IV31, IV32, etc.) video decoder for ffmpeg
- * written, produced, and directed by Alan Smithee
+ * Indeo Video v3 compatible decoder
+ * Copyright (c) 2009 - 2011 Maxim Poliakovski
*
* This file is part of Libav.
*
@@ -19,1134 +19,1052 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+/**
+ * @file
+ * This is a decoder for Intel Indeo Video v3.
+ * It is based on vector quantization, run-length coding and motion compensation.
+ * Known container formats: .avi and .mov
+ * Known FOURCCs: 'IV31', 'IV32'
+ *
+ * @see http://wiki.multimedia.cx/index.php?title=Indeo_3
+ */
#include "libavutil/imgutils.h"
+#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "dsputil.h"
#include "bytestream.h"
+#include "get_bits.h"
#include "indeo3data.h"
-typedef struct
-{
- uint8_t *Ybuf;
- uint8_t *Ubuf;
- uint8_t *Vbuf;
- unsigned short y_w, y_h;
- unsigned short uv_w, uv_h;
-} YUVBufs;
+/* RLE opcodes. */
+enum {
+ RLE_ESC_F9 = 249, ///< same as RLE_ESC_FA + do the same with next block
+ RLE_ESC_FA = 250, ///< INTRA: skip block, INTER: copy data from reference
+ RLE_ESC_FB = 251, ///< apply null delta to N blocks / skip N blocks
+ RLE_ESC_FC = 252, ///< same as RLE_ESC_FD + do the same with next block
+ RLE_ESC_FD = 253, ///< apply null delta to all remaining lines of this block
+ RLE_ESC_FE = 254, ///< apply null delta to all lines up to the 3rd line
+ RLE_ESC_FF = 255 ///< apply null delta to all lines up to the 2nd line
+};
-typedef struct Indeo3DecodeContext {
- AVCodecContext *avctx;
- int width, height;
- AVFrame frame;
- uint8_t *buf;
- YUVBufs iv_frame[2];
- YUVBufs *cur_frame;
- YUVBufs *ref_frame;
+/* Some constants for parsing frame bitstream flags. */
+#define BS_8BIT_PEL (1 << 1) ///< 8bit pixel bitdepth indicator
+#define BS_KEYFRAME (1 << 2) ///< intra frame indicator
+#define BS_MV_Y_HALF (1 << 4) ///< vertical mv halfpel resolution indicator
+#define BS_MV_X_HALF (1 << 5) ///< horizontal mv halfpel resolution indicator
+#define BS_NONREF (1 << 8) ///< nonref (discardable) frame indicator
+#define BS_BUFFER 9 ///< indicates which of two frame buffers should be used
+
- uint8_t *ModPred;
- uint8_t *corrector_type;
+typedef struct Plane {
+ uint8_t *buffers[2];
+ uint8_t *pixels[2]; ///< pointer to the actual pixel data of the buffers above
+ uint32_t width;
+ uint32_t height;
+ uint32_t pitch;
+} Plane;
+
+#define CELL_STACK_MAX 20
+
+typedef struct Cell {
+ int16_t xpos; ///< cell coordinates in 4x4 blocks
+ int16_t ypos;
+ int16_t width; ///< cell width in 4x4 blocks
+ int16_t height; ///< cell height in 4x4 blocks
+ uint8_t tree; ///< tree id: 0- MC tree, 1 - VQ tree
+ const int8_t *mv_ptr; ///< ptr to the motion vector if any
+} Cell;
+
+typedef struct Indeo3DecodeContext {
+ AVCodecContext *avctx;
+ AVFrame frame;
+ DSPContext dsp;
+
+ GetBitContext gb;
+ int need_resync;
+ int skip_bits;
+ const uint8_t *next_cell_data;
+ const uint8_t *last_byte;
+ const int8_t *mc_vectors;
+
+ int16_t width, height;
+ uint32_t frame_num; ///< current frame number (zero-based)
+ uint32_t data_size; ///< size of the frame data in bytes
+ uint16_t frame_flags; ///< frame properties
+ uint8_t cb_offset; ///< needed for selecting VQ tables
+ uint8_t buf_sel; ///< active frame buffer: 0 - primary, 1 -secondary
+ const uint8_t *y_data_ptr;
+ const uint8_t *v_data_ptr;
+ const uint8_t *u_data_ptr;
+ int32_t y_data_size;
+ int32_t v_data_size;
+ int32_t u_data_size;
+ const uint8_t *alt_quant; ///< secondary VQ table set for the modes 1 and 4
+ Plane planes[3];
} Indeo3DecodeContext;
-static const uint8_t corrector_type_0[24] = {
- 195, 159, 133, 115, 101, 93, 87, 77,
- 195, 159, 133, 115, 101, 93, 87, 77,
- 128, 79, 79, 79, 79, 79, 79, 79
-};
-static const uint8_t corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 };
+static uint8_t requant_tab[8][128];
-static av_cold int build_modpred(Indeo3DecodeContext *s)
+/*
+ * Build the static requantization table.
+ * This table is used to remap pixel values according to a specific
+ * quant index and thus avoid overflows while adding deltas.
+ */
+static av_cold void build_requant_tab(void)
{
- int i, j;
-
- if (!(s->ModPred = av_malloc(8 * 128)))
- return AVERROR(ENOMEM);
-
- for (i=0; i < 128; ++i) {
- s->ModPred[i+0*128] = i > 126 ? 254 : 2*(i + 1 - ((i + 1) % 2));
- s->ModPred[i+1*128] = i == 7 ? 20 :
- i == 119 ||
- i == 120 ? 236 : 2*(i + 2 - ((i + 1) % 3));
- s->ModPred[i+2*128] = i > 125 ? 248 : 2*(i + 2 - ((i + 2) % 4));
- s->ModPred[i+3*128] = 2*(i + 1 - ((i - 3) % 5));
- s->ModPred[i+4*128] = i == 8 ? 20 : 2*(i + 1 - ((i - 3) % 6));
- s->ModPred[i+5*128] = 2*(i + 4 - ((i + 3) % 7));
- s->ModPred[i+6*128] = i > 123 ? 240 : 2*(i + 4 - ((i + 4) % 8));
- s->ModPred[i+7*128] = 2*(i + 5 - ((i + 4) % 9));
- }
+ static int8_t offsets[8] = { 1, 1, 2, -3, -3, 3, 4, 4 };
+ static int8_t deltas [8] = { 0, 1, 0, 4, 4, 1, 0, 1 };
- if (!(s->corrector_type = av_malloc(24 * 256)))
- return AVERROR(ENOMEM);
+ int i, j, step;
- for (i=0; i < 24; ++i) {
- for (j=0; j < 256; ++j) {
- s->corrector_type[i*256+j] = j < corrector_type_0[i] ? 1 :
- j < 248 || (i == 16 && j == 248) ? 0 :
- corrector_type_2[j - 248];
- }
+ for (i = 0; i < 8; i++) {
+ step = i + 2;
+ for (j = 0; j < 128; j++)
+ requant_tab[i][j] = (j + offsets[i]) / step * step + deltas[i];
}
- return 0;
+ /* some last elements calculated above will have values >= 128 */
+ /* pixel values shall never exceed 127 so set them to non-overflowing values */
+ /* according with the quantization step of the respective section */
+ requant_tab[0][127] = 126;
+ requant_tab[1][119] = 118;
+ requant_tab[1][120] = 118;
+ requant_tab[2][126] = 124;
+ requant_tab[2][127] = 124;
+ requant_tab[6][124] = 120;
+ requant_tab[6][125] = 120;
+ requant_tab[6][126] = 120;
+ requant_tab[6][127] = 120;
+
+ /* Patch for compatibility with the Intel's binary decoders */
+ requant_tab[1][7] = 10;
+ requant_tab[4][8] = 10;
}
-static av_cold int iv_alloc_frames(Indeo3DecodeContext *s)
+
+static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx,
+ AVCodecContext *avctx)
{
- int luma_width = (s->width + 3) & ~3,
- luma_height = (s->height + 3) & ~3,
- chroma_width = ((luma_width >> 2) + 3) & ~3,
- chroma_height = ((luma_height >> 2) + 3) & ~3,
- luma_pixels = luma_width * luma_height,
- chroma_pixels = chroma_width * chroma_height,
- i;
- unsigned int bufsize = luma_pixels * 2 + luma_width * 3 +
- (chroma_pixels + chroma_width) * 4;
-
- av_freep(&s->buf);
- if(!(s->buf = av_malloc(bufsize)))
- return AVERROR(ENOMEM);
- s->iv_frame[0].y_w = s->iv_frame[1].y_w = luma_width;
- s->iv_frame[0].y_h = s->iv_frame[1].y_h = luma_height;
- s->iv_frame[0].uv_w = s->iv_frame[1].uv_w = chroma_width;
- s->iv_frame[0].uv_h = s->iv_frame[1].uv_h = chroma_height;
-
- s->iv_frame[0].Ybuf = s->buf + luma_width;
- i = luma_pixels + luma_width * 2;
- s->iv_frame[1].Ybuf = s->buf + i;
- i += (luma_pixels + luma_width);
- s->iv_frame[0].Ubuf = s->buf + i;
- i += (chroma_pixels + chroma_width);
- s->iv_frame[1].Ubuf = s->buf + i;
- i += (chroma_pixels + chroma_width);
- s->iv_frame[0].Vbuf = s->buf + i;
- i += (chroma_pixels + chroma_width);
- s->iv_frame[1].Vbuf = s->buf + i;
-
- for(i = 1; i <= luma_width; i++)
- s->iv_frame[0].Ybuf[-i] = s->iv_frame[1].Ybuf[-i] =
- s->iv_frame[0].Ubuf[-i] = 0x80;
-
- for(i = 1; i <= chroma_width; i++) {
- s->iv_frame[1].Ubuf[-i] = 0x80;
- s->iv_frame[0].Vbuf[-i] = 0x80;
- s->iv_frame[1].Vbuf[-i] = 0x80;
- s->iv_frame[1].Vbuf[chroma_pixels+i-1] = 0x80;
+ int p, luma_width, luma_height, chroma_width, chroma_height;
+ int luma_pitch, chroma_pitch, luma_size, chroma_size;
+
+ luma_width = ctx->width;
+ luma_height = ctx->height;
+
+ if (luma_width < 16 || luma_width > 640 ||
+ luma_height < 16 || luma_height > 480 ||
+ luma_width & 3 || luma_height & 3) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid picture dimensions: %d x %d!\n",
+ luma_width, luma_height);
+ return AVERROR_INVALIDDATA;
+ }
+
+ chroma_width = FFALIGN(luma_width >> 2, 4);
+ chroma_height = FFALIGN(luma_height >> 2, 4);
+
+ luma_pitch = FFALIGN(luma_width, 16);
+ chroma_pitch = FFALIGN(chroma_width, 16);
+
+ /* Calculate size of the luminance plane. */
+ /* Add one line more for INTRA prediction. */
+ luma_size = luma_pitch * (luma_height + 1);
+
+ /* Calculate size of a chrominance planes. */
+ /* Add one line more for INTRA prediction. */
+ chroma_size = chroma_pitch * (chroma_height + 1);
+
+ /* allocate frame buffers */
+ for (p = 0; p < 3; p++) {
+ ctx->planes[p].pitch = !p ? luma_pitch : chroma_pitch;
+ ctx->planes[p].width = !p ? luma_width : chroma_width;
+ ctx->planes[p].height = !p ? luma_height : chroma_height;
+
+ ctx->planes[p].buffers[0] = av_malloc(!p ? luma_size : chroma_size);
+ ctx->planes[p].buffers[1] = av_malloc(!p ? luma_size : chroma_size);
+
+ /* fill the INTRA prediction lines with the middle pixel value = 64 */
+ memset(ctx->planes[p].buffers[0], 0x40, ctx->planes[p].pitch);
+ memset(ctx->planes[p].buffers[1], 0x40, ctx->planes[p].pitch);
+
+ /* set buffer pointers = buf_ptr + pitch and thus skip the INTRA prediction line */
+ ctx->planes[p].pixels[0] = ctx->planes[p].buffers[0] + ctx->planes[p].pitch;
+ ctx->planes[p].pixels[1] = ctx->planes[p].buffers[1] + ctx->planes[p].pitch;
}
return 0;
}
-static av_cold void iv_free_func(Indeo3DecodeContext *s)
+
+static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
{
- av_freep(&s->buf);
- av_freep(&s->ModPred);
- av_freep(&s->corrector_type);
+ int p;
+
+ for (p = 0; p < 3; p++) {
+ av_freep(&ctx->planes[p].buffers[0]);
+ av_freep(&ctx->planes[p].buffers[1]);
+ }
}
-struct ustr {
- int xpos;
- int ypos;
- int width;
- int height;
- int split_flag;
- int split_direction;
- int usl7;
-};
+/**
+ * Copy pixels of the cell(x + mv_x, y + mv_y) from the previous frame into
+ * the cell(x, y) in the current frame.
+ *
+ * @param ctx pointer to the decoder context
+ * @param plane pointer to the plane descriptor
+ * @param cell pointer to the cell descriptor
+ */
+static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
+{
+ int h, w, mv_x, mv_y, offset, offset_dst;
+ uint8_t *src, *dst;
+
+ /* setup output and reference pointers */
+ offset_dst = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
+ dst = plane->pixels[ctx->buf_sel] + offset_dst;
+ mv_y = cell->mv_ptr[0];
+ mv_x = cell->mv_ptr[1];
+ offset = offset_dst + mv_y * plane->pitch + mv_x;
+ src = plane->pixels[ctx->buf_sel ^ 1] + offset;
+
+ h = cell->height << 2;
+
+ for (w = cell->width; w > 0;) {
+ /* copy using 16xH blocks */
+ if (!((cell->xpos << 2) & 15) && w >= 4) {
+ for (; w >= 4; src += 16, dst += 16, w -= 4)
+ ctx->dsp.put_no_rnd_pixels_tab[0][0](dst, src, plane->pitch, h);
+ }
+
+ /* copy using 8xH blocks */
+ if (!((cell->xpos << 2) & 7) && w >= 2) {
+ ctx->dsp.put_no_rnd_pixels_tab[1][0](dst, src, plane->pitch, h);
+ w -= 2;
+ src += 8;
+ dst += 8;
+ }
-#define LV1_CHECK(buf1,rle_v3,lv1,lp2) \
- if((lv1 & 0x80) != 0) { \
- if(rle_v3 != 0) \
- rle_v3 = 0; \
- else { \
- rle_v3 = 1; \
- buf1 -= 2; \
- } \
- } \
- lp2 = 4;
-
-
-#define RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) \
- if(rle_v3 == 0) { \
- rle_v2 = *buf1; \
- rle_v1 = 1; \
- if(rle_v2 > 32) { \
- rle_v2 -= 32; \
- rle_v1 = 0; \
- } \
- rle_v3 = 1; \
- } \
- buf1--;
-
-
-#define LP2_CHECK(buf1,rle_v3,lp2) \
- if(lp2 == 0 && rle_v3 != 0) \
- rle_v3 = 0; \
- else { \
- buf1--; \
- rle_v3 = 1; \
+ if (w >= 1) {
+ copy_block4(dst, src, plane->pitch, plane->pitch, h);
+ w--;
+ src += 4;
+ dst += 4;
+ }
}
+}
-#define RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) \
- rle_v2--; \
- if(rle_v2 == 0) { \
- rle_v3 = 0; \
- buf1 += 2; \
- } \
- lp2 = 4;
+/* Average 4/8 pixels at once without rounding using SWAR */
+#define AVG_32(dst, src, ref) \
+ AV_WN32A(dst, ((AV_RN32A(src) + AV_RN32A(ref)) >> 1) & 0x7F7F7F7FUL)
-static void iv_Decode_Chunk(Indeo3DecodeContext *s,
- uint8_t *cur, uint8_t *ref, int width, int height,
- const uint8_t *buf1, int cb_offset, const uint8_t *hdr,
- const uint8_t *buf2, int min_width_160)
-{
- uint8_t bit_buf;
- unsigned int bit_pos, lv, lv1, lv2;
- int *width_tbl, width_tbl_arr[10];
- const signed char *ref_vectors;
- uint8_t *cur_frm_pos, *ref_frm_pos, *cp, *cp2;
- uint32_t *cur_lp, *ref_lp;
- const uint32_t *correction_lp[2], *correctionloworder_lp[2], *correctionhighorder_lp[2];
- uint8_t *correction_type_sp[2];
- struct ustr strip_tbl[20], *strip;
- int i, j, k, lp1, lp2, flag1, cmd, blks_width, blks_height, region_160_width,
- rle_v1, rle_v2, rle_v3;
- unsigned short res;
-
- bit_buf = 0;
- ref_vectors = NULL;
-
- width_tbl = width_tbl_arr + 1;
- i = (width < 0 ? width + 3 : width)/4;
- for(j = -1; j < 8; j++)
- width_tbl[j] = i * j;
-
- strip = strip_tbl;
-
- for(region_160_width = 0; region_160_width < (width - min_width_160); region_160_width += min_width_160);
-
- strip->ypos = strip->xpos = 0;
- for(strip->width = min_width_160; width > strip->width; strip->width *= 2);
- strip->height = height;
- strip->split_direction = 0;
- strip->split_flag = 0;
- strip->usl7 = 0;
-
- bit_pos = 0;
-
- rle_v1 = rle_v2 = rle_v3 = 0;
-
- while(strip >= strip_tbl) {
- if(bit_pos <= 0) {
- bit_pos = 8;
- bit_buf = *buf1++;
- }
+#define AVG_64(dst, src, ref) \
+ AV_WN64A(dst, ((AV_RN64A(src) + AV_RN64A(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL)
- bit_pos -= 2;
- cmd = (bit_buf >> bit_pos) & 0x03;
- if(cmd == 0) {
- strip++;
- if(strip >= strip_tbl + FF_ARRAY_ELEMS(strip_tbl)) {
- av_log(s->avctx, AV_LOG_WARNING, "out of range strip\n");
- break;
- }
- memcpy(strip, strip-1, sizeof(*strip));
- strip->split_flag = 1;
- strip->split_direction = 0;
- strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4);
- continue;
- } else if(cmd == 1) {
- strip++;
- if(strip >= strip_tbl + FF_ARRAY_ELEMS(strip_tbl)) {
- av_log(s->avctx, AV_LOG_WARNING, "out of range strip\n");
- break;
- }
- memcpy(strip, strip-1, sizeof(*strip));
- strip->split_flag = 1;
- strip->split_direction = 1;
- strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4);
- continue;
- } else if(cmd == 2) {
- if(strip->usl7 == 0) {
- strip->usl7 = 1;
- ref_vectors = NULL;
- continue;
- }
- } else if(cmd == 3) {
- if(strip->usl7 == 0) {
- strip->usl7 = 1;
- ref_vectors = (const signed char*)buf2 + (*buf1 * 2);
- buf1++;
- continue;
- }
- }
+/*
+ * Replicate each even pixel as follows:
+ * ABCDEFGH -> AACCEEGG
+ */
+static inline uint64_t replicate64(uint64_t a) {
+#if HAVE_BIGENDIAN
+ a &= 0xFF00FF00FF00FF00ULL;
+ a |= a >> 8;
+#else
+ a &= 0x00FF00FF00FF00FFULL;
+ a |= a << 8;
+#endif
+ return a;
+}
- cur_frm_pos = cur + width * strip->ypos + strip->xpos;
+static inline uint32_t replicate32(uint32_t a) {
+#if HAVE_BIGENDIAN
+ a &= 0xFF00FF00UL;
+ a |= a >> 8;
+#else
+ a &= 0x00FF00FFUL;
+ a |= a << 8;
+#endif
+ return a;
+}
- if((blks_width = strip->width) < 0)
- blks_width += 3;
- blks_width >>= 2;
- blks_height = strip->height;
- if(ref_vectors != NULL) {
- ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width +
- ref_vectors[1] + strip->xpos;
- } else
- ref_frm_pos = cur_frm_pos - width_tbl[4];
+/* Fill n lines with 64bit pixel value pix */
+static inline void fill_64(uint8_t *dst, const uint64_t pix, int32_t n,
+ int32_t row_offset)
+{
+ for (; n > 0; dst += row_offset, n--)
+ AV_WN64A(dst, pix);
+}
- if(cmd == 2) {
- if(bit_pos <= 0) {
- bit_pos = 8;
- bit_buf = *buf1++;
- }
- bit_pos -= 2;
- cmd = (bit_buf >> bit_pos) & 0x03;
+/* Error codes for cell decoding. */
+enum {
+ IV3_NOERR = 0,
+ IV3_BAD_RLE = 1,
+ IV3_BAD_DATA = 2,
+ IV3_BAD_COUNTER = 3,
+ IV3_UNSUPPORTED = 4,
+ IV3_OUT_OF_DATA = 5
+};
- if(cmd == 0 || ref_vectors != NULL) {
- for(lp1 = 0; lp1 < blks_width; lp1++) {
- for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1])
- ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
- cur_frm_pos += 4;
- ref_frm_pos += 4;
- }
- } else if(cmd != 1)
- return;
- } else {
- k = *buf1 >> 4;
- j = *buf1 & 0x0f;
- buf1++;
- lv = j + cb_offset;
-
- if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) {
- cp2 = s->ModPred + ((lv - 8) << 7);
- cp = ref_frm_pos;
- for(i = 0; i < blks_width << 2; i++) {
- int v = *cp >> 1;
- *(cp++) = cp2[v];
- }
- }
- if(k == 1 || k == 4) {
- lv = (hdr[j] & 0xf) + cb_offset;
- correction_type_sp[0] = s->corrector_type + (lv << 8);
- correction_lp[0] = correction + (lv << 8);
- lv = (hdr[j] >> 4) + cb_offset;
- correction_lp[1] = correction + (lv << 8);
- correction_type_sp[1] = s->corrector_type + (lv << 8);
- } else {
- correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8);
- correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8);
- correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8);
- correction_lp[0] = correction_lp[1] = correction + (lv << 8);
- }
+#define BUFFER_PRECHECK \
+if (*data_ptr >= last_ptr) \
+ return IV3_OUT_OF_DATA; \
+
+#define RLE_BLOCK_COPY \
+ if (cell->mv_ptr || !skip_flag) \
+ copy_block4(dst, ref, row_offset, row_offset, 4 << v_zoom)
+
+#define RLE_BLOCK_COPY_8 \
+ pix64 = AV_RN64A(ref);\
+ if (is_first_row) {/* special prediction case: top line of a cell */\
+ pix64 = replicate64(pix64);\
+ fill_64(dst + row_offset, pix64, 7, row_offset);\
+ AVG_64(dst, ref, dst + row_offset);\
+ } else \
+ fill_64(dst, pix64, 8, row_offset)
+
+#define RLE_LINES_COPY \
+ copy_block4(dst, ref, row_offset, row_offset, num_lines << v_zoom)
+
+#define RLE_LINES_COPY_M10 \
+ pix64 = AV_RN64A(ref);\
+ if (is_top_of_cell) {\
+ pix64 = replicate64(pix64);\
+ fill_64(dst + row_offset, pix64, (num_lines << 1) - 1, row_offset);\
+ AVG_64(dst, ref, dst + row_offset);\
+ } else \
+ fill_64(dst, pix64, num_lines << 1, row_offset)
+
+#define APPLY_DELTA_4 \
+ AV_WN16A(dst + line_offset , AV_RN16A(ref ) + delta_tab->deltas[dyad1]);\
+ AV_WN16A(dst + line_offset + 2, AV_RN16A(ref + 2) + delta_tab->deltas[dyad2]);\
+ if (mode >= 3) {\
+ if (is_top_of_cell && !cell->ypos) {\
+ AV_COPY32(dst, dst + row_offset);\
+ } else {\
+ AVG_32(dst, ref, dst + row_offset);\
+ }\
+ }
- switch(k) {
- case 1:
- case 0: /********** CASE 0 **********/
- for( ; blks_height > 0; blks_height -= 4) {
- for(lp1 = 0; lp1 < blks_width; lp1++) {
- for(lp2 = 0; lp2 < 4; ) {
- k = *buf1++;
- cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2];
- ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2];
-
- switch(correction_type_sp[0][k]) {
- case 0:
- *cur_lp = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
- lp2++;
- break;
- case 1:
- res = ((av_le2ne16(((unsigned short *)(ref_lp))[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;
- ((unsigned short *)cur_lp)[0] = av_le2ne16(res);
- res = ((av_le2ne16(((unsigned short *)(ref_lp))[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
- ((unsigned short *)cur_lp)[1] = av_le2ne16(res);
- buf1++;
- lp2++;
- break;
- case 2:
- if(lp2 == 0) {
- for(i = 0, j = 0; i < 2; i++, j += width_tbl[1])
- cur_lp[j] = ref_lp[j];
- lp2 += 2;
- }
- break;
- case 3:
- if(lp2 < 2) {
- for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1])
- cur_lp[j] = ref_lp[j];
- lp2 = 3;
- }
- break;
- case 8:
- if(lp2 == 0) {
- RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
-
- if(rle_v1 == 1 || ref_vectors != NULL) {
- for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
- cur_lp[j] = ref_lp[j];
- }
-
- RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
- break;
- } else {
- rle_v1 = 1;
- rle_v2 = *buf1 - 1;
- }
- case 5:
- LP2_CHECK(buf1,rle_v3,lp2)
- case 4:
- for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1])
- cur_lp[j] = ref_lp[j];
- lp2 = 4;
- break;
-
- case 7:
- if(rle_v3 != 0)
- rle_v3 = 0;
- else {
- buf1--;
- rle_v3 = 1;
- }
- case 6:
- if(ref_vectors != NULL) {
- for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
- cur_lp[j] = ref_lp[j];
- }
- lp2 = 4;
- break;
-
- case 9:
- lv1 = *buf1++;
- lv = (lv1 & 0x7F) << 1;
- lv += (lv << 8);
- lv += (lv << 16);
- for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
- cur_lp[j] = lv;
-
- LV1_CHECK(buf1,rle_v3,lv1,lp2)
- break;
- default:
- return;
- }
- }
+#define APPLY_DELTA_8 \
+ /* apply two 32-bit VQ deltas to next even line */\
+ if (is_top_of_cell) { \
+ AV_WN32A(dst + row_offset , \
+ replicate32(AV_RN32A(ref )) + delta_tab->deltas_m10[dyad1]);\
+ AV_WN32A(dst + row_offset + 4, \
+ replicate32(AV_RN32A(ref + 4)) + delta_tab->deltas_m10[dyad2]);\
+ } else { \
+ AV_WN32A(dst + row_offset , \
+ AV_RN32A(ref ) + delta_tab->deltas_m10[dyad1]);\
+ AV_WN32A(dst + row_offset + 4, \
+ AV_RN32A(ref + 4) + delta_tab->deltas_m10[dyad2]);\
+ } \
+ /* odd lines are not coded but rather interpolated/replicated */\
+ /* first line of the cell on the top of image? - replicate */\
+ /* otherwise - interpolate */\
+ if (is_top_of_cell && !cell->ypos) {\
+ AV_COPY64(dst, dst + row_offset);\
+ } else \
+ AVG_64(dst, ref, dst + row_offset);
+
+
+#define APPLY_DELTA_1011_INTER \
+ if (mode == 10) { \
+ AV_WN32A(dst , \
+ AV_RN32A(dst ) + delta_tab->deltas_m10[dyad1]);\
+ AV_WN32A(dst + 4 , \
+ AV_RN32A(dst + 4 ) + delta_tab->deltas_m10[dyad2]);\
+ AV_WN32A(dst + row_offset , \
+ AV_RN32A(dst + row_offset ) + delta_tab->deltas_m10[dyad1]);\
+ AV_WN32A(dst + row_offset + 4, \
+ AV_RN32A(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]);\
+ } else { \
+ AV_WN16A(dst , \
+ AV_RN16A(dst ) + delta_tab->deltas[dyad1]);\
+ AV_WN16A(dst + 2 , \
+ AV_RN16A(dst + 2 ) + delta_tab->deltas[dyad2]);\
+ AV_WN16A(dst + row_offset , \
+ AV_RN16A(dst + row_offset ) + delta_tab->deltas[dyad1]);\
+ AV_WN16A(dst + row_offset + 2, \
+ AV_RN16A(dst + row_offset + 2) + delta_tab->deltas[dyad2]);\
+ }
- cur_frm_pos += 4;
- ref_frm_pos += 4;
- }
- cur_frm_pos += ((width - blks_width) * 4);
- ref_frm_pos += ((width - blks_width) * 4);
+static int decode_cell_data(Cell *cell, uint8_t *block, uint8_t *ref_block,
+ int pitch, int h_zoom, int v_zoom, int mode,
+ const vqEntry *delta[2], int swap_quads[2],
+ const uint8_t **data_ptr, const uint8_t *last_ptr)
+{
+ int x, y, line, num_lines;
+ int rle_blocks = 0;
+ uint8_t code, *dst, *ref;
+ const vqEntry *delta_tab;
+ unsigned int dyad1, dyad2;
+ uint64_t pix64;
+ int skip_flag = 0, is_top_of_cell, is_first_row = 1;
+ int row_offset, blk_row_offset, line_offset;
+
+ row_offset = pitch;
+ blk_row_offset = (row_offset << (2 + v_zoom)) - (cell->width << 2);
+ line_offset = v_zoom ? row_offset : 0;
+
+ for (y = 0; y < cell->height; is_first_row = 0, y += 1 + v_zoom) {
+ for (x = 0; x < cell->width; x += 1 + h_zoom) {
+ ref = ref_block;
+ dst = block;
+
+ if (rle_blocks > 0) {
+ if (mode <= 4) {
+ RLE_BLOCK_COPY;
+ } else if (mode == 10 && !cell->mv_ptr) {
+ RLE_BLOCK_COPY_8;
}
- break;
-
- case 4:
- case 3: /********** CASE 3 **********/
- if(ref_vectors != NULL)
- return;
- flag1 = 1;
-
- for( ; blks_height > 0; blks_height -= 8) {
- for(lp1 = 0; lp1 < blks_width; lp1++) {
- for(lp2 = 0; lp2 < 4; ) {
- k = *buf1++;
-
- cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
- ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
-
- switch(correction_type_sp[lp2 & 0x01][k]) {
- case 0:
- cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
- if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
- cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
- else
- cur_lp[0] = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
- lp2++;
- break;
-
- case 1:
- res = ((av_le2ne16(((unsigned short *)ref_lp)[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;
- ((unsigned short *)cur_lp)[width_tbl[2]] = av_le2ne16(res);
- res = ((av_le2ne16(((unsigned short *)ref_lp)[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
- ((unsigned short *)cur_lp)[width_tbl[2]+1] = av_le2ne16(res);
-
- if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
- cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
- else
- cur_lp[0] = cur_lp[width_tbl[1]];
- buf1++;
- lp2++;
- break;
-
- case 2:
- if(lp2 == 0) {
- for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
- cur_lp[j] = *ref_lp;
- lp2 += 2;
- }
- break;
-
- case 3:
- if(lp2 < 2) {
- for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
- cur_lp[j] = *ref_lp;
- lp2 = 3;
- }
- break;
-
- case 6:
- lp2 = 4;
- break;
-
- case 7:
- if(rle_v3 != 0)
- rle_v3 = 0;
- else {
- buf1--;
- rle_v3 = 1;
+ rle_blocks--;
+ } else {
+ for (line = 0; line < 4;) {
+ num_lines = 1;
+ is_top_of_cell = is_first_row && !line;
+
+ /* select primary VQ table for odd, secondary for even lines */
+ if (mode <= 4)
+ delta_tab = delta[line & 1];
+ else
+ delta_tab = delta[1];
+ BUFFER_PRECHECK;
+ code = bytestream_get_byte(data_ptr);
+ if (code < 248) {
+ if (code < delta_tab->num_dyads) {
+ BUFFER_PRECHECK;
+ dyad1 = bytestream_get_byte(data_ptr);
+ dyad2 = code;
+ if (dyad1 >= delta_tab->num_dyads || dyad1 >= 248)
+ return IV3_BAD_DATA;
+ } else {
+ /* process QUADS */
+ code -= delta_tab->num_dyads;
+ dyad1 = code / delta_tab->quad_exp;
+ dyad2 = code % delta_tab->quad_exp;
+ if (swap_quads[line & 1])
+ FFSWAP(unsigned int, dyad1, dyad2);
+ }
+ if (mode <= 4) {
+ APPLY_DELTA_4;
+ } else if (mode == 10 && !cell->mv_ptr) {
+ APPLY_DELTA_8;
+ } else {
+ APPLY_DELTA_1011_INTER;
+ }
+ } else {
+ /* process RLE codes */
+ switch (code) {
+ case RLE_ESC_FC:
+ skip_flag = 0;
+ rle_blocks = 1;
+ code = 253;
+ /* FALLTHROUGH */
+ case RLE_ESC_FF:
+ case RLE_ESC_FE:
+ case RLE_ESC_FD:
+ num_lines = 257 - code - line;
+ if (num_lines <= 0)
+ return IV3_BAD_RLE;
+ if (mode <= 4) {
+ RLE_LINES_COPY;
+ } else if (mode == 10 && !cell->mv_ptr) {
+ RLE_LINES_COPY_M10;
+ }
+ break;
+ case RLE_ESC_FB:
+ BUFFER_PRECHECK;
+ code = bytestream_get_byte(data_ptr);
+ rle_blocks = (code & 0x1F) - 1; /* set block counter */
+ if (code >= 64 || rle_blocks < 0)
+ return IV3_BAD_COUNTER;
+ skip_flag = code & 0x20;
+ num_lines = 4 - line; /* enforce next block processing */
+ if (mode >= 10 || (cell->mv_ptr || !skip_flag)) {
+ if (mode <= 4) {
+ RLE_LINES_COPY;
+ } else if (mode == 10 && !cell->mv_ptr) {
+ RLE_LINES_COPY_M10;
}
- lp2 = 4;
- break;
-
- case 8:
- if(lp2 == 0) {
- RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
-
- if(rle_v1 == 1) {
- for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
- cur_lp[j] = ref_lp[j];
- }
-
- RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
- break;
- } else {
- rle_v2 = (*buf1) - 1;
- rle_v1 = 1;
+ }
+ break;
+ case RLE_ESC_F9:
+ skip_flag = 1;
+ rle_blocks = 1;
+ /* FALLTHROUGH */
+ case RLE_ESC_FA:
+ if (line)
+ return IV3_BAD_RLE;
+ num_lines = 4; /* enforce next block processing */
+ if (cell->mv_ptr) {
+ if (mode <= 4) {
+ RLE_LINES_COPY;
+ } else if (mode == 10 && !cell->mv_ptr) {
+ RLE_LINES_COPY_M10;
}
- case 5:
- LP2_CHECK(buf1,rle_v3,lp2)
- case 4:
- for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
- cur_lp[j] = *ref_lp;
- lp2 = 4;
- break;
-
- case 9:
- av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
- lv1 = *buf1++;
- lv = (lv1 & 0x7F) << 1;
- lv += (lv << 8);
- lv += (lv << 16);
-
- for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
- cur_lp[j] = lv;
-
- LV1_CHECK(buf1,rle_v3,lv1,lp2)
- break;
-
- default:
- return;
}
+ break;
+ default:
+ return IV3_UNSUPPORTED;
}
-
- cur_frm_pos += 4;
}
- cur_frm_pos += (((width * 2) - blks_width) * 4);
- flag1 = 0;
+ line += num_lines;
+ ref += row_offset * (num_lines << v_zoom);
+ dst += row_offset * (num_lines << v_zoom);
}
- break;
-
- case 10: /********** CASE 10 **********/
- if(ref_vectors == NULL) {
- flag1 = 1;
-
- for( ; blks_height > 0; blks_height -= 8) {
- for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
- for(lp2 = 0; lp2 < 4; ) {
- k = *buf1++;
- cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
- ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
- lv1 = ref_lp[0];
- lv2 = ref_lp[1];
- if(lp2 == 0 && flag1 != 0) {
-#if HAVE_BIGENDIAN
- lv1 = lv1 & 0xFF00FF00;
- lv1 = (lv1 >> 8) | lv1;
- lv2 = lv2 & 0xFF00FF00;
- lv2 = (lv2 >> 8) | lv2;
-#else
- lv1 = lv1 & 0x00FF00FF;
- lv1 = (lv1 << 8) | lv1;
- lv2 = lv2 & 0x00FF00FF;
- lv2 = (lv2 << 8) | lv2;
-#endif
- }
-
- switch(correction_type_sp[lp2 & 0x01][k]) {
- case 0:
- cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);
- cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(lv2) >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1);
- if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
- cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
- cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
- } else {
- cur_lp[0] = cur_lp[width_tbl[1]];
- cur_lp[1] = cur_lp[width_tbl[1]+1];
- }
- lp2++;
- break;
-
- case 1:
- cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1]) << 1);
- cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(lv2) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);
- if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
- cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
- cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
- } else {
- cur_lp[0] = cur_lp[width_tbl[1]];
- cur_lp[1] = cur_lp[width_tbl[1]+1];
- }
- buf1++;
- lp2++;
- break;
-
- case 2:
- if(lp2 == 0) {
- if(flag1 != 0) {
- for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) {
- cur_lp[j] = lv1;
- cur_lp[j+1] = lv2;
- }
- cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
- cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
- } else {
- for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
- cur_lp[j] = lv1;
- cur_lp[j+1] = lv2;
- }
- }
- lp2 += 2;
- }
- break;
-
- case 3:
- if(lp2 < 2) {
- if(lp2 == 0 && flag1 != 0) {
- for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) {
- cur_lp[j] = lv1;
- cur_lp[j+1] = lv2;
- }
- cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
- cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
- } else {
- for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
- cur_lp[j] = lv1;
- cur_lp[j+1] = lv2;
- }
- }
- lp2 = 3;
- }
- break;
-
- case 8:
- if(lp2 == 0) {
- RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
- if(rle_v1 == 1) {
- if(flag1 != 0) {
- for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
- cur_lp[j] = lv1;
- cur_lp[j+1] = lv2;
- }
- cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
- cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
- } else {
- for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
- cur_lp[j] = lv1;
- cur_lp[j+1] = lv2;
- }
- }
- }
- RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
- break;
- } else {
- rle_v1 = 1;
- rle_v2 = (*buf1) - 1;
- }
- case 5:
- LP2_CHECK(buf1,rle_v3,lp2)
- case 4:
- if(lp2 == 0 && flag1 != 0) {
- for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
- cur_lp[j] = lv1;
- cur_lp[j+1] = lv2;
- }
- cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
- cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
- } else {
- for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
- cur_lp[j] = lv1;
- cur_lp[j+1] = lv2;
- }
- }
- lp2 = 4;
- break;
-
- case 6:
- lp2 = 4;
- break;
-
- case 7:
- if(lp2 == 0) {
- if(rle_v3 != 0)
- rle_v3 = 0;
- else {
- buf1--;
- rle_v3 = 1;
- }
- lp2 = 4;
- }
- break;
-
- case 9:
- av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
- lv1 = *buf1;
- lv = (lv1 & 0x7F) << 1;
- lv += (lv << 8);
- lv += (lv << 16);
- for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
- cur_lp[j] = lv;
- LV1_CHECK(buf1,rle_v3,lv1,lp2)
- break;
-
- default:
- return;
- }
- }
-
- cur_frm_pos += 8;
- }
+ }
- cur_frm_pos += (((width * 2) - blks_width) * 4);
- flag1 = 0;
- }
- } else {
- for( ; blks_height > 0; blks_height -= 8) {
- for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
- for(lp2 = 0; lp2 < 4; ) {
- k = *buf1++;
- cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
- ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
-
- switch(correction_type_sp[lp2 & 0x01][k]) {
- case 0:
- lv1 = correctionloworder_lp[lp2 & 0x01][k];
- lv2 = correctionhighorder_lp[lp2 & 0x01][k];
- cur_lp[0] = av_le2ne32(((av_le2ne32(ref_lp[0]) >> 1) + lv1) << 1);
- cur_lp[1] = av_le2ne32(((av_le2ne32(ref_lp[1]) >> 1) + lv2) << 1);
- cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);
- cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);
- lp2++;
- break;
-
- case 1:
- lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++];
- lv2 = correctionloworder_lp[lp2 & 0x01][k];
- cur_lp[0] = av_le2ne32(((av_le2ne32(ref_lp[0]) >> 1) + lv1) << 1);
- cur_lp[1] = av_le2ne32(((av_le2ne32(ref_lp[1]) >> 1) + lv2) << 1);
- cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);
- cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);
- lp2++;
- break;
-
- case 2:
- if(lp2 == 0) {
- for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
- cur_lp[j] = ref_lp[j];
- cur_lp[j+1] = ref_lp[j+1];
- }
- lp2 += 2;
- }
- break;
-
- case 3:
- if(lp2 < 2) {
- for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
- cur_lp[j] = ref_lp[j];
- cur_lp[j+1] = ref_lp[j+1];
- }
- lp2 = 3;
- }
- break;
-
- case 8:
- if(lp2 == 0) {
- RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
- for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
- ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
- ((uint32_t *)cur_frm_pos)[j+1] = ((uint32_t *)ref_frm_pos)[j+1];
- }
- RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
- break;
- } else {
- rle_v1 = 1;
- rle_v2 = (*buf1) - 1;
- }
- case 5:
- case 7:
- LP2_CHECK(buf1,rle_v3,lp2)
- case 6:
- case 4:
- for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
- cur_lp[j] = ref_lp[j];
- cur_lp[j+1] = ref_lp[j+1];
- }
- lp2 = 4;
- break;
-
- case 9:
- av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
- lv1 = *buf1;
- lv = (lv1 & 0x7F) << 1;
- lv += (lv << 8);
- lv += (lv << 16);
- for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
- ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)cur_frm_pos)[j+1] = lv;
- LV1_CHECK(buf1,rle_v3,lv1,lp2)
- break;
-
- default:
- return;
- }
- }
+ /* move to next horizontal block */
+ block += 4 << h_zoom;
+ ref_block += 4 << h_zoom;
+ }
- cur_frm_pos += 8;
- ref_frm_pos += 8;
- }
+ /* move to next line of blocks */
+ ref_block += blk_row_offset;
+ block += blk_row_offset;
+ }
+ return IV3_NOERR;
+}
- cur_frm_pos += (((width * 2) - blks_width) * 4);
- ref_frm_pos += (((width * 2) - blks_width) * 4);
- }
- }
- break;
-
- case 11: /********** CASE 11 **********/
- if(ref_vectors == NULL)
- return;
-
- for( ; blks_height > 0; blks_height -= 8) {
- for(lp1 = 0; lp1 < blks_width; lp1++) {
- for(lp2 = 0; lp2 < 4; ) {
- k = *buf1++;
- cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
- ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
-
- switch(correction_type_sp[lp2 & 0x01][k]) {
- case 0:
- cur_lp[0] = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
- cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
- lp2++;
- break;
-
- case 1:
- lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]);
- lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]);
- res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[0]) >> 1) + lv1) << 1);
- ((unsigned short *)cur_lp)[0] = av_le2ne16(res);
- res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[1]) >> 1) + lv2) << 1);
- ((unsigned short *)cur_lp)[1] = av_le2ne16(res);
- res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[width_tbl[2]]) >> 1) + lv1) << 1);
- ((unsigned short *)cur_lp)[width_tbl[2]] = av_le2ne16(res);
- res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[width_tbl[2]+1]) >> 1) + lv2) << 1);
- ((unsigned short *)cur_lp)[width_tbl[2]+1] = av_le2ne16(res);
- lp2++;
- break;
-
- case 2:
- if(lp2 == 0) {
- for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
- cur_lp[j] = ref_lp[j];
- lp2 += 2;
- }
- break;
- case 3:
- if(lp2 < 2) {
- for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
- cur_lp[j] = ref_lp[j];
- lp2 = 3;
- }
- break;
+/**
+ * Decode a vector-quantized cell.
+ * It consists of several routines, each of which handles one or more "modes"
+ * with which a cell can be encoded.
+ *
+ * @param ctx pointer to the decoder context
+ * @param avctx ptr to the AVCodecContext
+ * @param plane pointer to the plane descriptor
+ * @param cell pointer to the cell descriptor
+ * @param data_ptr pointer to the compressed data
+ * @param last_ptr pointer to the last byte to catch reads past end of buffer
+ * @return number of consumed bytes or negative number in case of error
+ */
+static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
+ Plane *plane, Cell *cell, const uint8_t *data_ptr,
+ const uint8_t *last_ptr)
+{
+ int x, mv_x, mv_y, mode, vq_index, prim_indx, second_indx;
+ int zoom_fac;
+ int offset, error = 0, swap_quads[2];
+ uint8_t code, *block, *ref_block = 0;
+ const vqEntry *delta[2];
+ const uint8_t *data_start = data_ptr;
+
+ /* get coding mode and VQ table index from the VQ descriptor byte */
+ code = *data_ptr++;
+ mode = code >> 4;
+ vq_index = code & 0xF;
+
+ /* setup output and reference pointers */
+ offset = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
+ block = plane->pixels[ctx->buf_sel] + offset;
+ if (!cell->mv_ptr) {
+ /* use previous line as reference for INTRA cells */
+ ref_block = block - plane->pitch;
+ } else if (mode >= 10) {
+ /* for mode 10 and 11 INTER first copy the predicted cell into the current one */
+ /* so we don't need to do data copying for each RLE code later */
+ copy_cell(ctx, plane, cell);
+ } else {
+ /* set the pointer to the reference pixels for modes 0-4 INTER */
+ mv_y = cell->mv_ptr[0];
+ mv_x = cell->mv_ptr[1];
+ offset += mv_y * plane->pitch + mv_x;
+ ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset;
+ }
- case 8:
- if(lp2 == 0) {
- RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
+ /* select VQ tables as follows: */
+ /* modes 0 and 3 use only the primary table for all lines in a block */
+ /* while modes 1 and 4 switch between primary and secondary tables on alternate lines */
+ if (mode == 1 || mode == 4) {
+ code = ctx->alt_quant[vq_index];
+ prim_indx = (code >> 4) + ctx->cb_offset;
+ second_indx = (code & 0xF) + ctx->cb_offset;
+ } else {
+ vq_index += ctx->cb_offset;
+ prim_indx = second_indx = vq_index;
+ }
- for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
- cur_lp[j] = ref_lp[j];
+ if (prim_indx >= 24 || second_indx >= 24) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid VQ table indexes! Primary: %d, secondary: %d!\n",
+ prim_indx, second_indx);
+ return AVERROR_INVALIDDATA;
+ }
- RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
- break;
- } else {
- rle_v1 = 1;
- rle_v2 = (*buf1) - 1;
- }
- case 5:
- case 7:
- LP2_CHECK(buf1,rle_v3,lp2)
- case 4:
- case 6:
- for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
- cur_lp[j] = ref_lp[j];
- lp2 = 4;
- break;
-
- case 9:
- av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
- lv1 = *buf1++;
- lv = (lv1 & 0x7F) << 1;
- lv += (lv << 8);
- lv += (lv << 16);
- for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
- cur_lp[j] = lv;
- LV1_CHECK(buf1,rle_v3,lv1,lp2)
- break;
-
- default:
- return;
- }
- }
+ delta[0] = &vq_tab[second_indx];
+ delta[1] = &vq_tab[prim_indx];
+ swap_quads[0] = second_indx >= 16;
+ swap_quads[1] = prim_indx >= 16;
- cur_frm_pos += 4;
- ref_frm_pos += 4;
- }
+ /* requantize the prediction if VQ index of this cell differs from VQ index */
+ /* of the predicted cell in order to avoid overflows. */
+ if (vq_index >= 8 && ref_block) {
+ for (x = 0; x < cell->width << 2; x++)
+ ref_block[x] = requant_tab[vq_index & 7][ref_block[x]];
+ }
- cur_frm_pos += (((width * 2) - blks_width) * 4);
- ref_frm_pos += (((width * 2) - blks_width) * 4);
- }
- break;
+ error = IV3_NOERR;
- default:
- return;
- }
+ switch (mode) {
+ case 0: /*------------------ MODES 0 & 1 (4x4 block processing) --------------------*/
+ case 1:
+ case 3: /*------------------ MODES 3 & 4 (4x8 block processing) --------------------*/
+ case 4:
+ if (mode >= 3 && cell->mv_ptr) {
+ av_log(avctx, AV_LOG_ERROR, "Attempt to apply Mode 3/4 to an INTER cell!\n");
+ return AVERROR_INVALIDDATA;
}
- for( ; strip >= strip_tbl; strip--) {
- if(strip->split_flag != 0) {
- strip->split_flag = 0;
- strip->usl7 = (strip-1)->usl7;
-
- if(strip->split_direction) {
- strip->xpos += strip->width;
- strip->width = (strip-1)->width - strip->width;
- if(region_160_width <= strip->xpos && width < strip->width + strip->xpos)
- strip->width = width - strip->xpos;
- } else {
- strip->ypos += strip->height;
- strip->height = (strip-1)->height - strip->height;
- }
- break;
+ zoom_fac = mode >= 3;
+ error = decode_cell_data(cell, block, ref_block, plane->pitch, 0, zoom_fac,
+ mode, delta, swap_quads, &data_ptr, last_ptr);
+ break;
+ case 10: /*-------------------- MODE 10 (8x8 block processing) ---------------------*/
+ case 11: /*----------------- MODE 11 (4x8 INTER block processing) ------------------*/
+ if (mode == 10 && !cell->mv_ptr) { /* MODE 10 INTRA processing */
+ error = decode_cell_data(cell, block, ref_block, plane->pitch, 1, 1,
+ mode, delta, swap_quads, &data_ptr, last_ptr);
+ } else { /* mode 10 and 11 INTER processing */
+ if (mode == 11 && !cell->mv_ptr) {
+ av_log(avctx, AV_LOG_ERROR, "Attempt to use Mode 11 for an INTRA cell!\n");
+ return AVERROR_INVALIDDATA;
}
+
+ zoom_fac = mode == 10;
+ error = decode_cell_data(cell, block, ref_block, plane->pitch,
+ zoom_fac, 1, mode, delta, swap_quads,
+ &data_ptr, last_ptr);
}
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unsupported coding mode: %d\n", mode);
+ return AVERROR_INVALIDDATA;
+ }//switch mode
+
+ switch (error) {
+ case IV3_BAD_RLE:
+ av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE code %X is not allowed at the current line\n",
+ mode, data_ptr[-1]);
+ return AVERROR_INVALIDDATA;
+ case IV3_BAD_DATA:
+ av_log(avctx, AV_LOG_ERROR, "Mode %d: invalid VQ data\n", mode);
+ return AVERROR_INVALIDDATA;
+ case IV3_BAD_COUNTER:
+ av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE-FB invalid counter: %d\n", mode, code);
+ return AVERROR_INVALIDDATA;
+ case IV3_UNSUPPORTED:
+ av_log(avctx, AV_LOG_ERROR, "Mode %d: unsupported RLE code: %X\n", mode, data_ptr[-1]);
+ return AVERROR_INVALIDDATA;
+ case IV3_OUT_OF_DATA:
+ av_log(avctx, AV_LOG_ERROR, "Mode %d: attempt to read past end of buffer\n", mode);
+ return AVERROR_INVALIDDATA;
}
+
+ return data_ptr - data_start; /* report number of bytes consumed from the input buffer */
}
-static av_cold int indeo3_decode_init(AVCodecContext *avctx)
+
+/* Binary tree codes. */
+enum {
+ H_SPLIT = 0,
+ V_SPLIT = 1,
+ INTRA_NULL = 2,
+ INTER_DATA = 3
+};
+
+
+#define SPLIT_CELL(size, new_size) (new_size) = ((size) > 2) ? ((((size) + 2) >> 2) << 1) : 1
+
+#define UPDATE_BITPOS(n) \
+ ctx->skip_bits += (n); \
+ ctx->need_resync = 1
+
+#define RESYNC_BITSTREAM \
+ if (ctx->need_resync && !(get_bits_count(&ctx->gb) & 7)) { \
+ skip_bits_long(&ctx->gb, ctx->skip_bits); \
+ ctx->skip_bits = 0; \
+ ctx->need_resync = 0; \
+ }
+
+#define CHECK_CELL \
+ if (curr_cell.xpos + curr_cell.width > (plane->width >> 2) || \
+ curr_cell.ypos + curr_cell.height > (plane->height >> 2)) { \
+ av_log(avctx, AV_LOG_ERROR, "Invalid cell: x=%d, y=%d, w=%d, h=%d\n", \
+ curr_cell.xpos, curr_cell.ypos, curr_cell.width, curr_cell.height); \
+ return AVERROR_INVALIDDATA; \
+ }
+
+
+static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
+ Plane *plane, int code, Cell *ref_cell,
+ const int depth, const int strip_width)
{
- Indeo3DecodeContext *s = avctx->priv_data;
- int ret = 0;
+ Cell curr_cell;
+ int bytes_used;
- s->avctx = avctx;
- s->width = avctx->width;
- s->height = avctx->height;
- avctx->pix_fmt = PIX_FMT_YUV410P;
+ if (depth <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");
+ return AVERROR_INVALIDDATA; // unwind recursion
+ }
+
+ curr_cell = *ref_cell; // clone parent cell
+ if (code == H_SPLIT) {
+ SPLIT_CELL(ref_cell->height, curr_cell.height);
+ ref_cell->ypos += curr_cell.height;
+ ref_cell->height -= curr_cell.height;
+ } else if (code == V_SPLIT) {
+ if (curr_cell.width > strip_width) {
+ /* split strip */
+ curr_cell.width = (curr_cell.width <= (strip_width << 1) ? 1 : 2) * strip_width;
+ } else
+ SPLIT_CELL(ref_cell->width, curr_cell.width);
+ ref_cell->xpos += curr_cell.width;
+ ref_cell->width -= curr_cell.width;
+ }
- if (!(ret = build_modpred(s)))
- ret = iv_alloc_frames(s);
- if (ret)
- iv_free_func(s);
+ while (1) { /* loop until return */
+ RESYNC_BITSTREAM;
+ switch (code = get_bits(&ctx->gb, 2)) {
+ case H_SPLIT:
+ case V_SPLIT:
+ if (parse_bintree(ctx, avctx, plane, code, &curr_cell, depth - 1, strip_width))
+ return AVERROR_INVALIDDATA;
+ break;
+ case INTRA_NULL:
+ if (!curr_cell.tree) { /* MC tree INTRA code */
+ curr_cell.mv_ptr = 0; /* mark the current strip as INTRA */
+ curr_cell.tree = 1; /* enter the VQ tree */
+ } else { /* VQ tree NULL code */
+ RESYNC_BITSTREAM;
+ code = get_bits(&ctx->gb, 2);
+ if (code >= 2) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid VQ_NULL code: %d\n", code);
+ return AVERROR_INVALIDDATA;
+ }
+ if (code == 1)
+ av_log(avctx, AV_LOG_ERROR, "SkipCell procedure not implemented yet!\n");
+
+ CHECK_CELL
+ if (!curr_cell.mv_ptr)
+ return AVERROR_INVALIDDATA;
+ copy_cell(ctx, plane, &curr_cell);
+ return 0;
+ }
+ break;
+ case INTER_DATA:
+ if (!curr_cell.tree) { /* MC tree INTER code */
+ /* get motion vector index and setup the pointer to the mv set */
+ if (!ctx->need_resync)
+ ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
+ curr_cell.mv_ptr = &ctx->mc_vectors[*(ctx->next_cell_data++) << 1];
+ curr_cell.tree = 1; /* enter the VQ tree */
+ UPDATE_BITPOS(8);
+ } else { /* VQ tree DATA code */
+ if (!ctx->need_resync)
+ ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
+
+ CHECK_CELL
+ bytes_used = decode_cell(ctx, avctx, plane, &curr_cell,
+ ctx->next_cell_data, ctx->last_byte);
+ if (bytes_used < 0)
+ return AVERROR_INVALIDDATA;
+
+ UPDATE_BITPOS(bytes_used << 3);
+ ctx->next_cell_data += bytes_used;
+ return 0;
+ }
+ break;
+ }
+ }//while
- return ret;
+ return 0;
}
-static int iv_decode_frame(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size)
+
+static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
+ Plane *plane, const uint8_t *data, int32_t data_size,
+ int32_t strip_width)
{
- Indeo3DecodeContext *s = avctx->priv_data;
- unsigned int image_width, image_height,
- chroma_width, chroma_height;
- unsigned int flags, cb_offset, data_size,
- y_offset, v_offset, u_offset, mc_vector_count;
- const uint8_t *hdr_pos, *buf_pos;
-
- buf_pos = buf;
- buf_pos += 18; /* skip OS header (16 bytes) and version number */
-
- flags = bytestream_get_le16(&buf_pos);
- data_size = bytestream_get_le32(&buf_pos);
- cb_offset = *buf_pos++;
- buf_pos += 3; /* skip reserved byte and checksum */
- image_height = bytestream_get_le16(&buf_pos);
- image_width = bytestream_get_le16(&buf_pos);
-
- if(av_image_check_size(image_width, image_height, 0, avctx))
- return -1;
- if (image_width != avctx->width || image_height != avctx->height) {
- int ret;
- avcodec_set_dimensions(avctx, image_width, image_height);
- s->width = avctx->width;
- s->height = avctx->height;
- ret = iv_alloc_frames(s);
- if (ret < 0) {
- s->width = s->height = 0;
- return ret;
- }
+ Cell curr_cell;
+ int num_vectors;
+
+ /* each plane data starts with mc_vector_count field, */
+ /* an optional array of motion vectors followed by the vq data */
+ num_vectors = bytestream_get_le32(&data);
+ ctx->mc_vectors = num_vectors ? data : 0;
+
+ if (num_vectors * 2 >= data_size)
+ return AVERROR_INVALIDDATA;
+ /* init the bitreader */
+ init_get_bits(&ctx->gb, &data[num_vectors * 2], (data_size - num_vectors * 2) << 3);
+ ctx->skip_bits = 0;
+ ctx->need_resync = 0;
+
+ ctx->last_byte = data + data_size - 1;
+
+ /* initialize the 1st cell and set its dimensions to whole plane */
+ curr_cell.xpos = curr_cell.ypos = 0;
+ curr_cell.width = plane->width >> 2;
+ curr_cell.height = plane->height >> 2;
+ curr_cell.tree = 0; // we are in the MC tree now
+ curr_cell.mv_ptr = 0; // no motion vector = INTRA cell
+
+ return parse_bintree(ctx, avctx, plane, INTRA_NULL, &curr_cell, CELL_STACK_MAX, strip_width);
+}
+
+
+#define OS_HDR_ID MKBETAG('F', 'R', 'M', 'H')
+
+static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ const uint8_t *buf_ptr = buf, *bs_hdr;
+ uint32_t frame_num, word2, check_sum, data_size;
+ uint32_t y_offset, u_offset, v_offset, starts[3], ends[3];
+ uint16_t height, width;
+ int i, j;
+
+ /* parse and check the OS header */
+ frame_num = bytestream_get_le32(&buf_ptr);
+ word2 = bytestream_get_le32(&buf_ptr);
+ check_sum = bytestream_get_le32(&buf_ptr);
+ data_size = bytestream_get_le32(&buf_ptr);
+
+ if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) {
+ av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n");
+ return AVERROR_INVALIDDATA;
}
- chroma_height = ((image_height >> 2) + 3) & 0x7ffc;
- chroma_width = ((image_width >> 2) + 3) & 0x7ffc;
- y_offset = bytestream_get_le32(&buf_pos);
- v_offset = bytestream_get_le32(&buf_pos);
- u_offset = bytestream_get_le32(&buf_pos);
- buf_pos += 4; /* reserved */
- hdr_pos = buf_pos;
- if(data_size == 0x80) return 4;
-
- if(FFMAX3(y_offset, v_offset, u_offset) >= buf_size-16) {
- av_log(s->avctx, AV_LOG_ERROR, "y/u/v offset outside buffer\n");
- return -1;
+ /* parse the bitstream header */
+ bs_hdr = buf_ptr;
+
+ if (bytestream_get_le16(&buf_ptr) != 32) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n");
+ return AVERROR_INVALIDDATA;
}
- if(flags & 0x200) {
- s->cur_frame = s->iv_frame + 1;
- s->ref_frame = s->iv_frame;
- } else {
- s->cur_frame = s->iv_frame;
- s->ref_frame = s->iv_frame + 1;
+ ctx->frame_num = frame_num;
+ ctx->frame_flags = bytestream_get_le16(&buf_ptr);
+ ctx->data_size = (bytestream_get_le32(&buf_ptr) + 7) >> 3;
+ ctx->cb_offset = *buf_ptr++;
+
+ if (ctx->data_size == 16)
+ return 4;
+ if (ctx->data_size > buf_size)
+ ctx->data_size = buf_size;
+
+ buf_ptr += 3; // skip reserved byte and checksum
+
+ /* check frame dimensions */
+ height = bytestream_get_le16(&buf_ptr);
+ width = bytestream_get_le16(&buf_ptr);
+ if (av_image_check_size(width, height, 0, avctx))
+ return AVERROR_INVALIDDATA;
+
+ if (width != ctx->width || height != ctx->height) {
+ av_dlog(avctx, "Frame dimensions changed!\n");
+
+ ctx->width = width;
+ ctx->height = height;
+
+ free_frame_buffers(ctx);
+ allocate_frame_buffers(ctx, avctx);
+ avcodec_set_dimensions(avctx, width, height);
+ }
+
+ y_offset = bytestream_get_le32(&buf_ptr);
+ v_offset = bytestream_get_le32(&buf_ptr);
+ u_offset = bytestream_get_le32(&buf_ptr);
+
+ /* unfortunately there is no common order of planes in the buffer */
+ /* so we use that sorting algo for determining planes data sizes */
+ starts[0] = y_offset;
+ starts[1] = v_offset;
+ starts[2] = u_offset;
+
+ for (j = 0; j < 3; j++) {
+ ends[j] = ctx->data_size;
+ for (i = 2; i >= 0; i--)
+ if (starts[i] < ends[j] && starts[i] > starts[j])
+ ends[j] = starts[i];
}
- buf_pos = buf + 16 + y_offset;
- mc_vector_count = bytestream_get_le32(&buf_pos);
- if(2LL*mc_vector_count >= buf_size-16-y_offset) {
- av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");
- return -1;
+ ctx->y_data_size = ends[0] - starts[0];
+ ctx->v_data_size = ends[1] - starts[1];
+ ctx->u_data_size = ends[2] - starts[2];
+ if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 ||
+ FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n");
+ return AVERROR_INVALIDDATA;
}
- iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, image_width,
- image_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
- FFMIN(image_width, 160));
+ ctx->y_data_ptr = bs_hdr + y_offset;
+ ctx->v_data_ptr = bs_hdr + v_offset;
+ ctx->u_data_ptr = bs_hdr + u_offset;
+ ctx->alt_quant = buf_ptr + sizeof(uint32_t);
- if (!(s->avctx->flags & CODEC_FLAG_GRAY))
- {
+ if (ctx->data_size == 16) {
+ av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n");
+ return 16;
+ }
- buf_pos = buf + 16 + v_offset;
- mc_vector_count = bytestream_get_le32(&buf_pos);
- if(2LL*mc_vector_count >= buf_size-16-v_offset) {
- av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");
- return -1;
- }
+ if (ctx->frame_flags & BS_8BIT_PEL) {
+ av_log_ask_for_sample(avctx, "8-bit pixel format\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (ctx->frame_flags & BS_MV_X_HALF || ctx->frame_flags & BS_MV_Y_HALF) {
+ av_log_ask_for_sample(avctx, "halfpel motion vectors\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ return 0;
+}
- iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width,
- chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
- FFMIN(chroma_width, 40));
- buf_pos = buf + 16 + u_offset;
- mc_vector_count = bytestream_get_le32(&buf_pos);
- if(2LL*mc_vector_count >= buf_size-16-u_offset) {
- av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");
- return -1;
+/**
+ * Convert and output the current plane.
+ * All pixel values will be upsampled by shifting right by one bit.
+ *
+ * @param[in] plane pointer to the descriptor of the plane being processed
+ * @param[in] buf_sel indicates which frame buffer the input data stored in
+ * @param[out] dst pointer to the buffer receiving converted pixels
+ * @param[in] dst_pitch pitch for moving to the next y line
+ */
+static void output_plane(const Plane *plane, int buf_sel, uint8_t *dst, int dst_pitch)
+{
+ int x,y;
+ const uint8_t *src = plane->pixels[buf_sel];
+ uint32_t pitch = plane->pitch;
+
+ for (y = 0; y < plane->height; y++) {
+ /* convert four pixels at once using SWAR */
+ for (x = 0; x < plane->width >> 2; x++) {
+ AV_WN32A(dst, (AV_RN32A(src) & 0x7F7F7F7F) << 1);
+ src += 4;
+ dst += 4;
}
- iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width,
- chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
- FFMIN(chroma_width, 40));
+ for (x <<= 2; x < plane->width; x++)
+ *dst++ = *src++ << 1;
+ src += pitch - plane->width;
+ dst += dst_pitch - plane->width;
}
+}
+
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ Indeo3DecodeContext *ctx = avctx->priv_data;
+
+ ctx->avctx = avctx;
+ ctx->width = avctx->width;
+ ctx->height = avctx->height;
+ avctx->pix_fmt = PIX_FMT_YUV410P;
+
+ build_requant_tab();
+
+ dsputil_init(&ctx->dsp, avctx);
+
+ allocate_frame_buffers(ctx, avctx);
- return 8;
+ return 0;
}
-static int indeo3_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
{
+ Indeo3DecodeContext *ctx = avctx->priv_data;
const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- Indeo3DecodeContext *s=avctx->priv_data;
- uint8_t *src, *dest;
- int y;
+ int buf_size = avpkt->size;
+ int res;
+
+ res = decode_frame_headers(ctx, avctx, buf, buf_size);
+ if (res < 0)
+ return res;
+
+ /* skip sync(null) frames */
+ if (res) {
+ // we have processed 16 bytes but no data was decoded
+ *data_size = 0;
+ return buf_size;
+ }
- if (iv_decode_frame(avctx, buf, buf_size) < 0)
- return -1;
+ /* skip droppable INTER frames if requested */
+ if (ctx->frame_flags & BS_NONREF &&
+ (avctx->skip_frame >= AVDISCARD_NONREF))
+ return 0;
- if(s->frame.data[0])
- avctx->release_buffer(avctx, &s->frame);
+ /* skip INTER frames if requested */
+ if (!(ctx->frame_flags & BS_KEYFRAME) && avctx->skip_frame >= AVDISCARD_NONKEY)
+ return 0;
- s->frame.reference = 0;
- if(avctx->get_buffer(avctx, &s->frame) < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
- return -1;
- }
+ /* use BS_BUFFER flag for buffer switching */
+ ctx->buf_sel = (ctx->frame_flags >> BS_BUFFER) & 1;
- src = s->cur_frame->Ybuf;
- dest = s->frame.data[0];
- for (y = 0; y < s->height; y++) {
- memcpy(dest, src, s->cur_frame->y_w);
- src += s->cur_frame->y_w;
- dest += s->frame.linesize[0];
- }
+ /* decode luma plane */
+ if ((res = decode_plane(ctx, avctx, ctx->planes, ctx->y_data_ptr, ctx->y_data_size, 40)))
+ return res;
- if (!(s->avctx->flags & CODEC_FLAG_GRAY))
- {
- src = s->cur_frame->Ubuf;
- dest = s->frame.data[1];
- for (y = 0; y < s->height / 4; y++) {
- memcpy(dest, src, s->cur_frame->uv_w);
- src += s->cur_frame->uv_w;
- dest += s->frame.linesize[1];
- }
+ /* decode chroma planes */
+ if ((res = decode_plane(ctx, avctx, &ctx->planes[1], ctx->u_data_ptr, ctx->u_data_size, 10)))
+ return res;
- src = s->cur_frame->Vbuf;
- dest = s->frame.data[2];
- for (y = 0; y < s->height / 4; y++) {
- memcpy(dest, src, s->cur_frame->uv_w);
- src += s->cur_frame->uv_w;
- dest += s->frame.linesize[2];
- }
+ if ((res = decode_plane(ctx, avctx, &ctx->planes[2], ctx->v_data_ptr, ctx->v_data_size, 10)))
+ return res;
+
+ if (ctx->frame.data[0])
+ avctx->release_buffer(avctx, &ctx->frame);
+
+ ctx->frame.reference = 0;
+ if ((res = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return res;
}
- *data_size=sizeof(AVFrame);
- *(AVFrame*)data= s->frame;
+ output_plane(&ctx->planes[0], ctx->buf_sel, ctx->frame.data[0], ctx->frame.linesize[0]);
+ output_plane(&ctx->planes[1], ctx->buf_sel, ctx->frame.data[1], ctx->frame.linesize[1]);
+ output_plane(&ctx->planes[2], ctx->buf_sel, ctx->frame.data[2], ctx->frame.linesize[2]);
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame*)data = ctx->frame;
return buf_size;
}
-static av_cold int indeo3_decode_end(AVCodecContext *avctx)
+
+static av_cold int decode_close(AVCodecContext *avctx)
{
- Indeo3DecodeContext *s = avctx->priv_data;
+ Indeo3DecodeContext *ctx = avctx->priv_data;
+
+ free_frame_buffers(avctx->priv_data);
- iv_free_func(s);
+ if (ctx->frame.data[0])
+ avctx->release_buffer(avctx, &ctx->frame);
return 0;
}
AVCodec ff_indeo3_decoder = {
- "indeo3",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_INDEO3,
- sizeof(Indeo3DecodeContext),
- indeo3_decode_init,
- NULL,
- indeo3_decode_end,
- indeo3_decode_frame,
- CODEC_CAP_DR1,
- NULL,
- .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
+ .name = "indeo3",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_INDEO3,
+ .priv_data_size = sizeof(Indeo3DecodeContext),
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
};
diff --git a/libavcodec/indeo3data.h b/libavcodec/indeo3data.h
index 334c3e0..6bb55ce 100644
--- a/libavcodec/indeo3data.h
+++ b/libavcodec/indeo3data.h
@@ -1,6 +1,6 @@
/*
- * Intel Indeo 3 (IV31, IV32, etc.) video decoder for ffmpeg
- * written, produced, and directed by Alan Smithee
+ * Indeo Video v3 compatible decoder
+ * Copyright (c) 2009 - 2011 Maxim Poliakovski
*
* This file is part of Libav.
*
@@ -24,2319 +24,339 @@
#include <stdint.h>
-static const uint32_t correction[] = {
- 0x00000000, 0x00000202, 0xfffffdfe, 0x000002ff, 0xfffffd01, 0xffffff03, 0x000000fd, 0x00000404,
- 0xfffffbfc, 0x00000501, 0xfffffaff, 0x00000105, 0xfffffefb, 0x000003fc, 0xfffffc04, 0x000005fe,
- 0xfffffa02, 0xfffffe06, 0x000001fa, 0x00000904, 0xfffff6fc, 0x00000409, 0xfffffbf7, 0x00000909,
- 0xfffff6f7, 0x00000a01, 0xfffff5ff, 0x0000010a, 0xfffffef6, 0x000007fb, 0xfffff805, 0xfffffb08,
- 0x000004f8, 0x00000f09, 0xfffff0f7, 0x0000090f, 0xfffff6f1, 0x00000bfd, 0xfffff403, 0xfffffd0c,
- 0x000002f4, 0x00001004, 0xffffeffc, 0x00000410, 0xfffffbf0, 0x00001010, 0xffffeff0, 0x00001200,
- 0xffffee00, 0x00000012, 0xffffffee, 0x00000bf4, 0xfffff40c, 0x00000ff7, 0xfffff009, 0xfffff710,
- 0x000008f0, 0x00001b0b, 0xffffe4f5, 0x00000b1b, 0xfffff4e5, 0x00001c13, 0xffffe3ed, 0x0000131c,
- 0xffffece4, 0x000015fa, 0xffffea06, 0xfffffa16, 0x000005ea, 0x00001d04, 0xffffe2fc, 0x0000041d,
- 0xfffffbe3, 0x00001e1e, 0xffffe1e2, 0x000020fe, 0xffffdf02, 0xfffffe21, 0x000001df, 0x000016ee,
- 0xffffe912, 0xffffee17, 0x000011e9, 0x00001df1, 0xffffe20f, 0xfffff11e, 0x00000ee2, 0x00002e16,
- 0xffffd1ea, 0x0000162e, 0xffffe9d2, 0x00002f0d, 0xffffd0f3, 0x00000d2f, 0xfffff2d1, 0x00003123,
- 0xffffcedd, 0x00002331, 0xffffdccf, 0x000028f5, 0xffffd70b, 0xfffff529, 0x00000ad7, 0x00003304,
- 0xffffccfc, 0x00000433, 0xfffffbcd, 0x00003636, 0xffffc9ca, 0x000021de, 0xffffde22, 0x000029e3,
- 0xffffd61d, 0xffffe32a, 0x00001cd6, 0x00003bfa, 0xffffc406, 0xfffffa3c, 0x000005c4, 0x00004c1b,
- 0xffffb3e5, 0x00001b4c, 0xffffe4b4, 0x00004d2b, 0xffffb2d5, 0x00002b4d, 0xffffd4b3, 0x000036e8,
- 0xffffc918, 0xffffe837, 0x000017c9, 0x00004f0e, 0xffffb0f2, 0x00000e4f, 0xfffff1b1, 0x0000533f,
- 0xffffacc1, 0x00003f53, 0xffffc0ad, 0x000049ec, 0xffffb614, 0xffffec4a, 0x000013b6, 0x00005802,
- 0xffffa7fe, 0x00000258, 0xfffffda8, 0x00005d5d, 0xffffa2a3, 0x00003ccc, 0xffffc334, 0xffffcc3d,
- 0x000033c3, 0x00007834, 0xffff87cc, 0x00003478, 0xffffcb88, 0x00004ad3, 0xffffb52d, 0xffffd34b,
- 0x00002cb5, 0x00007d4b, 0xffff82b5, 0x00004b7d, 0xffffb483, 0x00007a21, 0xffff85df, 0x0000217a,
- 0xffffde86, 0x000066f3, 0xffff990d, 0xfffff367, 0x00000c99, 0x00005fd8, 0xffffa028, 0xffffd860,
- 0x000027a0, 0x00007ede, 0xffff8122, 0xffffde7f, 0x00002181, 0x000058a7, 0xffffa759, 0x000068b2,
- 0xffff974e, 0xffffb269, 0x00004d97, 0x00000c0c, 0xfffff3f4, 0x00001717, 0xffffe8e9, 0x00002a2a,
- 0xffffd5d6, 0x00004949, 0xffffb6b7, 0x00000000, 0x02020000, 0xfdfe0000, 0x02ff0000, 0xfd010000,
- 0xff030000, 0x00fd0000, 0x00000202, 0x02020202, 0xfdfe0202, 0x02ff0202, 0xfd010202, 0xff030202,
- 0x00fd0202, 0xfffffdfe, 0x0201fdfe, 0xfdfdfdfe, 0x02fefdfe, 0xfd00fdfe, 0xff02fdfe, 0x00fcfdfe,
- 0x000002ff, 0x020202ff, 0xfdfe02ff, 0x02ff02ff, 0xfd0102ff, 0xff0302ff, 0x00fd02ff, 0xfffffd01,
- 0x0201fd01, 0xfdfdfd01, 0x02fefd01, 0xfd00fd01, 0xff02fd01, 0x00fcfd01, 0xffffff03, 0x0201ff03,
- 0xfdfdff03, 0x02feff03, 0xfd00ff03, 0xff02ff03, 0x00fcff03, 0x000000fd, 0x020200fd, 0xfdfe00fd,
- 0x02ff00fd, 0xfd0100fd, 0xff0300fd, 0x00fd00fd, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000303, 0xfffffcfd, 0x000003ff, 0xfffffc01, 0xffffff04, 0x000000fc, 0x00000707,
- 0xfffff8f9, 0x00000802, 0xfffff7fe, 0x00000208, 0xfffffdf8, 0x000008fe, 0xfffff702, 0xfffffe09,
- 0x000001f7, 0x000005fa, 0xfffffa06, 0x00000d06, 0xfffff2fa, 0x0000060d, 0xfffff9f3, 0x00000d0d,
- 0xfffff2f3, 0x00000e01, 0xfffff1ff, 0x0000010e, 0xfffffef2, 0x00000bf8, 0xfffff408, 0xfffff80c,
- 0x000007f4, 0x0000170e, 0xffffe8f2, 0x00000e17, 0xfffff1e9, 0x000011fb, 0xffffee05, 0xfffffb12,
- 0x000004ee, 0x00001806, 0xffffe7fa, 0x00000618, 0xfffff9e8, 0x00001818, 0xffffe7e8, 0x00001aff,
- 0xffffe501, 0xffffff1b, 0x000000e5, 0x000010ef, 0xffffef11, 0x000016f3, 0xffffe90d, 0xfffff317,
- 0x00000ce9, 0x00002810, 0xffffd7f0, 0x00001028, 0xffffefd8, 0x0000291c, 0xffffd6e4, 0x00001c29,
- 0xffffe3d7, 0x000020f7, 0xffffdf09, 0xfffff721, 0x000008df, 0x00002b06, 0xffffd4fa, 0x0000062b,
- 0xfffff9d5, 0x00002e2e, 0xffffd1d2, 0x000031fc, 0xffffce04, 0xfffffc32, 0x000003ce, 0x000021e5,
- 0xffffde1b, 0xffffe522, 0x00001ade, 0x00002cea, 0xffffd316, 0xffffea2d, 0x000015d3, 0x00004522,
- 0xffffbade, 0x00002245, 0xffffddbb, 0x00004613, 0xffffb9ed, 0x00001346, 0xffffecba, 0x00004935,
- 0xffffb6cb, 0x00003549, 0xffffcab7, 0x00003def, 0xffffc211, 0xffffef3e, 0x000010c2, 0x00004d05,
- 0xffffb2fb, 0x0000054d, 0xfffffab3, 0x00005252, 0xffffadae, 0x000032cd, 0xffffcd33, 0x00003fd5,
- 0xffffc02b, 0xffffd540, 0x00002ac0, 0x000059f6, 0xffffa60a, 0xfffff65a, 0x000009a6, 0x00007229,
- 0xffff8dd7, 0x00002972, 0xffffd68e, 0x00007440, 0xffff8bc0, 0x00004074, 0xffffbf8c, 0x000051db,
- 0xffffae25, 0xffffdb52, 0x000024ae, 0x00007716, 0xffff88ea, 0x00001677, 0xffffe989, 0x00007c5f,
- 0xffff83a1, 0x00005f7c, 0xffffa084, 0x00006ee2, 0xffff911e, 0xffffe26f, 0x00001d91, 0x00005bb2,
- 0xffffa44e, 0xffffb25c, 0x00004da4, 0x000070bc, 0xffff8f44, 0xffffbc71, 0x0000438f, 0x00001212,
- 0xffffedee, 0x00002222, 0xffffddde, 0x00003f3f, 0xffffc0c1, 0x00006d6d, 0xffff9293, 0x00000000,
- 0x03030000, 0xfcfd0000, 0x03ff0000, 0xfc010000, 0xff040000, 0x00fc0000, 0x07070000, 0xf8f90000,
- 0x00000303, 0x03030303, 0xfcfd0303, 0x03ff0303, 0xfc010303, 0xff040303, 0x00fc0303, 0x07070303,
- 0xf8f90303, 0xfffffcfd, 0x0302fcfd, 0xfcfcfcfd, 0x03fefcfd, 0xfc00fcfd, 0xff03fcfd, 0x00fbfcfd,
- 0x0706fcfd, 0xf8f8fcfd, 0x000003ff, 0x030303ff, 0xfcfd03ff, 0x03ff03ff, 0xfc0103ff, 0xff0403ff,
- 0x00fc03ff, 0x070703ff, 0xf8f903ff, 0xfffffc01, 0x0302fc01, 0xfcfcfc01, 0x03fefc01, 0xfc00fc01,
- 0xff03fc01, 0x00fbfc01, 0x0706fc01, 0xf8f8fc01, 0xffffff04, 0x0302ff04, 0xfcfcff04, 0x03feff04,
- 0xfc00ff04, 0xff03ff04, 0x00fbff04, 0x0706ff04, 0xf8f8ff04, 0x000000fc, 0x030300fc, 0xfcfd00fc,
- 0x03ff00fc, 0xfc0100fc, 0xff0400fc, 0x00fc00fc, 0x070700fc, 0xf8f900fc, 0x00000707, 0x03030707,
- 0xfcfd0707, 0x03ff0707, 0xfc010707, 0xff040707, 0x00fc0707, 0x07070707, 0xf8f90707, 0xfffff8f9,
- 0x0302f8f9, 0xfcfcf8f9, 0x03fef8f9, 0xfc00f8f9, 0xff03f8f9, 0x00fbf8f9, 0x0706f8f9, 0xf8f8f8f9,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000404, 0xfffffbfc, 0x000004ff, 0xfffffb01, 0xffffff05, 0x000000fb, 0x00000a03,
- 0xfffff5fd, 0x0000030a, 0xfffffcf6, 0x00000909, 0xfffff6f7, 0x000006f9, 0xfffff907, 0x00000bfd,
- 0xfffff403, 0xfffffd0c, 0x000002f4, 0x00001108, 0xffffeef8, 0x00000811, 0xfffff7ef, 0x00001111,
- 0xffffeeef, 0x00001301, 0xffffecff, 0x00000113, 0xfffffeed, 0x00000ff5, 0xfffff00b, 0xfffff510,
- 0x00000af0, 0x000016fa, 0xffffe906, 0xfffffa17, 0x000005e9, 0x00001f12, 0xffffe0ee, 0x0000121f,
- 0xffffede1, 0x00002008, 0xffffdff8, 0x00000820, 0xfffff7e0, 0x00002121, 0xffffdedf, 0x000023ff,
- 0xffffdc01, 0xffffff24, 0x000000dc, 0x000016e9, 0xffffe917, 0x00001eef, 0xffffe111, 0xffffef1f,
- 0x000010e1, 0x00003615, 0xffffc9eb, 0x00001536, 0xffffeaca, 0x00003725, 0xffffc8db, 0x00002537,
- 0xffffdac9, 0x00002bf4, 0xffffd40c, 0xfffff42c, 0x00000bd4, 0x00003908, 0xffffc6f8, 0x00000839,
- 0xfffff7c7, 0x00003d3d, 0xffffc2c3, 0x000041fb, 0xffffbe05, 0xfffffb42, 0x000004be, 0x00002cdc,
- 0xffffd324, 0xffffdc2d, 0x000023d3, 0x00003be3, 0xffffc41d, 0xffffe33c, 0x00001cc4, 0x00005c2d,
- 0xffffa3d3, 0x00002d5c, 0xffffd2a4, 0x00005d19, 0xffffa2e7, 0x0000195d, 0xffffe6a3, 0x00006147,
- 0xffff9eb9, 0x00004761, 0xffffb89f, 0x000052ea, 0xffffad16, 0xffffea53, 0x000015ad, 0x00006607,
- 0xffff99f9, 0x00000766, 0xfffff89a, 0x00006d6d, 0xffff9293, 0x000043bc, 0xffffbc44, 0x000054c7,
- 0xffffab39, 0xffffc755, 0x000038ab, 0x000077f3, 0xffff880d, 0xfffff378, 0x00000c88, 0x00006dcf,
- 0xffff9231, 0xffffcf6e, 0x00003092, 0x00007a98, 0xffff8568, 0xffff987b, 0x00006785, 0x00001818,
- 0xffffe7e8, 0x00002e2e, 0xffffd1d2, 0x00005454, 0xffffabac, 0x00000000, 0x04040000, 0xfbfc0000,
- 0x04ff0000, 0xfb010000, 0xff050000, 0x00fb0000, 0x0a030000, 0xf5fd0000, 0x030a0000, 0x00000404,
- 0x04040404, 0xfbfc0404, 0x04ff0404, 0xfb010404, 0xff050404, 0x00fb0404, 0x0a030404, 0xf5fd0404,
- 0x030a0404, 0xfffffbfc, 0x0403fbfc, 0xfbfbfbfc, 0x04fefbfc, 0xfb00fbfc, 0xff04fbfc, 0x00fafbfc,
- 0x0a02fbfc, 0xf5fcfbfc, 0x0309fbfc, 0x000004ff, 0x040404ff, 0xfbfc04ff, 0x04ff04ff, 0xfb0104ff,
- 0xff0504ff, 0x00fb04ff, 0x0a0304ff, 0xf5fd04ff, 0x030a04ff, 0xfffffb01, 0x0403fb01, 0xfbfbfb01,
- 0x04fefb01, 0xfb00fb01, 0xff04fb01, 0x00fafb01, 0x0a02fb01, 0xf5fcfb01, 0x0309fb01, 0xffffff05,
- 0x0403ff05, 0xfbfbff05, 0x04feff05, 0xfb00ff05, 0xff04ff05, 0x00faff05, 0x0a02ff05, 0xf5fcff05,
- 0x0309ff05, 0x000000fb, 0x040400fb, 0xfbfc00fb, 0x04ff00fb, 0xfb0100fb, 0xff0500fb, 0x00fb00fb,
- 0x0a0300fb, 0xf5fd00fb, 0x030a00fb, 0x00000a03, 0x04040a03, 0xfbfc0a03, 0x04ff0a03, 0xfb010a03,
- 0xff050a03, 0x00fb0a03, 0x0a030a03, 0xf5fd0a03, 0x030a0a03, 0xfffff5fd, 0x0403f5fd, 0xfbfbf5fd,
- 0x04fef5fd, 0xfb00f5fd, 0xff04f5fd, 0x00faf5fd, 0x0a02f5fd, 0xf5fcf5fd, 0x0309f5fd, 0x0000030a,
- 0x0404030a, 0xfbfc030a, 0x04ff030a, 0xfb01030a, 0xff05030a, 0x00fb030a, 0x0a03030a, 0xf5fd030a,
- 0x030a030a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000505, 0xfffffafb, 0x000006fe, 0xfffff902, 0xfffffe07, 0x000001f9, 0x00000b0b,
- 0xfffff4f5, 0x00000d03, 0xfffff2fd, 0x0000030d, 0xfffffcf3, 0x000008f7, 0xfffff709, 0x00000efc,
- 0xfffff104, 0xfffffc0f, 0x000003f1, 0x0000160b, 0xffffe9f5, 0x00000b16, 0xfffff4ea, 0x00001515,
- 0xffffeaeb, 0x00001802, 0xffffe7fe, 0x00000218, 0xfffffde8, 0x000013f2, 0xffffec0e, 0xfffff214,
- 0x00000dec, 0x00002617, 0xffffd9e9, 0x00001726, 0xffffe8da, 0x00001cf8, 0xffffe308, 0xfffff81d,
- 0x000007e3, 0x0000270b, 0xffffd8f5, 0x00000b27, 0xfffff4d9, 0x00002929, 0xffffd6d7, 0x00002cff,
- 0xffffd301, 0xffffff2d, 0x000000d3, 0x00001ce3, 0xffffe31d, 0x000026ea, 0xffffd916, 0xffffea27,
- 0x000015d9, 0x0000431b, 0xffffbce5, 0x00001b43, 0xffffe4bd, 0x0000452f, 0xffffbad1, 0x00002f45,
- 0xffffd0bb, 0x000037f1, 0xffffc80f, 0xfffff138, 0x00000ec8, 0x0000470b, 0xffffb8f5, 0x00000b47,
- 0xfffff4b9, 0x00004c4c, 0xffffb3b4, 0x000052fa, 0xffffad06, 0xfffffa53, 0x000005ad, 0x000038d3,
- 0xffffc72d, 0xffffd339, 0x00002cc7, 0x00004adc, 0xffffb524, 0xffffdc4b, 0x000023b5, 0x00007338,
- 0xffff8cc8, 0x00003873, 0xffffc78d, 0x0000751f, 0xffff8ae1, 0x00001f75, 0xffffe08b, 0x00007a58,
- 0xffff85a8, 0x0000587a, 0xffffa786, 0x000067e4, 0xffff981c, 0xffffe468, 0x00001b98, 0x000054ab,
- 0xffffab55, 0x000069b8, 0xffff9648, 0xffffb86a, 0x00004796, 0x00001e1e, 0xffffe1e2, 0x00003a3a,
- 0xffffc5c6, 0x00006969, 0xffff9697, 0x00000000, 0x05050000, 0xfafb0000, 0x06fe0000, 0xf9020000,
- 0xfe070000, 0x01f90000, 0x0b0b0000, 0xf4f50000, 0x0d030000, 0xf2fd0000, 0x00000505, 0x05050505,
- 0xfafb0505, 0x06fe0505, 0xf9020505, 0xfe070505, 0x01f90505, 0x0b0b0505, 0xf4f50505, 0x0d030505,
- 0xf2fd0505, 0xfffffafb, 0x0504fafb, 0xfafafafb, 0x06fdfafb, 0xf901fafb, 0xfe06fafb, 0x01f8fafb,
- 0x0b0afafb, 0xf4f4fafb, 0x0d02fafb, 0xf2fcfafb, 0x000006fe, 0x050506fe, 0xfafb06fe, 0x06fe06fe,
- 0xf90206fe, 0xfe0706fe, 0x01f906fe, 0x0b0b06fe, 0xf4f506fe, 0x0d0306fe, 0xf2fd06fe, 0xfffff902,
- 0x0504f902, 0xfafaf902, 0x06fdf902, 0xf901f902, 0xfe06f902, 0x01f8f902, 0x0b0af902, 0xf4f4f902,
- 0x0d02f902, 0xf2fcf902, 0xfffffe07, 0x0504fe07, 0xfafafe07, 0x06fdfe07, 0xf901fe07, 0xfe06fe07,
- 0x01f8fe07, 0x0b0afe07, 0xf4f4fe07, 0x0d02fe07, 0xf2fcfe07, 0x000001f9, 0x050501f9, 0xfafb01f9,
- 0x06fe01f9, 0xf90201f9, 0xfe0701f9, 0x01f901f9, 0x0b0b01f9, 0xf4f501f9, 0x0d0301f9, 0xf2fd01f9,
- 0x00000b0b, 0x05050b0b, 0xfafb0b0b, 0x06fe0b0b, 0xf9020b0b, 0xfe070b0b, 0x01f90b0b, 0x0b0b0b0b,
- 0xf4f50b0b, 0x0d030b0b, 0xf2fd0b0b, 0xfffff4f5, 0x0504f4f5, 0xfafaf4f5, 0x06fdf4f5, 0xf901f4f5,
- 0xfe06f4f5, 0x01f8f4f5, 0x0b0af4f5, 0xf4f4f4f5, 0x0d02f4f5, 0xf2fcf4f5, 0x00000d03, 0x05050d03,
- 0xfafb0d03, 0x06fe0d03, 0xf9020d03, 0xfe070d03, 0x01f90d03, 0x0b0b0d03, 0xf4f50d03, 0x0d030d03,
- 0xf2fd0d03, 0xfffff2fd, 0x0504f2fd, 0xfafaf2fd, 0x06fdf2fd, 0xf901f2fd, 0xfe06f2fd, 0x01f8f2fd,
- 0x0b0af2fd, 0xf4f4f2fd, 0x0d02f2fd, 0xf2fcf2fd, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000606, 0xfffff9fa, 0x000007fe, 0xfffff802, 0xfffffe08, 0x000001f8, 0x00000d0d,
- 0xfffff2f3, 0x00000f04, 0xfffff0fc, 0x0000040f, 0xfffffbf1, 0x00000af5, 0xfffff50b, 0x000011fb,
- 0xffffee05, 0xfffffb12, 0x000004ee, 0x00001a0d, 0xffffe5f3, 0x00000d1a, 0xfffff2e6, 0x00001a1a,
- 0xffffe5e6, 0x00001d02, 0xffffe2fe, 0x0000021d, 0xfffffde3, 0x000017f0, 0xffffe810, 0xfffff018,
- 0x00000fe8, 0x00002e1c, 0xffffd1e4, 0x00001c2e, 0xffffe3d2, 0x000022f7, 0xffffdd09, 0xfffff723,
- 0x000008dd, 0x00002f0d, 0xffffd0f3, 0x00000d2f, 0xfffff2d1, 0x00003131, 0xffffcecf, 0x000035ff,
- 0xffffca01, 0xffffff36, 0x000000ca, 0x000022dd, 0xffffdd23, 0x00002ee6, 0xffffd11a, 0xffffe62f,
- 0x000019d1, 0x00005120, 0xffffaee0, 0x00002051, 0xffffdfaf, 0x00005338, 0xffffacc8, 0x00003853,
- 0xffffc7ad, 0x000042ee, 0xffffbd12, 0xffffee43, 0x000011bd, 0x0000560d, 0xffffa9f3, 0x00000d56,
- 0xfffff2aa, 0x00005b5b, 0xffffa4a5, 0x000062f9, 0xffff9d07, 0xfffff963, 0x0000069d, 0x000043ca,
- 0xffffbc36, 0xffffca44, 0x000035bc, 0x000059d4, 0xffffa62c, 0xffffd45a, 0x00002ba6, 0x00007bdf,
- 0xffff8421, 0xffffdf7c, 0x00002084, 0x00006699, 0xffff9967, 0x00007eaa, 0xffff8156, 0xffffaa7f,
- 0x00005581, 0x00002525, 0xffffdadb, 0x00004545, 0xffffbabb, 0x00000000, 0x06060000, 0xf9fa0000,
- 0x07fe0000, 0xf8020000, 0xfe080000, 0x01f80000, 0x0d0d0000, 0xf2f30000, 0x0f040000, 0xf0fc0000,
- 0x040f0000, 0x00000606, 0x06060606, 0xf9fa0606, 0x07fe0606, 0xf8020606, 0xfe080606, 0x01f80606,
- 0x0d0d0606, 0xf2f30606, 0x0f040606, 0xf0fc0606, 0x040f0606, 0xfffff9fa, 0x0605f9fa, 0xf9f9f9fa,
- 0x07fdf9fa, 0xf801f9fa, 0xfe07f9fa, 0x01f7f9fa, 0x0d0cf9fa, 0xf2f2f9fa, 0x0f03f9fa, 0xf0fbf9fa,
- 0x040ef9fa, 0x000007fe, 0x060607fe, 0xf9fa07fe, 0x07fe07fe, 0xf80207fe, 0xfe0807fe, 0x01f807fe,
- 0x0d0d07fe, 0xf2f307fe, 0x0f0407fe, 0xf0fc07fe, 0x040f07fe, 0xfffff802, 0x0605f802, 0xf9f9f802,
- 0x07fdf802, 0xf801f802, 0xfe07f802, 0x01f7f802, 0x0d0cf802, 0xf2f2f802, 0x0f03f802, 0xf0fbf802,
- 0x040ef802, 0xfffffe08, 0x0605fe08, 0xf9f9fe08, 0x07fdfe08, 0xf801fe08, 0xfe07fe08, 0x01f7fe08,
- 0x0d0cfe08, 0xf2f2fe08, 0x0f03fe08, 0xf0fbfe08, 0x040efe08, 0x000001f8, 0x060601f8, 0xf9fa01f8,
- 0x07fe01f8, 0xf80201f8, 0xfe0801f8, 0x01f801f8, 0x0d0d01f8, 0xf2f301f8, 0x0f0401f8, 0xf0fc01f8,
- 0x040f01f8, 0x00000d0d, 0x06060d0d, 0xf9fa0d0d, 0x07fe0d0d, 0xf8020d0d, 0xfe080d0d, 0x01f80d0d,
- 0x0d0d0d0d, 0xf2f30d0d, 0x0f040d0d, 0xf0fc0d0d, 0x040f0d0d, 0xfffff2f3, 0x0605f2f3, 0xf9f9f2f3,
- 0x07fdf2f3, 0xf801f2f3, 0xfe07f2f3, 0x01f7f2f3, 0x0d0cf2f3, 0xf2f2f2f3, 0x0f03f2f3, 0xf0fbf2f3,
- 0x040ef2f3, 0x00000f04, 0x06060f04, 0xf9fa0f04, 0x07fe0f04, 0xf8020f04, 0xfe080f04, 0x01f80f04,
- 0x0d0d0f04, 0xf2f30f04, 0x0f040f04, 0xf0fc0f04, 0x040f0f04, 0xfffff0fc, 0x0605f0fc, 0xf9f9f0fc,
- 0x07fdf0fc, 0xf801f0fc, 0xfe07f0fc, 0x01f7f0fc, 0x0d0cf0fc, 0xf2f2f0fc, 0x0f03f0fc, 0xf0fbf0fc,
- 0x040ef0fc, 0x0000040f, 0x0606040f, 0xf9fa040f, 0x07fe040f, 0xf802040f, 0xfe08040f, 0x01f8040f,
- 0x0d0d040f, 0xf2f3040f, 0x0f04040f, 0xf0fc040f, 0x040f040f, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000707, 0xfffff8f9, 0x000009fd, 0xfffff603, 0xfffffd0a, 0x000002f6, 0x00001010,
- 0xffffeff0, 0x00001205, 0xffffedfb, 0x00000512, 0xfffffaee, 0x00000cf3, 0xfffff30d, 0x000014fa,
- 0xffffeb06, 0xfffffa15, 0x000005eb, 0x00001e0f, 0xffffe1f1, 0x00000f1e, 0xfffff0e2, 0x00001e1e,
- 0xffffe1e2, 0x00002202, 0xffffddfe, 0x00000222, 0xfffffdde, 0x00001bed, 0xffffe413, 0xffffed1c,
- 0x000012e4, 0x00003620, 0xffffc9e0, 0x00002036, 0xffffdfca, 0x000028f5, 0xffffd70b, 0xfffff529,
- 0x00000ad7, 0x0000370f, 0xffffc8f1, 0x00000f37, 0xfffff0c9, 0x00003939, 0xffffc6c7, 0x00003eff,
- 0xffffc101, 0xffffff3f, 0x000000c1, 0x000027d8, 0xffffd828, 0x000036e2, 0xffffc91e, 0xffffe237,
- 0x00001dc9, 0x00005e25, 0xffffa1db, 0x0000255e, 0xffffdaa2, 0x00006041, 0xffff9fbf, 0x00004160,
- 0xffffbea0, 0x00004deb, 0xffffb215, 0xffffeb4e, 0x000014b2, 0x0000640f, 0xffff9bf1, 0x00000f64,
- 0xfffff09c, 0x00006a6a, 0xffff9596, 0x000073f8, 0xffff8c08, 0xfffff874, 0x0000078c, 0x00004ec1,
- 0xffffb13f, 0xffffc14f, 0x00003eb1, 0x000068cd, 0xffff9733, 0xffffcd69, 0x00003297, 0x00007788,
- 0xffff8878, 0x00002b2b, 0xffffd4d5, 0x00005050, 0xffffafb0, 0x00000000, 0x07070000, 0xf8f90000,
- 0x09fd0000, 0xf6030000, 0xfd0a0000, 0x02f60000, 0x10100000, 0xeff00000, 0x12050000, 0xedfb0000,
- 0x05120000, 0x00000707, 0x07070707, 0xf8f90707, 0x09fd0707, 0xf6030707, 0xfd0a0707, 0x02f60707,
- 0x10100707, 0xeff00707, 0x12050707, 0xedfb0707, 0x05120707, 0xfffff8f9, 0x0706f8f9, 0xf8f8f8f9,
- 0x09fcf8f9, 0xf602f8f9, 0xfd09f8f9, 0x02f5f8f9, 0x100ff8f9, 0xefeff8f9, 0x1204f8f9, 0xedfaf8f9,
- 0x0511f8f9, 0x000009fd, 0x070709fd, 0xf8f909fd, 0x09fd09fd, 0xf60309fd, 0xfd0a09fd, 0x02f609fd,
- 0x101009fd, 0xeff009fd, 0x120509fd, 0xedfb09fd, 0x051209fd, 0xfffff603, 0x0706f603, 0xf8f8f603,
- 0x09fcf603, 0xf602f603, 0xfd09f603, 0x02f5f603, 0x100ff603, 0xefeff603, 0x1204f603, 0xedfaf603,
- 0x0511f603, 0xfffffd0a, 0x0706fd0a, 0xf8f8fd0a, 0x09fcfd0a, 0xf602fd0a, 0xfd09fd0a, 0x02f5fd0a,
- 0x100ffd0a, 0xefeffd0a, 0x1204fd0a, 0xedfafd0a, 0x0511fd0a, 0x000002f6, 0x070702f6, 0xf8f902f6,
- 0x09fd02f6, 0xf60302f6, 0xfd0a02f6, 0x02f602f6, 0x101002f6, 0xeff002f6, 0x120502f6, 0xedfb02f6,
- 0x051202f6, 0x00001010, 0x07071010, 0xf8f91010, 0x09fd1010, 0xf6031010, 0xfd0a1010, 0x02f61010,
- 0x10101010, 0xeff01010, 0x12051010, 0xedfb1010, 0x05121010, 0xffffeff0, 0x0706eff0, 0xf8f8eff0,
- 0x09fceff0, 0xf602eff0, 0xfd09eff0, 0x02f5eff0, 0x100feff0, 0xefefeff0, 0x1204eff0, 0xedfaeff0,
- 0x0511eff0, 0x00001205, 0x07071205, 0xf8f91205, 0x09fd1205, 0xf6031205, 0xfd0a1205, 0x02f61205,
- 0x10101205, 0xeff01205, 0x12051205, 0xedfb1205, 0x05121205, 0xffffedfb, 0x0706edfb, 0xf8f8edfb,
- 0x09fcedfb, 0xf602edfb, 0xfd09edfb, 0x02f5edfb, 0x100fedfb, 0xefefedfb, 0x1204edfb, 0xedfaedfb,
- 0x0511edfb, 0x00000512, 0x07070512, 0xf8f90512, 0x09fd0512, 0xf6030512, 0xfd0a0512, 0x02f60512,
- 0x10100512, 0xeff00512, 0x12050512, 0xedfb0512, 0x05120512, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000808, 0xfffff7f8, 0x00000afd, 0xfffff503, 0xfffffd0b, 0x000002f5, 0x00001212,
- 0xffffedee, 0x00001405, 0xffffebfb, 0x00000514, 0xfffffaec, 0x00000ef1, 0xfffff10f, 0x000017f9,
- 0xffffe807, 0xfffff918, 0x000006e8, 0x00002311, 0xffffdcef, 0x00001123, 0xffffeedd, 0x00002222,
- 0xffffddde, 0x00002603, 0xffffd9fd, 0x00000326, 0xfffffcda, 0x00001fea, 0xffffe016, 0xffffea20,
- 0x000015e0, 0x00003d25, 0xffffc2db, 0x0000253d, 0xffffdac3, 0x00002ef3, 0xffffd10d, 0xfffff32f,
- 0x00000cd1, 0x00003f11, 0xffffc0ef, 0x0000113f, 0xffffeec1, 0x00004141, 0xffffbebf, 0x000047ff,
- 0xffffb801, 0xffffff48, 0x000000b8, 0x00002dd2, 0xffffd22e, 0x00003edd, 0xffffc123, 0xffffdd3f,
- 0x000022c1, 0x00006b2b, 0xffff94d5, 0x00002b6b, 0xffffd495, 0x00006e4b, 0xffff91b5, 0x00004b6e,
- 0xffffb492, 0x000058e8, 0xffffa718, 0xffffe859, 0x000017a7, 0x00007211, 0xffff8def, 0x00001172,
- 0xffffee8e, 0x00007979, 0xffff8687, 0x00005ab8, 0xffffa548, 0xffffb85b, 0x000047a5, 0x000077c6,
- 0xffff883a, 0xffffc678, 0x00003988, 0x00003131, 0xffffcecf, 0x00005c5c, 0xffffa3a4, 0x00000000,
- 0x08080000, 0xf7f80000, 0x0afd0000, 0xf5030000, 0xfd0b0000, 0x02f50000, 0x12120000, 0xedee0000,
- 0x14050000, 0xebfb0000, 0x05140000, 0x00000808, 0x08080808, 0xf7f80808, 0x0afd0808, 0xf5030808,
- 0xfd0b0808, 0x02f50808, 0x12120808, 0xedee0808, 0x14050808, 0xebfb0808, 0x05140808, 0xfffff7f8,
- 0x0807f7f8, 0xf7f7f7f8, 0x0afcf7f8, 0xf502f7f8, 0xfd0af7f8, 0x02f4f7f8, 0x1211f7f8, 0xededf7f8,
- 0x1404f7f8, 0xebfaf7f8, 0x0513f7f8, 0x00000afd, 0x08080afd, 0xf7f80afd, 0x0afd0afd, 0xf5030afd,
- 0xfd0b0afd, 0x02f50afd, 0x12120afd, 0xedee0afd, 0x14050afd, 0xebfb0afd, 0x05140afd, 0xfffff503,
- 0x0807f503, 0xf7f7f503, 0x0afcf503, 0xf502f503, 0xfd0af503, 0x02f4f503, 0x1211f503, 0xededf503,
- 0x1404f503, 0xebfaf503, 0x0513f503, 0xfffffd0b, 0x0807fd0b, 0xf7f7fd0b, 0x0afcfd0b, 0xf502fd0b,
- 0xfd0afd0b, 0x02f4fd0b, 0x1211fd0b, 0xededfd0b, 0x1404fd0b, 0xebfafd0b, 0x0513fd0b, 0x000002f5,
- 0x080802f5, 0xf7f802f5, 0x0afd02f5, 0xf50302f5, 0xfd0b02f5, 0x02f502f5, 0x121202f5, 0xedee02f5,
- 0x140502f5, 0xebfb02f5, 0x051402f5, 0x00001212, 0x08081212, 0xf7f81212, 0x0afd1212, 0xf5031212,
- 0xfd0b1212, 0x02f51212, 0x12121212, 0xedee1212, 0x14051212, 0xebfb1212, 0x05141212, 0xffffedee,
- 0x0807edee, 0xf7f7edee, 0x0afcedee, 0xf502edee, 0xfd0aedee, 0x02f4edee, 0x1211edee, 0xedededee,
- 0x1404edee, 0xebfaedee, 0x0513edee, 0x00001405, 0x08081405, 0xf7f81405, 0x0afd1405, 0xf5031405,
- 0xfd0b1405, 0x02f51405, 0x12121405, 0xedee1405, 0x14051405, 0xebfb1405, 0x05141405, 0xffffebfb,
- 0x0807ebfb, 0xf7f7ebfb, 0x0afcebfb, 0xf502ebfb, 0xfd0aebfb, 0x02f4ebfb, 0x1211ebfb, 0xededebfb,
- 0x1404ebfb, 0xebfaebfb, 0x0513ebfb, 0x00000514, 0x08080514, 0xf7f80514, 0x0afd0514, 0xf5030514,
- 0xfd0b0514, 0x02f50514, 0x12120514, 0xedee0514, 0x14050514, 0xebfb0514, 0x05140514, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000909, 0xfffff6f7, 0x00000bfd, 0xfffff403, 0xfffffd0c, 0x000002f4, 0x00001414,
- 0xffffebec, 0x00001706, 0xffffe8fa, 0x00000617, 0xfffff9e9, 0x000010ef, 0xffffef11, 0x00001af9,
- 0xffffe507, 0xfffff91b, 0x000006e5, 0x00002713, 0xffffd8ed, 0x00001327, 0xffffecd9, 0x00002727,
- 0xffffd8d9, 0x00002b03, 0xffffd4fd, 0x0000032b, 0xfffffcd5, 0x000023e8, 0xffffdc18, 0xffffe824,
- 0x000017dc, 0x0000452a, 0xffffbad6, 0x00002a45, 0xffffd5bb, 0x000034f2, 0xffffcb0e, 0xfffff235,
- 0x00000dcb, 0x00004713, 0xffffb8ed, 0x00001347, 0xffffecb9, 0x00004949, 0xffffb6b7, 0x00004ffe,
- 0xffffb002, 0xfffffe50, 0x000001b0, 0x000033cc, 0xffffcc34, 0x000045d9, 0xffffba27, 0xffffd946,
- 0x000026ba, 0x00007930, 0xffff86d0, 0x00003079, 0xffffcf87, 0x00007c54, 0xffff83ac, 0x0000547c,
- 0xffffab84, 0x000063e5, 0xffff9c1b, 0xffffe564, 0x00001a9c, 0x000065af, 0xffff9a51, 0xffffaf66,
- 0x0000509a, 0x00003737, 0xffffc8c9, 0x00006868, 0xffff9798, 0x00000000, 0x09090000, 0xf6f70000,
- 0x0bfd0000, 0xf4030000, 0xfd0c0000, 0x02f40000, 0x14140000, 0xebec0000, 0x17060000, 0xe8fa0000,
- 0x06170000, 0xf9e90000, 0x00000909, 0x09090909, 0xf6f70909, 0x0bfd0909, 0xf4030909, 0xfd0c0909,
- 0x02f40909, 0x14140909, 0xebec0909, 0x17060909, 0xe8fa0909, 0x06170909, 0xf9e90909, 0xfffff6f7,
- 0x0908f6f7, 0xf6f6f6f7, 0x0bfcf6f7, 0xf402f6f7, 0xfd0bf6f7, 0x02f3f6f7, 0x1413f6f7, 0xebebf6f7,
- 0x1705f6f7, 0xe8f9f6f7, 0x0616f6f7, 0xf9e8f6f7, 0x00000bfd, 0x09090bfd, 0xf6f70bfd, 0x0bfd0bfd,
- 0xf4030bfd, 0xfd0c0bfd, 0x02f40bfd, 0x14140bfd, 0xebec0bfd, 0x17060bfd, 0xe8fa0bfd, 0x06170bfd,
- 0xf9e90bfd, 0xfffff403, 0x0908f403, 0xf6f6f403, 0x0bfcf403, 0xf402f403, 0xfd0bf403, 0x02f3f403,
- 0x1413f403, 0xebebf403, 0x1705f403, 0xe8f9f403, 0x0616f403, 0xf9e8f403, 0xfffffd0c, 0x0908fd0c,
- 0xf6f6fd0c, 0x0bfcfd0c, 0xf402fd0c, 0xfd0bfd0c, 0x02f3fd0c, 0x1413fd0c, 0xebebfd0c, 0x1705fd0c,
- 0xe8f9fd0c, 0x0616fd0c, 0xf9e8fd0c, 0x000002f4, 0x090902f4, 0xf6f702f4, 0x0bfd02f4, 0xf40302f4,
- 0xfd0c02f4, 0x02f402f4, 0x141402f4, 0xebec02f4, 0x170602f4, 0xe8fa02f4, 0x061702f4, 0xf9e902f4,
- 0x00001414, 0x09091414, 0xf6f71414, 0x0bfd1414, 0xf4031414, 0xfd0c1414, 0x02f41414, 0x14141414,
- 0xebec1414, 0x17061414, 0xe8fa1414, 0x06171414, 0xf9e91414, 0xffffebec, 0x0908ebec, 0xf6f6ebec,
- 0x0bfcebec, 0xf402ebec, 0xfd0bebec, 0x02f3ebec, 0x1413ebec, 0xebebebec, 0x1705ebec, 0xe8f9ebec,
- 0x0616ebec, 0xf9e8ebec, 0x00001706, 0x09091706, 0xf6f71706, 0x0bfd1706, 0xf4031706, 0xfd0c1706,
- 0x02f41706, 0x14141706, 0xebec1706, 0x17061706, 0xe8fa1706, 0x06171706, 0xf9e91706, 0xffffe8fa,
- 0x0908e8fa, 0xf6f6e8fa, 0x0bfce8fa, 0xf402e8fa, 0xfd0be8fa, 0x02f3e8fa, 0x1413e8fa, 0xebebe8fa,
- 0x1705e8fa, 0xe8f9e8fa, 0x0616e8fa, 0xf9e8e8fa, 0x00000617, 0x09090617, 0xf6f70617, 0x0bfd0617,
- 0xf4030617, 0xfd0c0617, 0x02f40617, 0x14140617, 0xebec0617, 0x17060617, 0xe8fa0617, 0x06170617,
- 0xf9e90617, 0xfffff9e9, 0x0908f9e9, 0xf6f6f9e9, 0x0bfcf9e9, 0xf402f9e9, 0xfd0bf9e9, 0x02f3f9e9,
- 0x1413f9e9, 0xebebf9e9, 0x1705f9e9, 0xe8f9f9e9, 0x0616f9e9, 0xf9e8f9e9, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000202, 0xfffffdfe, 0x00000200, 0xfffffe00, 0x00000002, 0xfffffffe, 0x00000404,
- 0xfffffbfc, 0x00000400, 0xfffffc00, 0x00000004, 0xfffffffc, 0x000003fc, 0xfffffc04, 0x000005fe,
- 0xfffffa02, 0xfffffe06, 0x000001fa, 0x00000804, 0xfffff7fc, 0x00000408, 0xfffffbf8, 0x00000808,
- 0xfffff7f8, 0x00000a00, 0xfffff600, 0x0000000a, 0xfffffff6, 0x000007fc, 0xfffff804, 0xfffffc08,
- 0x000003f8, 0x00000e08, 0xfffff1f8, 0x0000080e, 0xfffff7f2, 0x00000bfe, 0xfffff402, 0xfffffe0c,
- 0x000001f4, 0x00001004, 0xffffeffc, 0x00000410, 0xfffffbf0, 0x00001010, 0xffffeff0, 0x00001200,
- 0xffffee00, 0x00000012, 0xffffffee, 0x00000bf4, 0xfffff40c, 0x00000ff8, 0xfffff008, 0xfffff810,
- 0x000007f0, 0x00001a0a, 0xffffe5f6, 0x00000a1a, 0xfffff5e6, 0x00001c12, 0xffffe3ee, 0x0000121c,
- 0xffffede4, 0x000015fa, 0xffffea06, 0xfffffa16, 0x000005ea, 0x00001c04, 0xffffe3fc, 0x0000041c,
- 0xfffffbe4, 0x00001e1e, 0xffffe1e2, 0x00001ffe, 0xffffe002, 0xfffffe20, 0x000001e0, 0x000015ee,
- 0xffffea12, 0xffffee16, 0x000011ea, 0x00001df2, 0xffffe20e, 0xfffff21e, 0x00000de2, 0x00002e16,
- 0xffffd1ea, 0x0000162e, 0xffffe9d2, 0x00002e0c, 0xffffd1f4, 0x00000c2e, 0xfffff3d2, 0x00003022,
- 0xffffcfde, 0x00002230, 0xffffddd0, 0x000027f6, 0xffffd80a, 0xfffff628, 0x000009d8, 0x00003204,
- 0xffffcdfc, 0x00000432, 0xfffffbce, 0x00003636, 0xffffc9ca, 0x000021de, 0xffffde22, 0x000029e4,
- 0xffffd61c, 0xffffe42a, 0x00001bd6, 0x00003bfa, 0xffffc406, 0xfffffa3c, 0x000005c4, 0x00004c1a,
- 0xffffb3e6, 0x00001a4c, 0xffffe5b4, 0x00004c2a, 0xffffb3d6, 0x00002a4c, 0xffffd5b4, 0x000035e8,
- 0xffffca18, 0xffffe836, 0x000017ca, 0x00004e0e, 0xffffb1f2, 0x00000e4e, 0xfffff1b2, 0x0000523e,
- 0xffffadc2, 0x00003e52, 0xffffc1ae, 0x000049ec, 0xffffb614, 0xffffec4a, 0x000013b6, 0x00005802,
- 0xffffa7fe, 0x00000258, 0xfffffda8, 0x00005c5c, 0xffffa3a4, 0x00003bcc, 0xffffc434, 0xffffcc3c,
- 0x000033c4, 0x00007634, 0xffff89cc, 0x00003476, 0xffffcb8a, 0x000049d4, 0xffffb62c, 0xffffd44a,
- 0x00002bb6, 0x0000764a, 0xffff89b6, 0x00004a76, 0xffffb58a, 0x00007620, 0xffff89e0, 0x00002076,
- 0xffffdf8a, 0x000065f4, 0xffff9a0c, 0xfffff466, 0x00000b9a, 0x00005fd8, 0xffffa028, 0xffffd860,
- 0x000027a0, 0x000075de, 0xffff8a22, 0xffffde76, 0x0000218a, 0x000057a8, 0xffffa858, 0x000067b2,
- 0xffff984e, 0xffffb268, 0x00004d98, 0x00000c0c, 0xfffff3f4, 0x00001616, 0xffffe9ea, 0x00002a2a,
- 0xffffd5d6, 0x00004848, 0xffffb7b8, 0x00000000, 0x02020000, 0xfdfe0000, 0x02000000, 0xfe000000,
- 0x00020000, 0xfffe0000, 0x00000202, 0x02020202, 0xfdfe0202, 0x02000202, 0xfe000202, 0x00020202,
- 0xfffe0202, 0xfffffdfe, 0x0201fdfe, 0xfdfdfdfe, 0x01fffdfe, 0xfdfffdfe, 0x0001fdfe, 0xfffdfdfe,
- 0x00000200, 0x02020200, 0xfdfe0200, 0x02000200, 0xfe000200, 0x00020200, 0xfffe0200, 0xfffffe00,
- 0x0201fe00, 0xfdfdfe00, 0x01fffe00, 0xfdfffe00, 0x0001fe00, 0xfffdfe00, 0x00000002, 0x02020002,
- 0xfdfe0002, 0x02000002, 0xfe000002, 0x00020002, 0xfffe0002, 0xfffffffe, 0x0201fffe, 0xfdfdfffe,
- 0x01fffffe, 0xfdfffffe, 0x0001fffe, 0xfffdfffe, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000303, 0xfffffcfd, 0x00000300, 0xfffffd00, 0x00000003, 0xfffffffd, 0x00000606,
- 0xfffff9fa, 0x00000903, 0xfffff6fd, 0x00000309, 0xfffffcf7, 0x000008fd, 0xfffff703, 0xfffffd09,
- 0x000002f7, 0x000005fa, 0xfffffa06, 0x00000c06, 0xfffff3fa, 0x0000060c, 0xfffff9f4, 0x00000c0c,
- 0xfffff3f4, 0x00000f00, 0xfffff100, 0x0000000f, 0xfffffff1, 0x00000bf7, 0xfffff409, 0xfffff70c,
- 0x000008f4, 0x0000180f, 0xffffe7f1, 0x00000f18, 0xfffff0e8, 0x000011fa, 0xffffee06, 0xfffffa12,
- 0x000005ee, 0x00001806, 0xffffe7fa, 0x00000618, 0xfffff9e8, 0x00001818, 0xffffe7e8, 0x00001b00,
- 0xffffe500, 0x0000001b, 0xffffffe5, 0x000011ee, 0xffffee12, 0x000017f4, 0xffffe80c, 0xfffff418,
- 0x00000be8, 0x0000270f, 0xffffd8f1, 0x00000f27, 0xfffff0d9, 0x00002a1b, 0xffffd5e5, 0x00001b2a,
- 0xffffe4d6, 0x000020f7, 0xffffdf09, 0xfffff721, 0x000008df, 0x00002a06, 0xffffd5fa, 0x0000062a,
- 0xfffff9d6, 0x00002d2d, 0xffffd2d3, 0x000032fd, 0xffffcd03, 0xfffffd33, 0x000002cd, 0x000020e5,
- 0xffffdf1b, 0xffffe521, 0x00001adf, 0x00002ceb, 0xffffd315, 0xffffeb2d, 0x000014d3, 0x00004521,
- 0xffffbadf, 0x00002145, 0xffffdebb, 0x00004512, 0xffffbaee, 0x00001245, 0xffffedbb, 0x00004836,
- 0xffffb7ca, 0x00003648, 0xffffc9b8, 0x00003eee, 0xffffc112, 0xffffee3f, 0x000011c1, 0x00004e06,
- 0xffffb1fa, 0x0000064e, 0xfffff9b2, 0x00005151, 0xffffaeaf, 0x000032cd, 0xffffcd33, 0x00003ed6,
- 0xffffc12a, 0xffffd63f, 0x000029c1, 0x000059f7, 0xffffa609, 0xfffff75a, 0x000008a6, 0x0000722a,
- 0xffff8dd6, 0x00002a72, 0xffffd58e, 0x0000753f, 0xffff8ac1, 0x00003f75, 0xffffc08b, 0x000050dc,
- 0xffffaf24, 0xffffdc51, 0x000023af, 0x00007815, 0xffff87eb, 0x00001578, 0xffffea88, 0x00007b60,
- 0xffff84a0, 0x0000607b, 0xffff9f85, 0x00006ee2, 0xffff911e, 0xffffe26f, 0x00001d91, 0x00005cb2,
- 0xffffa34e, 0xffffb25d, 0x00004da3, 0x000071bb, 0xffff8e45, 0xffffbb72, 0x0000448e, 0x00001212,
- 0xffffedee, 0x00002121, 0xffffdedf, 0x00003f3f, 0xffffc0c1, 0x00006c6c, 0xffff9394, 0x00000000,
- 0x03030000, 0xfcfd0000, 0x03000000, 0xfd000000, 0x00030000, 0xfffd0000, 0x06060000, 0xf9fa0000,
- 0x00000303, 0x03030303, 0xfcfd0303, 0x03000303, 0xfd000303, 0x00030303, 0xfffd0303, 0x06060303,
- 0xf9fa0303, 0xfffffcfd, 0x0302fcfd, 0xfcfcfcfd, 0x02fffcfd, 0xfcfffcfd, 0x0002fcfd, 0xfffcfcfd,
- 0x0605fcfd, 0xf9f9fcfd, 0x00000300, 0x03030300, 0xfcfd0300, 0x03000300, 0xfd000300, 0x00030300,
- 0xfffd0300, 0x06060300, 0xf9fa0300, 0xfffffd00, 0x0302fd00, 0xfcfcfd00, 0x02fffd00, 0xfcfffd00,
- 0x0002fd00, 0xfffcfd00, 0x0605fd00, 0xf9f9fd00, 0x00000003, 0x03030003, 0xfcfd0003, 0x03000003,
- 0xfd000003, 0x00030003, 0xfffd0003, 0x06060003, 0xf9fa0003, 0xfffffffd, 0x0302fffd, 0xfcfcfffd,
- 0x02fffffd, 0xfcfffffd, 0x0002fffd, 0xfffcfffd, 0x0605fffd, 0xf9f9fffd, 0x00000606, 0x03030606,
- 0xfcfd0606, 0x03000606, 0xfd000606, 0x00030606, 0xfffd0606, 0x06060606, 0xf9fa0606, 0xfffff9fa,
- 0x0302f9fa, 0xfcfcf9fa, 0x02fff9fa, 0xfcfff9fa, 0x0002f9fa, 0xfffcf9fa, 0x0605f9fa, 0xf9f9f9fa,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000404, 0xfffffbfc, 0x00000400, 0xfffffc00, 0x00000004, 0xfffffffc, 0x00000804,
- 0xfffff7fc, 0x00000408, 0xfffffbf8, 0x00000808, 0xfffff7f8, 0x000007f8, 0xfffff808, 0x00000bfc,
- 0xfffff404, 0xfffffc0c, 0x000003f4, 0x00001008, 0xffffeff8, 0x00000810, 0xfffff7f0, 0x00001010,
- 0xffffeff0, 0x00001400, 0xffffec00, 0x00000014, 0xffffffec, 0x00000ff4, 0xfffff00c, 0xfffff410,
- 0x00000bf0, 0x000017fc, 0xffffe804, 0xfffffc18, 0x000003e8, 0x00002010, 0xffffdff0, 0x00001020,
- 0xffffefe0, 0x00002008, 0xffffdff8, 0x00000820, 0xfffff7e0, 0x00002020, 0xffffdfe0, 0x00002400,
- 0xffffdc00, 0x00000024, 0xffffffdc, 0x000017e8, 0xffffe818, 0x00001ff0, 0xffffe010, 0xfffff020,
- 0x00000fe0, 0x00003414, 0xffffcbec, 0x00001434, 0xffffebcc, 0x00003824, 0xffffc7dc, 0x00002438,
- 0xffffdbc8, 0x00002bf4, 0xffffd40c, 0xfffff42c, 0x00000bd4, 0x00003808, 0xffffc7f8, 0x00000838,
- 0xfffff7c8, 0x00003c3c, 0xffffc3c4, 0x00003ffc, 0xffffc004, 0xfffffc40, 0x000003c0, 0x00002bdc,
- 0xffffd424, 0xffffdc2c, 0x000023d4, 0x00003be4, 0xffffc41c, 0xffffe43c, 0x00001bc4, 0x00005c2c,
- 0xffffa3d4, 0x00002c5c, 0xffffd3a4, 0x00005c18, 0xffffa3e8, 0x0000185c, 0xffffe7a4, 0x00006048,
- 0xffff9fb8, 0x00004860, 0xffffb7a0, 0x000053ec, 0xffffac14, 0xffffec54, 0x000013ac, 0x00006408,
- 0xffff9bf8, 0x00000864, 0xfffff79c, 0x00006c6c, 0xffff9394, 0x000043bc, 0xffffbc44, 0x000053c8,
- 0xffffac38, 0xffffc854, 0x000037ac, 0x000077f4, 0xffff880c, 0xfffff478, 0x00000b88, 0x00006bd0,
- 0xffff9430, 0xffffd06c, 0x00002f94, 0x00007b98, 0xffff8468, 0xffff987c, 0x00006784, 0x00001818,
- 0xffffe7e8, 0x00002c2c, 0xffffd3d4, 0x00005454, 0xffffabac, 0x00000000, 0x04040000, 0xfbfc0000,
- 0x04000000, 0xfc000000, 0x00040000, 0xfffc0000, 0x08040000, 0xf7fc0000, 0x04080000, 0x00000404,
- 0x04040404, 0xfbfc0404, 0x04000404, 0xfc000404, 0x00040404, 0xfffc0404, 0x08040404, 0xf7fc0404,
- 0x04080404, 0xfffffbfc, 0x0403fbfc, 0xfbfbfbfc, 0x03fffbfc, 0xfbfffbfc, 0x0003fbfc, 0xfffbfbfc,
- 0x0803fbfc, 0xf7fbfbfc, 0x0407fbfc, 0x00000400, 0x04040400, 0xfbfc0400, 0x04000400, 0xfc000400,
- 0x00040400, 0xfffc0400, 0x08040400, 0xf7fc0400, 0x04080400, 0xfffffc00, 0x0403fc00, 0xfbfbfc00,
- 0x03fffc00, 0xfbfffc00, 0x0003fc00, 0xfffbfc00, 0x0803fc00, 0xf7fbfc00, 0x0407fc00, 0x00000004,
- 0x04040004, 0xfbfc0004, 0x04000004, 0xfc000004, 0x00040004, 0xfffc0004, 0x08040004, 0xf7fc0004,
- 0x04080004, 0xfffffffc, 0x0403fffc, 0xfbfbfffc, 0x03fffffc, 0xfbfffffc, 0x0003fffc, 0xfffbfffc,
- 0x0803fffc, 0xf7fbfffc, 0x0407fffc, 0x00000804, 0x04040804, 0xfbfc0804, 0x04000804, 0xfc000804,
- 0x00040804, 0xfffc0804, 0x08040804, 0xf7fc0804, 0x04080804, 0xfffff7fc, 0x0403f7fc, 0xfbfbf7fc,
- 0x03fff7fc, 0xfbfff7fc, 0x0003f7fc, 0xfffbf7fc, 0x0803f7fc, 0xf7fbf7fc, 0x0407f7fc, 0x00000408,
- 0x04040408, 0xfbfc0408, 0x04000408, 0xfc000408, 0x00040408, 0xfffc0408, 0x08040408, 0xf7fc0408,
- 0x04080408, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000505, 0xfffffafb, 0x00000500, 0xfffffb00, 0x00000005, 0xfffffffb, 0x00000a0a,
- 0xfffff5f6, 0x00000f05, 0xfffff0fb, 0x0000050f, 0xfffffaf1, 0x000009f6, 0xfffff60a, 0x00000efb,
- 0xfffff105, 0xfffffb0f, 0x000004f1, 0x0000140a, 0xffffebf6, 0x00000a14, 0xfffff5ec, 0x00001414,
- 0xffffebec, 0x00001900, 0xffffe700, 0x00000019, 0xffffffe7, 0x000013f1, 0xffffec0f, 0xfffff114,
- 0x00000eec, 0x00002819, 0xffffd7e7, 0x00001928, 0xffffe6d8, 0x00001df6, 0xffffe20a, 0xfffff61e,
- 0x000009e2, 0x0000280a, 0xffffd7f6, 0x00000a28, 0xfffff5d8, 0x00002828, 0xffffd7d8, 0x00002d00,
- 0xffffd300, 0x0000002d, 0xffffffd3, 0x00001de2, 0xffffe21e, 0x000027ec, 0xffffd814, 0xffffec28,
- 0x000013d8, 0x00004119, 0xffffbee7, 0x00001941, 0xffffe6bf, 0x0000462d, 0xffffb9d3, 0x00002d46,
- 0xffffd2ba, 0x000036f1, 0xffffc90f, 0xfffff137, 0x00000ec9, 0x0000460a, 0xffffb9f6, 0x00000a46,
- 0xfffff5ba, 0x00004b4b, 0xffffb4b5, 0x000054fb, 0xffffab05, 0xfffffb55, 0x000004ab, 0x000036d3,
- 0xffffc92d, 0xffffd337, 0x00002cc9, 0x00004add, 0xffffb523, 0xffffdd4b, 0x000022b5, 0x00007337,
- 0xffff8cc9, 0x00003773, 0xffffc88d, 0x0000731e, 0xffff8ce2, 0x00001e73, 0xffffe18d, 0x0000785a,
- 0xffff87a6, 0x00005a78, 0xffffa588, 0x000068e2, 0xffff971e, 0xffffe269, 0x00001d97, 0x000054ab,
- 0xffffab55, 0x000068ba, 0xffff9746, 0xffffba69, 0x00004597, 0x00001e1e, 0xffffe1e2, 0x00003c3c,
- 0xffffc3c4, 0x00006969, 0xffff9697, 0x00000000, 0x05050000, 0xfafb0000, 0x05000000, 0xfb000000,
- 0x00050000, 0xfffb0000, 0x0a0a0000, 0xf5f60000, 0x0f050000, 0xf0fb0000, 0x00000505, 0x05050505,
- 0xfafb0505, 0x05000505, 0xfb000505, 0x00050505, 0xfffb0505, 0x0a0a0505, 0xf5f60505, 0x0f050505,
- 0xf0fb0505, 0xfffffafb, 0x0504fafb, 0xfafafafb, 0x04fffafb, 0xfafffafb, 0x0004fafb, 0xfffafafb,
- 0x0a09fafb, 0xf5f5fafb, 0x0f04fafb, 0xf0fafafb, 0x00000500, 0x05050500, 0xfafb0500, 0x05000500,
- 0xfb000500, 0x00050500, 0xfffb0500, 0x0a0a0500, 0xf5f60500, 0x0f050500, 0xf0fb0500, 0xfffffb00,
- 0x0504fb00, 0xfafafb00, 0x04fffb00, 0xfafffb00, 0x0004fb00, 0xfffafb00, 0x0a09fb00, 0xf5f5fb00,
- 0x0f04fb00, 0xf0fafb00, 0x00000005, 0x05050005, 0xfafb0005, 0x05000005, 0xfb000005, 0x00050005,
- 0xfffb0005, 0x0a0a0005, 0xf5f60005, 0x0f050005, 0xf0fb0005, 0xfffffffb, 0x0504fffb, 0xfafafffb,
- 0x04fffffb, 0xfafffffb, 0x0004fffb, 0xfffafffb, 0x0a09fffb, 0xf5f5fffb, 0x0f04fffb, 0xf0fafffb,
- 0x00000a0a, 0x05050a0a, 0xfafb0a0a, 0x05000a0a, 0xfb000a0a, 0x00050a0a, 0xfffb0a0a, 0x0a0a0a0a,
- 0xf5f60a0a, 0x0f050a0a, 0xf0fb0a0a, 0xfffff5f6, 0x0504f5f6, 0xfafaf5f6, 0x04fff5f6, 0xfafff5f6,
- 0x0004f5f6, 0xfffaf5f6, 0x0a09f5f6, 0xf5f5f5f6, 0x0f04f5f6, 0xf0faf5f6, 0x00000f05, 0x05050f05,
- 0xfafb0f05, 0x05000f05, 0xfb000f05, 0x00050f05, 0xfffb0f05, 0x0a0a0f05, 0xf5f60f05, 0x0f050f05,
- 0xf0fb0f05, 0xfffff0fb, 0x0504f0fb, 0xfafaf0fb, 0x04fff0fb, 0xfafff0fb, 0x0004f0fb, 0xfffaf0fb,
- 0x0a09f0fb, 0xf5f5f0fb, 0x0f04f0fb, 0xf0faf0fb, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000606, 0xfffff9fa, 0x00000600, 0xfffffa00, 0x00000006, 0xfffffffa, 0x00000c0c,
- 0xfffff3f4, 0x00000c06, 0xfffff3fa, 0x0000060c, 0xfffff9f4, 0x00000bf4, 0xfffff40c, 0x000011fa,
- 0xffffee06, 0xfffffa12, 0x000005ee, 0x0000180c, 0xffffe7f4, 0x00000c18, 0xfffff3e8, 0x00001818,
- 0xffffe7e8, 0x00001e00, 0xffffe200, 0x0000001e, 0xffffffe2, 0x000017ee, 0xffffe812, 0xffffee18,
- 0x000011e8, 0x0000301e, 0xffffcfe2, 0x00001e30, 0xffffe1d0, 0x000023fa, 0xffffdc06, 0xfffffa24,
- 0x000005dc, 0x0000300c, 0xffffcff4, 0x00000c30, 0xfffff3d0, 0x00003030, 0xffffcfd0, 0x00003600,
- 0xffffca00, 0x00000036, 0xffffffca, 0x000023dc, 0xffffdc24, 0x00002fe8, 0xffffd018, 0xffffe830,
- 0x000017d0, 0x00004e1e, 0xffffb1e2, 0x00001e4e, 0xffffe1b2, 0x00005436, 0xffffabca, 0x00003654,
- 0xffffc9ac, 0x000041ee, 0xffffbe12, 0xffffee42, 0x000011be, 0x0000540c, 0xffffabf4, 0x00000c54,
- 0xfffff3ac, 0x00005a5a, 0xffffa5a6, 0x00005ffa, 0xffffa006, 0xfffffa60, 0x000005a0, 0x000041ca,
- 0xffffbe36, 0xffffca42, 0x000035be, 0x000059d6, 0xffffa62a, 0xffffd65a, 0x000029a6, 0x00007de2,
- 0xffff821e, 0xffffe27e, 0x00001d82, 0x0000659a, 0xffff9a66, 0x00007dac, 0xffff8254, 0xffffac7e,
- 0x00005382, 0x00002424, 0xffffdbdc, 0x00004242, 0xffffbdbe, 0x00000000, 0x06060000, 0xf9fa0000,
- 0x06000000, 0xfa000000, 0x00060000, 0xfffa0000, 0x0c0c0000, 0xf3f40000, 0x0c060000, 0xf3fa0000,
- 0x060c0000, 0x00000606, 0x06060606, 0xf9fa0606, 0x06000606, 0xfa000606, 0x00060606, 0xfffa0606,
- 0x0c0c0606, 0xf3f40606, 0x0c060606, 0xf3fa0606, 0x060c0606, 0xfffff9fa, 0x0605f9fa, 0xf9f9f9fa,
- 0x05fff9fa, 0xf9fff9fa, 0x0005f9fa, 0xfff9f9fa, 0x0c0bf9fa, 0xf3f3f9fa, 0x0c05f9fa, 0xf3f9f9fa,
- 0x060bf9fa, 0x00000600, 0x06060600, 0xf9fa0600, 0x06000600, 0xfa000600, 0x00060600, 0xfffa0600,
- 0x0c0c0600, 0xf3f40600, 0x0c060600, 0xf3fa0600, 0x060c0600, 0xfffffa00, 0x0605fa00, 0xf9f9fa00,
- 0x05fffa00, 0xf9fffa00, 0x0005fa00, 0xfff9fa00, 0x0c0bfa00, 0xf3f3fa00, 0x0c05fa00, 0xf3f9fa00,
- 0x060bfa00, 0x00000006, 0x06060006, 0xf9fa0006, 0x06000006, 0xfa000006, 0x00060006, 0xfffa0006,
- 0x0c0c0006, 0xf3f40006, 0x0c060006, 0xf3fa0006, 0x060c0006, 0xfffffffa, 0x0605fffa, 0xf9f9fffa,
- 0x05fffffa, 0xf9fffffa, 0x0005fffa, 0xfff9fffa, 0x0c0bfffa, 0xf3f3fffa, 0x0c05fffa, 0xf3f9fffa,
- 0x060bfffa, 0x00000c0c, 0x06060c0c, 0xf9fa0c0c, 0x06000c0c, 0xfa000c0c, 0x00060c0c, 0xfffa0c0c,
- 0x0c0c0c0c, 0xf3f40c0c, 0x0c060c0c, 0xf3fa0c0c, 0x060c0c0c, 0xfffff3f4, 0x0605f3f4, 0xf9f9f3f4,
- 0x05fff3f4, 0xf9fff3f4, 0x0005f3f4, 0xfff9f3f4, 0x0c0bf3f4, 0xf3f3f3f4, 0x0c05f3f4, 0xf3f9f3f4,
- 0x060bf3f4, 0x00000c06, 0x06060c06, 0xf9fa0c06, 0x06000c06, 0xfa000c06, 0x00060c06, 0xfffa0c06,
- 0x0c0c0c06, 0xf3f40c06, 0x0c060c06, 0xf3fa0c06, 0x060c0c06, 0xfffff3fa, 0x0605f3fa, 0xf9f9f3fa,
- 0x05fff3fa, 0xf9fff3fa, 0x0005f3fa, 0xfff9f3fa, 0x0c0bf3fa, 0xf3f3f3fa, 0x0c05f3fa, 0xf3f9f3fa,
- 0x060bf3fa, 0x0000060c, 0x0606060c, 0xf9fa060c, 0x0600060c, 0xfa00060c, 0x0006060c, 0xfffa060c,
- 0x0c0c060c, 0xf3f4060c, 0x0c06060c, 0xf3fa060c, 0x060c060c, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000707, 0xfffff8f9, 0x00000700, 0xfffff900, 0x00000007, 0xfffffff9, 0x00000e0e,
- 0xfffff1f2, 0x00001507, 0xffffeaf9, 0x00000715, 0xfffff8eb, 0x00000df2, 0xfffff20e, 0x000014f9,
- 0xffffeb07, 0xfffff915, 0x000006eb, 0x00001c0e, 0xffffe3f2, 0x00000e1c, 0xfffff1e4, 0x00001c1c,
- 0xffffe3e4, 0x00002300, 0xffffdd00, 0x00000023, 0xffffffdd, 0x00001beb, 0xffffe415, 0xffffeb1c,
- 0x000014e4, 0x00003823, 0xffffc7dd, 0x00002338, 0xffffdcc8, 0x000029f2, 0xffffd60e, 0xfffff22a,
- 0x00000dd6, 0x0000380e, 0xffffc7f2, 0x00000e38, 0xfffff1c8, 0x00003838, 0xffffc7c8, 0x00003f00,
- 0xffffc100, 0x0000003f, 0xffffffc1, 0x000029d6, 0xffffd62a, 0x000037e4, 0xffffc81c, 0xffffe438,
- 0x00001bc8, 0x00005b23, 0xffffa4dd, 0x0000235b, 0xffffdca5, 0x0000623f, 0xffff9dc1, 0x00003f62,
- 0xffffc09e, 0x00004ceb, 0xffffb315, 0xffffeb4d, 0x000014b3, 0x0000620e, 0xffff9df2, 0x00000e62,
- 0xfffff19e, 0x00006969, 0xffff9697, 0x000076f9, 0xffff8907, 0xfffff977, 0x00000689, 0x00004cc1,
- 0xffffb33f, 0xffffc14d, 0x00003eb3, 0x000068cf, 0xffff9731, 0xffffcf69, 0x00003097, 0x00007689,
- 0xffff8977, 0x00002a2a, 0xffffd5d6, 0x00004d4d, 0xffffb2b3, 0x00000000, 0x07070000, 0xf8f90000,
- 0x07000000, 0xf9000000, 0x00070000, 0xfff90000, 0x0e0e0000, 0xf1f20000, 0x15070000, 0xeaf90000,
- 0x07150000, 0x00000707, 0x07070707, 0xf8f90707, 0x07000707, 0xf9000707, 0x00070707, 0xfff90707,
- 0x0e0e0707, 0xf1f20707, 0x15070707, 0xeaf90707, 0x07150707, 0xfffff8f9, 0x0706f8f9, 0xf8f8f8f9,
- 0x06fff8f9, 0xf8fff8f9, 0x0006f8f9, 0xfff8f8f9, 0x0e0df8f9, 0xf1f1f8f9, 0x1506f8f9, 0xeaf8f8f9,
- 0x0714f8f9, 0x00000700, 0x07070700, 0xf8f90700, 0x07000700, 0xf9000700, 0x00070700, 0xfff90700,
- 0x0e0e0700, 0xf1f20700, 0x15070700, 0xeaf90700, 0x07150700, 0xfffff900, 0x0706f900, 0xf8f8f900,
- 0x06fff900, 0xf8fff900, 0x0006f900, 0xfff8f900, 0x0e0df900, 0xf1f1f900, 0x1506f900, 0xeaf8f900,
- 0x0714f900, 0x00000007, 0x07070007, 0xf8f90007, 0x07000007, 0xf9000007, 0x00070007, 0xfff90007,
- 0x0e0e0007, 0xf1f20007, 0x15070007, 0xeaf90007, 0x07150007, 0xfffffff9, 0x0706fff9, 0xf8f8fff9,
- 0x06fffff9, 0xf8fffff9, 0x0006fff9, 0xfff8fff9, 0x0e0dfff9, 0xf1f1fff9, 0x1506fff9, 0xeaf8fff9,
- 0x0714fff9, 0x00000e0e, 0x07070e0e, 0xf8f90e0e, 0x07000e0e, 0xf9000e0e, 0x00070e0e, 0xfff90e0e,
- 0x0e0e0e0e, 0xf1f20e0e, 0x15070e0e, 0xeaf90e0e, 0x07150e0e, 0xfffff1f2, 0x0706f1f2, 0xf8f8f1f2,
- 0x06fff1f2, 0xf8fff1f2, 0x0006f1f2, 0xfff8f1f2, 0x0e0df1f2, 0xf1f1f1f2, 0x1506f1f2, 0xeaf8f1f2,
- 0x0714f1f2, 0x00001507, 0x07071507, 0xf8f91507, 0x07001507, 0xf9001507, 0x00071507, 0xfff91507,
- 0x0e0e1507, 0xf1f21507, 0x15071507, 0xeaf91507, 0x07151507, 0xffffeaf9, 0x0706eaf9, 0xf8f8eaf9,
- 0x06ffeaf9, 0xf8ffeaf9, 0x0006eaf9, 0xfff8eaf9, 0x0e0deaf9, 0xf1f1eaf9, 0x1506eaf9, 0xeaf8eaf9,
- 0x0714eaf9, 0x00000715, 0x07070715, 0xf8f90715, 0x07000715, 0xf9000715, 0x00070715, 0xfff90715,
- 0x0e0e0715, 0xf1f20715, 0x15070715, 0xeaf90715, 0x07150715, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000808, 0xfffff7f8, 0x00000800, 0xfffff800, 0x00000008, 0xfffffff8, 0x00001010,
- 0xffffeff0, 0x00001008, 0xffffeff8, 0x00000810, 0xfffff7f0, 0x00000ff0, 0xfffff010, 0x000017f8,
- 0xffffe808, 0xfffff818, 0x000007e8, 0x00002010, 0xffffdff0, 0x00001020, 0xffffefe0, 0x00002020,
- 0xffffdfe0, 0x00002800, 0xffffd800, 0x00000028, 0xffffffd8, 0x00001fe8, 0xffffe018, 0xffffe820,
- 0x000017e0, 0x00004028, 0xffffbfd8, 0x00002840, 0xffffd7c0, 0x00002ff0, 0xffffd010, 0xfffff030,
- 0x00000fd0, 0x00004010, 0xffffbff0, 0x00001040, 0xffffefc0, 0x00004040, 0xffffbfc0, 0x00004800,
- 0xffffb800, 0x00000048, 0xffffffb8, 0x00002fd0, 0xffffd030, 0x00003fe0, 0xffffc020, 0xffffe040,
- 0x00001fc0, 0x00006828, 0xffff97d8, 0x00002868, 0xffffd798, 0x00007048, 0xffff8fb8, 0x00004870,
- 0xffffb790, 0x000057e8, 0xffffa818, 0xffffe858, 0x000017a8, 0x00007010, 0xffff8ff0, 0x00001070,
- 0xffffef90, 0x00007878, 0xffff8788, 0x000057b8, 0xffffa848, 0xffffb858, 0x000047a8, 0x000077c8,
- 0xffff8838, 0xffffc878, 0x00003788, 0x00003030, 0xffffcfd0, 0x00005858, 0xffffa7a8, 0x00000000,
- 0x08080000, 0xf7f80000, 0x08000000, 0xf8000000, 0x00080000, 0xfff80000, 0x10100000, 0xeff00000,
- 0x10080000, 0xeff80000, 0x08100000, 0x00000808, 0x08080808, 0xf7f80808, 0x08000808, 0xf8000808,
- 0x00080808, 0xfff80808, 0x10100808, 0xeff00808, 0x10080808, 0xeff80808, 0x08100808, 0xfffff7f8,
- 0x0807f7f8, 0xf7f7f7f8, 0x07fff7f8, 0xf7fff7f8, 0x0007f7f8, 0xfff7f7f8, 0x100ff7f8, 0xefeff7f8,
- 0x1007f7f8, 0xeff7f7f8, 0x080ff7f8, 0x00000800, 0x08080800, 0xf7f80800, 0x08000800, 0xf8000800,
- 0x00080800, 0xfff80800, 0x10100800, 0xeff00800, 0x10080800, 0xeff80800, 0x08100800, 0xfffff800,
- 0x0807f800, 0xf7f7f800, 0x07fff800, 0xf7fff800, 0x0007f800, 0xfff7f800, 0x100ff800, 0xefeff800,
- 0x1007f800, 0xeff7f800, 0x080ff800, 0x00000008, 0x08080008, 0xf7f80008, 0x08000008, 0xf8000008,
- 0x00080008, 0xfff80008, 0x10100008, 0xeff00008, 0x10080008, 0xeff80008, 0x08100008, 0xfffffff8,
- 0x0807fff8, 0xf7f7fff8, 0x07fffff8, 0xf7fffff8, 0x0007fff8, 0xfff7fff8, 0x100ffff8, 0xefeffff8,
- 0x1007fff8, 0xeff7fff8, 0x080ffff8, 0x00001010, 0x08081010, 0xf7f81010, 0x08001010, 0xf8001010,
- 0x00081010, 0xfff81010, 0x10101010, 0xeff01010, 0x10081010, 0xeff81010, 0x08101010, 0xffffeff0,
- 0x0807eff0, 0xf7f7eff0, 0x07ffeff0, 0xf7ffeff0, 0x0007eff0, 0xfff7eff0, 0x100feff0, 0xefefeff0,
- 0x1007eff0, 0xeff7eff0, 0x080feff0, 0x00001008, 0x08081008, 0xf7f81008, 0x08001008, 0xf8001008,
- 0x00081008, 0xfff81008, 0x10101008, 0xeff01008, 0x10081008, 0xeff81008, 0x08101008, 0xffffeff8,
- 0x0807eff8, 0xf7f7eff8, 0x07ffeff8, 0xf7ffeff8, 0x0007eff8, 0xfff7eff8, 0x100feff8, 0xefefeff8,
- 0x1007eff8, 0xeff7eff8, 0x080feff8, 0x00000810, 0x08080810, 0xf7f80810, 0x08000810, 0xf8000810,
- 0x00080810, 0xfff80810, 0x10100810, 0xeff00810, 0x10080810, 0xeff80810, 0x08100810, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000909, 0xfffff6f7, 0x00000900, 0xfffff700, 0x00000009, 0xfffffff7, 0x00001212,
- 0xffffedee, 0x00001b09, 0xffffe4f7, 0x0000091b, 0xfffff6e5, 0x000011ee, 0xffffee12, 0x00001af7,
- 0xffffe509, 0xfffff71b, 0x000008e5, 0x00002412, 0xffffdbee, 0x00001224, 0xffffeddc, 0x00002424,
- 0xffffdbdc, 0x00002d00, 0xffffd300, 0x0000002d, 0xffffffd3, 0x000023e5, 0xffffdc1b, 0xffffe524,
- 0x00001adc, 0x0000482d, 0xffffb7d3, 0x00002d48, 0xffffd2b8, 0x000035ee, 0xffffca12, 0xffffee36,
- 0x000011ca, 0x00004812, 0xffffb7ee, 0x00001248, 0xffffedb8, 0x00004848, 0xffffb7b8, 0x00005100,
- 0xffffaf00, 0x00000051, 0xffffffaf, 0x000035ca, 0xffffca36, 0x000047dc, 0xffffb824, 0xffffdc48,
- 0x000023b8, 0x0000752d, 0xffff8ad3, 0x00002d75, 0xffffd28b, 0x00007e51, 0xffff81af, 0x0000517e,
- 0xffffae82, 0x000062e5, 0xffff9d1b, 0xffffe563, 0x00001a9d, 0x000062af, 0xffff9d51, 0xffffaf63,
- 0x0000509d, 0x00003636, 0xffffc9ca, 0x00006c6c, 0xffff9394, 0x00000000, 0x09090000, 0xf6f70000,
- 0x09000000, 0xf7000000, 0x00090000, 0xfff70000, 0x12120000, 0xedee0000, 0x1b090000, 0xe4f70000,
- 0x091b0000, 0xf6e50000, 0x00000909, 0x09090909, 0xf6f70909, 0x09000909, 0xf7000909, 0x00090909,
- 0xfff70909, 0x12120909, 0xedee0909, 0x1b090909, 0xe4f70909, 0x091b0909, 0xf6e50909, 0xfffff6f7,
- 0x0908f6f7, 0xf6f6f6f7, 0x08fff6f7, 0xf6fff6f7, 0x0008f6f7, 0xfff6f6f7, 0x1211f6f7, 0xededf6f7,
- 0x1b08f6f7, 0xe4f6f6f7, 0x091af6f7, 0xf6e4f6f7, 0x00000900, 0x09090900, 0xf6f70900, 0x09000900,
- 0xf7000900, 0x00090900, 0xfff70900, 0x12120900, 0xedee0900, 0x1b090900, 0xe4f70900, 0x091b0900,
- 0xf6e50900, 0xfffff700, 0x0908f700, 0xf6f6f700, 0x08fff700, 0xf6fff700, 0x0008f700, 0xfff6f700,
- 0x1211f700, 0xededf700, 0x1b08f700, 0xe4f6f700, 0x091af700, 0xf6e4f700, 0x00000009, 0x09090009,
- 0xf6f70009, 0x09000009, 0xf7000009, 0x00090009, 0xfff70009, 0x12120009, 0xedee0009, 0x1b090009,
- 0xe4f70009, 0x091b0009, 0xf6e50009, 0xfffffff7, 0x0908fff7, 0xf6f6fff7, 0x08fffff7, 0xf6fffff7,
- 0x0008fff7, 0xfff6fff7, 0x1211fff7, 0xededfff7, 0x1b08fff7, 0xe4f6fff7, 0x091afff7, 0xf6e4fff7,
- 0x00001212, 0x09091212, 0xf6f71212, 0x09001212, 0xf7001212, 0x00091212, 0xfff71212, 0x12121212,
- 0xedee1212, 0x1b091212, 0xe4f71212, 0x091b1212, 0xf6e51212, 0xffffedee, 0x0908edee, 0xf6f6edee,
- 0x08ffedee, 0xf6ffedee, 0x0008edee, 0xfff6edee, 0x1211edee, 0xedededee, 0x1b08edee, 0xe4f6edee,
- 0x091aedee, 0xf6e4edee, 0x00001b09, 0x09091b09, 0xf6f71b09, 0x09001b09, 0xf7001b09, 0x00091b09,
- 0xfff71b09, 0x12121b09, 0xedee1b09, 0x1b091b09, 0xe4f71b09, 0x091b1b09, 0xf6e51b09, 0xffffe4f7,
- 0x0908e4f7, 0xf6f6e4f7, 0x08ffe4f7, 0xf6ffe4f7, 0x0008e4f7, 0xfff6e4f7, 0x1211e4f7, 0xedede4f7,
- 0x1b08e4f7, 0xe4f6e4f7, 0x091ae4f7, 0xf6e4e4f7, 0x0000091b, 0x0909091b, 0xf6f7091b, 0x0900091b,
- 0xf700091b, 0x0009091b, 0xfff7091b, 0x1212091b, 0xedee091b, 0x1b09091b, 0xe4f7091b, 0x091b091b,
- 0xf6e5091b, 0xfffff6e5, 0x0908f6e5, 0xf6f6f6e5, 0x08fff6e5, 0xf6fff6e5, 0x0008f6e5, 0xfff6f6e5,
- 0x1211f6e5, 0xededf6e5, 0x1b08f6e5, 0xe4f6f6e5, 0x091af6e5, 0xf6e4f6e5, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000202, 0xfffffdfe, 0x00000300, 0xfffffd00, 0x00000003, 0xfffffffd, 0x00000606,
- 0xfffff9fa, 0x00000700, 0xfffff900, 0x00000007, 0xfffffff9, 0x000004fb, 0xfffffb05, 0xfffffb05,
- 0x000004fb, 0x00000b06, 0xfffff4fa, 0x0000060b, 0xfffff9f5, 0x00000800, 0xfffff800, 0x00000008,
- 0xfffffff8, 0x00000b0b, 0xfffff4f5, 0x00000c00, 0xfffff400, 0x0000000c, 0xfffffff4, 0x0000110c,
- 0xffffeef4, 0x00000c11, 0xfffff3ef, 0x00001111, 0xffffeeef, 0x00001206, 0xffffedfa, 0x00000612,
- 0xfffff9ee, 0x00000af8, 0xfffff508, 0xfffff80b, 0x000007f5, 0x00000f00, 0xfffff100, 0x0000000f,
- 0xfffffff1, 0x00001400, 0xffffec00, 0x00000014, 0xffffffec, 0x00001912, 0xffffe6ee, 0x00001219,
- 0xffffede7, 0x0000190b, 0xffffe6f5, 0x00000b19, 0xfffff4e7, 0x00001919, 0xffffe6e7, 0x00000df2,
- 0xfffff20e, 0xfffff20e, 0x00000df2, 0x00001a00, 0xffffe600, 0x0000001a, 0xffffffe6, 0x000011f5,
- 0xffffee0b, 0xfffff512, 0x00000aee, 0x000015f9, 0xffffea07, 0xfffff916, 0x000006ea, 0x0000221a,
- 0xffffdde6, 0x00001a22, 0xffffe5de, 0x00002212, 0xffffddee, 0x00001222, 0xffffedde, 0x00002222,
- 0xffffddde, 0x0000230b, 0xffffdcf5, 0x00000b23, 0xfffff4dd, 0x00001d00, 0xffffe300, 0x0000001d,
- 0xffffffe3, 0x000015ed, 0xffffea13, 0xffffed16, 0x000012ea, 0x000019f1, 0xffffe60f, 0xfffff11a,
- 0x00000ee6, 0x00002500, 0xffffdb00, 0x00000025, 0xffffffdb, 0x00002c1b, 0xffffd3e5, 0x00001b2c,
- 0xffffe4d4, 0x00002c24, 0xffffd3dc, 0x0000242c, 0xffffdbd4, 0x00002c12, 0xffffd3ee, 0x0000122c,
- 0xffffedd4, 0x000020f6, 0xffffdf0a, 0xfffff621, 0x000009df, 0x00002d2d, 0xffffd2d3, 0x00000000,
- 0x00000000, 0x00000202, 0xfffffdfe, 0x00000300, 0xfffffd00, 0x00000003, 0xfffffffd, 0x00000606,
- 0xfffff9fa, 0x00000700, 0xfffff900, 0x02020000, 0x02020202, 0x0201fdfe, 0x02020300, 0x0201fd00,
- 0x02020003, 0x0201fffd, 0x02020606, 0x0201f9fa, 0x02020700, 0x0201f900, 0xfdfe0000, 0xfdfe0202,
- 0xfdfdfdfe, 0xfdfe0300, 0xfdfdfd00, 0xfdfe0003, 0xfdfdfffd, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0700,
- 0xfdfdf900, 0x03000000, 0x03000202, 0x02fffdfe, 0x03000300, 0x02fffd00, 0x03000003, 0x02fffffd,
- 0x03000606, 0x02fff9fa, 0x03000700, 0x02fff900, 0xfd000000, 0xfd000202, 0xfcfffdfe, 0xfd000300,
- 0xfcfffd00, 0xfd000003, 0xfcfffffd, 0xfd000606, 0xfcfff9fa, 0xfd000700, 0xfcfff900, 0x00030000,
- 0x00030202, 0x0002fdfe, 0x00030300, 0x0002fd00, 0x00030003, 0x0002fffd, 0x00030606, 0x0002f9fa,
- 0x00030700, 0x0002f900, 0xfffd0000, 0xfffd0202, 0xfffcfdfe, 0xfffd0300, 0xfffcfd00, 0xfffd0003,
- 0xfffcfffd, 0xfffd0606, 0xfffcf9fa, 0xfffd0700, 0xfffcf900, 0x06060000, 0x06060202, 0x0605fdfe,
- 0x06060300, 0x0605fd00, 0x06060003, 0x0605fffd, 0x06060606, 0x0605f9fa, 0x06060700, 0x0605f900,
- 0xf9fa0000, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0300, 0xf9f9fd00, 0xf9fa0003, 0xf9f9fffd, 0xf9fa0606,
- 0xf9f9f9fa, 0xf9fa0700, 0xf9f9f900, 0x07000000, 0x07000202, 0x06fffdfe, 0x07000300, 0x06fffd00,
- 0x07000003, 0x06fffffd, 0x07000606, 0x06fff9fa, 0x07000700, 0x06fff900, 0xf9000000, 0xf9000202,
- 0xf8fffdfe, 0xf9000300, 0xf8fffd00, 0xf9000003, 0xf8fffffd, 0xf9000606, 0xf8fff9fa, 0xf9000700,
- 0xf8fff900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000200, 0xfffffe00, 0x00000002, 0xfffffffe, 0x00000202, 0xfffffdfe, 0x00000606,
- 0xfffff9fa, 0x00000600, 0xfffffa00, 0x00000006, 0xfffffffa, 0x000003fc, 0xfffffc04, 0xfffffa0a,
- 0x000005f6, 0xfffff400, 0x00000c00, 0xfffff3fa, 0xfffff406, 0x00000bfa, 0x00000c06, 0xfffffff2,
- 0x0000000e, 0x00000c0c, 0xfffff3f4, 0xffffee00, 0x00001200, 0xfffff40e, 0x00000bf2, 0xfffff9ee,
- 0xfffffa12, 0x000005ee, 0x00000612, 0xffffedf6, 0xffffee0a, 0x000011f6, 0x0000120a, 0xffffffea,
- 0x00000016, 0xffffe800, 0x00001800, 0xfffff3ea, 0xfffff416, 0x00000bea, 0x00000c16, 0xffffe7f8,
- 0xffffe808, 0x000017f8, 0x00001808, 0xfffff9e6, 0xfffffa1a, 0x000005e6, 0x0000061a, 0xffffffe4,
- 0x0000001c, 0x00001414, 0xffffebec, 0xffffe5f2, 0x00001a0e, 0xfffff3e2, 0x00000c1e, 0xffffdff6,
- 0x0000200a, 0xffffdfee, 0x00002012, 0xffffe5e6, 0x00001a1a, 0xffffebde, 0x00001422, 0xfffff3da,
- 0x00000c26, 0xffffdfe0, 0x00002020, 0x00002020, 0xffffd7ea, 0xffffddde, 0x00002222, 0x00000000,
- 0x00000200, 0xfffffe00, 0x00000002, 0xfffffffe, 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa,
- 0x00000600, 0xfffffa00, 0x00000006, 0xfffffffa, 0x02000000, 0x02000200, 0x01fffe00, 0x02000002,
- 0x01fffffe, 0x02000202, 0x01fffdfe, 0x02000606, 0x01fff9fa, 0x02000600, 0x01fffa00, 0x02000006,
- 0x01fffffa, 0xfe000000, 0xfe000200, 0xfdfffe00, 0xfe000002, 0xfdfffffe, 0xfe000202, 0xfdfffdfe,
- 0xfe000606, 0xfdfff9fa, 0xfe000600, 0xfdfffa00, 0xfe000006, 0xfdfffffa, 0x00020000, 0x00020200,
- 0x0001fe00, 0x00020002, 0x0001fffe, 0x00020202, 0x0001fdfe, 0x00020606, 0x0001f9fa, 0x00020600,
- 0x0001fa00, 0x00020006, 0x0001fffa, 0xfffe0000, 0xfffe0200, 0xfffdfe00, 0xfffe0002, 0xfffdfffe,
- 0xfffe0202, 0xfffdfdfe, 0xfffe0606, 0xfffdf9fa, 0xfffe0600, 0xfffdfa00, 0xfffe0006, 0xfffdfffa,
- 0x02020000, 0x02020200, 0x0201fe00, 0x02020002, 0x0201fffe, 0x02020202, 0x0201fdfe, 0x02020606,
- 0x0201f9fa, 0x02020600, 0x0201fa00, 0x02020006, 0x0201fffa, 0xfdfe0000, 0xfdfe0200, 0xfdfdfe00,
- 0xfdfe0002, 0xfdfdfffe, 0xfdfe0202, 0xfdfdfdfe, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0600, 0xfdfdfa00,
- 0xfdfe0006, 0xfdfdfffa, 0x06060000, 0x06060200, 0x0605fe00, 0x06060002, 0x0605fffe, 0x06060202,
- 0x0605fdfe, 0x06060606, 0x0605f9fa, 0x06060600, 0x0605fa00, 0x06060006, 0x0605fffa, 0xf9fa0000,
- 0xf9fa0200, 0xf9f9fe00, 0xf9fa0002, 0xf9f9fffe, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0606, 0xf9f9f9fa,
- 0xf9fa0600, 0xf9f9fa00, 0xf9fa0006, 0xf9f9fffa, 0x06000000, 0x06000200, 0x05fffe00, 0x06000002,
- 0x05fffffe, 0x06000202, 0x05fffdfe, 0x06000606, 0x05fff9fa, 0x06000600, 0x05fffa00, 0x06000006,
- 0x05fffffa, 0xfa000000, 0xfa000200, 0xf9fffe00, 0xfa000002, 0xf9fffffe, 0xfa000202, 0xf9fffdfe,
- 0xfa000606, 0xf9fff9fa, 0xfa000600, 0xf9fffa00, 0xfa000006, 0xf9fffffa, 0x00060000, 0x00060200,
- 0x0005fe00, 0x00060002, 0x0005fffe, 0x00060202, 0x0005fdfe, 0x00060606, 0x0005f9fa, 0x00060600,
- 0x0005fa00, 0x00060006, 0x0005fffa, 0xfffa0000, 0xfffa0200, 0xfff9fe00, 0xfffa0002, 0xfff9fffe,
- 0xfffa0202, 0xfff9fdfe, 0xfffa0606, 0xfff9f9fa, 0xfffa0600, 0xfff9fa00, 0xfffa0006, 0xfff9fffa,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000200, 0xfffffe00, 0x00000002, 0xfffffffe, 0x00000404, 0xfffffbfc, 0x00000a0a,
- 0xfffff5f6, 0x00000a00, 0xfffff600, 0x0000000a, 0xfffffff6, 0x000005fa, 0xfffffa06, 0xfffff80e,
- 0x000007f2, 0xffffffee, 0x00000012, 0xfffff00a, 0x00000ff6, 0xffffe800, 0x00001800, 0xfffff7e8,
- 0xfffff818, 0x000007e8, 0x00000818, 0x00001212, 0xffffedee, 0xfffff014, 0x00000fec, 0xffffe5f2,
- 0xffffe60e, 0x000019f2, 0x00001a0e, 0xffffffe2, 0x0000001e, 0xffffde00, 0x00002200, 0xfffff7de,
- 0xfffff822, 0x000007de, 0x00000822, 0xffffede2, 0xffffee1e, 0x000011e2, 0x0000121e, 0xffffddf6,
- 0xffffde0a, 0x000021f6, 0x0000220a, 0xffffddec, 0x00002214, 0xffffffd8, 0x00000028, 0x00001e1e,
- 0xffffe1e2, 0xffffedd8, 0x00001228, 0xffffd400, 0x00002c00, 0xffffd3f0, 0x00002c10, 0xffffdbdc,
- 0xffffdbdc, 0x00002424, 0xffffd3e6, 0x00002c1a, 0xffffe5d2, 0x00001a2e, 0xffffedcc, 0x00001234,
- 0xffffc9ec, 0xffffd3d4, 0x00002c2c, 0xffffc9e0, 0xffffd1d2, 0xffffd1d2, 0x00002e2e, 0x00000000,
- 0x00000200, 0xfffffe00, 0x00000002, 0xfffffffe, 0x00000404, 0xfffffbfc, 0x00000a0a, 0xfffff5f6,
- 0x00000a00, 0xfffff600, 0x0000000a, 0xfffffff6, 0x02000000, 0x02000200, 0x01fffe00, 0x02000002,
- 0x01fffffe, 0x02000404, 0x01fffbfc, 0x02000a0a, 0x01fff5f6, 0x02000a00, 0x01fff600, 0x0200000a,
- 0x01fffff6, 0xfe000000, 0xfe000200, 0xfdfffe00, 0xfe000002, 0xfdfffffe, 0xfe000404, 0xfdfffbfc,
- 0xfe000a0a, 0xfdfff5f6, 0xfe000a00, 0xfdfff600, 0xfe00000a, 0xfdfffff6, 0x00020000, 0x00020200,
- 0x0001fe00, 0x00020002, 0x0001fffe, 0x00020404, 0x0001fbfc, 0x00020a0a, 0x0001f5f6, 0x00020a00,
- 0x0001f600, 0x0002000a, 0x0001fff6, 0xfffe0000, 0xfffe0200, 0xfffdfe00, 0xfffe0002, 0xfffdfffe,
- 0xfffe0404, 0xfffdfbfc, 0xfffe0a0a, 0xfffdf5f6, 0xfffe0a00, 0xfffdf600, 0xfffe000a, 0xfffdfff6,
- 0x04040000, 0x04040200, 0x0403fe00, 0x04040002, 0x0403fffe, 0x04040404, 0x0403fbfc, 0x04040a0a,
- 0x0403f5f6, 0x04040a00, 0x0403f600, 0x0404000a, 0x0403fff6, 0xfbfc0000, 0xfbfc0200, 0xfbfbfe00,
- 0xfbfc0002, 0xfbfbfffe, 0xfbfc0404, 0xfbfbfbfc, 0xfbfc0a0a, 0xfbfbf5f6, 0xfbfc0a00, 0xfbfbf600,
- 0xfbfc000a, 0xfbfbfff6, 0x0a0a0000, 0x0a0a0200, 0x0a09fe00, 0x0a0a0002, 0x0a09fffe, 0x0a0a0404,
- 0x0a09fbfc, 0x0a0a0a0a, 0x0a09f5f6, 0x0a0a0a00, 0x0a09f600, 0x0a0a000a, 0x0a09fff6, 0xf5f60000,
- 0xf5f60200, 0xf5f5fe00, 0xf5f60002, 0xf5f5fffe, 0xf5f60404, 0xf5f5fbfc, 0xf5f60a0a, 0xf5f5f5f6,
- 0xf5f60a00, 0xf5f5f600, 0xf5f6000a, 0xf5f5fff6, 0x0a000000, 0x0a000200, 0x09fffe00, 0x0a000002,
- 0x09fffffe, 0x0a000404, 0x09fffbfc, 0x0a000a0a, 0x09fff5f6, 0x0a000a00, 0x09fff600, 0x0a00000a,
- 0x09fffff6, 0xf6000000, 0xf6000200, 0xf5fffe00, 0xf6000002, 0xf5fffffe, 0xf6000404, 0xf5fffbfc,
- 0xf6000a0a, 0xf5fff5f6, 0xf6000a00, 0xf5fff600, 0xf600000a, 0xf5fffff6, 0x000a0000, 0x000a0200,
- 0x0009fe00, 0x000a0002, 0x0009fffe, 0x000a0404, 0x0009fbfc, 0x000a0a0a, 0x0009f5f6, 0x000a0a00,
- 0x0009f600, 0x000a000a, 0x0009fff6, 0xfff60000, 0xfff60200, 0xfff5fe00, 0xfff60002, 0xfff5fffe,
- 0xfff60404, 0xfff5fbfc, 0xfff60a0a, 0xfff5f5f6, 0xfff60a00, 0xfff5f600, 0xfff6000a, 0xfff5fff6,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000400, 0xfffffc00, 0x00000004, 0xfffffffc, 0x00000404, 0xfffffbfc, 0x00000c0c,
- 0xfffff3f4, 0x00000c00, 0xfffff400, 0x0000000c, 0xfffffff4, 0x000007f8, 0xfffff808, 0xfffff008,
- 0x00000ff8, 0xffffe800, 0x00001800, 0xfffff7e8, 0xfffff818, 0x000007e8, 0x00000818, 0xfffff014,
- 0x00000fec, 0xffffffe4, 0x0000001c, 0xffffe7f0, 0xffffe810, 0x000017f0, 0x00001810, 0xffffe000,
- 0x00002000, 0xffffefe4, 0xfffff01c, 0x00000fe4, 0x0000101c, 0xffffdff8, 0xffffe008, 0xfffff7e0,
- 0xfffff820, 0x000007e0, 0x00000820, 0x00001ff8, 0x00002008, 0x00001818, 0xffffe7e8, 0xffffe818,
- 0x000017e8, 0xffffdfec, 0x00002014, 0xffffffd8, 0x00000028, 0xffffefd8, 0x00001028, 0xffffd400,
- 0xffffd400, 0xffffffd4, 0x0000002c, 0x00002c00, 0x00002c00, 0xffffdfe0, 0x00002020, 0xffffd3f0,
- 0x00002c10, 0xffffd3e8, 0xffffe7d4, 0x0000182c, 0x00002c18, 0xffffefd0, 0x00001030, 0xffffdbdc,
- 0xffffdbdc, 0x00002424, 0x00002424, 0xffffcbec, 0x00002828, 0xffffd7d8, 0xffffcbe0, 0x00000000,
- 0x00000400, 0xfffffc00, 0x00000004, 0xfffffffc, 0x00000404, 0xfffffbfc, 0x00000c0c, 0xfffff3f4,
- 0x00000c00, 0xfffff400, 0x0000000c, 0xfffffff4, 0x04000000, 0x04000400, 0x03fffc00, 0x04000004,
- 0x03fffffc, 0x04000404, 0x03fffbfc, 0x04000c0c, 0x03fff3f4, 0x04000c00, 0x03fff400, 0x0400000c,
- 0x03fffff4, 0xfc000000, 0xfc000400, 0xfbfffc00, 0xfc000004, 0xfbfffffc, 0xfc000404, 0xfbfffbfc,
- 0xfc000c0c, 0xfbfff3f4, 0xfc000c00, 0xfbfff400, 0xfc00000c, 0xfbfffff4, 0x00040000, 0x00040400,
- 0x0003fc00, 0x00040004, 0x0003fffc, 0x00040404, 0x0003fbfc, 0x00040c0c, 0x0003f3f4, 0x00040c00,
- 0x0003f400, 0x0004000c, 0x0003fff4, 0xfffc0000, 0xfffc0400, 0xfffbfc00, 0xfffc0004, 0xfffbfffc,
- 0xfffc0404, 0xfffbfbfc, 0xfffc0c0c, 0xfffbf3f4, 0xfffc0c00, 0xfffbf400, 0xfffc000c, 0xfffbfff4,
- 0x04040000, 0x04040400, 0x0403fc00, 0x04040004, 0x0403fffc, 0x04040404, 0x0403fbfc, 0x04040c0c,
- 0x0403f3f4, 0x04040c00, 0x0403f400, 0x0404000c, 0x0403fff4, 0xfbfc0000, 0xfbfc0400, 0xfbfbfc00,
- 0xfbfc0004, 0xfbfbfffc, 0xfbfc0404, 0xfbfbfbfc, 0xfbfc0c0c, 0xfbfbf3f4, 0xfbfc0c00, 0xfbfbf400,
- 0xfbfc000c, 0xfbfbfff4, 0x0c0c0000, 0x0c0c0400, 0x0c0bfc00, 0x0c0c0004, 0x0c0bfffc, 0x0c0c0404,
- 0x0c0bfbfc, 0x0c0c0c0c, 0x0c0bf3f4, 0x0c0c0c00, 0x0c0bf400, 0x0c0c000c, 0x0c0bfff4, 0xf3f40000,
- 0xf3f40400, 0xf3f3fc00, 0xf3f40004, 0xf3f3fffc, 0xf3f40404, 0xf3f3fbfc, 0xf3f40c0c, 0xf3f3f3f4,
- 0xf3f40c00, 0xf3f3f400, 0xf3f4000c, 0xf3f3fff4, 0x0c000000, 0x0c000400, 0x0bfffc00, 0x0c000004,
- 0x0bfffffc, 0x0c000404, 0x0bfffbfc, 0x0c000c0c, 0x0bfff3f4, 0x0c000c00, 0x0bfff400, 0x0c00000c,
- 0x0bfffff4, 0xf4000000, 0xf4000400, 0xf3fffc00, 0xf4000004, 0xf3fffffc, 0xf4000404, 0xf3fffbfc,
- 0xf4000c0c, 0xf3fff3f4, 0xf4000c00, 0xf3fff400, 0xf400000c, 0xf3fffff4, 0x000c0000, 0x000c0400,
- 0x000bfc00, 0x000c0004, 0x000bfffc, 0x000c0404, 0x000bfbfc, 0x000c0c0c, 0x000bf3f4, 0x000c0c00,
- 0x000bf400, 0x000c000c, 0x000bfff4, 0xfff40000, 0xfff40400, 0xfff3fc00, 0xfff40004, 0xfff3fffc,
- 0xfff40404, 0xfff3fbfc, 0xfff40c0c, 0xfff3f3f4, 0xfff40c00, 0xfff3f400, 0xfff4000c, 0xfff3fff4,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414,
- 0xffffebec, 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, 0xffffebec,
- 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x02020000, 0x02020202, 0x0201fdfe, 0x02020606,
- 0x0201f9fa, 0x02020c0c, 0x0201f3f4, 0x02021414, 0x0201ebec, 0x02022020, 0x0201dfe0, 0x02022e2e,
- 0x0201d1d2, 0xfdfe0000, 0xfdfe0202, 0xfdfdfdfe, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0c0c, 0xfdfdf3f4,
- 0xfdfe1414, 0xfdfdebec, 0xfdfe2020, 0xfdfddfe0, 0xfdfe2e2e, 0xfdfdd1d2, 0x06060000, 0x06060202,
- 0x0605fdfe, 0x06060606, 0x0605f9fa, 0x06060c0c, 0x0605f3f4, 0x06061414, 0x0605ebec, 0x06062020,
- 0x0605dfe0, 0x06062e2e, 0x0605d1d2, 0xf9fa0000, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0606, 0xf9f9f9fa,
- 0xf9fa0c0c, 0xf9f9f3f4, 0xf9fa1414, 0xf9f9ebec, 0xf9fa2020, 0xf9f9dfe0, 0xf9fa2e2e, 0xf9f9d1d2,
- 0x0c0c0000, 0x0c0c0202, 0x0c0bfdfe, 0x0c0c0606, 0x0c0bf9fa, 0x0c0c0c0c, 0x0c0bf3f4, 0x0c0c1414,
- 0x0c0bebec, 0x0c0c2020, 0x0c0bdfe0, 0x0c0c2e2e, 0x0c0bd1d2, 0xf3f40000, 0xf3f40202, 0xf3f3fdfe,
- 0xf3f40606, 0xf3f3f9fa, 0xf3f40c0c, 0xf3f3f3f4, 0xf3f41414, 0xf3f3ebec, 0xf3f42020, 0xf3f3dfe0,
- 0xf3f42e2e, 0xf3f3d1d2, 0x14140000, 0x14140202, 0x1413fdfe, 0x14140606, 0x1413f9fa, 0x14140c0c,
- 0x1413f3f4, 0x14141414, 0x1413ebec, 0x14142020, 0x1413dfe0, 0x14142e2e, 0x1413d1d2, 0xebec0000,
- 0xebec0202, 0xebebfdfe, 0xebec0606, 0xebebf9fa, 0xebec0c0c, 0xebebf3f4, 0xebec1414, 0xebebebec,
- 0xebec2020, 0xebebdfe0, 0xebec2e2e, 0xebebd1d2, 0x20200000, 0x20200202, 0x201ffdfe, 0x20200606,
- 0x201ff9fa, 0x20200c0c, 0x201ff3f4, 0x20201414, 0x201febec, 0x20202020, 0x201fdfe0, 0x20202e2e,
- 0x201fd1d2, 0xdfe00000, 0xdfe00202, 0xdfdffdfe, 0xdfe00606, 0xdfdff9fa, 0xdfe00c0c, 0xdfdff3f4,
- 0xdfe01414, 0xdfdfebec, 0xdfe02020, 0xdfdfdfe0, 0xdfe02e2e, 0xdfdfd1d2, 0x2e2e0000, 0x2e2e0202,
- 0x2e2dfdfe, 0x2e2e0606, 0x2e2df9fa, 0x2e2e0c0c, 0x2e2df3f4, 0x2e2e1414, 0x2e2debec, 0x2e2e2020,
- 0x2e2ddfe0, 0x2e2e2e2e, 0x2e2dd1d2, 0xd1d20000, 0xd1d20202, 0xd1d1fdfe, 0xd1d20606, 0xd1d1f9fa,
- 0xd1d20c0c, 0xd1d1f3f4, 0xd1d21414, 0xd1d1ebec, 0xd1d22020, 0xd1d1dfe0, 0xd1d22e2e, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414,
- 0xffffebec, 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, 0xffffebec,
- 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x02020000, 0x02020202, 0x0201fdfe, 0x02020606,
- 0x0201f9fa, 0x02020c0c, 0x0201f3f4, 0x02021414, 0x0201ebec, 0x02022020, 0x0201dfe0, 0x02022e2e,
- 0x0201d1d2, 0xfdfe0000, 0xfdfe0202, 0xfdfdfdfe, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0c0c, 0xfdfdf3f4,
- 0xfdfe1414, 0xfdfdebec, 0xfdfe2020, 0xfdfddfe0, 0xfdfe2e2e, 0xfdfdd1d2, 0x06060000, 0x06060202,
- 0x0605fdfe, 0x06060606, 0x0605f9fa, 0x06060c0c, 0x0605f3f4, 0x06061414, 0x0605ebec, 0x06062020,
- 0x0605dfe0, 0x06062e2e, 0x0605d1d2, 0xf9fa0000, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0606, 0xf9f9f9fa,
- 0xf9fa0c0c, 0xf9f9f3f4, 0xf9fa1414, 0xf9f9ebec, 0xf9fa2020, 0xf9f9dfe0, 0xf9fa2e2e, 0xf9f9d1d2,
- 0x0c0c0000, 0x0c0c0202, 0x0c0bfdfe, 0x0c0c0606, 0x0c0bf9fa, 0x0c0c0c0c, 0x0c0bf3f4, 0x0c0c1414,
- 0x0c0bebec, 0x0c0c2020, 0x0c0bdfe0, 0x0c0c2e2e, 0x0c0bd1d2, 0xf3f40000, 0xf3f40202, 0xf3f3fdfe,
- 0xf3f40606, 0xf3f3f9fa, 0xf3f40c0c, 0xf3f3f3f4, 0xf3f41414, 0xf3f3ebec, 0xf3f42020, 0xf3f3dfe0,
- 0xf3f42e2e, 0xf3f3d1d2, 0x14140000, 0x14140202, 0x1413fdfe, 0x14140606, 0x1413f9fa, 0x14140c0c,
- 0x1413f3f4, 0x14141414, 0x1413ebec, 0x14142020, 0x1413dfe0, 0x14142e2e, 0x1413d1d2, 0xebec0000,
- 0xebec0202, 0xebebfdfe, 0xebec0606, 0xebebf9fa, 0xebec0c0c, 0xebebf3f4, 0xebec1414, 0xebebebec,
- 0xebec2020, 0xebebdfe0, 0xebec2e2e, 0xebebd1d2, 0x20200000, 0x20200202, 0x201ffdfe, 0x20200606,
- 0x201ff9fa, 0x20200c0c, 0x201ff3f4, 0x20201414, 0x201febec, 0x20202020, 0x201fdfe0, 0x20202e2e,
- 0x201fd1d2, 0xdfe00000, 0xdfe00202, 0xdfdffdfe, 0xdfe00606, 0xdfdff9fa, 0xdfe00c0c, 0xdfdff3f4,
- 0xdfe01414, 0xdfdfebec, 0xdfe02020, 0xdfdfdfe0, 0xdfe02e2e, 0xdfdfd1d2, 0x2e2e0000, 0x2e2e0202,
- 0x2e2dfdfe, 0x2e2e0606, 0x2e2df9fa, 0x2e2e0c0c, 0x2e2df3f4, 0x2e2e1414, 0x2e2debec, 0x2e2e2020,
- 0x2e2ddfe0, 0x2e2e2e2e, 0x2e2dd1d2, 0xd1d20000, 0xd1d20202, 0xd1d1fdfe, 0xd1d20606, 0xd1d1f9fa,
- 0xd1d20c0c, 0xd1d1f3f4, 0xd1d21414, 0xd1d1ebec, 0xd1d22020, 0xd1d1dfe0, 0xd1d22e2e, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414,
- 0xffffebec, 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, 0xffffebec,
- 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x02020000, 0x02020202, 0x0201fdfe, 0x02020606,
- 0x0201f9fa, 0x02020c0c, 0x0201f3f4, 0x02021414, 0x0201ebec, 0x02022020, 0x0201dfe0, 0x02022e2e,
- 0x0201d1d2, 0xfdfe0000, 0xfdfe0202, 0xfdfdfdfe, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0c0c, 0xfdfdf3f4,
- 0xfdfe1414, 0xfdfdebec, 0xfdfe2020, 0xfdfddfe0, 0xfdfe2e2e, 0xfdfdd1d2, 0x06060000, 0x06060202,
- 0x0605fdfe, 0x06060606, 0x0605f9fa, 0x06060c0c, 0x0605f3f4, 0x06061414, 0x0605ebec, 0x06062020,
- 0x0605dfe0, 0x06062e2e, 0x0605d1d2, 0xf9fa0000, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0606, 0xf9f9f9fa,
- 0xf9fa0c0c, 0xf9f9f3f4, 0xf9fa1414, 0xf9f9ebec, 0xf9fa2020, 0xf9f9dfe0, 0xf9fa2e2e, 0xf9f9d1d2,
- 0x0c0c0000, 0x0c0c0202, 0x0c0bfdfe, 0x0c0c0606, 0x0c0bf9fa, 0x0c0c0c0c, 0x0c0bf3f4, 0x0c0c1414,
- 0x0c0bebec, 0x0c0c2020, 0x0c0bdfe0, 0x0c0c2e2e, 0x0c0bd1d2, 0xf3f40000, 0xf3f40202, 0xf3f3fdfe,
- 0xf3f40606, 0xf3f3f9fa, 0xf3f40c0c, 0xf3f3f3f4, 0xf3f41414, 0xf3f3ebec, 0xf3f42020, 0xf3f3dfe0,
- 0xf3f42e2e, 0xf3f3d1d2, 0x14140000, 0x14140202, 0x1413fdfe, 0x14140606, 0x1413f9fa, 0x14140c0c,
- 0x1413f3f4, 0x14141414, 0x1413ebec, 0x14142020, 0x1413dfe0, 0x14142e2e, 0x1413d1d2, 0xebec0000,
- 0xebec0202, 0xebebfdfe, 0xebec0606, 0xebebf9fa, 0xebec0c0c, 0xebebf3f4, 0xebec1414, 0xebebebec,
- 0xebec2020, 0xebebdfe0, 0xebec2e2e, 0xebebd1d2, 0x20200000, 0x20200202, 0x201ffdfe, 0x20200606,
- 0x201ff9fa, 0x20200c0c, 0x201ff3f4, 0x20201414, 0x201febec, 0x20202020, 0x201fdfe0, 0x20202e2e,
- 0x201fd1d2, 0xdfe00000, 0xdfe00202, 0xdfdffdfe, 0xdfe00606, 0xdfdff9fa, 0xdfe00c0c, 0xdfdff3f4,
- 0xdfe01414, 0xdfdfebec, 0xdfe02020, 0xdfdfdfe0, 0xdfe02e2e, 0xdfdfd1d2, 0x2e2e0000, 0x2e2e0202,
- 0x2e2dfdfe, 0x2e2e0606, 0x2e2df9fa, 0x2e2e0c0c, 0x2e2df3f4, 0x2e2e1414, 0x2e2debec, 0x2e2e2020,
- 0x2e2ddfe0, 0x2e2e2e2e, 0x2e2dd1d2, 0xd1d20000, 0xd1d20202, 0xd1d1fdfe, 0xd1d20606, 0xd1d1f9fa,
- 0xd1d20c0c, 0xd1d1f3f4, 0xd1d21414, 0xd1d1ebec, 0xd1d22020, 0xd1d1dfe0, 0xd1d22e2e, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414,
- 0xffffebec, 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, 0xffffebec,
- 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x02020000, 0x02020202, 0x0201fdfe, 0x02020606,
- 0x0201f9fa, 0x02020c0c, 0x0201f3f4, 0x02021414, 0x0201ebec, 0x02022020, 0x0201dfe0, 0x02022e2e,
- 0x0201d1d2, 0xfdfe0000, 0xfdfe0202, 0xfdfdfdfe, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0c0c, 0xfdfdf3f4,
- 0xfdfe1414, 0xfdfdebec, 0xfdfe2020, 0xfdfddfe0, 0xfdfe2e2e, 0xfdfdd1d2, 0x06060000, 0x06060202,
- 0x0605fdfe, 0x06060606, 0x0605f9fa, 0x06060c0c, 0x0605f3f4, 0x06061414, 0x0605ebec, 0x06062020,
- 0x0605dfe0, 0x06062e2e, 0x0605d1d2, 0xf9fa0000, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0606, 0xf9f9f9fa,
- 0xf9fa0c0c, 0xf9f9f3f4, 0xf9fa1414, 0xf9f9ebec, 0xf9fa2020, 0xf9f9dfe0, 0xf9fa2e2e, 0xf9f9d1d2,
- 0x0c0c0000, 0x0c0c0202, 0x0c0bfdfe, 0x0c0c0606, 0x0c0bf9fa, 0x0c0c0c0c, 0x0c0bf3f4, 0x0c0c1414,
- 0x0c0bebec, 0x0c0c2020, 0x0c0bdfe0, 0x0c0c2e2e, 0x0c0bd1d2, 0xf3f40000, 0xf3f40202, 0xf3f3fdfe,
- 0xf3f40606, 0xf3f3f9fa, 0xf3f40c0c, 0xf3f3f3f4, 0xf3f41414, 0xf3f3ebec, 0xf3f42020, 0xf3f3dfe0,
- 0xf3f42e2e, 0xf3f3d1d2, 0x14140000, 0x14140202, 0x1413fdfe, 0x14140606, 0x1413f9fa, 0x14140c0c,
- 0x1413f3f4, 0x14141414, 0x1413ebec, 0x14142020, 0x1413dfe0, 0x14142e2e, 0x1413d1d2, 0xebec0000,
- 0xebec0202, 0xebebfdfe, 0xebec0606, 0xebebf9fa, 0xebec0c0c, 0xebebf3f4, 0xebec1414, 0xebebebec,
- 0xebec2020, 0xebebdfe0, 0xebec2e2e, 0xebebd1d2, 0x20200000, 0x20200202, 0x201ffdfe, 0x20200606,
- 0x201ff9fa, 0x20200c0c, 0x201ff3f4, 0x20201414, 0x201febec, 0x20202020, 0x201fdfe0, 0x20202e2e,
- 0x201fd1d2, 0xdfe00000, 0xdfe00202, 0xdfdffdfe, 0xdfe00606, 0xdfdff9fa, 0xdfe00c0c, 0xdfdff3f4,
- 0xdfe01414, 0xdfdfebec, 0xdfe02020, 0xdfdfdfe0, 0xdfe02e2e, 0xdfdfd1d2, 0x2e2e0000, 0x2e2e0202,
- 0x2e2dfdfe, 0x2e2e0606, 0x2e2df9fa, 0x2e2e0c0c, 0x2e2df3f4, 0x2e2e1414, 0x2e2debec, 0x2e2e2020,
- 0x2e2ddfe0, 0x2e2e2e2e, 0x2e2dd1d2, 0xd1d20000, 0xd1d20202, 0xd1d1fdfe, 0xd1d20606, 0xd1d1f9fa,
- 0xd1d20c0c, 0xd1d1f3f4, 0xd1d21414, 0xd1d1ebec, 0xd1d22020, 0xd1d1dfe0, 0xd1d22e2e, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
-};
+#include "config.h"
+
+/*
+ * Define compressed VQ tables.
+ */
+#define TAB_1_1 \
+ PD( 0, 0), E2( 2, 2), E4( -1, 3), E2( 4, 4), E4( 1, 5),\
+ E2( -4, 4), E4( -2, 6), E4( 4, 9), E2( 9, 9), E4( 1, 10),\
+ E4( -5, 8), E4( 9, 15), E4( -3, 12), E4( 4, 16), E2( 16, 16),\
+ E4( 0, 18), E2( -12, 12), E4( -9, 16), E4( 11, 27), E4( 19, 28),\
+ E4( -6, 22), E4( 4, 29), E2( 30, 30), E4( -2, 33), E4( -18, 23),\
+ E4( -15, 30), E4( 22, 46), E4( 13, 47), E4( 35, 49), E4( -11, 41),\
+ E4( 4, 51), E2( 54, 54), E2( -34, 34), E4( -29, 42), E4( -6, 60),\
+ E4( 27, 76), E4( 43, 77), E4( -24, 55), E4( 14, 79), E4( 63, 83),\
+ E4( -20, 74), E4( 2, 88), E2( 93, 93), E4( -52, 61), E4( 52, 120),\
+ E4( -45, 75), E4( 75, 125), E4( 33, 122), E4( -13, 103), E4( -40, 96),\
+ E4( -34, 127), E2( -89, 89), E4( -78, 105), E2( 12, 12), E2( 23, 23),\
+ E2( 42, 42), E2( 73, 73)
-static const uint32_t correctionloworder[] = {
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, 0x04040404,
- 0xfbfbfbfc, 0x05050101, 0xfafafeff, 0x01010505, 0xfefefafb, 0x0403fbfc, 0xfbfc0404, 0x0605fdfe,
- 0xf9fa0202, 0xfdfe0606, 0x0201f9fa, 0x09090404, 0xf6f6fbfc, 0x04040909, 0xfbfbf6f7, 0x09090909,
- 0xf6f6f6f7, 0x0a0a0101, 0xf5f5feff, 0x01010a0a, 0xfefef5f6, 0x0807fafb, 0xf7f80505, 0xfafb0808,
- 0x0504f7f8, 0x0f0f0909, 0xf0f0f6f7, 0x09090f0f, 0xf6f6f0f1, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c,
- 0x0302f3f4, 0x10100404, 0xefeffbfc, 0x04041010, 0xfbfbeff0, 0x10101010, 0xefefeff0, 0x12120000,
- 0xedee0000, 0x00001212, 0xffffedee, 0x0c0bf3f4, 0xf3f40c0c, 0x100ff6f7, 0xeff00909, 0xf6f71010,
- 0x0908eff0, 0x1b1b0b0b, 0xe4e4f4f5, 0x0b0b1b1b, 0xf4f4e4e5, 0x1c1c1313, 0xe3e3eced, 0x13131c1c,
- 0xecece3e4, 0x1615f9fa, 0xe9ea0606, 0xf9fa1616, 0x0605e9ea, 0x1d1d0404, 0xe2e2fbfc, 0x04041d1d,
- 0xfbfbe2e3, 0x1e1e1e1e, 0xe1e1e1e2, 0x2120fdfe, 0xdedf0202, 0xfdfe2121, 0x0201dedf, 0x1716edee,
- 0xe8e91212, 0xedee1717, 0x1211e8e9, 0x1e1df0f1, 0xe1e20f0f, 0xf0f11e1e, 0x0f0ee1e2, 0x2e2e1616,
- 0xd1d1e9ea, 0x16162e2e, 0xe9e9d1d2, 0x2f2f0d0d, 0xd0d0f2f3, 0x0d0d2f2f, 0xf2f2d0d1, 0x31312323,
- 0xcecedcdd, 0x23233131, 0xdcdccecf, 0x2928f4f5, 0xd6d70b0b, 0xf4f52929, 0x0b0ad6d7, 0x33330404,
- 0xccccfbfc, 0x04043333, 0xfbfbcccd, 0x36363636, 0xc9c9c9ca, 0x2221ddde, 0xddde2222, 0x2a29e2e3,
- 0xd5d61d1d, 0xe2e32a2a, 0x1d1cd5d6, 0x3c3bf9fa, 0xc3c40606, 0xf9fa3c3c, 0x0605c3c4, 0x4c4c1b1b,
- 0xb3b3e4e5, 0x1b1b4c4c, 0xe4e4b3b4, 0x4d4d2b2b, 0xb2b2d4d5, 0x2b2b4d4d, 0xd4d4b2b3, 0x3736e7e8,
- 0xc8c91818, 0xe7e83737, 0x1817c8c9, 0x4f4f0e0e, 0xb0b0f1f2, 0x0e0e4f4f, 0xf1f1b0b1, 0x53533f3f,
- 0xacacc0c1, 0x3f3f5353, 0xc0c0acad, 0x4a49ebec, 0xb5b61414, 0xebec4a4a, 0x1413b5b6, 0x58580202,
- 0xa7a7fdfe, 0x02025858, 0xfdfda7a8, 0x5d5d5d5d, 0xa2a2a2a3, 0x3d3ccbcc, 0xc2c33434, 0xcbcc3d3d,
- 0x3433c2c3, 0x78783434, 0x8787cbcc, 0x34347878, 0xcbcb8788, 0x4b4ad2d3, 0xb4b52d2d, 0xd2d34b4b,
- 0x2d2cb4b5, 0x7d7d4b4b, 0x8282b4b5, 0x4b4b7d7d, 0xb4b48283, 0x7a7a2121, 0x8585dedf, 0x21217a7a,
- 0xdede8586, 0x6766f2f3, 0x98990d0d, 0xf2f36767, 0x0d0c9899, 0x605fd7d8, 0x9fa02828, 0xd7d86060,
- 0x28279fa0, 0x7f7eddde, 0x80812222, 0xddde7f7f, 0x22218081, 0x5958a6a7, 0xa6a75959, 0x6968b1b2,
- 0x96974e4e, 0xb1b26969, 0x4e4d9697, 0x0c0c0c0c, 0xf3f3f3f4, 0x17171717, 0xe8e8e8e9, 0x2a2a2a2a,
- 0xd5d5d5d6, 0x49494949, 0xb6b6b6b7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe,
- 0x0302feff, 0x0302feff, 0x0302feff, 0x0302feff, 0x0302feff, 0x0302feff, 0x0302feff, 0xfcfd0101,
- 0xfcfd0101, 0xfcfd0101, 0xfcfd0101, 0xfcfd0101, 0xfcfd0101, 0xfcfd0101, 0xfeff0303, 0xfeff0303,
- 0xfeff0303, 0xfeff0303, 0xfeff0303, 0xfeff0303, 0xfeff0303, 0x0100fcfd, 0x0100fcfd, 0x0100fcfd,
- 0x0100fcfd, 0x0100fcfd, 0x0100fcfd, 0x0100fcfd, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707,
- 0xf8f8f8f9, 0x08080202, 0xf7f7fdfe, 0x02020808, 0xfdfdf7f8, 0x0908fdfe, 0xf6f70202, 0xfdfe0909,
- 0x0201f6f7, 0x0605f9fa, 0xf9fa0606, 0x0d0d0606, 0xf2f2f9fa, 0x06060d0d, 0xf9f9f2f3, 0x0d0d0d0d,
- 0xf2f2f2f3, 0x0e0e0101, 0xf1f1feff, 0x01010e0e, 0xfefef1f2, 0x0c0bf7f8, 0xf3f40808, 0xf7f80c0c,
- 0x0807f3f4, 0x17170e0e, 0xe8e8f1f2, 0x0e0e1717, 0xf1f1e8e9, 0x1211fafb, 0xedee0505, 0xfafb1212,
- 0x0504edee, 0x18180606, 0xe7e7f9fa, 0x06061818, 0xf9f9e7e8, 0x18181818, 0xe7e7e7e8, 0x1b1afeff,
- 0xe4e50101, 0xfeff1b1b, 0x0100e4e5, 0x1110eeef, 0xeeef1111, 0x1716f2f3, 0xe8e90d0d, 0xf2f31717,
- 0x0d0ce8e9, 0x28281010, 0xd7d7eff0, 0x10102828, 0xefefd7d8, 0x29291c1c, 0xd6d6e3e4, 0x1c1c2929,
- 0xe3e3d6d7, 0x2120f6f7, 0xdedf0909, 0xf6f72121, 0x0908dedf, 0x2b2b0606, 0xd4d4f9fa, 0x06062b2b,
- 0xf9f9d4d5, 0x2e2e2e2e, 0xd1d1d1d2, 0x3231fbfc, 0xcdce0404, 0xfbfc3232, 0x0403cdce, 0x2221e4e5,
- 0xddde1b1b, 0xe4e52222, 0x1b1addde, 0x2d2ce9ea, 0xd2d31616, 0xe9ea2d2d, 0x1615d2d3, 0x45452222,
- 0xbabaddde, 0x22224545, 0xddddbabb, 0x46461313, 0xb9b9eced, 0x13134646, 0xececb9ba, 0x49493535,
- 0xb6b6cacb, 0x35354949, 0xcacab6b7, 0x3e3deeef, 0xc1c21111, 0xeeef3e3e, 0x1110c1c2, 0x4d4d0505,
- 0xb2b2fafb, 0x05054d4d, 0xfafab2b3, 0x52525252, 0xadadadae, 0x3332cccd, 0xcccd3333, 0x403fd4d5,
- 0xbfc02b2b, 0xd4d54040, 0x2b2abfc0, 0x5a59f5f6, 0xa5a60a0a, 0xf5f65a5a, 0x0a09a5a6, 0x72722929,
- 0x8d8dd6d7, 0x29297272, 0xd6d68d8e, 0x74744040, 0x8b8bbfc0, 0x40407474, 0xbfbf8b8c, 0x5251dadb,
- 0xadae2525, 0xdadb5252, 0x2524adae, 0x77771616, 0x8888e9ea, 0x16167777, 0xe9e98889, 0x7c7c5f5f,
- 0x8383a0a1, 0x5f5f7c7c, 0xa0a08384, 0x6f6ee1e2, 0x90911e1e, 0xe1e26f6f, 0x1e1d9091, 0x5c5bb1b2,
- 0xa3a44e4e, 0xb1b25c5c, 0x4e4da3a4, 0x7170bbbc, 0x8e8f4444, 0xbbbc7171, 0x44438e8f, 0x12121212,
- 0xedededee, 0x22222222, 0xddddddde, 0x3f3f3f3f, 0xc0c0c0c1, 0x6d6d6d6d, 0x92929293, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303,
- 0x03030303, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd,
- 0xfcfcfcfd, 0xfcfcfcfd, 0x0403feff, 0x0403feff, 0x0403feff, 0x0403feff, 0x0403feff, 0x0403feff,
- 0x0403feff, 0x0403feff, 0x0403feff, 0xfbfc0101, 0xfbfc0101, 0xfbfc0101, 0xfbfc0101, 0xfbfc0101,
- 0xfbfc0101, 0xfbfc0101, 0xfbfc0101, 0xfbfc0101, 0xfeff0404, 0xfeff0404, 0xfeff0404, 0xfeff0404,
- 0xfeff0404, 0xfeff0404, 0xfeff0404, 0xfeff0404, 0xfeff0404, 0x0100fbfc, 0x0100fbfc, 0x0100fbfc,
- 0x0100fbfc, 0x0100fbfc, 0x0100fbfc, 0x0100fbfc, 0x0100fbfc, 0x0100fbfc, 0x07070707, 0x07070707,
- 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0xf8f8f8f9,
- 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303,
- 0xf5f5fcfd, 0x03030a0a, 0xfcfcf5f6, 0x09090909, 0xf6f6f6f7, 0x0706f8f9, 0xf8f90707, 0x0c0bfcfd,
- 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x11110808, 0xeeeef7f8, 0x08081111, 0xf7f7eeef, 0x11111111,
- 0xeeeeeeef, 0x13130101, 0xececfeff, 0x01011313, 0xfefeeced, 0x100ff4f5, 0xeff00b0b, 0xf4f51010,
- 0x0b0aeff0, 0x1716f9fa, 0xe8e90606, 0xf9fa1717, 0x0605e8e9, 0x1f1f1212, 0xe0e0edee, 0x12121f1f,
- 0xedede0e1, 0x20200808, 0xdfdff7f8, 0x08082020, 0xf7f7dfe0, 0x21212121, 0xdedededf, 0x2423feff,
- 0xdbdc0101, 0xfeff2424, 0x0100dbdc, 0x1716e8e9, 0xe8e91717, 0x1f1eeeef, 0xe0e11111, 0xeeef1f1f,
- 0x1110e0e1, 0x36361515, 0xc9c9eaeb, 0x15153636, 0xeaeac9ca, 0x37372525, 0xc8c8dadb, 0x25253737,
- 0xdadac8c9, 0x2c2bf3f4, 0xd3d40c0c, 0xf3f42c2c, 0x0c0bd3d4, 0x39390808, 0xc6c6f7f8, 0x08083939,
- 0xf7f7c6c7, 0x3d3d3d3d, 0xc2c2c2c3, 0x4241fafb, 0xbdbe0505, 0xfafb4242, 0x0504bdbe, 0x2d2cdbdc,
- 0xd2d32424, 0xdbdc2d2d, 0x2423d2d3, 0x3c3be2e3, 0xc3c41d1d, 0xe2e33c3c, 0x1d1cc3c4, 0x5c5c2d2d,
- 0xa3a3d2d3, 0x2d2d5c5c, 0xd2d2a3a4, 0x5d5d1919, 0xa2a2e6e7, 0x19195d5d, 0xe6e6a2a3, 0x61614747,
- 0x9e9eb8b9, 0x47476161, 0xb8b89e9f, 0x5352e9ea, 0xacad1616, 0xe9ea5353, 0x1615acad, 0x66660707,
- 0x9999f8f9, 0x07076666, 0xf8f8999a, 0x6d6d6d6d, 0x92929293, 0x4443bbbc, 0xbbbc4444, 0x5554c6c7,
- 0xaaab3939, 0xc6c75555, 0x3938aaab, 0x7877f2f3, 0x87880d0d, 0xf2f37878, 0x0d0c8788, 0x6e6dcecf,
- 0x91923131, 0xcecf6e6e, 0x31309192, 0x7b7a9798, 0x84856868, 0x97987b7b, 0x68678485, 0x18181818,
- 0xe7e7e7e8, 0x2e2e2e2e, 0xd1d1d1d2, 0x54545454, 0xabababac, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04040404,
- 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404,
- 0x04040404, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc,
- 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0x0504feff, 0x0504feff, 0x0504feff, 0x0504feff, 0x0504feff,
- 0x0504feff, 0x0504feff, 0x0504feff, 0x0504feff, 0x0504feff, 0xfafb0101, 0xfafb0101, 0xfafb0101,
- 0xfafb0101, 0xfafb0101, 0xfafb0101, 0xfafb0101, 0xfafb0101, 0xfafb0101, 0xfafb0101, 0xfeff0505,
- 0xfeff0505, 0xfeff0505, 0xfeff0505, 0xfeff0505, 0xfeff0505, 0xfeff0505, 0xfeff0505, 0xfeff0505,
- 0xfeff0505, 0x0100fafb, 0x0100fafb, 0x0100fafb, 0x0100fafb, 0x0100fafb, 0x0100fafb, 0x0100fafb,
- 0x0100fafb, 0x0100fafb, 0x0100fafb, 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, 0x0a0a0303,
- 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd,
- 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, 0x03030a0a,
- 0x03030a0a, 0x03030a0a, 0x03030a0a, 0x03030a0a, 0x03030a0a, 0x03030a0a, 0x03030a0a, 0x03030a0a,
- 0x03030a0a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b,
- 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x03030d0d, 0xfcfcf2f3, 0x0908f6f7, 0xf6f70909, 0x0f0efbfc,
- 0xf0f10404, 0xfbfc0f0f, 0x0403f0f1, 0x16160b0b, 0xe9e9f4f5, 0x0b0b1616, 0xf4f4e9ea, 0x15151515,
- 0xeaeaeaeb, 0x18180202, 0xe7e7fdfe, 0x02021818, 0xfdfde7e8, 0x1413f1f2, 0xebec0e0e, 0xf1f21414,
- 0x0e0debec, 0x26261717, 0xd9d9e8e9, 0x17172626, 0xe8e8d9da, 0x1d1cf7f8, 0xe2e30808, 0xf7f81d1d,
- 0x0807e2e3, 0x27270b0b, 0xd8d8f4f5, 0x0b0b2727, 0xf4f4d8d9, 0x29292929, 0xd6d6d6d7, 0x2d2cfeff,
- 0xd2d30101, 0xfeff2d2d, 0x0100d2d3, 0x1d1ce2e3, 0xe2e31d1d, 0x2726e9ea, 0xd8d91616, 0xe9ea2727,
- 0x1615d8d9, 0x43431b1b, 0xbcbce4e5, 0x1b1b4343, 0xe4e4bcbd, 0x45452f2f, 0xbabad0d1, 0x2f2f4545,
- 0xd0d0babb, 0x3837f0f1, 0xc7c80f0f, 0xf0f13838, 0x0f0ec7c8, 0x47470b0b, 0xb8b8f4f5, 0x0b0b4747,
- 0xf4f4b8b9, 0x4c4c4c4c, 0xb3b3b3b4, 0x5352f9fa, 0xacad0606, 0xf9fa5353, 0x0605acad, 0x3938d2d3,
- 0xc6c72d2d, 0xd2d33939, 0x2d2cc6c7, 0x4b4adbdc, 0xb4b52424, 0xdbdc4b4b, 0x2423b4b5, 0x73733838,
- 0x8c8cc7c8, 0x38387373, 0xc7c78c8d, 0x75751f1f, 0x8a8ae0e1, 0x1f1f7575, 0xe0e08a8b, 0x7a7a5858,
- 0x8585a7a8, 0x58587a7a, 0xa7a78586, 0x6867e3e4, 0x97981c1c, 0xe3e46868, 0x1c1b9798, 0x5554aaab,
- 0xaaab5555, 0x6a69b7b8, 0x95964848, 0xb7b86a6a, 0x48479596, 0x1e1e1e1e, 0xe1e1e1e2, 0x3a3a3a3a,
- 0xc5c5c5c6, 0x69696969, 0x96969697, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x05050505, 0x05050505,
- 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505,
- 0x05050505, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb,
- 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe,
- 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0xf8f90202,
- 0xf8f90202, 0xf8f90202, 0xf8f90202, 0xf8f90202, 0xf8f90202, 0xf8f90202, 0xf8f90202, 0xf8f90202,
- 0xf8f90202, 0xf8f90202, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707,
- 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9,
- 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9,
- 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b,
- 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5,
- 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0x0d0d0303, 0x0d0d0303,
- 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, 0x0d0d0303,
- 0x0d0d0303, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd,
- 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d,
- 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0xfbfbf0f1, 0x0b0af4f5, 0xf4f50b0b, 0x1211fafb,
- 0xedee0505, 0xfafb1212, 0x0504edee, 0x1a1a0d0d, 0xe5e5f2f3, 0x0d0d1a1a, 0xf2f2e5e6, 0x1a1a1a1a,
- 0xe5e5e5e6, 0x1d1d0202, 0xe2e2fdfe, 0x02021d1d, 0xfdfde2e3, 0x1817eff0, 0xe7e81010, 0xeff01818,
- 0x100fe7e8, 0x2e2e1c1c, 0xd1d1e3e4, 0x1c1c2e2e, 0xe3e3d1d2, 0x2322f6f7, 0xdcdd0909, 0xf6f72323,
- 0x0908dcdd, 0x2f2f0d0d, 0xd0d0f2f3, 0x0d0d2f2f, 0xf2f2d0d1, 0x31313131, 0xcecececf, 0x3635feff,
- 0xc9ca0101, 0xfeff3636, 0x0100c9ca, 0x2322dcdd, 0xdcdd2323, 0x2f2ee5e6, 0xd0d11a1a, 0xe5e62f2f,
- 0x1a19d0d1, 0x51512020, 0xaeaedfe0, 0x20205151, 0xdfdfaeaf, 0x53533838, 0xacacc7c8, 0x38385353,
- 0xc7c7acad, 0x4342edee, 0xbcbd1212, 0xedee4343, 0x1211bcbd, 0x56560d0d, 0xa9a9f2f3, 0x0d0d5656,
- 0xf2f2a9aa, 0x5b5b5b5b, 0xa4a4a4a5, 0x6362f8f9, 0x9c9d0707, 0xf8f96363, 0x07069c9d, 0x4443c9ca,
- 0xbbbc3636, 0xc9ca4444, 0x3635bbbc, 0x5a59d3d4, 0xa5a62c2c, 0xd3d45a5a, 0x2c2ba5a6, 0x7c7bdedf,
- 0x83842121, 0xdedf7c7c, 0x21208384, 0x67669899, 0x98996767, 0x7f7ea9aa, 0x80815656, 0xa9aa7f7f,
- 0x56558081, 0x25252525, 0xdadadadb, 0x45454545, 0xbabababb, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0xf9f9f9fa, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe,
- 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0xf7f80202, 0xf7f80202, 0xf7f80202,
- 0xf7f80202, 0xf7f80202, 0xf7f80202, 0xf7f80202, 0xf7f80202, 0xf7f80202, 0xf7f80202, 0xf7f80202,
- 0xf7f80202, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808,
- 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8,
- 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8,
- 0x0201f7f8, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d,
- 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3,
- 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3,
- 0xf2f2f2f3, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404,
- 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc,
- 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc,
- 0xf0f0fbfc, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f,
- 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010,
- 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0xfafaedee, 0x0d0cf2f3, 0xf2f30d0d, 0x1514f9fa,
- 0xeaeb0606, 0xf9fa1515, 0x0605eaeb, 0x1e1e0f0f, 0xe1e1f0f1, 0x0f0f1e1e, 0xf0f0e1e2, 0x1e1e1e1e,
- 0xe1e1e1e2, 0x22220202, 0xddddfdfe, 0x02022222, 0xfdfdddde, 0x1c1beced, 0xe3e41313, 0xeced1c1c,
- 0x1312e3e4, 0x36362020, 0xc9c9dfe0, 0x20203636, 0xdfdfc9ca, 0x2928f4f5, 0xd6d70b0b, 0xf4f52929,
- 0x0b0ad6d7, 0x37370f0f, 0xc8c8f0f1, 0x0f0f3737, 0xf0f0c8c9, 0x39393939, 0xc6c6c6c7, 0x3f3efeff,
- 0xc0c10101, 0xfeff3f3f, 0x0100c0c1, 0x2827d7d8, 0xd7d82828, 0x3736e1e2, 0xc8c91e1e, 0xe1e23737,
- 0x1e1dc8c9, 0x5e5e2525, 0xa1a1dadb, 0x25255e5e, 0xdadaa1a2, 0x60604141, 0x9f9fbebf, 0x41416060,
- 0xbebe9fa0, 0x4e4deaeb, 0xb1b21515, 0xeaeb4e4e, 0x1514b1b2, 0x64640f0f, 0x9b9bf0f1, 0x0f0f6464,
- 0xf0f09b9c, 0x6a6a6a6a, 0x95959596, 0x7473f7f8, 0x8b8c0808, 0xf7f87474, 0x08078b8c, 0x4f4ec0c1,
- 0xb0b13f3f, 0xc0c14f4f, 0x3f3eb0b1, 0x6968cccd, 0x96973333, 0xcccd6969, 0x33329697, 0x78778788,
- 0x87887878, 0x2b2b2b2b, 0xd4d4d4d5, 0x50505050, 0xafafafb0, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707,
- 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9,
- 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9,
- 0xf8f8f8f9, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd,
- 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0xf5f60303, 0xf5f60303, 0xf5f60303,
- 0xf5f60303, 0xf5f60303, 0xf5f60303, 0xf5f60303, 0xf5f60303, 0xf5f60303, 0xf5f60303, 0xf5f60303,
- 0xf5f60303, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a,
- 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6,
- 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6,
- 0x0302f5f6, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010,
- 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0xefefeff0, 0xefefeff0, 0xefefeff0,
- 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0,
- 0xefefeff0, 0x12120505, 0x12120505, 0x12120505, 0x12120505, 0x12120505, 0x12120505, 0x12120505,
- 0x12120505, 0x12120505, 0x12120505, 0x12120505, 0x12120505, 0xededfafb, 0xededfafb, 0xededfafb,
- 0xededfafb, 0xededfafb, 0xededfafb, 0xededfafb, 0xededfafb, 0xededfafb, 0xededfafb, 0xededfafb,
- 0xededfafb, 0x05051212, 0x05051212, 0x05051212, 0x05051212, 0x05051212, 0x05051212, 0x05051212,
- 0x05051212, 0x05051212, 0x05051212, 0x05051212, 0x05051212, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212,
- 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0xfafaebec, 0x0f0ef0f1, 0xf0f10f0f, 0x1817f8f9,
- 0xe7e80707, 0xf8f91818, 0x0706e7e8, 0x23231111, 0xdcdceeef, 0x11112323, 0xeeeedcdd, 0x22222222,
- 0xddddddde, 0x26260303, 0xd9d9fcfd, 0x03032626, 0xfcfcd9da, 0x201fe9ea, 0xdfe01616, 0xe9ea2020,
- 0x1615dfe0, 0x3d3d2525, 0xc2c2dadb, 0x25253d3d, 0xdadac2c3, 0x2f2ef2f3, 0xd0d10d0d, 0xf2f32f2f,
- 0x0d0cd0d1, 0x3f3f1111, 0xc0c0eeef, 0x11113f3f, 0xeeeec0c1, 0x41414141, 0xbebebebf, 0x4847feff,
- 0xb7b80101, 0xfeff4848, 0x0100b7b8, 0x2e2dd1d2, 0xd1d22e2e, 0x3f3edcdd, 0xc0c12323, 0xdcdd3f3f,
- 0x2322c0c1, 0x6b6b2b2b, 0x9494d4d5, 0x2b2b6b6b, 0xd4d49495, 0x6e6e4b4b, 0x9191b4b5, 0x4b4b6e6e,
- 0xb4b49192, 0x5958e7e8, 0xa6a71818, 0xe7e85959, 0x1817a6a7, 0x72721111, 0x8d8deeef, 0x11117272,
- 0xeeee8d8e, 0x79797979, 0x86868687, 0x5b5ab7b8, 0xa4a54848, 0xb7b85b5b, 0x4847a4a5, 0x7877c5c6,
- 0x87883a3a, 0xc5c67878, 0x3a398788, 0x31313131, 0xcecececf, 0x5c5c5c5c, 0xa3a3a3a4, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808,
- 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0xf7f7f7f8,
- 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8,
- 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd,
- 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0xf4f50303,
- 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xf4f50303,
- 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b,
- 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0x0302f4f5,
- 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x0302f4f5,
- 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212,
- 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0xedededee,
- 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee,
- 0xedededee, 0xedededee, 0xedededee, 0x14140505, 0x14140505, 0x14140505, 0x14140505, 0x14140505,
- 0x14140505, 0x14140505, 0x14140505, 0x14140505, 0x14140505, 0x14140505, 0x14140505, 0xebebfafb,
- 0xebebfafb, 0xebebfafb, 0xebebfafb, 0xebebfafb, 0xebebfafb, 0xebebfafb, 0xebebfafb, 0xebebfafb,
- 0xebebfafb, 0xebebfafb, 0xebebfafb, 0x05051414, 0x05051414, 0x05051414, 0x05051414, 0x05051414,
- 0x05051414, 0x05051414, 0x05051414, 0x05051414, 0x05051414, 0x05051414, 0x05051414, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414,
- 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x1110eeef, 0xeeef1111, 0x1b1af8f9,
- 0xe4e50707, 0xf8f91b1b, 0x0706e4e5, 0x27271313, 0xd8d8eced, 0x13132727, 0xececd8d9, 0x27272727,
- 0xd8d8d8d9, 0x2b2b0303, 0xd4d4fcfd, 0x03032b2b, 0xfcfcd4d5, 0x2423e7e8, 0xdbdc1818, 0xe7e82424,
- 0x1817dbdc, 0x45452a2a, 0xbabad5d6, 0x2a2a4545, 0xd5d5babb, 0x3534f1f2, 0xcacb0e0e, 0xf1f23535,
- 0x0e0dcacb, 0x47471313, 0xb8b8eced, 0x13134747, 0xececb8b9, 0x49494949, 0xb6b6b6b7, 0x504ffdfe,
- 0xafb00202, 0xfdfe5050, 0x0201afb0, 0x3433cbcc, 0xcbcc3434, 0x4645d8d9, 0xb9ba2727, 0xd8d94646,
- 0x2726b9ba, 0x79793030, 0x8686cfd0, 0x30307979, 0xcfcf8687, 0x7c7c5454, 0x8383abac, 0x54547c7c,
- 0xabab8384, 0x6463e4e5, 0x9b9c1b1b, 0xe4e56464, 0x1b1a9b9c, 0x6665aeaf, 0x999a5151, 0xaeaf6666,
- 0x5150999a, 0x37373737, 0xc8c8c8c9, 0x68686868, 0x97979798, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909,
- 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0xf6f6f6f7,
- 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7,
- 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd,
- 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd,
- 0x0c0bfcfd, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303,
- 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xfcfd0c0c, 0xfcfd0c0c,
- 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c,
- 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4,
- 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4,
- 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414,
- 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0xebebebec, 0xebebebec, 0xebebebec,
- 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec,
- 0xebebebec, 0xebebebec, 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0x17170606,
- 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0xe8e8f9fa,
- 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa,
- 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0x06061717, 0x06061717, 0x06061717, 0x06061717,
- 0x06061717, 0x06061717, 0x06061717, 0x06061717, 0x06061717, 0x06061717, 0x06061717, 0x06061717,
- 0x06061717, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9,
- 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404,
- 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x0403fbfc, 0xfbfc0404, 0x0605fdfe,
- 0xf9fa0202, 0xfdfe0606, 0x0201f9fa, 0x08080404, 0xf7f7fbfc, 0x04040808, 0xfbfbf7f8, 0x08080808,
- 0xf7f7f7f8, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x0807fbfc, 0xf7f80404, 0xfbfc0808,
- 0x0403f7f8, 0x0e0e0808, 0xf1f1f7f8, 0x08080e0e, 0xf7f7f1f2, 0x0c0bfdfe, 0xf3f40202, 0xfdfe0c0c,
- 0x0201f3f4, 0x10100404, 0xefeffbfc, 0x04041010, 0xfbfbeff0, 0x10101010, 0xefefeff0, 0x12120000,
- 0xedee0000, 0x00001212, 0xffffedee, 0x0c0bf3f4, 0xf3f40c0c, 0x100ff7f8, 0xeff00808, 0xf7f81010,
- 0x0807eff0, 0x1a1a0a0a, 0xe5e5f5f6, 0x0a0a1a1a, 0xf5f5e5e6, 0x1c1c1212, 0xe3e3edee, 0x12121c1c,
- 0xedede3e4, 0x1615f9fa, 0xe9ea0606, 0xf9fa1616, 0x0605e9ea, 0x1c1c0404, 0xe3e3fbfc, 0x04041c1c,
- 0xfbfbe3e4, 0x1e1e1e1e, 0xe1e1e1e2, 0x201ffdfe, 0xdfe00202, 0xfdfe2020, 0x0201dfe0, 0x1615edee,
- 0xe9ea1212, 0xedee1616, 0x1211e9ea, 0x1e1df1f2, 0xe1e20e0e, 0xf1f21e1e, 0x0e0de1e2, 0x2e2e1616,
- 0xd1d1e9ea, 0x16162e2e, 0xe9e9d1d2, 0x2e2e0c0c, 0xd1d1f3f4, 0x0c0c2e2e, 0xf3f3d1d2, 0x30302222,
- 0xcfcfddde, 0x22223030, 0xddddcfd0, 0x2827f5f6, 0xd7d80a0a, 0xf5f62828, 0x0a09d7d8, 0x32320404,
- 0xcdcdfbfc, 0x04043232, 0xfbfbcdce, 0x36363636, 0xc9c9c9ca, 0x2221ddde, 0xddde2222, 0x2a29e3e4,
- 0xd5d61c1c, 0xe3e42a2a, 0x1c1bd5d6, 0x3c3bf9fa, 0xc3c40606, 0xf9fa3c3c, 0x0605c3c4, 0x4c4c1a1a,
- 0xb3b3e5e6, 0x1a1a4c4c, 0xe5e5b3b4, 0x4c4c2a2a, 0xb3b3d5d6, 0x2a2a4c4c, 0xd5d5b3b4, 0x3635e7e8,
- 0xc9ca1818, 0xe7e83636, 0x1817c9ca, 0x4e4e0e0e, 0xb1b1f1f2, 0x0e0e4e4e, 0xf1f1b1b2, 0x52523e3e,
- 0xadadc1c2, 0x3e3e5252, 0xc1c1adae, 0x4a49ebec, 0xb5b61414, 0xebec4a4a, 0x1413b5b6, 0x58580202,
- 0xa7a7fdfe, 0x02025858, 0xfdfda7a8, 0x5c5c5c5c, 0xa3a3a3a4, 0x3c3bcbcc, 0xc3c43434, 0xcbcc3c3c,
- 0x3433c3c4, 0x76763434, 0x8989cbcc, 0x34347676, 0xcbcb898a, 0x4a49d3d4, 0xb5b62c2c, 0xd3d44a4a,
- 0x2c2bb5b6, 0x76764a4a, 0x8989b5b6, 0x4a4a7676, 0xb5b5898a, 0x76762020, 0x8989dfe0, 0x20207676,
- 0xdfdf898a, 0x6665f3f4, 0x999a0c0c, 0xf3f46666, 0x0c0b999a, 0x605fd7d8, 0x9fa02828, 0xd7d86060,
- 0x28279fa0, 0x7675ddde, 0x898a2222, 0xddde7676, 0x2221898a, 0x5857a7a8, 0xa7a85858, 0x6867b1b2,
- 0x97984e4e, 0xb1b26868, 0x4e4d9798, 0x0c0c0c0c, 0xf3f3f3f4, 0x16161616, 0xe9e9e9ea, 0x2a2a2a2a,
- 0xd5d5d5d6, 0x48484848, 0xb7b7b7b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe,
- 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0xfdfe0000,
- 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0x00000202, 0x00000202,
- 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe,
- 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606,
- 0xf9f9f9fa, 0x09090303, 0xf6f6fcfd, 0x03030909, 0xfcfcf6f7, 0x0908fcfd, 0xf6f70303, 0xfcfd0909,
- 0x0302f6f7, 0x0605f9fa, 0xf9fa0606, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0xf9f9f3f4, 0x0c0c0c0c,
- 0xf3f3f3f4, 0x0f0f0000, 0xf0f10000, 0x00000f0f, 0xfffff0f1, 0x0c0bf6f7, 0xf3f40909, 0xf6f70c0c,
- 0x0908f3f4, 0x18180f0f, 0xe7e7f0f1, 0x0f0f1818, 0xf0f0e7e8, 0x1211f9fa, 0xedee0606, 0xf9fa1212,
- 0x0605edee, 0x18180606, 0xe7e7f9fa, 0x06061818, 0xf9f9e7e8, 0x18181818, 0xe7e7e7e8, 0x1b1b0000,
- 0xe4e50000, 0x00001b1b, 0xffffe4e5, 0x1211edee, 0xedee1212, 0x1817f3f4, 0xe7e80c0c, 0xf3f41818,
- 0x0c0be7e8, 0x27270f0f, 0xd8d8f0f1, 0x0f0f2727, 0xf0f0d8d9, 0x2a2a1b1b, 0xd5d5e4e5, 0x1b1b2a2a,
- 0xe4e4d5d6, 0x2120f6f7, 0xdedf0909, 0xf6f72121, 0x0908dedf, 0x2a2a0606, 0xd5d5f9fa, 0x06062a2a,
- 0xf9f9d5d6, 0x2d2d2d2d, 0xd2d2d2d3, 0x3332fcfd, 0xcccd0303, 0xfcfd3333, 0x0302cccd, 0x2120e4e5,
- 0xdedf1b1b, 0xe4e52121, 0x1b1adedf, 0x2d2ceaeb, 0xd2d31515, 0xeaeb2d2d, 0x1514d2d3, 0x45452121,
- 0xbabadedf, 0x21214545, 0xdedebabb, 0x45451212, 0xbabaedee, 0x12124545, 0xededbabb, 0x48483636,
- 0xb7b7c9ca, 0x36364848, 0xc9c9b7b8, 0x3f3eedee, 0xc0c11212, 0xedee3f3f, 0x1211c0c1, 0x4e4e0606,
- 0xb1b1f9fa, 0x06064e4e, 0xf9f9b1b2, 0x51515151, 0xaeaeaeaf, 0x3332cccd, 0xcccd3333, 0x3f3ed5d6,
- 0xc0c12a2a, 0xd5d63f3f, 0x2a29c0c1, 0x5a59f6f7, 0xa5a60909, 0xf6f75a5a, 0x0908a5a6, 0x72722a2a,
- 0x8d8dd5d6, 0x2a2a7272, 0xd5d58d8e, 0x75753f3f, 0x8a8ac0c1, 0x3f3f7575, 0xc0c08a8b, 0x5150dbdc,
- 0xaeaf2424, 0xdbdc5151, 0x2423aeaf, 0x78781515, 0x8787eaeb, 0x15157878, 0xeaea8788, 0x7b7b6060,
- 0x84849fa0, 0x60607b7b, 0x9f9f8485, 0x6f6ee1e2, 0x90911e1e, 0xe1e26f6f, 0x1e1d9091, 0x5d5cb1b2,
- 0xa2a34e4e, 0xb1b25d5d, 0x4e4da2a3, 0x7271babb, 0x8d8e4545, 0xbabb7272, 0x45448d8e, 0x12121212,
- 0xedededee, 0x21212121, 0xdedededf, 0x3f3f3f3f, 0xc0c0c0c1, 0x6c6c6c6c, 0x93939394, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303,
- 0x03030303, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd,
- 0xfcfcfcfd, 0xfcfcfcfd, 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0x03030000,
- 0x03030000, 0x03030000, 0x03030000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000,
- 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0x00000303, 0x00000303, 0x00000303, 0x00000303,
- 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd,
- 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404,
- 0xf7f7fbfc, 0x04040808, 0xfbfbf7f8, 0x08080808, 0xf7f7f7f8, 0x0807f7f8, 0xf7f80808, 0x0c0bfbfc,
- 0xf3f40404, 0xfbfc0c0c, 0x0403f3f4, 0x10100808, 0xefeff7f8, 0x08081010, 0xf7f7eff0, 0x10101010,
- 0xefefeff0, 0x14140000, 0xebec0000, 0x00001414, 0xffffebec, 0x100ff3f4, 0xeff00c0c, 0xf3f41010,
- 0x0c0beff0, 0x1817fbfc, 0xe7e80404, 0xfbfc1818, 0x0403e7e8, 0x20201010, 0xdfdfeff0, 0x10102020,
- 0xefefdfe0, 0x20200808, 0xdfdff7f8, 0x08082020, 0xf7f7dfe0, 0x20202020, 0xdfdfdfe0, 0x24240000,
- 0xdbdc0000, 0x00002424, 0xffffdbdc, 0x1817e7e8, 0xe7e81818, 0x201feff0, 0xdfe01010, 0xeff02020,
- 0x100fdfe0, 0x34341414, 0xcbcbebec, 0x14143434, 0xebebcbcc, 0x38382424, 0xc7c7dbdc, 0x24243838,
- 0xdbdbc7c8, 0x2c2bf3f4, 0xd3d40c0c, 0xf3f42c2c, 0x0c0bd3d4, 0x38380808, 0xc7c7f7f8, 0x08083838,
- 0xf7f7c7c8, 0x3c3c3c3c, 0xc3c3c3c4, 0x403ffbfc, 0xbfc00404, 0xfbfc4040, 0x0403bfc0, 0x2c2bdbdc,
- 0xd3d42424, 0xdbdc2c2c, 0x2423d3d4, 0x3c3be3e4, 0xc3c41c1c, 0xe3e43c3c, 0x1c1bc3c4, 0x5c5c2c2c,
- 0xa3a3d3d4, 0x2c2c5c5c, 0xd3d3a3a4, 0x5c5c1818, 0xa3a3e7e8, 0x18185c5c, 0xe7e7a3a4, 0x60604848,
- 0x9f9fb7b8, 0x48486060, 0xb7b79fa0, 0x5453ebec, 0xabac1414, 0xebec5454, 0x1413abac, 0x64640808,
- 0x9b9bf7f8, 0x08086464, 0xf7f79b9c, 0x6c6c6c6c, 0x93939394, 0x4443bbbc, 0xbbbc4444, 0x5453c7c8,
- 0xabac3838, 0xc7c85454, 0x3837abac, 0x7877f3f4, 0x87880c0c, 0xf3f47878, 0x0c0b8788, 0x6c6bcfd0,
- 0x93943030, 0xcfd06c6c, 0x302f9394, 0x7c7b9798, 0x83846868, 0x97987c7c, 0x68678384, 0x18181818,
- 0xe7e7e7e8, 0x2c2c2c2c, 0xd3d3d3d4, 0x54545454, 0xabababac, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04040404,
- 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404,
- 0x04040404, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc,
- 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000,
- 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000,
- 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0x00000404,
- 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404,
- 0x00000404, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc,
- 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0x08080404, 0x08080404, 0x08080404, 0x08080404, 0x08080404,
- 0x08080404, 0x08080404, 0x08080404, 0x08080404, 0x08080404, 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc,
- 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, 0x04040808,
- 0x04040808, 0x04040808, 0x04040808, 0x04040808, 0x04040808, 0x04040808, 0x04040808, 0x04040808,
- 0x04040808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a,
- 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x05050f0f, 0xfafaf0f1, 0x0a09f5f6, 0xf5f60a0a, 0x0f0efafb,
- 0xf0f10505, 0xfafb0f0f, 0x0504f0f1, 0x14140a0a, 0xebebf5f6, 0x0a0a1414, 0xf5f5ebec, 0x14141414,
- 0xebebebec, 0x19190000, 0xe6e70000, 0x00001919, 0xffffe6e7, 0x1413f0f1, 0xebec0f0f, 0xf0f11414,
- 0x0f0eebec, 0x28281919, 0xd7d7e6e7, 0x19192828, 0xe6e6d7d8, 0x1e1df5f6, 0xe1e20a0a, 0xf5f61e1e,
- 0x0a09e1e2, 0x28280a0a, 0xd7d7f5f6, 0x0a0a2828, 0xf5f5d7d8, 0x28282828, 0xd7d7d7d8, 0x2d2d0000,
- 0xd2d30000, 0x00002d2d, 0xffffd2d3, 0x1e1de1e2, 0xe1e21e1e, 0x2827ebec, 0xd7d81414, 0xebec2828,
- 0x1413d7d8, 0x41411919, 0xbebee6e7, 0x19194141, 0xe6e6bebf, 0x46462d2d, 0xb9b9d2d3, 0x2d2d4646,
- 0xd2d2b9ba, 0x3736f0f1, 0xc8c90f0f, 0xf0f13737, 0x0f0ec8c9, 0x46460a0a, 0xb9b9f5f6, 0x0a0a4646,
- 0xf5f5b9ba, 0x4b4b4b4b, 0xb4b4b4b5, 0x5554fafb, 0xaaab0505, 0xfafb5555, 0x0504aaab, 0x3736d2d3,
- 0xc8c92d2d, 0xd2d33737, 0x2d2cc8c9, 0x4b4adcdd, 0xb4b52323, 0xdcdd4b4b, 0x2322b4b5, 0x73733737,
- 0x8c8cc8c9, 0x37377373, 0xc8c88c8d, 0x73731e1e, 0x8c8ce1e2, 0x1e1e7373, 0xe1e18c8d, 0x78785a5a,
- 0x8787a5a6, 0x5a5a7878, 0xa5a58788, 0x6968e1e2, 0x96971e1e, 0xe1e26969, 0x1e1d9697, 0x5554aaab,
- 0xaaab5555, 0x6968b9ba, 0x96974646, 0xb9ba6969, 0x46459697, 0x1e1e1e1e, 0xe1e1e1e2, 0x3c3c3c3c,
- 0xc3c3c3c4, 0x69696969, 0x96969697, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x05050505, 0x05050505,
- 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505,
- 0x05050505, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb,
- 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0x05050000, 0x05050000, 0x05050000, 0x05050000,
- 0x05050000, 0x05050000, 0x05050000, 0x05050000, 0x05050000, 0x05050000, 0x05050000, 0xfafb0000,
- 0xfafb0000, 0xfafb0000, 0xfafb0000, 0xfafb0000, 0xfafb0000, 0xfafb0000, 0xfafb0000, 0xfafb0000,
- 0xfafb0000, 0xfafb0000, 0x00000505, 0x00000505, 0x00000505, 0x00000505, 0x00000505, 0x00000505,
- 0x00000505, 0x00000505, 0x00000505, 0x00000505, 0x00000505, 0xfffffafb, 0xfffffafb, 0xfffffafb,
- 0xfffffafb, 0xfffffafb, 0xfffffafb, 0xfffffafb, 0xfffffafb, 0xfffffafb, 0xfffffafb, 0xfffffafb,
- 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a,
- 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6,
- 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0x0f0f0505, 0x0f0f0505,
- 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, 0x0f0f0505,
- 0x0f0f0505, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb,
- 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c,
- 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0xf9f9f3f4, 0x0c0bf3f4, 0xf3f40c0c, 0x1211f9fa,
- 0xedee0606, 0xf9fa1212, 0x0605edee, 0x18180c0c, 0xe7e7f3f4, 0x0c0c1818, 0xf3f3e7e8, 0x18181818,
- 0xe7e7e7e8, 0x1e1e0000, 0xe1e20000, 0x00001e1e, 0xffffe1e2, 0x1817edee, 0xe7e81212, 0xedee1818,
- 0x1211e7e8, 0x30301e1e, 0xcfcfe1e2, 0x1e1e3030, 0xe1e1cfd0, 0x2423f9fa, 0xdbdc0606, 0xf9fa2424,
- 0x0605dbdc, 0x30300c0c, 0xcfcff3f4, 0x0c0c3030, 0xf3f3cfd0, 0x30303030, 0xcfcfcfd0, 0x36360000,
- 0xc9ca0000, 0x00003636, 0xffffc9ca, 0x2423dbdc, 0xdbdc2424, 0x302fe7e8, 0xcfd01818, 0xe7e83030,
- 0x1817cfd0, 0x4e4e1e1e, 0xb1b1e1e2, 0x1e1e4e4e, 0xe1e1b1b2, 0x54543636, 0xababc9ca, 0x36365454,
- 0xc9c9abac, 0x4241edee, 0xbdbe1212, 0xedee4242, 0x1211bdbe, 0x54540c0c, 0xababf3f4, 0x0c0c5454,
- 0xf3f3abac, 0x5a5a5a5a, 0xa5a5a5a6, 0x605ff9fa, 0x9fa00606, 0xf9fa6060, 0x06059fa0, 0x4241c9ca,
- 0xbdbe3636, 0xc9ca4242, 0x3635bdbe, 0x5a59d5d6, 0xa5a62a2a, 0xd5d65a5a, 0x2a29a5a6, 0x7e7de1e2,
- 0x81821e1e, 0xe1e27e7e, 0x1e1d8182, 0x6665999a, 0x999a6666, 0x7e7dabac, 0x81825454, 0xabac7e7e,
- 0x54538182, 0x24242424, 0xdbdbdbdc, 0x42424242, 0xbdbdbdbe, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0xf9f9f9fa, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000,
- 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000,
- 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000,
- 0xf9fa0000, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606,
- 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa,
- 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa,
- 0xfffff9fa, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
- 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606,
- 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa,
- 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa,
- 0xf3f3f9fa, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c,
- 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e,
- 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0xf8f8eaeb, 0x0e0df1f2, 0xf1f20e0e, 0x1514f8f9,
- 0xeaeb0707, 0xf8f91515, 0x0706eaeb, 0x1c1c0e0e, 0xe3e3f1f2, 0x0e0e1c1c, 0xf1f1e3e4, 0x1c1c1c1c,
- 0xe3e3e3e4, 0x23230000, 0xdcdd0000, 0x00002323, 0xffffdcdd, 0x1c1beaeb, 0xe3e41515, 0xeaeb1c1c,
- 0x1514e3e4, 0x38382323, 0xc7c7dcdd, 0x23233838, 0xdcdcc7c8, 0x2a29f1f2, 0xd5d60e0e, 0xf1f22a2a,
- 0x0e0dd5d6, 0x38380e0e, 0xc7c7f1f2, 0x0e0e3838, 0xf1f1c7c8, 0x38383838, 0xc7c7c7c8, 0x3f3f0000,
- 0xc0c10000, 0x00003f3f, 0xffffc0c1, 0x2a29d5d6, 0xd5d62a2a, 0x3837e3e4, 0xc7c81c1c, 0xe3e43838,
- 0x1c1bc7c8, 0x5b5b2323, 0xa4a4dcdd, 0x23235b5b, 0xdcdca4a5, 0x62623f3f, 0x9d9dc0c1, 0x3f3f6262,
- 0xc0c09d9e, 0x4d4ceaeb, 0xb2b31515, 0xeaeb4d4d, 0x1514b2b3, 0x62620e0e, 0x9d9df1f2, 0x0e0e6262,
- 0xf1f19d9e, 0x69696969, 0x96969697, 0x7776f8f9, 0x88890707, 0xf8f97777, 0x07068889, 0x4d4cc0c1,
- 0xb2b33f3f, 0xc0c14d4d, 0x3f3eb2b3, 0x6968cecf, 0x96973131, 0xcecf6969, 0x31309697, 0x77768889,
- 0x88897777, 0x2a2a2a2a, 0xd5d5d5d6, 0x4d4d4d4d, 0xb2b2b2b3, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707,
- 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9,
- 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9,
- 0xf8f8f8f9, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000,
- 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0xf8f90000, 0xf8f90000, 0xf8f90000,
- 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000,
- 0xf8f90000, 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0x00000707,
- 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9,
- 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9,
- 0xfffff8f9, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e,
- 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2,
- 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2,
- 0xf1f1f1f2, 0x15150707, 0x15150707, 0x15150707, 0x15150707, 0x15150707, 0x15150707, 0x15150707,
- 0x15150707, 0x15150707, 0x15150707, 0x15150707, 0x15150707, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9,
- 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9,
- 0xeaeaf8f9, 0x07071515, 0x07071515, 0x07071515, 0x07071515, 0x07071515, 0x07071515, 0x07071515,
- 0x07071515, 0x07071515, 0x07071515, 0x07071515, 0x07071515, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010,
- 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0xf7f7eff0, 0x100feff0, 0xeff01010, 0x1817f7f8,
- 0xe7e80808, 0xf7f81818, 0x0807e7e8, 0x20201010, 0xdfdfeff0, 0x10102020, 0xefefdfe0, 0x20202020,
- 0xdfdfdfe0, 0x28280000, 0xd7d80000, 0x00002828, 0xffffd7d8, 0x201fe7e8, 0xdfe01818, 0xe7e82020,
- 0x1817dfe0, 0x40402828, 0xbfbfd7d8, 0x28284040, 0xd7d7bfc0, 0x302feff0, 0xcfd01010, 0xeff03030,
- 0x100fcfd0, 0x40401010, 0xbfbfeff0, 0x10104040, 0xefefbfc0, 0x40404040, 0xbfbfbfc0, 0x48480000,
- 0xb7b80000, 0x00004848, 0xffffb7b8, 0x302fcfd0, 0xcfd03030, 0x403fdfe0, 0xbfc02020, 0xdfe04040,
- 0x201fbfc0, 0x68682828, 0x9797d7d8, 0x28286868, 0xd7d79798, 0x70704848, 0x8f8fb7b8, 0x48487070,
- 0xb7b78f90, 0x5857e7e8, 0xa7a81818, 0xe7e85858, 0x1817a7a8, 0x70701010, 0x8f8feff0, 0x10107070,
- 0xefef8f90, 0x78787878, 0x87878788, 0x5857b7b8, 0xa7a84848, 0xb7b85858, 0x4847a7a8, 0x7877c7c8,
- 0x87883838, 0xc7c87878, 0x38378788, 0x30303030, 0xcfcfcfd0, 0x58585858, 0xa7a7a7a8, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808,
- 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0xf7f7f7f8,
- 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8,
- 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000,
- 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0xf7f80000,
- 0xf7f80000, 0xf7f80000, 0xf7f80000, 0xf7f80000, 0xf7f80000, 0xf7f80000, 0xf7f80000, 0xf7f80000,
- 0xf7f80000, 0xf7f80000, 0xf7f80000, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808,
- 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0xfffff7f8,
- 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0xfffff7f8,
- 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010,
- 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0xefefeff0,
- 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0,
- 0xefefeff0, 0xefefeff0, 0xefefeff0, 0x10100808, 0x10100808, 0x10100808, 0x10100808, 0x10100808,
- 0x10100808, 0x10100808, 0x10100808, 0x10100808, 0x10100808, 0x10100808, 0x10100808, 0xefeff7f8,
- 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0xefeff7f8,
- 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0x08081010, 0x08081010, 0x08081010, 0x08081010, 0x08081010,
- 0x08081010, 0x08081010, 0x08081010, 0x08081010, 0x08081010, 0x08081010, 0x08081010, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212,
- 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x1211edee, 0xedee1212, 0x1b1af6f7,
- 0xe4e50909, 0xf6f71b1b, 0x0908e4e5, 0x24241212, 0xdbdbedee, 0x12122424, 0xededdbdc, 0x24242424,
- 0xdbdbdbdc, 0x2d2d0000, 0xd2d30000, 0x00002d2d, 0xffffd2d3, 0x2423e4e5, 0xdbdc1b1b, 0xe4e52424,
- 0x1b1adbdc, 0x48482d2d, 0xb7b7d2d3, 0x2d2d4848, 0xd2d2b7b8, 0x3635edee, 0xc9ca1212, 0xedee3636,
- 0x1211c9ca, 0x48481212, 0xb7b7edee, 0x12124848, 0xededb7b8, 0x48484848, 0xb7b7b7b8, 0x51510000,
- 0xaeaf0000, 0x00005151, 0xffffaeaf, 0x3635c9ca, 0xc9ca3636, 0x4847dbdc, 0xb7b82424, 0xdbdc4848,
- 0x2423b7b8, 0x75752d2d, 0x8a8ad2d3, 0x2d2d7575, 0xd2d28a8b, 0x7e7e5151, 0x8181aeaf, 0x51517e7e,
- 0xaeae8182, 0x6362e4e5, 0x9c9d1b1b, 0xe4e56363, 0x1b1a9c9d, 0x6362aeaf, 0x9c9d5151, 0xaeaf6363,
- 0x51509c9d, 0x36363636, 0xc9c9c9ca, 0x6c6c6c6c, 0x93939394, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909,
- 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0xf6f6f6f7,
- 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7,
- 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0x09090000, 0x09090000, 0x09090000, 0x09090000,
- 0x09090000, 0x09090000, 0x09090000, 0x09090000, 0x09090000, 0x09090000, 0x09090000, 0x09090000,
- 0x09090000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000,
- 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0x00000909, 0x00000909,
- 0x00000909, 0x00000909, 0x00000909, 0x00000909, 0x00000909, 0x00000909, 0x00000909, 0x00000909,
- 0x00000909, 0x00000909, 0x00000909, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7,
- 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7,
- 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212,
- 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0xedededee, 0xedededee, 0xedededee,
- 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee,
- 0xedededee, 0xedededee, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909,
- 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0xe4e4f6f7,
- 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7,
- 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b,
- 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b,
- 0x09091b1b, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5,
- 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606,
- 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0504fafb, 0xfafb0505, 0xfafb0505,
- 0x0504fafb, 0x0b0b0606, 0xf4f4f9fa, 0x06060b0b, 0xf9f9f4f5, 0x08080000, 0xf7f80000, 0x00000808,
- 0xfffff7f8, 0x0b0b0b0b, 0xf4f4f4f5, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x11110c0c,
- 0xeeeef3f4, 0x0c0c1111, 0xf3f3eeef, 0x11111111, 0xeeeeeeef, 0x12120606, 0xededf9fa, 0x06061212,
- 0xf9f9edee, 0x0b0af7f8, 0xf4f50808, 0xf7f80b0b, 0x0807f4f5, 0x0f0f0000, 0xf0f10000, 0x00000f0f,
- 0xfffff0f1, 0x14140000, 0xebec0000, 0x00001414, 0xffffebec, 0x19191212, 0xe6e6edee, 0x12121919,
- 0xedede6e7, 0x19190b0b, 0xe6e6f4f5, 0x0b0b1919, 0xf4f4e6e7, 0x19191919, 0xe6e6e6e7, 0x0e0df1f2,
- 0xf1f20e0e, 0xf1f20e0e, 0x0e0df1f2, 0x1a1a0000, 0xe5e60000, 0x00001a1a, 0xffffe5e6, 0x1211f4f5,
- 0xedee0b0b, 0xf4f51212, 0x0b0aedee, 0x1615f8f9, 0xe9ea0707, 0xf8f91616, 0x0706e9ea, 0x22221a1a,
- 0xdddde5e6, 0x1a1a2222, 0xe5e5ddde, 0x22221212, 0xddddedee, 0x12122222, 0xededddde, 0x22222222,
- 0xddddddde, 0x23230b0b, 0xdcdcf4f5, 0x0b0b2323, 0xf4f4dcdd, 0x1d1d0000, 0xe2e30000, 0x00001d1d,
- 0xffffe2e3, 0x1615eced, 0xe9ea1313, 0xeced1616, 0x1312e9ea, 0x1a19f0f1, 0xe5e60f0f, 0xf0f11a1a,
- 0x0f0ee5e6, 0x25250000, 0xdadb0000, 0x00002525, 0xffffdadb, 0x2c2c1b1b, 0xd3d3e4e5, 0x1b1b2c2c,
- 0xe4e4d3d4, 0x2c2c2424, 0xd3d3dbdc, 0x24242c2c, 0xdbdbd3d4, 0x2c2c1212, 0xd3d3edee, 0x12122c2c,
- 0xededd3d4, 0x2120f5f6, 0xdedf0a0a, 0xf5f62121, 0x0a09dedf, 0x2d2d2d2d, 0xd2d2d2d3, 0x00000000,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606,
- 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000,
- 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000,
- 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd,
- 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000,
- 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa,
- 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303,
- 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe,
- 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606,
- 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000,
- 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000,
- 0xf8f90000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606,
- 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0403fbfc, 0xfbfc0404, 0xf9fa0a0a,
- 0x0605f5f6, 0xf3f40000, 0x0c0c0000, 0xf3f3f9fa, 0xf3f40606, 0x0c0bf9fa, 0x0c0c0606, 0xfffff1f2,
- 0x00000e0e, 0x0c0c0c0c, 0xf3f3f3f4, 0xedee0000, 0x12120000, 0xf3f40e0e, 0x0c0bf1f2, 0xf9f9edee,
- 0xf9fa1212, 0x0605edee, 0x06061212, 0xededf5f6, 0xedee0a0a, 0x1211f5f6, 0x12120a0a, 0xffffe9ea,
- 0x00001616, 0xe7e80000, 0x18180000, 0xf3f3e9ea, 0xf3f41616, 0x0c0be9ea, 0x0c0c1616, 0xe7e7f7f8,
- 0xe7e80808, 0x1817f7f8, 0x18180808, 0xf9f9e5e6, 0xf9fa1a1a, 0x0605e5e6, 0x06061a1a, 0xffffe3e4,
- 0x00001c1c, 0x14141414, 0xebebebec, 0xe5e5f1f2, 0x1a1a0e0e, 0xf3f3e1e2, 0x0c0c1e1e, 0xdfdff5f6,
- 0x20200a0a, 0xdfdfedee, 0x20201212, 0xe5e5e5e6, 0x1a1a1a1a, 0xebebddde, 0x14142222, 0xf3f3d9da,
- 0x0c0c2626, 0xdfdfdfe0, 0x20202020, 0x20202020, 0xd7d7e9ea, 0xddddddde, 0x22222222, 0x00000000,
- 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa,
- 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202,
- 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606,
- 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe,
- 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000,
- 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000,
- 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe,
- 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa,
- 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606,
- 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000,
- 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000,
- 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202,
- 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000,
- 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa,
- 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202,
- 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606,
- 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe,
- 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000,
- 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000,
- 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe,
- 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a,
- 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x0605f9fa, 0xf9fa0606, 0xf7f80e0e,
- 0x0807f1f2, 0xffffedee, 0x00001212, 0xeff00a0a, 0x100ff5f6, 0xe7e80000, 0x18180000, 0xf7f7e7e8,
- 0xf7f81818, 0x0807e7e8, 0x08081818, 0x12121212, 0xedededee, 0xeff01414, 0x100febec, 0xe5e5f1f2,
- 0xe5e60e0e, 0x1a19f1f2, 0x1a1a0e0e, 0xffffe1e2, 0x00001e1e, 0xddde0000, 0x22220000, 0xf7f7ddde,
- 0xf7f82222, 0x0807ddde, 0x08082222, 0xedede1e2, 0xedee1e1e, 0x1211e1e2, 0x12121e1e, 0xddddf5f6,
- 0xddde0a0a, 0x2221f5f6, 0x22220a0a, 0xddddebec, 0x22221414, 0xffffd7d8, 0x00002828, 0x1e1e1e1e,
- 0xe1e1e1e2, 0xededd7d8, 0x12122828, 0xd3d40000, 0x2c2c0000, 0xd3d3eff0, 0x2c2c1010, 0xdbdbdbdc,
- 0xdbdbdbdc, 0x24242424, 0xd3d3e5e6, 0x2c2c1a1a, 0xe5e5d1d2, 0x1a1a2e2e, 0xededcbcc, 0x12123434,
- 0xc9c9ebec, 0xd3d3d3d4, 0x2c2c2c2c, 0xc9c9dfe0, 0xd1d1d1d2, 0xd1d1d1d2, 0x2e2e2e2e, 0x00000000,
- 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6,
- 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202,
- 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a,
- 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc,
- 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000,
- 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000,
- 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe,
- 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6,
- 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a,
- 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000,
- 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000,
- 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404,
- 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000,
- 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6,
- 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202,
- 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a,
- 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc,
- 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000,
- 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000,
- 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe,
- 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c,
- 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x0807f7f8, 0xf7f80808, 0xeff00808,
- 0x100ff7f8, 0xe7e80000, 0x18180000, 0xf7f7e7e8, 0xf7f81818, 0x0807e7e8, 0x08081818, 0xeff01414,
- 0x100febec, 0xffffe3e4, 0x00001c1c, 0xe7e7eff0, 0xe7e81010, 0x1817eff0, 0x18181010, 0xdfe00000,
- 0x20200000, 0xefefe3e4, 0xeff01c1c, 0x100fe3e4, 0x10101c1c, 0xdfdff7f8, 0xdfe00808, 0xf7f7dfe0,
- 0xf7f82020, 0x0807dfe0, 0x08082020, 0x201ff7f8, 0x20200808, 0x18181818, 0xe7e7e7e8, 0xe7e81818,
- 0x1817e7e8, 0xdfdfebec, 0x20201414, 0xffffd7d8, 0x00002828, 0xefefd7d8, 0x10102828, 0xd3d40000,
- 0xd3d40000, 0xffffd3d4, 0x00002c2c, 0x2c2c0000, 0x2c2c0000, 0xdfdfdfe0, 0x20202020, 0xd3d3eff0,
- 0x2c2c1010, 0xd3d3e7e8, 0xe7e7d3d4, 0x18182c2c, 0x2c2c1818, 0xefefcfd0, 0x10103030, 0xdbdbdbdc,
- 0xdbdbdbdc, 0x24242424, 0x24242424, 0xcbcbebec, 0x28282828, 0xd7d7d7d8, 0xcbcbdfe0, 0x00000000,
- 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4,
- 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404,
- 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c,
- 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000,
- 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000,
- 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc,
- 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4,
- 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c,
- 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000,
- 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000,
- 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404,
- 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000,
- 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4,
- 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404,
- 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c,
- 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000,
- 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000,
- 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc,
- 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414,
- 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec,
- 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606,
- 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e,
- 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4,
- 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020,
- 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414,
- 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe,
- 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0,
- 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c,
- 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec,
- 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606,
- 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e,
- 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4,
- 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020,
- 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414,
- 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec,
- 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606,
- 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e,
- 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4,
- 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020,
- 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414,
- 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe,
- 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0,
- 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c,
- 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec,
- 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606,
- 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e,
- 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4,
- 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020,
- 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414,
- 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec,
- 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606,
- 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e,
- 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4,
- 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020,
- 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414,
- 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe,
- 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0,
- 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c,
- 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec,
- 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606,
- 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e,
- 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4,
- 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020,
- 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414,
- 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec,
- 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606,
- 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e,
- 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4,
- 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020,
- 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414,
- 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe,
- 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0,
- 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c,
- 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec,
- 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606,
- 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e,
- 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4,
- 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020,
- 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
-};
+#define TAB_1_2 \
+ PD( 0, 0), E2( 3, 3), E4( -1, 4), E2( 7, 7), E4( 2, 8),\
+ E4( -2, 9), E2( -6, 6), E4( 6, 13), E2( 13, 13), E4( 1, 14),\
+ E4( -8, 12), E4( 14, 23), E4( -5, 18), E4( 6, 24), E2( 24, 24),\
+ E4( -1, 27), E2( -17, 17), E4( -13, 23), E4( 16, 40), E4( 28, 41),\
+ E4( -9, 33), E4( 6, 43), E2( 46, 46), E4( -4, 50), E4( -27, 34),\
+ E4( -22, 45), E4( 34, 69), E4( 19, 70), E4( 53, 73), E4( -17, 62),\
+ E4( 5, 77), E2( 82, 82), E2( -51, 51), E4( -43, 64), E4( -10, 90),\
+ E4( 41, 114), E4( 64, 116), E4( -37, 82), E4( 22, 119), E4( 95, 124),\
+ E4( -30, 111), E4( -78, 92), E4( -68, 113), E2( 18, 18), E2( 34, 34),\
+ E2( 63, 63), E2( 109, 109)
+
+#define TAB_1_3 \
+ PD( 0, 0), E2( 4, 4), E4( -1, 5), E4( 3, 10), E2( 9, 9),\
+ E2( -7, 7), E4( -3, 12), E4( 8, 17), E2( 17, 17), E4( 1, 19),\
+ E4( -11, 16), E4( -6, 23), E4( 18, 31), E4( 8, 32), E2( 33, 33),\
+ E4( -1, 36), E2( -23, 23), E4( -17, 31), E4( 21, 54), E4( 37, 55),\
+ E4( -12, 44), E4( 8, 57), E2( 61, 61), E4( -5, 66), E4( -36, 45),\
+ E4( -29, 60), E4( 45, 92), E4( 25, 93), E4( 71, 97), E4( -22, 83),\
+ E4( 7, 102), E2( 109, 109), E2( -68, 68), E4( -57, 85), E4( -13, 120),\
+ E4( -49, 110), E4(-104, 123), E2( 24, 24), E2( 46, 46), E2( 84, 84)
+
+#define TAB_1_4 \
+ PD( 0, 0), E2( 5, 5), E4( -2, 7), E2( 11, 11), E4( 3, 13),\
+ E2( -9, 9), E4( -4, 15), E4( 11, 22), E2( 21, 21), E4( 2, 24),\
+ E4( -14, 20), E4( 23, 38), E4( -8, 29), E4( 11, 39), E2( 41, 41),\
+ E4( -1, 45), E2( -29, 29), E4( -22, 39), E4( 27, 67), E4( 47, 69),\
+ E4( -15, 56), E4( 11, 71), E2( 76, 76), E4( -6, 83), E4( -45, 57),\
+ E4( -36, 75), E4( 56, 115), E4( 31, 117), E4( 88, 122), E4( -28, 104),\
+ E2( -85, 85), E4( -72, 106), E2( 30, 30), E2( 58, 58), E2( 105, 105)
+
+#define TAB_1_5 \
+ PD( 0, 0), E2( 6, 6), E4( -2, 8), E2( 13, 13), E4( 4, 15),\
+ E2( -11, 11), E4( -5, 18), E4( 13, 26), E2( 26, 26), E4( 2, 29),\
+ E4( -16, 24), E4( 28, 46), E4( -9, 35), E4( 13, 47), E2( 49, 49),\
+ E4( -1, 54), E2( -35, 35), E4( -26, 47), E4( 32, 81), E4( 56, 83),\
+ E4( -18, 67), E4( 13, 86), E2( 91, 91), E4( -7, 99), E4( -54, 68),\
+ E4( -44, 90), E4( -33, 124), E2(-103, 103), E4( -86, 127), E2( 37, 37),\
+ E2( 69, 69)
+
+#define TAB_1_6 \
+ PD( 0, 0), E2( 7, 7), E4( -3, 10), E2( 16, 16), E4( 5, 18),\
+ E2( -13, 13), E4( -6, 21), E4( 15, 30), E2( 30, 30), E4( 2, 34),\
+ E4( -19, 28), E4( 32, 54), E4( -11, 41), E4( 15, 55), E2( 57, 57),\
+ E4( -1, 63), E2( -40, 40), E4( -30, 55), E4( 37, 94), E4( 65, 96),\
+ E4( -21, 78), E4( 15, 100), E2( 106, 106), E4( -8, 116), E4( -63, 79),\
+ E4( -51, 105), E2(-120, 120), E2( 43, 43), E2( 80, 80)
+
+#define TAB_1_7 \
+ PD( 0, 0), E2( 8, 8), E4( -3, 11), E2( 18, 18), E4( 5, 20),\
+ E2( -15, 15), E4( -7, 24), E4( 17, 35), E2( 34, 34), E4( 3, 38),\
+ E4( -22, 32), E4( 37, 61), E4( -13, 47), E4( 17, 63), E2( 65, 65),\
+ E4( -1, 72), E2( -46, 46), E4( -35, 63), E4( 43, 107), E4( 75, 110),\
+ E4( -24, 89), E4( 17, 114), E2( 121, 121), E4( -72, 91), E4( -58, 120),\
+ E2( 49, 49), E2( 92, 92)
+
+#define TAB_1_8 \
+ PD( 0, 0), E2( 9, 9), E4( -3, 12), E2( 20, 20), E4( 6, 23),\
+ E2( -17, 17), E4( -7, 27), E4( 19, 39), E2( 39, 39), E4( 3, 43),\
+ E4( -24, 36), E4( 42, 69), E4( -14, 53), E4( 19, 71), E2( 73, 73),\
+ E4( -2, 80), E2( -52, 52), E4( -39, 70), E4( 48, 121), E4( 84, 124),\
+ E4( -27, 100), E4( -81, 102), E2( 55, 55), E2( 104, 104)
+
+#define TAB_2_1 \
+ PD( 0, 0), E2( 2, 2), E4( 0, 2), E2( 4, 4), E4( 0, 4),\
+ E2( -4, 4), E4( -2, 6), E4( 4, 8), E2( 8, 8), E4( 0, 10),\
+ E4( -4, 8), E4( 8, 14), E4( -2, 12), E4( 4, 16), E2( 16, 16),\
+ E4( 0, 18), E2( -12, 12), E4( -8, 16), E4( 10, 26), E4( 18, 28),\
+ E4( -6, 22), E4( 4, 28), E2( 30, 30), E4( -2, 32), E4( -18, 22),\
+ E4( -14, 30), E4( 22, 46), E4( 12, 46), E4( 34, 48), E4( -10, 40),\
+ E4( 4, 50), E2( 54, 54), E2( -34, 34), E4( -28, 42), E4( -6, 60),\
+ E4( 26, 76), E4( 42, 76), E4( -24, 54), E4( 14, 78), E4( 62, 82),\
+ E4( -20, 74), E4( 2, 88), E2( 92, 92), E4( -52, 60), E4( 52, 118),\
+ E4( -44, 74), E4( 74, 118), E4( 32, 118), E4( -12, 102), E4( -40, 96),\
+ E4( -34, 118), E2( -88, 88), E4( -78, 104), E2( 12, 12), E2( 22, 22),\
+ E2( 42, 42), E2( 72, 72)
+
+#define TAB_2_2 \
+ PD( 0, 0), E2( 3, 3), E4( 0, 3), E2( 6, 6), E4( 3, 9),\
+ E4( -3, 9), E2( -6, 6), E4( 6, 12), E2( 12, 12), E4( 0, 15),\
+ E4( -9, 12), E4( 15, 24), E4( -6, 18), E4( 6, 24), E2( 24, 24),\
+ E4( 0, 27), E2( -18, 18), E4( -12, 24), E4( 15, 39), E4( 27, 42),\
+ E4( -9, 33), E4( 6, 42), E2( 45, 45), E4( -3, 51), E4( -27, 33),\
+ E4( -21, 45), E4( 33, 69), E4( 18, 69), E4( 54, 72), E4( -18, 63),\
+ E4( 6, 78), E2( 81, 81), E2( -51, 51), E4( -42, 63), E4( -9, 90),\
+ E4( 42, 114), E4( 63, 117), E4( -36, 81), E4( 21, 120), E4( 96, 123),\
+ E4( -30, 111), E4( -78, 93), E4( -69, 114), E2( 18, 18), E2( 33, 33),\
+ E2( 63, 63), E2( 108, 108)
+
+#define TAB_2_3 \
+ PD( 0, 0), E2( 4, 4), E4( 0, 4), E4( 4, 8), E2( 8, 8),\
+ E2( -8, 8), E4( -4, 12), E4( 8, 16), E2( 16, 16), E4( 0, 20),\
+ E4( -12, 16), E4( -4, 24), E4( 16, 32), E4( 8, 32), E2( 32, 32),\
+ E4( 0, 36), E2( -24, 24), E4( -16, 32), E4( 20, 52), E4( 36, 56),\
+ E4( -12, 44), E4( 8, 56), E2( 60, 60), E4( -4, 64), E4( -36, 44),\
+ E4( -28, 60), E4( 44, 92), E4( 24, 92), E4( 72, 96), E4( -20, 84),\
+ E4( 8, 100), E2( 108, 108), E2( -68, 68), E4( -56, 84), E4( -12, 120),\
+ E4( -48, 108), E4(-104, 124), E2( 24, 24), E2( 44, 44), E2( 84, 84)
+
+#define TAB_2_4 \
+ PD( 0, 0), E2( 5, 5), E4( 0, 5), E2( 10, 10), E4( 5, 15),\
+ E2( -10, 10), E4( -5, 15), E4( 10, 20), E2( 20, 20), E4( 0, 25),\
+ E4( -15, 20), E4( 25, 40), E4( -10, 30), E4( 10, 40), E2( 40, 40),\
+ E4( 0, 45), E2( -30, 30), E4( -20, 40), E4( 25, 65), E4( 45, 70),\
+ E4( -15, 55), E4( 10, 70), E2( 75, 75), E4( -5, 85), E4( -45, 55),\
+ E4( -35, 75), E4( 55, 115), E4( 30, 115), E4( 90, 120), E4( -30, 105),\
+ E2( -85, 85), E4( -70, 105), E2( 30, 30), E2( 60, 60), E2( 105, 105)
+
+#define TAB_2_5 \
+ PD( 0, 0), E2( 6, 6), E4( 0, 6), E2( 12, 12), E4( 6, 12),\
+ E2( -12, 12), E4( -6, 18), E4( 12, 24), E2( 24, 24), E4( 0, 30),\
+ E4( -18, 24), E4( 30, 48), E4( -6, 36), E4( 12, 48), E2( 48, 48),\
+ E4( 0, 54), E2( -36, 36), E4( -24, 48), E4( 30, 78), E4( 54, 84),\
+ E4( -18, 66), E4( 12, 84), E2( 90, 90), E4( -6, 96), E4( -54, 66),\
+ E4( -42, 90), E4( -30, 126), E2(-102, 102), E4( -84, 126), E2( 36, 36),\
+ E2( 66, 66)
+
+#define TAB_2_6 \
+ PD( 0, 0), E2( 7, 7), E4( 0, 7), E2( 14, 14), E4( 7, 21),\
+ E2( -14, 14), E4( -7, 21), E4( 14, 28), E2( 28, 28), E4( 0, 35),\
+ E4( -21, 28), E4( 35, 56), E4( -14, 42), E4( 14, 56), E2( 56, 56),\
+ E4( 0, 63), E2( -42, 42), E4( -28, 56), E4( 35, 91), E4( 63, 98),\
+ E4( -21, 77), E4( 14, 98), E2( 105, 105), E4( -7, 119), E4( -63, 77),\
+ E4( -49, 105), E2(-119, 119), E2( 42, 42), E2( 77, 77)
+
+#define TAB_2_7 \
+ PD( 0, 0), E2( 8, 8), E4( 0, 8), E2( 16, 16), E4( 8, 16),\
+ E2( -16, 16), E4( -8, 24), E4( 16, 32), E2( 32, 32), E4( 0, 40),\
+ E4( -24, 32), E4( 40, 64), E4( -16, 48), E4( 16, 64), E2( 64, 64),\
+ E4( 0, 72), E2( -48, 48), E4( -32, 64), E4( 40, 104), E4( 72, 112),\
+ E4( -24, 88), E4( 16, 112), E2( 120, 120), E4( -72, 88), E4( -56, 120),\
+ E2( 48, 48), E2( 88, 88)
+
+#define TAB_2_8 \
+ PD( 0, 0), E2( 9, 9), E4( 0, 9), E2( 18, 18), E4( 9, 27),\
+ E2( -18, 18), E4( -9, 27), E4( 18, 36), E2( 36, 36), E4( 0, 45),\
+ E4( -27, 36), E4( 45, 72), E4( -18, 54), E4( 18, 72), E2( 72, 72),\
+ E4( 0, 81), E2( -54, 54), E4( -36, 72), E4( 45, 117), E4( 81, 126),\
+ E4( -27, 99), E4( -81, 99), E2( 54, 54), E2( 108, 108)
+
+#define TAB_3_1 \
+ PD( 0, 0), E2( 2, 2), E4( 0, 3), E2( 6, 6), E4( 0, 7),\
+ E2( -5, 5), E2( 5, -5), E4( 6, 11), E4( 0, 8), E2( 11, 11),\
+ E4( 0, 12), E4( 12, 17), E2( 17, 17), E4( 6, 18), E4( -8, 11),\
+ E4( 0, 15), E4( 0, 20), E4( 18, 25), E4( 11, 25), E2( 25, 25),\
+ E2( -14, 14), E2( 14, -14), E4( 0, 26), E4( -11, 18), E4( -7, 22),\
+ E4( 26, 34), E4( 18, 34), E2( 34, 34), E4( 11, 35), E4( 0, 29),\
+ E4( -19, 22), E4( -15, 26), E4( 0, 37), E4( 27, 44), E4( 36, 44),\
+ E4( 18, 44), E4( -10, 33), E2( 45, 45)
+
+#define TAB_3_2 \
+ PD( 0, 0), E4( 0, 2), E2( 2, 2), E2( 6, 6), E4( 0, 6),\
+ E2( -4, 4), E2( 10, -6), E2( 0, -12), PD( -6, -12), E2( 6, -12),\
+ PD( 6, 12), E2( -14, 0), E2( 12, 12), E2( 0, -18), E2( 14, -12),\
+ PD( -18, -6), E2( 18, -6), PD( 18, 6), PD( -10, -18), E2( 10, -18),\
+ PD( 10, 18), E2( -22, 0), E2( 0, -24), PD( -22, -12), E2( 22, -12),\
+ PD( 22, 12), PD( -8, -24), E2( 8, -24), PD( 8, 24), PD( -26, -6),\
+ E2( 26, -6), PD( 26, 6), E2( -28, 0), E2( 20, 20), E2( -14, -26),\
+ E2( -30, -12), E2( -10, -32), E2( -18, -32), E2( -26, -26), E2( -34, -20),\
+ E2( -38, -12), E2( -32, -32), PD( 32, 32), PD( -22, -40), E2( -34, -34)
+
+#define TAB_3_3 \
+ PD( 0, 0), E4( 0, 2), E2( 4, 4), E2( 10, 10), E4( 0, 10),\
+ E2( -6, 6), E2( 14, -8), E2( -18, 0), E2( 10, -16), E2( 0, -24),\
+ PD( -24, -8), E2( 24, -8), PD( 24, 8), E2( 18, 18), E2( 20, -16),\
+ PD( -14, -26), E2( 14, -26), PD( 14, 26), E2( -30, 0), E2( 0, -34),\
+ PD( -34, -8), E2( 34, -8), PD( 34, 8), PD( -30, -18), E2( 30, -18),\
+ PD( 30, 18), PD( -10, -34), E2( 10, -34), PD( 10, 34), E2( -20, -34),\
+ E2( -40, 0), E2( 30, 30), E2( -40, -18), E2( 0, -44), E2( -16, -44),\
+ PD( -36, -36), E2( -36, -36), E2( -26, -44), E2( -46, -26), E2( -52, -18),\
+ PD( -20, -54), E2( -44, -44), PD( -32, -54), PD( -46, -46), E2( -46, -46)
+
+#define TAB_3_4 \
+ PD( 0, 0), E4( 0, 4), E2( 4, 4), E2( 12, 12), E4( 0, 12),\
+ E2( -8, 8), E2( 8, -16), E2( 0, -24), PD( -24, -8), E2( 24, -8),\
+ PD( 24, 8), E2( 20, -16), E2( -28, 0), PD( -16, -24), E2( 16, -24),\
+ PD( 16, 24), E2( 0, -32), PD( -28, -16), E2( 28, -16), PD( 28, 16),\
+ PD( -8, -32), PD( 8, -32), PD( -32, -8), E2( 32, -8), PD( 32, 8),\
+ PD( -8, 32), PD( 8, 32), E2( 24, 24), E2( 24, -24), E2( -20, -32),\
+ E2( -40, 0), E2( -40, -16), PD( 0, -44), PD( 0, -44), E2( -44, 0),\
+ PD( 0, 44), PD( 0, 44), E2( -32, -32), E2( -16, -44), PD( -24, -44),\
+ E2( -44, -24), PD( 24, 44), E2( -48, -16), PD( -36, -36), E2( -36, -36),\
+ PD( 36, 36), PD( -20, -52), E2( 40, 40), PD( -32, -52)
+
+#define TAB_3_5 \
+ PD( 0, 0), E2( 2, 2), E2( 6, 6), E2( 12, 12), E2( 20, 20),\
+ E2( 32, 32), E2( 46, 46)
+
+
+/**
+ * Pack two delta values (a,b) into one 16bit word
+ * according with endianess of the host machine.
+ */
+#if HAVE_BIGENDIAN
+#define PD(a,b) (((a) << 8) + (b))
+#else
+#define PD(a,b) (((b) << 8) + (a))
+#endif
+
+/**
+ * Expand a pair of delta values (a,b)
+ * into two/four delta entries.
+ */
+#define E2(a, b) PD(a, b), PD(-a, -b)
+#define E4(a, b) PD(a, b), PD(-a, -b), PD(b, a), PD(-b, -a)
+
+/*
+ * VQ tables for 4x4 block modes.
+ * Let the compiler decompress and build the tables for us.
+ */
+static const int16_t delta_tab_1_1[195] = { TAB_1_1 };
+static const int16_t delta_tab_1_2[159] = { TAB_1_2 };
+static const int16_t delta_tab_1_3[133] = { TAB_1_3 };
+static const int16_t delta_tab_1_4[115] = { TAB_1_4 };
+static const int16_t delta_tab_1_5[101] = { TAB_1_5 };
+static const int16_t delta_tab_1_6[93] = { TAB_1_6 };
+static const int16_t delta_tab_1_7[87] = { TAB_1_7 };
+static const int16_t delta_tab_1_8[77] = { TAB_1_8 };
+
+static const int16_t delta_tab_2_1[195] = { TAB_2_1 };
+static const int16_t delta_tab_2_2[159] = { TAB_2_2 };
+static const int16_t delta_tab_2_3[133] = { TAB_2_3 };
+static const int16_t delta_tab_2_4[115] = { TAB_2_4 };
+static const int16_t delta_tab_2_5[101] = { TAB_2_5 };
+static const int16_t delta_tab_2_6[93] = { TAB_2_6 };
+static const int16_t delta_tab_2_7[87] = { TAB_2_7 };
+static const int16_t delta_tab_2_8[77] = { TAB_2_8 };
+
+static const int16_t delta_tab_3_1[128] = { TAB_3_1 };
+static const int16_t delta_tab_3_2[79] = { TAB_3_2 };
+static const int16_t delta_tab_3_3[79] = { TAB_3_3 };
+static const int16_t delta_tab_3_4[79] = { TAB_3_4 };
+static const int16_t delta_tab_3_5[79] = { TAB_3_5 };
+
+#undef PD
+
+/**
+ * Pack four delta values (a,a,b,b) into one 32bit word
+ * according with endianess of the host machine.
+ */
+#if HAVE_BIGENDIAN
+#define PD(a,b) (((a) << 24) + ((a) << 16) + ((b) << 8) + (b))
+#else
+#define PD(a,b) (((b) << 24) + ((b) << 16) + ((a) << 8) + (a))
+#endif
+
+/*
+ * VQ tables for 8x8 block modes.
+ * Those are based on the same delta tables by using
+ * each value twice: ABCD --> AABBCCDD.
+ */
+static const int32_t delta_tab_1_1_m10[195] = { TAB_1_1 };
+static const int32_t delta_tab_1_2_m10[159] = { TAB_1_2 };
+static const int32_t delta_tab_1_3_m10[133] = { TAB_1_3 };
+static const int32_t delta_tab_1_4_m10[115] = { TAB_1_4 };
+static const int32_t delta_tab_1_5_m10[101] = { TAB_1_5 };
+static const int32_t delta_tab_1_6_m10[93] = { TAB_1_6 };
+static const int32_t delta_tab_1_7_m10[87] = { TAB_1_7 };
+static const int32_t delta_tab_1_8_m10[77] = { TAB_1_8 };
+
+static const int32_t delta_tab_2_1_m10[195] = { TAB_2_1 };
+static const int32_t delta_tab_2_2_m10[159] = { TAB_2_2 };
+static const int32_t delta_tab_2_3_m10[133] = { TAB_2_3 };
+static const int32_t delta_tab_2_4_m10[115] = { TAB_2_4 };
+static const int32_t delta_tab_2_5_m10[101] = { TAB_2_5 };
+static const int32_t delta_tab_2_6_m10[93] = { TAB_2_6 };
+static const int32_t delta_tab_2_7_m10[87] = { TAB_2_7 };
+static const int32_t delta_tab_2_8_m10[77] = { TAB_2_8 };
+
+static const int32_t delta_tab_3_1_m10[128] = { TAB_3_1 };
+static const int32_t delta_tab_3_2_m10[79] = { TAB_3_2 };
+static const int32_t delta_tab_3_3_m10[79] = { TAB_3_3 };
+static const int32_t delta_tab_3_4_m10[79] = { TAB_3_4 };
+static const int32_t delta_tab_3_5_m10[79] = { TAB_3_5 };
+
+
+typedef struct {
+ const int16_t *deltas; ///< delta tables for 4x4 block modes
+ const int32_t *deltas_m10; ///< delta tables for 8x8 block modes
+ uint8_t num_dyads; ///< number of two-pixel deltas
+ uint8_t quad_exp; ///< log2 of four-pixel deltas
+} vqEntry;
+
+static const vqEntry vq_tab[24] = {
+ /* set 1 */
+ { delta_tab_1_1, delta_tab_1_1_m10, 195, 7 },
+ { delta_tab_1_2, delta_tab_1_2_m10, 159, 9 },
+ { delta_tab_1_3, delta_tab_1_3_m10, 133, 10 },
+ { delta_tab_1_4, delta_tab_1_4_m10, 115, 11 },
+ { delta_tab_1_5, delta_tab_1_5_m10, 101, 12 },
+ { delta_tab_1_6, delta_tab_1_6_m10, 93, 12 },
+ { delta_tab_1_7, delta_tab_1_7_m10, 87, 12 },
+ { delta_tab_1_8, delta_tab_1_8_m10, 77, 13 },
+ /* set 2 */
+ { delta_tab_2_1, delta_tab_2_1_m10, 195, 7 },
+ { delta_tab_2_2, delta_tab_2_2_m10, 159, 9 },
+ { delta_tab_2_3, delta_tab_2_3_m10, 133, 10 },
+ { delta_tab_2_4, delta_tab_2_4_m10, 115, 11 },
+ { delta_tab_2_5, delta_tab_2_5_m10, 101, 12 },
+ { delta_tab_2_6, delta_tab_2_6_m10, 93, 12 },
+ { delta_tab_2_7, delta_tab_2_7_m10, 87, 12 },
+ { delta_tab_2_8, delta_tab_2_8_m10, 77, 13 },
-static const uint32_t correctionhighorder[] = {
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101,
- 0xfeff0303, 0x0100fcfd, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303,
- 0x0100fcfd, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, 0x00000000, 0x02020202, 0xfdfdfdfe,
- 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9,
- 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707,
- 0xf8f8f8f9, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc,
- 0x07070707, 0xf8f8f8f9, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404,
- 0x0100fbfc, 0x07070707, 0xf8f8f8f9, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101,
- 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff,
- 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9, 0x00000000, 0x03030303, 0xfcfcfcfd,
- 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9, 0x00000000, 0x03030303,
- 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9, 0x00000000,
- 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x04040404, 0xfbfbfbfc,
- 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000,
- 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd,
- 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb,
- 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101,
- 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc,
- 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000,
- 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd,
- 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb,
- 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101,
- 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc,
- 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000,
- 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd,
- 0x03030a0a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202,
- 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505,
- 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303,
- 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9,
- 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe,
- 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000,
- 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5,
- 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707,
- 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb,
- 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd,
- 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b,
- 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202,
- 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505,
- 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303,
- 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9,
- 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc,
- 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8,
- 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc,
- 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8,
- 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc,
- 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8,
- 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc,
- 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8,
- 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc,
- 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8,
- 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc,
- 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8,
- 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb,
- 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6,
- 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb,
- 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6,
- 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb,
- 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6,
- 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb,
- 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6,
- 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb,
- 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6,
- 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb,
- 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6,
- 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee,
- 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303,
- 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee,
- 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303,
- 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee,
- 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303,
- 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee,
- 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303,
- 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee,
- 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303,
- 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee,
- 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303,
- 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x09090909, 0xf6f6f6f7,
- 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa,
- 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c,
- 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000,
- 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec,
- 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd,
- 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717,
- 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4,
- 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909,
- 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606,
- 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303,
- 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9,
- 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414,
- 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7,
- 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa,
- 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c,
- 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000,
- 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec,
- 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd,
- 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717,
- 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4,
- 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000,
- 0x00000202, 0xfffffdfe, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202,
- 0xfffffdfe, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe,
- 0x00000000, 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x00000000,
- 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x00000000, 0x02020202,
- 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x00000000, 0x02020202, 0xfdfdfdfe,
- 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa,
- 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606,
- 0xf9f9f9fa, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd,
- 0x06060606, 0xf9f9f9fa, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303,
- 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000,
- 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000,
- 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x00000000, 0x03030303, 0xfcfcfcfd,
- 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x00000000, 0x03030303,
- 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x00000000,
- 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x04040404, 0xfbfbfbfc,
- 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000,
- 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc,
- 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc,
- 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000,
- 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc,
- 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000,
- 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc,
- 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc,
- 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000,
- 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc,
- 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000,
- 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc,
- 0x04040808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000,
- 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505,
- 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505,
- 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb,
- 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000,
- 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000,
- 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6,
- 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505,
- 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb,
- 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb,
- 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a,
- 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000,
- 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505,
- 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505,
- 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb,
- 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa,
- 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa,
- 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa,
- 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa,
- 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa,
- 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa,
- 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa,
- 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa,
- 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9,
- 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9,
- 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9,
- 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9,
- 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9,
- 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9,
- 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9,
- 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9,
- 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9,
- 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9,
- 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9,
- 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9,
- 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9,
- 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0,
- 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000,
- 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0,
- 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000,
- 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0,
- 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000,
- 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0,
- 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000,
- 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0,
- 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000,
- 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000,
- 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0,
- 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000,
- 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x09090909, 0xf6f6f6f7,
- 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7,
- 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909,
- 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000,
- 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee,
- 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000,
- 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b,
- 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7,
- 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909,
- 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909,
- 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000,
- 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5,
- 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212,
- 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7,
- 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7,
- 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909,
- 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000,
- 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee,
- 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000,
- 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b,
- 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7,
- 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe,
- 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe,
- 0xfdfdfdfe, 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0x03030000,
- 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000,
- 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0x00000303,
- 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0x00000303,
- 0x00000303, 0x00000303, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd,
- 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0x06060606, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000,
- 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0xf8f90000, 0xf8f90000,
- 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000,
- 0xf8f90000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020000, 0x02020000, 0x02020000, 0x02020000,
- 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000,
- 0x02020000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000,
- 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0x00000202, 0x00000202,
- 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202,
- 0x00000202, 0x00000202, 0x00000202, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe,
- 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe,
- 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe,
- 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe,
- 0xfdfdfdfe, 0xfdfdfdfe, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0x06060000, 0x06060000, 0x06060000, 0x06060000,
- 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000,
- 0x06060000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000,
- 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0x00000606, 0x00000606,
- 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606,
- 0x00000606, 0x00000606, 0x00000606, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa,
- 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020000, 0x02020000, 0x02020000, 0x02020000,
- 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000,
- 0x02020000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000,
- 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0x00000202, 0x00000202,
- 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202,
- 0x00000202, 0x00000202, 0x00000202, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe,
- 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe,
- 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404,
- 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc,
- 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc,
- 0xfbfbfbfc, 0xfbfbfbfc, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a,
- 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0xf5f5f5f6,
- 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6,
- 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000,
- 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000,
- 0x0a0a0000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000,
- 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0x00000a0a, 0x00000a0a,
- 0x00000a0a, 0x00000a0a, 0x00000a0a, 0x00000a0a, 0x00000a0a, 0x00000a0a, 0x00000a0a, 0x00000a0a,
- 0x00000a0a, 0x00000a0a, 0x00000a0a, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6,
- 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04040000, 0x04040000, 0x04040000, 0x04040000,
- 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000,
- 0x04040000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000,
- 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0x00000404, 0x00000404,
- 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404,
- 0x00000404, 0x00000404, 0x00000404, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc,
- 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc,
- 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404,
- 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc,
- 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc,
- 0xfbfbfbfc, 0xfbfbfbfc, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
- 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000,
- 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000,
- 0x0c0c0000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000,
- 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0x00000c0c, 0x00000c0c,
- 0x00000c0c, 0x00000c0c, 0x00000c0c, 0x00000c0c, 0x00000c0c, 0x00000c0c, 0x00000c0c, 0x00000c0c,
- 0x00000c0c, 0x00000c0c, 0x00000c0c, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4,
- 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe,
- 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
- 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414,
- 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0xebebebec,
- 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec,
- 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
- 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
- 0x20202020, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0,
- 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0x2e2e2e2e, 0x2e2e2e2e,
- 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e,
- 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2,
- 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe,
- 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
- 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414,
- 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0xebebebec,
- 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec,
- 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
- 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
- 0x20202020, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0,
- 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0x2e2e2e2e, 0x2e2e2e2e,
- 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e,
- 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2,
- 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe,
- 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
- 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414,
- 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0xebebebec,
- 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec,
- 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
- 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
- 0x20202020, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0,
- 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0x2e2e2e2e, 0x2e2e2e2e,
- 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e,
- 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2,
- 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
- 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202,
- 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe,
- 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
- 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa,
- 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
- 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4,
- 0xf3f3f3f4, 0xf3f3f3f4, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414,
- 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0xebebebec,
- 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec,
- 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
- 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
- 0x20202020, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0,
- 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0x2e2e2e2e, 0x2e2e2e2e,
- 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e,
- 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2,
- 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
+ /* set 3 */
+ { delta_tab_3_1, delta_tab_3_1_m10, 128, 11 },
+ { delta_tab_3_2, delta_tab_3_2_m10, 79, 13 },
+ { delta_tab_3_3, delta_tab_3_3_m10, 79, 13 },
+ { delta_tab_3_4, delta_tab_3_4_m10, 79, 13 },
+ { delta_tab_3_5, delta_tab_3_5_m10, 79, 13 },
+ { delta_tab_3_5, delta_tab_3_5_m10, 79, 13 },
+ { delta_tab_3_5, delta_tab_3_5_m10, 79, 13 },
+ { delta_tab_3_5, delta_tab_3_5_m10, 79, 13 }
};
#endif /* AVCODEC_INDEO3DATA_H */
diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c
new file mode 100644
index 0000000..e816330
--- /dev/null
+++ b/libavcodec/indeo4.c
@@ -0,0 +1,826 @@
+/*
+ * Indeo Video Interactive v4 compatible decoder
+ * Copyright (c) 2009-2011 Maxim Poliakovski
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Indeo Video Interactive version 4 decoder
+ *
+ * Indeo 4 data is usually transported within .avi or .mov files.
+ * Known FOURCCs: 'IV41'
+ */
+
+#define BITSTREAM_READER_LE
+#include "avcodec.h"
+#include "get_bits.h"
+#include "dsputil.h"
+#include "ivi_dsp.h"
+#include "ivi_common.h"
+#include "indeo4data.h"
+
+#define IVI4_STREAM_ANALYSER 0
+#define IVI4_DEBUG_CHECKSUM 0
+
+/**
+ * Indeo 4 frame types.
+ */
+enum {
+ FRAMETYPE_INTRA = 0,
+ FRAMETYPE_BIDIR1 = 1, ///< bidirectional frame
+ FRAMETYPE_INTER = 2, ///< non-droppable P-frame
+ FRAMETYPE_BIDIR = 3, ///< bidirectional frame
+ FRAMETYPE_INTER_NOREF = 4, ///< droppable P-frame
+ FRAMETYPE_NULL_FIRST = 5, ///< empty frame with no data
+ FRAMETYPE_NULL_LAST = 6 ///< empty frame with no data
+};
+
+#define IVI4_PIC_SIZE_ESC 7
+
+
+typedef struct {
+ GetBitContext gb;
+ AVFrame frame;
+ RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables
+
+ uint32_t frame_num;
+ int frame_type;
+ int prev_frame_type; ///< frame type of the previous frame
+ uint32_t data_size; ///< size of the frame data in bytes from picture header
+ int is_scalable;
+ int transp_status; ///< transparency mode status: 1 - enabled
+
+ IVIPicConfig pic_conf;
+ IVIPlaneDesc planes[3]; ///< color planes
+
+ int buf_switch; ///< used to switch between three buffers
+ int dst_buf; ///< buffer index for the currently decoded frame
+ int ref_buf; ///< inter frame reference buffer index
+
+ IVIHuffTab mb_vlc; ///< current macroblock table descriptor
+ IVIHuffTab blk_vlc; ///< current block table descriptor
+
+ uint16_t checksum; ///< frame checksum
+
+ uint8_t rvmap_sel;
+ uint8_t in_imf;
+ uint8_t in_q; ///< flag for explicitly stored quantiser delta
+ uint8_t pic_glob_quant;
+ uint8_t unknown1;
+
+#if IVI4_STREAM_ANALYSER
+ uint8_t has_b_frames;
+ uint8_t has_transp;
+ uint8_t uses_tiling;
+ uint8_t uses_haar;
+ uint8_t uses_fullpel;
+#endif
+} IVI4DecContext;
+
+
+struct {
+ InvTransformPtr *inv_trans;
+ DCTransformPtr *dc_trans;
+ int is_2d_trans;
+} transforms[18] = {
+ { ff_ivi_inverse_haar_8x8, ff_ivi_dc_haar_2d, 1 },
+ { NULL, NULL, 0 }, /* inverse Haar 8x1 */
+ { NULL, NULL, 0 }, /* inverse Haar 1x8 */
+ { ff_ivi_put_pixels_8x8, ff_ivi_put_dc_pixel_8x8, 1 },
+ { ff_ivi_inverse_slant_8x8, ff_ivi_dc_slant_2d, 1 },
+ { ff_ivi_row_slant8, ff_ivi_dc_row_slant, 1 },
+ { ff_ivi_col_slant8, ff_ivi_dc_col_slant, 1 },
+ { NULL, NULL, 0 }, /* inverse DCT 8x8 */
+ { NULL, NULL, 0 }, /* inverse DCT 8x1 */
+ { NULL, NULL, 0 }, /* inverse DCT 1x8 */
+ { NULL, NULL, 0 }, /* inverse Haar 4x4 */
+ { ff_ivi_inverse_slant_4x4, ff_ivi_dc_slant_2d, 1 },
+ { NULL, NULL, 0 }, /* no transform 4x4 */
+ { NULL, NULL, 0 }, /* inverse Haar 1x4 */
+ { NULL, NULL, 0 }, /* inverse Haar 4x1 */
+ { NULL, NULL, 0 }, /* inverse slant 1x4 */
+ { NULL, NULL, 0 }, /* inverse slant 4x1 */
+ { NULL, NULL, 0 }, /* inverse DCT 4x4 */
+};
+
+/**
+ * Decode subdivision of a plane.
+ * This is a simplified version that checks for two supported subdivisions:
+ * - 1 wavelet band per plane, size factor 1:1, code pattern: 3
+ * - 4 wavelet bands per plane, size factor 1:4, code pattern: 2,3,3,3,3
+ * Anything else is either unsupported or corrupt.
+ *
+ * @param[in,out] gb the GetBit context
+ * @return number of wavelet bands or 0 on error
+ */
+static int decode_plane_subdivision(GetBitContext *gb)
+{
+ int i;
+
+ switch (get_bits(gb, 2)) {
+ case 3:
+ return 1;
+ case 2:
+ for (i = 0; i < 4; i++)
+ if (get_bits(gb, 2) != 3)
+ return 0;
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+static inline int scale_tile_size(int def_size, int size_factor)
+{
+ return (size_factor == 15 ? def_size : (size_factor + 1) << 5);
+}
+
+/**
+ * Decode Indeo 4 picture header.
+ *
+ * @param[in,out] ctx pointer to the decoder context
+ * @param[in] avctx pointer to the AVCodecContext
+ * @return result code: 0 = OK, negative number = error
+ */
+static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx)
+{
+ int pic_size_indx, i, p;
+ IVIPicConfig pic_conf;
+
+ if (get_bits(&ctx->gb, 18) != 0x3FFF8) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ctx->prev_frame_type = ctx->frame_type;
+ ctx->frame_type = get_bits(&ctx->gb, 3);
+ if (ctx->frame_type == 7) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d\n", ctx->frame_type);
+ return AVERROR_INVALIDDATA;
+ }
+
+#if IVI4_STREAM_ANALYSER
+ if ( ctx->frame_type == FRAMETYPE_BIDIR1
+ || ctx->frame_type == FRAMETYPE_BIDIR)
+ ctx->has_b_frames = 1;
+#endif
+
+ ctx->transp_status = get_bits1(&ctx->gb);
+#if IVI4_STREAM_ANALYSER
+ if (ctx->transp_status) {
+ ctx->has_transp = 1;
+ }
+#endif
+
+ /* unknown bit: Mac decoder ignores this bit, XANIM returns error */
+ if (get_bits1(&ctx->gb)) {
+ av_log(avctx, AV_LOG_ERROR, "Sync bit is set!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ctx->data_size = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 24) : 0;
+
+ /* null frames don't contain anything else so we just return */
+ if (ctx->frame_type >= FRAMETYPE_NULL_FIRST) {
+ av_dlog(avctx, "Null frame encountered!\n");
+ return 0;
+ }
+
+ /* Check key lock status. If enabled - ignore lock word. */
+ /* Usually we have to prompt the user for the password, but */
+ /* we don't do that because Indeo 4 videos can be decoded anyway */
+ if (get_bits1(&ctx->gb)) {
+ skip_bits_long(&ctx->gb, 32);
+ av_dlog(avctx, "Password-protected clip!\n");
+ }
+
+ pic_size_indx = get_bits(&ctx->gb, 3);
+ if (pic_size_indx == IVI4_PIC_SIZE_ESC) {
+ pic_conf.pic_height = get_bits(&ctx->gb, 16);
+ pic_conf.pic_width = get_bits(&ctx->gb, 16);
+ } else {
+ pic_conf.pic_height = ivi4_common_pic_sizes[pic_size_indx * 2 + 1];
+ pic_conf.pic_width = ivi4_common_pic_sizes[pic_size_indx * 2 ];
+ }
+
+ /* Decode tile dimensions. */
+ if (get_bits1(&ctx->gb)) {
+ pic_conf.tile_height = scale_tile_size(pic_conf.pic_height, get_bits(&ctx->gb, 4));
+ pic_conf.tile_width = scale_tile_size(pic_conf.pic_width, get_bits(&ctx->gb, 4));
+#if IVI4_STREAM_ANALYSER
+ ctx->uses_tiling = 1;
+#endif
+ } else {
+ pic_conf.tile_height = pic_conf.pic_height;
+ pic_conf.tile_width = pic_conf.pic_width;
+ }
+
+ /* Decode chroma subsampling. We support only 4:4 aka YVU9. */
+ if (get_bits(&ctx->gb, 2)) {
+ av_log(avctx, AV_LOG_ERROR, "Only YVU9 picture format is supported!\n");
+ return AVERROR_INVALIDDATA;
+ }
+ pic_conf.chroma_height = (pic_conf.pic_height + 3) >> 2;
+ pic_conf.chroma_width = (pic_conf.pic_width + 3) >> 2;
+
+ /* decode subdivision of the planes */
+ pic_conf.luma_bands = decode_plane_subdivision(&ctx->gb);
+ if (pic_conf.luma_bands)
+ pic_conf.chroma_bands = decode_plane_subdivision(&ctx->gb);
+ ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1;
+ if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n",
+ pic_conf.luma_bands, pic_conf.chroma_bands);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* check if picture layout was changed and reallocate buffers */
+ if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) {
+ if (ff_ivi_init_planes(ctx->planes, &pic_conf)) {
+ av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n");
+ return AVERROR(ENOMEM);
+ }
+
+ ctx->pic_conf = pic_conf;
+
+ /* set default macroblock/block dimensions */
+ for (p = 0; p <= 2; p++) {
+ for (i = 0; i < (!p ? pic_conf.luma_bands : pic_conf.chroma_bands); i++) {
+ ctx->planes[p].bands[i].mb_size = !p ? (!ctx->is_scalable ? 16 : 8) : 4;
+ ctx->planes[p].bands[i].blk_size = !p ? 8 : 4;
+ }
+ }
+
+ if (ff_ivi_init_tiles(ctx->planes, ctx->pic_conf.tile_width,
+ ctx->pic_conf.tile_height)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Couldn't reallocate internal structures!\n");
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ ctx->frame_num = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 20) : 0;
+
+ /* skip decTimeEst field if present */
+ if (get_bits1(&ctx->gb))
+ skip_bits(&ctx->gb, 8);
+
+ /* decode macroblock and block huffman codebooks */
+ if (ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_MB_HUFF, &ctx->mb_vlc, avctx) ||
+ ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_BLK_HUFF, &ctx->blk_vlc, avctx))
+ return AVERROR_INVALIDDATA;
+
+ ctx->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8;
+
+ ctx->in_imf = get_bits1(&ctx->gb);
+ ctx->in_q = get_bits1(&ctx->gb);
+
+ ctx->pic_glob_quant = get_bits(&ctx->gb, 5);
+
+ /* TODO: ignore this parameter if unused */
+ ctx->unknown1 = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 0;
+
+ ctx->checksum = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 16) : 0;
+
+ /* skip picture header extension if any */
+ while (get_bits1(&ctx->gb)) {
+ av_dlog(avctx, "Pic hdr extension encountered!\n");
+ skip_bits(&ctx->gb, 8);
+ }
+
+ if (get_bits1(&ctx->gb)) {
+ av_log(avctx, AV_LOG_ERROR, "Bad blocks bits encountered!\n");
+ }
+
+ align_get_bits(&ctx->gb);
+
+ return 0;
+}
+
+
+/**
+ * Decode Indeo 4 band header.
+ *
+ * @param[in,out] ctx pointer to the decoder context
+ * @param[in,out] band pointer to the band descriptor
+ * @param[in] avctx pointer to the AVCodecContext
+ * @return result code: 0 = OK, negative number = error
+ */
+static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
+ AVCodecContext *avctx)
+{
+ int plane, band_num, indx, transform_id, scan_indx;
+ int i;
+
+ plane = get_bits(&ctx->gb, 2);
+ band_num = get_bits(&ctx->gb, 4);
+ if (band->plane != plane || band->band_num != band_num) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid band header sequence!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ band->is_empty = get_bits1(&ctx->gb);
+ if (!band->is_empty) {
+ /* skip header size
+ * If header size is not given, header size is 4 bytes. */
+ if (get_bits1(&ctx->gb))
+ skip_bits(&ctx->gb, 16);
+
+ band->is_halfpel = get_bits(&ctx->gb, 2);
+ if (band->is_halfpel >= 2) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid/unsupported mv resolution: %d!\n",
+ band->is_halfpel);
+ return AVERROR_INVALIDDATA;
+ }
+#if IVI4_STREAM_ANALYSER
+ if (!band->is_halfpel)
+ ctx->uses_fullpel = 1;
+#endif
+
+ band->checksum_present = get_bits1(&ctx->gb);
+ if (band->checksum_present)
+ band->checksum = get_bits(&ctx->gb, 16);
+
+ indx = get_bits(&ctx->gb, 2);
+ if (indx == 3) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid block size!\n");
+ return AVERROR_INVALIDDATA;
+ }
+ band->mb_size = 16 >> indx;
+ band->blk_size = 8 >> (indx >> 1);
+
+ band->inherit_mv = get_bits1(&ctx->gb);
+ band->inherit_qdelta = get_bits1(&ctx->gb);
+
+ band->glob_quant = get_bits(&ctx->gb, 5);
+
+ if (!get_bits1(&ctx->gb) || ctx->frame_type == FRAMETYPE_INTRA) {
+ transform_id = get_bits(&ctx->gb, 5);
+ if (!transforms[transform_id].inv_trans) {
+ av_log_ask_for_sample(avctx, "Unimplemented transform: %d!\n", transform_id);
+ return AVERROR_PATCHWELCOME;
+ }
+ if ((transform_id >= 7 && transform_id <= 9) ||
+ transform_id == 17) {
+ av_log_ask_for_sample(avctx, "DCT transform not supported yet!\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+#if IVI4_STREAM_ANALYSER
+ if ((transform_id >= 0 && transform_id <= 2) || transform_id == 10)
+ ctx->uses_haar = 1;
+#endif
+
+ band->inv_transform = transforms[transform_id].inv_trans;
+ band->dc_transform = transforms[transform_id].dc_trans;
+ band->is_2d_trans = transforms[transform_id].is_2d_trans;
+
+ scan_indx = get_bits(&ctx->gb, 4);
+ if (scan_indx == 15) {
+ av_log(avctx, AV_LOG_ERROR, "Custom scan pattern encountered!\n");
+ return AVERROR_INVALIDDATA;
+ }
+ band->scan = scan_index_to_tab[scan_indx];
+
+ band->quant_mat = get_bits(&ctx->gb, 5);
+ if (band->quant_mat == 31) {
+ av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ /* decode block huffman codebook */
+ if (ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_BLK_HUFF,
+ &band->blk_vlc, avctx))
+ return AVERROR_INVALIDDATA;
+
+ /* select appropriate rvmap table for this band */
+ band->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8;
+
+ /* decode rvmap probability corrections if any */
+ band->num_corr = 0; /* there is no corrections */
+ if (get_bits1(&ctx->gb)) {
+ band->num_corr = get_bits(&ctx->gb, 8); /* get number of correction pairs */
+ if (band->num_corr > 61) {
+ av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n",
+ band->num_corr);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* read correction pairs */
+ for (i = 0; i < band->num_corr * 2; i++)
+ band->corr[i] = get_bits(&ctx->gb, 8);
+ }
+ }
+
+ if (band->blk_size == 8) {
+ band->intra_base = &ivi4_quant_8x8_intra[quant_index_to_tab[band->quant_mat]][0];
+ band->inter_base = &ivi4_quant_8x8_inter[quant_index_to_tab[band->quant_mat]][0];
+ } else {
+ band->intra_base = &ivi4_quant_4x4_intra[quant_index_to_tab[band->quant_mat]][0];
+ band->inter_base = &ivi4_quant_4x4_inter[quant_index_to_tab[band->quant_mat]][0];
+ }
+
+ /* Indeo 4 doesn't use scale tables */
+ band->intra_scale = NULL;
+ band->inter_scale = NULL;
+
+ align_get_bits(&ctx->gb);
+
+ return 0;
+}
+
+
+/**
+ * Decode information (block type, cbp, quant delta, motion vector)
+ * for all macroblocks in the current tile.
+ *
+ * @param[in,out] ctx pointer to the decoder context
+ * @param[in,out] band pointer to the band descriptor
+ * @param[in,out] tile pointer to the tile descriptor
+ * @param[in] avctx pointer to the AVCodecContext
+ * @return result code: 0 = OK, negative number = error
+ */
+static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
+ IVITile *tile, AVCodecContext *avctx)
+{
+ int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb,
+ mv_scale, mb_type_bits;
+ IVIMbInfo *mb, *ref_mb;
+ int row_offset = band->mb_size * band->pitch;
+
+ mb = tile->mbs;
+ ref_mb = tile->ref_mbs;
+ offs = tile->ypos * band->pitch + tile->xpos;
+
+ blks_per_mb = band->mb_size != band->blk_size ? 4 : 1;
+ mb_type_bits = ctx->frame_type == FRAMETYPE_BIDIR ? 2 : 1;
+
+ /* scale factor for motion vectors */
+ mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);
+ mv_x = mv_y = 0;
+
+ for (y = tile->ypos; y < tile->ypos + tile->height; y += band->mb_size) {
+ mb_offset = offs;
+
+ for (x = tile->xpos; x < tile->xpos + tile->width; x += band->mb_size) {
+ mb->xpos = x;
+ mb->ypos = y;
+ mb->buf_offs = mb_offset;
+
+ if (get_bits1(&ctx->gb)) {
+ if (ctx->frame_type == FRAMETYPE_INTRA) {
+ av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n");
+ return AVERROR_INVALIDDATA;
+ }
+ mb->type = 1; /* empty macroblocks are always INTER */
+ mb->cbp = 0; /* all blocks are empty */
+
+ mb->q_delta = 0;
+ if (!band->plane && !band->band_num && ctx->in_q) {
+ mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,
+ IVI_VLC_BITS, 1);
+ mb->q_delta = IVI_TOSIGNED(mb->q_delta);
+ }
+
+ mb->mv_x = mb->mv_y = 0; /* no motion vector coded */
+ if (band->inherit_mv) {
+ /* motion vector inheritance */
+ if (mv_scale) {
+ mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
+ mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);
+ } else {
+ mb->mv_x = ref_mb->mv_x;
+ mb->mv_y = ref_mb->mv_y;
+ }
+ }
+ } else {
+ if (band->inherit_mv) {
+ mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
+ } else if (ctx->frame_type == FRAMETYPE_INTRA) {
+ mb->type = 0; /* mb_type is always INTRA for intra-frames */
+ } else {
+ mb->type = get_bits(&ctx->gb, mb_type_bits);
+ }
+
+ mb->cbp = get_bits(&ctx->gb, blks_per_mb);
+
+ mb->q_delta = 0;
+ if (band->inherit_qdelta) {
+ if (ref_mb) mb->q_delta = ref_mb->q_delta;
+ } else if (mb->cbp || (!band->plane && !band->band_num &&
+ ctx->in_q)) {
+ mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,
+ IVI_VLC_BITS, 1);
+ mb->q_delta = IVI_TOSIGNED(mb->q_delta);
+ }
+
+ if (!mb->type) {
+ mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */
+ } else {
+ if (band->inherit_mv) {
+ /* motion vector inheritance */
+ if (mv_scale) {
+ mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
+ mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);
+ } else {
+ mb->mv_x = ref_mb->mv_x;
+ mb->mv_y = ref_mb->mv_y;
+ }
+ } else {
+ /* decode motion vector deltas */
+ mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,
+ IVI_VLC_BITS, 1);
+ mv_y += IVI_TOSIGNED(mv_delta);
+ mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,
+ IVI_VLC_BITS, 1);
+ mv_x += IVI_TOSIGNED(mv_delta);
+ mb->mv_x = mv_x;
+ mb->mv_y = mv_y;
+ }
+ }
+ }
+
+ mb++;
+ if (ref_mb)
+ ref_mb++;
+ mb_offset += band->mb_size;
+ }
+
+ offs += row_offset;
+ }
+
+ align_get_bits(&ctx->gb);
+
+ return 0;
+}
+
+
+/**
+ * Decode an Indeo 4 band.
+ *
+ * @param[in,out] ctx pointer to the decoder context
+ * @param[in,out] band pointer to the band descriptor
+ * @param[in] avctx pointer to the AVCodecContext
+ * @return result code: 0 = OK, negative number = error
+ */
+static int decode_band(IVI4DecContext *ctx, int plane_num,
+ IVIBandDesc *band, AVCodecContext *avctx)
+{
+ int result, i, t, pos, idx1, idx2;
+ IVITile *tile;
+
+ band->buf = band->bufs[ctx->dst_buf];
+ band->ref_buf = band->bufs[ctx->ref_buf];
+
+ result = decode_band_hdr(ctx, band, avctx);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding band header\n");
+ return result;
+ }
+
+ if (band->is_empty) {
+ av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];
+
+ /* apply corrections to the selected rvmap table if present */
+ for (i = 0; i < band->num_corr; i++) {
+ idx1 = band->corr[i * 2];
+ idx2 = band->corr[i * 2 + 1];
+ FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
+ FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
+ }
+
+ pos = get_bits_count(&ctx->gb);
+
+ for (t = 0; t < band->num_tiles; t++) {
+ tile = &band->tiles[t];
+
+ tile->is_empty = get_bits1(&ctx->gb);
+ if (tile->is_empty) {
+ ff_ivi_process_empty_tile(avctx, band, tile,
+ (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
+ av_dlog(avctx, "Empty tile encountered!\n");
+ } else {
+ tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
+ if (!tile->data_size) {
+ av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ result = decode_mb_info(ctx, band, tile, avctx);
+ if (result < 0)
+ break;
+
+ result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
+ if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) {
+ av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n");
+ break;
+ }
+
+ pos += tile->data_size << 3; // skip to next tile
+ }
+ }
+
+ /* restore the selected rvmap table by applying its corrections in reverse order */
+ for (i = band->num_corr - 1; i >= 0; i--) {
+ idx1 = band->corr[i * 2];
+ idx2 = band->corr[i * 2 + 1];
+ FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
+ FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
+ }
+
+#if defined(DEBUG) && IVI4_DEBUG_CHECKSUM
+ if (band->checksum_present) {
+ uint16_t chksum = ivi_calc_band_checksum(band);
+ if (chksum != band->checksum) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",
+ band->plane, band->band_num, band->checksum, chksum);
+ }
+ }
+#endif
+
+ align_get_bits(&ctx->gb);
+
+ return 0;
+}
+
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ IVI4DecContext *ctx = avctx->priv_data;
+
+ ff_ivi_init_static_vlc();
+
+ /* copy rvmap tables in our context so we can apply changes to them */
+ memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs));
+
+ /* Force allocation of the internal buffers */
+ /* during picture header decoding. */
+ ctx->pic_conf.pic_width = 0;
+ ctx->pic_conf.pic_height = 0;
+
+ avctx->pix_fmt = PIX_FMT_YUV410P;
+
+ return 0;
+}
+
+
+/**
+ * Rearrange decoding and reference buffers.
+ *
+ * @param[in,out] ctx pointer to the decoder context
+ */
+static void switch_buffers(IVI4DecContext *ctx)
+{
+ switch (ctx->prev_frame_type) {
+ case FRAMETYPE_INTRA:
+ case FRAMETYPE_INTER:
+ ctx->buf_switch ^= 1;
+ ctx->dst_buf = ctx->buf_switch;
+ ctx->ref_buf = ctx->buf_switch ^ 1;
+ break;
+ case FRAMETYPE_INTER_NOREF:
+ break;
+ }
+
+ switch (ctx->frame_type) {
+ case FRAMETYPE_INTRA:
+ ctx->buf_switch = 0;
+ /* FALLTHROUGH */
+ case FRAMETYPE_INTER:
+ ctx->dst_buf = ctx->buf_switch;
+ ctx->ref_buf = ctx->buf_switch ^ 1;
+ break;
+ case FRAMETYPE_INTER_NOREF:
+ case FRAMETYPE_NULL_FIRST:
+ case FRAMETYPE_NULL_LAST:
+ break;
+ }
+}
+
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ IVI4DecContext *ctx = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int result, p, b;
+
+ init_get_bits(&ctx->gb, buf, buf_size * 8);
+
+ result = decode_pic_hdr(ctx, avctx);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding picture header\n");
+ return result;
+ }
+
+ switch_buffers(ctx);
+
+ if (ctx->frame_type < FRAMETYPE_NULL_FIRST) {
+ for (p = 0; p < 3; p++) {
+ for (b = 0; b < ctx->planes[p].num_bands; b++) {
+ result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error decoding band: %d, plane: %d\n", b, p);
+ return result;
+ }
+ }
+ }
+ }
+
+ /* If the bidirectional mode is enabled, next I and the following P frame will */
+ /* be sent together. Unfortunately the approach below seems to be the only way */
+ /* to handle the B-frames mode. That's exactly the same Intel decoders do. */
+ if (ctx->frame_type == FRAMETYPE_INTRA) {
+ while (get_bits(&ctx->gb, 8)); // skip version string
+ skip_bits_long(&ctx->gb, 64); // skip padding, TODO: implement correct 8-bytes alignment
+ if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8)
+ av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
+ }
+
+ if (ctx->frame.data[0])
+ avctx->release_buffer(avctx, &ctx->frame);
+
+ ctx->frame.reference = 0;
+ if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return result;
+ }
+
+ if (ctx->is_scalable) {
+ ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
+ } else {
+ ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+ }
+
+ ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
+ ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame*)data = ctx->frame;
+
+ return buf_size;
+}
+
+
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+ IVI4DecContext *ctx = avctx->priv_data;
+
+ ff_ivi_free_buffers(&ctx->planes[0]);
+
+ if (ctx->frame.data[0])
+ avctx->release_buffer(avctx, &ctx->frame);
+
+#if IVI4_STREAM_ANALYSER
+ if (ctx->is_scalable)
+ av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n");
+ if (ctx->uses_tiling)
+ av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n");
+ if (ctx->has_b_frames)
+ av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n");
+ if (ctx->has_transp)
+ av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n");
+ if (ctx->uses_haar)
+ av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n");
+ if (ctx->uses_fullpel)
+ av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n");
+#endif
+
+ return 0;
+}
+
+
+AVCodec ff_indeo4_decoder = {
+ .name = "indeo4",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_INDEO4,
+ .priv_data_size = sizeof(IVI4DecContext),
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"),
+};
diff --git a/libavcodec/indeo4data.h b/libavcodec/indeo4data.h
new file mode 100644
index 0000000..affd9c6
--- /dev/null
+++ b/libavcodec/indeo4data.h
@@ -0,0 +1,350 @@
+/*
+ * Indeo Video Interactive 4 compatible decoder
+ * Copyright (c) 2009-2010 Maxim Poliakovski
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * This file contains data needed for the Indeo 4 decoder.
+ */
+
+#ifndef AVCODEC_INDEO4DATA_H
+#define AVCODEC_INDEO4DATA_H
+
+#include <stdint.h>
+#include "dsputil.h"
+#include "ivi_common.h"
+
+/**
+ * standard picture dimensions
+ */
+static const uint16_t ivi4_common_pic_sizes[14] = {
+ 640, 480, 320, 240, 160, 120, 704, 480, 352, 240, 352, 288, 176, 144
+};
+
+/**
+ * Indeo 4 8x8 scan (zigzag) patterns
+ */
+static const uint8_t ivi4_alternate_scan_8x8[64] = {
+ 0, 8, 1, 9, 16, 24, 2, 3, 17, 25, 10, 11, 32, 40, 48, 56,
+ 4, 5, 6, 7, 33, 41, 49, 57, 18, 19, 26, 27, 12, 13, 14, 15,
+ 34, 35, 43, 42, 50, 51, 59, 58, 20, 21, 22, 23, 31, 30, 29, 28,
+ 36, 37, 38, 39, 47, 46, 45, 44, 52, 53, 54, 55, 63, 62, 61, 60
+};
+
+static const uint8_t ivi4_alternate_scan_4x4[16] = {
+ 0, 1, 4, 5, 8, 12, 2, 3, 9, 13, 6, 7, 10, 11, 14, 15
+};
+
+static const uint8_t ivi4_vertical_scan_4x4[16] = {
+ 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15
+};
+
+static const uint8_t ivi4_horizontal_scan_4x4[16] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static const uint8_t *scan_index_to_tab[15] = {
+ // for 8x8 transforms
+ ff_zigzag_direct,
+ ivi4_alternate_scan_8x8,
+ ff_ivi_horizontal_scan_8x8,
+ ff_ivi_vertical_scan_8x8,
+ ff_zigzag_direct,
+
+ // for 4x4 transforms
+ ff_ivi_direct_scan_4x4,
+ ivi4_alternate_scan_4x4,
+ ivi4_vertical_scan_4x4,
+ ivi4_horizontal_scan_4x4,
+ ff_ivi_direct_scan_4x4,
+
+ // TODO: check if those are needed
+ ff_ivi_horizontal_scan_8x8,
+ ff_ivi_horizontal_scan_8x8,
+ ff_ivi_horizontal_scan_8x8,
+ ff_ivi_horizontal_scan_8x8,
+ ff_ivi_horizontal_scan_8x8
+};
+
+/**
+ * Indeo 4 dequant tables
+ */
+static uint16_t ivi4_quant_8x8_intra[9][64] = {
+ {
+ 43, 342, 385, 470, 555, 555, 598, 726,
+ 342, 342, 470, 513, 555, 598, 726, 769,
+ 385, 470, 555, 555, 598, 726, 726, 811,
+ 470, 470, 555, 555, 598, 726, 769, 854,
+ 470, 555, 555, 598, 683, 726, 854, 1025,
+ 555, 555, 598, 683, 726, 854, 1025, 1153,
+ 555, 555, 598, 726, 811, 982, 1195, 1451,
+ 555, 598, 726, 811, 982, 1195, 1451, 1793
+ },
+ {
+ 86, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
+ 1195, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
+ 2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
+ 2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
+ 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
+ 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
+ 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
+ 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827
+ },
+ {
+ 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
+ 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
+ 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
+ 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
+ 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
+ 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
+ 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
+ 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835
+ },
+ {
+ 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
+ 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
+ 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
+ 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
+ 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
+ 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
+ 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
+ 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414
+ },
+ {
+ 897, 897, 897, 897, 897, 897, 897, 897,
+ 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067,
+ 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
+ 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409,
+ 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579,
+ 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750,
+ 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921,
+ 2091, 2091, 2091, 2091, 2091, 2091, 2091, 2091
+ },
+ {
+ 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
+ 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
+ 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
+ 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
+ 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
+ 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
+ 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
+ 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414
+ },
+ {
+ 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
+ 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
+ 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
+ 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
+ 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
+ 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
+ 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
+ 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390
+ },
+ {
+ 22, 171, 214, 257, 257, 299, 299, 342,
+ 171, 171, 257, 257, 299, 299, 342, 385,
+ 214, 257, 257, 299, 299, 342, 342, 385,
+ 257, 257, 257, 299, 299, 342, 385, 427,
+ 257, 257, 299, 299, 342, 385, 427, 513,
+ 257, 299, 299, 342, 385, 427, 513, 598,
+ 299, 299, 299, 385, 385, 470, 598, 726,
+ 299, 299, 385, 385, 470, 598, 726, 897
+ },
+ {
+ 86, 598, 1195, 1195, 2390, 2390, 2390, 2390,
+ 598, 598, 1195, 1195, 2390, 2390, 2390, 2390,
+ 1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
+ 1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
+ 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
+ 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
+ 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
+ 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414
+ }
+};
+
+static uint16_t ivi4_quant_8x8_inter[9][64] = {
+ {
+ 427, 427, 470, 427, 427, 427, 470, 470,
+ 427, 427, 470, 427, 427, 427, 470, 470,
+ 470, 470, 470, 470, 470, 470, 470, 470,
+ 427, 427, 470, 470, 427, 427, 470, 470,
+ 427, 427, 470, 427, 427, 427, 470, 470,
+ 427, 427, 470, 427, 427, 427, 470, 470,
+ 470, 470, 470, 470, 470, 470, 470, 470,
+ 470, 470, 470, 470, 470, 470, 470, 470
+ },
+ {
+ 1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
+ 1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
+ 2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
+ 2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
+ 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
+ 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
+ 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
+ 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414
+ },
+ {
+ 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
+ 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
+ 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
+ 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
+ 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
+ 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
+ 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
+ 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281
+ },
+ {
+ 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
+ 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
+ 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
+ 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
+ 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
+ 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
+ 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
+ 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433
+ },
+ {
+ 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
+ 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
+ 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
+ 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
+ 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
+ 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
+ 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
+ 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281
+ },
+ {
+ 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
+ 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
+ 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
+ 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
+ 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
+ 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
+ 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
+ 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433
+ },
+ {
+ 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
+ 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
+ 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
+ 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
+ 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
+ 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
+ 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
+ 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707
+ },
+ {
+ 86, 171, 171, 214, 214, 214, 214, 257,
+ 171, 171, 214, 214, 214, 214, 257, 257,
+ 171, 214, 214, 214, 214, 257, 257, 257,
+ 214, 214, 214, 214, 257, 257, 257, 299,
+ 214, 214, 214, 257, 257, 257, 299, 299,
+ 214, 214, 257, 257, 257, 299, 299, 299,
+ 214, 257, 257, 257, 299, 299, 299, 342,
+ 257, 257, 257, 299, 299, 299, 342, 342
+ },
+ {
+ 854, 854, 1195, 1195, 1707, 1707, 1707, 1707,
+ 854, 854, 1195, 1195, 1707, 1707, 1707, 1707,
+ 1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
+ 1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
+ 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
+ 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
+ 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
+ 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707
+ }
+};
+
+static uint16_t ivi4_quant_4x4_intra[5][16] = {
+ {
+ 22, 214, 257, 299,
+ 214, 257, 299, 342,
+ 257, 299, 342, 427,
+ 299, 342, 427, 513
+ },
+ {
+ 129, 1025, 1451, 1451,
+ 1025, 1025, 1451, 1451,
+ 1451, 1451, 2049, 2049,
+ 1451, 1451, 2049, 2049
+ },
+ {
+ 43, 171, 171, 171,
+ 43, 171, 171, 171,
+ 43, 171, 171, 171,
+ 43, 171, 171, 171
+ },
+ {
+ 43, 43, 43, 43,
+ 171, 171, 171, 171,
+ 171, 171, 171, 171,
+ 171, 171, 171, 171
+ },
+ {
+ 43, 43, 43, 43,
+ 43, 43, 43, 43,
+ 43, 43, 43, 43,
+ 43, 43, 43, 43
+ }
+};
+
+static uint16_t ivi4_quant_4x4_inter[5][16] = {
+ {
+ 107, 214, 257, 299,
+ 214, 257, 299, 299,
+ 257, 299, 299, 342,
+ 299, 299, 342, 342
+ },
+ {
+ 513, 1025, 1238, 1238,
+ 1025, 1025, 1238, 1238,
+ 1238, 1238, 1451, 1451,
+ 1238, 1238, 1451, 1451
+ },
+ {
+ 43, 171, 171, 171,
+ 43, 171, 171, 171,
+ 43, 171, 171, 171,
+ 43, 171, 171, 171
+ },
+ {
+ 43, 43, 43, 43,
+ 171, 171, 171, 171,
+ 171, 171, 171, 171,
+ 171, 171, 171, 171
+ },
+ {
+ 43, 43, 43, 43,
+ 43, 43, 43, 43,
+ 43, 43, 43, 43,
+ 43, 43, 43, 43
+ }
+};
+
+/**
+ * Table for mapping quant matrix index from the bitstream
+ * into internal quant table number.
+ */
+static uint8_t quant_index_to_tab[22] = {
+ 0, 1, 0, 2, 1, 3, 0, 4, 1, 5, 0, 1, 6, 7, 8, // for 8x8 quant matrixes
+ 0, 1, 2, 2, 3, 3, 4 // for 4x4 quant matrixes
+};
+
+#endif /* AVCODEC_INDEO4DATA_H */
diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c
index ba1bc18..8b72b1f 100644
--- a/libavcodec/indeo5.c
+++ b/libavcodec/indeo5.c
@@ -27,7 +27,7 @@
* Known FOURCCs: 'IV50'
*/
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
diff --git a/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c
index 83049bc..8347c79 100644
--- a/libavcodec/intelh263dec.c
+++ b/libavcodec/intelh263dec.c
@@ -125,15 +125,14 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s)
}
AVCodec ff_h263i_decoder = {
- "h263i",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_H263I,
- sizeof(MpegEncContext),
- ff_h263_decode_init,
- NULL,
- ff_h263_decode_end,
- ff_h263_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+ .name = "h263i",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_H263I,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_h263_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Intel H.263"),
.pix_fmts= ff_pixfmt_list_420,
};
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index fe853ab..b5a0454 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -25,8 +25,49 @@
#define AVCODEC_INTERNAL_H
#include <stdint.h>
+
+#include "libavutil/pixfmt.h"
#include "avcodec.h"
+typedef struct InternalBuffer {
+ uint8_t *base[AV_NUM_DATA_POINTERS];
+ uint8_t *data[AV_NUM_DATA_POINTERS];
+ int linesize[AV_NUM_DATA_POINTERS];
+ int width;
+ int height;
+ enum PixelFormat pix_fmt;
+ uint8_t **extended_data;
+ int audio_data_size;
+ int nb_channels;
+} InternalBuffer;
+
+typedef struct AVCodecInternal {
+ /**
+ * internal buffer count
+ * used by default get/release/reget_buffer().
+ */
+ int buffer_count;
+
+ /**
+ * internal buffers
+ * used by default get/release/reget_buffer().
+ */
+ InternalBuffer *buffer;
+
+ /**
+ * Whether the parent AVCodecContext is a copy of the context which had
+ * init() called on it.
+ * This is used by multithreading - shared tables and picture pointers
+ * should be freed from the original context only.
+ */
+ int is_copy;
+} AVCodecInternal;
+
+struct AVCodecDefault {
+ const uint8_t *key;
+ const uint8_t *value;
+};
+
/**
* Determine whether pix_fmt is a hardware accelerated format.
*/
@@ -48,6 +89,9 @@ AVHWAccel *ff_find_hwaccel(enum CodecID codec_id, enum PixelFormat pix_fmt);
*/
int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b);
-unsigned int ff_toupper4(unsigned int x);
+unsigned int avpriv_toupper4(unsigned int x);
+
+int avpriv_lock_avformat(void);
+int avpriv_unlock_avformat(void);
#endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
index 3bbb464..db98bec 100644
--- a/libavcodec/interplayvideo.c
+++ b/libavcodec/interplayvideo.c
@@ -41,7 +41,7 @@
#include "avcodec.h"
#include "bytestream.h"
#include "dsputil.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
#define PALETTE_COUNT 256
@@ -1089,14 +1089,13 @@ static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
}
AVCodec ff_interplay_video_decoder = {
- "interplayvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_INTERPLAY_VIDEO,
- sizeof(IpvideoContext),
- ipvideo_decode_init,
- NULL,
- ipvideo_decode_end,
- ipvideo_decode_frame,
- CODEC_CAP_DR1,
+ .name = "interplayvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_INTERPLAY_VIDEO,
+ .priv_data_size = sizeof(IpvideoContext),
+ .init = ipvideo_decode_init,
+ .close = ipvideo_decode_end,
+ .decode = ipvideo_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
};
diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c
index 69f940a..0dc33e2 100644
--- a/libavcodec/intrax8.c
+++ b/libavcodec/intrax8.c
@@ -304,7 +304,7 @@ static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma
int quant;
s->dsp.x8_setup_spatial_compensation(s->dest[chroma], s->edge_emu_buffer,
- s->current_picture.linesize[chroma>0],
+ s->current_picture.f.linesize[chroma>0],
&range, &sum, w->edges);
if(chroma){
w->orient=w->chroma_orient;
@@ -613,7 +613,7 @@ static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;
dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),
- s->dest[chroma], s->current_picture.linesize[!!chroma]);
+ s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
goto block_placed;
}
@@ -637,15 +637,15 @@ static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
}
if(w->flat_dc){
- dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.linesize[!!chroma]);
+ dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
}else{
s->dsp.x8_spatial_compensation[w->orient]( s->edge_emu_buffer,
s->dest[chroma],
- s->current_picture.linesize[!!chroma] );
+ s->current_picture.f.linesize[!!chroma] );
}
if(!zeros_only)
s->dsp.idct_add ( s->dest[chroma],
- s->current_picture.linesize[!!chroma],
+ s->current_picture.f.linesize[!!chroma],
s->block[0] );
block_placed:
@@ -656,7 +656,7 @@ block_placed:
if(s->loop_filter){
uint8_t* ptr = s->dest[chroma];
- int linesize = s->current_picture.linesize[!!chroma];
+ int linesize = s->current_picture.f.linesize[!!chroma];
if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){
s->dsp.x8_h_loop_filter(ptr, linesize, w->quant);
@@ -671,12 +671,12 @@ block_placed:
static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*
//not s->linesize as this would be wrong for field pics
//not that IntraX8 has interlacing support ;)
- const int linesize = s->current_picture.linesize[0];
- const int uvlinesize= s->current_picture.linesize[1];
+ const int linesize = s->current_picture.f.linesize[0];
+ const int uvlinesize = s->current_picture.f.linesize[1];
- s->dest[0] = s->current_picture.data[0];
- s->dest[1] = s->current_picture.data[1];
- s->dest[2] = s->current_picture.data[2];
+ s->dest[0] = s->current_picture.f.data[0];
+ s->dest[1] = s->current_picture.f.data[1];
+ s->dest[2] = s->current_picture.f.data[2];
s->dest[0] += s->mb_y * linesize << 3;
s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows
@@ -771,7 +771,7 @@ int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_of
/*emulate MB info in the relevant tables*/
s->mbskip_table [mb_xy]=0;
s->mbintra_table[mb_xy]=1;
- s->current_picture.qscale_table[mb_xy]=w->quant;
+ s->current_picture.f.qscale_table[mb_xy] = w->quant;
mb_xy++;
}
s->dest[0]+= 8;
@@ -784,6 +784,6 @@ int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_of
error:
ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
(s->mb_x>>1)-1, (s->mb_y>>1)-1,
- (AC_END|DC_END|MV_END) );
+ ER_MB_END );
return 0;
}
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index 0bb92da..148bb33 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -30,6 +30,7 @@
//#define DEBUG
#include <limits.h>
+#include "libavutil/mathematics.h"
#include "dsputil.h"
#include "avcodec.h"
#include "mpegvideo.h"
@@ -147,7 +148,7 @@ int ff_h263_decode_mba(MpegEncContext *s)
}
/**
- * decodes the group of blocks header or slice header.
+ * Decode the group of blocks header or slice header.
* @return <0 if an error occurred
*/
static int h263_decode_gob_header(MpegEncContext *s)
@@ -202,7 +203,7 @@ static int h263_decode_gob_header(MpegEncContext *s)
}
/**
- * finds the next resync_marker
+ * Find the next resync_marker.
* @param p pointer to buffer to scan
* @param end pointer to the end of the buffer
* @return pointer to the next resync_marker, or end if none was found
@@ -223,7 +224,7 @@ const uint8_t *ff_h263_find_resync_marker(const uint8_t *restrict p, const uint8
}
/**
- * decodes the group of blocks / video packet header.
+ * Decode the group of blocks / video packet header.
* @return bit position of the resync_marker, or <0 if none was found
*/
int ff_h263_resync(MpegEncContext *s){
@@ -270,7 +271,7 @@ int ff_h263_resync(MpegEncContext *s){
int h263_decode_motion(MpegEncContext * s, int pred, int f_code)
{
- int code, val, sign, shift, l;
+ int code, val, sign, shift;
code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2);
if (code == 0)
@@ -292,8 +293,7 @@ int h263_decode_motion(MpegEncContext * s, int pred, int f_code)
/* modulo decoding */
if (!s->h263_long_vectors) {
- l = INT_BIT - 5 - f_code;
- val = (val<<l)>>l;
+ val = sign_extend(val, 5 + f_code);
} else {
/* horrible h263 long vector mode */
if (pred < -31 && val < -63)
@@ -306,7 +306,7 @@ int h263_decode_motion(MpegEncContext * s, int pred, int f_code)
}
-/* Decodes RVLC of H.263+ UMV */
+/* Decode RVLC of H.263+ UMV */
static int h263p_decode_umotion(MpegEncContext * s, int pred)
{
int code = 0, sign;
@@ -352,20 +352,20 @@ static void preview_obmc(MpegEncContext *s){
do{
if (get_bits1(&s->gb)) {
/* skip mb */
- mot_val = s->current_picture.motion_val[0][ s->block_index[0] ];
+ mot_val = s->current_picture.f.motion_val[0][s->block_index[0]];
mot_val[0 ]= mot_val[2 ]=
mot_val[0+stride]= mot_val[2+stride]= 0;
mot_val[1 ]= mot_val[3 ]=
mot_val[1+stride]= mot_val[3+stride]= 0;
- s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
goto end;
}
cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
}while(cbpc == 20);
if(cbpc & 4){
- s->current_picture.mb_type[xy]= MB_TYPE_INTRA;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
}else{
get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
if (cbpc & 8) {
@@ -377,7 +377,7 @@ static void preview_obmc(MpegEncContext *s){
}
if ((cbpc & 16) == 0) {
- s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
/* 16x16 motion prediction */
mot_val= h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
if (s->umvplus)
@@ -395,7 +395,7 @@ static void preview_obmc(MpegEncContext *s){
mot_val[1 ]= mot_val[3 ]=
mot_val[1+stride]= mot_val[3+stride]= my;
} else {
- s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
for(i=0;i<4;i++) {
mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y);
if (s->umvplus)
@@ -484,7 +484,7 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
level = get_bits(&s->gb, 8);
if((level&0x7F) == 0){
av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y);
- if(s->error_recognition >= FF_ER_COMPLIANT)
+ if(s->err_recognition & AV_EF_BITSTREAM)
return -1;
}
if (level == 255)
@@ -617,7 +617,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
s->block_last_index[i] = -1;
s->mv_dir = MV_DIR_FORWARD;
s->mv_type = MV_TYPE_16X16;
- s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
s->mv[0][0][0] = 0;
s->mv[0][0][1] = 0;
s->mb_skipped = !(s->obmc | s->loop_filter);
@@ -650,7 +650,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
s->mv_dir = MV_DIR_FORWARD;
if ((cbpc & 16) == 0) {
- s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
/* 16x16 motion prediction */
s->mv_type = MV_TYPE_16X16;
h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
@@ -675,7 +675,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
} else {
- s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
s->mv_type = MV_TYPE_8X8;
for(i=0;i<4;i++) {
mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y);
@@ -703,8 +703,8 @@ int ff_h263_decode_mb(MpegEncContext *s,
} else if(s->pict_type==AV_PICTURE_TYPE_B) {
int mb_type;
const int stride= s->b8_stride;
- int16_t *mot_val0 = s->current_picture.motion_val[0][ 2*(s->mb_x + s->mb_y*stride) ];
- int16_t *mot_val1 = s->current_picture.motion_val[1][ 2*(s->mb_x + s->mb_y*stride) ];
+ int16_t *mot_val0 = s->current_picture.f.motion_val[0][2 * (s->mb_x + s->mb_y * stride)];
+ int16_t *mot_val1 = s->current_picture.f.motion_val[1][2 * (s->mb_x + s->mb_y * stride)];
// const int mv_xy= s->mb_x + 1 + s->mb_y * s->mb_stride;
//FIXME ugly
@@ -787,7 +787,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
}
}
- s->current_picture.mb_type[xy]= mb_type;
+ s->current_picture.f.mb_type[xy] = mb_type;
} else { /* I-Frame */
do{
cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
@@ -802,11 +802,11 @@ int ff_h263_decode_mb(MpegEncContext *s,
dquant = cbpc & 4;
s->mb_intra = 1;
intra:
- s->current_picture.mb_type[xy]= MB_TYPE_INTRA;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
if (s->h263_aic) {
s->ac_pred = get_bits1(&s->gb);
if(s->ac_pred){
- s->current_picture.mb_type[xy]= MB_TYPE_INTRA | MB_TYPE_ACPRED;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
s->h263_aic_dir = get_bits1(&s->gb);
}
@@ -888,7 +888,7 @@ int h263_decode_picture_header(MpegEncContext *s)
i = get_bits(&s->gb, 8); /* picture timestamp */
if( (s->picture_number&~0xFF)+i < s->picture_number)
i+= 256;
- s->current_picture_ptr->pts=
+ s->current_picture_ptr->f.pts =
s->picture_number= (s->picture_number&~0xFF) + i;
/* PTYPE starts here */
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index cadf389..6efba2d 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -126,7 +126,7 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number)
coded_frame_rate= 1800000;
coded_frame_rate_base= (1000+best_clock_code)*best_divisor;
- align_put_bits(&s->pb);
+ avpriv_align_put_bits(&s->pb);
/* Update the pointer to last GOB */
s->ptr_lastgob = put_bits_ptr(&s->pb);
@@ -275,7 +275,7 @@ void h263_encode_gob_header(MpegEncContext * s, int mb_line)
*/
void ff_clean_h263_qscales(MpegEncContext *s){
int i;
- int8_t * const qscale_table= s->current_picture.qscale_table;
+ int8_t * const qscale_table = s->current_picture.f.qscale_table;
ff_init_qscale_tab(s);
@@ -302,7 +302,7 @@ void ff_clean_h263_qscales(MpegEncContext *s){
static const int dquant_code[5]= {1,0,9,2,3};
/**
- * encodes a 8x8 block.
+ * Encode an 8x8 block.
* @param block the 8x8 block
* @param n block index (0-3 are luma, 4-5 are chroma)
*/
@@ -529,8 +529,8 @@ void h263_encode_mb(MpegEncContext * s,
/* motion vectors: 8x8 mode*/
h263_pred_motion(s, i, 0, &pred_x, &pred_y);
- motion_x= s->current_picture.motion_val[0][ s->block_index[i] ][0];
- motion_y= s->current_picture.motion_val[0][ s->block_index[i] ][1];
+ motion_x = s->current_picture.f.motion_val[0][s->block_index[i]][0];
+ motion_y = s->current_picture.f.motion_val[0][s->block_index[i]][1];
if (!s->umvplus) {
ff_h263_encode_motion_vector(s, motion_x - pred_x,
motion_y - pred_y, 1);
@@ -657,7 +657,7 @@ void h263_encode_mb(MpegEncContext * s,
void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code)
{
- int range, l, bit_size, sign, code, bits;
+ int range, bit_size, sign, code, bits;
if (val == 0) {
/* zero vector */
@@ -667,8 +667,7 @@ void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code)
bit_size = f_code - 1;
range = 1 << bit_size;
/* modulo encoding */
- l= INT_BIT - 6 - bit_size;
- val = (val<<l)>>l;
+ val = sign_extend(val, 6 + bit_size);
sign = val>>31;
val= (val^sign)-sign;
sign&=1;
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index bd3d4e6..9cec0a8 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -26,7 +26,7 @@
* Indeo5 decoders.
*/
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "get_bits.h"
#include "ivi_common.h"
diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h
index fd3d825..dcda13a 100644
--- a/libavcodec/ivi_common.h
+++ b/libavcodec/ivi_common.h
@@ -51,7 +51,7 @@ typedef struct {
/// or "7" for custom one
VLC *tab; /// pointer to the table associated with tab_sel
- //! the following are used only when tab_sel == 7
+ /// the following are used only when tab_sel == 7
IVIHuffDesc cust_desc; /// custom Huffman codebook descriptor
VLC cust_tab; /// vlc table for custom codebook
} IVIHuffTab;
diff --git a/libavcodec/ivi_dsp.c b/libavcodec/ivi_dsp.c
index 6b62dc8..caad843 100644
--- a/libavcodec/ivi_dsp.c
+++ b/libavcodec/ivi_dsp.c
@@ -1,7 +1,7 @@
/*
* DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5)
*
- * Copyright (c) 2009 Maxim Poliakovski
+ * Copyright (c) 2009-2011 Maxim Poliakovski
*
* This file is part of Libav.
*
@@ -178,6 +178,153 @@ void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst,
}
}
+void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,
+ const int dst_pitch, const int num_bands)
+{
+ int x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3;
+ const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
+ int32_t pitch;
+
+ /* all bands should have the same pitch */
+ pitch = plane->bands[0].pitch;
+
+ /* get pointers to the wavelet bands */
+ b0_ptr = plane->bands[0].buf;
+ b1_ptr = plane->bands[1].buf;
+ b2_ptr = plane->bands[2].buf;
+ b3_ptr = plane->bands[3].buf;
+
+ for (y = 0; y < plane->height; y += 2) {
+ for (x = 0, indx = 0; x < plane->width; x += 2, indx++) {
+ /* load coefficients */
+ b0 = b0_ptr[indx]; //should be: b0 = (num_bands > 0) ? b0_ptr[indx] : 0;
+ b1 = b1_ptr[indx]; //should be: b1 = (num_bands > 1) ? b1_ptr[indx] : 0;
+ b2 = b2_ptr[indx]; //should be: b2 = (num_bands > 2) ? b2_ptr[indx] : 0;
+ b3 = b3_ptr[indx]; //should be: b3 = (num_bands > 3) ? b3_ptr[indx] : 0;
+
+ /* haar wavelet recomposition */
+ p0 = (b0 + b1 + b2 + b3 + 2) >> 2;
+ p1 = (b0 + b1 - b2 - b3 + 2) >> 2;
+ p2 = (b0 - b1 + b2 - b3 + 2) >> 2;
+ p3 = (b0 - b1 - b2 + b3 + 2) >> 2;
+
+ /* bias, convert and output four pixels */
+ dst[x] = av_clip_uint8(p0 + 128);
+ dst[x + 1] = av_clip_uint8(p1 + 128);
+ dst[dst_pitch + x] = av_clip_uint8(p2 + 128);
+ dst[dst_pitch + x + 1] = av_clip_uint8(p3 + 128);
+ }// for x
+
+ dst += dst_pitch << 1;
+
+ b0_ptr += pitch;
+ b1_ptr += pitch;
+ b2_ptr += pitch;
+ b3_ptr += pitch;
+ }// for y
+}
+
+/** butterfly operation for the inverse Haar transform */
+#define IVI_HAAR_BFLY(s1, s2, o1, o2, t) \
+ t = (s1 - s2) >> 1;\
+ o1 = (s1 + s2) >> 1;\
+ o2 = t;\
+
+/** inverse 8-point Haar transform */
+#define INV_HAAR8(s1, s5, s3, s7, s2, s4, s6, s8,\
+ d1, d2, d3, d4, d5, d6, d7, d8,\
+ t0, t1, t2, t3, t4, t5, t6, t7, t8) {\
+ t1 = s1 << 1; t5 = s5 << 1;\
+ IVI_HAAR_BFLY(t1, t5, t1, t5, t0); IVI_HAAR_BFLY(t1, s3, t1, t3, t0);\
+ IVI_HAAR_BFLY(t5, s7, t5, t7, t0); IVI_HAAR_BFLY(t1, s2, t1, t2, t0);\
+ IVI_HAAR_BFLY(t3, s4, t3, t4, t0); IVI_HAAR_BFLY(t5, s6, t5, t6, t0);\
+ IVI_HAAR_BFLY(t7, s8, t7, t8, t0);\
+ d1 = COMPENSATE(t1);\
+ d2 = COMPENSATE(t2);\
+ d3 = COMPENSATE(t3);\
+ d4 = COMPENSATE(t4);\
+ d5 = COMPENSATE(t5);\
+ d6 = COMPENSATE(t6);\
+ d7 = COMPENSATE(t7);\
+ d8 = COMPENSATE(t8); }
+
+/** inverse 4-point Haar transform */
+#define INV_HAAR4(s1, s3, s5, s7) {\
+ HAAR_BFLY(s1, s5); HAAR_BFLY(s1, s3); HAAR_BFLY(s5, s7);\
+ s1 = COMPENSATE(s1);\
+ s3 = COMPENSATE(s3);\
+ s5 = COMPENSATE(s5);\
+ s7 = COMPENSATE(s7); }
+
+void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
+ const uint8_t *flags)
+{
+ int i, shift, sp1, sp2, sp3, sp4;
+ const int32_t *src;
+ int32_t *dst;
+ int tmp[64];
+ int t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+ /* apply the InvHaar8 to all columns */
+#define COMPENSATE(x) (x)
+ src = in;
+ dst = tmp;
+ for (i = 0; i < 8; i++) {
+ if (flags[i]) {
+ /* pre-scaling */
+ shift = !(i & 4);
+ sp1 = src[ 0] << shift;
+ sp2 = src[ 8] << shift;
+ sp3 = src[16] << shift;
+ sp4 = src[24] << shift;
+ INV_HAAR8( sp1, sp2, sp3, sp4,
+ src[32], src[40], src[48], src[56],
+ dst[ 0], dst[ 8], dst[16], dst[24],
+ dst[32], dst[40], dst[48], dst[56],
+ t0, t1, t2, t3, t4, t5, t6, t7, t8);
+ } else
+ dst[ 0] = dst[ 8] = dst[16] = dst[24] =
+ dst[32] = dst[40] = dst[48] = dst[56] = 0;
+
+ src++;
+ dst++;
+ }
+#undef COMPENSATE
+
+ /* apply the InvHaar8 to all rows */
+#define COMPENSATE(x) (x)
+ src = tmp;
+ for (i = 0; i < 8; i++) {
+ if ( !src[0] && !src[1] && !src[2] && !src[3]
+ && !src[4] && !src[5] && !src[6] && !src[7]) {
+ memset(out, 0, 8 * sizeof(out[0]));
+ } else {
+ INV_HAAR8(src[0], src[1], src[2], src[3],
+ src[4], src[5], src[6], src[7],
+ out[0], out[1], out[2], out[3],
+ out[4], out[5], out[6], out[7],
+ t0, t1, t2, t3, t4, t5, t6, t7, t8);
+ }
+ src += 8;
+ out += pitch;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch,
+ int blk_size)
+{
+ int x, y;
+ int16_t dc_coeff;
+
+ dc_coeff = (*in + 0) >> 3;
+
+ for (y = 0; y < blk_size; out += pitch, y++) {
+ for (x = 0; x < blk_size; x++)
+ out[x] = dc_coeff;
+ }
+}
+
/** butterfly operation for the inverse slant transform */
#define IVI_SLANT_BFLY(s1, s2, o1, o2, t) \
t = s1 - s2;\
diff --git a/libavcodec/ivi_dsp.h b/libavcodec/ivi_dsp.h
index 9632966..0438514 100644
--- a/libavcodec/ivi_dsp.h
+++ b/libavcodec/ivi_dsp.h
@@ -1,7 +1,7 @@
/*
* DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5)
*
- * Copyright (c) 2009 Maxim Poliakovski
+ * Copyright (c) 2009-2011 Maxim Poliakovski
*
* This file is part of Libav.
*
@@ -44,6 +44,43 @@ void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst,
const int dst_pitch, const int num_bands);
/**
+ * Haar wavelet recomposition filter for Indeo 4
+ *
+ * @param[in] plane pointer to the descriptor of the plane being processed
+ * @param[out] dst pointer to the destination buffer
+ * @param[in] dst_pitch pitch of the destination buffer
+ * @param[in] num_bands number of wavelet bands to be processed
+ */
+void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,
+ const int dst_pitch, const int num_bands);
+
+/**
+ * two-dimensional inverse Haar 8x8 transform for Indeo 4
+ *
+ * @param[in] in pointer to the vector of transform coefficients
+ * @param[out] out pointer to the output buffer (frame)
+ * @param[in] pitch pitch to move to the next y line
+ * @param[in] flags pointer to the array of column flags:
+ * != 0 - non_empty column, 0 - empty one
+ * (this array must be filled by caller)
+ */
+void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
+ const uint8_t *flags);
+
+/**
+ * DC-only two-dimensional inverse Haar transform for Indeo 4.
+ * Performing the inverse transform in this case is equivalent to
+ * spreading DC_coeff >> 3 over the whole block.
+ *
+ * @param[in] in pointer to the dc coefficient
+ * @param[out] out pointer to the output buffer (frame)
+ * @param[in] pitch pitch to move to the next y line
+ * @param[in] blk_size transform block size
+ */
+void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch,
+ int blk_size);
+
+/**
* two-dimensional inverse slant 8x8 transform
*
* @param[in] in pointer to the vector of transform coefficients
diff --git a/libavcodec/jfdctfst.c b/libavcodec/jfdctfst.c
index 8d3448a..b8dc407 100644
--- a/libavcodec/jfdctfst.c
+++ b/libavcodec/jfdctfst.c
@@ -1,6 +1,4 @@
/*
- * jfdctfst.c
- *
* This file is part of the Independent JPEG Group's software.
*
* The authors make NO WARRANTY or representation, either express or implied,
diff --git a/libavcodec/jfdctint.c b/libavcodec/jfdctint.c
index 072c744..0482bc5 100644
--- a/libavcodec/jfdctint.c
+++ b/libavcodec/jfdctint.c
@@ -1,402 +1,25 @@
-/*
- * jfdctint.c
- *
- * This file is part of the Independent JPEG Group's software.
- *
- * The authors make NO WARRANTY or representation, either express or implied,
- * with respect to this software, its quality, accuracy, merchantability, or
- * fitness for a particular purpose. This software is provided "AS IS", and
- * you, its user, assume the entire risk as to its quality and accuracy.
- *
- * This software is copyright (C) 1991-1996, Thomas G. Lane.
- * All Rights Reserved except as specified below.
- *
- * Permission is hereby granted to use, copy, modify, and distribute this
- * software (or portions thereof) for any purpose, without fee, subject to
- * these conditions:
- * (1) If any part of the source code for this software is distributed, then
- * this README file must be included, with this copyright and no-warranty
- * notice unaltered; and any additions, deletions, or changes to the original
- * files must be clearly indicated in accompanying documentation.
- * (2) If only executable code is distributed, then the accompanying
- * documentation must state that "this software is based in part on the work
- * of the Independent JPEG Group".
- * (3) Permission for use of this software is granted only if the user accepts
- * full responsibility for any undesirable consequences; the authors accept
- * NO LIABILITY for damages of any kind.
- *
- * These conditions apply to any software derived from or based on the IJG
- * code, not just to the unmodified library. If you use our work, you ought
- * to acknowledge us.
- *
- * Permission is NOT granted for the use of any IJG author's name or company
- * name in advertising or publicity relating to this software or products
- * derived from it. This software may be referred to only as "the Independent
- * JPEG Group's software".
- *
- * We specifically permit and encourage the use of this software as the basis
- * of commercial products, provided that all warranty or liability claims are
- * assumed by the product vendor.
- *
- * This file contains a slow-but-accurate integer implementation of the
- * forward DCT (Discrete Cosine Transform).
- *
- * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
- * on each column. Direct algorithms are also available, but they are
- * much more complex and seem not to be any faster when reduced to code.
- *
- * This implementation is based on an algorithm described in
- * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
- * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
- * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
- * The primary algorithm described there uses 11 multiplies and 29 adds.
- * We use their alternate method with 12 multiplies and 32 adds.
- * The advantage of this method is that no data path contains more than one
- * multiplication; this allows a very simple and accurate implementation in
- * scaled fixed-point arithmetic, with a minimal number of shifts.
- */
-
/**
- * @file
- * Independent JPEG Group's slow & accurate dct.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "libavutil/common.h"
-#include "dsputil.h"
-
-#define DCTSIZE 8
-#define BITS_IN_JSAMPLE 8
-#define GLOBAL(x) x
-#define RIGHT_SHIFT(x, n) ((x) >> (n))
-#define MULTIPLY16C16(var,const) ((var)*(const))
-
-#if 1 //def USE_ACCURATE_ROUNDING
-#define DESCALE(x,n) RIGHT_SHIFT((x) + (1 << ((n) - 1)), n)
-#else
-#define DESCALE(x,n) RIGHT_SHIFT(x, n)
-#endif
-
-
-/*
- * This module is specialized to the case DCTSIZE = 8.
- */
-
-#if DCTSIZE != 8
- Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
-#endif
-
-
-/*
- * The poop on this scaling stuff is as follows:
- *
- * Each 1-D DCT step produces outputs which are a factor of sqrt(N)
- * larger than the true DCT outputs. The final outputs are therefore
- * a factor of N larger than desired; since N=8 this can be cured by
- * a simple right shift at the end of the algorithm. The advantage of
- * this arrangement is that we save two multiplications per 1-D DCT,
- * because the y0 and y4 outputs need not be divided by sqrt(N).
- * In the IJG code, this factor of 8 is removed by the quantization step
- * (in jcdctmgr.c), NOT in this module.
+ * This file is part of Libav.
*
- * We have to do addition and subtraction of the integer inputs, which
- * is no problem, and multiplication by fractional constants, which is
- * a problem to do in integer arithmetic. We multiply all the constants
- * by CONST_SCALE and convert them to integer constants (thus retaining
- * CONST_BITS bits of precision in the constants). After doing a
- * multiplication we have to divide the product by CONST_SCALE, with proper
- * rounding, to produce the correct output. This division can be done
- * cheaply as a right shift of CONST_BITS bits. We postpone shifting
- * as long as possible so that partial sums can be added together with
- * full fractional precision.
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
*
- * The outputs of the first pass are scaled up by PASS1_BITS bits so that
- * they are represented to better-than-integral precision. These outputs
- * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
- * with the recommended scaling. (For 12-bit sample data, the intermediate
- * array is int32_t anyway.)
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * To avoid overflow of the 32-bit intermediate results in pass 2, we must
- * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
- * shows that the values given below are the most effective.
- */
-
-#if BITS_IN_JSAMPLE == 8
-#define CONST_BITS 13
-#define PASS1_BITS 4 /* set this to 2 if 16x16 multiplies are faster */
-#else
-#define CONST_BITS 13
-#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
-#endif
-
-/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
- * causing a lot of useless floating-point operations at run time.
- * To get around this we use the following pre-calculated constants.
- * If you change CONST_BITS you may want to add appropriate values.
- * (With a reasonable C compiler, you can just rely on the FIX() macro...)
- */
-
-#if CONST_BITS == 13
-#define FIX_0_298631336 ((int32_t) 2446) /* FIX(0.298631336) */
-#define FIX_0_390180644 ((int32_t) 3196) /* FIX(0.390180644) */
-#define FIX_0_541196100 ((int32_t) 4433) /* FIX(0.541196100) */
-#define FIX_0_765366865 ((int32_t) 6270) /* FIX(0.765366865) */
-#define FIX_0_899976223 ((int32_t) 7373) /* FIX(0.899976223) */
-#define FIX_1_175875602 ((int32_t) 9633) /* FIX(1.175875602) */
-#define FIX_1_501321110 ((int32_t) 12299) /* FIX(1.501321110) */
-#define FIX_1_847759065 ((int32_t) 15137) /* FIX(1.847759065) */
-#define FIX_1_961570560 ((int32_t) 16069) /* FIX(1.961570560) */
-#define FIX_2_053119869 ((int32_t) 16819) /* FIX(2.053119869) */
-#define FIX_2_562915447 ((int32_t) 20995) /* FIX(2.562915447) */
-#define FIX_3_072711026 ((int32_t) 25172) /* FIX(3.072711026) */
-#else
-#define FIX_0_298631336 FIX(0.298631336)
-#define FIX_0_390180644 FIX(0.390180644)
-#define FIX_0_541196100 FIX(0.541196100)
-#define FIX_0_765366865 FIX(0.765366865)
-#define FIX_0_899976223 FIX(0.899976223)
-#define FIX_1_175875602 FIX(1.175875602)
-#define FIX_1_501321110 FIX(1.501321110)
-#define FIX_1_847759065 FIX(1.847759065)
-#define FIX_1_961570560 FIX(1.961570560)
-#define FIX_2_053119869 FIX(2.053119869)
-#define FIX_2_562915447 FIX(2.562915447)
-#define FIX_3_072711026 FIX(3.072711026)
-#endif
-
-
-/* Multiply an int32_t variable by an int32_t constant to yield an int32_t result.
- * For 8-bit samples with the recommended scaling, all the variable
- * and constant values involved are no more than 16 bits wide, so a
- * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
- * For 12-bit samples, a full 32-bit multiplication will be needed.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#if BITS_IN_JSAMPLE == 8 && CONST_BITS<=13 && PASS1_BITS<=2
-#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
-#else
-#define MULTIPLY(var,const) ((var) * (const))
-#endif
-
-
-static av_always_inline void row_fdct(DCTELEM * data){
- int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
- int tmp10, tmp11, tmp12, tmp13;
- int z1, z2, z3, z4, z5;
- DCTELEM *dataptr;
- int ctr;
-
- /* Pass 1: process rows. */
- /* Note results are scaled up by sqrt(8) compared to a true DCT; */
- /* furthermore, we scale the results by 2**PASS1_BITS. */
-
- dataptr = data;
- for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
- tmp0 = dataptr[0] + dataptr[7];
- tmp7 = dataptr[0] - dataptr[7];
- tmp1 = dataptr[1] + dataptr[6];
- tmp6 = dataptr[1] - dataptr[6];
- tmp2 = dataptr[2] + dataptr[5];
- tmp5 = dataptr[2] - dataptr[5];
- tmp3 = dataptr[3] + dataptr[4];
- tmp4 = dataptr[3] - dataptr[4];
-
- /* Even part per LL&M figure 1 --- note that published figure is faulty;
- * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
- */
-
- tmp10 = tmp0 + tmp3;
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
- dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
-
- z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
- dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
- CONST_BITS-PASS1_BITS);
- dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
- CONST_BITS-PASS1_BITS);
-
- /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
- * cK represents cos(K*pi/16).
- * i0..i3 in the paper are tmp4..tmp7 here.
- */
-
- z1 = tmp4 + tmp7;
- z2 = tmp5 + tmp6;
- z3 = tmp4 + tmp6;
- z4 = tmp5 + tmp7;
- z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
-
- tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
- tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
- tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
- tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
- z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
- z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
- z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
- z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
-
- z3 += z5;
- z4 += z5;
-
- dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
- dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
- dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
- dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
-
- dataptr += DCTSIZE; /* advance pointer to next row */
- }
-}
-
-/*
- * Perform the forward DCT on one block of samples.
- */
-
-GLOBAL(void)
-ff_jpeg_fdct_islow (DCTELEM * data)
-{
- int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
- int tmp10, tmp11, tmp12, tmp13;
- int z1, z2, z3, z4, z5;
- DCTELEM *dataptr;
- int ctr;
-
- row_fdct(data);
-
- /* Pass 2: process columns.
- * We remove the PASS1_BITS scaling, but leave the results scaled up
- * by an overall factor of 8.
- */
-
- dataptr = data;
- for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
- tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
- tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
- tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
- tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
- tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
- tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
- tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
- tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
-
- /* Even part per LL&M figure 1 --- note that published figure is faulty;
- * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
- */
-
- tmp10 = tmp0 + tmp3;
- tmp13 = tmp0 - tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
-
- dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
- dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
-
- z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
- dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
- CONST_BITS+PASS1_BITS);
- dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
- CONST_BITS+PASS1_BITS);
-
- /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
- * cK represents cos(K*pi/16).
- * i0..i3 in the paper are tmp4..tmp7 here.
- */
-
- z1 = tmp4 + tmp7;
- z2 = tmp5 + tmp6;
- z3 = tmp4 + tmp6;
- z4 = tmp5 + tmp7;
- z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
-
- tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
- tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
- tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
- tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
- z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
- z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
- z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
- z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
-
- z3 += z5;
- z4 += z5;
-
- dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3,
- CONST_BITS+PASS1_BITS);
- dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4,
- CONST_BITS+PASS1_BITS);
- dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3,
- CONST_BITS+PASS1_BITS);
- dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4,
- CONST_BITS+PASS1_BITS);
-
- dataptr++; /* advance pointer to next column */
- }
-}
-
-/*
- * The secret of DCT2-4-8 is really simple -- you do the usual 1-DCT
- * on the rows and then, instead of doing even and odd, part on the colums
- * you do even part two times.
- */
-GLOBAL(void)
-ff_fdct248_islow (DCTELEM * data)
-{
- int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
- int tmp10, tmp11, tmp12, tmp13;
- int z1;
- DCTELEM *dataptr;
- int ctr;
-
- row_fdct(data);
-
- /* Pass 2: process columns.
- * We remove the PASS1_BITS scaling, but leave the results scaled up
- * by an overall factor of 8.
- */
-
- dataptr = data;
- for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
- tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*1];
- tmp1 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*3];
- tmp2 = dataptr[DCTSIZE*4] + dataptr[DCTSIZE*5];
- tmp3 = dataptr[DCTSIZE*6] + dataptr[DCTSIZE*7];
- tmp4 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*1];
- tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*3];
- tmp6 = dataptr[DCTSIZE*4] - dataptr[DCTSIZE*5];
- tmp7 = dataptr[DCTSIZE*6] - dataptr[DCTSIZE*7];
-
- tmp10 = tmp0 + tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp1 - tmp2;
- tmp13 = tmp0 - tmp3;
-
- dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
- dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
-
- z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
- dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
- CONST_BITS+PASS1_BITS);
- dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
- CONST_BITS+PASS1_BITS);
-
- tmp10 = tmp4 + tmp7;
- tmp11 = tmp5 + tmp6;
- tmp12 = tmp5 - tmp6;
- tmp13 = tmp4 - tmp7;
-
- dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
- dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
-
- z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
- dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
- CONST_BITS+PASS1_BITS);
- dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
- CONST_BITS+PASS1_BITS);
+#define BIT_DEPTH 8
+#include "jfdctint_template.c"
+#undef BIT_DEPTH
- dataptr++; /* advance pointer to next column */
- }
-}
+#define BIT_DEPTH 10
+#include "jfdctint_template.c"
+#undef BIT_DEPTH
diff --git a/libavcodec/jfdctint_template.c b/libavcodec/jfdctint_template.c
new file mode 100644
index 0000000..5175390
--- /dev/null
+++ b/libavcodec/jfdctint_template.c
@@ -0,0 +1,403 @@
+/*
+ * This file is part of the Independent JPEG Group's software.
+ *
+ * The authors make NO WARRANTY or representation, either express or implied,
+ * with respect to this software, its quality, accuracy, merchantability, or
+ * fitness for a particular purpose. This software is provided "AS IS", and
+ * you, its user, assume the entire risk as to its quality and accuracy.
+ *
+ * This software is copyright (C) 1991-1996, Thomas G. Lane.
+ * All Rights Reserved except as specified below.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * software (or portions thereof) for any purpose, without fee, subject to
+ * these conditions:
+ * (1) If any part of the source code for this software is distributed, then
+ * this README file must be included, with this copyright and no-warranty
+ * notice unaltered; and any additions, deletions, or changes to the original
+ * files must be clearly indicated in accompanying documentation.
+ * (2) If only executable code is distributed, then the accompanying
+ * documentation must state that "this software is based in part on the work
+ * of the Independent JPEG Group".
+ * (3) Permission for use of this software is granted only if the user accepts
+ * full responsibility for any undesirable consequences; the authors accept
+ * NO LIABILITY for damages of any kind.
+ *
+ * These conditions apply to any software derived from or based on the IJG
+ * code, not just to the unmodified library. If you use our work, you ought
+ * to acknowledge us.
+ *
+ * Permission is NOT granted for the use of any IJG author's name or company
+ * name in advertising or publicity relating to this software or products
+ * derived from it. This software may be referred to only as "the Independent
+ * JPEG Group's software".
+ *
+ * We specifically permit and encourage the use of this software as the basis
+ * of commercial products, provided that all warranty or liability claims are
+ * assumed by the product vendor.
+ *
+ * This file contains a slow-but-accurate integer implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column. Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on an algorithm described in
+ * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
+ * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
+ * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
+ * The primary algorithm described there uses 11 multiplies and 29 adds.
+ * We use their alternate method with 12 multiplies and 32 adds.
+ * The advantage of this method is that no data path contains more than one
+ * multiplication; this allows a very simple and accurate implementation in
+ * scaled fixed-point arithmetic, with a minimal number of shifts.
+ */
+
+/**
+ * @file
+ * Independent JPEG Group's slow & accurate dct.
+ */
+
+#include "libavutil/common.h"
+#include "dsputil.h"
+
+#include "bit_depth_template.c"
+
+#define DCTSIZE 8
+#define BITS_IN_JSAMPLE BIT_DEPTH
+#define GLOBAL(x) x
+#define RIGHT_SHIFT(x, n) ((x) >> (n))
+#define MULTIPLY16C16(var,const) ((var)*(const))
+
+#if 1 //def USE_ACCURATE_ROUNDING
+#define DESCALE(x,n) RIGHT_SHIFT((x) + (1 << ((n) - 1)), n)
+#else
+#define DESCALE(x,n) RIGHT_SHIFT(x, n)
+#endif
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+#error "Sorry, this code only copes with 8x8 DCTs."
+#endif
+
+
+/*
+ * The poop on this scaling stuff is as follows:
+ *
+ * Each 1-D DCT step produces outputs which are a factor of sqrt(N)
+ * larger than the true DCT outputs. The final outputs are therefore
+ * a factor of N larger than desired; since N=8 this can be cured by
+ * a simple right shift at the end of the algorithm. The advantage of
+ * this arrangement is that we save two multiplications per 1-D DCT,
+ * because the y0 and y4 outputs need not be divided by sqrt(N).
+ * In the IJG code, this factor of 8 is removed by the quantization step
+ * (in jcdctmgr.c), NOT in this module.
+ *
+ * We have to do addition and subtraction of the integer inputs, which
+ * is no problem, and multiplication by fractional constants, which is
+ * a problem to do in integer arithmetic. We multiply all the constants
+ * by CONST_SCALE and convert them to integer constants (thus retaining
+ * CONST_BITS bits of precision in the constants). After doing a
+ * multiplication we have to divide the product by CONST_SCALE, with proper
+ * rounding, to produce the correct output. This division can be done
+ * cheaply as a right shift of CONST_BITS bits. We postpone shifting
+ * as long as possible so that partial sums can be added together with
+ * full fractional precision.
+ *
+ * The outputs of the first pass are scaled up by PASS1_BITS bits so that
+ * they are represented to better-than-integral precision. These outputs
+ * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
+ * with the recommended scaling. (For 12-bit sample data, the intermediate
+ * array is int32_t anyway.)
+ *
+ * To avoid overflow of the 32-bit intermediate results in pass 2, we must
+ * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
+ * shows that the values given below are the most effective.
+ */
+
+#undef CONST_BITS
+#undef PASS1_BITS
+#undef OUT_SHIFT
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS 13
+#define PASS1_BITS 4 /* set this to 2 if 16x16 multiplies are faster */
+#define OUT_SHIFT PASS1_BITS
+#else
+#define CONST_BITS 13
+#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+#define OUT_SHIFT (PASS1_BITS + 1)
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 13
+#define FIX_0_298631336 ((int32_t) 2446) /* FIX(0.298631336) */
+#define FIX_0_390180644 ((int32_t) 3196) /* FIX(0.390180644) */
+#define FIX_0_541196100 ((int32_t) 4433) /* FIX(0.541196100) */
+#define FIX_0_765366865 ((int32_t) 6270) /* FIX(0.765366865) */
+#define FIX_0_899976223 ((int32_t) 7373) /* FIX(0.899976223) */
+#define FIX_1_175875602 ((int32_t) 9633) /* FIX(1.175875602) */
+#define FIX_1_501321110 ((int32_t) 12299) /* FIX(1.501321110) */
+#define FIX_1_847759065 ((int32_t) 15137) /* FIX(1.847759065) */
+#define FIX_1_961570560 ((int32_t) 16069) /* FIX(1.961570560) */
+#define FIX_2_053119869 ((int32_t) 16819) /* FIX(2.053119869) */
+#define FIX_2_562915447 ((int32_t) 20995) /* FIX(2.562915447) */
+#define FIX_3_072711026 ((int32_t) 25172) /* FIX(3.072711026) */
+#else
+#define FIX_0_298631336 FIX(0.298631336)
+#define FIX_0_390180644 FIX(0.390180644)
+#define FIX_0_541196100 FIX(0.541196100)
+#define FIX_0_765366865 FIX(0.765366865)
+#define FIX_0_899976223 FIX(0.899976223)
+#define FIX_1_175875602 FIX(1.175875602)
+#define FIX_1_501321110 FIX(1.501321110)
+#define FIX_1_847759065 FIX(1.847759065)
+#define FIX_1_961570560 FIX(1.961570560)
+#define FIX_2_053119869 FIX(2.053119869)
+#define FIX_2_562915447 FIX(2.562915447)
+#define FIX_3_072711026 FIX(3.072711026)
+#endif
+
+
+/* Multiply an int32_t variable by an int32_t constant to yield an int32_t result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
+ * For 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#if BITS_IN_JSAMPLE == 8 && CONST_BITS<=13 && PASS1_BITS<=2
+#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
+#else
+#define MULTIPLY(var,const) ((var) * (const))
+#endif
+
+
+static av_always_inline void FUNC(row_fdct)(DCTELEM *data)
+{
+ int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ int tmp10, tmp11, tmp12, tmp13;
+ int z1, z2, z3, z4, z5;
+ DCTELEM *dataptr;
+ int ctr;
+
+ /* Pass 1: process rows. */
+ /* Note results are scaled up by sqrt(8) compared to a true DCT; */
+ /* furthermore, we scale the results by 2**PASS1_BITS. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[0] + dataptr[7];
+ tmp7 = dataptr[0] - dataptr[7];
+ tmp1 = dataptr[1] + dataptr[6];
+ tmp6 = dataptr[1] - dataptr[6];
+ tmp2 = dataptr[2] + dataptr[5];
+ tmp5 = dataptr[2] - dataptr[5];
+ tmp3 = dataptr[3] + dataptr[4];
+ tmp4 = dataptr[3] - dataptr[4];
+
+ /* Even part per LL&M figure 1 --- note that published figure is faulty;
+ * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+ */
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
+ dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+ dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+ CONST_BITS-PASS1_BITS);
+ dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+ CONST_BITS-PASS1_BITS);
+
+ /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
+ * cK represents cos(K*pi/16).
+ * i0..i3 in the paper are tmp4..tmp7 here.
+ */
+
+ z1 = tmp4 + tmp7;
+ z2 = tmp5 + tmp6;
+ z3 = tmp4 + tmp6;
+ z4 = tmp5 + tmp7;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+
+ tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
+ dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
+ dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
+ dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+FUNC(ff_jpeg_fdct_islow)(DCTELEM *data)
+{
+ int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ int tmp10, tmp11, tmp12, tmp13;
+ int z1, z2, z3, z4, z5;
+ DCTELEM *dataptr;
+ int ctr;
+
+ FUNC(row_fdct)(data);
+
+ /* Pass 2: process columns.
+ * We remove the PASS1_BITS scaling, but leave the results scaled up
+ * by an overall factor of 8.
+ */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+ tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+ tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+ tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+ tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+ tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+ tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+ tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+
+ /* Even part per LL&M figure 1 --- note that published figure is faulty;
+ * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+ */
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[DCTSIZE*0] = DESCALE(tmp10 + tmp11, OUT_SHIFT);
+ dataptr[DCTSIZE*4] = DESCALE(tmp10 - tmp11, OUT_SHIFT);
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+ dataptr[DCTSIZE*2] = DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+ CONST_BITS + OUT_SHIFT);
+ dataptr[DCTSIZE*6] = DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+ CONST_BITS + OUT_SHIFT);
+
+ /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
+ * cK represents cos(K*pi/16).
+ * i0..i3 in the paper are tmp4..tmp7 here.
+ */
+
+ z1 = tmp4 + tmp7;
+ z2 = tmp5 + tmp6;
+ z3 = tmp4 + tmp6;
+ z4 = tmp5 + tmp7;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+
+ tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ dataptr[DCTSIZE*7] = DESCALE(tmp4 + z1 + z3, CONST_BITS + OUT_SHIFT);
+ dataptr[DCTSIZE*5] = DESCALE(tmp5 + z2 + z4, CONST_BITS + OUT_SHIFT);
+ dataptr[DCTSIZE*3] = DESCALE(tmp6 + z2 + z3, CONST_BITS + OUT_SHIFT);
+ dataptr[DCTSIZE*1] = DESCALE(tmp7 + z1 + z4, CONST_BITS + OUT_SHIFT);
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
+
+/*
+ * The secret of DCT2-4-8 is really simple -- you do the usual 1-DCT
+ * on the rows and then, instead of doing even and odd, part on the columns
+ * you do even part two times.
+ */
+GLOBAL(void)
+FUNC(ff_fdct248_islow)(DCTELEM *data)
+{
+ int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ int tmp10, tmp11, tmp12, tmp13;
+ int z1;
+ DCTELEM *dataptr;
+ int ctr;
+
+ FUNC(row_fdct)(data);
+
+ /* Pass 2: process columns.
+ * We remove the PASS1_BITS scaling, but leave the results scaled up
+ * by an overall factor of 8.
+ */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*1];
+ tmp1 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*3];
+ tmp2 = dataptr[DCTSIZE*4] + dataptr[DCTSIZE*5];
+ tmp3 = dataptr[DCTSIZE*6] + dataptr[DCTSIZE*7];
+ tmp4 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*1];
+ tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*3];
+ tmp6 = dataptr[DCTSIZE*4] - dataptr[DCTSIZE*5];
+ tmp7 = dataptr[DCTSIZE*6] - dataptr[DCTSIZE*7];
+
+ tmp10 = tmp0 + tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+ tmp13 = tmp0 - tmp3;
+
+ dataptr[DCTSIZE*0] = DESCALE(tmp10 + tmp11, OUT_SHIFT);
+ dataptr[DCTSIZE*4] = DESCALE(tmp10 - tmp11, OUT_SHIFT);
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+ dataptr[DCTSIZE*2] = DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+ CONST_BITS+OUT_SHIFT);
+ dataptr[DCTSIZE*6] = DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+ CONST_BITS+OUT_SHIFT);
+
+ tmp10 = tmp4 + tmp7;
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp5 - tmp6;
+ tmp13 = tmp4 - tmp7;
+
+ dataptr[DCTSIZE*1] = DESCALE(tmp10 + tmp11, OUT_SHIFT);
+ dataptr[DCTSIZE*5] = DESCALE(tmp10 - tmp11, OUT_SHIFT);
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+ dataptr[DCTSIZE*3] = DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+ CONST_BITS + OUT_SHIFT);
+ dataptr[DCTSIZE*7] = DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+ CONST_BITS + OUT_SHIFT);
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index 69cc1d3..a4cfe4f 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -364,14 +364,13 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor
AVCodec ff_jpegls_decoder = {
- "jpegls",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_JPEGLS,
- sizeof(MJpegDecodeContext),
- ff_mjpeg_decode_init,
- NULL,
- ff_mjpeg_decode_end,
- ff_mjpeg_decode_frame,
- CODEC_CAP_DR1,
+ .name = "jpegls",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_JPEGLS,
+ .priv_data_size = sizeof(MJpegDecodeContext),
+ .init = ff_mjpeg_decode_init,
+ .close = ff_mjpeg_decode_end,
+ .decode = ff_mjpeg_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"),
};
diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c
index a825cf9..2b6e54d 100644
--- a/libavcodec/jpeglsenc.c
+++ b/libavcodec/jpeglsenc.c
@@ -357,7 +357,7 @@ static int encode_picture_ls(AVCodecContext *avctx, unsigned char *buf, int buf_
put_bits(&pb, 8, v);
}
}
- align_put_bits(&pb);
+ avpriv_align_put_bits(&pb);
av_free(buf2);
/* End of image */
@@ -383,13 +383,12 @@ static av_cold int encode_init_ls(AVCodecContext *ctx) {
}
AVCodec ff_jpegls_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them
- "jpegls",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_JPEGLS,
- sizeof(JpeglsContext),
- encode_init_ls,
- encode_picture_ls,
- NULL,
- .pix_fmts= (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_RGB24, PIX_FMT_GRAY8, PIX_FMT_GRAY16, PIX_FMT_NONE},
- .long_name= NULL_IF_CONFIG_SMALL("JPEG-LS"),
+ .name = "jpegls",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_JPEGLS,
+ .priv_data_size = sizeof(JpeglsContext),
+ .init = encode_init_ls,
+ .encode = encode_picture_ls,
+ .pix_fmts = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_RGB24, PIX_FMT_GRAY8, PIX_FMT_GRAY16, PIX_FMT_NONE},
+ .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"),
};
diff --git a/libavcodec/jrevdct.c b/libavcodec/jrevdct.c
index 9e28dae..5ed96da 100644
--- a/libavcodec/jrevdct.c
+++ b/libavcodec/jrevdct.c
@@ -1,6 +1,4 @@
/*
- * jrevdct.c
- *
* This file is part of the Independent JPEG Group's software.
*
* The authors make NO WARRANTY or representation, either express or implied,
diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c
index 88c54bf..2d6fa73 100644
--- a/libavcodec/kgv1dec.c
+++ b/libavcodec/kgv1dec.c
@@ -165,13 +165,12 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_kgv1_decoder = {
- "kgv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_KGV1,
- sizeof(KgvContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
+ .name = "kgv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_KGV1,
+ .priv_data_size = sizeof(KgvContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"),
};
diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c
index 718cdfd..6c55863 100644
--- a/libavcodec/kmvc.c
+++ b/libavcodec/kmvc.c
@@ -57,17 +57,21 @@ typedef struct BitBuf {
#define kmvc_init_getbits(bb, src) bb.bits = 7; bb.bitbuf = *src++;
-#define kmvc_getbit(bb, src, res) {\
+#define kmvc_getbit(bb, src, src_end, res) {\
res = 0; \
if (bb.bitbuf & (1 << bb.bits)) res = 1; \
bb.bits--; \
if(bb.bits == -1) { \
+ if (src >= src_end) { \
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); \
+ return AVERROR_INVALIDDATA; \
+ } \
bb.bitbuf = *src++; \
bb.bits = 7; \
} \
}
-static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h)
+static int kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int src_size, int w, int h)
{
BitBuf bb;
int res, val;
@@ -75,13 +79,18 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w,
int bx, by;
int l0x, l1x, l0y, l1y;
int mx, my;
+ const uint8_t *src_end = src + src_size;
kmvc_init_getbits(bb, src);
for (by = 0; by < h; by += 8)
for (bx = 0; bx < w; bx += 8) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 8x8 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
for (i = 0; i < 64; i++)
BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
@@ -89,14 +98,22 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w,
for (i = 0; i < 4; i++) {
l0x = bx + (i & 1) * 4;
l0y = by + (i & 2) * 2;
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 4x4 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
for (j = 0; j < 16; j++)
BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
} else { // copy block from already decoded place
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
mx = val & 0xF;
my = val >> 4;
@@ -108,16 +125,24 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w,
for (j = 0; j < 4; j++) {
l1x = l0x + (j & 1) * 2;
l1y = l0y + (j & 2);
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 2x2 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
BLK(ctx->cur, l1x, l1y) = val;
BLK(ctx->cur, l1x + 1, l1y) = val;
BLK(ctx->cur, l1x, l1y + 1) = val;
BLK(ctx->cur, l1x + 1, l1y + 1) = val;
} else { // copy block from already decoded place
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
mx = val & 0xF;
my = val >> 4;
@@ -140,9 +165,11 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w,
}
}
}
+
+ return 0;
}
-static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h)
+static int kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int src_size, int w, int h)
{
BitBuf bb;
int res, val;
@@ -150,15 +177,20 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w,
int bx, by;
int l0x, l1x, l0y, l1y;
int mx, my;
+ const uint8_t *src_end = src + src_size;
kmvc_init_getbits(bb, src);
for (by = 0; by < h; by += 8)
for (bx = 0; bx < w; bx += 8) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 8x8 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
for (i = 0; i < 64; i++)
BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
@@ -171,14 +203,22 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w,
for (i = 0; i < 4; i++) {
l0x = bx + (i & 1) * 4;
l0y = by + (i & 2) * 2;
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 4x4 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
for (j = 0; j < 16; j++)
BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
} else { // copy block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
mx = (val & 0xF) - 8;
my = (val >> 4) - 8;
@@ -190,16 +230,24 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w,
for (j = 0; j < 4; j++) {
l1x = l0x + (j & 1) * 2;
l1y = l0y + (j & 2);
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 2x2 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
BLK(ctx->cur, l1x, l1y) = val;
BLK(ctx->cur, l1x + 1, l1y) = val;
BLK(ctx->cur, l1x, l1y + 1) = val;
BLK(ctx->cur, l1x + 1, l1y + 1) = val;
} else { // copy block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
mx = (val & 0xF) - 8;
my = (val >> 4) - 8;
@@ -222,6 +270,8 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w,
}
}
}
+
+ return 0;
}
static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt)
@@ -299,10 +349,10 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPa
memcpy(ctx->cur, ctx->prev, 320 * 200);
break;
case 3:
- kmvc_decode_intra_8x8(ctx, buf, avctx->width, avctx->height);
+ kmvc_decode_intra_8x8(ctx, buf, buf_size, avctx->width, avctx->height);
break;
case 4:
- kmvc_decode_inter_8x8(ctx, buf, avctx->width, avctx->height);
+ kmvc_decode_inter_8x8(ctx, buf, buf_size, avctx->width, avctx->height);
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD);
@@ -398,14 +448,13 @@ static av_cold int decode_end(AVCodecContext * avctx)
}
AVCodec ff_kmvc_decoder = {
- "kmvc",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_KMVC,
- sizeof(KmvcContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "kmvc",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_KMVC,
+ .priv_data_size = sizeof(KmvcContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"),
};
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index 3d53536..757873e 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -32,25 +32,27 @@
#include "lagarithrac.h"
enum LagarithFrameType {
- FRAME_RAW = 1, /*!< uncompressed */
- FRAME_U_RGB24 = 2, /*!< unaligned RGB24 */
- FRAME_ARITH_YUY2 = 3, /*!< arithmetic coded YUY2 */
- FRAME_ARITH_RGB24 = 4, /*!< arithmetic coded RGB24 */
- FRAME_SOLID_GRAY = 5, /*!< solid grayscale color frame */
- FRAME_SOLID_COLOR = 6, /*!< solid non-grayscale color frame */
- FRAME_OLD_ARITH_RGB = 7, /*!< obsolete arithmetic coded RGB (no longer encoded by upstream since version 1.1.0) */
- FRAME_ARITH_RGBA = 8, /*!< arithmetic coded RGBA */
- FRAME_SOLID_RGBA = 9, /*!< solid RGBA color frame */
- FRAME_ARITH_YV12 = 10, /*!< arithmetic coded YV12 */
- FRAME_REDUCED_RES = 11, /*!< reduced resolution YV12 frame */
+ FRAME_RAW = 1, /**< uncompressed */
+ FRAME_U_RGB24 = 2, /**< unaligned RGB24 */
+ FRAME_ARITH_YUY2 = 3, /**< arithmetic coded YUY2 */
+ FRAME_ARITH_RGB24 = 4, /**< arithmetic coded RGB24 */
+ FRAME_SOLID_GRAY = 5, /**< solid grayscale color frame */
+ FRAME_SOLID_COLOR = 6, /**< solid non-grayscale color frame */
+ FRAME_OLD_ARITH_RGB = 7, /**< obsolete arithmetic coded RGB (no longer encoded by upstream since version 1.1.0) */
+ FRAME_ARITH_RGBA = 8, /**< arithmetic coded RGBA */
+ FRAME_SOLID_RGBA = 9, /**< solid RGBA color frame */
+ FRAME_ARITH_YV12 = 10, /**< arithmetic coded YV12 */
+ FRAME_REDUCED_RES = 11, /**< reduced resolution YV12 frame */
};
typedef struct LagarithContext {
AVCodecContext *avctx;
AVFrame picture;
DSPContext dsp;
- int zeros; /*!< number of consecutive zero bytes encountered */
- int zeros_rem; /*!< number of zero bytes remaining to output */
+ int zeros; /**< number of consecutive zero bytes encountered */
+ int zeros_rem; /**< number of zero bytes remaining to output */
+ uint8_t *rgb_planes;
+ int rgb_stride;
} LagarithContext;
/**
@@ -245,21 +247,21 @@ static void lag_pred_line(LagarithContext *l, uint8_t *buf,
{
int L, TL;
+ /* Left pixel is actually prev_row[width] */
+ L = buf[width - stride - 1];
if (!line) {
/* Left prediction only for first line */
L = l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1,
width - 1, buf[0]);
return;
} else if (line == 1) {
- /* Second line, left predict first pixel, the rest of the line is median predicted */
- /* FIXME: In the case of RGB this pixel is top predicted */
- TL = buf[-stride];
+ /* Second line, left predict first pixel, the rest of the line is median predicted
+ * NOTE: In the case of RGB this pixel is top predicted */
+ TL = l->avctx->pix_fmt == PIX_FMT_YUV420P ? buf[-stride] : L;
} else {
/* Top left is 2 rows back, last pixel */
TL = buf[width - (2 * stride) - 1];
}
- /* Left pixel is actually prev_row[width] */
- L = buf[width - stride - 1];
add_lag_median_prediction(buf, buf - stride, buf,
width, &L, &TL);
@@ -443,6 +445,9 @@ static int lag_decode_frame(AVCodecContext *avctx,
AVFrame *const p = &l->picture;
uint8_t frametype = 0;
uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
+ int offs[4];
+ uint8_t *srcs[4], *dst;
+ int i, j, planes = 3;
AVFrame *picture = data;
@@ -458,6 +463,79 @@ static int lag_decode_frame(AVCodecContext *avctx,
offset_bv = AV_RL32(buf + 5);
switch (frametype) {
+ case FRAME_SOLID_RGBA:
+ avctx->pix_fmt = PIX_FMT_RGB32;
+
+ if (avctx->get_buffer(avctx, p) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return -1;
+ }
+
+ dst = p->data[0];
+ for (j = 0; j < avctx->height; j++) {
+ for (i = 0; i < avctx->width; i++)
+ AV_WN32(dst + i * 4, offset_gu);
+ dst += p->linesize[0];
+ }
+ break;
+ case FRAME_ARITH_RGBA:
+ avctx->pix_fmt = PIX_FMT_RGB32;
+ planes = 4;
+ offset_ry += 4;
+ offs[3] = AV_RL32(buf + 9);
+ case FRAME_ARITH_RGB24:
+ if (frametype == FRAME_ARITH_RGB24)
+ avctx->pix_fmt = PIX_FMT_RGB24;
+
+ if (avctx->get_buffer(avctx, p) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return -1;
+ }
+
+ offs[0] = offset_bv;
+ offs[1] = offset_gu;
+ offs[2] = offset_ry;
+
+ if (!l->rgb_planes) {
+ l->rgb_stride = FFALIGN(avctx->width, 16);
+ l->rgb_planes = av_malloc(l->rgb_stride * avctx->height * planes);
+ if (!l->rgb_planes) {
+ av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n");
+ return AVERROR(ENOMEM);
+ }
+ }
+ for (i = 0; i < planes; i++)
+ srcs[i] = l->rgb_planes + (i + 1) * l->rgb_stride * avctx->height - l->rgb_stride;
+ for (i = 0; i < planes; i++)
+ lag_decode_arith_plane(l, srcs[i],
+ avctx->width, avctx->height,
+ -l->rgb_stride, buf + offs[i],
+ buf_size);
+ dst = p->data[0];
+ for (i = 0; i < planes; i++)
+ srcs[i] = l->rgb_planes + i * l->rgb_stride * avctx->height;
+ for (j = 0; j < avctx->height; j++) {
+ for (i = 0; i < avctx->width; i++) {
+ uint8_t r, g, b, a;
+ r = srcs[0][i];
+ g = srcs[1][i];
+ b = srcs[2][i];
+ r += g;
+ b += g;
+ if (frametype == FRAME_ARITH_RGBA) {
+ a = srcs[3][i];
+ AV_WN32(dst + i * 4, MKBETAG(a, r, g, b));
+ } else {
+ dst[i * 3 + 0] = r;
+ dst[i * 3 + 1] = g;
+ dst[i * 3 + 2] = b;
+ }
+ }
+ dst += p->linesize[0];
+ for (i = 0; i < planes; i++)
+ srcs[i] += l->rgb_stride;
+ }
+ break;
case FRAME_ARITH_YV12:
avctx->pix_fmt = PIX_FMT_YUV420P;
@@ -504,19 +582,19 @@ static av_cold int lag_decode_end(AVCodecContext *avctx)
if (l->picture.data[0])
avctx->release_buffer(avctx, &l->picture);
+ av_freep(&l->rgb_planes);
return 0;
}
AVCodec ff_lagarith_decoder = {
- "lagarith",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_LAGARITH,
- sizeof(LagarithContext),
- lag_decode_init,
- NULL,
- lag_decode_end,
- lag_decode_frame,
- CODEC_CAP_DR1,
+ .name = "lagarith",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_LAGARITH,
+ .priv_data_size = sizeof(LagarithContext),
+ .init = lag_decode_init,
+ .close = lag_decode_end,
+ .decode = lag_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
};
diff --git a/libavcodec/lagarithrac.h b/libavcodec/lagarithrac.h
index 6a8fa95..b942199 100644
--- a/libavcodec/lagarithrac.h
+++ b/libavcodec/lagarithrac.h
@@ -40,15 +40,15 @@ typedef struct lag_rac {
AVCodecContext *avctx;
unsigned low;
unsigned range;
- unsigned scale; /*!< Number of bits of precision in range. */
- unsigned hash_shift; /*!< Number of bits to shift to calculate hash for radix search. */
+ unsigned scale; /**< Number of bits of precision in range. */
+ unsigned hash_shift; /**< Number of bits to shift to calculate hash for radix search. */
- const uint8_t *bytestream_start; /*!< Start of input bytestream. */
- const uint8_t *bytestream; /*!< Current position in input bytestream. */
- const uint8_t *bytestream_end; /*!< End position of input bytestream. */
+ const uint8_t *bytestream_start; /**< Start of input bytestream. */
+ const uint8_t *bytestream; /**< Current position in input bytestream. */
+ const uint8_t *bytestream_end; /**< End position of input bytestream. */
- uint32_t prob[258]; /*!< Table of cumulative probability for each symbol. */
- uint8_t range_hash[256]; /*!< Hash table mapping upper byte to approximate symbol. */
+ uint32_t prob[258]; /**< Table of cumulative probability for each symbol. */
+ uint8_t range_hash[256]; /**< Hash table mapping upper byte to approximate symbol. */
} lag_rac;
void lag_rac_init(lag_rac *l, GetBitContext *gb, int length);
diff --git a/libavcodec/latm_parser.c b/libavcodec/latm_parser.c
index fe39de8..bd941f6 100644
--- a/libavcodec/latm_parser.c
+++ b/libavcodec/latm_parser.c
@@ -36,7 +36,7 @@ typedef struct LATMParseContext{
} LATMParseContext;
/**
- * finds the end of the current frame in the bitstream.
+ * Find the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
static int latm_find_frame_end(AVCodecParserContext *s1, const uint8_t *buf,
@@ -106,9 +106,8 @@ static int latm_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
}
AVCodecParser ff_aac_latm_parser = {
- { CODEC_ID_AAC_LATM },
- sizeof(LATMParseContext),
- NULL,
- latm_parse,
- ff_parse_close
+ .codec_ids = { CODEC_ID_AAC_LATM },
+ .priv_data_size = sizeof(LATMParseContext),
+ .parser_parse = latm_parse,
+ .parser_close = ff_parse_close
};
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index 70414d4..b66a3ce 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -73,8 +73,8 @@ typedef struct LclDecContext {
/**
- * \param srcptr compressed source buffer, must be padded with at least 5 extra bytes
- * \param destptr must be padded sufficiently for av_memcpy_backptr
+ * @param srcptr compressed source buffer, must be padded with at least 5 extra bytes
+ * @param destptr must be padded sufficiently for av_memcpy_backptr
*/
static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize)
{
@@ -119,11 +119,11 @@ static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsign
#if CONFIG_ZLIB_DECODER
/**
- * \brief decompress a zlib-compressed data block into decomp_buf
- * \param src compressed input buffer
- * \param src_len data length in input buffer
- * \param offset offset in decomp_buf
- * \param expected expected decompressed length
+ * @brief decompress a zlib-compressed data block into decomp_buf
+ * @param src compressed input buffer
+ * @param src_len data length in input buffer
+ * @param offset offset in decomp_buf
+ * @param expected expected decompressed length
*/
static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected)
{
@@ -610,30 +610,28 @@ static av_cold int decode_end(AVCodecContext *avctx)
#if CONFIG_MSZH_DECODER
AVCodec ff_mszh_decoder = {
- "mszh",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MSZH,
- sizeof(LclDecContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "mszh",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MSZH,
+ .priv_data_size = sizeof(LclDecContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"),
};
#endif
#if CONFIG_ZLIB_DECODER
AVCodec ff_zlib_decoder = {
- "zlib",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ZLIB,
- sizeof(LclDecContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "zlib",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ZLIB,
+ .priv_data_size = sizeof(LclDecContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
};
#endif
diff --git a/libavcodec/lclenc.c b/libavcodec/lclenc.c
index 3285d1a..4c902d5 100644
--- a/libavcodec/lclenc.c
+++ b/libavcodec/lclenc.c
@@ -171,13 +171,13 @@ static av_cold int encode_end(AVCodecContext *avctx)
}
AVCodec ff_zlib_encoder = {
- "zlib",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ZLIB,
- sizeof(LclEncContext),
- encode_init,
- encode_frame,
- encode_end,
+ .name = "zlib",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ZLIB,
+ .priv_data_size = sizeof(LclEncContext),
+ .init = encode_init,
+ .encode = encode_frame,
+ .close = encode_end,
.pix_fmts = (const enum PixelFormat[]) { PIX_FMT_BGR24, PIX_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
};
diff --git a/libavcodec/libavcodec.v b/libavcodec/libavcodec.v
index 6569903..a9e7674 100644
--- a/libavcodec/libavcodec.v
+++ b/libavcodec/libavcodec.v
@@ -1,9 +1,8 @@
LIBAVCODEC_$MAJOR {
- global: *;
- local:
- ff_*_bsf;
- ff_*_decoder;
- ff_*_encoder;
- ff_*_hwaccel;
- ff_*_parser;
+ global: av*;
+ audio_resample;
+ audio_resample_close;
+ #deprecated, remove after next bump
+ img_get_alpha_info;
+ local: *;
};
diff --git a/libavcodec/libdirac.h b/libavcodec/libdirac.h
index 7f79122..4403fb2 100644
--- a/libavcodec/libdirac.h
+++ b/libavcodec/libdirac.h
@@ -20,7 +20,7 @@
/**
* @file
-* data structures common to libdiracenc.c and libdiracdec.c
+* data structures common to libdirac encoder and decoder
*/
#ifndef AVCODEC_LIBDIRAC_H
@@ -35,7 +35,7 @@
static const struct {
enum PixelFormat ff_pix_fmt;
dirac_chroma_t dirac_pix_fmt;
-} ffmpeg_dirac_pixel_format_map[] = {
+} dirac_pixel_format_map[] = {
{ PIX_FMT_YUV420P, format420 },
{ PIX_FMT_YUV422P, format422 },
{ PIX_FMT_YUV444P, format444 },
diff --git a/libavcodec/libdirac_libschro.c b/libavcodec/libdirac_libschro.c
index 525d866..45b5b83 100644
--- a/libavcodec/libdirac_libschro.c
+++ b/libavcodec/libdirac_libschro.c
@@ -25,7 +25,7 @@
#include "libdirac_libschro.h"
-static const FfmpegDiracSchroVideoFormatInfo ff_dirac_schro_video_format_info[] = {
+static const DiracSchroVideoFormatInfo ff_dirac_schro_video_format_info[] = {
{ 640, 480, 24000, 1001},
{ 176, 120, 15000, 1001},
{ 176, 144, 25, 2 },
@@ -53,7 +53,7 @@ unsigned int ff_dirac_schro_get_video_format_idx(AVCodecContext *avccontext)
sizeof(ff_dirac_schro_video_format_info[0]);
for (idx = 1; idx < num_formats; ++idx) {
- const FfmpegDiracSchroVideoFormatInfo *vf = &ff_dirac_schro_video_format_info[idx];
+ const DiracSchroVideoFormatInfo *vf = &ff_dirac_schro_video_format_info[idx];
if (avccontext->width == vf->width &&
avccontext->height == vf->height) {
ret_idx = idx;
@@ -65,22 +65,22 @@ unsigned int ff_dirac_schro_get_video_format_idx(AVCodecContext *avccontext)
return ret_idx;
}
-void ff_dirac_schro_queue_init(FfmpegDiracSchroQueue *queue)
+void ff_dirac_schro_queue_init(DiracSchroQueue *queue)
{
queue->p_head = queue->p_tail = NULL;
queue->size = 0;
}
-void ff_dirac_schro_queue_free(FfmpegDiracSchroQueue *queue,
+void ff_dirac_schro_queue_free(DiracSchroQueue *queue,
void (*free_func)(void *))
{
while (queue->p_head)
free_func(ff_dirac_schro_queue_pop(queue));
}
-int ff_dirac_schro_queue_push_back(FfmpegDiracSchroQueue *queue, void *p_data)
+int ff_dirac_schro_queue_push_back(DiracSchroQueue *queue, void *p_data)
{
- FfmpegDiracSchroQueueElement *p_new = av_mallocz(sizeof(FfmpegDiracSchroQueueElement));
+ DiracSchroQueueElement *p_new = av_mallocz(sizeof(DiracSchroQueueElement));
if (!p_new)
return -1;
@@ -97,9 +97,9 @@ int ff_dirac_schro_queue_push_back(FfmpegDiracSchroQueue *queue, void *p_data)
return 0;
}
-void *ff_dirac_schro_queue_pop(FfmpegDiracSchroQueue *queue)
+void *ff_dirac_schro_queue_pop(DiracSchroQueue *queue)
{
- FfmpegDiracSchroQueueElement *top = queue->p_head;
+ DiracSchroQueueElement *top = queue->p_head;
if (top) {
void *data = top->data;
diff --git a/libavcodec/libdirac_libschro.h b/libavcodec/libdirac_libschro.h
index 9c2e9e7..a80558f 100644
--- a/libavcodec/libdirac_libschro.h
+++ b/libavcodec/libdirac_libschro.h
@@ -33,7 +33,7 @@ typedef struct {
uint16_t height;
uint16_t frame_rate_num;
uint16_t frame_rate_denom;
-} FfmpegDiracSchroVideoFormatInfo;
+} DiracSchroVideoFormatInfo;
/**
* Returns the index into the Dirac Schro common video format info table
@@ -43,7 +43,7 @@ unsigned int ff_dirac_schro_get_video_format_idx(AVCodecContext *avccontext);
/**
* contains a single encoded frame returned from Dirac or Schroedinger
*/
-typedef struct FfmpegDiracSchroEncodedFrame {
+typedef struct DiracSchroEncodedFrame {
/** encoded frame data */
uint8_t *p_encbuf;
@@ -55,51 +55,51 @@ typedef struct FfmpegDiracSchroEncodedFrame {
/** key frame flag. 1 : is key frame , 0 : in not key frame */
uint16_t key_frame;
-} FfmpegDiracSchroEncodedFrame;
+} DiracSchroEncodedFrame;
/**
* queue element
*/
-typedef struct FfmpegDiracSchroQueueElement {
+typedef struct DiracSchroQueueElement {
/** Data to be stored in queue*/
void *data;
/** Pointer to next element queue */
- struct FfmpegDiracSchroQueueElement *next;
-} FfmpegDiracSchroQueueElement;
+ struct DiracSchroQueueElement *next;
+} DiracSchroQueueElement;
/**
* A simple queue implementation used in libdirac and libschroedinger
*/
-typedef struct FfmpegDiracSchroQueue {
+typedef struct DiracSchroQueue {
/** Pointer to head of queue */
- FfmpegDiracSchroQueueElement *p_head;
+ DiracSchroQueueElement *p_head;
/** Pointer to tail of queue */
- FfmpegDiracSchroQueueElement *p_tail;
+ DiracSchroQueueElement *p_tail;
/** Queue size*/
int size;
-} FfmpegDiracSchroQueue;
+} DiracSchroQueue;
/**
* Initialise the queue
*/
-void ff_dirac_schro_queue_init(FfmpegDiracSchroQueue *queue);
+void ff_dirac_schro_queue_init(DiracSchroQueue *queue);
/**
* Add an element to the end of the queue
*/
-int ff_dirac_schro_queue_push_back(FfmpegDiracSchroQueue *queue, void *p_data);
+int ff_dirac_schro_queue_push_back(DiracSchroQueue *queue, void *p_data);
/**
* Return the first element in the queue
*/
-void *ff_dirac_schro_queue_pop(FfmpegDiracSchroQueue *queue);
+void *ff_dirac_schro_queue_pop(DiracSchroQueue *queue);
/**
* Free the queue resources. free_func is a function supplied by the caller to
* free any resources allocated by the caller. The data field of the queue
* element is passed to it.
*/
-void ff_dirac_schro_queue_free(FfmpegDiracSchroQueue *queue,
+void ff_dirac_schro_queue_free(DiracSchroQueue *queue,
void (*free_func)(void *));
#endif /* AVCODEC_LIBDIRAC_LIBSCHRO_H */
diff --git a/libavcodec/libdiracdec.c b/libavcodec/libdiracdec.c
index 08fec3d..6565171 100644
--- a/libavcodec/libdiracdec.c
+++ b/libavcodec/libdiracdec.c
@@ -37,34 +37,34 @@
#include <libdirac_decoder/dirac_parser.h>
/** contains a single frame returned from Dirac */
-typedef struct FfmpegDiracDecoderParams {
+typedef struct DiracDecoderParams {
/** decoder handle */
dirac_decoder_t* p_decoder;
/** buffer to hold decoded frame */
unsigned char* p_out_frame_buf;
-} FfmpegDiracDecoderParams;
+} DiracDecoderParams;
/**
* returns Libav chroma format
*/
-static enum PixelFormat GetFfmpegChromaFormat(dirac_chroma_t dirac_pix_fmt)
+static enum PixelFormat get_chroma_format(dirac_chroma_t dirac_pix_fmt)
{
- int num_formats = sizeof(ffmpeg_dirac_pixel_format_map) /
- sizeof(ffmpeg_dirac_pixel_format_map[0]);
+ int num_formats = sizeof(dirac_pixel_format_map) /
+ sizeof(dirac_pixel_format_map[0]);
int idx;
for (idx = 0; idx < num_formats; ++idx)
- if (ffmpeg_dirac_pixel_format_map[idx].dirac_pix_fmt == dirac_pix_fmt)
- return ffmpeg_dirac_pixel_format_map[idx].ff_pix_fmt;
+ if (dirac_pixel_format_map[idx].dirac_pix_fmt == dirac_pix_fmt)
+ return dirac_pixel_format_map[idx].ff_pix_fmt;
return PIX_FMT_NONE;
}
static av_cold int libdirac_decode_init(AVCodecContext *avccontext)
{
- FfmpegDiracDecoderParams *p_dirac_params = avccontext->priv_data;
+ DiracDecoderParams *p_dirac_params = avccontext->priv_data;
p_dirac_params->p_decoder = dirac_decoder_init(avccontext->debug);
if (!p_dirac_params->p_decoder)
@@ -80,7 +80,7 @@ static int libdirac_decode_frame(AVCodecContext *avccontext,
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- FfmpegDiracDecoderParams *p_dirac_params = avccontext->priv_data;
+ DiracDecoderParams *p_dirac_params = avccontext->priv_data;
AVPicture *picture = data;
AVPicture pic;
int pict_size;
@@ -117,7 +117,7 @@ static int libdirac_decode_frame(AVCodecContext *avccontext,
avccontext->height = src_params->height;
avccontext->width = src_params->width;
- avccontext->pix_fmt = GetFfmpegChromaFormat(src_params->chroma);
+ avccontext->pix_fmt = get_chroma_format(src_params->chroma);
if (avccontext->pix_fmt == PIX_FMT_NONE) {
av_log(avccontext, AV_LOG_ERROR,
"Dirac chroma format %d not supported currently\n",
@@ -174,7 +174,7 @@ static int libdirac_decode_frame(AVCodecContext *avccontext,
static av_cold int libdirac_decode_close(AVCodecContext *avccontext)
{
- FfmpegDiracDecoderParams *p_dirac_params = avccontext->priv_data;
+ DiracDecoderParams *p_dirac_params = avccontext->priv_data;
dirac_decoder_close(p_dirac_params->p_decoder);
av_freep(&p_dirac_params->p_out_frame_buf);
@@ -195,15 +195,14 @@ static void libdirac_flush(AVCodecContext *avccontext)
AVCodec ff_libdirac_decoder = {
- "libdirac",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DIRAC,
- sizeof(FfmpegDiracDecoderParams),
- libdirac_decode_init,
- NULL,
- libdirac_decode_close,
- libdirac_decode_frame,
- CODEC_CAP_DELAY,
+ .name = "libdirac",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DIRAC,
+ .priv_data_size = sizeof(DiracDecoderParams),
+ .init = libdirac_decode_init,
+ .close = libdirac_decode_close,
+ .decode = libdirac_decode_frame,
+ .capabilities = CODEC_CAP_DELAY,
.flush = libdirac_flush,
.long_name = NULL_IF_CONFIG_SMALL("libdirac Dirac 2.2"),
};
diff --git a/libavcodec/libdiracenc.c b/libavcodec/libdiracenc.c
index ff4b92f..33dba22 100644
--- a/libavcodec/libdiracenc.c
+++ b/libavcodec/libdiracenc.c
@@ -38,7 +38,7 @@
#include <libdirac_encoder/dirac_encoder.h>
/** Dirac encoder private data */
-typedef struct FfmpegDiracEncoderParams {
+typedef struct DiracEncoderParams {
/** Dirac encoder context */
dirac_encoder_context_t enc_ctx;
@@ -61,27 +61,27 @@ typedef struct FfmpegDiracEncoderParams {
int enc_buf_size;
/** queue storing encoded frames */
- FfmpegDiracSchroQueue enc_frame_queue;
+ DiracSchroQueue enc_frame_queue;
/** end of sequence signalled by user, 0 - false, 1 - true */
int eos_signalled;
/** end of sequence returned by encoder, 0 - false, 1 - true */
int eos_pulled;
-} FfmpegDiracEncoderParams;
+} DiracEncoderParams;
/**
* Works out Dirac-compatible chroma format.
*/
static dirac_chroma_t GetDiracChromaFormat(enum PixelFormat ff_pix_fmt)
{
- int num_formats = sizeof(ffmpeg_dirac_pixel_format_map) /
- sizeof(ffmpeg_dirac_pixel_format_map[0]);
+ int num_formats = sizeof(dirac_pixel_format_map) /
+ sizeof(dirac_pixel_format_map[0]);
int idx;
for (idx = 0; idx < num_formats; ++idx)
- if (ffmpeg_dirac_pixel_format_map[idx].ff_pix_fmt == ff_pix_fmt)
- return ffmpeg_dirac_pixel_format_map[idx].dirac_pix_fmt;
+ if (dirac_pixel_format_map[idx].ff_pix_fmt == ff_pix_fmt)
+ return dirac_pixel_format_map[idx].dirac_pix_fmt;
return formatNK;
}
@@ -127,7 +127,7 @@ static VideoFormat GetDiracVideoFormatPreset(AVCodecContext *avccontext)
static av_cold int libdirac_encode_init(AVCodecContext *avccontext)
{
- FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data;
+ DiracEncoderParams* p_dirac_params = avccontext->priv_data;
int no_local = 1;
int verbose = avccontext->debug;
VideoFormat preset;
@@ -219,7 +219,7 @@ static av_cold int libdirac_encode_init(AVCodecContext *avccontext)
static void DiracFreeFrame(void *data)
{
- FfmpegDiracSchroEncodedFrame *enc_frame = data;
+ DiracSchroEncodedFrame *enc_frame = data;
av_freep(&(enc_frame->p_encbuf));
av_free(enc_frame);
@@ -231,9 +231,9 @@ static int libdirac_encode_frame(AVCodecContext *avccontext,
{
int enc_size = 0;
dirac_encoder_state_t state;
- FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data;
- FfmpegDiracSchroEncodedFrame* p_frame_output = NULL;
- FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL;
+ DiracEncoderParams *p_dirac_params = avccontext->priv_data;
+ DiracSchroEncodedFrame *p_frame_output = NULL;
+ DiracSchroEncodedFrame *p_next_output_frame = NULL;
int go = 1;
int last_frame_in_sequence = 0;
@@ -303,7 +303,7 @@ static int libdirac_encode_frame(AVCodecContext *avccontext,
break;
/* create output frame */
- p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame));
+ p_frame_output = av_mallocz(sizeof(DiracSchroEncodedFrame));
/* set output data */
p_frame_output->size = p_dirac_params->enc_buf_size;
p_frame_output->p_encbuf = p_dirac_params->enc_buf;
@@ -371,7 +371,7 @@ static int libdirac_encode_frame(AVCodecContext *avccontext,
static av_cold int libdirac_encode_close(AVCodecContext *avccontext)
{
- FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data;
+ DiracEncoderParams *p_dirac_params = avccontext->priv_data;
/* close the encoder */
dirac_encoder_close(p_dirac_params->p_encoder);
@@ -392,13 +392,13 @@ static av_cold int libdirac_encode_close(AVCodecContext *avccontext)
AVCodec ff_libdirac_encoder = {
- "libdirac",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DIRAC,
- sizeof(FfmpegDiracEncoderParams),
- libdirac_encode_init,
- libdirac_encode_frame,
- libdirac_encode_close,
+ .name = "libdirac",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DIRAC,
+ .priv_data_size = sizeof(DiracEncoderParams),
+ .init = libdirac_encode_init,
+ .encode = libdirac_encode_frame,
+ .close = libdirac_encode_close,
.capabilities = CODEC_CAP_DELAY,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("libdirac Dirac 2.2"),
diff --git a/libavcodec/libfaac.c b/libavcodec/libfaac.c
index 51d965e..7ee1f3c 100644
--- a/libavcodec/libfaac.c
+++ b/libavcodec/libfaac.c
@@ -155,13 +155,13 @@ static const AVProfile profiles[] = {
};
AVCodec ff_libfaac_encoder = {
- "libfaac",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_AAC,
- sizeof(FaacAudioContext),
- Faac_encode_init,
- Faac_encode_frame,
- Faac_encode_close,
+ .name = "libfaac",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AAC,
+ .priv_data_size = sizeof(FaacAudioContext),
+ .init = Faac_encode_init,
+ .encode = Faac_encode_frame,
+ .close = Faac_encode_close,
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Codec)"),
diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c
index 34f2957..16d9972 100644
--- a/libavcodec/libgsm.c
+++ b/libavcodec/libgsm.c
@@ -35,36 +35,26 @@
#define GSM_MS_BLOCK_SIZE 65
#define GSM_FRAME_SIZE 160
-static av_cold int libgsm_init(AVCodecContext *avctx) {
+static av_cold int libgsm_encode_init(AVCodecContext *avctx) {
if (avctx->channels > 1) {
av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n",
avctx->channels);
return -1;
}
- if(avctx->codec->decode){
- if(!avctx->channels)
- avctx->channels= 1;
-
- if(!avctx->sample_rate)
- avctx->sample_rate= 8000;
-
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- }else{
- if (avctx->sample_rate != 8000) {
- av_log(avctx, AV_LOG_ERROR, "Sample rate 8000Hz required for GSM, got %dHz\n",
- avctx->sample_rate);
- if(avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)
- return -1;
- }
- if (avctx->bit_rate != 13000 /* Official */ &&
- avctx->bit_rate != 13200 /* Very common */ &&
- avctx->bit_rate != 0 /* Unknown; a.o. mov does not set bitrate when decoding */ ) {
- av_log(avctx, AV_LOG_ERROR, "Bitrate 13000bps required for GSM, got %dbps\n",
- avctx->bit_rate);
- if(avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)
- return -1;
- }
+ if (avctx->sample_rate != 8000) {
+ av_log(avctx, AV_LOG_ERROR, "Sample rate 8000Hz required for GSM, got %dHz\n",
+ avctx->sample_rate);
+ if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)
+ return -1;
+ }
+ if (avctx->bit_rate != 13000 /* Official */ &&
+ avctx->bit_rate != 13200 /* Very common */ &&
+ avctx->bit_rate != 0 /* Unknown; a.o. mov does not set bitrate when decoding */ ) {
+ av_log(avctx, AV_LOG_ERROR, "Bitrate 13000bps required for GSM, got %dbps\n",
+ avctx->bit_rate);
+ if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)
+ return -1;
}
avctx->priv_data = gsm_create();
@@ -88,7 +78,7 @@ static av_cold int libgsm_init(AVCodecContext *avctx) {
return 0;
}
-static av_cold int libgsm_close(AVCodecContext *avctx) {
+static av_cold int libgsm_encode_close(AVCodecContext *avctx) {
av_freep(&avctx->coded_frame);
gsm_destroy(avctx->priv_data);
avctx->priv_data = NULL;
@@ -113,69 +103,145 @@ static int libgsm_encode_frame(AVCodecContext *avctx,
AVCodec ff_libgsm_encoder = {
- "libgsm",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_GSM,
- 0,
- libgsm_init,
- libgsm_encode_frame,
- libgsm_close,
+ .name = "libgsm",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_GSM,
+ .init = libgsm_encode_init,
+ .encode = libgsm_encode_frame,
+ .close = libgsm_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"),
};
AVCodec ff_libgsm_ms_encoder = {
- "libgsm_ms",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_GSM_MS,
- 0,
- libgsm_init,
- libgsm_encode_frame,
- libgsm_close,
+ .name = "libgsm_ms",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_GSM_MS,
+ .init = libgsm_encode_init,
+ .encode = libgsm_encode_frame,
+ .close = libgsm_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
};
-static int libgsm_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt) {
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- *data_size = 0; /* In case of error */
- if(buf_size < avctx->block_align) return -1;
+typedef struct LibGSMDecodeContext {
+ AVFrame frame;
+ struct gsm_state *state;
+} LibGSMDecodeContext;
+
+static av_cold int libgsm_decode_init(AVCodecContext *avctx) {
+ LibGSMDecodeContext *s = avctx->priv_data;
+
+ if (avctx->channels > 1) {
+ av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n",
+ avctx->channels);
+ return -1;
+ }
+
+ if (!avctx->channels)
+ avctx->channels = 1;
+
+ if (!avctx->sample_rate)
+ avctx->sample_rate = 8000;
+
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ s->state = gsm_create();
+
switch(avctx->codec_id) {
case CODEC_ID_GSM:
- if(gsm_decode(avctx->priv_data,buf,data)) return -1;
- *data_size = GSM_FRAME_SIZE*sizeof(int16_t);
+ avctx->frame_size = GSM_FRAME_SIZE;
+ avctx->block_align = GSM_BLOCK_SIZE;
break;
- case CODEC_ID_GSM_MS:
- if(gsm_decode(avctx->priv_data,buf,data) ||
- gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1;
- *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2;
+ case CODEC_ID_GSM_MS: {
+ int one = 1;
+ gsm_option(s->state, GSM_OPT_WAV49, &one);
+ avctx->frame_size = 2 * GSM_FRAME_SIZE;
+ avctx->block_align = GSM_MS_BLOCK_SIZE;
+ }
+ }
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
+ return 0;
+}
+
+static av_cold int libgsm_decode_close(AVCodecContext *avctx) {
+ LibGSMDecodeContext *s = avctx->priv_data;
+
+ gsm_destroy(s->state);
+ s->state = NULL;
+ return 0;
+}
+
+static int libgsm_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ int i, ret;
+ LibGSMDecodeContext *s = avctx->priv_data;
+ uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int16_t *samples;
+
+ if (buf_size < avctx->block_align) {
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* get output buffer */
+ s->frame.nb_samples = avctx->frame_size;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (int16_t *)s->frame.data[0];
+
+ for (i = 0; i < avctx->frame_size / GSM_FRAME_SIZE; i++) {
+ if ((ret = gsm_decode(s->state, buf, samples)) < 0)
+ return -1;
+ buf += GSM_BLOCK_SIZE;
+ samples += GSM_FRAME_SIZE;
}
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return avctx->block_align;
}
+static void libgsm_flush(AVCodecContext *avctx) {
+ LibGSMDecodeContext *s = avctx->priv_data;
+ int one = 1;
+
+ gsm_destroy(s->state);
+ s->state = gsm_create();
+ if (avctx->codec_id == CODEC_ID_GSM_MS)
+ gsm_option(s->state, GSM_OPT_WAV49, &one);
+}
+
AVCodec ff_libgsm_decoder = {
- "libgsm",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_GSM,
- 0,
- libgsm_init,
- NULL,
- libgsm_close,
- libgsm_decode_frame,
+ .name = "libgsm",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_GSM,
+ .priv_data_size = sizeof(LibGSMDecodeContext),
+ .init = libgsm_decode_init,
+ .close = libgsm_decode_close,
+ .decode = libgsm_decode_frame,
+ .flush = libgsm_flush,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"),
};
AVCodec ff_libgsm_ms_decoder = {
- "libgsm_ms",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_GSM_MS,
- 0,
- libgsm_init,
- NULL,
- libgsm_close,
- libgsm_decode_frame,
+ .name = "libgsm_ms",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_GSM_MS,
+ .priv_data_size = sizeof(LibGSMDecodeContext),
+ .init = libgsm_decode_init,
+ .close = libgsm_decode_close,
+ .decode = libgsm_decode_frame,
+ .flush = libgsm_flush,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
};
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
index 68f1bc9..f3c4528 100644
--- a/libavcodec/libmp3lame.c
+++ b/libavcodec/libmp3lame.c
@@ -25,16 +25,20 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
#include "avcodec.h"
#include "mpegaudio.h"
#include <lame/lame.h>
-#define BUFFER_SIZE (7200 + 2*MPA_FRAME_SIZE + MPA_FRAME_SIZE/4)
+#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4)
typedef struct Mp3AudioContext {
+ AVClass *class;
lame_global_flags *gfp;
int stereo;
uint8_t buffer[BUFFER_SIZE];
int buffer_index;
+ int reservoir;
} Mp3AudioContext;
static av_cold int MP3lame_encode_init(AVCodecContext *avctx)
@@ -51,27 +55,29 @@ static av_cold int MP3lame_encode_init(AVCodecContext *avctx)
lame_set_in_samplerate(s->gfp, avctx->sample_rate);
lame_set_out_samplerate(s->gfp, avctx->sample_rate);
lame_set_num_channels(s->gfp, avctx->channels);
- if(avctx->compression_level == FF_COMPRESSION_DEFAULT) {
+ if (avctx->compression_level == FF_COMPRESSION_DEFAULT) {
lame_set_quality(s->gfp, 5);
} else {
lame_set_quality(s->gfp, avctx->compression_level);
}
lame_set_mode(s->gfp, s->stereo ? JOINT_STEREO : MONO);
- lame_set_brate(s->gfp, avctx->bit_rate/1000);
- if(avctx->flags & CODEC_FLAG_QSCALE) {
+ lame_set_brate(s->gfp, avctx->bit_rate / 1000);
+ if (avctx->flags & CODEC_FLAG_QSCALE) {
lame_set_brate(s->gfp, 0);
lame_set_VBR(s->gfp, vbr_default);
- lame_set_VBR_quality(s->gfp, avctx->global_quality/(float)FF_QP2LAMBDA);
+ lame_set_VBR_quality(s->gfp, avctx->global_quality / (float)FF_QP2LAMBDA);
}
lame_set_bWriteVbrTag(s->gfp,0);
- lame_set_disable_reservoir(s->gfp, avctx->flags2 & CODEC_FLAG2_BIT_RESERVOIR ? 0 : 1);
+#if FF_API_LAME_GLOBAL_OPTS
+ s->reservoir = avctx->flags2 & CODEC_FLAG2_BIT_RESERVOIR;
+#endif
+ lame_set_disable_reservoir(s->gfp, !s->reservoir);
if (lame_init_params(s->gfp) < 0)
goto err_close;
- avctx->frame_size = lame_get_framesize(s->gfp);
-
- avctx->coded_frame= avcodec_alloc_frame();
- avctx->coded_frame->key_frame= 1;
+ avctx->frame_size = lame_get_framesize(s->gfp);
+ avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame->key_frame = 1;
return 0;
@@ -86,60 +92,62 @@ static const int sSampleRates[] = {
};
static const int sBitRates[2][3][15] = {
- { { 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448},
- { 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384},
- { 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320}
+ {
+ { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
+ { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
+ { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }
},
- { { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256},
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160},
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}
+ {
+ { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 },
+ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 },
+ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }
},
};
-static const int sSamplesPerFrame[2][3] =
-{
- { 384, 1152, 1152 },
- { 384, 1152, 576 }
+static const int sSamplesPerFrame[2][3] = {
+ { 384, 1152, 1152 },
+ { 384, 1152, 576 }
};
-static const int sBitsPerSlot[3] = {
- 32,
- 8,
- 8
-};
+static const int sBitsPerSlot[3] = { 32, 8, 8 };
static int mp3len(void *data, int *samplesPerFrame, int *sampleRate)
{
- uint32_t header = AV_RB32(data);
- int layerID = 3 - ((header >> 17) & 0x03);
- int bitRateID = ((header >> 12) & 0x0f);
+ uint32_t header = AV_RB32(data);
+ int layerID = 3 - ((header >> 17) & 0x03);
+ int bitRateID = ((header >> 12) & 0x0f);
int sampleRateID = ((header >> 10) & 0x03);
- int bitsPerSlot = sBitsPerSlot[layerID];
- int isPadded = ((header >> 9) & 0x01);
- static int const mode_tab[4]= {2,3,1,0};
- int mode= mode_tab[(header >> 19) & 0x03];
- int mpeg_id= mode>0;
+ int bitsPerSlot = sBitsPerSlot[layerID];
+ int isPadded = ((header >> 9) & 0x01);
+ static int const mode_tab[4] = { 2, 3, 1, 0 };
+ int mode = mode_tab[(header >> 19) & 0x03];
+ int mpeg_id = mode > 0;
int temp0, temp1, bitRate;
- if ( (( header >> 21 ) & 0x7ff) != 0x7ff || mode == 3 || layerID==3 || sampleRateID==3) {
+ if (((header >> 21) & 0x7ff) != 0x7ff || mode == 3 || layerID == 3 ||
+ sampleRateID == 3) {
return -1;
}
- if(!samplesPerFrame) samplesPerFrame= &temp0;
- if(!sampleRate ) sampleRate = &temp1;
+ if (!samplesPerFrame)
+ samplesPerFrame = &temp0;
+ if (!sampleRate)
+ sampleRate = &temp1;
-// *isMono = ((header >> 6) & 0x03) == 0x03;
+ //*isMono = ((header >> 6) & 0x03) == 0x03;
- *sampleRate = sSampleRates[sampleRateID]>>mode;
- bitRate = sBitRates[mpeg_id][layerID][bitRateID] * 1000;
+ *sampleRate = sSampleRates[sampleRateID] >> mode;
+ bitRate = sBitRates[mpeg_id][layerID][bitRateID] * 1000;
*samplesPerFrame = sSamplesPerFrame[mpeg_id][layerID];
-//av_log(NULL, AV_LOG_DEBUG, "sr:%d br:%d spf:%d l:%d m:%d\n", *sampleRate, bitRate, *samplesPerFrame, layerID, mode);
+ //av_log(NULL, AV_LOG_DEBUG,
+ // "sr:%d br:%d spf:%d l:%d m:%d\n",
+ // *sampleRate, bitRate, *samplesPerFrame, layerID, mode);
return *samplesPerFrame * bitRate / (bitsPerSlot * *sampleRate) + isPadded;
}
-static int MP3lame_encode_frame(AVCodecContext *avctx,
- unsigned char *frame, int buf_size, void *data)
+static int MP3lame_encode_frame(AVCodecContext *avctx, unsigned char *frame,
+ int buf_size, void *data)
{
Mp3AudioContext *s = avctx->priv_data;
int len;
@@ -147,59 +155,52 @@ static int MP3lame_encode_frame(AVCodecContext *avctx,
/* lame 3.91 dies on '1-channel interleaved' data */
- if(data){
+ if (data) {
if (s->stereo) {
- lame_result = lame_encode_buffer_interleaved(
- s->gfp,
- data,
- avctx->frame_size,
- s->buffer + s->buffer_index,
- BUFFER_SIZE - s->buffer_index
- );
+ lame_result = lame_encode_buffer_interleaved(s->gfp, data,
+ avctx->frame_size,
+ s->buffer + s->buffer_index,
+ BUFFER_SIZE - s->buffer_index);
} else {
- lame_result = lame_encode_buffer(
- s->gfp,
- data,
- data,
- avctx->frame_size,
- s->buffer + s->buffer_index,
- BUFFER_SIZE - s->buffer_index
- );
+ lame_result = lame_encode_buffer(s->gfp, data, data,
+ avctx->frame_size, s->buffer +
+ s->buffer_index, BUFFER_SIZE -
+ s->buffer_index);
}
- }else{
- lame_result= lame_encode_flush(
- s->gfp,
- s->buffer + s->buffer_index,
- BUFFER_SIZE - s->buffer_index
- );
+ } else {
+ lame_result = lame_encode_flush(s->gfp, s->buffer + s->buffer_index,
+ BUFFER_SIZE - s->buffer_index);
}
- if(lame_result < 0){
- if(lame_result==-1) {
+ if (lame_result < 0) {
+ if (lame_result == -1) {
/* output buffer too small */
- av_log(avctx, AV_LOG_ERROR, "lame: output buffer too small (buffer index: %d, free bytes: %d)\n", s->buffer_index, BUFFER_SIZE - s->buffer_index);
+ av_log(avctx, AV_LOG_ERROR,
+ "lame: output buffer too small (buffer index: %d, free bytes: %d)\n",
+ s->buffer_index, BUFFER_SIZE - s->buffer_index);
}
return -1;
}
s->buffer_index += lame_result;
- if(s->buffer_index<4)
+ if (s->buffer_index < 4)
return 0;
- len= mp3len(s->buffer, NULL, NULL);
-//av_log(avctx, AV_LOG_DEBUG, "in:%d packet-len:%d index:%d\n", avctx->frame_size, len, s->buffer_index);
- if(len <= s->buffer_index){
+ len = mp3len(s->buffer, NULL, NULL);
+ //av_log(avctx, AV_LOG_DEBUG, "in:%d packet-len:%d index:%d\n",
+ // avctx->frame_size, len, s->buffer_index);
+ if (len <= s->buffer_index) {
memcpy(frame, s->buffer, len);
s->buffer_index -= len;
- memmove(s->buffer, s->buffer+len, s->buffer_index);
- //FIXME fix the audio codec API, so we do not need the memcpy()
-/*for(i=0; i<len; i++){
- av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]);
-}*/
+ memmove(s->buffer, s->buffer + len, s->buffer_index);
+ // FIXME fix the audio codec API, so we do not need the memcpy()
+ /*for(i=0; i<len; i++) {
+ av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]);
+ }*/
return len;
- }else
+ } else
return 0;
}
@@ -213,17 +214,32 @@ static av_cold int MP3lame_encode_close(AVCodecContext *avctx)
return 0;
}
+#define OFFSET(x) offsetof(Mp3AudioContext, x)
+#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "reservoir", "Use bit reservoir.", OFFSET(reservoir), AV_OPT_TYPE_INT, { 1 }, 0, 1, AE },
+ { NULL },
+};
+
+static const AVClass libmp3lame_class = {
+ .class_name = "libmp3lame encoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
AVCodec ff_libmp3lame_encoder = {
- "libmp3lame",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP3,
- sizeof(Mp3AudioContext),
- MP3lame_encode_init,
- MP3lame_encode_frame,
- MP3lame_encode_close,
- .capabilities= CODEC_CAP_DELAY,
- .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
- .supported_samplerates= sSampleRates,
- .long_name= NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
+ .name = "libmp3lame",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP3,
+ .priv_data_size = sizeof(Mp3AudioContext),
+ .init = MP3lame_encode_init,
+ .encode = MP3lame_encode_frame,
+ .close = MP3lame_encode_close,
+ .capabilities = CODEC_CAP_DELAY,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+ .supported_samplerates = sSampleRates,
+ .long_name = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
+ .priv_class = &libmp3lame_class,
};
diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c
index cf8bdbb..ded9217 100644
--- a/libavcodec/libopencore-amr.c
+++ b/libavcodec/libopencore-amr.c
@@ -79,7 +79,7 @@ static int get_bitrate_mode(int bitrate, void *log_ctx)
typedef struct AMRContext {
AVClass *av_class;
- int frame_count;
+ AVFrame frame;
void *dec_state;
void *enc_state;
int enc_bitrate;
@@ -88,7 +88,7 @@ typedef struct AMRContext {
} AMRContext;
static const AVOption options[] = {
- { "dtx", "Allow DTX (generate comfort noise)", offsetof(AMRContext, enc_dtx), FF_OPT_TYPE_INT, 0, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
+ { "dtx", "Allow DTX (generate comfort noise)", offsetof(AMRContext, enc_dtx), AV_OPT_TYPE_INT, { 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
{ NULL }
};
@@ -100,7 +100,6 @@ static av_cold int amr_nb_decode_init(AVCodecContext *avctx)
{
AMRContext *s = avctx->priv_data;
- s->frame_count = 0;
s->dec_state = Decoder_Interface_init();
if (!s->dec_state) {
av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\n");
@@ -114,6 +113,9 @@ static av_cold int amr_nb_decode_init(AVCodecContext *avctx)
return AVERROR(ENOSYS);
}
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
@@ -122,21 +124,29 @@ static av_cold int amr_nb_decode_close(AVCodecContext *avctx)
AMRContext *s = avctx->priv_data;
Decoder_Interface_exit(s->dec_state);
+
return 0;
}
static int amr_nb_decode_frame(AVCodecContext *avctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
AMRContext *s = avctx->priv_data;
static const uint8_t block_size[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
enum Mode dec_mode;
- int packet_size;
+ int packet_size, ret;
av_dlog(avctx, "amr_decode_frame buf=%p buf_size=%d frame_count=%d!!\n",
- buf, buf_size, s->frame_count);
+ buf, buf_size, avctx->frame_number);
+
+ /* get output buffer */
+ s->frame.nb_samples = 160;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
dec_mode = (buf[0] >> 3) & 0x000F;
packet_size = block_size[dec_mode] + 1;
@@ -147,25 +157,26 @@ static int amr_nb_decode_frame(AVCodecContext *avctx, void *data,
return AVERROR_INVALIDDATA;
}
- s->frame_count++;
av_dlog(avctx, "packet_size=%d buf= 0x%X %X %X %X\n",
packet_size, buf[0], buf[1], buf[2], buf[3]);
/* call decoder */
- Decoder_Interface_Decode(s->dec_state, buf, data, 0);
- *data_size = 160 * 2;
+ Decoder_Interface_Decode(s->dec_state, buf, (short *)s->frame.data[0], 0);
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
return packet_size;
}
AVCodec ff_libopencore_amrnb_decoder = {
- "libopencore_amrnb",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_AMR_NB,
- sizeof(AMRContext),
- amr_nb_decode_init,
- NULL,
- amr_nb_decode_close,
- amr_nb_decode_frame,
+ .name = "libopencore_amrnb",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AMR_NB,
+ .priv_data_size = sizeof(AMRContext),
+ .init = amr_nb_decode_init,
+ .close = amr_nb_decode_close,
+ .decode = amr_nb_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band"),
};
@@ -173,8 +184,6 @@ static av_cold int amr_nb_encode_init(AVCodecContext *avctx)
{
AMRContext *s = avctx->priv_data;
- s->frame_count = 0;
-
if (avctx->sample_rate != 8000) {
av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n");
return AVERROR(ENOSYS);
@@ -230,14 +239,13 @@ static int amr_nb_encode_frame(AVCodecContext *avctx,
}
AVCodec ff_libopencore_amrnb_encoder = {
- "libopencore_amrnb",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_AMR_NB,
- sizeof(AMRContext),
- amr_nb_encode_init,
- amr_nb_encode_frame,
- amr_nb_encode_close,
- NULL,
+ .name = "libopencore_amrnb",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AMR_NB,
+ .priv_data_size = sizeof(AMRContext),
+ .init = amr_nb_encode_init,
+ .encode = amr_nb_encode_frame,
+ .close = amr_nb_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band"),
.priv_class = &class,
@@ -252,6 +260,7 @@ AVCodec ff_libopencore_amrnb_encoder = {
#include <opencore-amrwb/if_rom.h>
typedef struct AMRWBContext {
+ AVFrame frame;
void *state;
} AMRWBContext;
@@ -268,22 +277,28 @@ static av_cold int amr_wb_decode_init(AVCodecContext *avctx)
return AVERROR(ENOSYS);
}
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
static int amr_wb_decode_frame(AVCodecContext *avctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
AMRWBContext *s = avctx->priv_data;
- int mode;
+ int mode, ret;
int packet_size;
static const uint8_t block_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
- if (!buf_size)
- /* nothing to do */
- return 0;
+ /* get output buffer */
+ s->frame.nb_samples = 320;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
mode = (buf[0] >> 3) & 0x000F;
packet_size = block_size[mode];
@@ -294,8 +309,11 @@ static int amr_wb_decode_frame(AVCodecContext *avctx, void *data,
return AVERROR_INVALIDDATA;
}
- D_IF_decode(s->state, buf, data, _good_frame);
- *data_size = 320 * 2;
+ D_IF_decode(s->state, buf, (short *)s->frame.data[0], _good_frame);
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return packet_size;
}
@@ -308,14 +326,14 @@ static int amr_wb_decode_close(AVCodecContext *avctx)
}
AVCodec ff_libopencore_amrwb_decoder = {
- "libopencore_amrwb",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_AMR_WB,
- sizeof(AMRWBContext),
- amr_wb_decode_init,
- NULL,
- amr_wb_decode_close,
- amr_wb_decode_frame,
+ .name = "libopencore_amrwb",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AMR_WB,
+ .priv_data_size = sizeof(AMRWBContext),
+ .init = amr_wb_decode_init,
+ .close = amr_wb_decode_close,
+ .decode = amr_wb_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Wide-Band"),
};
diff --git a/libavcodec/libopenjpeg.c b/libavcodec/libopenjpeg.c
index 342dcd9..1facd21 100644
--- a/libavcodec/libopenjpeg.c
+++ b/libavcodec/libopenjpeg.c
@@ -27,6 +27,7 @@
#include "libavutil/imgutils.h"
#include "avcodec.h"
#include "libavutil/intreadwrite.h"
+#include "thread.h"
#define OPJ_STATIC
#include <openjpeg.h>
@@ -57,11 +58,19 @@ static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx)
return 0;
}
+static av_cold int libopenjpeg_decode_init_thread_copy(AVCodecContext *avctx)
+{
+ LibOpenJPEGContext *ctx = avctx->priv_data;
+
+ avctx->coded_frame = &ctx->image;
+ return 0;
+}
+
static int libopenjpeg_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
+ uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
LibOpenJPEGContext *ctx = avctx->priv_data;
AVFrame *picture = &ctx->image, *output = data;
@@ -94,7 +103,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
}
opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
- ctx->dec_params.cp_reduce = avctx->lowres;
+ ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
// Tie decoder with decoding parameters
opj_setup_decoder(dec, &ctx->dec_params);
stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
@@ -104,7 +113,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
return -1;
}
- // Decode the codestream
+ // Decode the header only
image = opj_decode_with_info(dec, stream, NULL);
opj_cio_close(stream);
if(!image) {
@@ -112,8 +121,8 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
opj_destroy_decompress(dec);
return -1;
}
- width = image->comps[0].w << avctx->lowres;
- height = image->comps[0].h << avctx->lowres;
+ width = image->x1 - image->x0;
+ height = image->y1 - image->y0;
if(av_image_check_size(width, height, 0, avctx) < 0) {
av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height);
goto done;
@@ -139,13 +148,30 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
}
if(picture->data[0])
- avctx->release_buffer(avctx, picture);
+ ff_thread_release_buffer(avctx, picture);
+
+ if(ff_thread_get_buffer(avctx, picture) < 0){
+ av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n");
+ return -1;
+ }
- if(avctx->get_buffer(avctx, picture) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n");
+ ff_thread_finish_setup(avctx);
+
+ ctx->dec_params.cp_limit_decoding = NO_LIMITATION;
+ ctx->dec_params.cp_reduce = avctx->lowres;
+ // Tie decoder with decoding parameters
+ opj_setup_decoder(dec, &ctx->dec_params);
+ stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
+ if(!stream) {
+ av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n");
+ opj_destroy_decompress(dec);
return -1;
}
+ // Decode the codestream
+ image = opj_decode_with_info(dec, stream, NULL);
+ opj_cio_close(stream);
+
for(x = 0; x < image->numcomps; x++) {
adjust[x] = FFMAX(image->comps[x].prec - 8, 0);
}
@@ -179,21 +205,21 @@ static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx)
LibOpenJPEGContext *ctx = avctx->priv_data;
if(ctx->image.data[0])
- avctx->release_buffer(avctx, &ctx->image);
+ ff_thread_release_buffer(avctx, &ctx->image);
return 0 ;
}
AVCodec ff_libopenjpeg_decoder = {
- "libopenjpeg",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_JPEG2000,
- sizeof(LibOpenJPEGContext),
- libopenjpeg_decode_init,
- NULL,
- libopenjpeg_decode_close,
- libopenjpeg_decode_frame,
- CODEC_CAP_DR1,
- .max_lowres = 5,
- .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"),
-} ;
+ .name = "libopenjpeg",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_JPEG2000,
+ .priv_data_size = sizeof(LibOpenJPEGContext),
+ .init = libopenjpeg_decode_init,
+ .close = libopenjpeg_decode_close,
+ .decode = libopenjpeg_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+ .max_lowres = 5,
+ .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"),
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy)
+};
diff --git a/libavcodec/libschroedinger.c b/libavcodec/libschroedinger.c
index 804d652..527c492 100644
--- a/libavcodec/libschroedinger.c
+++ b/libavcodec/libschroedinger.c
@@ -20,7 +20,7 @@
/**
* @file
-* function definitions common to libschroedingerdec.c and libschroedingerenc.c
+* function definitions common to libschroedinger decoder and encoder
*/
#include "libdirac_libschro.h"
@@ -64,14 +64,14 @@ SchroVideoFormatEnum ff_get_schro_video_format_preset(AVCodecContext *avccontext
int ff_get_schro_frame_format (SchroChromaFormat schro_pix_fmt,
SchroFrameFormat *schro_frame_fmt)
{
- unsigned int num_formats = sizeof(ffmpeg_schro_pixel_format_map) /
- sizeof(ffmpeg_schro_pixel_format_map[0]);
+ unsigned int num_formats = sizeof(schro_pixel_format_map) /
+ sizeof(schro_pixel_format_map[0]);
int idx;
for (idx = 0; idx < num_formats; ++idx) {
- if (ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt) {
- *schro_frame_fmt = ffmpeg_schro_pixel_format_map[idx].schro_frame_fmt;
+ if (schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt) {
+ *schro_frame_fmt = schro_pixel_format_map[idx].schro_frame_fmt;
return 0;
}
}
diff --git a/libavcodec/libschroedinger.h b/libavcodec/libschroedinger.h
index c9e2a5e..8147821 100644
--- a/libavcodec/libschroedinger.h
+++ b/libavcodec/libschroedinger.h
@@ -20,7 +20,7 @@
/**
* @file
-* data structures common to libschroedingerdec.c and libschroedingerenc.c
+* data structures common to libschroedinger decoder and encoder
*/
#ifndef AVCODEC_LIBSCHROEDINGER_H
@@ -34,7 +34,7 @@ static const struct {
enum PixelFormat ff_pix_fmt;
SchroChromaFormat schro_pix_fmt;
SchroFrameFormat schro_frame_fmt;
-} ffmpeg_schro_pixel_format_map[] = {
+} schro_pixel_format_map[] = {
{ PIX_FMT_YUV420P, SCHRO_CHROMA_420, SCHRO_FRAME_FORMAT_U8_420 },
{ PIX_FMT_YUV422P, SCHRO_CHROMA_422, SCHRO_FRAME_FORMAT_U8_422 },
{ PIX_FMT_YUV444P, SCHRO_CHROMA_444, SCHRO_FRAME_FORMAT_U8_444 },
diff --git a/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c
index ee29704..184e8cb 100644
--- a/libavcodec/libschroedingerdec.c
+++ b/libavcodec/libschroedingerdec.c
@@ -41,7 +41,7 @@
#include <schroedinger/schrovideoformat.h>
/** libschroedinger decoder private data */
-typedef struct FfmpegSchroDecoderParams {
+typedef struct SchroDecoderParams {
/** Schroedinger video format */
SchroVideoFormat *format;
@@ -52,7 +52,7 @@ typedef struct FfmpegSchroDecoderParams {
SchroDecoder* decoder;
/** queue storing decoded frames */
- FfmpegDiracSchroQueue dec_frame_queue;
+ DiracSchroQueue dec_frame_queue;
/** end of sequence signalled */
int eos_signalled;
@@ -62,25 +62,25 @@ typedef struct FfmpegSchroDecoderParams {
/** decoded picture */
AVPicture dec_pic;
-} FfmpegSchroDecoderParams;
+} SchroDecoderParams;
-typedef struct FfmpegSchroParseUnitContext {
+typedef struct SchroParseUnitContext {
const uint8_t *buf;
int buf_size;
-} FfmpegSchroParseUnitContext;
+} SchroParseUnitContext;
static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf,
void *priv);
-static void FfmpegSchroParseContextInit(FfmpegSchroParseUnitContext *parse_ctx,
- const uint8_t *buf, int buf_size)
+static void SchroParseContextInit(SchroParseUnitContext *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)
+static SchroBuffer *FindNextSchroParseUnit(SchroParseUnitContext *parse_ctx)
{
SchroBuffer *enc_buf = NULL;
int next_pu_offset = 0;
@@ -120,22 +120,22 @@ static SchroBuffer* FfmpegFindNextSchroParseUnit(FfmpegSchroParseUnitContext *pa
/**
* Returns Libav chroma format.
*/
-static enum PixelFormat GetFfmpegChromaFormat(SchroChromaFormat schro_pix_fmt)
+static enum PixelFormat get_chroma_format(SchroChromaFormat schro_pix_fmt)
{
- int num_formats = sizeof(ffmpeg_schro_pixel_format_map) /
- sizeof(ffmpeg_schro_pixel_format_map[0]);
+ int num_formats = sizeof(schro_pixel_format_map) /
+ sizeof(schro_pixel_format_map[0]);
int idx;
for (idx = 0; idx < num_formats; ++idx)
- if (ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt)
- return ffmpeg_schro_pixel_format_map[idx].ff_pix_fmt;
+ if (schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt)
+ return schro_pixel_format_map[idx].ff_pix_fmt;
return PIX_FMT_NONE;
}
static av_cold int libschroedinger_decode_init(AVCodecContext *avccontext)
{
- FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
+ SchroDecoderParams *p_schro_params = avccontext->priv_data;
/* First of all, initialize our supporting libraries. */
schro_init();
@@ -164,7 +164,7 @@ static void libschroedinger_decode_frame_free(void *frame)
static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext)
{
- FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
+ SchroDecoderParams *p_schro_params = avccontext->priv_data;
SchroDecoder *decoder = p_schro_params->decoder;
p_schro_params->format = schro_decoder_get_video_format(decoder);
@@ -179,7 +179,7 @@ static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext)
}
avccontext->height = p_schro_params->format->height;
avccontext->width = p_schro_params->format->width;
- avccontext->pix_fmt = GetFfmpegChromaFormat(p_schro_params->format->chroma_format);
+ avccontext->pix_fmt = get_chroma_format(p_schro_params->format->chroma_format);
if (ff_get_schro_frame_format(p_schro_params->format->chroma_format,
&p_schro_params->frame_format) == -1) {
@@ -206,20 +206,19 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
+ SchroDecoderParams *p_schro_params = avccontext->priv_data;
SchroDecoder *decoder = p_schro_params->decoder;
- SchroVideoFormat *format;
AVPicture *picture = data;
SchroBuffer *enc_buf;
SchroFrame* frame;
int state;
int go = 1;
int outer = 1;
- FfmpegSchroParseUnitContext parse_ctx;
+ SchroParseUnitContext parse_ctx;
*data_size = 0;
- FfmpegSchroParseContextInit(&parse_ctx, buf, buf_size);
+ SchroParseContextInit(&parse_ctx, buf, buf_size);
if (!buf_size) {
if (!p_schro_params->eos_signalled) {
state = schro_decoder_push_end_of_stream(decoder);
@@ -229,7 +228,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
/* Loop through all the individual parse units in the input buffer */
do {
- if ((enc_buf = FfmpegFindNextSchroParseUnit(&parse_ctx))) {
+ if ((enc_buf = FindNextSchroParseUnit(&parse_ctx))) {
/* Push buffer into decoder. */
if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) &&
SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0)
@@ -240,7 +239,6 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
go = 1;
} else
outer = 0;
- format = p_schro_params->format;
while (go) {
/* Parse data and process result. */
@@ -316,7 +314,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext)
{
- FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
+ SchroDecoderParams *p_schro_params = avccontext->priv_data;
/* Free the decoder. */
schro_decoder_free(p_schro_params->decoder);
av_freep(&p_schro_params->format);
@@ -334,7 +332,7 @@ static void libschroedinger_flush(AVCodecContext *avccontext)
{
/* Got a seek request. Free the decoded frames queue and then reset
* the decoder */
- FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
+ SchroDecoderParams *p_schro_params = avccontext->priv_data;
/* Free data in the output frame queue. */
ff_dirac_schro_queue_free(&p_schro_params->dec_frame_queue,
@@ -347,15 +345,14 @@ static void libschroedinger_flush(AVCodecContext *avccontext)
}
AVCodec ff_libschroedinger_decoder = {
- "libschroedinger",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DIRAC,
- sizeof(FfmpegSchroDecoderParams),
- libschroedinger_decode_init,
- NULL,
- libschroedinger_decode_close,
- libschroedinger_decode_frame,
- CODEC_CAP_DELAY,
+ .name = "libschroedinger",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DIRAC,
+ .priv_data_size = sizeof(SchroDecoderParams),
+ .init = libschroedinger_decode_init,
+ .close = libschroedinger_decode_close,
+ .decode = libschroedinger_decode_frame,
+ .capabilities = CODEC_CAP_DELAY,
.flush = libschroedinger_flush,
.long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
};
diff --git a/libavcodec/libschroedingerenc.c b/libavcodec/libschroedingerenc.c
index d7190d0..dec9c2a 100644
--- a/libavcodec/libschroedingerenc.c
+++ b/libavcodec/libschroedingerenc.c
@@ -41,7 +41,7 @@
/** libschroedinger encoder private data */
-typedef struct FfmpegSchroEncoderParams {
+typedef struct SchroEncoderParams {
/** Schroedinger video format */
SchroVideoFormat *format;
@@ -64,31 +64,31 @@ typedef struct FfmpegSchroEncoderParams {
int enc_buf_size;
/** queue storing encoded frames */
- FfmpegDiracSchroQueue enc_frame_queue;
+ DiracSchroQueue enc_frame_queue;
/** end of sequence signalled */
int eos_signalled;
/** end of sequence pulled */
int eos_pulled;
-} FfmpegSchroEncoderParams;
+} SchroEncoderParams;
/**
* Works out Schro-compatible chroma format.
*/
static int SetSchroChromaFormat(AVCodecContext *avccontext)
{
- int num_formats = sizeof(ffmpeg_schro_pixel_format_map) /
- sizeof(ffmpeg_schro_pixel_format_map[0]);
+ int num_formats = sizeof(schro_pixel_format_map) /
+ sizeof(schro_pixel_format_map[0]);
int idx;
- FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data;
+ SchroEncoderParams *p_schro_params = avccontext->priv_data;
for (idx = 0; idx < num_formats; ++idx) {
- if (ffmpeg_schro_pixel_format_map[idx].ff_pix_fmt ==
+ if (schro_pixel_format_map[idx].ff_pix_fmt ==
avccontext->pix_fmt) {
p_schro_params->format->chroma_format =
- ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt;
+ schro_pixel_format_map[idx].schro_pix_fmt;
return 0;
}
}
@@ -102,7 +102,7 @@ static int SetSchroChromaFormat(AVCodecContext *avccontext)
static int libschroedinger_encode_init(AVCodecContext *avccontext)
{
- FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data;
+ SchroEncoderParams *p_schro_params = avccontext->priv_data;
SchroVideoFormatEnum preset;
/* Initialize the libraries that libschroedinger depends on. */
@@ -238,7 +238,7 @@ static int libschroedinger_encode_init(AVCodecContext *avccontext)
static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avccontext,
void *in_data)
{
- FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data;
+ SchroEncoderParams *p_schro_params = avccontext->priv_data;
SchroFrame *in_frame;
/* Input line size may differ from what the codec supports. Especially
* when transcoding from one format to another. So use avpicture_layout
@@ -256,7 +256,7 @@ static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avccontext,
static void SchroedingerFreeFrame(void *data)
{
- FfmpegDiracSchroEncodedFrame *enc_frame = data;
+ DiracSchroEncodedFrame *enc_frame = data;
av_freep(&(enc_frame->p_encbuf));
av_free(enc_frame);
@@ -267,9 +267,9 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext,
int buf_size, void *data)
{
int enc_size = 0;
- FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data;
+ SchroEncoderParams *p_schro_params = avccontext->priv_data;
SchroEncoder *encoder = p_schro_params->encoder;
- struct FfmpegDiracSchroEncodedFrame* p_frame_output = NULL;
+ struct DiracSchroEncodedFrame *p_frame_output = NULL;
int go = 1;
SchroBuffer *enc_buf;
int presentation_frame;
@@ -328,7 +328,7 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext,
}
/* Create output frame. */
- p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame));
+ p_frame_output = av_mallocz(sizeof(DiracSchroEncodedFrame));
/* Set output data. */
p_frame_output->size = p_schro_params->enc_buf_size;
p_frame_output->p_encbuf = p_schro_params->enc_buf;
@@ -400,8 +400,7 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext,
static int libschroedinger_encode_close(AVCodecContext *avccontext)
{
-
- FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data;
+ SchroEncoderParams *p_schro_params = avccontext->priv_data;
/* Close the encoder. */
schro_encoder_free(p_schro_params->encoder);
@@ -423,13 +422,13 @@ static int libschroedinger_encode_close(AVCodecContext *avccontext)
AVCodec ff_libschroedinger_encoder = {
- "libschroedinger",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_DIRAC,
- sizeof(FfmpegSchroEncoderParams),
- libschroedinger_encode_init,
- libschroedinger_encode_frame,
- libschroedinger_encode_close,
+ .name = "libschroedinger",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_DIRAC,
+ .priv_data_size = sizeof(SchroEncoderParams),
+ .init = libschroedinger_encode_init,
+ .encode = libschroedinger_encode_frame,
+ .close = libschroedinger_encode_close,
.capabilities = CODEC_CAP_DELAY,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c
index e6626dc..eba2f16 100644
--- a/libavcodec/libspeexdec.c
+++ b/libavcodec/libspeexdec.c
@@ -18,13 +18,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "avcodec.h"
#include <speex/speex.h>
#include <speex/speex_header.h>
#include <speex/speex_stereo.h>
#include <speex/speex_callbacks.h>
+#include "avcodec.h"
typedef struct {
+ AVFrame frame;
SpeexBits bits;
SpeexStereoState stereo;
void *dec_state;
@@ -60,14 +61,14 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx)
mode = speex_lib_get_mode(s->header->mode);
if (!mode) {
av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", s->header->mode);
- return -1;
+ return AVERROR_INVALIDDATA;
}
} else
av_log(avctx, AV_LOG_INFO, "Missing Speex header, assuming defaults.\n");
if (avctx->channels > 2) {
av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n");
- return -1;
+ return AVERROR(EINVAL);
}
speex_bits_init(&s->bits);
@@ -89,42 +90,57 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx)
s->stereo = (SpeexStereoState)SPEEX_STEREO_STATE_INIT;
speex_decoder_ctl(s->dec_state, SPEEX_SET_HANDLER, &callback);
}
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
-static int libspeex_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int libspeex_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
+ uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
LibSpeexContext *s = avctx->priv_data;
- int16_t *output = data, *end;
- int i, num_samples;
-
- num_samples = s->frame_size * avctx->channels;
- end = output + *data_size / sizeof(*output);
-
- speex_bits_read_from(&s->bits, buf, buf_size);
-
- for (i = 0; speex_bits_remaining(&s->bits) && output + num_samples < end; i++) {
- int ret = speex_decode_int(s->dec_state, &s->bits, output);
- if (ret <= -2) {
- av_log(avctx, AV_LOG_ERROR, "Error decoding Speex frame.\n");
- return -1;
- } else if (ret == -1)
- // end of stream
- break;
-
- if (avctx->channels == 2)
- speex_decode_stereo_int(output, s->frame_size, &s->stereo);
+ int16_t *output;
+ int ret, consumed = 0;
+
+ /* get output buffer */
+ s->frame.nb_samples = s->frame_size;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ output = (int16_t *)s->frame.data[0];
+
+ /* if there is not enough data left for the smallest possible frame,
+ reset the libspeex buffer using the current packet, otherwise ignore
+ the current packet and keep decoding frames from the libspeex buffer. */
+ if (speex_bits_remaining(&s->bits) < 43) {
+ /* check for flush packet */
+ if (!buf || !buf_size) {
+ *got_frame_ptr = 0;
+ return buf_size;
+ }
+ /* set new buffer */
+ speex_bits_read_from(&s->bits, buf, buf_size);
+ consumed = buf_size;
+ }
- output += num_samples;
+ /* decode a single frame */
+ ret = speex_decode_int(s->dec_state, &s->bits, output);
+ if (ret <= -2) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding Speex frame.\n");
+ return AVERROR_INVALIDDATA;
}
+ if (avctx->channels == 2)
+ speex_decode_stereo_int(output, s->frame_size, &s->stereo);
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
- avctx->frame_size = s->frame_size * i;
- *data_size = avctx->channels * avctx->frame_size * sizeof(*output);
- return buf_size;
+ return consumed;
}
static av_cold int libspeex_decode_close(AVCodecContext *avctx)
@@ -138,14 +154,21 @@ static av_cold int libspeex_decode_close(AVCodecContext *avctx)
return 0;
}
+static av_cold void libspeex_decode_flush(AVCodecContext *avctx)
+{
+ LibSpeexContext *s = avctx->priv_data;
+ speex_bits_reset(&s->bits);
+}
+
AVCodec ff_libspeex_decoder = {
- "libspeex",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_SPEEX,
- sizeof(LibSpeexContext),
- libspeex_decode_init,
- NULL,
- libspeex_decode_close,
- libspeex_decode_frame,
+ .name = "libspeex",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_SPEEX,
+ .priv_data_size = sizeof(LibSpeexContext),
+ .init = libspeex_decode_init,
+ .close = libspeex_decode_close,
+ .decode = libspeex_decode_frame,
+ .flush = libspeex_decode_flush,
+ .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DELAY | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"),
};
diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c
new file mode 100644
index 0000000..18f973f
--- /dev/null
+++ b/libavcodec/libspeexenc.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2009 Justin Ruggles
+ * Copyright (c) 2009 Xuggle Incorporated
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * libspeex Speex audio encoder
+ *
+ * Usage Guide
+ * This explains the values that need to be set prior to initialization in
+ * order to control various encoding parameters.
+ *
+ * Channels
+ * Speex only supports mono or stereo, so avctx->channels must be set to
+ * 1 or 2.
+ *
+ * Sample Rate / Encoding Mode
+ * Speex has 3 modes, each of which uses a specific sample rate.
+ * narrowband : 8 kHz
+ * wideband : 16 kHz
+ * ultra-wideband : 32 kHz
+ * avctx->sample_rate must be set to one of these 3 values. This will be
+ * used to set the encoding mode.
+ *
+ * Rate Control
+ * VBR mode is turned on by setting CODEC_FLAG_QSCALE in avctx->flags.
+ * avctx->global_quality is used to set the encoding quality.
+ * For CBR mode, avctx->bit_rate can be used to set the constant bitrate.
+ * Alternatively, the 'cbr_quality' option can be set from 0 to 10 to set
+ * a constant bitrate based on quality.
+ * For ABR mode, set avctx->bit_rate and set the 'abr' option to 1.
+ * Approx. Bitrate Range:
+ * narrowband : 2400 - 25600 bps
+ * wideband : 4000 - 43200 bps
+ * ultra-wideband : 4400 - 45200 bps
+ *
+ * Complexity
+ * Encoding complexity is controlled by setting avctx->compression_level.
+ * The valid range is 0 to 10. A higher setting gives generally better
+ * quality at the expense of encoding speed. This does not affect the
+ * bit rate.
+ *
+ * Frames-per-Packet
+ * The encoder defaults to using 1 frame-per-packet. However, it is
+ * sometimes desirable to use multiple frames-per-packet to reduce the
+ * amount of container overhead. This can be done by setting the
+ * 'frames_per_packet' option to a value 1 to 8.
+ */
+
+#include <speex/speex.h>
+#include <speex/speex_header.h>
+#include <speex/speex_stereo.h>
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+
+typedef struct {
+ AVClass *class; ///< AVClass for private options
+ SpeexBits bits; ///< libspeex bitwriter context
+ SpeexHeader header; ///< libspeex header struct
+ void *enc_state; ///< libspeex encoder state
+ int frames_per_packet; ///< number of frames to encode in each packet
+ float vbr_quality; ///< VBR quality 0.0 to 10.0
+ int cbr_quality; ///< CBR quality 0 to 10
+ int abr; ///< flag to enable ABR
+ int pkt_frame_count; ///< frame count for the current packet
+ int lookahead; ///< encoder delay
+ int sample_count; ///< total sample count (used for pts)
+} LibSpeexEncContext;
+
+static av_cold void print_enc_params(AVCodecContext *avctx,
+ LibSpeexEncContext *s)
+{
+ const char *mode_str = "unknown";
+
+ av_log(avctx, AV_LOG_DEBUG, "channels: %d\n", avctx->channels);
+ switch (s->header.mode) {
+ case SPEEX_MODEID_NB: mode_str = "narrowband"; break;
+ case SPEEX_MODEID_WB: mode_str = "wideband"; break;
+ case SPEEX_MODEID_UWB: mode_str = "ultra-wideband"; break;
+ }
+ av_log(avctx, AV_LOG_DEBUG, "mode: %s\n", mode_str);
+ if (s->header.vbr) {
+ av_log(avctx, AV_LOG_DEBUG, "rate control: VBR\n");
+ av_log(avctx, AV_LOG_DEBUG, " quality: %f\n", s->vbr_quality);
+ } else if (s->abr) {
+ av_log(avctx, AV_LOG_DEBUG, "rate control: ABR\n");
+ av_log(avctx, AV_LOG_DEBUG, " bitrate: %d bps\n", avctx->bit_rate);
+ } else {
+ av_log(avctx, AV_LOG_DEBUG, "rate control: CBR\n");
+ av_log(avctx, AV_LOG_DEBUG, " bitrate: %d bps\n", avctx->bit_rate);
+ }
+ av_log(avctx, AV_LOG_DEBUG, "complexity: %d\n",
+ avctx->compression_level);
+ av_log(avctx, AV_LOG_DEBUG, "frame size: %d samples\n",
+ avctx->frame_size);
+ av_log(avctx, AV_LOG_DEBUG, "frames per packet: %d\n",
+ s->frames_per_packet);
+ av_log(avctx, AV_LOG_DEBUG, "packet size: %d\n",
+ avctx->frame_size * s->frames_per_packet);
+}
+
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+ LibSpeexEncContext *s = avctx->priv_data;
+ const SpeexMode *mode;
+ uint8_t *header_data;
+ int header_size;
+ int32_t complexity;
+
+ /* channels */
+ if (avctx->channels < 1 || avctx->channels > 2) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid channels (%d). Only stereo and "
+ "mono are supported\n", avctx->channels);
+ return AVERROR(EINVAL);
+ }
+
+ /* sample rate and encoding mode */
+ switch (avctx->sample_rate) {
+ case 8000: mode = &speex_nb_mode; break;
+ case 16000: mode = &speex_wb_mode; break;
+ case 32000: mode = &speex_uwb_mode; break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Sample rate of %d Hz is not supported. "
+ "Resample to 8, 16, or 32 kHz.\n", avctx->sample_rate);
+ return AVERROR(EINVAL);
+ }
+
+ /* initialize libspeex */
+ s->enc_state = speex_encoder_init(mode);
+ if (!s->enc_state) {
+ av_log(avctx, AV_LOG_ERROR, "Error initializing libspeex\n");
+ return -1;
+ }
+ speex_init_header(&s->header, avctx->sample_rate, avctx->channels, mode);
+
+ /* rate control method and parameters */
+ if (avctx->flags & CODEC_FLAG_QSCALE) {
+ /* VBR */
+ s->header.vbr = 1;
+ speex_encoder_ctl(s->enc_state, SPEEX_SET_VBR, &s->header.vbr);
+ s->vbr_quality = av_clipf(avctx->global_quality / (float)FF_QP2LAMBDA,
+ 0.0f, 10.0f);
+ speex_encoder_ctl(s->enc_state, SPEEX_SET_VBR_QUALITY, &s->vbr_quality);
+ } else {
+ s->header.bitrate = avctx->bit_rate;
+ if (avctx->bit_rate > 0) {
+ /* CBR or ABR by bitrate */
+ if (s->abr) {
+ speex_encoder_ctl(s->enc_state, SPEEX_SET_ABR,
+ &s->header.bitrate);
+ speex_encoder_ctl(s->enc_state, SPEEX_GET_ABR,
+ &s->header.bitrate);
+ } else {
+ speex_encoder_ctl(s->enc_state, SPEEX_SET_BITRATE,
+ &s->header.bitrate);
+ speex_encoder_ctl(s->enc_state, SPEEX_GET_BITRATE,
+ &s->header.bitrate);
+ }
+ } else {
+ /* CBR by quality */
+ speex_encoder_ctl(s->enc_state, SPEEX_SET_QUALITY,
+ &s->cbr_quality);
+ speex_encoder_ctl(s->enc_state, SPEEX_GET_BITRATE,
+ &s->header.bitrate);
+ }
+ /* stereo side information adds about 800 bps to the base bitrate */
+ /* TODO: this should be calculated exactly */
+ avctx->bit_rate = s->header.bitrate + (avctx->channels == 2 ? 800 : 0);
+ }
+
+ /* set encoding complexity */
+ if (avctx->compression_level > FF_COMPRESSION_DEFAULT) {
+ complexity = av_clip(avctx->compression_level, 0, 10);
+ speex_encoder_ctl(s->enc_state, SPEEX_SET_COMPLEXITY, &complexity);
+ }
+ speex_encoder_ctl(s->enc_state, SPEEX_GET_COMPLEXITY, &complexity);
+ avctx->compression_level = complexity;
+
+ /* set packet size */
+ avctx->frame_size = s->header.frame_size;
+ s->header.frames_per_packet = s->frames_per_packet;
+
+ /* set encoding delay */
+ speex_encoder_ctl(s->enc_state, SPEEX_GET_LOOKAHEAD, &s->lookahead);
+ s->sample_count = -s->lookahead;
+
+ /* create header packet bytes from header struct */
+ /* note: libspeex allocates the memory for header_data, which is freed
+ below with speex_header_free() */
+ header_data = speex_header_to_packet(&s->header, &header_size);
+
+ /* allocate extradata and coded_frame */
+ avctx->extradata = av_malloc(header_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ avctx->coded_frame = avcodec_alloc_frame();
+ if (!avctx->extradata || !avctx->coded_frame) {
+ speex_header_free(header_data);
+ speex_encoder_destroy(s->enc_state);
+ av_log(avctx, AV_LOG_ERROR, "memory allocation error\n");
+ return AVERROR(ENOMEM);
+ }
+
+ /* copy header packet to extradata */
+ memcpy(avctx->extradata, header_data, header_size);
+ avctx->extradata_size = header_size;
+ speex_header_free(header_data);
+
+ /* init libspeex bitwriter */
+ speex_bits_init(&s->bits);
+
+ print_enc_params(avctx, s);
+ return 0;
+}
+
+static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size,
+ void *data)
+{
+ LibSpeexEncContext *s = avctx->priv_data;
+ int16_t *samples = data;
+ int sample_count = s->sample_count;
+
+ if (data) {
+ /* encode Speex frame */
+ if (avctx->channels == 2)
+ speex_encode_stereo_int(samples, s->header.frame_size, &s->bits);
+ speex_encode_int(s->enc_state, samples, &s->bits);
+ s->pkt_frame_count++;
+ s->sample_count += avctx->frame_size;
+ } else {
+ /* handle end-of-stream */
+ if (!s->pkt_frame_count)
+ return 0;
+ /* add extra terminator codes for unused frames in last packet */
+ while (s->pkt_frame_count < s->frames_per_packet) {
+ speex_bits_pack(&s->bits, 15, 5);
+ s->pkt_frame_count++;
+ }
+ }
+
+ /* write output if all frames for the packet have been encoded */
+ if (s->pkt_frame_count == s->frames_per_packet) {
+ s->pkt_frame_count = 0;
+ avctx->coded_frame->pts =
+ av_rescale_q(sample_count, (AVRational){ 1, avctx->sample_rate },
+ avctx->time_base);
+ if (buf_size > speex_bits_nbytes(&s->bits)) {
+ int ret = speex_bits_write(&s->bits, frame, buf_size);
+ speex_bits_reset(&s->bits);
+ return ret;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "output buffer too small");
+ return AVERROR(EINVAL);
+ }
+ }
+ return 0;
+}
+
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+ LibSpeexEncContext *s = avctx->priv_data;
+
+ speex_bits_destroy(&s->bits);
+ speex_encoder_destroy(s->enc_state);
+
+ av_freep(&avctx->coded_frame);
+ av_freep(&avctx->extradata);
+
+ return 0;
+}
+
+#define OFFSET(x) offsetof(LibSpeexEncContext, x)
+#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "abr", "Use average bit rate", OFFSET(abr), AV_OPT_TYPE_INT, { 0 }, 0, 1, AE },
+ { "cbr_quality", "Set quality value (0 to 10) for CBR", OFFSET(cbr_quality), AV_OPT_TYPE_INT, { 8 }, 0, 10, AE },
+ { "frames_per_packet", "Number of frames to encode in each packet", OFFSET(frames_per_packet), AV_OPT_TYPE_INT, { 1 }, 1, 8, AE },
+ { NULL },
+};
+
+static const AVClass class = {
+ .class_name = "libspeex",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVCodecDefault defaults[] = {
+ { "b", "0" },
+ { "compression_level", "3" },
+ { NULL },
+};
+
+AVCodec ff_libspeex_encoder = {
+ .name = "libspeex",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_SPEEX,
+ .priv_data_size = sizeof(LibSpeexEncContext),
+ .init = encode_init,
+ .encode = encode_frame,
+ .close = encode_close,
+ .capabilities = CODEC_CAP_DELAY,
+ .sample_fmts = (const enum SampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
+ .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"),
+ .priv_class = &class,
+ .defaults = defaults,
+};
diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c
index 86cc09f..eccecea 100644
--- a/libavcodec/libtheoraenc.c
+++ b/libavcodec/libtheoraenc.c
@@ -241,7 +241,7 @@ static av_cold int encode_init(AVCodecContext* avc_context)
header, comment, and tables.
Each one is prefixed with a 16bit size, then they
- are concatenated together into ffmpeg's extradata.
+ are concatenated together into libavcodec's extradata.
*/
offset = 0;
diff --git a/libavcodec/libvo-aacenc.c b/libavcodec/libvo-aacenc.c
index 5a75bcb..647971a 100644
--- a/libavcodec/libvo-aacenc.c
+++ b/libavcodec/libvo-aacenc.c
@@ -63,7 +63,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
}
for (index = 0; index < 16; index++)
- if (avctx->sample_rate == ff_mpeg4audio_sample_rates[index])
+ if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[index])
break;
if (index == 16) {
av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n",
@@ -116,14 +116,13 @@ static int aac_encode_frame(AVCodecContext *avctx,
}
AVCodec ff_libvo_aacenc_encoder = {
- "libvo_aacenc",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_AAC,
- sizeof(AACContext),
- aac_encode_init,
- aac_encode_frame,
- aac_encode_close,
- NULL,
+ .name = "libvo_aacenc",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AAC,
+ .priv_data_size = sizeof(AACContext),
+ .init = aac_encode_init,
+ .encode = aac_encode_frame,
+ .close = aac_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Android VisualOn AAC"),
};
diff --git a/libavcodec/libvo-amrwbenc.c b/libavcodec/libvo-amrwbenc.c
index b3615ed..f39317e 100644
--- a/libavcodec/libvo-amrwbenc.c
+++ b/libavcodec/libvo-amrwbenc.c
@@ -34,7 +34,7 @@ typedef struct AMRWBContext {
} AMRWBContext;
static const AVOption options[] = {
- { "dtx", "Allow DTX (generate comfort noise)", offsetof(AMRWBContext, allow_dtx), FF_OPT_TYPE_INT, 0, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
+ { "dtx", "Allow DTX (generate comfort noise)", offsetof(AMRWBContext, allow_dtx), AV_OPT_TYPE_INT, { 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
{ NULL }
};
@@ -118,14 +118,13 @@ static int amr_wb_encode_frame(AVCodecContext *avctx,
}
AVCodec ff_libvo_amrwbenc_encoder = {
- "libvo_amrwbenc",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_AMR_WB,
- sizeof(AMRWBContext),
- amr_wb_encode_init,
- amr_wb_encode_frame,
- amr_wb_encode_close,
- NULL,
+ .name = "libvo_amrwbenc",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_AMR_WB,
+ .priv_data_size = sizeof(AMRWBContext),
+ .init = amr_wb_encode_init,
+ .encode = amr_wb_encode_frame,
+ .close = amr_wb_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Android VisualOn Adaptive Multi-Rate "
"(AMR) Wide-Band"),
diff --git a/libavcodec/libvorbis.c b/libavcodec/libvorbis.c
index 85cb9c5..28e313a 100644
--- a/libavcodec/libvorbis.c
+++ b/libavcodec/libvorbis.c
@@ -37,63 +37,65 @@
#define OGGVORBIS_FRAME_SIZE 64
-#define BUFFER_SIZE (1024*64)
+#define BUFFER_SIZE (1024 * 64)
typedef struct OggVorbisContext {
AVClass *av_class;
- vorbis_info vi ;
- vorbis_dsp_state vd ;
- vorbis_block vb ;
+ vorbis_info vi;
+ vorbis_dsp_state vd;
+ vorbis_block vb;
uint8_t buffer[BUFFER_SIZE];
int buffer_index;
int eof;
/* decoder */
- vorbis_comment vc ;
+ vorbis_comment vc;
ogg_packet op;
double iblock;
-} OggVorbisContext ;
+} OggVorbisContext;
-static const AVOption options[]={
-{"iblock", "Sets the impulse block bias", offsetof(OggVorbisContext, iblock), FF_OPT_TYPE_DOUBLE, {.dbl = 0}, -15, 0, AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_ENCODING_PARAM},
-{NULL}
+static const AVOption options[] = {
+ { "iblock", "Sets the impulse block bias", offsetof(OggVorbisContext, iblock), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -15, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL }
};
static const AVClass class = { "libvorbis", av_default_item_name, options, LIBAVUTIL_VERSION_INT };
-static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext) {
- OggVorbisContext *context = avccontext->priv_data ;
+static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext)
+{
+ OggVorbisContext *context = avccontext->priv_data;
double cfreq;
- if(avccontext->flags & CODEC_FLAG_QSCALE) {
+ if (avccontext->flags & CODEC_FLAG_QSCALE) {
/* variable bitrate */
- if(vorbis_encode_setup_vbr(vi, avccontext->channels,
- avccontext->sample_rate,
- avccontext->global_quality / (float)FF_QP2LAMBDA / 10.0))
+ if (vorbis_encode_setup_vbr(vi, avccontext->channels,
+ avccontext->sample_rate,
+ avccontext->global_quality / (float)FF_QP2LAMBDA / 10.0))
return -1;
} else {
int minrate = avccontext->rc_min_rate > 0 ? avccontext->rc_min_rate : -1;
int maxrate = avccontext->rc_min_rate > 0 ? avccontext->rc_max_rate : -1;
/* constant bitrate */
- if(vorbis_encode_setup_managed(vi, avccontext->channels,
- avccontext->sample_rate, minrate, avccontext->bit_rate, maxrate))
+ if (vorbis_encode_setup_managed(vi, avccontext->channels,
+ avccontext->sample_rate, minrate,
+ avccontext->bit_rate, maxrate))
return -1;
/* variable bitrate by estimate, disable slow rate management */
- if(minrate == -1 && maxrate == -1)
- if(vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL))
+ if (minrate == -1 && maxrate == -1)
+ if (vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL))
return -1;
}
/* cutoff frequency */
- if(avccontext->cutoff > 0) {
+ if (avccontext->cutoff > 0) {
cfreq = avccontext->cutoff / 1000.0;
- if(vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq))
+ if (vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq))
return -1;
}
- if(context->iblock){
+ if (context->iblock) {
vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &context->iblock);
}
@@ -101,35 +103,39 @@ static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avcco
}
/* How many bytes are needed for a buffer of length 'l' */
-static int xiph_len(int l) { return (1 + l / 255 + l); }
+static int xiph_len(int l)
+{
+ return (1 + l / 255 + l);
+}
-static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext) {
- OggVorbisContext *context = avccontext->priv_data ;
+static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext)
+{
+ OggVorbisContext *context = avccontext->priv_data;
ogg_packet header, header_comm, header_code;
uint8_t *p;
unsigned int offset;
- vorbis_info_init(&context->vi) ;
- if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) {
- av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed\n") ;
- return -1 ;
+ vorbis_info_init(&context->vi);
+ if (oggvorbis_init_encoder(&context->vi, avccontext) < 0) {
+ av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed\n");
+ return -1;
}
- vorbis_analysis_init(&context->vd, &context->vi) ;
- vorbis_block_init(&context->vd, &context->vb) ;
+ vorbis_analysis_init(&context->vd, &context->vi);
+ vorbis_block_init(&context->vd, &context->vb);
vorbis_comment_init(&context->vc);
- vorbis_comment_add_tag(&context->vc, "encoder", LIBAVCODEC_IDENT) ;
+ vorbis_comment_add_tag(&context->vc, "encoder", LIBAVCODEC_IDENT);
vorbis_analysis_headerout(&context->vd, &context->vc, &header,
- &header_comm, &header_code);
+ &header_comm, &header_code);
- avccontext->extradata_size=
+ avccontext->extradata_size =
1 + xiph_len(header.bytes) + xiph_len(header_comm.bytes) +
header_code.bytes;
p = avccontext->extradata =
- av_malloc(avccontext->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
- p[0] = 2;
- offset = 1;
+ av_malloc(avccontext->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ p[0] = 2;
+ offset = 1;
offset += av_xiphlacing(&p[offset], header.bytes);
offset += av_xiphlacing(&p[offset], header_comm.bytes);
memcpy(&p[offset], header.packet, header.bytes);
@@ -140,56 +146,57 @@ static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext) {
offset += header_code.bytes;
assert(offset == avccontext->extradata_size);
-/* vorbis_block_clear(&context->vb);
+#if 0
+ vorbis_block_clear(&context->vb);
vorbis_dsp_clear(&context->vd);
- vorbis_info_clear(&context->vi);*/
+ vorbis_info_clear(&context->vi);
+#endif
vorbis_comment_clear(&context->vc);
- avccontext->frame_size = OGGVORBIS_FRAME_SIZE ;
+ avccontext->frame_size = OGGVORBIS_FRAME_SIZE;
- avccontext->coded_frame= avcodec_alloc_frame();
- avccontext->coded_frame->key_frame= 1;
+ avccontext->coded_frame = avcodec_alloc_frame();
+ avccontext->coded_frame->key_frame = 1;
- return 0 ;
+ return 0;
}
-
static int oggvorbis_encode_frame(AVCodecContext *avccontext,
unsigned char *packets,
- int buf_size, void *data)
+ int buf_size, void *data)
{
- OggVorbisContext *context = avccontext->priv_data ;
- ogg_packet op ;
- signed short *audio = data ;
+ OggVorbisContext *context = avccontext->priv_data;
+ ogg_packet op;
+ signed short *audio = data;
int l;
- if(data) {
+ if (data) {
const int samples = avccontext->frame_size;
- float **buffer ;
+ float **buffer;
int c, channels = context->vi.channels;
- buffer = vorbis_analysis_buffer(&context->vd, samples) ;
+ buffer = vorbis_analysis_buffer(&context->vd, samples);
for (c = 0; c < channels; c++) {
int co = (channels > 8) ? c :
- ff_vorbis_encoding_channel_layout_offsets[channels-1][c];
- for(l = 0 ; l < samples ; l++)
- buffer[c][l]=audio[l*channels+co]/32768.f;
+ ff_vorbis_encoding_channel_layout_offsets[channels - 1][c];
+ for (l = 0; l < samples; l++)
+ buffer[c][l] = audio[l * channels + co] / 32768.f;
}
- vorbis_analysis_wrote(&context->vd, samples) ;
+ vorbis_analysis_wrote(&context->vd, samples);
} else {
- if(!context->eof)
- vorbis_analysis_wrote(&context->vd, 0) ;
+ if (!context->eof)
+ vorbis_analysis_wrote(&context->vd, 0);
context->eof = 1;
}
- while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) {
+ while (vorbis_analysis_blockout(&context->vd, &context->vb) == 1) {
vorbis_analysis(&context->vb, NULL);
- vorbis_bitrate_addblock(&context->vb) ;
+ vorbis_bitrate_addblock(&context->vb);
- while(vorbis_bitrate_flushpacket(&context->vd, &op)) {
+ while (vorbis_bitrate_flushpacket(&context->vd, &op)) {
/* i'd love to say the following line is a hack, but sadly it's
* not, apparently the end of stream decision is in libogg. */
- if(op.bytes==1 && op.e_o_s)
+ if (op.bytes == 1 && op.e_o_s)
continue;
if (context->buffer_index + sizeof(ogg_packet) + op.bytes > BUFFER_SIZE) {
av_log(avccontext, AV_LOG_ERROR, "libvorbis: buffer overflow.");
@@ -203,13 +210,13 @@ static int oggvorbis_encode_frame(AVCodecContext *avccontext,
}
}
- l=0;
- if(context->buffer_index){
- ogg_packet *op2= (ogg_packet*)context->buffer;
+ l = 0;
+ if (context->buffer_index) {
+ ogg_packet *op2 = (ogg_packet *)context->buffer;
op2->packet = context->buffer + sizeof(ogg_packet);
- l= op2->bytes;
- avccontext->coded_frame->pts= av_rescale_q(op2->granulepos, (AVRational){1, avccontext->sample_rate}, avccontext->time_base);
+ l = op2->bytes;
+ avccontext->coded_frame->pts = av_rescale_q(op2->granulepos, (AVRational) { 1, avccontext->sample_rate }, avccontext->time_base);
//FIXME we should reorder the user supplied pts and not assume that they are spaced by 1/sample_rate
if (l > buf_size) {
@@ -226,12 +233,12 @@ static int oggvorbis_encode_frame(AVCodecContext *avccontext,
return l;
}
-
-static av_cold int oggvorbis_encode_close(AVCodecContext *avccontext) {
- OggVorbisContext *context = avccontext->priv_data ;
+static av_cold int oggvorbis_encode_close(AVCodecContext *avccontext)
+{
+ OggVorbisContext *context = avccontext->priv_data;
/* ogg_packet op ; */
- vorbis_analysis_wrote(&context->vd, 0) ; /* notify vorbisenc this is EOF */
+ vorbis_analysis_wrote(&context->vd, 0); /* notify vorbisenc this is EOF */
vorbis_block_clear(&context->vb);
vorbis_dsp_clear(&context->vd);
@@ -240,20 +247,19 @@ static av_cold int oggvorbis_encode_close(AVCodecContext *avccontext) {
av_freep(&avccontext->coded_frame);
av_freep(&avccontext->extradata);
- return 0 ;
+ return 0;
}
-
AVCodec ff_libvorbis_encoder = {
- "libvorbis",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_VORBIS,
- sizeof(OggVorbisContext),
- oggvorbis_encode_init,
- oggvorbis_encode_frame,
- oggvorbis_encode_close,
- .capabilities= CODEC_CAP_DELAY,
- .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
- .long_name= NULL_IF_CONFIG_SMALL("libvorbis Vorbis"),
- .priv_class= &class,
-} ;
+ .name = "libvorbis",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_VORBIS,
+ .priv_data_size = sizeof(OggVorbisContext),
+ .init = oggvorbis_encode_init,
+ .encode = oggvorbis_encode_frame,
+ .close = oggvorbis_encode_close,
+ .capabilities = CODEC_CAP_DELAY,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
+ .long_name = NULL_IF_CONFIG_SMALL("libvorbis Vorbis"),
+ .priv_class = &class,
+};
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c
index 2aa077c..5acd0f9 100644
--- a/libavcodec/libvpxdec.c
+++ b/libavcodec/libvpxdec.c
@@ -112,14 +112,12 @@ static av_cold int vp8_free(AVCodecContext *avctx)
}
AVCodec ff_libvpx_decoder = {
- "libvpx",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VP8,
- sizeof(VP8Context),
- vp8_init,
- NULL, /* encode */
- vp8_free,
- vp8_decode,
- 0, /* capabilities */
+ .name = "libvpx",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VP8,
+ .priv_data_size = sizeof(VP8Context),
+ .init = vp8_init,
+ .close = vp8_free,
+ .decode = vp8_decode,
.long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"),
};
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index ca2e615..fce3de0 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -29,8 +29,10 @@
#include <vpx/vp8cx.h>
#include "avcodec.h"
+#include "internal.h"
#include "libavutil/base64.h"
#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
/**
* Portion of struct vpx_codec_cx_pkt from vpx_encoder.h.
@@ -48,11 +50,19 @@ struct FrameListData {
};
typedef struct VP8EncoderContext {
+ AVClass *class;
struct vpx_codec_ctx encoder;
struct vpx_image rawimg;
struct vpx_fixed_buf twopass_stats;
unsigned long deadline; //i.e., RT/GOOD/BEST
struct FrameListData *coded_frame_list;
+ int cpu_used;
+ int auto_alt_ref;
+ int arnr_max_frames;
+ int arnr_strength;
+ int arnr_type;
+ int lag_in_frames;
+ int error_resilient;
} VP8Context;
/** String mappings for enum vp8e_enc_control_id */
@@ -205,7 +215,6 @@ static av_cold int vp8_init(AVCodecContext *avctx)
{
VP8Context *ctx = avctx->priv_data;
const struct vpx_codec_iface *iface = &vpx_codec_vp8_cx_algo;
- int cpuused = 3;
struct vpx_codec_enc_cfg enccfg;
int res;
@@ -225,6 +234,9 @@ static av_cold int vp8_init(AVCodecContext *avctx)
enccfg.g_timebase.den = avctx->time_base.den;
enccfg.g_threads = avctx->thread_count;
+ if (ctx->lag_in_frames >= 0)
+ enccfg.g_lag_in_frames = ctx->lag_in_frames;
+
if (avctx->flags & CODEC_FLAG_PASS1)
enccfg.g_pass = VPX_RC_FIRST_PASS;
else if (avctx->flags & CODEC_FLAG_PASS2)
@@ -237,9 +249,10 @@ static av_cold int vp8_init(AVCodecContext *avctx)
enccfg.rc_end_usage = VPX_CBR;
enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000,
AV_ROUND_NEAR_INF);
-
- enccfg.rc_min_quantizer = avctx->qmin;
- enccfg.rc_max_quantizer = avctx->qmax;
+ if (avctx->qmin > 0)
+ enccfg.rc_min_quantizer = avctx->qmin;
+ if (avctx->qmax > 0)
+ enccfg.rc_max_quantizer = avctx->qmax;
enccfg.rc_dropframe_thresh = avctx->frame_skip_threshold;
//0-100 (0 => CBR, 100 => VBR)
@@ -259,9 +272,10 @@ static av_cold int vp8_init(AVCodecContext *avctx)
enccfg.rc_buf_optimal_sz = enccfg.rc_buf_sz * 5 / 6;
//_enc_init() will balk if kf_min_dist differs from max w/VPX_KF_AUTO
- if (avctx->keyint_min == avctx->gop_size)
+ if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size)
enccfg.kf_min_dist = avctx->keyint_min;
- enccfg.kf_max_dist = avctx->gop_size;
+ if (avctx->gop_size >= 0)
+ enccfg.kf_max_dist = avctx->gop_size;
if (enccfg.g_pass == VPX_RC_FIRST_PASS)
enccfg.g_lag_in_frames = 0;
@@ -292,13 +306,14 @@ static av_cold int vp8_init(AVCodecContext *avctx)
enccfg.rc_twopass_stats_in = ctx->twopass_stats;
}
- ctx->deadline = VPX_DL_GOOD_QUALITY;
/* 0-3: For non-zero values the encoder increasingly optimizes for reduced
complexity playback on low powered devices at the expense of encode
quality. */
if (avctx->profile != FF_PROFILE_UNKNOWN)
enccfg.g_profile = avctx->profile;
+ enccfg.g_error_resilient = ctx->error_resilient;
+
dump_enc_cfg(avctx, &enccfg);
/* Construct Encoder Context */
res = vpx_codec_enc_init(&ctx->encoder, iface, &enccfg, 0);
@@ -309,7 +324,16 @@ static av_cold int vp8_init(AVCodecContext *avctx)
//codec control failures are currently treated only as warnings
av_log(avctx, AV_LOG_DEBUG, "vpx_codec_control\n");
- codecctl_int(avctx, VP8E_SET_CPUUSED, cpuused);
+ if (ctx->cpu_used != INT_MIN)
+ codecctl_int(avctx, VP8E_SET_CPUUSED, ctx->cpu_used);
+ if (ctx->auto_alt_ref >= 0)
+ codecctl_int(avctx, VP8E_SET_ENABLEAUTOALTREF, ctx->auto_alt_ref);
+ if (ctx->arnr_max_frames >= 0)
+ codecctl_int(avctx, VP8E_SET_ARNR_MAXFRAMES, ctx->arnr_max_frames);
+ if (ctx->arnr_strength >= 0)
+ codecctl_int(avctx, VP8E_SET_ARNR_STRENGTH, ctx->arnr_strength);
+ if (ctx->arnr_type >= 0)
+ codecctl_int(avctx, VP8E_SET_ARNR_TYPE, ctx->arnr_type);
codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction);
codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS, av_log2(avctx->slices));
codecctl_int(avctx, VP8E_SET_STATIC_THRESHOLD, avctx->mb_threshold);
@@ -496,16 +520,61 @@ static int vp8_encode(AVCodecContext *avctx, uint8_t *buf, int buf_size,
return coded_size;
}
+#define OFFSET(x) offsetof(VP8Context, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "cpu-used", "Quality/Speed ratio modifier", OFFSET(cpu_used), AV_OPT_TYPE_INT, {INT_MIN}, INT_MIN, INT_MAX, VE},
+ { "auto-alt-ref", "Enable use of alternate reference "
+ "frames (2-pass only)", OFFSET(auto_alt_ref), AV_OPT_TYPE_INT, {-1}, -1, 1, VE},
+ { "lag-in-frames", "Number of frames to look ahead for "
+ "alternate reference frame selection", OFFSET(lag_in_frames), AV_OPT_TYPE_INT, {-1}, -1, INT_MAX, VE},
+ { "arnr-maxframes", "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {-1}, -1, INT_MAX, VE},
+ { "arnr-strength", "altref noise reduction filter strength", OFFSET(arnr_strength), AV_OPT_TYPE_INT, {-1}, -1, INT_MAX, VE},
+ { "arnr-type", "altref noise reduction filter type", OFFSET(arnr_type), AV_OPT_TYPE_INT, {-1}, -1, INT_MAX, VE, "arnr_type"},
+ { "backward", NULL, 0, AV_OPT_TYPE_CONST, {1}, 0, 0, VE, "arnr_type" },
+ { "forward", NULL, 0, AV_OPT_TYPE_CONST, {2}, 0, 0, VE, "arnr_type" },
+ { "centered", NULL, 0, AV_OPT_TYPE_CONST, {3}, 0, 0, VE, "arnr_type" },
+ { "deadline", "Time to spend encoding, in microseconds.", OFFSET(deadline), AV_OPT_TYPE_INT, {VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"},
+ { "best", NULL, 0, AV_OPT_TYPE_CONST, {VPX_DL_BEST_QUALITY}, 0, 0, VE, "quality"},
+ { "good", NULL, 0, AV_OPT_TYPE_CONST, {VPX_DL_GOOD_QUALITY}, 0, 0, VE, "quality"},
+ { "realtime", NULL, 0, AV_OPT_TYPE_CONST, {VPX_DL_REALTIME}, 0, 0, VE, "quality"},
+ { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, VE, "er"},
+#ifdef VPX_ERROR_RESILIENT_DEFAULT
+ { "default", "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {VPX_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"},
+ { "partitions", "The frame partitions are independently decodable "
+ "by the bool decoder, meaning that partitions can be decoded even "
+ "though earlier partitions have been lost. Note that intra predicition"
+ " is still done over the partition boundary.", 0, AV_OPT_TYPE_CONST, {VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"},
+#endif
+ { NULL }
+};
+
+static const AVClass class = {
+ .class_name = "libvpx encoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVCodecDefault defaults[] = {
+ { "qmin", "-1" },
+ { "qmax", "-1" },
+ { "g", "-1" },
+ { "keyint_min", "-1" },
+ { NULL },
+};
+
AVCodec ff_libvpx_encoder = {
- "libvpx",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VP8,
- sizeof(VP8Context),
- vp8_init,
- vp8_encode,
- vp8_free,
- NULL,
- CODEC_CAP_DELAY,
+ .name = "libvpx",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VP8,
+ .priv_data_size = sizeof(VP8Context),
+ .init = vp8_init,
+ .encode = vp8_encode,
+ .close = vp8_free,
+ .capabilities = CODEC_CAP_DELAY,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"),
+ .priv_class = &class,
+ .defaults = defaults,
};
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 74ee1d4..c525808 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -19,20 +19,53 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
#include "avcodec.h"
+#include "internal.h"
#include <x264.h>
+#include <float.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct X264Context {
+ AVClass *class;
x264_param_t params;
x264_t *enc;
x264_picture_t pic;
uint8_t *sei;
int sei_size;
AVFrame out_pic;
+ char *preset;
+ char *tune;
+ char *profile;
+ int fastfirstpass;
+ float crf;
+ float crf_max;
+ int cqp;
+ int aq_mode;
+ float aq_strength;
+ char *psy_rd;
+ int psy;
+ int rc_lookahead;
+ int weightp;
+ int weightb;
+ int ssim;
+ int intra_refresh;
+ int b_bias;
+ int b_pyramid;
+ int mixed_refs;
+ int dct8x8;
+ int fast_pskip;
+ int aud;
+ int mbtree;
+ char *deblock;
+ float cplxblur;
+ char *partitions;
+ int direct_pred;
+ int slice_max_size;
} X264Context;
static void X264_log(void *p, int level, const char *fmt, va_list args)
@@ -90,7 +123,9 @@ static int X264_frame(AVCodecContext *ctx, uint8_t *buf,
x264_picture_t pic_out;
x264_picture_init( &x4->pic );
- x4->pic.img.i_csp = X264_CSP_I420;
+ x4->pic.img.i_csp = x4->params.i_csp;
+ if (x264_bit_depth > 8)
+ x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH;
x4->pic.img.i_plane = 3;
if (frame) {
@@ -157,25 +192,61 @@ static av_cold int X264_close(AVCodecContext *avctx)
return 0;
}
+static int convert_pix_fmt(enum PixelFormat pix_fmt)
+{
+ switch (pix_fmt) {
+ case PIX_FMT_YUV420P:
+ case PIX_FMT_YUVJ420P:
+ case PIX_FMT_YUV420P9:
+ case PIX_FMT_YUV420P10: return X264_CSP_I420;
+ case PIX_FMT_YUV422P:
+ case PIX_FMT_YUV422P10: return X264_CSP_I422;
+ case PIX_FMT_YUV444P:
+ case PIX_FMT_YUV444P9:
+ case PIX_FMT_YUV444P10: return X264_CSP_I444;
+ };
+ return 0;
+}
+
+#define PARSE_X264_OPT(name, var)\
+ if (x4->var && x264_param_parse(&x4->params, name, x4->var) < 0) {\
+ av_log(avctx, AV_LOG_ERROR, "Error parsing option '%s' with value '%s'.\n", name, x4->var);\
+ return AVERROR(EINVAL);\
+ }
+
static av_cold int X264_init(AVCodecContext *avctx)
{
X264Context *x4 = avctx->priv_data;
- x4->sei_size = 0;
x264_param_default(&x4->params);
+ x4->params.b_deblocking_filter = avctx->flags & CODEC_FLAG_LOOP_FILTER;
+
+ if (x4->preset || x4->tune)
+ if (x264_param_default_preset(&x4->params, x4->preset, x4->tune) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error setting preset/tune %s/%s.\n", x4->preset, x4->tune);
+ return AVERROR(EINVAL);
+ }
+
+ if (avctx->level > 0)
+ x4->params.i_level_idc = avctx->level;
+
x4->params.pf_log = X264_log;
x4->params.p_log_private = avctx;
+ x4->params.i_log_level = X264_LOG_DEBUG;
+ x4->params.i_csp = convert_pix_fmt(avctx->pix_fmt);
- x4->params.i_keyint_max = avctx->gop_size;
- x4->params.b_intra_refresh = avctx->flags2 & CODEC_FLAG2_INTRA_REFRESH;
- x4->params.rc.i_bitrate = avctx->bit_rate / 1000;
+ if (avctx->bit_rate) {
+ x4->params.rc.i_bitrate = avctx->bit_rate / 1000;
+ x4->params.rc.i_rc_method = X264_RC_ABR;
+ }
x4->params.rc.i_vbv_buffer_size = avctx->rc_buffer_size / 1000;
x4->params.rc.i_vbv_max_bitrate = avctx->rc_max_rate / 1000;
x4->params.rc.b_stat_write = avctx->flags & CODEC_FLAG_PASS1;
if (avctx->flags & CODEC_FLAG_PASS2) {
x4->params.rc.b_stat_read = 1;
} else {
+#if FF_API_X264_GLOBAL_OPTS
if (avctx->crf) {
x4->params.rc.i_rc_method = X264_RC_CRF;
x4->params.rc.f_rf_constant = avctx->crf;
@@ -184,48 +255,53 @@ static av_cold int X264_init(AVCodecContext *avctx)
x4->params.rc.i_rc_method = X264_RC_CQP;
x4->params.rc.i_qp_constant = avctx->cqp;
}
- }
-
- // if neither crf nor cqp modes are selected we have to enable the RC
- // we do it this way because we cannot check if the bitrate has been set
- if (!(avctx->crf || (avctx->cqp > -1)))
- x4->params.rc.i_rc_method = X264_RC_ABR;
-
- x4->params.i_bframe = avctx->max_b_frames;
- x4->params.b_cabac = avctx->coder_type == FF_CODER_TYPE_AC;
- x4->params.i_bframe_adaptive = avctx->b_frame_strategy;
- x4->params.i_bframe_bias = avctx->bframebias;
- x4->params.i_bframe_pyramid = avctx->flags2 & CODEC_FLAG2_BPYRAMID ? X264_B_PYRAMID_NORMAL : X264_B_PYRAMID_NONE;
- avctx->has_b_frames = avctx->flags2 & CODEC_FLAG2_BPYRAMID ? 2 : !!avctx->max_b_frames;
-
- x4->params.i_keyint_min = avctx->keyint_min;
- if (x4->params.i_keyint_min > x4->params.i_keyint_max)
- x4->params.i_keyint_min = x4->params.i_keyint_max;
-
- x4->params.i_scenecut_threshold = avctx->scenechange_threshold;
+#endif
- x4->params.b_deblocking_filter = avctx->flags & CODEC_FLAG_LOOP_FILTER;
- x4->params.i_deblocking_filter_alphac0 = avctx->deblockalpha;
- x4->params.i_deblocking_filter_beta = avctx->deblockbeta;
-
- x4->params.rc.i_qp_min = avctx->qmin;
- x4->params.rc.i_qp_max = avctx->qmax;
- x4->params.rc.i_qp_step = avctx->max_qdiff;
+ if (x4->crf >= 0) {
+ x4->params.rc.i_rc_method = X264_RC_CRF;
+ x4->params.rc.f_rf_constant = x4->crf;
+ } else if (x4->cqp >= 0) {
+ x4->params.rc.i_rc_method = X264_RC_CQP;
+ x4->params.rc.i_qp_constant = x4->cqp;
+ }
- x4->params.rc.f_qcompress = avctx->qcompress; /* 0.0 => cbr, 1.0 => constant qp */
- x4->params.rc.f_qblur = avctx->qblur; /* temporally blur quants */
- x4->params.rc.f_complexity_blur = avctx->complexityblur;
+ if (x4->crf_max >= 0)
+ x4->params.rc.f_rf_constant_max = x4->crf_max;
+ }
- x4->params.i_frame_reference = avctx->refs;
+ if (avctx->rc_buffer_size && avctx->rc_initial_buffer_occupancy &&
+ (avctx->rc_initial_buffer_occupancy <= avctx->rc_buffer_size)) {
+ x4->params.rc.f_vbv_buffer_init =
+ (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size;
+ }
- x4->params.i_width = avctx->width;
- x4->params.i_height = avctx->height;
- x4->params.vui.i_sar_width = avctx->sample_aspect_ratio.num;
- x4->params.vui.i_sar_height = avctx->sample_aspect_ratio.den;
- x4->params.i_fps_num = x4->params.i_timebase_den = avctx->time_base.den;
- x4->params.i_fps_den = x4->params.i_timebase_num = avctx->time_base.num;
+ x4->params.rc.f_ip_factor = 1 / fabs(avctx->i_quant_factor);
+ x4->params.rc.f_pb_factor = avctx->b_quant_factor;
+ x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset;
- x4->params.analyse.inter = 0;
+#if FF_API_X264_GLOBAL_OPTS
+ if (avctx->aq_mode >= 0)
+ x4->params.rc.i_aq_mode = avctx->aq_mode;
+ if (avctx->aq_strength >= 0)
+ x4->params.rc.f_aq_strength = avctx->aq_strength;
+ if (avctx->psy_rd >= 0)
+ x4->params.analyse.f_psy_rd = avctx->psy_rd;
+ if (avctx->psy_trellis >= 0)
+ x4->params.analyse.f_psy_trellis = avctx->psy_trellis;
+ if (avctx->rc_lookahead >= 0)
+ x4->params.rc.i_lookahead = avctx->rc_lookahead;
+ if (avctx->weighted_p_pred >= 0)
+ x4->params.analyse.i_weighted_pred = avctx->weighted_p_pred;
+ if (avctx->bframebias)
+ x4->params.i_bframe_bias = avctx->bframebias;
+ if (avctx->deblockalpha)
+ x4->params.i_deblocking_filter_alphac0 = avctx->deblockalpha;
+ if (avctx->deblockbeta)
+ x4->params.i_deblocking_filter_beta = avctx->deblockbeta;
+ if (avctx->complexityblur >= 0)
+ x4->params.rc.f_complexity_blur = avctx->complexityblur;
+ if (avctx->directpred >= 0)
+ x4->params.analyse.i_direct_mv_pred = avctx->directpred;
if (avctx->partitions) {
if (avctx->partitions & X264_PART_I4X4)
x4->params.analyse.inter |= X264_ANALYSE_I4x4;
@@ -238,11 +314,17 @@ static av_cold int X264_init(AVCodecContext *avctx)
if (avctx->partitions & X264_PART_B8X8)
x4->params.analyse.inter |= X264_ANALYSE_BSUB16x16;
}
-
- x4->params.analyse.i_direct_mv_pred = avctx->directpred;
-
+ x4->params.analyse.b_ssim = avctx->flags2 & CODEC_FLAG2_SSIM;
+ x4->params.b_intra_refresh = avctx->flags2 & CODEC_FLAG2_INTRA_REFRESH;
+ x4->params.i_bframe_pyramid = avctx->flags2 & CODEC_FLAG2_BPYRAMID ? X264_B_PYRAMID_NORMAL : X264_B_PYRAMID_NONE;
x4->params.analyse.b_weighted_bipred = avctx->flags2 & CODEC_FLAG2_WPRED;
- x4->params.analyse.i_weighted_pred = avctx->weighted_p_pred;
+ x4->params.analyse.b_mixed_references = avctx->flags2 & CODEC_FLAG2_MIXED_REFS;
+ x4->params.analyse.b_transform_8x8 = avctx->flags2 & CODEC_FLAG2_8X8DCT;
+ x4->params.analyse.b_fast_pskip = avctx->flags2 & CODEC_FLAG2_FASTPSKIP;
+ x4->params.b_aud = avctx->flags2 & CODEC_FLAG2_AUD;
+ x4->params.analyse.b_psy = avctx->flags2 & CODEC_FLAG2_PSY;
+ x4->params.rc.b_mb_tree = !!(avctx->flags2 & CODEC_FLAG2_MBTREE);
+#endif
if (avctx->me_method == ME_EPZS)
x4->params.analyse.i_me_method = X264_ME_DIA;
@@ -254,46 +336,101 @@ static av_cold int X264_init(AVCodecContext *avctx)
x4->params.analyse.i_me_method = X264_ME_ESA;
else if (avctx->me_method == ME_TESA)
x4->params.analyse.i_me_method = X264_ME_TESA;
- else x4->params.analyse.i_me_method = X264_ME_HEX;
-
- x4->params.rc.i_aq_mode = avctx->aq_mode;
- x4->params.rc.f_aq_strength = avctx->aq_strength;
- x4->params.rc.i_lookahead = avctx->rc_lookahead;
-
- x4->params.analyse.b_psy = avctx->flags2 & CODEC_FLAG2_PSY;
- x4->params.analyse.f_psy_rd = avctx->psy_rd;
- x4->params.analyse.f_psy_trellis = avctx->psy_trellis;
-
- x4->params.analyse.i_me_range = avctx->me_range;
- x4->params.analyse.i_subpel_refine = avctx->me_subpel_quality;
-
- x4->params.analyse.b_mixed_references = avctx->flags2 & CODEC_FLAG2_MIXED_REFS;
- x4->params.analyse.b_chroma_me = avctx->me_cmp & FF_CMP_CHROMA;
- x4->params.analyse.b_transform_8x8 = avctx->flags2 & CODEC_FLAG2_8X8DCT;
- x4->params.analyse.b_fast_pskip = avctx->flags2 & CODEC_FLAG2_FASTPSKIP;
- x4->params.analyse.i_trellis = avctx->trellis;
- x4->params.analyse.i_noise_reduction = avctx->noise_reduction;
-
- if (avctx->level > 0)
- x4->params.i_level_idc = avctx->level;
-
- if (avctx->rc_buffer_size && avctx->rc_initial_buffer_occupancy &&
- (avctx->rc_initial_buffer_occupancy <= avctx->rc_buffer_size)) {
- x4->params.rc.f_vbv_buffer_init =
- (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size;
- }
+ if (avctx->gop_size >= 0)
+ x4->params.i_keyint_max = avctx->gop_size;
+ if (avctx->max_b_frames >= 0)
+ x4->params.i_bframe = avctx->max_b_frames;
+ if (avctx->scenechange_threshold >= 0)
+ x4->params.i_scenecut_threshold = avctx->scenechange_threshold;
+ if (avctx->qmin >= 0)
+ x4->params.rc.i_qp_min = avctx->qmin;
+ if (avctx->qmax >= 0)
+ x4->params.rc.i_qp_max = avctx->qmax;
+ if (avctx->max_qdiff >= 0)
+ x4->params.rc.i_qp_step = avctx->max_qdiff;
+ if (avctx->qblur >= 0)
+ x4->params.rc.f_qblur = avctx->qblur; /* temporally blur quants */
+ if (avctx->qcompress >= 0)
+ x4->params.rc.f_qcompress = avctx->qcompress; /* 0.0 => cbr, 1.0 => constant qp */
+ if (avctx->refs >= 0)
+ x4->params.i_frame_reference = avctx->refs;
+ if (avctx->trellis >= 0)
+ x4->params.analyse.i_trellis = avctx->trellis;
+ if (avctx->me_range >= 0)
+ x4->params.analyse.i_me_range = avctx->me_range;
+ if (avctx->noise_reduction >= 0)
+ x4->params.analyse.i_noise_reduction = avctx->noise_reduction;
+ if (avctx->me_subpel_quality >= 0)
+ x4->params.analyse.i_subpel_refine = avctx->me_subpel_quality;
+ if (avctx->b_frame_strategy >= 0)
+ x4->params.i_bframe_adaptive = avctx->b_frame_strategy;
+ if (avctx->keyint_min >= 0)
+ x4->params.i_keyint_min = avctx->keyint_min;
+ if (avctx->coder_type >= 0)
+ x4->params.b_cabac = avctx->coder_type == FF_CODER_TYPE_AC;
+ if (avctx->me_cmp >= 0)
+ x4->params.analyse.b_chroma_me = avctx->me_cmp & FF_CMP_CHROMA;
+
+ if (x4->aq_mode >= 0)
+ x4->params.rc.i_aq_mode = x4->aq_mode;
+ if (x4->aq_strength >= 0)
+ x4->params.rc.f_aq_strength = x4->aq_strength;
+ PARSE_X264_OPT("psy-rd", psy_rd);
+ PARSE_X264_OPT("deblock", deblock);
+ PARSE_X264_OPT("partitions", partitions);
+ if (x4->psy >= 0)
+ x4->params.analyse.b_psy = x4->psy;
+ if (x4->rc_lookahead >= 0)
+ x4->params.rc.i_lookahead = x4->rc_lookahead;
+ if (x4->weightp >= 0)
+ x4->params.analyse.i_weighted_pred = x4->weightp;
+ if (x4->weightb >= 0)
+ x4->params.analyse.b_weighted_bipred = x4->weightb;
+ if (x4->cplxblur >= 0)
+ x4->params.rc.f_complexity_blur = x4->cplxblur;
+
+ if (x4->ssim >= 0)
+ x4->params.analyse.b_ssim = x4->ssim;
+ if (x4->intra_refresh >= 0)
+ x4->params.b_intra_refresh = x4->intra_refresh;
+ if (x4->b_bias != INT_MIN)
+ x4->params.i_bframe_bias = x4->b_bias;
+ if (x4->b_pyramid >= 0)
+ x4->params.i_bframe_pyramid = x4->b_pyramid;
+ if (x4->mixed_refs >= 0)
+ x4->params.analyse.b_mixed_references = x4->mixed_refs;
+ if (x4->dct8x8 >= 0)
+ x4->params.analyse.b_transform_8x8 = x4->dct8x8;
+ if (x4->fast_pskip >= 0)
+ x4->params.analyse.b_fast_pskip = x4->fast_pskip;
+ if (x4->aud >= 0)
+ x4->params.b_aud = x4->aud;
+ if (x4->mbtree >= 0)
+ x4->params.rc.b_mb_tree = x4->mbtree;
+ if (x4->direct_pred >= 0)
+ x4->params.analyse.i_direct_mv_pred = x4->direct_pred;
+
+ if (x4->slice_max_size >= 0)
+ x4->params.i_slice_max_size = x4->slice_max_size;
+
+ if (x4->fastfirstpass)
+ x264_param_apply_fastfirstpass(&x4->params);
+
+ if (x4->profile)
+ if (x264_param_apply_profile(&x4->params, x4->profile) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error setting profile %s.\n", x4->profile);
+ return AVERROR(EINVAL);
+ }
- x4->params.rc.b_mb_tree = !!(avctx->flags2 & CODEC_FLAG2_MBTREE);
- x4->params.rc.f_ip_factor = 1 / fabs(avctx->i_quant_factor);
- x4->params.rc.f_pb_factor = avctx->b_quant_factor;
- x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset;
+ x4->params.i_width = avctx->width;
+ x4->params.i_height = avctx->height;
+ x4->params.vui.i_sar_width = avctx->sample_aspect_ratio.num;
+ x4->params.vui.i_sar_height = avctx->sample_aspect_ratio.den;
+ x4->params.i_fps_num = x4->params.i_timebase_den = avctx->time_base.den;
+ x4->params.i_fps_den = x4->params.i_timebase_num = avctx->time_base.num;
x4->params.analyse.b_psnr = avctx->flags & CODEC_FLAG_PSNR;
- x4->params.analyse.b_ssim = avctx->flags2 & CODEC_FLAG2_SSIM;
- x4->params.i_log_level = X264_LOG_DEBUG;
-
- x4->params.b_aud = avctx->flags2 & CODEC_FLAG2_AUD;
x4->params.i_threads = avctx->thread_count;
@@ -308,6 +445,14 @@ static av_cold int X264_init(AVCodecContext *avctx)
if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER)
x4->params.b_repeat_headers = 0;
+ // update AVCodecContext with x264 parameters
+ avctx->has_b_frames = x4->params.i_bframe ?
+ x4->params.i_bframe_pyramid ? 2 : 1 : 0;
+ avctx->bit_rate = x4->params.rc.i_bitrate*1000;
+#if FF_API_X264_GLOBAL_OPTS
+ avctx->crf = x4->params.rc.f_rf_constant;
+#endif
+
x4->enc = x264_encoder_open(&x4->params);
if (!x4->enc)
return -1;
@@ -331,6 +476,114 @@ static av_cold int X264_init(AVCodecContext *avctx)
return 0;
}
+static const enum PixelFormat pix_fmts_8bit[] = {
+ PIX_FMT_YUV420P,
+ PIX_FMT_YUVJ420P,
+ PIX_FMT_YUV422P,
+ PIX_FMT_YUV444P,
+ PIX_FMT_NONE
+};
+static const enum PixelFormat pix_fmts_9bit[] = {
+ PIX_FMT_YUV420P9,
+ PIX_FMT_YUV444P9,
+ PIX_FMT_NONE
+};
+static const enum PixelFormat pix_fmts_10bit[] = {
+ PIX_FMT_YUV420P10,
+ PIX_FMT_YUV422P10,
+ PIX_FMT_YUV444P10,
+ PIX_FMT_NONE
+};
+
+static av_cold void X264_init_static(AVCodec *codec)
+{
+ if (x264_bit_depth == 8)
+ codec->pix_fmts = pix_fmts_8bit;
+ else if (x264_bit_depth == 9)
+ codec->pix_fmts = pix_fmts_9bit;
+ else if (x264_bit_depth == 10)
+ codec->pix_fmts = pix_fmts_10bit;
+}
+
+#define OFFSET(x) offsetof(X264Context, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "preset", "Set the encoding preset (cf. x264 --fullhelp)", OFFSET(preset), AV_OPT_TYPE_STRING, { .str = "medium" }, 0, 0, VE},
+ { "tune", "Tune the encoding params (cf. x264 --fullhelp)", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
+ { "profile", "Set profile restrictions (cf. x264 --fullhelp) ", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
+ { "fastfirstpass", "Use fast settings when encoding first pass", OFFSET(fastfirstpass), AV_OPT_TYPE_INT, { 1 }, 0, 1, VE},
+ { "crf", "Select the quality for constant quality mode", OFFSET(crf), AV_OPT_TYPE_FLOAT, {-1 }, -1, FLT_MAX, VE },
+ { "crf_max", "In CRF mode, prevents VBV from lowering quality beyond this point.",OFFSET(crf_max), AV_OPT_TYPE_FLOAT, {-1 }, -1, FLT_MAX, VE },
+ { "qp", "Constant quantization parameter rate control method",OFFSET(cqp), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE },
+ { "aq-mode", "AQ method", OFFSET(aq_mode), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE, "aq_mode"},
+ { "none", NULL, 0, AV_OPT_TYPE_CONST, {X264_AQ_NONE}, INT_MIN, INT_MAX, VE, "aq_mode" },
+ { "variance", "Variance AQ (complexity mask)", 0, AV_OPT_TYPE_CONST, {X264_AQ_VARIANCE}, INT_MIN, INT_MAX, VE, "aq_mode" },
+ { "autovariance", "Auto-variance AQ (experimental)", 0, AV_OPT_TYPE_CONST, {X264_AQ_AUTOVARIANCE}, INT_MIN, INT_MAX, VE, "aq_mode" },
+ { "aq-strength", "AQ strength. Reduces blocking and blurring in flat and textured areas.", OFFSET(aq_strength), AV_OPT_TYPE_FLOAT, {-1}, -1, FLT_MAX, VE},
+ { "psy", "Use psychovisual optimizations.", OFFSET(psy), AV_OPT_TYPE_INT, {-1 }, -1, 1, VE },
+ { "psy-rd", "Strength of psychovisual optimization, in <psy-rd>:<psy-trellis> format.", OFFSET(psy_rd), AV_OPT_TYPE_STRING, {0 }, 0, 0, VE},
+ { "rc-lookahead", "Number of frames to look ahead for frametype and ratecontrol", OFFSET(rc_lookahead), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE },
+ { "weightb", "Weighted prediction for B-frames.", OFFSET(weightb), AV_OPT_TYPE_INT, {-1 }, -1, 1, VE },
+ { "weightp", "Weighted prediction analysis method.", OFFSET(weightp), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE, "weightp" },
+ { "none", NULL, 0, AV_OPT_TYPE_CONST, {X264_WEIGHTP_NONE}, INT_MIN, INT_MAX, VE, "weightp" },
+ { "simple", NULL, 0, AV_OPT_TYPE_CONST, {X264_WEIGHTP_SIMPLE}, INT_MIN, INT_MAX, VE, "weightp" },
+ { "smart", NULL, 0, AV_OPT_TYPE_CONST, {X264_WEIGHTP_SMART}, INT_MIN, INT_MAX, VE, "weightp" },
+ { "ssim", "Calculate and print SSIM stats.", OFFSET(ssim), AV_OPT_TYPE_INT, {-1 }, -1, 1, VE },
+ { "intra-refresh", "Use Periodic Intra Refresh instead of IDR frames.",OFFSET(intra_refresh),AV_OPT_TYPE_INT, {-1 }, -1, 1, VE },
+ { "b-bias", "Influences how often B-frames are used", OFFSET(b_bias), AV_OPT_TYPE_INT, {INT_MIN}, INT_MIN, INT_MAX, VE },
+ { "b-pyramid", "Keep some B-frames as references.", OFFSET(b_pyramid), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE, "b_pyramid" },
+ { "none", NULL, 0, AV_OPT_TYPE_CONST, {X264_B_PYRAMID_NONE}, INT_MIN, INT_MAX, VE, "b_pyramid" },
+ { "strict", "Strictly hierarchical pyramid", 0, AV_OPT_TYPE_CONST, {X264_B_PYRAMID_STRICT}, INT_MIN, INT_MAX, VE, "b_pyramid" },
+ { "normal", "Non-strict (not Blu-ray compatible)", 0, AV_OPT_TYPE_CONST, {X264_B_PYRAMID_NORMAL}, INT_MIN, INT_MAX, VE, "b_pyramid" },
+ { "mixed-refs", "One reference per partition, as opposed to one reference per macroblock", OFFSET(mixed_refs), AV_OPT_TYPE_INT, {-1}, -1, 1, VE },
+ { "8x8dct", "High profile 8x8 transform.", OFFSET(dct8x8), AV_OPT_TYPE_INT, {-1 }, -1, 1, VE},
+ { "fast-pskip", NULL, OFFSET(fast_pskip), AV_OPT_TYPE_INT, {-1 }, -1, 1, VE},
+ { "aud", "Use access unit delimiters.", OFFSET(aud), AV_OPT_TYPE_INT, {-1 }, -1, 1, VE},
+ { "mbtree", "Use macroblock tree ratecontrol.", OFFSET(mbtree), AV_OPT_TYPE_INT, {-1 }, -1, 1, VE},
+ { "deblock", "Loop filter parameters, in <alpha:beta> form.", OFFSET(deblock), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
+ { "cplxblur", "Reduce fluctuations in QP (before curve compression)", OFFSET(cplxblur), AV_OPT_TYPE_FLOAT, {-1 }, -1, FLT_MAX, VE},
+ { "partitions", "A comma-separated list of partitions to consider. "
+ "Possible values: p8x8, p4x4, b8x8, i8x8, i4x4, none, all", OFFSET(partitions), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
+ { "direct-pred", "Direct MV prediction mode", OFFSET(direct_pred), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE, "direct-pred" },
+ { "none", NULL, 0, AV_OPT_TYPE_CONST, { X264_DIRECT_PRED_NONE }, 0, 0, VE, "direct-pred" },
+ { "spatial", NULL, 0, AV_OPT_TYPE_CONST, { X264_DIRECT_PRED_SPATIAL }, 0, 0, VE, "direct-pred" },
+ { "temporal", NULL, 0, AV_OPT_TYPE_CONST, { X264_DIRECT_PRED_TEMPORAL }, 0, 0, VE, "direct-pred" },
+ { "auto", NULL, 0, AV_OPT_TYPE_CONST, { X264_DIRECT_PRED_AUTO }, 0, 0, VE, "direct-pred" },
+ { "slice-max-size","Constant quantization parameter rate control method",OFFSET(slice_max_size), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE },
+ { NULL },
+};
+
+static const AVClass class = {
+ .class_name = "libx264",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVCodecDefault x264_defaults[] = {
+ { "b", "0" },
+ { "bf", "-1" },
+ { "g", "-1" },
+ { "qmin", "-1" },
+ { "qmax", "-1" },
+ { "qdiff", "-1" },
+ { "qblur", "-1" },
+ { "qcomp", "-1" },
+ { "refs", "-1" },
+ { "sc_threshold", "-1" },
+ { "trellis", "-1" },
+ { "nr", "-1" },
+ { "me_range", "-1" },
+ { "me_method", "-1" },
+ { "subq", "-1" },
+ { "b_strategy", "-1" },
+ { "keyint_min", "-1" },
+ { "coder", "-1" },
+ { "cmp", "-1" },
+ { "threads", AV_STRINGIFY(X264_THREADS_AUTO) },
+ { NULL },
+};
+
AVCodec ff_libx264_encoder = {
.name = "libx264",
.type = AVMEDIA_TYPE_VIDEO,
@@ -340,6 +593,8 @@ AVCodec ff_libx264_encoder = {
.encode = X264_frame,
.close = X264_close,
.capabilities = CODEC_CAP_DELAY,
- .pix_fmts = (const enum PixelFormat[]) { PIX_FMT_YUV420P, PIX_FMT_YUVJ420P, PIX_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
+ .priv_class = &class,
+ .defaults = x264_defaults,
+ .init_static_data = X264_init_static,
};
diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c
index d11c424..823f5fb 100644
--- a/libavcodec/libxavs.c
+++ b/libavcodec/libxavs.c
@@ -24,8 +24,11 @@
#include <string.h>
#include <math.h>
#include <stdint.h>
+#include <float.h>
#include <xavs.h>
#include "avcodec.h"
+#include "internal.h"
+#include "libavutil/opt.h"
#define END_OF_STREAM 0x001
@@ -41,6 +44,15 @@ typedef struct XavsContext {
int sei_size;
AVFrame out_pic;
int end_of_stream;
+ float crf;
+ int cqp;
+ int b_bias;
+ float cplxblur;
+ int direct_pred;
+ int aud;
+ int fast_pskip;
+ int mbtree;
+ int mixed_refs;
} XavsContext;
static void XAVS_log(void *p, int level, const char *fmt, va_list args)
@@ -181,13 +193,17 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
x4->params.pf_log = XAVS_log;
x4->params.p_log_private = avctx;
x4->params.i_keyint_max = avctx->gop_size;
- x4->params.rc.i_bitrate = avctx->bit_rate / 1000;
+ if (avctx->bit_rate) {
+ x4->params.rc.i_bitrate = avctx->bit_rate / 1000;
+ x4->params.rc.i_rc_method = XAVS_RC_ABR;
+ }
x4->params.rc.i_vbv_buffer_size = avctx->rc_buffer_size / 1000;
x4->params.rc.i_vbv_max_bitrate = avctx->rc_max_rate / 1000;
x4->params.rc.b_stat_write = avctx->flags & CODEC_FLAG_PASS1;
if (avctx->flags & CODEC_FLAG_PASS2) {
x4->params.rc.b_stat_read = 1;
} else {
+#if FF_API_X264_GLOBAL_OPTS
if (avctx->crf) {
x4->params.rc.i_rc_method = XAVS_RC_CRF;
x4->params.rc.f_rf_constant = avctx->crf;
@@ -195,19 +211,63 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
x4->params.rc.i_rc_method = XAVS_RC_CQP;
x4->params.rc.i_qp_constant = avctx->cqp;
}
+#endif
+
+ if (x4->crf >= 0) {
+ x4->params.rc.i_rc_method = XAVS_RC_CRF;
+ x4->params.rc.f_rf_constant = x4->crf;
+ } else if (x4->cqp >= 0) {
+ x4->params.rc.i_rc_method = XAVS_RC_CQP;
+ x4->params.rc.i_qp_constant = x4->cqp;
+ }
}
- /* if neither crf nor cqp modes are selected we have to enable the RC */
- /* we do it this way because we cannot check if the bitrate has been set */
- if (!(avctx->crf || (avctx->cqp > -1)))
- x4->params.rc.i_rc_method = XAVS_RC_ABR;
+#if FF_API_X264_GLOBAL_OPTS
+ if (avctx->bframebias)
+ x4->params.i_bframe_bias = avctx->bframebias;
+ if (avctx->deblockalpha)
+ x4->params.i_deblocking_filter_alphac0 = avctx->deblockalpha;
+ if (avctx->deblockbeta)
+ x4->params.i_deblocking_filter_beta = avctx->deblockbeta;
+ if (avctx->complexityblur >= 0)
+ x4->params.rc.f_complexity_blur = avctx->complexityblur;
+ if (avctx->directpred >= 0)
+ x4->params.analyse.i_direct_mv_pred = avctx->directpred;
+ if (avctx->partitions) {
+ if (avctx->partitions & XAVS_PART_I8X8)
+ x4->params.analyse.inter |= XAVS_ANALYSE_I8x8;
+ if (avctx->partitions & XAVS_PART_P8X8)
+ x4->params.analyse.inter |= XAVS_ANALYSE_PSUB16x16;
+ if (avctx->partitions & XAVS_PART_B8X8)
+ x4->params.analyse.inter |= XAVS_ANALYSE_BSUB16x16;
+ }
+ x4->params.rc.b_mb_tree = !!(avctx->flags2 & CODEC_FLAG2_MBTREE);
+ x4->params.b_aud = avctx->flags2 & CODEC_FLAG2_AUD;
+ x4->params.analyse.b_mixed_references = avctx->flags2 & CODEC_FLAG2_MIXED_REFS;
+ x4->params.analyse.b_fast_pskip = avctx->flags2 & CODEC_FLAG2_FASTPSKIP;
+ x4->params.analyse.b_weighted_bipred = avctx->flags2 & CODEC_FLAG2_WPRED;
+#endif
+
+ if (x4->aud >= 0)
+ x4->params.b_aud = x4->aud;
+ if (x4->mbtree >= 0)
+ x4->params.rc.b_mb_tree = x4->mbtree;
+ if (x4->direct_pred >= 0)
+ x4->params.analyse.i_direct_mv_pred = x4->direct_pred;
+ if (x4->fast_pskip >= 0)
+ x4->params.analyse.b_fast_pskip = x4->fast_pskip;
+ if (x4->mixed_refs >= 0)
+ x4->params.analyse.b_mixed_references = x4->mixed_refs;
+ if (x4->b_bias != INT_MIN)
+ x4->params.i_bframe_bias = x4->b_bias;
+ if (x4->cplxblur >= 0)
+ x4->params.rc.f_complexity_blur = x4->cplxblur;
x4->params.i_bframe = avctx->max_b_frames;
/* cabac is not included in AVS JiZhun Profile */
x4->params.b_cabac = 0;
x4->params.i_bframe_adaptive = avctx->b_frame_strategy;
- x4->params.i_bframe_bias = avctx->bframebias;
avctx->has_b_frames = !!avctx->max_b_frames;
@@ -220,8 +280,6 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
x4->params.i_scenecut_threshold = avctx->scenechange_threshold;
// x4->params.b_deblocking_filter = avctx->flags & CODEC_FLAG_LOOP_FILTER;
- x4->params.i_deblocking_filter_alphac0 = avctx->deblockalpha;
- x4->params.i_deblocking_filter_beta = avctx->deblockbeta;
x4->params.rc.i_qp_min = avctx->qmin;
x4->params.rc.i_qp_max = avctx->qmax;
@@ -229,7 +287,6 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
x4->params.rc.f_qcompress = avctx->qcompress; /* 0.0 => cbr, 1.0 => constant qp */
x4->params.rc.f_qblur = avctx->qblur; /* temporally blur quants */
- x4->params.rc.f_complexity_blur = avctx->complexityblur;
x4->params.i_frame_reference = avctx->refs;
@@ -241,20 +298,6 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
x4->params.i_fps_num = avctx->time_base.den;
x4->params.i_fps_den = avctx->time_base.num;
x4->params.analyse.inter = XAVS_ANALYSE_I8x8 |XAVS_ANALYSE_PSUB16x16| XAVS_ANALYSE_BSUB16x16;
- if (avctx->partitions) {
- if (avctx->partitions & XAVS_PART_I8X8)
- x4->params.analyse.inter |= XAVS_ANALYSE_I8x8;
-
- if (avctx->partitions & XAVS_PART_P8X8)
- x4->params.analyse.inter |= XAVS_ANALYSE_PSUB16x16;
-
- if (avctx->partitions & XAVS_PART_B8X8)
- x4->params.analyse.inter |= XAVS_ANALYSE_BSUB16x16;
- }
-
- x4->params.analyse.i_direct_mv_pred = avctx->directpred;
-
- x4->params.analyse.b_weighted_bipred = avctx->flags2 & CODEC_FLAG2_WPRED;
switch (avctx->me_method) {
case ME_EPZS:
@@ -279,11 +322,9 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
x4->params.analyse.i_me_range = avctx->me_range;
x4->params.analyse.i_subpel_refine = avctx->me_subpel_quality;
- x4->params.analyse.b_mixed_references = avctx->flags2 & CODEC_FLAG2_MIXED_REFS;
x4->params.analyse.b_chroma_me = avctx->me_cmp & FF_CMP_CHROMA;
/* AVS P2 only enables 8x8 transform */
x4->params.analyse.b_transform_8x8 = 1; //avctx->flags2 & CODEC_FLAG2_8X8DCT;
- x4->params.analyse.b_fast_pskip = avctx->flags2 & CODEC_FLAG2_FASTPSKIP;
x4->params.analyse.i_trellis = avctx->trellis;
x4->params.analyse.i_noise_reduction = avctx->noise_reduction;
@@ -303,14 +344,12 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
/* TAG:do we have MB tree RC method */
/* what is the RC method we are now using? Default NO */
- x4->params.rc.b_mb_tree = !!(avctx->flags2 & CODEC_FLAG2_MBTREE);
x4->params.rc.f_ip_factor = 1 / fabs(avctx->i_quant_factor);
x4->params.rc.f_pb_factor = avctx->b_quant_factor;
x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset;
x4->params.analyse.b_psnr = avctx->flags & CODEC_FLAG_PSNR;
x4->params.i_log_level = XAVS_LOG_DEBUG;
- x4->params.b_aud = avctx->flags2 & CODEC_FLAG2_AUD;
x4->params.i_threads = avctx->thread_count;
x4->params.b_interlaced = avctx->flags & CODEC_FLAG_INTERLACED_DCT;
@@ -336,6 +375,37 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
return 0;
}
+#define OFFSET(x) offsetof(XavsContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "crf", "Select the quality for constant quality mode", OFFSET(crf), AV_OPT_TYPE_FLOAT, {-1 }, -1, FLT_MAX, VE },
+ { "qp", "Constant quantization parameter rate control method",OFFSET(cqp), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE },
+ { "b-bias", "Influences how often B-frames are used", OFFSET(b_bias), AV_OPT_TYPE_INT, {INT_MIN}, INT_MIN, INT_MAX, VE },
+ { "cplxblur", "Reduce fluctuations in QP (before curve compression)", OFFSET(cplxblur), AV_OPT_TYPE_FLOAT, {-1 }, -1, FLT_MAX, VE},
+ { "direct-pred", "Direct MV prediction mode", OFFSET(direct_pred), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE, "direct-pred" },
+ { "none", NULL, 0, AV_OPT_TYPE_CONST, { XAVS_DIRECT_PRED_NONE }, 0, 0, VE, "direct-pred" },
+ { "spatial", NULL, 0, AV_OPT_TYPE_CONST, { XAVS_DIRECT_PRED_SPATIAL }, 0, 0, VE, "direct-pred" },
+ { "temporal", NULL, 0, AV_OPT_TYPE_CONST, { XAVS_DIRECT_PRED_TEMPORAL }, 0, 0, VE, "direct-pred" },
+ { "auto", NULL, 0, AV_OPT_TYPE_CONST, { XAVS_DIRECT_PRED_AUTO }, 0, 0, VE, "direct-pred" },
+ { "aud", "Use access unit delimiters.", OFFSET(aud), AV_OPT_TYPE_INT, {-1 }, -1, 1, VE},
+ { "mbtree", "Use macroblock tree ratecontrol.", OFFSET(mbtree), AV_OPT_TYPE_INT, {-1 }, -1, 1, VE},
+ { "mixed-refs", "One reference per partition, as opposed to one reference per macroblock", OFFSET(mixed_refs), AV_OPT_TYPE_INT, {-1}, -1, 1, VE },
+ { "fast-pskip", NULL, OFFSET(fast_pskip), AV_OPT_TYPE_INT, {-1 }, -1, 1, VE},
+ { NULL },
+};
+
+static const AVClass class = {
+ .class_name = "libxavs",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVCodecDefault xavs_defaults[] = {
+ { "b", "0" },
+ { NULL },
+};
+
AVCodec ff_libxavs_encoder = {
.name = "libxavs",
.type = AVMEDIA_TYPE_VIDEO,
@@ -347,5 +417,7 @@ AVCodec ff_libxavs_encoder = {
.capabilities = CODEC_CAP_DELAY,
.pix_fmts = (const enum PixelFormat[]) { PIX_FMT_YUV420P, PIX_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("libxavs - the Chinese Audio Video Standard Encoder"),
+ .priv_class = &class,
+ .defaults = xavs_defaults,
};
diff --git a/libavcodec/libxvidff.c b/libavcodec/libxvidff.c
index fd0aea5..d0f4ed3 100644
--- a/libavcodec/libxvidff.c
+++ b/libavcodec/libxvidff.c
@@ -137,7 +137,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) {
xvid_enc_create_t xvid_enc_create;
xvid_enc_plugin_t plugins[7];
- /* Bring in VOP flags from ffmpeg command-line */
+ /* Bring in VOP flags from avconv command-line */
x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */
if( xvid_flags & CODEC_FLAG_4MV )
x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */
@@ -191,7 +191,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) {
break;
}
- /* Bring in VOL flags from ffmpeg command-line */
+ /* Bring in VOL flags from avconv command-line */
x->vol_flags = 0;
if( xvid_flags & CODEC_FLAG_GMC ) {
x->vol_flags |= XVID_VOL_GMC;
@@ -669,7 +669,7 @@ static int xvid_ff_2pass_create(xvid_plg_create_t * param,
/* This is because we can safely prevent a buffer overflow */
log[0] = 0;
snprintf(log, BUFFER_REMAINING(log),
- "# ffmpeg 2-pass log file, using xvid codec\n");
+ "# avconv 2-pass log file, using xvid codec\n");
snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
"# Do not modify. libxvidcore version: %d.%d.%d\n\n",
XVID_VERSION_MAJOR(XVID_VERSION),
@@ -749,7 +749,7 @@ static int xvid_ff_2pass_before(struct xvid_context *ref,
static int xvid_ff_2pass_after(struct xvid_context *ref,
xvid_plg_data_t *param) {
char *log = ref->twopassbuffer;
- char *frame_types = " ipbs";
+ const char *frame_types = " ipbs";
char frame_type;
/* Quick bounds check */
@@ -809,13 +809,13 @@ int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) {
* Xvid codec definition for libavcodec.
*/
AVCodec ff_libxvid_encoder = {
- "libxvid",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG4,
- sizeof(struct xvid_context),
- xvid_encode_init,
- xvid_encode_frame,
- xvid_encode_close,
+ .name = "libxvid",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG4,
+ .priv_data_size = sizeof(struct xvid_context),
+ .init = xvid_encode_init,
+ .encode = xvid_encode_frame,
+ .close = xvid_encode_close,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
};
diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c
index 56a60c9..6a90338 100644
--- a/libavcodec/ljpegenc.c
+++ b/libavcodec/ljpegenc.c
@@ -187,12 +187,12 @@ static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, in
AVCodec ff_ljpeg_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them
- "ljpeg",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_LJPEG,
- sizeof(MpegEncContext),
- MPV_encode_init,
- encode_picture_lossless,
- MPV_encode_end,
- .long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
+ .name = "ljpeg",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_LJPEG,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = MPV_encode_init,
+ .encode = encode_picture_lossless,
+ .close = MPV_encode_end,
+ .long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
};
diff --git a/libavcodec/loco.c b/libavcodec/loco.c
index 32b1bfc..919a06b 100644
--- a/libavcodec/loco.c
+++ b/libavcodec/loco.c
@@ -286,14 +286,13 @@ static av_cold int decode_end(AVCodecContext *avctx){
}
AVCodec ff_loco_decoder = {
- "loco",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_LOCO,
- sizeof(LOCOContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "loco",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_LOCO,
+ .priv_data_size = sizeof(LOCOContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("LOCO"),
};
diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index ed985d3..d1833cb 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -35,8 +35,9 @@ static void lpc_apply_welch_window_c(const int32_t *data, int len,
double w;
double c;
- assert(!(len&1)); //the optimization in r11881 does not support odd len
- //if someone wants odd len extend the change in r11881
+ /* The optimization in commit fa4ed8c does not support odd len.
+ * If someone wants odd len extend that change. */
+ assert(!(len & 1));
n2 = (len >> 1);
c = 2.0 / (len - 1.0);
@@ -149,10 +150,8 @@ static int estimate_best_order(double *ref, int min_order, int max_order)
/**
* Calculate LPC coefficients for multiple orders
*
- * @param use_lpc LPC method for determining coefficients
- * 0 = LPC with fixed pre-defined coeffs
- * 1 = LPC with coeffs determined by Levinson-Durbin recursion
- * 2+ = LPC with coeffs determined by Cholesky factorization using (use_lpc-1) passes.
+ * @param lpc_type LPC method for determining coefficients,
+ * see #FFLPCType for details
*/
int ff_lpc_calc_coefs(LPCContext *s,
const int32_t *samples, int blocksize, int min_order,
diff --git a/libavcodec/lpc.h b/libavcodec/lpc.h
index 8cc2362..2a944b6 100644
--- a/libavcodec/lpc.h
+++ b/libavcodec/lpc.h
@@ -67,7 +67,7 @@ typedef struct LPCContext {
* Perform autocorrelation on input samples with delay of 0 to lag.
* @param data input samples.
* constraints: no alignment needed, but must have have at
- * least lag*sizeof(double) valid bytes preceeding it, and
+ * least lag*sizeof(double) valid bytes preceding it, and
* size must be at least (len+1)*sizeof(double) if data is
* 16-byte aligned or (len+2)*sizeof(double) if data is
* unaligned.
diff --git a/libavcodec/lsp.c b/libavcodec/lsp.c
index d9ddd7d..2adc9cf 100644
--- a/libavcodec/lsp.c
+++ b/libavcodec/lsp.c
@@ -74,9 +74,9 @@ void ff_acelp_lsf2lspd(double *lsp, const float *lsf, int lp_order)
}
/**
- * \brief decodes polynomial coefficients from LSP
- * \param f [out] decoded polynomial coefficients (-0x20000000 <= (3.22) <= 0x1fffffff)
- * \param lsp LSP coefficients (-0x8000 <= (0.15) <= 0x7fff)
+ * @brief decodes polynomial coefficients from LSP
+ * @param[out] f decoded polynomial coefficients (-0x20000000 <= (3.22) <= 0x1fffffff)
+ * @param lsp LSP coefficients (-0x8000 <= (0.15) <= 0x7fff)
*/
static void lsp2poly(int* f, const int16_t* lsp, int lp_half_order)
{
@@ -120,8 +120,8 @@ void ff_acelp_lsp2lpc(int16_t* lp, const int16_t* lsp, int lp_half_order)
void ff_amrwb_lsp2lpc(const double *lsp, float *lp, int lp_order)
{
int lp_half_order = lp_order >> 1;
- double buf[lp_half_order + 1];
- double pa[lp_half_order + 1];
+ double buf[MAX_LP_HALF_ORDER + 1];
+ double pa[MAX_LP_HALF_ORDER + 1];
double *qa = buf + 1;
int i,j;
@@ -150,11 +150,7 @@ void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd
/* LSP values for first subframe (3.2.5 of G.729, Equation 24)*/
for(i=0; i<lp_order; i++)
-#ifdef G729_BITEXACT
- lsp_1st[i] = (lsp_2nd[i] >> 1) + (lsp_prev[i] >> 1);
-#else
lsp_1st[i] = (lsp_2nd[i] + lsp_prev[i]) >> 1;
-#endif
ff_acelp_lsp2lpc(lp_1st, lsp_1st, lp_order >> 1);
diff --git a/libavcodec/lsp.h b/libavcodec/lsp.h
index 388de51..4b95567 100644
--- a/libavcodec/lsp.h
+++ b/libavcodec/lsp.h
@@ -30,12 +30,12 @@
*/
/**
- * \brief ensure a minimum distance between LSFs
- * \param[in,out] lsfq LSF to check and adjust
- * \param lsfq_min_distance minimum distance between LSFs
- * \param lsfq_min minimum allowed LSF value
- * \param lsfq_max maximum allowed LSF value
- * \param lp_order LP filter order
+ * @brief ensure a minimum distance between LSFs
+ * @param[in,out] lsfq LSF to check and adjust
+ * @param lsfq_min_distance minimum distance between LSFs
+ * @param lsfq_min minimum allowed LSF value
+ * @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 lsfq_min, int lsfq_max, int lp_order);
@@ -53,12 +53,12 @@ void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, in
void ff_set_min_dist_lsf(float *lsf, double min_spacing, int size);
/**
- * \brief Convert LSF to LSP
- * \param[out] lsp LSP coefficients (-0x8000 <= (0.15) < 0x8000)
- * \param lsf normalized LSF coefficients (0 <= (2.13) < 0x2000 * PI)
- * \param lp_order LP filter order
+ * @brief Convert LSF to LSP
+ * @param[out] lsp LSP coefficients (-0x8000 <= (0.15) < 0x8000)
+ * @param lsf normalized LSF coefficients (0 <= (2.13) < 0x2000 * PI)
+ * @param lp_order LP filter order
*
- * \remark It is safe to pass the same array into the lsf and lsp parameters.
+ * @remark It is safe to pass the same array into the lsf and lsp parameters.
*/
void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order);
@@ -68,10 +68,10 @@ void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order);
void ff_acelp_lsf2lspd(double *lsp, const float *lsf, int lp_order);
/**
- * \brief LSP to LP conversion (3.2.6 of G.729)
- * \param[out] lp decoded LP coefficients (-0x8000 <= (3.12) < 0x8000)
- * \param lsp LSP coefficients (-0x8000 <= (0.15) < 0x8000)
- * \param lp_half_order LP filter order, divided by 2
+ * @brief LSP to LP conversion (3.2.6 of G.729)
+ * @param[out] lp decoded LP coefficients (-0x8000 <= (3.12) < 0x8000)
+ * @param lsp LSP coefficients (-0x8000 <= (0.15) < 0x8000)
+ * @param lp_half_order LP filter order, divided by 2
*/
void ff_acelp_lsp2lpc(int16_t* lp, const int16_t* lsp, int lp_half_order);
@@ -81,17 +81,17 @@ void ff_acelp_lsp2lpc(int16_t* lp, const int16_t* lsp, int lp_half_order);
void ff_amrwb_lsp2lpc(const double *lsp, float *lp, int lp_order);
/**
- * \brief Interpolate LSP for the first subframe and convert LSP -> LP for both subframes (3.2.5 and 3.2.6 of G.729)
- * \param[out] lp_1st decoded LP coefficients for first subframe (-0x8000 <= (3.12) < 0x8000)
- * \param[out] lp_2nd decoded LP coefficients for second subframe (-0x8000 <= (3.12) < 0x8000)
- * \param lsp_2nd LSP coefficients of the second subframe (-0x8000 <= (0.15) < 0x8000)
- * \param lsp_prev LSP coefficients from the second subframe of the previous frame (-0x8000 <= (0.15) < 0x8000)
- * \param lp_order LP filter order
+ * @brief Interpolate LSP for the first subframe and convert LSP -> LP for both subframes (3.2.5 and 3.2.6 of G.729)
+ * @param[out] lp_1st decoded LP coefficients for first subframe (-0x8000 <= (3.12) < 0x8000)
+ * @param[out] lp_2nd decoded LP coefficients for second subframe (-0x8000 <= (3.12) < 0x8000)
+ * @param lsp_2nd LSP coefficients of the second subframe (-0x8000 <= (0.15) < 0x8000)
+ * @param lsp_prev LSP coefficients from the second subframe of the previous frame (-0x8000 <= (0.15) < 0x8000)
+ * @param lp_order LP filter order
*/
void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd, const int16_t* lsp_prev, int lp_order);
-#define MAX_LP_HALF_ORDER 8
+#define MAX_LP_HALF_ORDER 10
#define MAX_LP_ORDER (2*MAX_LP_HALF_ORDER)
/**
diff --git a/libavcodec/lzw.c b/libavcodec/lzw.c
index 6129429..873b314 100644
--- a/libavcodec/lzw.c
+++ b/libavcodec/lzw.c
@@ -24,7 +24,7 @@
* @file
* @brief LZW decoding routines
* @author Fabrice Bellard
- * Modified for use in TIFF by Konstantin Shishkov
+ * @author modified for use in TIFF by Konstantin Shishkov
*/
#include "avcodec.h"
diff --git a/libavcodec/lzw.h b/libavcodec/lzw.h
index d1efdaf..ab782f5 100644
--- a/libavcodec/lzw.h
+++ b/libavcodec/lzw.h
@@ -24,7 +24,7 @@
* @file
* @brief LZW decoding routines
* @author Fabrice Bellard
- * Modified for use in TIFF by Konstantin Shishkov
+ * @author modified for use in TIFF by Konstantin Shishkov
*/
#ifndef AVCODEC_LZW_H
diff --git a/libavcodec/lzwenc.c b/libavcodec/lzwenc.c
index df38116..cb064e7 100644
--- a/libavcodec/lzwenc.c
+++ b/libavcodec/lzwenc.c
@@ -20,8 +20,8 @@
*/
/**
- * LZW encoder
* @file
+ * LZW encoder
* @author Bartlomiej Wolowiec
*/
diff --git a/libavcodec/mace.c b/libavcodec/mace.c
index 53ec056..792d71d 100644
--- a/libavcodec/mace.c
+++ b/libavcodec/mace.c
@@ -27,7 +27,7 @@
#include "avcodec.h"
/*
- * Adapted to ffmpeg by Francois Revol <revol at free.fr>
+ * Adapted to libavcodec by Francois Revol <revol at free.fr>
* (removed 68k REG stuff, changed types, added some statics and consts,
* libavcodec api, context stuff, interlaced stereo out).
*/
@@ -153,6 +153,7 @@ typedef struct ChannelData {
} ChannelData;
typedef struct MACEContext {
+ AVFrame frame;
ChannelData chd[2];
} MACEContext;
@@ -228,27 +229,35 @@ static void chomp6(ChannelData *chd, int16_t *output, uint8_t val,
static av_cold int mace_decode_init(AVCodecContext * avctx)
{
+ MACEContext *ctx = avctx->priv_data;
+
if (avctx->channels > 2)
return -1;
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ avcodec_get_frame_defaults(&ctx->frame);
+ avctx->coded_frame = &ctx->frame;
+
return 0;
}
-static int mace_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int mace_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- int16_t *samples = data;
+ int16_t *samples;
MACEContext *ctx = avctx->priv_data;
- int i, j, k, l;
+ int i, j, k, l, ret;
int is_mace3 = (avctx->codec_id == CODEC_ID_MACE3);
- if (*data_size < (3 * buf_size << (2-is_mace3))) {
- av_log(avctx, AV_LOG_ERROR, "Output buffer too small!\n");
- return -1;
+ /* get output buffer */
+ ctx->frame.nb_samples = 3 * (buf_size << (1 - is_mace3)) / avctx->channels;
+ if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
+ samples = (int16_t *)ctx->frame.data[0];
for(i = 0; i < avctx->channels; i++) {
int16_t *output = samples + i;
@@ -274,32 +283,31 @@ static int mace_decode_frame(AVCodecContext *avctx,
}
}
- *data_size = 3 * buf_size << (2-is_mace3);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = ctx->frame;
return buf_size;
}
AVCodec ff_mace3_decoder = {
- "mace3",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MACE3,
- sizeof(MACEContext),
- mace_decode_init,
- NULL,
- NULL,
- mace_decode_frame,
+ .name = "mace3",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MACE3,
+ .priv_data_size = sizeof(MACEContext),
+ .init = mace_decode_init,
+ .decode = mace_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 3:1"),
};
AVCodec ff_mace6_decoder = {
- "mace6",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MACE6,
- sizeof(MACEContext),
- mace_decode_init,
- NULL,
- NULL,
- mace_decode_frame,
+ .name = "mace6",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MACE6,
+ .priv_data_size = sizeof(MACEContext),
+ .init = mace_decode_init,
+ .decode = mace_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 6:1"),
};
diff --git a/libavcodec/mathops.h b/libavcodec/mathops.h
index ec76eaa..45b1ecf 100644
--- a/libavcodec/mathops.h
+++ b/libavcodec/mathops.h
@@ -116,7 +116,9 @@ static inline av_const int mid_pred(int a, int b, int c)
#ifndef sign_extend
static inline av_const int sign_extend(int val, unsigned bits)
{
- return (val << ((8 * sizeof(int)) - bits)) >> ((8 * sizeof(int)) - bits);
+ unsigned shift = 8 * sizeof(int) - bits;
+ union { unsigned u; int s; } v = { (unsigned) val << shift };
+ return v.s >> shift;
}
#endif
diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c
index 02b69d0..3741549 100644
--- a/libavcodec/mdec.c
+++ b/libavcodec/mdec.c
@@ -265,15 +265,14 @@ static av_cold int decode_end(AVCodecContext *avctx){
}
AVCodec ff_mdec_decoder = {
- "mdec",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MDEC,
- sizeof(MDECContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+ .name = "mdec",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MDEC,
+ .priv_data_size = sizeof(MDECContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
.long_name= NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"),
.init_thread_copy= ONLY_IF_THREADS_ENABLED(decode_init_thread_copy)
};
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index 46497ec..b93f51f 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -24,6 +24,7 @@
#include <stdint.h>
#include "avcodec.h"
+#include "internal.h"
#include "get_bits.h"
#include "bytestream.h"
#include "dsputil.h"
@@ -405,7 +406,8 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx)
av_free(ctx->swap_buf);
- if(avctx->is_copy) return 0;
+ if (avctx->internal->is_copy)
+ return 0;
for(i = 0; i < 16; i++)
if(ctx->buf_ptrs[i].data[0])
@@ -416,15 +418,14 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx)
}
AVCodec ff_mimic_decoder = {
- "mimic",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MIMIC,
- sizeof(MimicContext),
- mimic_decode_init,
- NULL,
- mimic_decode_end,
- mimic_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+ .name = "mimic",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MIMIC,
+ .priv_data_size = sizeof(MimicContext),
+ .init = mimic_decode_init,
+ .close = mimic_decode_end,
+ .decode = mimic_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
.long_name = NULL_IF_CONFIG_SMALL("Mimic"),
.update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context)
};
diff --git a/libavcodec/mjpeg2jpeg_bsf.c b/libavcodec/mjpeg2jpeg_bsf.c
index 335a73b..a91152d 100644
--- a/libavcodec/mjpeg2jpeg_bsf.c
+++ b/libavcodec/mjpeg2jpeg_bsf.c
@@ -108,6 +108,5 @@ static int mjpeg2jpeg_filter(AVBitStreamFilterContext *bsfc,
AVBitStreamFilter ff_mjpeg2jpeg_bsf = {
.name = "mjpeg2jpeg",
- .priv_data_size = 0,
.filter = mjpeg2jpeg_filter,
};
diff --git a/libavcodec/mjpeg_parser.c b/libavcodec/mjpeg_parser.c
index b5282f1..5b83e59 100644
--- a/libavcodec/mjpeg_parser.c
+++ b/libavcodec/mjpeg_parser.c
@@ -30,7 +30,7 @@
/**
- * finds the end of the current frame in the bitstream.
+ * Find the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
@@ -97,9 +97,8 @@ static int jpeg_parse(AVCodecParserContext *s,
AVCodecParser ff_mjpeg_parser = {
- { CODEC_ID_MJPEG },
- sizeof(ParseContext),
- NULL,
- jpeg_parse,
- ff_parse_close,
+ .codec_ids = { CODEC_ID_MJPEG },
+ .priv_data_size = sizeof(ParseContext),
+ .parser_parse = jpeg_parse,
+ .parser_close = ff_parse_close,
};
diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c
index 837304e..4ad17ab 100644
--- a/libavcodec/mjpegbdec.c
+++ b/libavcodec/mjpegbdec.c
@@ -81,7 +81,9 @@ read_header:
{
init_get_bits(&s->gb, buf_ptr+dqt_offs, (buf_end - (buf_ptr+dqt_offs))*8);
s->start_code = DQT;
- ff_mjpeg_decode_dqt(s);
+ if (ff_mjpeg_decode_dqt(s) < 0 &&
+ (avctx->err_recognition & AV_EF_EXPLODE))
+ return AVERROR_INVALIDDATA;
}
dht_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dht is %d and size is %d\n");
@@ -113,7 +115,9 @@ read_header:
init_get_bits(&s->gb, buf_ptr+sos_offs, field_size*8);
s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16));
s->start_code = SOS;
- ff_mjpeg_decode_sos(s, NULL, NULL);
+ if (ff_mjpeg_decode_sos(s, NULL, NULL) < 0 &&
+ (avctx->err_recognition & AV_EF_EXPLODE))
+ return AVERROR_INVALIDDATA;
}
if (s->interlaced) {
@@ -146,16 +150,14 @@ read_header:
}
AVCodec ff_mjpegb_decoder = {
- "mjpegb",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MJPEGB,
- sizeof(MJpegDecodeContext),
- ff_mjpeg_decode_init,
- NULL,
- ff_mjpeg_decode_end,
- mjpegb_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "mjpegb",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MJPEGB,
+ .priv_data_size = sizeof(MJpegDecodeContext),
+ .init = ff_mjpeg_decode_init,
+ .close = ff_mjpeg_decode_end,
+ .decode = mjpegb_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("Apple MJPEG-B"),
};
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 3f6b1f1..058b08f 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -34,6 +34,7 @@
#include <assert.h>
#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
#include "avcodec.h"
#include "dsputil.h"
#include "mjpeg.h"
@@ -96,21 +97,22 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
build_basic_mjpeg_vlc(s);
+#if FF_API_MJPEG_GLOBAL_OPTS
if (avctx->flags & CODEC_FLAG_EXTERN_HUFF)
+ s->extern_huff = 1;
+#endif
+ if (s->extern_huff)
{
av_log(avctx, AV_LOG_INFO, "mjpeg: using external huffman table\n");
init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8);
if (ff_mjpeg_decode_dht(s)) {
- av_log(avctx, AV_LOG_ERROR, "mjpeg: error using external huffman table, switching back to internal\n");
- build_basic_mjpeg_vlc(s);
+ av_log(avctx, AV_LOG_ERROR, "mjpeg: error using external huffman table\n");
+ return AVERROR_INVALIDDATA;
}
}
- if (avctx->extradata_size > 9 &&
- AV_RL32(avctx->extradata + 4) == MKTAG('f','i','e','l')) {
- if (avctx->extradata[9] == 6) { /* quicktime icefloe 019 */
- s->interlace_polarity = 1; /* bottom field first */
- av_log(avctx, AV_LOG_DEBUG, "mjpeg bottom field first\n");
- }
+ if (avctx->field_order == AV_FIELD_BB) { /* quicktime icefloe 019 */
+ s->interlace_polarity = 1; /* bottom field first */
+ av_log(avctx, AV_LOG_DEBUG, "mjpeg bottom field first\n");
}
if (avctx->codec->id == CODEC_ID_AMV)
s->flipped = 1;
@@ -1104,9 +1106,9 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
av_log(s->avctx, AV_LOG_DEBUG, "APPx %8X\n", id);
}
- /* buggy AVID, it puts EOI only at every 10th frame */
- /* also this fourcc is used by non-avid files too, it holds some
- informations, but it's always present in AVID creates files */
+ /* Buggy AVID, it puts EOI only at every 10th frame. */
+ /* Also, this fourcc is used by non-avid files too, it holds some
+ information, but it's always present in AVID-created files. */
if (id == AV_RL32("AVI1"))
{
/* structure:
@@ -1272,29 +1274,6 @@ static int mjpeg_decode_com(MJpegDecodeContext *s)
return 0;
}
-#if 0
-static int valid_marker_list[] =
-{
- /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f */
-/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 3 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-/* c */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* d */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* e */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-/* f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
-}
-#endif
-
/* return the 8 bit start code value and update the search
state. Return -1 if no start code found */
static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
@@ -1523,35 +1502,34 @@ eoi_parser:
av_log(avctx, AV_LOG_WARNING, "Found EOI before any SOF, ignoring\n");
break;
}
- {
- if (s->interlaced) {
- s->bottom_field ^= 1;
- /* if not bottom field, do not output image yet */
- if (s->bottom_field == !s->interlace_polarity)
- goto not_the_end;
- }
- *picture = *s->picture_ptr;
- *data_size = sizeof(AVFrame);
-
- if(!s->lossless){
- picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]);
- picture->qstride= 0;
- picture->qscale_table= s->qscale_table;
- memset(picture->qscale_table, picture->quality, (s->width+15)/16);
- if(avctx->debug & FF_DEBUG_QP)
- av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality);
- picture->quality*= FF_QP2LAMBDA;
- }
-
- goto the_end;
+ if (s->interlaced) {
+ s->bottom_field ^= 1;
+ /* if not bottom field, do not output image yet */
+ if (s->bottom_field == !s->interlace_polarity)
+ goto not_the_end;
}
- break;
+ *picture = *s->picture_ptr;
+ *data_size = sizeof(AVFrame);
+
+ if(!s->lossless){
+ picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]);
+ picture->qstride= 0;
+ picture->qscale_table= s->qscale_table;
+ memset(picture->qscale_table, picture->quality, (s->width+15)/16);
+ if(avctx->debug & FF_DEBUG_QP)
+ av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality);
+ picture->quality*= FF_QP2LAMBDA;
+ }
+
+ goto the_end;
case SOS:
if (!s->got_picture) {
av_log(avctx, AV_LOG_WARNING, "Can not process SOS before SOF, skipping\n");
break;
}
- ff_mjpeg_decode_sos(s, NULL, NULL);
+ if (ff_mjpeg_decode_sos(s, NULL, NULL) < 0 &&
+ (avctx->err_recognition & AV_EF_EXPLODE))
+ return AVERROR_INVALIDDATA;
/* buggy avid puts EOI every 10-20th frame */
/* if restart period is over process EOI */
if ((s->buggy_avid && !s->interlaced) || s->restart_interval)
@@ -1621,32 +1599,43 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx)
return 0;
}
+#define OFFSET(x) offsetof(MJpegDecodeContext, x)
+#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ { "extern_huff", "Use external huffman table.", OFFSET(extern_huff), AV_OPT_TYPE_INT, { 0 }, 0, 1, VD },
+ { NULL },
+};
+
+static const AVClass mjpegdec_class = {
+ .class_name = "MJPEG decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_mjpeg_decoder = {
- "mjpeg",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MJPEG,
- sizeof(MJpegDecodeContext),
- ff_mjpeg_decode_init,
- NULL,
- ff_mjpeg_decode_end,
- ff_mjpeg_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "mjpeg",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MJPEG,
+ .priv_data_size = sizeof(MJpegDecodeContext),
+ .init = ff_mjpeg_decode_init,
+ .close = ff_mjpeg_decode_end,
+ .decode = ff_mjpeg_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
+ .priv_class = &mjpegdec_class,
};
AVCodec ff_thp_decoder = {
- "thp",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_THP,
- sizeof(MJpegDecodeContext),
- ff_mjpeg_decode_init,
- NULL,
- ff_mjpeg_decode_end,
- ff_mjpeg_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "thp",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_THP,
+ .priv_data_size = sizeof(MJpegDecodeContext),
+ .init = ff_mjpeg_decode_init,
+ .close = ff_mjpeg_decode_end,
+ .decode = ff_mjpeg_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"),
};
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index 52c256e..bfa987d 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -29,6 +29,8 @@
#ifndef AVCODEC_MJPEGDEC_H
#define AVCODEC_MJPEGDEC_H
+#include "libavutil/log.h"
+
#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
@@ -36,6 +38,7 @@
#define MAX_COMPONENTS 4
typedef struct MJpegDecodeContext {
+ AVClass *class;
AVCodecContext *avctx;
GetBitContext gb;
@@ -106,6 +109,8 @@ typedef struct MJpegDecodeContext {
uint16_t (*ljpeg_buffer)[4];
unsigned int ljpeg_buffer_size;
+
+ int extern_huff;
} MJpegDecodeContext;
int ff_mjpeg_decode_init(AVCodecContext *avctx);
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 169d19e..d1005c8 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -446,13 +446,13 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64])
}
AVCodec ff_mjpeg_encoder = {
- "mjpeg",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MJPEG,
- sizeof(MpegEncContext),
- MPV_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "mjpeg",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MJPEG,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = MPV_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
};
diff --git a/libavcodec/mlib/dsputil_mlib.c b/libavcodec/mlib/dsputil_mlib.c
index c0f2c03..bfa5153 100644
--- a/libavcodec/mlib/dsputil_mlib.c
+++ b/libavcodec/mlib/dsputil_mlib.c
@@ -421,13 +421,14 @@ static void ff_fdct_mlib(DCTELEM *data)
void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx)
{
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
- c->get_pixels = get_pixels_mlib;
c->diff_pixels = diff_pixels_mlib;
c->add_pixels_clamped = add_pixels_clamped_mlib;
if (!high_bit_depth) {
+ c->get_pixels = get_pixels_mlib;
+
c->put_pixels_tab[0][0] = put_pixels16_mlib;
c->put_pixels_tab[0][1] = put_pixels16_x2_mlib;
c->put_pixels_tab[0][2] = put_pixels16_y2_mlib;
diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c
index e85eb72..e0fedeb 100644
--- a/libavcodec/mlp_parser.c
+++ b/libavcodec/mlp_parser.c
@@ -107,7 +107,7 @@ static int truehd_channels(int chanmap)
return channels;
}
-static int64_t truehd_layout(int chanmap)
+static uint64_t truehd_layout(int chanmap)
{
int layout = 0, i;
@@ -138,11 +138,11 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
checksum = ff_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;
+ return AVERROR_INVALIDDATA;
}
if (get_bits_long(gb, 24) != 0xf8726f) /* Sync words */
- return -1;
+ return AVERROR_INVALIDDATA;
mh->stream_type = get_bits(gb, 8);
@@ -173,7 +173,7 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
mh->channels_thd_stream2 = get_bits(gb, 13);
} else
- return -1;
+ return AVERROR_INVALIDDATA;
mh->access_unit_size = 40 << (ratebits & 7);
mh->access_unit_size_pow2 = 64 << (ratebits & 7);
@@ -345,9 +345,9 @@ lost_sync:
}
AVCodecParser ff_mlp_parser = {
- { CODEC_ID_MLP, CODEC_ID_TRUEHD },
- sizeof(MLPParseContext),
- mlp_init,
- mlp_parse,
- ff_parse_close,
+ .codec_ids = { CODEC_ID_MLP, CODEC_ID_TRUEHD },
+ .priv_data_size = sizeof(MLPParseContext),
+ .parser_init = mlp_init,
+ .parser_parse = mlp_parse,
+ .parser_close = ff_parse_close,
};
diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index 5e50eba..357e287 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -45,35 +45,35 @@ static const char* sample_message =
"a sample of this file.";
typedef struct SubStream {
- //! Set if a valid restart header has been read. Otherwise the substream cannot be decoded.
+ /// 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.
+ /// 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.
+ /// The index of the first channel coded in this substream.
uint8_t min_channel;
- //! The index of the last channel coded in this substream.
+ /// The index of the last channel coded in this substream.
uint8_t max_channel;
- //! The number of channels input into the rematrix stage.
+ /// The number of channels input into the rematrix stage.
uint8_t max_matrix_channel;
- //! For each channel output by the matrix, the output channel to map it to
+ /// For each channel output by the matrix, the output channel to map it to
uint8_t ch_assign[MAX_CHANNELS];
- //! Channel coding parameters for channels in the substream
+ /// Channel coding parameters for channels in the substream
ChannelParams channel_params[MAX_CHANNELS];
- //! The left shift applied to random noise in 0x31ea substreams.
+ /// The left shift applied to random noise in 0x31ea substreams.
uint8_t noise_shift;
- //! The current seed value for the pseudorandom noise generator(s).
+ /// 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.
+ /// 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.
+ /// 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)
@@ -88,54 +88,55 @@ typedef struct SubStream {
//@{
/** matrix data */
- //! Number of matrices to be applied.
+ /// Number of matrices to be applied.
uint8_t num_primitive_matrices;
- //! matrix output channel
+ /// matrix output channel
uint8_t matrix_out_ch[MAX_MATRICES];
- //! Whether the LSBs of the matrix output are encoded in the bitstream.
+ /// 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.
+ /// Matrix coefficients, stored as 2.14 fixed point.
int32_t matrix_coeff[MAX_MATRICES][MAX_CHANNELS];
- //! Left shift to apply to noise values in 0x31eb substreams.
+ /// 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.
+ /// Left shift to apply to Huffman-decoded residuals.
uint8_t quant_step_size[MAX_CHANNELS];
- //! number of PCM samples in current audio block
+ /// number of PCM samples in current audio block
uint16_t blocksize;
- //! Number of PCM samples decoded so far in this frame.
+ /// 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.
+ /// 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.
+ /// Running XOR of all output samples.
int32_t lossless_check_data;
} SubStream;
typedef struct MLPDecodeContext {
AVCodecContext *avctx;
+ AVFrame frame;
- //! Current access unit being read has a major sync.
+ /// Current access unit being read has a major sync.
int is_major_sync_unit;
- //! Set if a valid major sync block has been read. Otherwise no decoding is possible.
+ /// 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.
+ /// Number of substreams contained within this stream.
uint8_t num_substreams;
- //! Index of the last substream to decode - further substreams are skipped.
+ /// Index of the last substream to decode - further substreams are skipped.
uint8_t max_decoded_substream;
- //! number of PCM samples contained in each frame
+ /// number of PCM samples contained in each frame
int access_unit_size;
- //! next power of two above the number of samples in each frame
+ /// next power of two above the number of samples in each frame
int access_unit_size_pow2;
SubStream substream[MAX_SUBSTREAMS];
@@ -214,7 +215,7 @@ static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp,
VLC_BITS, (9 + VLC_BITS - 1) / VLC_BITS);
if (result < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
if (lsb_bits > 0)
result = (result << lsb_bits) + get_bits(gbp, lsb_bits);
@@ -239,6 +240,9 @@ static av_cold int mlp_decode_init(AVCodecContext *avctx)
m->substream[substr].lossless_check_data = 0xffffffff;
dsputil_init(&m->dsp, avctx);
+ avcodec_get_frame_defaults(&m->frame);
+ avctx->coded_frame = &m->frame;
+
return 0;
}
@@ -250,61 +254,61 @@ static av_cold int mlp_decode_init(AVCodecContext *avctx)
static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb)
{
MLPHeaderInfo mh;
- int substr;
+ int substr, ret;
- if (ff_mlp_read_major_sync(m->avctx, &mh, gb) != 0)
- return -1;
+ if ((ret = ff_mlp_read_major_sync(m->avctx, &mh, gb)) != 0)
+ return ret;
if (mh.group1_bits == 0) {
av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown bits per sample\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
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;
+ return AVERROR_INVALIDDATA;
}
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;
+ return AVERROR_INVALIDDATA;
}
if (mh.group1_samplerate == 0) {
av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown sampling rate\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
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;
+ return AVERROR_INVALIDDATA;
}
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;
+ return AVERROR_INVALIDDATA;
}
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;
+ return AVERROR_INVALIDDATA;
}
if (mh.num_substreams == 0)
- return -1;
+ return AVERROR_INVALIDDATA;
if (m->avctx->codec_id == CODEC_ID_MLP && mh.num_substreams > 2) {
av_log(m->avctx, AV_LOG_ERROR, "MLP only supports up to 2 substreams.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
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;
+ return AVERROR_INVALIDDATA;
}
m->access_unit_size = mh.access_unit_size;
@@ -351,14 +355,14 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
if (sync_word != 0x31ea >> 1) {
av_log(m->avctx, AV_LOG_ERROR,
"restart header sync incorrect (got 0x%04x)\n", sync_word);
- return -1;
+ return AVERROR_INVALIDDATA;
}
s->noise_type = get_bits1(gbp);
if (m->avctx->codec_id == CODEC_ID_MLP && s->noise_type) {
av_log(m->avctx, AV_LOG_ERROR, "MLP must have 0x31ea sync word.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
skip_bits(gbp, 16); /* Output timestamp */
@@ -371,13 +375,13 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
av_log(m->avctx, AV_LOG_ERROR,
"Max matrix channel cannot be greater than %d.\n",
max_matrix_channel);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (s->max_channel != s->max_matrix_channel) {
av_log(m->avctx, AV_LOG_ERROR,
"Max channel must be equal max matrix channel.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
/* This should happen for TrueHD streams with >6 channels and MLP's noise
@@ -386,13 +390,13 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
av_log(m->avctx, AV_LOG_ERROR,
"Number of channels %d is larger than the maximum supported "
"by the decoder. %s\n", s->max_channel+2, sample_message);
- return -1;
+ return AVERROR_INVALIDDATA;
}
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;
+ return AVERROR_INVALIDDATA;
}
if (m->avctx->request_channels > 0
@@ -431,7 +435,7 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
av_log(m->avctx, AV_LOG_ERROR,
"Assignment of matrix channel %d to invalid output channel %d. %s\n",
ch, ch_assign, sample_message);
- return -1;
+ return AVERROR_INVALIDDATA;
}
s->ch_assign[ch_assign] = ch;
}
@@ -487,7 +491,7 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp,
if (m->filter_changed[channel][filter]++ > 1) {
av_log(m->avctx, AV_LOG_ERROR, "Filters may change only once per access unit.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
order = get_bits(gbp, 4);
@@ -495,7 +499,7 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp,
av_log(m->avctx, AV_LOG_ERROR,
"%cIR filter order %d is greater than maximum %d.\n",
fchar, order, max_order);
- return -1;
+ return AVERROR_INVALIDDATA;
}
fp->order = order;
@@ -511,13 +515,13 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp,
av_log(m->avctx, AV_LOG_ERROR,
"%cIR filter coeff_bits must be between 1 and 16.\n",
fchar);
- return -1;
+ return AVERROR_INVALIDDATA;
}
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;
+ return AVERROR_INVALIDDATA;
}
for (i = 0; i < order; i++)
@@ -529,7 +533,7 @@ static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp,
if (filter == FIR) {
av_log(m->avctx, AV_LOG_ERROR,
"FIR filter has state data specified.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
state_bits = get_bits(gbp, 4);
@@ -557,7 +561,7 @@ static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitCo
if (m->matrix_changed++ > 1) {
av_log(m->avctx, AV_LOG_ERROR, "Matrices may change only once per access unit.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
s->num_primitive_matrices = get_bits(gbp, 4);
@@ -566,7 +570,7 @@ static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitCo
av_log(m->avctx, AV_LOG_ERROR,
"Number of primitive matrices cannot be greater than %d.\n",
max_primitive_matrices);
- return -1;
+ return AVERROR_INVALIDDATA;
}
for (mat = 0; mat < s->num_primitive_matrices; mat++) {
@@ -579,12 +583,12 @@ static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitCo
av_log(m->avctx, AV_LOG_ERROR,
"Invalid channel %d specified as output from matrix.\n",
s->matrix_out_ch[mat]);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (frac_bits > 14) {
av_log(m->avctx, AV_LOG_ERROR,
"Too many fractional bits specified.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
max_chan = s->max_matrix_channel;
@@ -617,27 +621,28 @@ static int read_channel_params(MLPDecodeContext *m, unsigned int substr,
ChannelParams *cp = &s->channel_params[ch];
FilterParams *fir = &cp->filter_params[FIR];
FilterParams *iir = &cp->filter_params[IIR];
+ int ret;
if (s->param_presence_flags & PARAM_FIR)
if (get_bits1(gbp))
- if (read_filter_params(m, gbp, substr, ch, FIR) < 0)
- return -1;
+ if ((ret = read_filter_params(m, gbp, substr, ch, FIR)) < 0)
+ return ret;
if (s->param_presence_flags & PARAM_IIR)
if (get_bits1(gbp))
- if (read_filter_params(m, gbp, substr, ch, IIR) < 0)
- return -1;
+ if ((ret = read_filter_params(m, gbp, substr, ch, IIR)) < 0)
+ return ret;
if (fir->order + iir->order > 8) {
av_log(m->avctx, AV_LOG_ERROR, "Total filter orders too high.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (fir->order && iir->order &&
fir->shift != iir->shift) {
av_log(m->avctx, AV_LOG_ERROR,
"FIR and IIR filters must use the same precision.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
/* The FIR and IIR filters must have the same precision.
* To simplify the filtering code, only the precision of the
@@ -656,7 +661,7 @@ static int read_channel_params(MLPDecodeContext *m, unsigned int substr,
if (cp->huff_lsbs > 24) {
av_log(m->avctx, AV_LOG_ERROR, "Invalid huff_lsbs.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
cp->sign_huff_offset = calculate_sign_huff(m, substr, ch);
@@ -672,6 +677,7 @@ static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp,
{
SubStream *s = &m->substream[substr];
unsigned int ch;
+ int ret;
if (s->param_presence_flags & PARAM_PRESENCE)
if (get_bits1(gbp))
@@ -683,14 +689,14 @@ static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp,
if (s->blocksize < 8 || s->blocksize > m->access_unit_size) {
av_log(m->avctx, AV_LOG_ERROR, "Invalid blocksize.");
s->blocksize = 0;
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
if (s->param_presence_flags & PARAM_MATRIX)
if (get_bits1(gbp))
- if (read_matrix_params(m, substr, gbp) < 0)
- return -1;
+ if ((ret = read_matrix_params(m, substr, gbp)) < 0)
+ return ret;
if (s->param_presence_flags & PARAM_OUTSHIFT)
if (get_bits1(gbp))
@@ -709,8 +715,8 @@ static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp,
for (ch = s->min_channel; ch <= s->max_channel; ch++)
if (get_bits1(gbp))
- if (read_channel_params(m, substr, gbp, ch) < 0)
- return -1;
+ if ((ret = read_channel_params(m, substr, gbp, ch)) < 0)
+ return ret;
return 0;
}
@@ -752,6 +758,7 @@ static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp,
{
SubStream *s = &m->substream[substr];
unsigned int i, ch, expected_stream_pos = 0;
+ int ret;
if (s->data_check_present) {
expected_stream_pos = get_bits_count(gbp);
@@ -762,15 +769,15 @@ static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp,
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;
+ return AVERROR_INVALIDDATA;
}
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;
+ if ((ret = read_huff_channels(m, gbp, substr, i)) < 0)
+ return ret;
for (ch = s->min_channel; ch <= s->max_channel; ch++)
filter_channel(m, substr, ch);
@@ -901,16 +908,30 @@ static void rematrix_channels(MLPDecodeContext *m, unsigned int substr)
/** 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)
+static int output_data(MLPDecodeContext *m, unsigned int substr,
+ void *data, int *got_frame_ptr)
{
+ AVCodecContext *avctx = m->avctx;
SubStream *s = &m->substream[substr];
unsigned int i, out_ch = 0;
- int32_t *data_32 = (int32_t*) data;
- int16_t *data_16 = (int16_t*) data;
+ int32_t *data_32;
+ int16_t *data_16;
+ int ret;
+ int is32 = (m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
+
+ if (m->avctx->channels != s->max_matrix_channel + 1) {
+ av_log(m->avctx, AV_LOG_ERROR, "channel count mismatch\n");
+ return AVERROR_INVALIDDATA;
+ }
- if (*data_size < (s->max_channel + 1) * s->blockpos * (is32 ? 4 : 2))
- return -1;
+ /* get output buffer */
+ m->frame.nb_samples = s->blockpos;
+ if ((ret = avctx->get_buffer(avctx, &m->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ data_32 = (int32_t *)m->frame.data[0];
+ data_16 = (int16_t *)m->frame.data[0];
for (i = 0; i < s->blockpos; i++) {
for (out_ch = 0; out_ch <= s->max_matrix_channel; out_ch++) {
@@ -923,27 +944,18 @@ static int output_data_internal(MLPDecodeContext *m, unsigned int substr,
}
}
- *data_size = i * out_ch * (is32 ? 4 : 2);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = m->frame;
return 0;
}
-static int output_data(MLPDecodeContext *m, unsigned int substr,
- uint8_t *data, unsigned int *data_size)
-{
- if (m->avctx->sample_fmt == AV_SAMPLE_FMT_S32)
- return output_data_internal(m, substr, data, data_size, 1);
- else
- return output_data_internal(m, substr, data, data_size, 0);
-}
-
-
/** Read an access unit from the stream.
* @return negative on error, 0 if not enough data is present in the input stream,
* otherwise the number of bytes consumed. */
-static int read_access_unit(AVCodecContext *avctx, void* data, int *data_size,
- AVPacket *avpkt)
+static int read_access_unit(AVCodecContext *avctx, void* data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
@@ -956,6 +968,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data, int *data_size,
uint8_t substream_parity_present[MAX_SUBSTREAMS];
uint16_t substream_data_len[MAX_SUBSTREAMS];
uint8_t parity_bits;
+ int ret;
if (buf_size < 4)
return 0;
@@ -963,7 +976,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data, int *data_size,
length = (AV_RB16(buf) & 0xfff) * 2;
if (length < 4 || length > buf_size)
- return -1;
+ return AVERROR_INVALIDDATA;
init_get_bits(&gb, (buf + 4), (length - 4) * 8);
@@ -978,7 +991,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data, int *data_size,
if (!m->params_valid) {
av_log(m->avctx, AV_LOG_WARNING,
"Stream parameters not seen; skipping frame.\n");
- *data_size = 0;
+ *got_frame_ptr = 0;
return length;
}
@@ -1069,8 +1082,8 @@ static int read_access_unit(AVCodecContext *avctx, void* data, int *data_size,
if (!s->restart_seen)
goto next_substr;
- if (read_block_data(m, &gb, substr) < 0)
- return -1;
+ if ((ret = read_block_data(m, &gb, substr)) < 0)
+ return ret;
if (get_bits_count(&gb) >= substream_data_len[substr] * 8)
goto substream_length_mismatch;
@@ -1083,13 +1096,13 @@ static int read_access_unit(AVCodecContext *avctx, void* data, int *data_size,
int shorten_by;
if (get_bits(&gb, 16) != 0xD234)
- return -1;
+ return AVERROR_INVALIDDATA;
shorten_by = get_bits(&gb, 16);
if (m->avctx->codec_id == CODEC_ID_TRUEHD && shorten_by & 0x2000)
s->blockpos -= FFMIN(shorten_by & 0x1FFF, s->blockpos);
else if (m->avctx->codec_id == CODEC_ID_MLP && shorten_by != 0xD234)
- return -1;
+ return AVERROR_INVALIDDATA;
if (substr == m->max_decoded_substream)
av_log(m->avctx, AV_LOG_INFO, "End of stream indicated.\n");
@@ -1123,42 +1136,40 @@ next_substr:
rematrix_channels(m, m->max_decoded_substream);
- if (output_data(m, m->max_decoded_substream, data, data_size) < 0)
- return -1;
+ if ((ret = output_data(m, m->max_decoded_substream, data, got_frame_ptr)) < 0)
+ return ret;
return length;
substream_length_mismatch:
av_log(m->avctx, AV_LOG_ERROR, "substream %d length mismatch\n", substr);
- return -1;
+ return AVERROR_INVALIDDATA;
error:
m->params_valid = 0;
- return -1;
+ return AVERROR_INVALIDDATA;
}
AVCodec ff_mlp_decoder = {
- "mlp",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MLP,
- sizeof(MLPDecodeContext),
- mlp_decode_init,
- NULL,
- NULL,
- read_access_unit,
+ .name = "mlp",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MLP,
+ .priv_data_size = sizeof(MLPDecodeContext),
+ .init = mlp_decode_init,
+ .decode = read_access_unit,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"),
};
#if CONFIG_TRUEHD_DECODER
AVCodec ff_truehd_decoder = {
- "truehd",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_TRUEHD,
- sizeof(MLPDecodeContext),
- mlp_decode_init,
- NULL,
- NULL,
- read_access_unit,
+ .name = "truehd",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_TRUEHD,
+ .priv_data_size = sizeof(MLPDecodeContext),
+ .init = mlp_decode_init,
+ .decode = read_access_unit,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("TrueHD"),
};
#endif /* CONFIG_TRUEHD_DECODER */
diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c
index b65335e..9e82ef9 100644
--- a/libavcodec/mmvideo.c
+++ b/libavcodec/mmvideo.c
@@ -214,14 +214,13 @@ static av_cold int mm_decode_end(AVCodecContext *avctx)
}
AVCodec ff_mmvideo_decoder = {
- "mmvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MMVIDEO,
- sizeof(MmContext),
- mm_decode_init,
- NULL,
- mm_decode_end,
- mm_decode_frame,
- CODEC_CAP_DR1,
+ .name = "mmvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MMVIDEO,
+ .priv_data_size = sizeof(MmContext),
+ .init = mm_decode_init,
+ .close = mm_decode_end,
+ .decode = mm_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("American Laser Games MM Video"),
};
diff --git a/libavcodec/motion-test.c b/libavcodec/motion-test.c
index b88917c..8708636 100644
--- a/libavcodec/motion-test.c
+++ b/libavcodec/motion-test.c
@@ -33,14 +33,13 @@
#include "dsputil.h"
#include "libavutil/lfg.h"
-#undef exit
#undef printf
#define WIDTH 64
#define HEIGHT 64
-uint8_t img1[WIDTH * HEIGHT];
-uint8_t img2[WIDTH * HEIGHT];
+static uint8_t img1[WIDTH * HEIGHT];
+static uint8_t img2[WIDTH * HEIGHT];
static void fill_random(uint8_t *tab, int size)
{
@@ -61,7 +60,6 @@ static void help(void)
{
printf("motion-test [-h]\n"
"test motion implementations\n");
- exit(1);
}
static int64_t gettime(void)
@@ -138,13 +136,13 @@ int main(int argc, char **argv)
switch(c) {
case 'h':
help();
- break;
+ return 1;
}
}
- printf("ffmpeg motion test\n");
+ printf("Libav motion test\n");
- ctx = avcodec_alloc_context();
+ ctx = avcodec_alloc_context3(NULL);
ctx->dsp_mask = AV_CPU_FLAG_FORCE;
dsputil_init(&cctx, ctx);
for (c = 0; c < flags_size; c++) {
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 5f10456..c4512a9 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -52,7 +52,7 @@ static inline int sad_hpel_motion_search(MpegEncContext * s,
int src_index, int ref_index,
int size, int h);
-static inline int update_map_generation(MotionEstContext *c)
+static inline unsigned update_map_generation(MotionEstContext *c)
{
c->map_generation+= 1<<(ME_MAP_MV_BITS*2);
if(c->map_generation==0){
@@ -248,7 +248,7 @@ static int cmp_internal(MpegEncContext *s, const int x, const int y, const int s
}
}
-/*! \brief compares a block (either a full macroblock or a partition thereof)
+/** @brief compares a block (either a full macroblock or a partition thereof)
against a proposed motion-compensated prediction of that block
*/
static av_always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
@@ -374,30 +374,6 @@ int ff_init_me(MpegEncContext *s){
return 0;
}
-#if 0
-static int pix_dev(uint8_t * pix, int line_size, int mean)
-{
- int s, i, j;
-
- s = 0;
- for (i = 0; i < 16; i++) {
- for (j = 0; j < 16; j += 8) {
- s += FFABS(pix[0]-mean);
- s += FFABS(pix[1]-mean);
- s += FFABS(pix[2]-mean);
- s += FFABS(pix[3]-mean);
- s += FFABS(pix[4]-mean);
- s += FFABS(pix[5]-mean);
- s += FFABS(pix[6]-mean);
- s += FFABS(pix[7]-mean);
- pix += 8;
- }
- pix += line_size - 16;
- }
- return s;
-}
-#endif
-
static inline void no_motion_search(MpegEncContext * s,
int *mx_ptr, int *my_ptr)
{
@@ -533,16 +509,16 @@ static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4)
if(mv4){
int mot_xy= s->block_index[0];
- s->current_picture.motion_val[0][mot_xy ][0]= mx;
- s->current_picture.motion_val[0][mot_xy ][1]= my;
- s->current_picture.motion_val[0][mot_xy+1][0]= mx;
- s->current_picture.motion_val[0][mot_xy+1][1]= my;
+ s->current_picture.f.motion_val[0][mot_xy ][0] = mx;
+ s->current_picture.f.motion_val[0][mot_xy ][1] = my;
+ s->current_picture.f.motion_val[0][mot_xy + 1][0] = mx;
+ s->current_picture.f.motion_val[0][mot_xy + 1][1] = my;
mot_xy += s->b8_stride;
- s->current_picture.motion_val[0][mot_xy ][0]= mx;
- s->current_picture.motion_val[0][mot_xy ][1]= my;
- s->current_picture.motion_val[0][mot_xy+1][0]= mx;
- s->current_picture.motion_val[0][mot_xy+1][1]= my;
+ s->current_picture.f.motion_val[0][mot_xy ][0] = mx;
+ s->current_picture.f.motion_val[0][mot_xy ][1] = my;
+ s->current_picture.f.motion_val[0][mot_xy + 1][0] = mx;
+ s->current_picture.f.motion_val[0][mot_xy + 1][1] = my;
}
}
@@ -615,8 +591,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
const int mot_stride = s->b8_stride;
const int mot_xy = s->block_index[block];
- P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
- P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
+ P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0];
+ P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1];
if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift);
@@ -625,10 +601,10 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
c->pred_x= pred_x4= P_LEFT[0];
c->pred_y= pred_y4= P_LEFT[1];
} else {
- P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0];
- P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1];
- P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0];
- P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1];
+ P_TOP[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][0];
+ P_TOP[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][1];
+ P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + off[block]][0];
+ P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + off[block]][1];
if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1] = (c->ymax<<shift);
if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift);
@@ -680,8 +656,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
my4_sum+= my4;
}
- s->current_picture.motion_val[0][ s->block_index[block] ][0]= mx4;
- s->current_picture.motion_val[0][ s->block_index[block] ][1]= my4;
+ s->current_picture.f.motion_val[0][s->block_index[block]][0] = mx4;
+ s->current_picture.f.motion_val[0][s->block_index[block]][1] = my4;
if(mx4 != mx || my4 != my) same=0;
}
@@ -690,7 +666,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
return INT_MAX;
if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){
- dmin_sum += s->dsp.mb_cmp[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*16*stride, c->scratchpad, stride, 16);
+ dmin_sum += s->dsp.mb_cmp[0](s, s->new_picture.f.data[0] + s->mb_x*16 + s->mb_y*16*stride, c->scratchpad, stride, 16);
}
if(c->avctx->mb_cmp&FF_CMP_CHROMA){
@@ -705,15 +681,15 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize;
if(s->no_rounding){
- s->dsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8);
- s->dsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8);
+ s->dsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad , s->last_picture.f.data[1] + offset, s->uvlinesize, 8);
+ s->dsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad + 8, s->last_picture.f.data[2] + offset, s->uvlinesize, 8);
}else{
- s->dsp.put_pixels_tab [1][dxy](c->scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8);
- s->dsp.put_pixels_tab [1][dxy](c->scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8);
+ s->dsp.put_pixels_tab [1][dxy](c->scratchpad , s->last_picture.f.data[1] + offset, s->uvlinesize, 8);
+ s->dsp.put_pixels_tab [1][dxy](c->scratchpad + 8, s->last_picture.f.data[2] + offset, s->uvlinesize, 8);
}
- dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad , s->uvlinesize, 8);
- dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad+8, s->uvlinesize, 8);
+ dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.f.data[1] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad , s->uvlinesize, 8);
+ dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.f.data[2] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad+8, s->uvlinesize, 8);
}
c->pred_x= mx;
@@ -879,7 +855,7 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
Picture *p= s->current_picture_ptr;
int mb_xy= mb_x + mb_y*s->mb_stride;
int xy= 2*mb_x + 2*mb_y*s->b8_stride;
- int mb_type= s->current_picture.mb_type[mb_xy];
+ int mb_type= s->current_picture.f.mb_type[mb_xy];
int flags= c->flags;
int shift= (flags&FLAG_QPEL) + 1;
int mask= (1<<shift)-1;
@@ -896,8 +872,8 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
for(i=0; i<4; i++){
int xy= s->block_index[i];
- clip_input_mv(s, p->motion_val[0][xy], !!IS_INTERLACED(mb_type));
- clip_input_mv(s, p->motion_val[1][xy], !!IS_INTERLACED(mb_type));
+ clip_input_mv(s, p->f.motion_val[0][xy], !!IS_INTERLACED(mb_type));
+ clip_input_mv(s, p->f.motion_val[1][xy], !!IS_INTERLACED(mb_type));
}
if(IS_INTERLACED(mb_type)){
@@ -912,8 +888,8 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
}
if(USES_LIST(mb_type, 0)){
- int field_select0= p->ref_index[0][4*mb_xy ];
- int field_select1= p->ref_index[0][4*mb_xy+2];
+ int field_select0= p->f.ref_index[0][4*mb_xy ];
+ int field_select1= p->f.ref_index[0][4*mb_xy+2];
assert(field_select0==0 ||field_select0==1);
assert(field_select1==0 ||field_select1==1);
init_interlaced_ref(s, 0);
@@ -921,46 +897,46 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
if(p_type){
s->p_field_select_table[0][mb_xy]= field_select0;
s->p_field_select_table[1][mb_xy]= field_select1;
- *(uint32_t*)s->p_field_mv_table[0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ];
- *(uint32_t*)s->p_field_mv_table[1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2];
+ *(uint32_t*)s->p_field_mv_table[0][field_select0][mb_xy] = *(uint32_t*)p->f.motion_val[0][xy ];
+ *(uint32_t*)s->p_field_mv_table[1][field_select1][mb_xy] = *(uint32_t*)p->f.motion_val[0][xy2];
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER_I;
}else{
s->b_field_select_table[0][0][mb_xy]= field_select0;
s->b_field_select_table[0][1][mb_xy]= field_select1;
- *(uint32_t*)s->b_field_mv_table[0][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ];
- *(uint32_t*)s->b_field_mv_table[0][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2];
+ *(uint32_t*)s->b_field_mv_table[0][0][field_select0][mb_xy] = *(uint32_t*)p->f.motion_val[0][xy ];
+ *(uint32_t*)s->b_field_mv_table[0][1][field_select1][mb_xy] = *(uint32_t*)p->f.motion_val[0][xy2];
s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_FORWARD_I;
}
- x= p->motion_val[0][xy ][0];
- y= p->motion_val[0][xy ][1];
+ x = p->f.motion_val[0][xy ][0];
+ y = p->f.motion_val[0][xy ][1];
d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0, 0, cmpf, chroma_cmpf, flags);
- x= p->motion_val[0][xy2][0];
- y= p->motion_val[0][xy2][1];
+ x = p->f.motion_val[0][xy2][0];
+ y = p->f.motion_val[0][xy2][1];
d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1, 1, cmpf, chroma_cmpf, flags);
}
if(USES_LIST(mb_type, 1)){
- int field_select0= p->ref_index[1][4*mb_xy ];
- int field_select1= p->ref_index[1][4*mb_xy+2];
+ int field_select0 = p->f.ref_index[1][4 * mb_xy ];
+ int field_select1 = p->f.ref_index[1][4 * mb_xy + 2];
assert(field_select0==0 ||field_select0==1);
assert(field_select1==0 ||field_select1==1);
init_interlaced_ref(s, 2);
s->b_field_select_table[1][0][mb_xy]= field_select0;
s->b_field_select_table[1][1][mb_xy]= field_select1;
- *(uint32_t*)s->b_field_mv_table[1][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[1][xy ];
- *(uint32_t*)s->b_field_mv_table[1][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[1][xy2];
+ *(uint32_t*)s->b_field_mv_table[1][0][field_select0][mb_xy] = *(uint32_t*)p->f.motion_val[1][xy ];
+ *(uint32_t*)s->b_field_mv_table[1][1][field_select1][mb_xy] = *(uint32_t*)p->f.motion_val[1][xy2];
if(USES_LIST(mb_type, 0)){
s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BIDIR_I;
}else{
s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BACKWARD_I;
}
- x= p->motion_val[1][xy ][0];
- y= p->motion_val[1][xy ][1];
+ x = p->f.motion_val[1][xy ][0];
+ y = p->f.motion_val[1][xy ][1];
d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0+2, 0, cmpf, chroma_cmpf, flags);
- x= p->motion_val[1][xy2][0];
- y= p->motion_val[1][xy2][1];
+ x = p->f.motion_val[1][xy2][0];
+ y = p->f.motion_val[1][xy2][1];
d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1+2, 1, cmpf, chroma_cmpf, flags);
//FIXME bidir scores
}
@@ -976,33 +952,33 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
init_mv4_ref(c);
for(i=0; i<4; i++){
xy= s->block_index[i];
- x= p->motion_val[0][xy][0];
- y= p->motion_val[0][xy][1];
+ x= p->f.motion_val[0][xy][0];
+ y= p->f.motion_val[0][xy][1];
d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 1, 8, i, i, cmpf, chroma_cmpf, flags);
}
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER4V;
}else{
if(USES_LIST(mb_type, 0)){
if(p_type){
- *(uint32_t*)s->p_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy];
+ *(uint32_t*)s->p_mv_table[mb_xy] = *(uint32_t*)p->f.motion_val[0][xy];
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER;
}else if(USES_LIST(mb_type, 1)){
- *(uint32_t*)s->b_bidir_forw_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy];
- *(uint32_t*)s->b_bidir_back_mv_table[mb_xy]= *(uint32_t*)p->motion_val[1][xy];
+ *(uint32_t*)s->b_bidir_forw_mv_table[mb_xy] = *(uint32_t*)p->f.motion_val[0][xy];
+ *(uint32_t*)s->b_bidir_back_mv_table[mb_xy] = *(uint32_t*)p->f.motion_val[1][xy];
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BIDIR;
}else{
- *(uint32_t*)s->b_forw_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy];
+ *(uint32_t*)s->b_forw_mv_table[mb_xy] = *(uint32_t*)p->f.motion_val[0][xy];
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_FORWARD;
}
- x= p->motion_val[0][xy][0];
- y= p->motion_val[0][xy][1];
+ x = p->f.motion_val[0][xy][0];
+ y = p->f.motion_val[0][xy][1];
d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 0, 0, cmpf, chroma_cmpf, flags);
}else if(USES_LIST(mb_type, 1)){
- *(uint32_t*)s->b_back_mv_table[mb_xy]= *(uint32_t*)p->motion_val[1][xy];
+ *(uint32_t*)s->b_back_mv_table[mb_xy] = *(uint32_t*)p->f.motion_val[1][xy];
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BACKWARD;
- x= p->motion_val[1][xy][0];
- y= p->motion_val[1][xy][1];
+ x = p->f.motion_val[1][xy][0];
+ y = p->f.motion_val[1][xy][1];
d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 2, 0, cmpf, chroma_cmpf, flags);
}else
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA;
@@ -1023,7 +999,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
int mb_type=0;
Picture * const pic= &s->current_picture;
- init_ref(c, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0);
+ init_ref(c, s->new_picture.f.data, s->last_picture.f.data, NULL, 16*mb_x, 16*mb_y, 0);
assert(s->quarter_sample==0 || s->quarter_sample==1);
assert(s->linesize == c->stride);
@@ -1040,7 +1016,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
/* intra / predictive decision */
pix = c->src[0][0];
sum = s->dsp.pix_sum(pix, s->linesize);
- varc = s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500;
+ varc = s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)sum*sum)>>8) + 500;
pic->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
pic->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8;
@@ -1075,16 +1051,16 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
const int mot_stride = s->b8_stride;
const int mot_xy = s->block_index[0];
- P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
- P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
+ P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0];
+ P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1];
if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift);
if(!s->first_slice_line) {
- P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0];
- P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1];
- P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][0];
- P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1];
+ P_TOP[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][0];
+ P_TOP[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride ][1];
+ P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][0];
+ P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][1];
if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1] = (c->ymax<<shift);
if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
@@ -1202,7 +1178,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
if((c->avctx->mb_cmp&0xFF)==FF_CMP_SSE){
intra_score= varc - 500;
}else{
- int mean= (sum+128)>>8;
+ unsigned mean = (sum+128)>>8;
mean*= 0x01010101;
for(i=0; i<16; i++){
@@ -1214,37 +1190,13 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
intra_score= s->dsp.mb_cmp[0](s, c->scratchpad, pix, s->linesize, 16);
}
-#if 0 //FIXME
- /* get chroma score */
- if(c->avctx->mb_cmp&FF_CMP_CHROMA){
- for(i=1; i<3; i++){
- uint8_t *dest_c;
- int mean;
-
- if(s->out_format == FMT_H263){
- mean= (s->dc_val[i][mb_x + mb_y*s->b8_stride] + 4)>>3; //FIXME not exact but simple ;)
- }else{
- mean= (s->last_dc[i] + 4)>>3;
- }
- dest_c = s->new_picture.data[i] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8;
-
- mean*= 0x01010101;
- for(i=0; i<8; i++){
- *(uint32_t*)(&c->scratchpad[i*s->uvlinesize+ 0]) = mean;
- *(uint32_t*)(&c->scratchpad[i*s->uvlinesize+ 4]) = mean;
- }
-
- intra_score+= s->dsp.mb_cmp[1](s, c->scratchpad, dest_c, s->uvlinesize);
- }
- }
-#endif
intra_score += c->mb_penalty_factor*16;
if(intra_score < dmin){
mb_type= CANDIDATE_MB_TYPE_INTRA;
- s->current_picture.mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
+ s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
}else
- s->current_picture.mb_type[mb_y*s->mb_stride + mb_x]= 0;
+ s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = 0;
{
int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
@@ -1264,7 +1216,7 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
int P[10][2];
const int shift= 1+s->quarter_sample;
const int xy= mb_x + mb_y*s->mb_stride;
- init_ref(c, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0);
+ init_ref(c, s->new_picture.f.data, s->last_picture.f.data, NULL, 16*mb_x, 16*mb_y, 0);
assert(s->quarter_sample==0 || s->quarter_sample==1);
@@ -1615,7 +1567,7 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
ymin= xmin=(-32)>>shift;
ymax= xmax= 31>>shift;
- if(IS_8X8(s->next_picture.mb_type[mot_xy])){
+ if (IS_8X8(s->next_picture.f.mb_type[mot_xy])) {
s->mv_type= MV_TYPE_8X8;
}else{
s->mv_type= MV_TYPE_16X16;
@@ -1625,8 +1577,8 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
int index= s->block_index[i];
int min, max;
- c->co_located_mv[i][0]= s->next_picture.motion_val[0][index][0];
- c->co_located_mv[i][1]= s->next_picture.motion_val[0][index][1];
+ c->co_located_mv[i][0] = s->next_picture.f.motion_val[0][index][0];
+ c->co_located_mv[i][1] = s->next_picture.f.motion_val[0][index][1];
c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3));
c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3));
// c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3);
@@ -1708,13 +1660,14 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
int fmin, bmin, dmin, fbmin, bimin, fimin;
int type=0;
const int xy = mb_y*s->mb_stride + mb_x;
- init_ref(c, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2);
+ init_ref(c, s->new_picture.f.data, s->last_picture.f.data,
+ s->next_picture.f.data, 16 * mb_x, 16 * mb_y, 2);
get_limits(s, 16*mb_x, 16*mb_y);
c->skip=0;
- if(s->codec_id == CODEC_ID_MPEG4 && s->next_picture.mbskip_table[xy]){
+ if (s->codec_id == CODEC_ID_MPEG4 && s->next_picture.f.mbskip_table[xy]) {
int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0
score= ((unsigned)(score*score + 128*256))>>16;
@@ -1849,10 +1802,6 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //do not try direct mode if it is invalid for this MB
if(s->codec_id == CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT && s->flags&CODEC_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy])
type |= CANDIDATE_MB_TYPE_DIRECT0;
-#if 0
- if(s->out_format == FMT_MPEG1)
- type |= CANDIDATE_MB_TYPE_INTRA;
-#endif
}
s->mb_type[mb_y*s->mb_stride + mb_x]= type;
@@ -1947,14 +1896,14 @@ void ff_fix_long_p_mvs(MpegEncContext * s)
int block;
for(block=0; block<4; block++){
int off= (block& 1) + (block>>1)*wrap;
- int mx= s->current_picture.motion_val[0][ xy + off ][0];
- int my= s->current_picture.motion_val[0][ xy + off ][1];
+ int mx = s->current_picture.f.motion_val[0][ xy + off ][0];
+ int my = s->current_picture.f.motion_val[0][ xy + off ][1];
if( mx >=range || mx <-range
|| my >=range || my <-range){
s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V;
s->mb_type[i] |= CANDIDATE_MB_TYPE_INTRA;
- s->current_picture.mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
+ s->current_picture.f.mb_type[i] = CANDIDATE_MB_TYPE_INTRA;
}
}
}
diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c
index d65edd9..d0d4b41 100644
--- a/libavcodec/motion_est_template.c
+++ b/libavcodec/motion_est_template.c
@@ -44,75 +44,6 @@
COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
}
-#if 0
-static int hpel_motion_search)(MpegEncContext * s,
- int *mx_ptr, int *my_ptr, int dmin,
- uint8_t *ref_data[3],
- int size)
-{
- const int xx = 16 * s->mb_x + 8*(n&1);
- const int yy = 16 * s->mb_y + 8*(n>>1);
- const int mx = *mx_ptr;
- const int my = *my_ptr;
- const int penalty_factor= c->sub_penalty_factor;
-
- LOAD_COMMON
-
- // INIT;
- //FIXME factorize
- me_cmp_func cmp, chroma_cmp, cmp_sub, chroma_cmp_sub;
-
- if(s->no_rounding /*FIXME b_type*/){
- hpel_put= &s->dsp.put_no_rnd_pixels_tab[size];
- chroma_hpel_put= &s->dsp.put_no_rnd_pixels_tab[size+1];
- }else{
- hpel_put=& s->dsp.put_pixels_tab[size];
- chroma_hpel_put= &s->dsp.put_pixels_tab[size+1];
- }
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
- cmp_sub= s->dsp.me_sub_cmp[size];
- chroma_cmp_sub= s->dsp.me_sub_cmp[size+1];
-
- if(c->skip){ //FIXME somehow move up (benchmark)
- *mx_ptr = 0;
- *my_ptr = 0;
- return dmin;
- }
-
- if(c->avctx->me_cmp != c->avctx->me_sub_cmp){
- CMP_HPEL(dmin, 0, 0, mx, my, size);
- if(mx || my)
- dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor;
- }
-
- if (mx > xmin && mx < xmax &&
- my > ymin && my < ymax) {
- int bx=2*mx, by=2*my;
- int d= dmin;
-
- CHECK_HALF_MV(1, 1, mx-1, my-1)
- CHECK_HALF_MV(0, 1, mx , my-1)
- CHECK_HALF_MV(1, 1, mx , my-1)
- CHECK_HALF_MV(1, 0, mx-1, my )
- CHECK_HALF_MV(1, 0, mx , my )
- CHECK_HALF_MV(1, 1, mx-1, my )
- CHECK_HALF_MV(0, 1, mx , my )
- CHECK_HALF_MV(1, 1, mx , my )
-
- assert(bx >= xmin*2 || bx <= xmax*2 || by >= ymin*2 || by <= ymax*2);
-
- *mx_ptr = bx;
- *my_ptr = by;
- }else{
- *mx_ptr =2*mx;
- *my_ptr =2*my;
- }
-
- return dmin;
-}
-
-#else
static int hpel_motion_search(MpegEncContext * s,
int *mx_ptr, int *my_ptr, int dmin,
int src_index, int ref_index,
@@ -158,8 +89,8 @@ static int hpel_motion_search(MpegEncContext * s,
const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]
+ (mv_penalty[bx - pred_x] + mv_penalty[by+2 - pred_y])*c->penalty_factor;
- int key;
- int map_generation= c->map_generation;
+ unsigned key;
+ unsigned map_generation= c->map_generation;
#ifndef NDEBUG
uint32_t *map= c->map;
#endif
@@ -218,7 +149,6 @@ static int hpel_motion_search(MpegEncContext * s,
return dmin;
}
-#endif
static int no_sub_motion_search(MpegEncContext * s,
int *mx_ptr, int *my_ptr, int dmin,
@@ -278,7 +208,7 @@ static int qpel_motion_search(MpegEncContext * s,
const int mx = *mx_ptr;
const int my = *my_ptr;
const int penalty_factor= c->sub_penalty_factor;
- const int map_generation= c->map_generation;
+ const unsigned map_generation = c->map_generation;
const int subpel_quality= c->avctx->me_subpel_quality;
uint32_t *map= c->map;
me_cmp_func cmpf, chroma_cmpf;
@@ -321,7 +251,6 @@ static int qpel_motion_search(MpegEncContext * s,
int best_pos[8][2];
memset(best, 64, sizeof(int)*8);
-#if 1
if(s->me.dia_size>=2){
const int tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
const int bl= score_map[(index+(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
@@ -410,76 +339,6 @@ static int qpel_motion_search(MpegEncContext * s,
CHECK_QUARTER_MV(nx&3, ny&3, nx>>2, ny>>2)
}
-#if 0
- const int tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
- const int bl= score_map[(index+(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
- const int tr= score_map[(index-(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];
- const int br= score_map[(index+(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];
-// if(l < r && l < t && l < b && l < tl && l < bl && l < tr && l < br && bl < tl){
- if(tl<br){
-
-// nx= FFMAX(4*mx - bx, bx - 4*mx);
-// ny= FFMAX(4*my - by, by - 4*my);
-
- static int stats[7][7], count;
- count++;
- stats[4*mx - bx + 3][4*my - by + 3]++;
- if(256*256*256*64 % count ==0){
- for(i=0; i<49; i++){
- if((i%7)==0) printf("\n");
- printf("%6d ", stats[0][i]);
- }
- printf("\n");
- }
- }
-#endif
-#else
-
- CHECK_QUARTER_MV(2, 2, mx-1, my-1)
- CHECK_QUARTER_MV(0, 2, mx , my-1)
- CHECK_QUARTER_MV(2, 2, mx , my-1)
- CHECK_QUARTER_MV(2, 0, mx , my )
- CHECK_QUARTER_MV(2, 2, mx , my )
- CHECK_QUARTER_MV(0, 2, mx , my )
- CHECK_QUARTER_MV(2, 2, mx-1, my )
- CHECK_QUARTER_MV(2, 0, mx-1, my )
-
- nx= bx;
- ny= by;
-
- for(i=0; i<8; i++){
- int ox[8]= {0, 1, 1, 1, 0,-1,-1,-1};
- int oy[8]= {1, 1, 0,-1,-1,-1, 0, 1};
- CHECK_QUARTER_MV((nx + ox[i])&3, (ny + oy[i])&3, (nx + ox[i])>>2, (ny + oy[i])>>2)
- }
-#endif
-#if 0
- //outer ring
- CHECK_QUARTER_MV(1, 3, mx-1, my-1)
- CHECK_QUARTER_MV(1, 2, mx-1, my-1)
- CHECK_QUARTER_MV(1, 1, mx-1, my-1)
- CHECK_QUARTER_MV(2, 1, mx-1, my-1)
- CHECK_QUARTER_MV(3, 1, mx-1, my-1)
- CHECK_QUARTER_MV(0, 1, mx , my-1)
- CHECK_QUARTER_MV(1, 1, mx , my-1)
- CHECK_QUARTER_MV(2, 1, mx , my-1)
- CHECK_QUARTER_MV(3, 1, mx , my-1)
- CHECK_QUARTER_MV(3, 2, mx , my-1)
- CHECK_QUARTER_MV(3, 3, mx , my-1)
- CHECK_QUARTER_MV(3, 0, mx , my )
- CHECK_QUARTER_MV(3, 1, mx , my )
- CHECK_QUARTER_MV(3, 2, mx , my )
- CHECK_QUARTER_MV(3, 3, mx , my )
- CHECK_QUARTER_MV(2, 3, mx , my )
- CHECK_QUARTER_MV(1, 3, mx , my )
- CHECK_QUARTER_MV(0, 3, mx , my )
- CHECK_QUARTER_MV(3, 3, mx-1, my )
- CHECK_QUARTER_MV(2, 3, mx-1, my )
- CHECK_QUARTER_MV(1, 3, mx-1, my )
- CHECK_QUARTER_MV(1, 2, mx-1, my )
- CHECK_QUARTER_MV(1, 1, mx-1, my )
- CHECK_QUARTER_MV(1, 0, mx-1, my )
-#endif
assert(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4);
*mx_ptr = bx;
@@ -495,7 +354,7 @@ static int qpel_motion_search(MpegEncContext * s,
#define CHECK_MV(x,y)\
{\
- const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
+ const unsigned key = ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
assert((x) >= xmin);\
assert((x) <= xmax);\
@@ -523,7 +382,7 @@ static int qpel_motion_search(MpegEncContext * s,
#define CHECK_MV_DIR(x,y,new_dir)\
{\
- const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
+ const unsigned key = ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
/*printf("check_mv_dir %d %d %d\n", x, y, new_dir);*/\
if(map[index]!=key){\
@@ -561,13 +420,13 @@ static av_always_inline int small_diamond_search(MpegEncContext * s, int *best,
int next_dir=-1;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
{ /* ensure that the best point is in the MAP as h/qpel refinement needs it */
- const int key= (best[1]<<ME_MAP_MV_BITS) + best[0] + map_generation;
+ const unsigned key = (best[1]<<ME_MAP_MV_BITS) + best[0] + map_generation;
const int index= ((best[1]<<ME_MAP_SHIFT) + best[0])&(ME_MAP_SIZE-1);
if(map[index]!=key){ //this will be executed only very rarey
score_map[index]= cmp(s, best[0], best[1], 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
@@ -603,7 +462,7 @@ static int funny_diamond_search(MpegEncContext * s, int *best, int dmin,
int dia_size;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
@@ -644,7 +503,7 @@ static int hex_search(MpegEncContext * s, int *best, int dmin,
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
int x,y,d;
const int dec= dia_size & (dia_size-1);
@@ -678,7 +537,7 @@ static int l2s_dia_search(MpegEncContext * s, int *best, int dmin,
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
int x,y,i,d;
int dia_size= c->dia_size&0xFF;
const int dec= dia_size & (dia_size-1);
@@ -716,7 +575,7 @@ static int umh_search(MpegEncContext * s, int *best, int dmin,
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
int x,y,x2,y2, i, j, d;
const int dia_size= c->dia_size&0xFE;
static const int hex[16][2]={{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2},
@@ -763,7 +622,7 @@ static int full_search(MpegEncContext * s, int *best, int dmin,
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
int x,y, d;
const int dia_size= c->dia_size&0xFF;
@@ -792,7 +651,7 @@ static int full_search(MpegEncContext * s, int *best, int dmin,
#define SAB_CHECK_MV(ax,ay)\
{\
- const int key= ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\
+ const unsigned key = ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\
const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\
/*printf("sab check %d %d\n", ax, ay);*/\
if(map[index]!=key){\
@@ -831,7 +690,7 @@ static int sab_diamond_search(MpegEncContext * s, int *best, int dmin,
int i, j;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
@@ -916,7 +775,7 @@ static int var_diamond_search(MpegEncContext * s, int *best, int dmin,
int dia_size;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
cmpf= s->dsp.me_cmp[size];
chroma_cmpf= s->dsp.me_cmp[size+1];
@@ -1001,14 +860,14 @@ static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int
int ref_mv_scale, int flags, int size, int h)
{
MotionEstContext * const c= &s->me;
- int best[2]={0, 0}; /*!< x and y coordinates of the best motion vector.
+ int best[2]={0, 0}; /**< x and y coordinates of the best motion vector.
i.e. the difference between the position of the
block currently being encoded and the position of
the block chosen to predict it from. */
int d; ///< the score (cmp + penalty) of any given mv
- int dmin; /*!< the best value of d, i.e. the score
+ int dmin; /**< the best value of d, i.e. the score
corresponding to the mv stored in best[]. */
- int map_generation;
+ unsigned map_generation;
int penalty_factor;
const int ref_mv_stride= s->mb_stride; //pass as arg FIXME
const int ref_mv_xy= s->mb_x + s->mb_y*ref_mv_stride; //add to last_mv beforepassing FIXME
@@ -1136,7 +995,7 @@ static int epzs_motion_search4(MpegEncContext * s,
MotionEstContext * const c= &s->me;
int best[2]={0, 0};
int d, dmin;
- int map_generation;
+ unsigned map_generation;
const int penalty_factor= c->penalty_factor;
const int size=1;
const int h=8;
@@ -1196,7 +1055,7 @@ static int epzs_motion_search2(MpegEncContext * s,
MotionEstContext * const c= &s->me;
int best[2]={0, 0};
int d, dmin;
- int map_generation;
+ unsigned map_generation;
const int penalty_factor= c->penalty_factor;
const int size=0; //FIXME pass as arg
const int h=8;
diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c
index ebc4b31..d054e00 100644
--- a/libavcodec/motionpixels.c
+++ b/libavcodec/motionpixels.c
@@ -52,14 +52,16 @@ typedef struct MotionPixelsContext {
static av_cold int mp_decode_init(AVCodecContext *avctx)
{
MotionPixelsContext *mp = avctx->priv_data;
+ int w4 = (avctx->width + 3) & ~3;
+ int h4 = (avctx->height + 3) & ~3;
motionpixels_tableinit();
mp->avctx = avctx;
dsputil_init(&mp->dsp, avctx);
- mp->changes_map = av_mallocz(avctx->width * avctx->height);
+ mp->changes_map = av_mallocz(avctx->width * h4);
mp->offset_bits_len = av_log2(avctx->width * avctx->height) + 1;
mp->vpt = av_mallocz(avctx->height * sizeof(YuvPixel));
- mp->hpt = av_mallocz(avctx->height * avctx->width / 16 * sizeof(YuvPixel));
+ mp->hpt = av_mallocz(h4 * w4 / 16 * sizeof(YuvPixel));
avctx->pix_fmt = PIX_FMT_RGB555;
return 0;
}
@@ -252,6 +254,7 @@ static int mp_decode_frame(AVCodecContext *avctx,
mp->dsp.bswap_buf((uint32_t *)mp->bswapbuf, (const uint32_t *)buf, buf_size / 4);
if (buf_size & 3)
memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3);
+ memset(mp->bswapbuf + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
init_get_bits(&gb, mp->bswapbuf, buf_size * 8);
memset(mp->changes_map, 0, avctx->width * avctx->height);
@@ -278,7 +281,10 @@ static int mp_decode_frame(AVCodecContext *avctx,
if (sz == 0)
goto end;
- init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0);
+ if (mp->max_codes_bits <= 0)
+ goto end;
+ if (init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0))
+ goto end;
mp_decode_frame_helper(mp, &gb);
free_vlc(&mp->vlc);
@@ -303,14 +309,13 @@ static av_cold int mp_decode_end(AVCodecContext *avctx)
}
AVCodec ff_motionpixels_decoder = {
- "motionpixels",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MOTIONPIXELS,
- sizeof(MotionPixelsContext),
- mp_decode_init,
- NULL,
- mp_decode_end,
- mp_decode_frame,
- CODEC_CAP_DR1,
+ .name = "motionpixels",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MOTIONPIXELS,
+ .priv_data_size = sizeof(MotionPixelsContext),
+ .init = mp_decode_init,
+ .close = mp_decode_end,
+ .decode = mp_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Motion Pixels video"),
};
diff --git a/libavcodec/mp3_header_decompress_bsf.c b/libavcodec/mp3_header_decompress_bsf.c
index 3f30742..78025cc 100644
--- a/libavcodec/mp3_header_decompress_bsf.c
+++ b/libavcodec/mp3_header_decompress_bsf.c
@@ -50,10 +50,10 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext
lsf = sample_rate < (24000+32000)/2;
mpeg25 = sample_rate < (12000+16000)/2;
sample_rate_index= (header>>10)&3;
- sample_rate= ff_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off
+ sample_rate= avpriv_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off
for(bitrate_index=2; bitrate_index<30; bitrate_index++){
- frame_size = ff_mpa_bitrate_tab[lsf][2][bitrate_index>>1];
+ frame_size = avpriv_mpa_bitrate_tab[lsf][2][bitrate_index>>1];
frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1);
if(frame_size == buf_size + 4)
break;
diff --git a/libavcodec/mpc.h b/libavcodec/mpc.h
index 6d0f7b4..1a6e794 100644
--- a/libavcodec/mpc.h
+++ b/libavcodec/mpc.h
@@ -50,6 +50,7 @@ typedef struct {
}Band;
typedef struct {
+ AVFrame frame;
DSPContext dsp;
MPADSPContext mpadsp;
GetBitContext gb;
diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c
index dbfa3c8..290ecfb 100644
--- a/libavcodec/mpc7.c
+++ b/libavcodec/mpc7.c
@@ -61,6 +61,13 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx)
static VLC_TYPE hdr_table[1 << MPC7_HDR_BITS][2];
static VLC_TYPE quant_tables[7224][2];
+ /* Musepack SV7 is always stereo */
+ if (avctx->channels != 2) {
+ av_log_ask_for_sample(avctx, "Unsupported number of channels: %d\n",
+ avctx->channels);
+ return AVERROR_PATCHWELCOME;
+ }
+
if(avctx->extradata_size < 16){
av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size);
return -1;
@@ -88,7 +95,7 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx)
c->frames_to_skip = 0;
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
+ avctx->channel_layout = AV_CH_LAYOUT_STEREO;
if(vlc_initialized) return 0;
av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n");
@@ -129,6 +136,10 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx)
}
}
vlc_initialized = 1;
+
+ avcodec_get_frame_defaults(&c->frame);
+ avctx->coded_frame = &c->frame;
+
return 0;
}
@@ -185,9 +196,8 @@ static int get_scale_idx(GetBitContext *gb, int ref)
return ref + t;
}
-static int mpc7_decode_frame(AVCodecContext * avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
@@ -197,12 +207,20 @@ static int mpc7_decode_frame(AVCodecContext * avctx,
int i, ch;
int mb = -1;
Band *bands = c->bands;
- int off;
+ int off, ret;
int bits_used, bits_avail;
- memset(bands, 0, sizeof(bands));
+ memset(bands, 0, sizeof(*bands) * (c->maxbands + 1));
if(buf_size <= 4){
av_log(avctx, AV_LOG_ERROR, "Too small buffer passed (%i bytes)\n", buf_size);
+ return AVERROR(EINVAL);
+ }
+
+ /* get output buffer */
+ c->frame.nb_samples = buf[1] ? c->lastframelen : MPC_FRAME_SIZE;
+ if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
bits = av_malloc(((buf_size - 1) & ~3) + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -262,7 +280,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx,
for(ch = 0; ch < 2; ch++)
idx_to_quant(c, &gb, bands[i].res[ch], c->Q[ch] + off);
- ff_mpc_dequantize_and_synth(c, mb, data, 2);
+ ff_mpc_dequantize_and_synth(c, mb, c->frame.data[0], 2);
av_free(bits);
@@ -274,10 +292,12 @@ static int mpc7_decode_frame(AVCodecContext * avctx,
}
if(c->frames_to_skip){
c->frames_to_skip--;
- *data_size = 0;
+ *got_frame_ptr = 0;
return buf_size;
}
- *data_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4;
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = c->frame;
return buf_size;
}
@@ -291,14 +311,13 @@ static void mpc7_decode_flush(AVCodecContext *avctx)
}
AVCodec ff_mpc7_decoder = {
- "mpc7",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MUSEPACK7,
- sizeof(MPCContext),
- mpc7_decode_init,
- NULL,
- NULL,
- mpc7_decode_frame,
+ .name = "mpc7",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MUSEPACK7,
+ .priv_data_size = sizeof(MPCContext),
+ .init = mpc7_decode_init,
+ .decode = mpc7_decode_frame,
.flush = mpc7_decode_flush,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Musepack SV7"),
};
diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c
index 3177faf..b97f3ed 100644
--- a/libavcodec/mpc8.c
+++ b/libavcodec/mpc8.c
@@ -228,12 +228,15 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx)
&mpc8_q8_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
}
vlc_initialized = 1;
+
+ avcodec_get_frame_defaults(&c->frame);
+ avctx->coded_frame = &c->frame;
+
return 0;
}
-static int mpc8_decode_frame(AVCodecContext * avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int mpc8_decode_frame(AVCodecContext * avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
@@ -245,6 +248,13 @@ static int mpc8_decode_frame(AVCodecContext * avctx,
int maxband, keyframe;
int last[2];
+ /* get output buffer */
+ c->frame.nb_samples = MPC_FRAME_SIZE;
+ if ((res = avctx->get_buffer(avctx, &c->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return res;
+ }
+
keyframe = c->cur_frame == 0;
if(keyframe){
@@ -260,6 +270,8 @@ static int mpc8_decode_frame(AVCodecContext * avctx,
maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2);
if(maxband > 32) maxband -= 33;
}
+ if(maxband > c->maxbands)
+ return AVERROR_INVALIDDATA;
c->last_max_band = maxband;
/* read subband indexes */
@@ -393,26 +405,27 @@ static int mpc8_decode_frame(AVCodecContext * avctx,
}
}
- ff_mpc_dequantize_and_synth(c, maxband, data, avctx->channels);
+ ff_mpc_dequantize_and_synth(c, maxband, c->frame.data[0], avctx->channels);
c->cur_frame++;
c->last_bits_used = get_bits_count(gb);
if(c->cur_frame >= c->frames)
c->cur_frame = 0;
- *data_size = MPC_FRAME_SIZE * 2 * avctx->channels;
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = c->frame;
return c->cur_frame ? c->last_bits_used >> 3 : buf_size;
}
AVCodec ff_mpc8_decoder = {
- "mpc8",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MUSEPACK8,
- sizeof(MPCContext),
- mpc8_decode_init,
- NULL,
- NULL,
- mpc8_decode_frame,
+ .name = "mpc8",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MUSEPACK8,
+ .priv_data_size = sizeof(MPCContext),
+ .init = mpc8_decode_init,
+ .decode = mpc8_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Musepack SV8"),
};
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 03c95c1..48860cf 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -1,6 +1,6 @@
/*
* MPEG-1/2 decoder
- * Copyright (c) 2000,2001 Fabrice Bellard
+ * Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
*
* This file is part of Libav.
@@ -49,343 +49,867 @@
#define MB_PTYPE_VLC_BITS 6
#define MB_BTYPE_VLC_BITS 6
-static inline int mpeg1_decode_block_intra(MpegEncContext *s,
- DCTELEM *block,
- int n);
-static inline int mpeg1_decode_block_inter(MpegEncContext *s,
- DCTELEM *block,
- int n);
-static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n);
-static inline int mpeg2_decode_block_non_intra(MpegEncContext *s,
- DCTELEM *block,
- int n);
-static inline int mpeg2_decode_block_intra(MpegEncContext *s,
- DCTELEM *block,
- int n);
-static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n);
-static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n);
-static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);
-static void exchange_uv(MpegEncContext *s);
+static VLC mv_vlc;
-static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = {
- PIX_FMT_XVMC_MPEG2_IDCT,
- PIX_FMT_XVMC_MPEG2_MC,
- PIX_FMT_NONE};
+/* as H.263, but only 17 codes */
+static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
+{
+ int code, sign, val, shift;
-uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
+ code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2);
+ if (code == 0) {
+ return pred;
+ }
+ if (code < 0) {
+ return 0xffff;
+ }
+ sign = get_bits1(&s->gb);
+ shift = fcode - 1;
+ val = code;
+ if (shift) {
+ val = (val - 1) << shift;
+ val |= get_bits(&s->gb, shift);
+ val++;
+ }
+ if (sign)
+ val = -val;
+ val += pred;
-#define INIT_2D_VLC_RL(rl, static_size)\
-{\
- static RL_VLC_ELEM rl_vlc_table[static_size];\
- INIT_VLC_STATIC(&rl.vlc, TEX_VLC_BITS, rl.n + 2,\
- &rl.table_vlc[0][1], 4, 2,\
- &rl.table_vlc[0][0], 4, 2, static_size);\
-\
- rl.rl_vlc[0]= rl_vlc_table;\
- init_2d_vlc_rl(&rl);\
+ /* modulo decoding */
+ return sign_extend(val, 5 + shift);
}
-static void init_2d_vlc_rl(RLTable *rl)
+static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
{
- int i;
+ int level, dc, diff, i, j, run;
+ int component;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t * const scantable = s->intra_scantable.permutated;
+ const uint16_t *quant_matrix = s->intra_matrix;
+ const int qscale = s->qscale;
- for(i=0; i<rl->vlc.table_size; i++){
- int code= rl->vlc.table[i][0];
- int len = rl->vlc.table[i][1];
- int level, run;
+ /* DC coefficient */
+ component = (n <= 3 ? 0 : n - 4 + 1);
+ diff = decode_dc(&s->gb, component);
+ if (diff >= 0xffff)
+ return -1;
+ dc = s->last_dc[component];
+ dc += diff;
+ s->last_dc[component] = dc;
+ block[0] = dc * quant_matrix[0];
+ av_dlog(s->avctx, "dc=%d diff=%d\n", dc, diff);
+ i = 0;
+ {
+ OPEN_READER(re, &s->gb);
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
- if(len==0){ // illegal code
- run= 65;
- level= MAX_LEVEL;
- }else if(len<0){ //more bits needed
- run= 0;
- level= code;
- }else{
- if(code==rl->n){ //esc
- run= 65;
- level= 0;
- }else if(code==rl->n+1){ //eob
- run= 0;
- level= 127;
- }else{
- run= rl->table_run [code] + 1;
- level= rl->table_level[code];
+ if (level == 127) {
+ break;
+ } else if (level != 0) {
+ i += run;
+ j = scantable[i];
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ level = (level - 1) | 1;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
+ if (level == -128) {
+ level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8);
+ } else if (level == 0) {
+ level = SHOW_UBITS(re, &s->gb, 8) ; LAST_SKIP_BITS(re, &s->gb, 8);
+ }
+ i += run;
+ j = scantable[i];
+ if (level < 0) {
+ level = -level;
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ level = (level - 1) | 1;
+ }
+ }
+ if (i > 63) {
+ av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
}
+
+ block[j] = level;
}
- rl->rl_vlc[0][i].len= len;
- rl->rl_vlc[0][i].level= level;
- rl->rl_vlc[0][i].run= run;
+ CLOSE_READER(re, &s->gb);
}
+ s->block_last_index[n] = i;
+ return 0;
}
-void ff_mpeg12_common_init(MpegEncContext *s)
+int ff_mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
{
-
- s->y_dc_scale_table=
- s->c_dc_scale_table= ff_mpeg2_dc_scale_table[s->intra_dc_precision];
-
-}
-
-void ff_mpeg1_clean_buffers(MpegEncContext *s){
- s->last_dc[0] = 1 << (7 + s->intra_dc_precision);
- s->last_dc[1] = s->last_dc[0];
- s->last_dc[2] = s->last_dc[0];
- memset(s->last_mv, 0, sizeof(s->last_mv));
+ return mpeg1_decode_block_intra(s, block, n);
}
-
-/******************************************/
-/* decoding */
-
-VLC ff_dc_lum_vlc;
-VLC ff_dc_chroma_vlc;
-
-static VLC mv_vlc;
-static VLC mbincr_vlc;
-static VLC mb_ptype_vlc;
-static VLC mb_btype_vlc;
-static VLC mb_pat_vlc;
-
-av_cold void ff_mpeg12_init_vlcs(void)
+static inline int mpeg1_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n)
{
- static int done = 0;
-
- if (!done) {
- done = 1;
+ int level, i, j, run;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t * const scantable = s->intra_scantable.permutated;
+ const uint16_t *quant_matrix = s->inter_matrix;
+ const int qscale = s->qscale;
- INIT_VLC_STATIC(&ff_dc_lum_vlc, DC_VLC_BITS, 12,
- ff_mpeg12_vlc_dc_lum_bits, 1, 1,
- ff_mpeg12_vlc_dc_lum_code, 2, 2, 512);
- INIT_VLC_STATIC(&ff_dc_chroma_vlc, DC_VLC_BITS, 12,
- ff_mpeg12_vlc_dc_chroma_bits, 1, 1,
- ff_mpeg12_vlc_dc_chroma_code, 2, 2, 514);
- INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 17,
- &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1,
- &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 518);
- INIT_VLC_STATIC(&mbincr_vlc, MBINCR_VLC_BITS, 36,
- &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1,
- &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 538);
- INIT_VLC_STATIC(&mb_pat_vlc, MB_PAT_VLC_BITS, 64,
- &ff_mpeg12_mbPatTable[0][1], 2, 1,
- &ff_mpeg12_mbPatTable[0][0], 2, 1, 512);
+ {
+ OPEN_READER(re, &s->gb);
+ i = -1;
+ // special case for first coefficient, no need to add second VLC table
+ UPDATE_CACHE(re, &s->gb);
+ if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
+ level = (3 * qscale * quant_matrix[0]) >> 5;
+ level = (level - 1) | 1;
+ if (GET_CACHE(re, &s->gb) & 0x40000000)
+ level = -level;
+ block[0] = level;
+ i++;
+ SKIP_BITS(re, &s->gb, 2);
+ if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+ goto end;
+ }
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
- INIT_VLC_STATIC(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7,
- &table_mb_ptype[0][1], 2, 1,
- &table_mb_ptype[0][0], 2, 1, 64);
- INIT_VLC_STATIC(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11,
- &table_mb_btype[0][1], 2, 1,
- &table_mb_btype[0][0], 2, 1, 64);
- init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]);
- init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]);
+ if (level != 0) {
+ i += run;
+ j = scantable[i];
+ level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ level = (level - 1) | 1;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
+ if (level == -128) {
+ level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
+ } else if (level == 0) {
+ level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8);
+ }
+ i += run;
+ j = scantable[i];
+ if (level < 0) {
+ level = -level;
+ level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ level = (level - 1) | 1;
+ }
+ }
+ if (i > 63) {
+ av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
- INIT_2D_VLC_RL(ff_rl_mpeg1, 680);
- INIT_2D_VLC_RL(ff_rl_mpeg2, 674);
+ block[j] = level;
+ if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+ break;
+ UPDATE_CACHE(re, &s->gb);
+ }
+end:
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ CLOSE_READER(re, &s->gb);
}
+ s->block_last_index[n] = i;
+ return 0;
}
-static inline int get_dmv(MpegEncContext *s)
+static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n)
{
- if(get_bits1(&s->gb))
- return 1 - (get_bits1(&s->gb) << 1);
- else
- return 0;
-}
+ int level, i, j, run;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t * const scantable = s->intra_scantable.permutated;
+ const int qscale = s->qscale;
-static inline int get_qscale(MpegEncContext *s)
-{
- int qscale = get_bits(&s->gb, 5);
- if (s->q_scale_type) {
- return non_linear_qscale[qscale];
- } else {
- return qscale << 1;
- }
-}
+ {
+ OPEN_READER(re, &s->gb);
+ i = -1;
+ // special case for first coefficient, no need to add second VLC table
+ UPDATE_CACHE(re, &s->gb);
+ if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
+ level = (3 * qscale) >> 1;
+ level = (level - 1) | 1;
+ if (GET_CACHE(re, &s->gb) & 0x40000000)
+ level = -level;
+ block[0] = level;
+ i++;
+ SKIP_BITS(re, &s->gb, 2);
+ if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+ goto end;
+ }
-/* motion type (for MPEG-2) */
-#define MT_FIELD 1
-#define MT_FRAME 2
-#define MT_16X8 2
-#define MT_DMV 3
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-static int mpeg_decode_mb(MpegEncContext *s,
- DCTELEM block[12][64])
-{
- int i, j, k, cbp, val, mb_type, motion_type;
- const int mb_block_count = 4 + (1<< s->chroma_format);
+ if (level != 0) {
+ i += run;
+ j = scantable[i];
+ level = ((level * 2 + 1) * qscale) >> 1;
+ level = (level - 1) | 1;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
+ if (level == -128) {
+ level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
+ } else if (level == 0) {
+ level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8);
+ }
+ i += run;
+ j = scantable[i];
+ if (level < 0) {
+ level = -level;
+ level = ((level * 2 + 1) * qscale) >> 1;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = ((level * 2 + 1) * qscale) >> 1;
+ level = (level - 1) | 1;
+ }
+ }
- av_dlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
+ block[j] = level;
+ if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+ break;
+ UPDATE_CACHE(re, &s->gb);
+ }
+end:
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ CLOSE_READER(re, &s->gb);
+ }
+ s->block_last_index[n] = i;
+ return 0;
+}
- assert(s->mb_skipped==0);
- if (s->mb_skip_run-- != 0) {
- if (s->pict_type == AV_PICTURE_TYPE_P) {
- s->mb_skipped = 1;
- s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
- } else {
- int mb_type;
+static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n)
+{
+ int level, i, j, run;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t * const scantable = s->intra_scantable.permutated;
+ const uint16_t *quant_matrix;
+ const int qscale = s->qscale;
+ int mismatch;
- if(s->mb_x)
- mb_type= s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1];
- else
- mb_type= s->current_picture.mb_type[ s->mb_width + (s->mb_y-1)*s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all
- if(IS_INTRA(mb_type))
- return -1;
+ mismatch = 1;
- s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]=
- mb_type | MB_TYPE_SKIP;
-// assert(s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]&(MB_TYPE_16x16|MB_TYPE_16x8));
+ {
+ OPEN_READER(re, &s->gb);
+ i = -1;
+ if (n < 4)
+ quant_matrix = s->inter_matrix;
+ else
+ quant_matrix = s->chroma_inter_matrix;
- if((s->mv[0][0][0]|s->mv[0][0][1]|s->mv[1][0][0]|s->mv[1][0][1])==0)
- s->mb_skipped = 1;
+ // special case for first coefficient, no need to add second VLC table
+ UPDATE_CACHE(re, &s->gb);
+ if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
+ level= (3 * qscale * quant_matrix[0]) >> 5;
+ if (GET_CACHE(re, &s->gb) & 0x40000000)
+ level = -level;
+ block[0] = level;
+ mismatch ^= level;
+ i++;
+ SKIP_BITS(re, &s->gb, 2);
+ if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+ goto end;
}
- return 0;
- }
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
- switch(s->pict_type) {
- default:
- case AV_PICTURE_TYPE_I:
- if (get_bits1(&s->gb) == 0) {
- if (get_bits1(&s->gb) == 0){
- av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y);
+ if (level != 0) {
+ i += run;
+ j = scantable[i];
+ level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
+
+ i += run;
+ j = scantable[i];
+ if (level < 0) {
+ level = ((-level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ level = -level;
+ } else {
+ level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ }
+ }
+ if (i > 63) {
+ av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
- mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;
- } else {
- mb_type = MB_TYPE_INTRA;
- }
- break;
- case AV_PICTURE_TYPE_P:
- mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);
- if (mb_type < 0){
- av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- mb_type = ptype2mb_type[ mb_type ];
- break;
- case AV_PICTURE_TYPE_B:
- mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);
- if (mb_type < 0){
- av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);
- return -1;
+
+ mismatch ^= level;
+ block[j] = level;
+ if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+ break;
+ UPDATE_CACHE(re, &s->gb);
}
- mb_type = btype2mb_type[ mb_type ];
- break;
+end:
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ CLOSE_READER(re, &s->gb);
}
- av_dlog(s->avctx, "mb_type=%x\n", mb_type);
-// motion_type = 0; /* avoid warning */
- if (IS_INTRA(mb_type)) {
- s->dsp.clear_blocks(s->block[0]);
+ block[63] ^= (mismatch & 1);
- if(!s->chroma_y_shift){
- s->dsp.clear_blocks(s->block[6]);
- }
+ s->block_last_index[n] = i;
+ return 0;
+}
- /* compute DCT type */
- if (s->picture_structure == PICT_FRAME && //FIXME add an interlaced_dct coded var?
- !s->frame_pred_frame_dct) {
- s->interlaced_dct = get_bits1(&s->gb);
- }
+static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s,
+ DCTELEM *block, int n)
+{
+ int level, i, j, run;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t * const scantable = s->intra_scantable.permutated;
+ const int qscale = s->qscale;
+ OPEN_READER(re, &s->gb);
+ i = -1;
- if (IS_QUANT(mb_type))
- s->qscale = get_qscale(s);
+ // special case for first coefficient, no need to add second VLC table
+ UPDATE_CACHE(re, &s->gb);
+ if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
+ level = (3 * qscale) >> 1;
+ if (GET_CACHE(re, &s->gb) & 0x40000000)
+ level = -level;
+ block[0] = level;
+ i++;
+ SKIP_BITS(re, &s->gb, 2);
+ if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+ goto end;
+ }
- if (s->concealment_motion_vectors) {
- /* just parse them */
- if (s->picture_structure != PICT_FRAME)
- skip_bits1(&s->gb); /* field select */
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
- s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] =
- mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]);
- s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] =
- mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]);
+ if (level != 0) {
+ i += run;
+ j = scantable[i];
+ level = ((level * 2 + 1) * qscale) >> 1;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
- skip_bits1(&s->gb); /* marker */
- }else
- memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
- s->mb_intra = 1;
- //if 1, we memcpy blocks in xvmcvideo
- if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1){
- ff_xvmc_pack_pblocks(s,-1);//inter are always full blocks
- if(s->swap_uv){
- exchange_uv(s);
+ i += run;
+ j = scantable[i];
+ if (level < 0) {
+ level = ((-level * 2 + 1) * qscale) >> 1;
+ level = -level;
+ } else {
+ level = ((level * 2 + 1) * qscale) >> 1;
}
}
- if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
- if(s->flags2 & CODEC_FLAG2_FAST){
- for(i=0;i<6;i++) {
- mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
- }
- }else{
- for(i=0;i<mb_block_count;i++) {
- if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0)
- return -1;
+ block[j] = level;
+ if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+ break;
+ UPDATE_CACHE(re, &s->gb);
+ }
+end:
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ CLOSE_READER(re, &s->gb);
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+
+static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
+{
+ int level, dc, diff, i, j, run;
+ int component;
+ RLTable *rl;
+ uint8_t * const scantable = s->intra_scantable.permutated;
+ const uint16_t *quant_matrix;
+ const int qscale = s->qscale;
+ int mismatch;
+
+ /* DC coefficient */
+ if (n < 4) {
+ quant_matrix = s->intra_matrix;
+ component = 0;
+ } else {
+ quant_matrix = s->chroma_intra_matrix;
+ component = (n & 1) + 1;
+ }
+ diff = decode_dc(&s->gb, component);
+ if (diff >= 0xffff)
+ return -1;
+ dc = s->last_dc[component];
+ dc += diff;
+ s->last_dc[component] = dc;
+ block[0] = dc << (3 - s->intra_dc_precision);
+ av_dlog(s->avctx, "dc=%d\n", block[0]);
+ mismatch = block[0] ^ 1;
+ i = 0;
+ if (s->intra_vlc_format)
+ rl = &ff_rl_mpeg2;
+ else
+ rl = &ff_rl_mpeg1;
+
+ {
+ OPEN_READER(re, &s->gb);
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+ if (level == 127) {
+ break;
+ } else if (level != 0) {
+ i += run;
+ j = scantable[i];
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
+ i += run;
+ j = scantable[i];
+ if (level < 0) {
+ level = (-level * qscale * quant_matrix[j]) >> 4;
+ level = -level;
+ } else {
+ level = (level * qscale * quant_matrix[j]) >> 4;
}
}
- } else {
- for(i=0;i<6;i++) {
- if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
- return -1;
+ if (i > 63) {
+ av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
}
+
+ mismatch ^= level;
+ block[j] = level;
}
+ CLOSE_READER(re, &s->gb);
+ }
+ block[63] ^= mismatch & 1;
+
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
+{
+ int level, dc, diff, j, run;
+ int component;
+ RLTable *rl;
+ uint8_t * scantable = s->intra_scantable.permutated;
+ const uint16_t *quant_matrix;
+ const int qscale = s->qscale;
+
+ /* DC coefficient */
+ if (n < 4) {
+ quant_matrix = s->intra_matrix;
+ component = 0;
} else {
- if (mb_type & MB_TYPE_ZERO_MV){
- assert(mb_type & MB_TYPE_CBP);
+ quant_matrix = s->chroma_intra_matrix;
+ component = (n & 1) + 1;
+ }
+ diff = decode_dc(&s->gb, component);
+ if (diff >= 0xffff)
+ return -1;
+ dc = s->last_dc[component];
+ dc += diff;
+ s->last_dc[component] = dc;
+ block[0] = dc << (3 - s->intra_dc_precision);
+ if (s->intra_vlc_format)
+ rl = &ff_rl_mpeg2;
+ else
+ rl = &ff_rl_mpeg1;
- s->mv_dir = MV_DIR_FORWARD;
- if(s->picture_structure == PICT_FRAME){
- if(!s->frame_pred_frame_dct)
- s->interlaced_dct = get_bits1(&s->gb);
- s->mv_type = MV_TYPE_16X16;
- }else{
- s->mv_type = MV_TYPE_FIELD;
- mb_type |= MB_TYPE_INTERLACED;
- s->field_select[0][0]= s->picture_structure - 1;
+ {
+ OPEN_READER(re, &s->gb);
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+ if (level == 127) {
+ break;
+ } else if (level != 0) {
+ scantable += run;
+ j = *scantable;
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
+ scantable += run;
+ j = *scantable;
+ if (level < 0) {
+ level = (-level * qscale * quant_matrix[j]) >> 4;
+ level = -level;
+ } else {
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ }
}
- if (IS_QUANT(mb_type))
- s->qscale = get_qscale(s);
+ block[j] = level;
+ }
+ CLOSE_READER(re, &s->gb);
+ }
- s->last_mv[0][0][0] = 0;
- s->last_mv[0][0][1] = 0;
- s->last_mv[0][1][0] = 0;
- s->last_mv[0][1][1] = 0;
- s->mv[0][0][0] = 0;
- s->mv[0][0][1] = 0;
- }else{
- assert(mb_type & MB_TYPE_L0L1);
-//FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED
- /* get additional motion vector type */
- if (s->frame_pred_frame_dct)
- motion_type = MT_FRAME;
- else{
- motion_type = get_bits(&s->gb, 2);
- if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))
- s->interlaced_dct = get_bits1(&s->gb);
- }
+ s->block_last_index[n] = scantable - s->intra_scantable.permutated;
+ return 0;
+}
- if (IS_QUANT(mb_type))
- s->qscale = get_qscale(s);
+uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
- /* motion vectors */
- s->mv_dir= (mb_type>>13)&3;
- av_dlog(s->avctx, "motion_type=%d\n", motion_type);
- switch(motion_type) {
- case MT_FRAME: /* or MT_16X8 */
- if (s->picture_structure == PICT_FRAME) {
- mb_type |= MB_TYPE_16x16;
- s->mv_type = MV_TYPE_16X16;
- for(i=0;i<2;i++) {
- if (USES_LIST(mb_type, i)) {
- /* MT_FRAME */
- s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] =
- mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]);
- s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] =
+#define INIT_2D_VLC_RL(rl, static_size)\
+{\
+ static RL_VLC_ELEM rl_vlc_table[static_size];\
+ INIT_VLC_STATIC(&rl.vlc, TEX_VLC_BITS, rl.n + 2,\
+ &rl.table_vlc[0][1], 4, 2,\
+ &rl.table_vlc[0][0], 4, 2, static_size);\
+\
+ rl.rl_vlc[0] = rl_vlc_table;\
+ init_2d_vlc_rl(&rl);\
+}
+
+static void init_2d_vlc_rl(RLTable *rl)
+{
+ int i;
+
+ for (i = 0; i < rl->vlc.table_size; i++) {
+ int code = rl->vlc.table[i][0];
+ int len = rl->vlc.table[i][1];
+ int level, run;
+
+ if (len == 0) { // illegal code
+ run = 65;
+ level = MAX_LEVEL;
+ } else if (len<0) { //more bits needed
+ run = 0;
+ level = code;
+ } else {
+ if (code == rl->n) { //esc
+ run = 65;
+ level = 0;
+ } else if (code == rl->n+1) { //eob
+ run = 0;
+ level = 127;
+ } else {
+ run = rl->table_run [code] + 1;
+ level = rl->table_level[code];
+ }
+ }
+ rl->rl_vlc[0][i].len = len;
+ rl->rl_vlc[0][i].level = level;
+ rl->rl_vlc[0][i].run = run;
+ }
+}
+
+void ff_mpeg12_common_init(MpegEncContext *s)
+{
+
+ s->y_dc_scale_table =
+ s->c_dc_scale_table = ff_mpeg2_dc_scale_table[s->intra_dc_precision];
+
+}
+
+void ff_mpeg1_clean_buffers(MpegEncContext *s)
+{
+ s->last_dc[0] = 1 << (7 + s->intra_dc_precision);
+ s->last_dc[1] = s->last_dc[0];
+ s->last_dc[2] = s->last_dc[0];
+ memset(s->last_mv, 0, sizeof(s->last_mv));
+}
+
+
+/******************************************/
+/* decoding */
+
+VLC ff_dc_lum_vlc;
+VLC ff_dc_chroma_vlc;
+
+static VLC mbincr_vlc;
+static VLC mb_ptype_vlc;
+static VLC mb_btype_vlc;
+static VLC mb_pat_vlc;
+
+av_cold void ff_mpeg12_init_vlcs(void)
+{
+ static int done = 0;
+
+ if (!done) {
+ done = 1;
+
+ INIT_VLC_STATIC(&ff_dc_lum_vlc, DC_VLC_BITS, 12,
+ ff_mpeg12_vlc_dc_lum_bits, 1, 1,
+ ff_mpeg12_vlc_dc_lum_code, 2, 2, 512);
+ INIT_VLC_STATIC(&ff_dc_chroma_vlc, DC_VLC_BITS, 12,
+ ff_mpeg12_vlc_dc_chroma_bits, 1, 1,
+ ff_mpeg12_vlc_dc_chroma_code, 2, 2, 514);
+ INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 17,
+ &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1,
+ &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 518);
+ INIT_VLC_STATIC(&mbincr_vlc, MBINCR_VLC_BITS, 36,
+ &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1,
+ &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 538);
+ INIT_VLC_STATIC(&mb_pat_vlc, MB_PAT_VLC_BITS, 64,
+ &ff_mpeg12_mbPatTable[0][1], 2, 1,
+ &ff_mpeg12_mbPatTable[0][0], 2, 1, 512);
+
+ INIT_VLC_STATIC(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7,
+ &table_mb_ptype[0][1], 2, 1,
+ &table_mb_ptype[0][0], 2, 1, 64);
+ INIT_VLC_STATIC(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11,
+ &table_mb_btype[0][1], 2, 1,
+ &table_mb_btype[0][0], 2, 1, 64);
+ init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]);
+ init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]);
+
+ INIT_2D_VLC_RL(ff_rl_mpeg1, 680);
+ INIT_2D_VLC_RL(ff_rl_mpeg2, 674);
+ }
+}
+
+static inline int get_dmv(MpegEncContext *s)
+{
+ if (get_bits1(&s->gb))
+ return 1 - (get_bits1(&s->gb) << 1);
+ else
+ return 0;
+}
+
+static inline int get_qscale(MpegEncContext *s)
+{
+ int qscale = get_bits(&s->gb, 5);
+ if (s->q_scale_type) {
+ return non_linear_qscale[qscale];
+ } else {
+ return qscale << 1;
+ }
+}
+
+static void exchange_uv(MpegEncContext *s)
+{
+ DCTELEM (*tmp)[64];
+
+ tmp = s->pblocks[4];
+ s->pblocks[4] = s->pblocks[5];
+ s->pblocks[5] = tmp;
+}
+
+/* motion type (for MPEG-2) */
+#define MT_FIELD 1
+#define MT_FRAME 2
+#define MT_16X8 2
+#define MT_DMV 3
+
+static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64])
+{
+ int i, j, k, cbp, val, mb_type, motion_type;
+ const int mb_block_count = 4 + (1 << s->chroma_format);
+
+ av_dlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
+
+ assert(s->mb_skipped == 0);
+
+ if (s->mb_skip_run-- != 0) {
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ s->mb_skipped = 1;
+ s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
+ } else {
+ int mb_type;
+
+ if (s->mb_x)
+ mb_type = s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
+ else
+ mb_type = s->current_picture.f.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all
+ if (IS_INTRA(mb_type))
+ return -1;
+ s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
+ mb_type | MB_TYPE_SKIP;
+// assert(s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
+
+ if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)
+ s->mb_skipped = 1;
+ }
+
+ return 0;
+ }
+
+ switch (s->pict_type) {
+ default:
+ case AV_PICTURE_TYPE_I:
+ if (get_bits1(&s->gb) == 0) {
+ if (get_bits1(&s->gb) == 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;
+ } else {
+ mb_type = MB_TYPE_INTRA;
+ }
+ break;
+ case AV_PICTURE_TYPE_P:
+ mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);
+ if (mb_type < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ mb_type = ptype2mb_type[mb_type];
+ break;
+ case AV_PICTURE_TYPE_B:
+ mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);
+ if (mb_type < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ mb_type = btype2mb_type[mb_type];
+ break;
+ }
+ av_dlog(s->avctx, "mb_type=%x\n", mb_type);
+// motion_type = 0; /* avoid warning */
+ if (IS_INTRA(mb_type)) {
+ s->dsp.clear_blocks(s->block[0]);
+
+ if (!s->chroma_y_shift) {
+ s->dsp.clear_blocks(s->block[6]);
+ }
+
+ /* compute DCT type */
+ if (s->picture_structure == PICT_FRAME && // FIXME add an interlaced_dct coded var?
+ !s->frame_pred_frame_dct) {
+ s->interlaced_dct = get_bits1(&s->gb);
+ }
+
+ if (IS_QUANT(mb_type))
+ s->qscale = get_qscale(s);
+
+ if (s->concealment_motion_vectors) {
+ /* just parse them */
+ if (s->picture_structure != PICT_FRAME)
+ skip_bits1(&s->gb); /* field select */
+
+ s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] =
+ mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]);
+ s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] =
+ mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]);
+
+ skip_bits1(&s->gb); /* marker */
+ } else
+ memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
+ s->mb_intra = 1;
+ // if 1, we memcpy blocks in xvmcvideo
+ if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
+ ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks
+ if (s->swap_uv) {
+ exchange_uv(s);
+ }
+ }
+
+ if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
+ if (s->flags2 & CODEC_FLAG2_FAST) {
+ for (i = 0; i < 6; i++) {
+ mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
+ }
+ } else {
+ for (i = 0; i < mb_block_count; i++) {
+ if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0)
+ return -1;
+ }
+ }
+ } else {
+ for (i = 0; i < 6; i++) {
+ if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
+ return -1;
+ }
+ }
+ } else {
+ if (mb_type & MB_TYPE_ZERO_MV) {
+ assert(mb_type & MB_TYPE_CBP);
+
+ s->mv_dir = MV_DIR_FORWARD;
+ if (s->picture_structure == PICT_FRAME) {
+ if (!s->frame_pred_frame_dct)
+ s->interlaced_dct = get_bits1(&s->gb);
+ s->mv_type = MV_TYPE_16X16;
+ } else {
+ s->mv_type = MV_TYPE_FIELD;
+ mb_type |= MB_TYPE_INTERLACED;
+ s->field_select[0][0] = s->picture_structure - 1;
+ }
+
+ if (IS_QUANT(mb_type))
+ s->qscale = get_qscale(s);
+
+ s->last_mv[0][0][0] = 0;
+ s->last_mv[0][0][1] = 0;
+ s->last_mv[0][1][0] = 0;
+ s->last_mv[0][1][1] = 0;
+ s->mv[0][0][0] = 0;
+ s->mv[0][0][1] = 0;
+ } else {
+ assert(mb_type & MB_TYPE_L0L1);
+ // FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED
+ /* get additional motion vector type */
+ if (s->frame_pred_frame_dct)
+ motion_type = MT_FRAME;
+ else {
+ motion_type = get_bits(&s->gb, 2);
+ if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))
+ s->interlaced_dct = get_bits1(&s->gb);
+ }
+
+ if (IS_QUANT(mb_type))
+ s->qscale = get_qscale(s);
+
+ /* motion vectors */
+ s->mv_dir = (mb_type >> 13) & 3;
+ av_dlog(s->avctx, "motion_type=%d\n", motion_type);
+ switch (motion_type) {
+ case MT_FRAME: /* or MT_16X8 */
+ if (s->picture_structure == PICT_FRAME) {
+ mb_type |= MB_TYPE_16x16;
+ s->mv_type = MV_TYPE_16X16;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ /* MT_FRAME */
+ s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] =
+ mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]);
+ s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] =
mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]);
/* full_pel: only for MPEG-1 */
- if (s->full_pel[i]){
+ if (s->full_pel[i]) {
s->mv[i][0][0] <<= 1;
s->mv[i][0][1] <<= 1;
}
@@ -394,16 +918,16 @@ static int mpeg_decode_mb(MpegEncContext *s,
} else {
mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
s->mv_type = MV_TYPE_16X8;
- for(i=0;i<2;i++) {
+ for (i = 0; i < 2; i++) {
if (USES_LIST(mb_type, i)) {
/* MT_16X8 */
- for(j=0;j<2;j++) {
+ for (j = 0; j < 2; j++) {
s->field_select[i][j] = get_bits1(&s->gb);
- for(k=0;k<2;k++) {
+ for (k = 0; k < 2; k++) {
val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
s->last_mv[i][j][k]);
s->last_mv[i][j][k] = val;
- s->mv[i][j][k] = val;
+ s->mv[i][j][k] = val;
}
}
}
@@ -414,34 +938,34 @@ static int mpeg_decode_mb(MpegEncContext *s,
s->mv_type = MV_TYPE_FIELD;
if (s->picture_structure == PICT_FRAME) {
mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
- for(i=0;i<2;i++) {
+ for (i = 0; i < 2; i++) {
if (USES_LIST(mb_type, i)) {
- for(j=0;j<2;j++) {
+ for (j = 0; j < 2; j++) {
s->field_select[i][j] = get_bits1(&s->gb);
val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
s->last_mv[i][j][0]);
s->last_mv[i][j][0] = val;
- s->mv[i][j][0] = val;
+ s->mv[i][j][0] = val;
av_dlog(s->avctx, "fmx=%d\n", val);
val = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
s->last_mv[i][j][1] >> 1);
s->last_mv[i][j][1] = val << 1;
- s->mv[i][j][1] = val;
+ s->mv[i][j][1] = val;
av_dlog(s->avctx, "fmy=%d\n", val);
}
}
}
} else {
mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
- for(i=0;i<2;i++) {
+ for (i = 0; i < 2; i++) {
if (USES_LIST(mb_type, i)) {
s->field_select[i][0] = get_bits1(&s->gb);
- for(k=0;k<2;k++) {
+ for (k = 0; k < 2; k++) {
val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
s->last_mv[i][0][k]);
s->last_mv[i][0][k] = val;
s->last_mv[i][1][k] = val;
- s->mv[i][0][k] = val;
+ s->mv[i][0][k] = val;
}
}
}
@@ -449,706 +973,139 @@ static int mpeg_decode_mb(MpegEncContext *s,
break;
case MT_DMV:
s->mv_type = MV_TYPE_DMV;
- for(i=0;i<2;i++) {
+ for (i = 0; i < 2; i++) {
if (USES_LIST(mb_type, i)) {
int dmx, dmy, mx, my, m;
- const int my_shift= s->picture_structure == PICT_FRAME;
-
- mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
- s->last_mv[i][0][0]);
- s->last_mv[i][0][0] = mx;
- s->last_mv[i][1][0] = mx;
- dmx = get_dmv(s);
- my = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
- s->last_mv[i][0][1] >> my_shift);
- dmy = get_dmv(s);
-
-
- s->last_mv[i][0][1] = my<<my_shift;
- s->last_mv[i][1][1] = my<<my_shift;
-
- s->mv[i][0][0] = mx;
- s->mv[i][0][1] = my;
- s->mv[i][1][0] = mx;//not used
- s->mv[i][1][1] = my;//not used
-
- if (s->picture_structure == PICT_FRAME) {
- mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
-
- //m = 1 + 2 * s->top_field_first;
- m = s->top_field_first ? 1 : 3;
-
- /* top -> top pred */
- s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
- s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;
- m = 4 - m;
- s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
- s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;
- } else {
- mb_type |= MB_TYPE_16x16;
-
- s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx;
- s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy;
- if(s->picture_structure == PICT_TOP_FIELD)
- s->mv[i][2][1]--;
- else
- s->mv[i][2][1]++;
- }
- }
- }
- break;
- default:
- av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- }
-
- s->mb_intra = 0;
- if (HAS_CBP(mb_type)) {
- s->dsp.clear_blocks(s->block[0]);
-
- cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);
- if(mb_block_count > 6){
- cbp<<= mb_block_count-6;
- cbp |= get_bits(&s->gb, mb_block_count-6);
- s->dsp.clear_blocks(s->block[6]);
- }
- if (cbp <= 0){
- av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- //if 1, we memcpy blocks in xvmcvideo
- if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1){
- ff_xvmc_pack_pblocks(s,cbp);
- if(s->swap_uv){
- exchange_uv(s);
- }
- }
-
- if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
- if(s->flags2 & CODEC_FLAG2_FAST){
- for(i=0;i<6;i++) {
- if(cbp & 32) {
- mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);
- } else {
- s->block_last_index[i] = -1;
- }
- cbp+=cbp;
- }
- }else{
- cbp<<= 12-mb_block_count;
-
- for(i=0;i<mb_block_count;i++) {
- if ( cbp & (1<<11) ) {
- if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0)
- return -1;
- } else {
- s->block_last_index[i] = -1;
- }
- cbp+=cbp;
- }
- }
- } else {
- if(s->flags2 & CODEC_FLAG2_FAST){
- for(i=0;i<6;i++) {
- if (cbp & 32) {
- mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);
- } else {
- s->block_last_index[i] = -1;
- }
- cbp+=cbp;
- }
- }else{
- for(i=0;i<6;i++) {
- if (cbp & 32) {
- if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0)
- return -1;
- } else {
- s->block_last_index[i] = -1;
- }
- cbp+=cbp;
- }
- }
- }
- }else{
- for(i=0;i<12;i++)
- s->block_last_index[i] = -1;
- }
- }
-
- s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= mb_type;
-
- return 0;
-}
-
-/* as H.263, but only 17 codes */
-static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
-{
- int code, sign, val, l, shift;
-
- code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2);
- if (code == 0) {
- return pred;
- }
- if (code < 0) {
- return 0xffff;
- }
-
- sign = get_bits1(&s->gb);
- shift = fcode - 1;
- val = code;
- if (shift) {
- val = (val - 1) << shift;
- val |= get_bits(&s->gb, shift);
- val++;
- }
- if (sign)
- val = -val;
- val += pred;
-
- /* modulo decoding */
- l= INT_BIT - 5 - shift;
- val = (val<<l)>>l;
- return val;
-}
-
-static inline int mpeg1_decode_block_intra(MpegEncContext *s,
- DCTELEM *block,
- int n)
-{
- int level, dc, diff, i, j, run;
- int component;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t * const scantable= s->intra_scantable.permutated;
- const uint16_t *quant_matrix= s->intra_matrix;
- const int qscale= s->qscale;
-
- /* DC coefficient */
- component = (n <= 3 ? 0 : n - 4 + 1);
- diff = decode_dc(&s->gb, component);
- if (diff >= 0xffff)
- return -1;
- dc = s->last_dc[component];
- dc += diff;
- s->last_dc[component] = dc;
- block[0] = dc*quant_matrix[0];
- av_dlog(s->avctx, "dc=%d diff=%d\n", dc, diff);
- i = 0;
- {
- OPEN_READER(re, &s->gb);
- /* now quantify & encode AC coefficients */
- for(;;) {
- UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
- if(level == 127){
- break;
- } else if(level != 0) {
- i += run;
- j = scantable[i];
- level= (level*qscale*quant_matrix[j])>>4;
- level= (level-1)|1;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
- if (level == -128) {
- level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8);
- } else if (level == 0) {
- level = SHOW_UBITS(re, &s->gb, 8) ; LAST_SKIP_BITS(re, &s->gb, 8);
- }
- i += run;
- j = scantable[i];
- if(level<0){
- level= -level;
- level= (level*qscale*quant_matrix[j])>>4;
- level= (level-1)|1;
- level= -level;
- }else{
- level= (level*qscale*quant_matrix[j])>>4;
- level= (level-1)|1;
- }
- }
- if (i > 63){
- av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- block[j] = level;
- }
- CLOSE_READER(re, &s->gb);
- }
- s->block_last_index[n] = i;
- return 0;
-}
-
-int ff_mpeg1_decode_block_intra(MpegEncContext *s,
- DCTELEM *block,
- int n)
-{
- return mpeg1_decode_block_intra(s, block, n);
-}
-
-static inline int mpeg1_decode_block_inter(MpegEncContext *s,
- DCTELEM *block,
- int n)
-{
- int level, i, j, run;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t * const scantable= s->intra_scantable.permutated;
- const uint16_t *quant_matrix= s->inter_matrix;
- const int qscale= s->qscale;
-
- {
- OPEN_READER(re, &s->gb);
- i = -1;
- // special case for first coefficient, no need to add second VLC table
- UPDATE_CACHE(re, &s->gb);
- if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
- level= (3*qscale*quant_matrix[0])>>5;
- level= (level-1)|1;
- if(GET_CACHE(re, &s->gb)&0x40000000)
- level= -level;
- block[0] = level;
- i++;
- SKIP_BITS(re, &s->gb, 2);
- if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
- goto end;
- }
- /* now quantify & encode AC coefficients */
- for(;;) {
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
- if(level != 0) {
- i += run;
- j = scantable[i];
- level= ((level*2+1)*qscale*quant_matrix[j])>>5;
- level= (level-1)|1;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
- if (level == -128) {
- level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
- } else if (level == 0) {
- level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8);
- }
- i += run;
- j = scantable[i];
- if(level<0){
- level= -level;
- level= ((level*2+1)*qscale*quant_matrix[j])>>5;
- level= (level-1)|1;
- level= -level;
- }else{
- level= ((level*2+1)*qscale*quant_matrix[j])>>5;
- level= (level-1)|1;
- }
- }
- if (i > 63){
- av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- block[j] = level;
- if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
- break;
- UPDATE_CACHE(re, &s->gb);
- }
-end:
- LAST_SKIP_BITS(re, &s->gb, 2);
- CLOSE_READER(re, &s->gb);
- }
- s->block_last_index[n] = i;
- return 0;
-}
-
-static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n)
-{
- int level, i, j, run;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t * const scantable= s->intra_scantable.permutated;
- const int qscale= s->qscale;
-
- {
- OPEN_READER(re, &s->gb);
- i = -1;
- // special case for first coefficient, no need to add second VLC table
- UPDATE_CACHE(re, &s->gb);
- if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
- level= (3*qscale)>>1;
- level= (level-1)|1;
- if(GET_CACHE(re, &s->gb)&0x40000000)
- level= -level;
- block[0] = level;
- i++;
- SKIP_BITS(re, &s->gb, 2);
- if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
- goto end;
- }
-
- /* now quantify & encode AC coefficients */
- for(;;) {
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
- if(level != 0) {
- i += run;
- j = scantable[i];
- level= ((level*2+1)*qscale)>>1;
- level= (level-1)|1;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
- if (level == -128) {
- level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
- } else if (level == 0) {
- level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8);
- }
- i += run;
- j = scantable[i];
- if(level<0){
- level= -level;
- level= ((level*2+1)*qscale)>>1;
- level= (level-1)|1;
- level= -level;
- }else{
- level= ((level*2+1)*qscale)>>1;
- level= (level-1)|1;
- }
- }
-
- block[j] = level;
- if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
- break;
- UPDATE_CACHE(re, &s->gb);
- }
-end:
- LAST_SKIP_BITS(re, &s->gb, 2);
- CLOSE_READER(re, &s->gb);
- }
- s->block_last_index[n] = i;
- return 0;
-}
-
-
-static inline int mpeg2_decode_block_non_intra(MpegEncContext *s,
- DCTELEM *block,
- int n)
-{
- int level, i, j, run;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t * const scantable= s->intra_scantable.permutated;
- const uint16_t *quant_matrix;
- const int qscale= s->qscale;
- int mismatch;
-
- mismatch = 1;
-
- {
- OPEN_READER(re, &s->gb);
- i = -1;
- if (n < 4)
- quant_matrix = s->inter_matrix;
- else
- quant_matrix = s->chroma_inter_matrix;
-
- // special case for first coefficient, no need to add second VLC table
- UPDATE_CACHE(re, &s->gb);
- if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
- level= (3*qscale*quant_matrix[0])>>5;
- if(GET_CACHE(re, &s->gb)&0x40000000)
- level= -level;
- block[0] = level;
- mismatch ^= level;
- i++;
- SKIP_BITS(re, &s->gb, 2);
- if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
- goto end;
- }
-
- /* now quantify & encode AC coefficients */
- for(;;) {
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
- if(level != 0) {
- i += run;
- j = scantable[i];
- level= ((level*2+1)*qscale*quant_matrix[j])>>5;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
-
- i += run;
- j = scantable[i];
- if(level<0){
- level= ((-level*2+1)*qscale*quant_matrix[j])>>5;
- level= -level;
- }else{
- level= ((level*2+1)*qscale*quant_matrix[j])>>5;
- }
- }
- if (i > 63){
- av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- mismatch ^= level;
- block[j] = level;
- if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
- break;
- UPDATE_CACHE(re, &s->gb);
- }
-end:
- LAST_SKIP_BITS(re, &s->gb, 2);
- CLOSE_READER(re, &s->gb);
- }
- block[63] ^= (mismatch & 1);
-
- s->block_last_index[n] = i;
- return 0;
-}
-
-static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s,
- DCTELEM *block,
- int n)
-{
- int level, i, j, run;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t * const scantable= s->intra_scantable.permutated;
- const int qscale= s->qscale;
- OPEN_READER(re, &s->gb);
- i = -1;
-
- // special case for first coefficient, no need to add second VLC table
- UPDATE_CACHE(re, &s->gb);
- if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
- level= (3*qscale)>>1;
- if(GET_CACHE(re, &s->gb)&0x40000000)
- level= -level;
- block[0] = level;
- i++;
- SKIP_BITS(re, &s->gb, 2);
- if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
- goto end;
- }
-
- /* now quantify & encode AC coefficients */
- for(;;) {
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+ const int my_shift = s->picture_structure == PICT_FRAME;
- if(level != 0) {
- i += run;
- j = scantable[i];
- level= ((level*2+1)*qscale)>>1;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
+ mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
+ s->last_mv[i][0][0]);
+ s->last_mv[i][0][0] = mx;
+ s->last_mv[i][1][0] = mx;
+ dmx = get_dmv(s);
+ my = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
+ s->last_mv[i][0][1] >> my_shift);
+ dmy = get_dmv(s);
- i += run;
- j = scantable[i];
- if(level<0){
- level= ((-level*2+1)*qscale)>>1;
- level= -level;
- }else{
- level= ((level*2+1)*qscale)>>1;
- }
- }
- block[j] = level;
- if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
- break;
- UPDATE_CACHE(re, &s->gb);
- }
-end:
- LAST_SKIP_BITS(re, &s->gb, 2);
- CLOSE_READER(re, &s->gb);
- s->block_last_index[n] = i;
- return 0;
-}
+ s->last_mv[i][0][1] = my << my_shift;
+ s->last_mv[i][1][1] = my << my_shift;
+ s->mv[i][0][0] = mx;
+ s->mv[i][0][1] = my;
+ s->mv[i][1][0] = mx; // not used
+ s->mv[i][1][1] = my; // not used
-static inline int mpeg2_decode_block_intra(MpegEncContext *s,
- DCTELEM *block,
- int n)
-{
- int level, dc, diff, i, j, run;
- int component;
- RLTable *rl;
- uint8_t * const scantable= s->intra_scantable.permutated;
- const uint16_t *quant_matrix;
- const int qscale= s->qscale;
- int mismatch;
+ if (s->picture_structure == PICT_FRAME) {
+ mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
- /* DC coefficient */
- if (n < 4){
- quant_matrix = s->intra_matrix;
- component = 0;
- }else{
- quant_matrix = s->chroma_intra_matrix;
- component = (n&1) + 1;
- }
- diff = decode_dc(&s->gb, component);
- if (diff >= 0xffff)
- return -1;
- dc = s->last_dc[component];
- dc += diff;
- s->last_dc[component] = dc;
- block[0] = dc << (3 - s->intra_dc_precision);
- av_dlog(s->avctx, "dc=%d\n", block[0]);
- mismatch = block[0] ^ 1;
- i = 0;
- if (s->intra_vlc_format)
- rl = &ff_rl_mpeg2;
- else
- rl = &ff_rl_mpeg1;
+ // m = 1 + 2 * s->top_field_first;
+ m = s->top_field_first ? 1 : 3;
- {
- OPEN_READER(re, &s->gb);
- /* now quantify & encode AC coefficients */
- for(;;) {
- UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+ /* top -> top pred */
+ s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
+ s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;
+ m = 4 - m;
+ s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
+ s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;
+ } else {
+ mb_type |= MB_TYPE_16x16;
- if(level == 127){
- break;
- } else if(level != 0) {
- i += run;
- j = scantable[i];
- level= (level*qscale*quant_matrix[j])>>4;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
- i += run;
- j = scantable[i];
- if(level<0){
- level= (-level*qscale*quant_matrix[j])>>4;
- level= -level;
- }else{
- level= (level*qscale*quant_matrix[j])>>4;
+ s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx;
+ s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy;
+ if (s->picture_structure == PICT_TOP_FIELD)
+ s->mv[i][2][1]--;
+ else
+ s->mv[i][2][1]++;
+ }
+ }
}
- }
- if (i > 63){
- av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
-
- mismatch^= level;
- block[j] = level;
}
- CLOSE_READER(re, &s->gb);
- }
- block[63]^= mismatch&1;
- s->block_last_index[n] = i;
- return 0;
-}
+ s->mb_intra = 0;
+ if (HAS_CBP(mb_type)) {
+ s->dsp.clear_blocks(s->block[0]);
-static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s,
- DCTELEM *block,
- int n)
-{
- int level, dc, diff, j, run;
- int component;
- RLTable *rl;
- uint8_t * scantable= s->intra_scantable.permutated;
- const uint16_t *quant_matrix;
- const int qscale= s->qscale;
+ cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);
+ if (mb_block_count > 6) {
+ cbp <<= mb_block_count - 6;
+ cbp |= get_bits(&s->gb, mb_block_count - 6);
+ s->dsp.clear_blocks(s->block[6]);
+ }
+ if (cbp <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
- /* DC coefficient */
- if (n < 4){
- quant_matrix = s->intra_matrix;
- component = 0;
- }else{
- quant_matrix = s->chroma_intra_matrix;
- component = (n&1) + 1;
- }
- diff = decode_dc(&s->gb, component);
- if (diff >= 0xffff)
- return -1;
- dc = s->last_dc[component];
- dc += diff;
- s->last_dc[component] = dc;
- block[0] = dc << (3 - s->intra_dc_precision);
- if (s->intra_vlc_format)
- rl = &ff_rl_mpeg2;
- else
- rl = &ff_rl_mpeg1;
+ //if 1, we memcpy blocks in xvmcvideo
+ if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
+ ff_xvmc_pack_pblocks(s, cbp);
+ if (s->swap_uv) {
+ exchange_uv(s);
+ }
+ }
- {
- OPEN_READER(re, &s->gb);
- /* now quantify & encode AC coefficients */
- for(;;) {
- UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+ if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
+ if (s->flags2 & CODEC_FLAG2_FAST) {
+ for (i = 0; i < 6; i++) {
+ if (cbp & 32) {
+ mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp += cbp;
+ }
+ } else {
+ cbp <<= 12-mb_block_count;
- if(level == 127){
- break;
- } else if(level != 0) {
- scantable += run;
- j = *scantable;
- level= (level*qscale*quant_matrix[j])>>4;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
+ for (i = 0; i < mb_block_count; i++) {
+ if (cbp & (1 << 11)) {
+ if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0)
+ return -1;
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp += cbp;
+ }
+ }
} else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
- scantable += run;
- j = *scantable;
- if(level<0){
- level= (-level*qscale*quant_matrix[j])>>4;
- level= -level;
- }else{
- level= (level*qscale*quant_matrix[j])>>4;
+ if (s->flags2 & CODEC_FLAG2_FAST) {
+ for (i = 0; i < 6; i++) {
+ if (cbp & 32) {
+ mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp += cbp;
+ }
+ } else {
+ for (i = 0; i < 6; i++) {
+ if (cbp & 32) {
+ if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0)
+ return -1;
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp += cbp;
+ }
}
}
-
- block[j] = level;
+ } else {
+ for (i = 0; i < 12; i++)
+ s->block_last_index[i] = -1;
}
- CLOSE_READER(re, &s->gb);
}
- s->block_last_index[n] = scantable - s->intra_scantable.permutated;
+ s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;
+
return 0;
}
-typedef struct Mpeg1Context {
- MpegEncContext mpeg_enc_ctx;
- int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
- int repeat_field; /* true if we must repeat the field */
- AVPanScan pan_scan; /**< some temporary storage for the panscan */
- int slice_count;
- int swap_uv;//indicate VCR2
- int save_aspect_info;
- int save_width, save_height, save_progressive_seq;
- AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator
- int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame?
-} Mpeg1Context;
-
static av_cold int mpeg_decode_init(AVCodecContext *avctx)
{
Mpeg1Context *s = avctx->priv_data;
@@ -1157,22 +1114,22 @@ static av_cold int mpeg_decode_init(AVCodecContext *avctx)
/* we need some permutation to store matrices,
* until MPV_common_init() sets the real permutation. */
- for(i=0;i<64;i++)
+ for (i = 0; i < 64; i++)
s2->dsp.idct_permutation[i]=i;
MPV_decode_defaults(s2);
- s->mpeg_enc_ctx.avctx= avctx;
- s->mpeg_enc_ctx.flags= avctx->flags;
- s->mpeg_enc_ctx.flags2= avctx->flags2;
+ s->mpeg_enc_ctx.avctx = avctx;
+ s->mpeg_enc_ctx.flags = avctx->flags;
+ s->mpeg_enc_ctx.flags2 = avctx->flags2;
ff_mpeg12_common_init(&s->mpeg_enc_ctx);
ff_mpeg12_init_vlcs();
- s->mpeg_enc_ctx_allocated = 0;
+ s->mpeg_enc_ctx_allocated = 0;
s->mpeg_enc_ctx.picture_number = 0;
- s->repeat_field = 0;
- s->mpeg_enc_ctx.codec_id= avctx->codec->id;
- avctx->color_range= AVCOL_RANGE_MPEG;
+ s->repeat_field = 0;
+ s->mpeg_enc_ctx.codec_id = avctx->codec->id;
+ avctx->color_range = AVCOL_RANGE_MPEG;
if (avctx->codec->id == CODEC_ID_MPEG1VIDEO)
avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
else
@@ -1186,48 +1143,55 @@ static int mpeg_decode_update_thread_context(AVCodecContext *avctx, const AVCode
MpegEncContext *s = &ctx->mpeg_enc_ctx, *s1 = &ctx_from->mpeg_enc_ctx;
int err;
- if(avctx == avctx_from || !ctx_from->mpeg_enc_ctx_allocated || !s1->context_initialized)
+ if (avctx == avctx_from || !ctx_from->mpeg_enc_ctx_allocated || !s1->context_initialized)
return 0;
err = ff_mpeg_update_thread_context(avctx, avctx_from);
- if(err) return err;
+ if (err) return err;
- if(!ctx->mpeg_enc_ctx_allocated)
+ if (!ctx->mpeg_enc_ctx_allocated)
memcpy(s + 1, s1 + 1, sizeof(Mpeg1Context) - sizeof(MpegEncContext));
- if(!(s->pict_type == FF_B_TYPE || s->low_delay))
+ if (!(s->pict_type == AV_PICTURE_TYPE_B || s->low_delay))
s->picture_number++;
return 0;
}
static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm,
- const uint8_t *new_perm){
+ const uint8_t *new_perm)
+{
uint16_t temp_matrix[64];
int i;
- memcpy(temp_matrix,matrix,64*sizeof(uint16_t));
+ memcpy(temp_matrix, matrix, 64 * sizeof(uint16_t));
- for(i=0;i<64;i++){
+ for (i = 0; i < 64; i++) {
matrix[new_perm[i]] = temp_matrix[old_perm[i]];
}
}
-static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx){
+static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = {
+ PIX_FMT_XVMC_MPEG2_IDCT,
+ PIX_FMT_XVMC_MPEG2_MC,
+ PIX_FMT_NONE };
+
+static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
+{
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
- if(avctx->xvmc_acceleration)
- return avctx->get_format(avctx,pixfmt_xvmc_mpg2_420);
- else if(avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){
- if(avctx->codec_id == CODEC_ID_MPEG1VIDEO)
+ if (avctx->xvmc_acceleration)
+ return avctx->get_format(avctx, pixfmt_xvmc_mpg2_420);
+ else if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
+ if (avctx->codec_id == CODEC_ID_MPEG1VIDEO)
return PIX_FMT_VDPAU_MPEG1;
else
return PIX_FMT_VDPAU_MPEG2;
- }else{
- if(s->chroma_format < 2)
- return avctx->get_format(avctx,ff_hwaccel_pixfmt_list_420);
- else if(s->chroma_format == 2)
+ } else {
+ if (s->chroma_format < 2)
+ return avctx->get_format(avctx, ff_hwaccel_pixfmt_list_420);
+ else if (s->chroma_format == 2)
return PIX_FMT_YUV422P;
else
return PIX_FMT_YUV444P;
@@ -1236,118 +1200,111 @@ static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx){
/* Call this function when we know all parameters.
* It may be called in different places for MPEG-1 and MPEG-2. */
-static int mpeg_decode_postinit(AVCodecContext *avctx){
+static int mpeg_decode_postinit(AVCodecContext *avctx)
+{
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
uint8_t old_permutation[64];
- if (
- (s1->mpeg_enc_ctx_allocated == 0)||
- avctx->coded_width != s->width ||
- avctx->coded_height != s->height||
- s1->save_width != s->width ||
- s1->save_height != s->height ||
- s1->save_aspect_info != s->aspect_ratio_info||
+ if ((s1->mpeg_enc_ctx_allocated == 0) ||
+ avctx->coded_width != s->width ||
+ avctx->coded_height != s->height ||
+ s1->save_width != s->width ||
+ s1->save_height != s->height ||
+ s1->save_aspect_info != s->aspect_ratio_info ||
s1->save_progressive_seq != s->progressive_sequence ||
0)
{
if (s1->mpeg_enc_ctx_allocated) {
- ParseContext pc= s->parse_context;
- s->parse_context.buffer=0;
+ ParseContext pc = s->parse_context;
+ s->parse_context.buffer = 0;
MPV_common_end(s);
- s->parse_context= pc;
+ s->parse_context = pc;
}
- if( (s->width == 0 )||(s->height == 0))
+ if ((s->width == 0) || (s->height == 0))
return -2;
avcodec_set_dimensions(avctx, s->width, s->height);
- avctx->bit_rate = s->bit_rate;
- s1->save_aspect_info = s->aspect_ratio_info;
- s1->save_width = s->width;
- s1->save_height = s->height;
+ avctx->bit_rate = s->bit_rate;
+ s1->save_aspect_info = s->aspect_ratio_info;
+ s1->save_width = s->width;
+ s1->save_height = s->height;
s1->save_progressive_seq = s->progressive_sequence;
/* low_delay may be forced, in this case we will have B-frames
* that behave like P-frames. */
avctx->has_b_frames = !(s->low_delay);
- assert((avctx->sub_id==1) == (avctx->codec_id==CODEC_ID_MPEG1VIDEO));
- if(avctx->codec_id==CODEC_ID_MPEG1VIDEO){
+ assert((avctx->sub_id == 1) == (avctx->codec_id == CODEC_ID_MPEG1VIDEO));
+ if (avctx->codec_id == CODEC_ID_MPEG1VIDEO) {
//MPEG-1 fps
- avctx->time_base.den= ff_frame_rate_tab[s->frame_rate_index].num;
- avctx->time_base.num= ff_frame_rate_tab[s->frame_rate_index].den;
+ avctx->time_base.den = avpriv_frame_rate_tab[s->frame_rate_index].num;
+ avctx->time_base.num = avpriv_frame_rate_tab[s->frame_rate_index].den;
//MPEG-1 aspect
- avctx->sample_aspect_ratio= av_d2q(
- 1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255);
+ avctx->sample_aspect_ratio = av_d2q(1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255);
avctx->ticks_per_frame=1;
- }else{//MPEG-2
+ } else {//MPEG-2
//MPEG-2 fps
- av_reduce(
- &s->avctx->time_base.den,
- &s->avctx->time_base.num,
- ff_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num*2,
- ff_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den,
- 1<<30);
- avctx->ticks_per_frame=2;
- //MPEG-2 aspect
- if(s->aspect_ratio_info > 1){
+ av_reduce(&s->avctx->time_base.den,
+ &s->avctx->time_base.num,
+ avpriv_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num*2,
+ avpriv_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den,
+ 1 << 30);
+ avctx->ticks_per_frame = 2;
+ //MPEG-2 aspect
+ if (s->aspect_ratio_info > 1) {
AVRational dar =
- av_mul_q(
- av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
- (AVRational){s1->pan_scan.width, s1->pan_scan.height}),
- (AVRational){s->width, s->height});
+ av_mul_q(av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
+ (AVRational) {s1->pan_scan.width, s1->pan_scan.height}),
+ (AVRational) {s->width, s->height});
// we ignore the spec here and guess a bit as reality does not match the spec, see for example
// res_change_ffmpeg_aspect.ts and sequence-display-aspect.mpg
// issue1613, 621, 562
- if((s1->pan_scan.width == 0 ) || (s1->pan_scan.height == 0) ||
- (av_cmp_q(dar,(AVRational){4,3}) && av_cmp_q(dar,(AVRational){16,9}))) {
- s->avctx->sample_aspect_ratio=
- av_div_q(
- ff_mpeg2_aspect[s->aspect_ratio_info],
- (AVRational){s->width, s->height}
- );
- }else{
- s->avctx->sample_aspect_ratio=
- av_div_q(
- ff_mpeg2_aspect[s->aspect_ratio_info],
- (AVRational){s1->pan_scan.width, s1->pan_scan.height}
- );
+ if ((s1->pan_scan.width == 0) || (s1->pan_scan.height == 0) ||
+ (av_cmp_q(dar, (AVRational) {4, 3}) && av_cmp_q(dar, (AVRational) {16, 9}))) {
+ s->avctx->sample_aspect_ratio =
+ av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
+ (AVRational) {s->width, s->height});
+ } else {
+ s->avctx->sample_aspect_ratio =
+ av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
+ (AVRational) {s1->pan_scan.width, s1->pan_scan.height});
//issue1613 4/3 16/9 -> 16/9
//res_change_ffmpeg_aspect.ts 4/3 225/44 ->4/3
//widescreen-issue562.mpg 4/3 16/9 -> 16/9
-// s->avctx->sample_aspect_ratio= av_mul_q(s->avctx->sample_aspect_ratio, (AVRational){s->width, s->height});
-//av_log(NULL, AV_LOG_ERROR, "A %d/%d\n",ff_mpeg2_aspect[s->aspect_ratio_info].num, ff_mpeg2_aspect[s->aspect_ratio_info].den);
-//av_log(NULL, AV_LOG_ERROR, "B %d/%d\n",s->avctx->sample_aspect_ratio.num, s->avctx->sample_aspect_ratio.den);
+// s->avctx->sample_aspect_ratio = av_mul_q(s->avctx->sample_aspect_ratio, (AVRational) {s->width, s->height});
+//av_log(NULL, AV_LOG_ERROR, "A %d/%d\n", ff_mpeg2_aspect[s->aspect_ratio_info].num, ff_mpeg2_aspect[s->aspect_ratio_info].den);
+//av_log(NULL, AV_LOG_ERROR, "B %d/%d\n", s->avctx->sample_aspect_ratio.num, s->avctx->sample_aspect_ratio.den);
}
- }else{
- s->avctx->sample_aspect_ratio=
+ } else {
+ s->avctx->sample_aspect_ratio =
ff_mpeg2_aspect[s->aspect_ratio_info];
}
- }//MPEG-2
+ } // MPEG-2
avctx->pix_fmt = mpeg_get_pixelformat(avctx);
avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
- //until then pix_fmt may be changed right after codec init
- if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ||
- avctx->hwaccel ||
- s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU )
- if( avctx->idct_algo == FF_IDCT_AUTO )
+ // until then pix_fmt may be changed right after codec init
+ if (avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ||
+ avctx->hwaccel ||
+ s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+ if (avctx->idct_algo == FF_IDCT_AUTO)
avctx->idct_algo = FF_IDCT_SIMPLE;
/* Quantization matrices may need reordering
* if DCT permutation is changed. */
- memcpy(old_permutation,s->dsp.idct_permutation,64*sizeof(uint8_t));
+ memcpy(old_permutation, s->dsp.idct_permutation, 64 * sizeof(uint8_t));
if (MPV_common_init(s) < 0)
return -2;
- quant_matrix_rebuild(s->intra_matrix, old_permutation,s->dsp.idct_permutation);
- quant_matrix_rebuild(s->inter_matrix, old_permutation,s->dsp.idct_permutation);
- quant_matrix_rebuild(s->chroma_intra_matrix,old_permutation,s->dsp.idct_permutation);
- quant_matrix_rebuild(s->chroma_inter_matrix,old_permutation,s->dsp.idct_permutation);
+ quant_matrix_rebuild(s->intra_matrix, old_permutation, s->dsp.idct_permutation);
+ quant_matrix_rebuild(s->inter_matrix, old_permutation, s->dsp.idct_permutation);
+ quant_matrix_rebuild(s->chroma_intra_matrix, old_permutation, s->dsp.idct_permutation);
+ quant_matrix_rebuild(s->chroma_inter_matrix, old_permutation, s->dsp.idct_permutation);
s1->mpeg_enc_ctx_allocated = 1;
}
@@ -1365,14 +1322,14 @@ static int mpeg1_decode_picture(AVCodecContext *avctx,
ref = get_bits(&s->gb, 10); /* temporal ref */
s->pict_type = get_bits(&s->gb, 3);
- if(s->pict_type == 0 || s->pict_type > 3)
+ if (s->pict_type == 0 || s->pict_type > 3)
return -1;
- vbv_delay= get_bits(&s->gb, 16);
+ vbv_delay = get_bits(&s->gb, 16);
if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type == AV_PICTURE_TYPE_B) {
s->full_pel[0] = get_bits1(&s->gb);
f_code = get_bits(&s->gb, 3);
- if (f_code == 0 && avctx->error_recognition >= FF_ER_COMPLIANT)
+ if (f_code == 0 && (avctx->err_recognition & AV_EF_BITSTREAM))
return -1;
s->mpeg_f_code[0][0] = f_code;
s->mpeg_f_code[0][1] = f_code;
@@ -1380,15 +1337,15 @@ static int mpeg1_decode_picture(AVCodecContext *avctx,
if (s->pict_type == AV_PICTURE_TYPE_B) {
s->full_pel[1] = get_bits1(&s->gb);
f_code = get_bits(&s->gb, 3);
- if (f_code == 0 && avctx->error_recognition >= FF_ER_COMPLIANT)
+ if (f_code == 0 && (avctx->err_recognition & AV_EF_BITSTREAM))
return -1;
s->mpeg_f_code[1][0] = f_code;
s->mpeg_f_code[1][1] = f_code;
}
- s->current_picture.pict_type= s->pict_type;
- s->current_picture.key_frame= s->pict_type == AV_PICTURE_TYPE_I;
+ s->current_picture.f.pict_type = s->pict_type;
+ s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
- if(avctx->debug & FF_DEBUG_PICT_INFO)
+ if (avctx->debug & FF_DEBUG_PICT_INFO)
av_log(avctx, AV_LOG_DEBUG, "vbv_delay %d, ref %d type:%d\n", vbv_delay, ref, s->pict_type);
s->y_dc_scale = 8;
@@ -1403,30 +1360,31 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
int bit_rate_ext;
skip_bits(&s->gb, 1); /* profile and level esc*/
- s->avctx->profile= get_bits(&s->gb, 3);
- s->avctx->level= get_bits(&s->gb, 4);
+ s->avctx->profile = get_bits(&s->gb, 3);
+ s->avctx->level = get_bits(&s->gb, 4);
s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */
- s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
- horiz_size_ext = get_bits(&s->gb, 2);
- vert_size_ext = get_bits(&s->gb, 2);
- s->width |= (horiz_size_ext << 12);
- s->height |= (vert_size_ext << 12);
+ s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
+ horiz_size_ext = get_bits(&s->gb, 2);
+ vert_size_ext = get_bits(&s->gb, 2);
+ s->width |= (horiz_size_ext << 12);
+ s->height |= (vert_size_ext << 12);
bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */
s->bit_rate += (bit_rate_ext << 18) * 400;
skip_bits1(&s->gb); /* marker */
- s->avctx->rc_buffer_size += get_bits(&s->gb, 8)*1024*16<<10;
+ s->avctx->rc_buffer_size += get_bits(&s->gb, 8) * 1024 * 16 << 10;
s->low_delay = get_bits1(&s->gb);
- if(s->flags & CODEC_FLAG_LOW_DELAY) s->low_delay=1;
+ if (s->flags & CODEC_FLAG_LOW_DELAY)
+ s->low_delay = 1;
- s1->frame_rate_ext.num = get_bits(&s->gb, 2)+1;
- s1->frame_rate_ext.den = get_bits(&s->gb, 5)+1;
+ s1->frame_rate_ext.num = get_bits(&s->gb, 2) + 1;
+ s1->frame_rate_ext.den = get_bits(&s->gb, 5) + 1;
av_dlog(s->avctx, "sequence extension\n");
- s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG2VIDEO;
+ s->codec_id = s->avctx->codec_id = CODEC_ID_MPEG2VIDEO;
s->avctx->sub_id = 2; /* indicates MPEG-2 found */
- if(s->avctx->debug & FF_DEBUG_PICT_INFO)
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d vbv buffer: %d, bitrate:%d\n",
s->avctx->profile, s->avctx->level, s->avctx->rc_buffer_size, s->bit_rate);
@@ -1434,78 +1392,78 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1)
{
- MpegEncContext *s= &s1->mpeg_enc_ctx;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
int color_description, w, h;
skip_bits(&s->gb, 3); /* video format */
- color_description= get_bits1(&s->gb);
- if(color_description){
- s->avctx->color_primaries= get_bits(&s->gb, 8);
- s->avctx->color_trc = get_bits(&s->gb, 8);
- s->avctx->colorspace = get_bits(&s->gb, 8);
+ color_description = get_bits1(&s->gb);
+ if (color_description) {
+ s->avctx->color_primaries = get_bits(&s->gb, 8);
+ s->avctx->color_trc = get_bits(&s->gb, 8);
+ s->avctx->colorspace = get_bits(&s->gb, 8);
}
- w= get_bits(&s->gb, 14);
+ w = get_bits(&s->gb, 14);
skip_bits(&s->gb, 1); //marker
- h= get_bits(&s->gb, 14);
+ h = get_bits(&s->gb, 14);
// remaining 3 bits are zero padding
- s1->pan_scan.width= 16*w;
- s1->pan_scan.height=16*h;
+ s1->pan_scan.width = 16 * w;
+ s1->pan_scan.height = 16 * h;
- if(s->avctx->debug & FF_DEBUG_PICT_INFO)
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_DEBUG, "sde w:%d, h:%d\n", w, h);
}
static void mpeg_decode_picture_display_extension(Mpeg1Context *s1)
{
- MpegEncContext *s= &s1->mpeg_enc_ctx;
- int i,nofco;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int i, nofco;
nofco = 1;
- if(s->progressive_sequence){
- if(s->repeat_first_field){
+ if (s->progressive_sequence) {
+ if (s->repeat_first_field) {
nofco++;
- if(s->top_field_first)
+ if (s->top_field_first)
nofco++;
}
- }else{
- if(s->picture_structure == PICT_FRAME){
+ } else {
+ if (s->picture_structure == PICT_FRAME) {
nofco++;
- if(s->repeat_first_field)
+ if (s->repeat_first_field)
nofco++;
}
}
- for(i=0; i<nofco; i++){
- s1->pan_scan.position[i][0]= get_sbits(&s->gb, 16);
- skip_bits(&s->gb, 1); //marker
- s1->pan_scan.position[i][1]= get_sbits(&s->gb, 16);
- skip_bits(&s->gb, 1); //marker
+ for (i = 0; i < nofco; i++) {
+ s1->pan_scan.position[i][0] = get_sbits(&s->gb, 16);
+ skip_bits(&s->gb, 1); // marker
+ s1->pan_scan.position[i][1] = get_sbits(&s->gb, 16);
+ skip_bits(&s->gb, 1); // marker
}
- if(s->avctx->debug & FF_DEBUG_PICT_INFO)
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_DEBUG, "pde (%d,%d) (%d,%d) (%d,%d)\n",
- s1->pan_scan.position[0][0], s1->pan_scan.position[0][1],
- s1->pan_scan.position[1][0], s1->pan_scan.position[1][1],
- s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]
- );
+ s1->pan_scan.position[0][0], s1->pan_scan.position[0][1],
+ s1->pan_scan.position[1][0], s1->pan_scan.position[1][1],
+ s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]);
}
-static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], uint16_t matrix1[64], int intra){
+static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], uint16_t matrix1[64], int intra)
+{
int i;
- for(i=0; i<64; i++) {
- int j = s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
+ for (i = 0; i < 64; i++) {
+ int j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
int v = get_bits(&s->gb, 8);
- if(v==0){
+ if (v == 0) {
av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n");
return -1;
}
- if(intra && i==0 && v!=8){
+ if (intra && i == 0 && v != 8) {
av_log(s->avctx, AV_LOG_ERROR, "intra matrix invalid, ignoring\n");
- v= 8; // needed by pink.mpg / issue1046
+ v = 8; // needed by pink.mpg / issue1046
}
matrix0[j] = v;
- if(matrix1)
+ if (matrix1)
matrix1[j] = v;
}
return 0;
@@ -1515,75 +1473,75 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
{
av_dlog(s->avctx, "matrix extension\n");
- if(get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
- if(get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
- if(get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, NULL , 1);
- if(get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, NULL , 0);
+ if (get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
+ if (get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
+ if (get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, NULL , 1);
+ if (get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, NULL , 0);
}
static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)
{
- MpegEncContext *s= &s1->mpeg_enc_ctx;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
s->full_pel[0] = s->full_pel[1] = 0;
s->mpeg_f_code[0][0] = get_bits(&s->gb, 4);
s->mpeg_f_code[0][1] = get_bits(&s->gb, 4);
s->mpeg_f_code[1][0] = get_bits(&s->gb, 4);
s->mpeg_f_code[1][1] = get_bits(&s->gb, 4);
- if(!s->pict_type && s1->mpeg_enc_ctx_allocated){
+ if (!s->pict_type && s1->mpeg_enc_ctx_allocated) {
av_log(s->avctx, AV_LOG_ERROR, "Missing picture start code, guessing missing values\n");
- if(s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1]==15){
- if(s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15)
- s->pict_type= AV_PICTURE_TYPE_I;
+ if (s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1] == 15) {
+ if (s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15)
+ s->pict_type = AV_PICTURE_TYPE_I;
else
- s->pict_type= AV_PICTURE_TYPE_P;
- }else
- s->pict_type= AV_PICTURE_TYPE_B;
- s->current_picture.pict_type= s->pict_type;
- s->current_picture.key_frame= s->pict_type == AV_PICTURE_TYPE_I;
+ s->pict_type = AV_PICTURE_TYPE_P;
+ } else
+ s->pict_type = AV_PICTURE_TYPE_B;
+ s->current_picture.f.pict_type = s->pict_type;
+ s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
}
- s->intra_dc_precision = get_bits(&s->gb, 2);
- s->picture_structure = get_bits(&s->gb, 2);
- s->top_field_first = get_bits1(&s->gb);
- s->frame_pred_frame_dct = get_bits1(&s->gb);
+ s->intra_dc_precision = get_bits(&s->gb, 2);
+ s->picture_structure = get_bits(&s->gb, 2);
+ s->top_field_first = get_bits1(&s->gb);
+ s->frame_pred_frame_dct = get_bits1(&s->gb);
s->concealment_motion_vectors = get_bits1(&s->gb);
- s->q_scale_type = get_bits1(&s->gb);
- s->intra_vlc_format = get_bits1(&s->gb);
- s->alternate_scan = get_bits1(&s->gb);
- s->repeat_first_field = get_bits1(&s->gb);
- s->chroma_420_type = get_bits1(&s->gb);
- s->progressive_frame = get_bits1(&s->gb);
-
- if(s->progressive_sequence && !s->progressive_frame){
- s->progressive_frame= 1;
+ s->q_scale_type = get_bits1(&s->gb);
+ s->intra_vlc_format = get_bits1(&s->gb);
+ s->alternate_scan = get_bits1(&s->gb);
+ s->repeat_first_field = get_bits1(&s->gb);
+ s->chroma_420_type = get_bits1(&s->gb);
+ s->progressive_frame = get_bits1(&s->gb);
+
+ if (s->progressive_sequence && !s->progressive_frame) {
+ s->progressive_frame = 1;
av_log(s->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n");
}
- if(s->picture_structure==0 || (s->progressive_frame && s->picture_structure!=PICT_FRAME)){
+ if (s->picture_structure == 0 || (s->progressive_frame && s->picture_structure != PICT_FRAME)) {
av_log(s->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s->picture_structure);
- s->picture_structure= PICT_FRAME;
+ s->picture_structure = PICT_FRAME;
}
- if(s->progressive_sequence && !s->frame_pred_frame_dct){
+ if (s->progressive_sequence && !s->frame_pred_frame_dct) {
av_log(s->avctx, AV_LOG_ERROR, "invalid frame_pred_frame_dct\n");
- s->frame_pred_frame_dct= 1;
+ s->frame_pred_frame_dct = 1;
}
- if(s->picture_structure == PICT_FRAME){
- s->first_field=0;
- s->v_edge_pos= 16*s->mb_height;
- }else{
+ if (s->picture_structure == PICT_FRAME) {
+ s->first_field = 0;
+ s->v_edge_pos = 16 * s->mb_height;
+ } else {
s->first_field ^= 1;
- s->v_edge_pos= 8*s->mb_height;
- memset(s->mbskip_table, 0, s->mb_stride*s->mb_height);
+ s->v_edge_pos = 8 * s->mb_height;
+ memset(s->mbskip_table, 0, s->mb_stride * s->mb_height);
}
- if(s->alternate_scan){
- ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan);
- }else{
- ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct);
+ if (s->alternate_scan) {
+ ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
+ } else {
+ ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
}
/* composite display not parsed */
@@ -1598,56 +1556,49 @@ static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)
av_dlog(s->avctx, "progressive_frame=%d\n", s->progressive_frame);
}
-static void exchange_uv(MpegEncContext *s){
- DCTELEM (*tmp)[64];
-
- tmp = s->pblocks[4];
- s->pblocks[4] = s->pblocks[5];
- s->pblocks[5] = tmp;
-}
-
-static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size){
- AVCodecContext *avctx= s->avctx;
+static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
+{
+ AVCodecContext *avctx = s->avctx;
Mpeg1Context *s1 = (Mpeg1Context*)s;
/* start frame decoding */
- if(s->first_field || s->picture_structure==PICT_FRAME){
- if(MPV_frame_start(s, avctx) < 0)
+ if (s->first_field || s->picture_structure == PICT_FRAME) {
+ if (MPV_frame_start(s, avctx) < 0)
return -1;
ff_er_frame_start(s);
/* first check if we must repeat the frame */
- s->current_picture_ptr->repeat_pict = 0;
+ s->current_picture_ptr->f.repeat_pict = 0;
if (s->repeat_first_field) {
if (s->progressive_sequence) {
if (s->top_field_first)
- s->current_picture_ptr->repeat_pict = 4;
+ s->current_picture_ptr->f.repeat_pict = 4;
else
- s->current_picture_ptr->repeat_pict = 2;
+ s->current_picture_ptr->f.repeat_pict = 2;
} else if (s->progressive_frame) {
- s->current_picture_ptr->repeat_pict = 1;
+ s->current_picture_ptr->f.repeat_pict = 1;
}
}
- *s->current_picture_ptr->pan_scan= s1->pan_scan;
+ *s->current_picture_ptr->f.pan_scan = s1->pan_scan;
- if (HAVE_PTHREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
+ if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
ff_thread_finish_setup(avctx);
- }else{ //second field
- int i;
+ } else { // second field
+ int i;
- if(!s->current_picture_ptr){
- av_log(s->avctx, AV_LOG_ERROR, "first field missing\n");
- return -1;
- }
+ if (!s->current_picture_ptr) {
+ av_log(s->avctx, AV_LOG_ERROR, "first field missing\n");
+ return -1;
+ }
- for(i=0; i<4; i++){
- s->current_picture.data[i] = s->current_picture_ptr->data[i];
- if(s->picture_structure == PICT_BOTTOM_FIELD){
- s->current_picture.data[i] += s->current_picture_ptr->linesize[i];
- }
+ for (i = 0; i < 4; i++) {
+ s->current_picture.f.data[i] = s->current_picture_ptr->f.data[i];
+ if (s->picture_structure == PICT_BOTTOM_FIELD) {
+ s->current_picture.f.data[i] += s->current_picture_ptr->f.linesize[i];
}
+ }
}
if (avctx->hwaccel) {
@@ -1657,42 +1608,42 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
// MPV_frame_start will call this function too,
// but we need to call it on every field
- if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
- if(ff_xvmc_field_start(s,avctx) < 0)
+ if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
+ if (ff_xvmc_field_start(s, avctx) < 0)
return -1;
return 0;
}
#define DECODE_SLICE_ERROR -1
-#define DECODE_SLICE_OK 0
+#define DECODE_SLICE_OK 0
/**
- * decodes a slice. MpegEncContext.mb_y must be set to the MB row from the startcode
- * @return DECODE_SLICE_ERROR if the slice is damaged<br>
- * DECODE_SLICE_OK if this slice is ok<br>
+ * Decode a slice.
+ * MpegEncContext.mb_y must be set to the MB row from the startcode.
+ * @return DECODE_SLICE_ERROR if the slice is damaged,
+ * DECODE_SLICE_OK if this slice is OK
*/
-static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y,
+static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
const uint8_t **buf, int buf_size)
{
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- AVCodecContext *avctx= s->avctx;
- const int field_pic= s->picture_structure != PICT_FRAME;
- const int lowres= s->avctx->lowres;
+ AVCodecContext *avctx = s->avctx;
+ const int lowres = s->avctx->lowres;
+ const int field_pic = s->picture_structure != PICT_FRAME;
- s->resync_mb_x=
- s->resync_mb_y= -1;
+ s->resync_mb_x =
+ s->resync_mb_y = -1;
assert(mb_y < s->mb_height);
- init_get_bits(&s->gb, *buf, buf_size*8);
+ init_get_bits(&s->gb, *buf, buf_size * 8);
ff_mpeg1_clean_buffers(s);
s->interlaced_dct = 0;
s->qscale = get_qscale(s);
- if(s->qscale == 0){
+ if (s->qscale == 0) {
av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n");
return -1;
}
@@ -1702,14 +1653,14 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y,
skip_bits(&s->gb, 8);
}
- s->mb_x=0;
+ s->mb_x = 0;
- if(mb_y==0 && s->codec_tag == AV_RL32("SLIF")){
+ if (mb_y == 0 && s->codec_tag == AV_RL32("SLIF")) {
skip_bits1(&s->gb);
- }else{
- for(;;) {
+ } else {
+ for (;;) {
int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);
- if (code < 0){
+ if (code < 0) {
av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");
return -1;
}
@@ -1725,7 +1676,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y,
}
}
- if(s->mb_x >= (unsigned)s->mb_width){
+ if (s->mb_x >= (unsigned)s->mb_width) {
av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n");
return -1;
}
@@ -1733,7 +1684,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y,
if (avctx->hwaccel) {
const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */
int start_code = -1;
- buf_end = ff_find_start_code(buf_start + 2, *buf + buf_size, &start_code);
+ buf_end = avpriv_mpv_find_start_code(buf_start + 2, *buf + buf_size, &start_code);
if (buf_end < *buf + buf_size)
buf_end -= 4;
s->mb_y = mb_y;
@@ -1743,41 +1694,41 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y,
return DECODE_SLICE_OK;
}
- s->resync_mb_x= s->mb_x;
- s->resync_mb_y= s->mb_y= mb_y;
- s->mb_skip_run= 0;
+ s->resync_mb_x = s->mb_x;
+ s->resync_mb_y = s->mb_y = mb_y;
+ s->mb_skip_run = 0;
ff_init_block_index(s);
- if (s->mb_y==0 && s->mb_x==0 && (s->first_field || s->picture_structure==PICT_FRAME)) {
- if(s->avctx->debug&FF_DEBUG_PICT_INFO){
+ if (s->mb_y == 0 && s->mb_x == 0 && (s->first_field || s->picture_structure == PICT_FRAME)) {
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n",
- s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1],
- s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")),
- s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"",
- s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors,
- s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :"");
+ s->qscale, s->mpeg_f_code[0][0], s->mpeg_f_code[0][1], s->mpeg_f_code[1][0], s->mpeg_f_code[1][1],
+ s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")),
+ s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"",
+ s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors,
+ s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :"");
}
}
- for(;;) {
- //If 1, we memcpy blocks in xvmcvideo.
- if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1)
- ff_xvmc_init_block(s);//set s->block
+ for (;;) {
+ // If 1, we memcpy blocks in xvmcvideo.
+ if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1)
+ ff_xvmc_init_block(s); // set s->block
- if(mpeg_decode_mb(s, s->block) < 0)
+ if (mpeg_decode_mb(s, s->block) < 0)
return -1;
- if(s->current_picture.motion_val[0] && !s->encoding){ //note motion_val is normally NULL unless we want to extract the MVs
+ if (s->current_picture.f.motion_val[0] && !s->encoding) { // note motion_val is normally NULL unless we want to extract the MVs
const int wrap = s->b8_stride;
- int xy = s->mb_x*2 + s->mb_y*2*wrap;
- int b8_xy= 4*(s->mb_x + s->mb_y*s->mb_stride);
+ int xy = s->mb_x * 2 + s->mb_y * 2 * wrap;
+ int b8_xy = 4 * (s->mb_x + s->mb_y * s->mb_stride);
int motion_x, motion_y, dir, i;
- for(i=0; i<2; i++){
- for(dir=0; dir<2; dir++){
- if (s->mb_intra || (dir==1 && s->pict_type != AV_PICTURE_TYPE_B)) {
+ for (i = 0; i < 2; i++) {
+ for (dir = 0; dir < 2; dir++) {
+ if (s->mb_intra || (dir == 1 && s->pict_type != AV_PICTURE_TYPE_B)) {
motion_x = motion_y = 0;
- }else if (s->mv_type == MV_TYPE_16X16 || (s->mv_type == MV_TYPE_FIELD && field_pic)){
+ } else if (s->mv_type == MV_TYPE_16X16 || (s->mv_type == MV_TYPE_FIELD && field_pic)) {
motion_x = s->mv[dir][0][0];
motion_y = s->mv[dir][0][1];
} else /*if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8))*/ {
@@ -1785,13 +1736,13 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y,
motion_y = s->mv[dir][i][1];
}
- s->current_picture.motion_val[dir][xy ][0] = motion_x;
- s->current_picture.motion_val[dir][xy ][1] = motion_y;
- s->current_picture.motion_val[dir][xy + 1][0] = motion_x;
- s->current_picture.motion_val[dir][xy + 1][1] = motion_y;
- s->current_picture.ref_index [dir][b8_xy ]=
- s->current_picture.ref_index [dir][b8_xy + 1]= s->field_select[dir][i];
- assert(s->field_select[dir][i]==0 || s->field_select[dir][i]==1);
+ s->current_picture.f.motion_val[dir][xy ][0] = motion_x;
+ s->current_picture.f.motion_val[dir][xy ][1] = motion_y;
+ s->current_picture.f.motion_val[dir][xy + 1][0] = motion_x;
+ s->current_picture.f.motion_val[dir][xy + 1][1] = motion_y;
+ s->current_picture.f.ref_index [dir][b8_xy ] =
+ s->current_picture.f.ref_index [dir][b8_xy + 1] = s->field_select[dir][i];
+ assert(s->field_select[dir][i] == 0 || s->field_select[dir][i] == 1);
}
xy += wrap;
b8_xy +=2;
@@ -1805,25 +1756,25 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y,
MPV_decode_mb(s, s->block);
if (++s->mb_x >= s->mb_width) {
- const int mb_size= 16>>s->avctx->lowres;
+ const int mb_size = 16 >> s->avctx->lowres;
- ff_draw_horiz_band(s, mb_size*(s->mb_y>>field_pic), mb_size);
+ ff_draw_horiz_band(s, mb_size*(s->mb_y >> field_pic), mb_size);
MPV_report_decode_progress(s);
s->mb_x = 0;
- s->mb_y += 1<<field_pic;
+ s->mb_y += 1 << field_pic;
- if(s->mb_y >= s->mb_height){
- int left= get_bits_left(&s->gb);
- int is_d10= s->chroma_format==2 && s->pict_type==AV_PICTURE_TYPE_I && avctx->profile==0 && avctx->level==5
- && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0
- && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/;
+ if (s->mb_y >= s->mb_height) {
+ int left = get_bits_left(&s->gb);
+ int is_d10 = s->chroma_format == 2 && s->pict_type == AV_PICTURE_TYPE_I && avctx->profile == 0 && avctx->level == 5
+ && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0
+ && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/;
- if(left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10)
- || (avctx->error_recognition >= FF_ER_AGGRESSIVE && left>8)){
+ if (left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10)
+ || ((avctx->err_recognition & AV_EF_BUFFER) && left > 8)) {
av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23)));
return -1;
- }else
+ } else
goto eos;
}
@@ -1834,17 +1785,17 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y,
if (s->mb_skip_run == -1) {
/* read increment again */
s->mb_skip_run = 0;
- for(;;) {
+ for (;;) {
int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);
- if (code < 0){
+ if (code < 0) {
av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n");
return -1;
}
if (code >= 33) {
if (code == 33) {
s->mb_skip_run += 33;
- }else if(code == 35){
- if(s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0){
+ } else if (code == 35) {
+ if (s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0) {
av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n");
return -1;
}
@@ -1856,28 +1807,28 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y,
break;
}
}
- if(s->mb_skip_run){
+ if (s->mb_skip_run) {
int i;
- if(s->pict_type == AV_PICTURE_TYPE_I){
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
/* skip mb */
s->mb_intra = 0;
- for(i=0;i<12;i++)
+ for (i = 0; i < 12; i++)
s->block_last_index[i] = -1;
- if(s->picture_structure == PICT_FRAME)
+ if (s->picture_structure == PICT_FRAME)
s->mv_type = MV_TYPE_16X16;
else
s->mv_type = MV_TYPE_FIELD;
if (s->pict_type == AV_PICTURE_TYPE_P) {
/* if P type, zero motion vector is implied */
- s->mv_dir = MV_DIR_FORWARD;
- s->mv[0][0][0] = s->mv[0][0][1] = 0;
- s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0;
- s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0;
- s->field_select[0][0]= (s->picture_structure - 1) & 1;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv[0][0][0] = s->mv[0][0][1] = 0;
+ s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0;
+ s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0;
+ s->field_select[0][0] = (s->picture_structure - 1) & 1;
} else {
/* if B type, reuse previous vectors and directions */
s->mv[0][0][0] = s->last_mv[0][0][0];
@@ -1894,42 +1845,43 @@ eos: // end of slice
return 0;
}
-static int slice_decode_thread(AVCodecContext *c, void *arg){
- MpegEncContext *s= *(void**)arg;
- const uint8_t *buf= s->gb.buffer;
- int mb_y= s->start_mb_y;
- const int field_pic= s->picture_structure != PICT_FRAME;
+static int slice_decode_thread(AVCodecContext *c, void *arg)
+{
+ MpegEncContext *s = *(void**)arg;
+ const uint8_t *buf = s->gb.buffer;
+ int mb_y = s->start_mb_y;
+ const int field_pic = s->picture_structure != PICT_FRAME;
- s->error_count= (3*(s->end_mb_y - s->start_mb_y)*s->mb_width) >> field_pic;
+ s->error_count = (3 * (s->end_mb_y - s->start_mb_y) * s->mb_width) >> field_pic;
- for(;;){
+ for (;;) {
uint32_t start_code;
int ret;
- ret= mpeg_decode_slice((Mpeg1Context*)s, mb_y, &buf, s->gb.buffer_end - buf);
+ ret = mpeg_decode_slice(s, mb_y, &buf, s->gb.buffer_end - buf);
emms_c();
//av_log(c, AV_LOG_DEBUG, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%d\n",
//ret, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, s->start_mb_y, s->end_mb_y, s->error_count);
- if(ret < 0){
- if(s->resync_mb_x>=0 && s->resync_mb_y>=0)
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, AC_ERROR|DC_ERROR|MV_ERROR);
- }else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
+ if (ret < 0) {
+ if (c->err_recognition & AV_EF_EXPLODE)
+ return ret;
+ if (s->resync_mb_x >= 0 && s->resync_mb_y >= 0)
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
+ } else {
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
}
- if(s->mb_y == s->end_mb_y)
+ if (s->mb_y == s->end_mb_y)
return 0;
- start_code= -1;
- buf = ff_find_start_code(buf, s->gb.buffer_end, &start_code);
+ start_code = -1;
+ buf = avpriv_mpv_find_start_code(buf, s->gb.buffer_end, &start_code);
mb_y= (start_code - SLICE_MIN_START_CODE) << field_pic;
if (s->picture_structure == PICT_BOTTOM_FIELD)
mb_y++;
- if(mb_y < 0 || mb_y >= s->end_mb_y)
+ if (mb_y < 0 || mb_y >= s->end_mb_y)
return -1;
}
-
- return 0; //not reached
}
/**
@@ -1949,21 +1901,21 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict)
av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n");
}
- if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
+ if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
ff_xvmc_field_end(s);
/* end of slice reached */
- if (/*s->mb_y<<field_pic == s->mb_height &&*/ !s->first_field) {
+ if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field) {
/* end of image */
- s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_MPEG2;
+ s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_MPEG2;
ff_er_frame_end(s);
MPV_frame_end(s);
if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
- *pict= *(AVFrame*)s->current_picture_ptr;
+ *pict = *(AVFrame*)s->current_picture_ptr;
ff_print_debug_info(s, pict);
} else {
if (avctx->active_thread_type & FF_THREAD_FRAME)
@@ -1971,7 +1923,7 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict)
/* latency of 1 frame for I- and P-frames */
/* XXX: use another variable than picture_number */
if (s->last_picture_ptr != NULL) {
- *pict= *(AVFrame*)s->last_picture_ptr;
+ *pict = *(AVFrame*)s->last_picture_ptr;
ff_print_debug_info(s, pict);
}
}
@@ -1987,19 +1939,19 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
{
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
- int width,height;
+ int width, height;
int i, v, j;
init_get_bits(&s->gb, buf, buf_size*8);
- width = get_bits(&s->gb, 12);
+ width = get_bits(&s->gb, 12);
height = get_bits(&s->gb, 12);
if (width <= 0 || height <= 0)
return -1;
- s->aspect_ratio_info= get_bits(&s->gb, 4);
+ s->aspect_ratio_info = get_bits(&s->gb, 4);
if (s->aspect_ratio_info == 0) {
av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n");
- if (avctx->error_recognition >= FF_ER_COMPLIANT)
+ if (avctx->err_recognition & AV_EF_BITSTREAM)
return -1;
}
s->frame_rate_index = get_bits(&s->gb, 4);
@@ -2008,52 +1960,53 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
s->bit_rate = get_bits(&s->gb, 18) * 400;
if (get_bits1(&s->gb) == 0) /* marker */
return -1;
- s->width = width;
+ s->width = width;
s->height = height;
- s->avctx->rc_buffer_size= get_bits(&s->gb, 10) * 1024*16;
+ s->avctx->rc_buffer_size = get_bits(&s->gb, 10) * 1024 * 16;
skip_bits(&s->gb, 1);
/* get matrix */
if (get_bits1(&s->gb)) {
load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
} else {
- for(i=0;i<64;i++) {
+ for (i = 0; i < 64; i++) {
j = s->dsp.idct_permutation[i];
v = ff_mpeg1_default_intra_matrix[i];
- s->intra_matrix[j] = v;
+ s->intra_matrix[j] = v;
s->chroma_intra_matrix[j] = v;
}
}
if (get_bits1(&s->gb)) {
load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
} else {
- for(i=0;i<64;i++) {
- int j= s->dsp.idct_permutation[i];
+ for (i = 0; i < 64; i++) {
+ int j = s->dsp.idct_permutation[i];
v = ff_mpeg1_default_non_intra_matrix[i];
- s->inter_matrix[j] = v;
+ s->inter_matrix[j] = v;
s->chroma_inter_matrix[j] = v;
}
}
- if(show_bits(&s->gb, 23) != 0){
+ if (show_bits(&s->gb, 23) != 0) {
av_log(s->avctx, AV_LOG_ERROR, "sequence header damaged\n");
return -1;
}
/* we set MPEG-2 parameters so that it emulates MPEG-1 */
s->progressive_sequence = 1;
- s->progressive_frame = 1;
- s->picture_structure = PICT_FRAME;
+ s->progressive_frame = 1;
+ s->picture_structure = PICT_FRAME;
s->frame_pred_frame_dct = 1;
- s->chroma_format = 1;
- s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG1VIDEO;
- avctx->sub_id = 1; /* indicates MPEG-1 */
- s->out_format = FMT_MPEG1;
- s->swap_uv = 0;//AFAIK VCR2 does not have SEQ_HEADER
- if(s->flags & CODEC_FLAG_LOW_DELAY) s->low_delay=1;
-
- if(s->avctx->debug & FF_DEBUG_PICT_INFO)
+ s->chroma_format = 1;
+ s->codec_id = s->avctx->codec_id = CODEC_ID_MPEG1VIDEO;
+ avctx->sub_id = 1; /* indicates MPEG-1 */
+ s->out_format = FMT_MPEG1;
+ s->swap_uv = 0; // AFAIK VCR2 does not have SEQ_HEADER
+ if (s->flags & CODEC_FLAG_LOW_DELAY)
+ s->low_delay = 1;
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%d\n",
s->avctx->rc_buffer_size, s->bit_rate);
@@ -2073,41 +2026,41 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
}
s->width = avctx->coded_width;
s->height = avctx->coded_height;
- avctx->has_b_frames= 0; //true?
- s->low_delay= 1;
+ avctx->has_b_frames = 0; // true?
+ s->low_delay = 1;
avctx->pix_fmt = mpeg_get_pixelformat(avctx);
avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
- if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel ||
- s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU )
- if( avctx->idct_algo == FF_IDCT_AUTO )
+ if (avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel ||
+ s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+ if (avctx->idct_algo == FF_IDCT_AUTO)
avctx->idct_algo = FF_IDCT_SIMPLE;
if (MPV_common_init(s) < 0)
return -1;
- exchange_uv(s);//common init reset pblocks, so we swap them here
- s->swap_uv = 1;// in case of xvmc we need to swap uv for each MB
+ exchange_uv(s); // common init reset pblocks, so we swap them here
+ s->swap_uv = 1; // in case of xvmc we need to swap uv for each MB
s1->mpeg_enc_ctx_allocated = 1;
- for(i=0;i<64;i++) {
- int j= s->dsp.idct_permutation[i];
+ for (i = 0; i < 64; i++) {
+ int j = s->dsp.idct_permutation[i];
v = ff_mpeg1_default_intra_matrix[i];
- s->intra_matrix[j] = v;
+ s->intra_matrix[j] = v;
s->chroma_intra_matrix[j] = v;
v = ff_mpeg1_default_non_intra_matrix[i];
- s->inter_matrix[j] = v;
+ s->inter_matrix[j] = v;
s->chroma_inter_matrix[j] = v;
}
- s->progressive_sequence = 1;
- s->progressive_frame = 1;
- s->picture_structure = PICT_FRAME;
- s->frame_pred_frame_dct = 1;
- s->chroma_format = 1;
- s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG2VIDEO;
- avctx->sub_id = 2; /* indicates MPEG-2 */
+ s->progressive_sequence = 1;
+ s->progressive_frame = 1;
+ s->picture_structure = PICT_FRAME;
+ s->frame_pred_frame_dct = 1;
+ s->chroma_format = 1;
+ s->codec_id = s->avctx->codec_id = CODEC_ID_MPEG2VIDEO;
+ avctx->sub_id = 2; /* indicates MPEG-2 */
s1->save_width = s->width;
s1->save_height = s->height;
s1->save_progressive_seq = s->progressive_sequence;
@@ -2118,7 +2071,7 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
static void mpeg_decode_user_data(AVCodecContext *avctx,
const uint8_t *p, int buf_size)
{
- const uint8_t *buf_end = p+buf_size;
+ const uint8_t *buf_end = p + buf_size;
/* we parse the DTG active format information */
if (buf_end - p >= 5 &&
@@ -2138,8 +2091,9 @@ static void mpeg_decode_user_data(AVCodecContext *avctx,
}
static void mpeg_decode_gop(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size){
- Mpeg1Context *s1 = avctx->priv_data;
+ const uint8_t *buf, int buf_size)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
int time_code_hours, time_code_minutes;
@@ -2150,22 +2104,22 @@ static void mpeg_decode_gop(AVCodecContext *avctx,
skip_bits1(&s->gb); /* drop_frame_flag */
- time_code_hours=get_bits(&s->gb,5);
- time_code_minutes = get_bits(&s->gb,6);
- skip_bits1(&s->gb);//marker bit
- time_code_seconds = get_bits(&s->gb,6);
- time_code_pictures = get_bits(&s->gb,6);
+ time_code_hours = get_bits(&s->gb, 5);
+ time_code_minutes = get_bits(&s->gb, 6);
+ skip_bits1(&s->gb); // marker bit
+ time_code_seconds = get_bits(&s->gb, 6);
+ time_code_pictures = get_bits(&s->gb, 6);
- s->closed_gop = get_bits1(&s->gb);
+ s1->closed_gop = get_bits1(&s->gb);
/*broken_link indicate that after editing the
reference frames of the first B-Frames after GOP I-Frame
are missing (open gop)*/
broken_link = get_bits1(&s->gb);
- if(s->avctx->debug & FF_DEBUG_PICT_INFO)
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_DEBUG, "GOP (%2d:%02d:%02d.[%02d]) closed_gop=%d broken_link=%d\n",
- time_code_hours, time_code_minutes, time_code_seconds,
- time_code_pictures, s->closed_gop, broken_link);
+ time_code_hours, time_code_minutes, time_code_seconds,
+ time_code_pictures, s1->closed_gop, broken_link);
}
/**
* Find the end of the current frame in the bitstream.
@@ -2174,7 +2128,7 @@ static void mpeg_decode_gop(AVCodecContext *avctx,
int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s)
{
int i;
- uint32_t state= pc->state;
+ uint32_t state = pc->state;
/* EOF considered as end of frame */
if (buf_size == 0)
@@ -2188,49 +2142,51 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size,
4 searching end
*/
- for(i=0; i<buf_size; i++){
- assert(pc->frame_start_found>=0 && pc->frame_start_found<=4);
- if(pc->frame_start_found&1){
- if(state == EXT_START_CODE && (buf[i]&0xF0) != 0x80)
+ for (i = 0; i < buf_size; i++) {
+ assert(pc->frame_start_found >= 0 && pc->frame_start_found <= 4);
+ if (pc->frame_start_found & 1) {
+ if (state == EXT_START_CODE && (buf[i] & 0xF0) != 0x80)
pc->frame_start_found--;
- else if(state == EXT_START_CODE+2){
- if((buf[i]&3) == 3) pc->frame_start_found= 0;
- else pc->frame_start_found= (pc->frame_start_found+1)&3;
+ else if (state == EXT_START_CODE + 2) {
+ if ((buf[i] & 3) == 3)
+ pc->frame_start_found = 0;
+ else
+ pc->frame_start_found = (pc->frame_start_found + 1) & 3;
}
state++;
- }else{
- i= ff_find_start_code(buf+i, buf+buf_size, &state) - buf - 1;
- if(pc->frame_start_found==0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){
+ } else {
+ i = avpriv_mpv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1;
+ if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) {
i++;
- pc->frame_start_found=4;
+ pc->frame_start_found = 4;
}
- if(state == SEQ_END_CODE){
+ if (state == SEQ_END_CODE) {
pc->state=-1;
return i+1;
}
- if(pc->frame_start_found==2 && state == SEQ_START_CODE)
- pc->frame_start_found= 0;
- if(pc->frame_start_found<4 && state == EXT_START_CODE)
+ if (pc->frame_start_found == 2 && state == SEQ_START_CODE)
+ pc->frame_start_found = 0;
+ if (pc->frame_start_found < 4 && state == EXT_START_CODE)
pc->frame_start_found++;
- if(pc->frame_start_found == 4 && (state&0xFFFFFF00) == 0x100){
- if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){
- pc->frame_start_found=0;
- pc->state=-1;
- return i-3;
+ if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) {
+ if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) {
+ pc->frame_start_found = 0;
+ pc->state = -1;
+ return i - 3;
}
}
- if(pc->frame_start_found == 0 && s && state == PICTURE_START_CODE){
- ff_fetch_timestamp(s, i-3, 1);
+ if (pc->frame_start_found == 0 && s && state == PICTURE_START_CODE) {
+ ff_fetch_timestamp(s, i - 3, 1);
}
}
}
- pc->state= state;
+ pc->state = state;
return END_NOT_FOUND;
}
static int decode_chunks(AVCodecContext *avctx,
- AVFrame *picture, int *data_size,
- const uint8_t *buf, int buf_size);
+ AVFrame *picture, int *data_size,
+ const uint8_t *buf, int buf_size);
/* handle buffering and image synchronisation */
static int mpeg_decode_frame(AVCodecContext *avctx,
@@ -2246,102 +2202,94 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) {
/* special case for last picture */
- if (s2->low_delay==0 && s2->next_picture_ptr) {
- *picture= *(AVFrame*)s2->next_picture_ptr;
- s2->next_picture_ptr= NULL;
+ if (s2->low_delay == 0 && s2->next_picture_ptr) {
+ *picture = *(AVFrame*)s2->next_picture_ptr;
+ s2->next_picture_ptr = NULL;
*data_size = sizeof(AVFrame);
}
return buf_size;
}
- if(s2->flags&CODEC_FLAG_TRUNCATED){
- int next= ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL);
+ if (s2->flags & CODEC_FLAG_TRUNCATED) {
+ int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL);
- if( ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 )
+ if (ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0)
return buf_size;
}
-#if 0
- if (s->repeat_field % 2 == 1) {
- s->repeat_field++;
- //fprintf(stderr,"\nRepeating last frame: %d -> %d! pict: %d %d", avctx->frame_number-1, avctx->frame_number,
- // s2->picture_number, s->repeat_field);
- if (avctx->flags & CODEC_FLAG_REPEAT_FIELD) {
- *data_size = sizeof(AVPicture);
- goto the_end;
- }
- }
-#endif
-
- if(s->mpeg_enc_ctx_allocated==0 && avctx->codec_tag == AV_RL32("VCR2"))
+ if (s->mpeg_enc_ctx_allocated == 0 && avctx->codec_tag == AV_RL32("VCR2"))
vcr2_init_sequence(avctx);
- s->slice_count= 0;
+ s->slice_count = 0;
- if(avctx->extradata && !avctx->frame_number)
- decode_chunks(avctx, picture, data_size, avctx->extradata, avctx->extradata_size);
+ if (avctx->extradata && !avctx->frame_number) {
+ int ret = decode_chunks(avctx, picture, data_size, avctx->extradata, avctx->extradata_size);
+ if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
+ return ret;
+ }
return decode_chunks(avctx, picture, data_size, buf, buf_size);
}
static int decode_chunks(AVCodecContext *avctx,
- AVFrame *picture, int *data_size,
- const uint8_t *buf, int buf_size)
+ AVFrame *picture, int *data_size,
+ const uint8_t *buf, int buf_size)
{
Mpeg1Context *s = avctx->priv_data;
MpegEncContext *s2 = &s->mpeg_enc_ctx;
const uint8_t *buf_ptr = buf;
const uint8_t *buf_end = buf + buf_size;
int ret, input_size;
- int last_code= 0;
+ int last_code = 0;
- for(;;) {
+ for (;;) {
/* find next start code */
uint32_t start_code = -1;
- buf_ptr = ff_find_start_code(buf_ptr,buf_end, &start_code);
- if (start_code > 0x1ff){
- if(s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT){
- if(HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)){
+ buf_ptr = avpriv_mpv_find_start_code(buf_ptr, buf_end, &start_code);
+ if (start_code > 0x1ff) {
+ if (s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT) {
+ if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) {
int i;
avctx->execute(avctx, slice_decode_thread, &s2->thread_context[0], NULL, s->slice_count, sizeof(void*));
- for(i=0; i<s->slice_count; i++)
+ for (i = 0; i < s->slice_count; i++)
s2->error_count += s2->thread_context[i]->error_count;
}
- if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
+ if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);
if (slice_end(avctx, picture)) {
- if(s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
+ if (s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
*data_size = sizeof(AVPicture);
}
}
- s2->pict_type= 0;
+ s2->pict_type = 0;
return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);
}
input_size = buf_end - buf_ptr;
- if(avctx->debug & FF_DEBUG_STARTCODE){
+ if (avctx->debug & FF_DEBUG_STARTCODE) {
av_log(avctx, AV_LOG_DEBUG, "%3X at %td left %d\n", start_code, buf_ptr-buf, input_size);
}
/* prepare data for next start code */
- switch(start_code) {
+ switch (start_code) {
case SEQ_START_CODE:
- if(last_code == 0){
- mpeg1_decode_sequence(avctx, buf_ptr,
- input_size);
+ if (last_code == 0) {
+ mpeg1_decode_sequence(avctx, buf_ptr, input_size);
s->sync=1;
- }else{
+ } else {
av_log(avctx, AV_LOG_ERROR, "ignoring SEQ_START_CODE after %X\n", last_code);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
break;
case PICTURE_START_CODE:
- if (HAVE_THREADS && (avctx->active_thread_type&FF_THREAD_SLICE) && s->slice_count) {
+ if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) && s->slice_count) {
int i;
avctx->execute(avctx, slice_decode_thread,
@@ -2351,31 +2299,35 @@ static int decode_chunks(AVCodecContext *avctx,
s2->error_count += s2->thread_context[i]->error_count;
s->slice_count = 0;
}
- if(last_code == 0 || last_code == SLICE_MIN_START_CODE){
- if(mpeg_decode_postinit(avctx) < 0){
- av_log(avctx, AV_LOG_ERROR, "mpeg_decode_postinit() failure\n");
- return -1;
- }
+ if (last_code == 0 || last_code == SLICE_MIN_START_CODE) {
+ ret = mpeg_decode_postinit(avctx);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "mpeg_decode_postinit() failure\n");
+ return ret;
+ }
- /* we have a complete image: we try to decompress it */
- if(mpeg1_decode_picture(avctx,
- buf_ptr, input_size) < 0)
- s2->pict_type=0;
+ /* we have a complete image: we try to decompress it */
+ if (mpeg1_decode_picture(avctx, buf_ptr, input_size) < 0)
+ s2->pict_type = 0;
s2->first_slice = 1;
- last_code= PICTURE_START_CODE;
- }else{
+ last_code = PICTURE_START_CODE;
+ } else {
av_log(avctx, AV_LOG_ERROR, "ignoring pic after %X\n", last_code);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
break;
case EXT_START_CODE:
init_get_bits(&s2->gb, buf_ptr, input_size*8);
- switch(get_bits(&s2->gb, 4)) {
+ switch (get_bits(&s2->gb, 4)) {
case 0x1:
- if(last_code == 0){
+ if (last_code == 0) {
mpeg_decode_sequence_extension(s);
- }else{
+ } else {
av_log(avctx, AV_LOG_ERROR, "ignoring seq ext after %X\n", last_code);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
break;
case 0x2:
@@ -2388,112 +2340,119 @@ static int decode_chunks(AVCodecContext *avctx,
mpeg_decode_picture_display_extension(s);
break;
case 0x8:
- if(last_code == PICTURE_START_CODE){
- mpeg_decode_picture_coding_extension(s);
- }else{
+ if (last_code == PICTURE_START_CODE) {
+ mpeg_decode_picture_coding_extension(s);
+ } else {
av_log(avctx, AV_LOG_ERROR, "ignoring pic cod ext after %X\n", last_code);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
break;
}
break;
case USER_START_CODE:
- mpeg_decode_user_data(avctx,
- buf_ptr, input_size);
+ mpeg_decode_user_data(avctx, buf_ptr, input_size);
break;
case GOP_START_CODE:
- if(last_code == 0){
- s2->first_field=0;
- mpeg_decode_gop(avctx,
- buf_ptr, input_size);
+ if (last_code == 0) {
+ s2->first_field=0;
+ mpeg_decode_gop(avctx, buf_ptr, input_size);
s->sync=1;
- }else{
+ } else {
av_log(avctx, AV_LOG_ERROR, "ignoring GOP_START_CODE after %X\n", last_code);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
break;
default:
if (start_code >= SLICE_MIN_START_CODE &&
- start_code <= SLICE_MAX_START_CODE && last_code!=0) {
- const int field_pic= s2->picture_structure != PICT_FRAME;
- int mb_y= (start_code - SLICE_MIN_START_CODE) << field_pic;
- last_code= SLICE_MIN_START_CODE;
+ start_code <= SLICE_MAX_START_CODE && last_code != 0) {
+ const int field_pic = s2->picture_structure != PICT_FRAME;
+ int mb_y = (start_code - SLICE_MIN_START_CODE) << field_pic;
+ last_code = SLICE_MIN_START_CODE;
- if(s2->picture_structure == PICT_BOTTOM_FIELD)
+ if (s2->picture_structure == PICT_BOTTOM_FIELD)
mb_y++;
- if (mb_y >= s2->mb_height){
+ if (mb_y >= s2->mb_height) {
av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height);
return -1;
}
- if(s2->last_picture_ptr==NULL){
+ if (s2->last_picture_ptr == NULL) {
/* Skip B-frames if we do not have reference frames and gop is not closed */
- if(s2->pict_type==AV_PICTURE_TYPE_B){
- if(!s2->closed_gop)
+ if (s2->pict_type == AV_PICTURE_TYPE_B) {
+ if (!s->closed_gop)
break;
}
}
- if(s2->pict_type==AV_PICTURE_TYPE_I)
+ if (s2->pict_type == AV_PICTURE_TYPE_I)
s->sync=1;
- if(s2->next_picture_ptr==NULL){
+ if (s2->next_picture_ptr == NULL) {
/* Skip P-frames if we do not have a reference frame or we have an invalid header. */
- if(s2->pict_type==AV_PICTURE_TYPE_P && !s->sync) break;
+ if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) break;
}
- if( (avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type==AV_PICTURE_TYPE_B)
- ||(avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type!=AV_PICTURE_TYPE_I)
- || avctx->skip_frame >= AVDISCARD_ALL)
+ if ((avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type == AV_PICTURE_TYPE_B) ||
+ (avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type != AV_PICTURE_TYPE_I) ||
+ avctx->skip_frame >= AVDISCARD_ALL)
break;
- if (!s->mpeg_enc_ctx_allocated) break;
+ if (!s->mpeg_enc_ctx_allocated)
+ break;
- if(s2->codec_id == CODEC_ID_MPEG2VIDEO){
- if(mb_y < avctx->skip_top || mb_y >= s2->mb_height - avctx->skip_bottom)
+ if (s2->codec_id == CODEC_ID_MPEG2VIDEO) {
+ if (mb_y < avctx->skip_top || mb_y >= s2->mb_height - avctx->skip_bottom)
break;
}
- if(!s2->pict_type){
+ if (!s2->pict_type) {
av_log(avctx, AV_LOG_ERROR, "Missing picture start code\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
break;
}
- if(s2->first_slice){
- s2->first_slice=0;
- if(mpeg_field_start(s2, buf, buf_size) < 0)
+ if (s2->first_slice) {
+ s2->first_slice = 0;
+ if (mpeg_field_start(s2, buf, buf_size) < 0)
return -1;
}
- if(!s2->current_picture_ptr){
+ if (!s2->current_picture_ptr) {
av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
- if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
+ if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
s->slice_count++;
break;
}
- if(HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)){
- int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count;
- if(threshold <= mb_y){
- MpegEncContext *thread_context= s2->thread_context[s->slice_count];
+ if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) {
+ int threshold= (s2->mb_height * s->slice_count + avctx->thread_count / 2) / avctx->thread_count;
+ if (threshold <= mb_y) {
+ MpegEncContext *thread_context = s2->thread_context[s->slice_count];
- thread_context->start_mb_y= mb_y;
- thread_context->end_mb_y = s2->mb_height;
- if(s->slice_count){
- s2->thread_context[s->slice_count-1]->end_mb_y= mb_y;
+ thread_context->start_mb_y = mb_y;
+ thread_context->end_mb_y = s2->mb_height;
+ if (s->slice_count) {
+ s2->thread_context[s->slice_count-1]->end_mb_y = mb_y;
ff_update_duplicate_context(thread_context, s2);
}
init_get_bits(&thread_context->gb, buf_ptr, input_size*8);
s->slice_count++;
}
- buf_ptr += 2; //FIXME add minimum number of bytes per slice
- }else{
- ret = mpeg_decode_slice(s, mb_y, &buf_ptr, input_size);
+ buf_ptr += 2; // FIXME add minimum number of bytes per slice
+ } else {
+ ret = mpeg_decode_slice(s2, mb_y, &buf_ptr, input_size);
emms_c();
- if(ret < 0){
- if(s2->resync_mb_x>=0 && s2->resync_mb_y>=0)
- ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, AC_ERROR|DC_ERROR|MV_ERROR);
- }else{
- ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, AC_END|DC_END|MV_END);
+ if (ret < 0) {
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return ret;
+ if (s2->resync_mb_x >= 0 && s2->resync_mb_y >= 0)
+ ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
+ } else {
+ ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
}
}
}
@@ -2502,10 +2461,12 @@ static int decode_chunks(AVCodecContext *avctx,
}
}
-static void flush(AVCodecContext *avctx){
+static void flush(AVCodecContext *avctx)
+{
Mpeg1Context *s = avctx->priv_data;
s->sync=0;
+ s->closed_gop = 0;
ff_mpeg_flush(avctx);
}
@@ -2533,115 +2494,95 @@ static const AVProfile mpeg2_video_profiles[] = {
AVCodec ff_mpeg1video_decoder = {
- "mpeg1video",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG1VIDEO,
- sizeof(Mpeg1Context),
- mpeg_decode_init,
- NULL,
- mpeg_decode_end,
- mpeg_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
- .flush= flush,
- .max_lowres= 3,
- .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"),
- .update_thread_context= ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context)
+ .name = "mpeg1video",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG1VIDEO,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
+ .flush = flush,
+ .max_lowres = 3,
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context)
};
AVCodec ff_mpeg2video_decoder = {
- "mpeg2video",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG2VIDEO,
- sizeof(Mpeg1Context),
- mpeg_decode_init,
- NULL,
- mpeg_decode_end,
- mpeg_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
- .flush= flush,
- .max_lowres= 3,
- .long_name= NULL_IF_CONFIG_SMALL("MPEG-2 video"),
- .profiles = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
-};
-
-//legacy decoder
-AVCodec ff_mpegvideo_decoder = {
- "mpegvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG2VIDEO,
- sizeof(Mpeg1Context),
- mpeg_decode_init,
- NULL,
- mpeg_decode_end,
- mpeg_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
- .flush= flush,
- .max_lowres= 3,
- .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"),
+ .name = "mpeg2video",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG2VIDEO,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
+ .flush = flush,
+ .max_lowres = 3,
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"),
+ .profiles = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
};
#if CONFIG_MPEG_XVMC_DECODER
-static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx){
- if( avctx->active_thread_type & FF_THREAD_SLICE )
+static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx)
+{
+ if (avctx->active_thread_type & FF_THREAD_SLICE)
return -1;
- if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) )
+ if (!(avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
return -1;
- if( !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD) ){
+ if (!(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {
av_dlog(avctx, "mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n");
}
mpeg_decode_init(avctx);
- avctx->pix_fmt = PIX_FMT_XVMC_MPEG2_IDCT;
- avctx->xvmc_acceleration = 2;//2 - the blocks are packed!
+ avctx->pix_fmt = PIX_FMT_XVMC_MPEG2_IDCT;
+ avctx->xvmc_acceleration = 2; // 2 - the blocks are packed!
return 0;
}
AVCodec ff_mpeg_xvmc_decoder = {
- "mpegvideo_xvmc",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG2VIDEO_XVMC,
- sizeof(Mpeg1Context),
- mpeg_mc_decode_init,
- NULL,
- mpeg_decode_end,
- mpeg_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL | CODEC_CAP_DELAY,
- .flush= flush,
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
+ .name = "mpegvideo_xvmc",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG2VIDEO_XVMC,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_mc_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL | CODEC_CAP_DELAY,
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
};
#endif
#if CONFIG_MPEG_VDPAU_DECODER
AVCodec ff_mpeg_vdpau_decoder = {
- "mpegvideo_vdpau",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG2VIDEO,
- sizeof(Mpeg1Context),
- mpeg_decode_init,
- NULL,
- mpeg_decode_end,
- mpeg_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
- .flush= flush,
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
+ .name = "mpegvideo_vdpau",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG2VIDEO,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
};
#endif
#if CONFIG_MPEG1_VDPAU_DECODER
AVCodec ff_mpeg1_vdpau_decoder = {
- "mpeg1video_vdpau",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG1VIDEO,
- sizeof(Mpeg1Context),
- mpeg_decode_init,
- NULL,
- mpeg_decode_end,
- mpeg_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
- .flush= flush,
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"),
+ .name = "mpeg1video_vdpau",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG1VIDEO,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"),
};
#endif
diff --git a/libavcodec/mpeg12.h b/libavcodec/mpeg12.h
index 4c55726..ab0352f 100644
--- a/libavcodec/mpeg12.h
+++ b/libavcodec/mpeg12.h
@@ -30,6 +30,20 @@
extern VLC ff_dc_lum_vlc;
extern VLC ff_dc_chroma_vlc;
+typedef struct Mpeg1Context {
+ MpegEncContext mpeg_enc_ctx;
+ int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
+ int repeat_field; /* true if we must repeat the field */
+ AVPanScan pan_scan; /**< some temporary storage for the panscan */
+ int slice_count;
+ int swap_uv;//indicate VCR2
+ int save_aspect_info;
+ int save_width, save_height, save_progressive_seq;
+ AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator
+ int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame?
+ int closed_gop; ///< GOP is closed
+} Mpeg1Context;
+
extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
void ff_mpeg12_common_init(MpegEncContext *s);
diff --git a/libavcodec/mpeg12data.c b/libavcodec/mpeg12data.c
index 299215f..5ac8c24 100644
--- a/libavcodec/mpeg12data.c
+++ b/libavcodec/mpeg12data.c
@@ -305,7 +305,7 @@ const uint8_t ff_mpeg12_mbMotionVectorTable[17][2] = {
{ 0xc, 10 },
};
-const AVRational ff_frame_rate_tab[] = {
+const AVRational avpriv_frame_rate_tab[] = {
{ 0, 0},
{24000, 1001},
{ 24, 1},
diff --git a/libavcodec/mpeg12data.h b/libavcodec/mpeg12data.h
index 3586a61..86ba3ec 100644
--- a/libavcodec/mpeg12data.h
+++ b/libavcodec/mpeg12data.h
@@ -48,7 +48,7 @@ extern const uint8_t ff_mpeg12_mbPatTable[64][2];
extern const uint8_t ff_mpeg12_mbMotionVectorTable[17][2];
-extern const AVRational ff_frame_rate_tab[];
+extern const AVRational avpriv_frame_rate_tab[];
extern const float ff_mpeg1_aspect[16];
extern const AVRational ff_mpeg2_aspect[16];
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index eb07ecf..17097db 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -27,12 +27,15 @@
#include "avcodec.h"
#include "dsputil.h"
+#include "mathops.h"
#include "mpegvideo.h"
#include "mpeg12.h"
#include "mpeg12data.h"
#include "bytestream.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
static const uint8_t inv_non_linear_qscale[13] = {
0, 2, 4, 6, 8,
@@ -71,11 +74,12 @@ static void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len){
for(i=0; i<128; i++){
int level= i-64;
int run;
+ if (!level)
+ continue;
for(run=0; run<64; run++){
- int len, bits, code;
+ int len, code;
int alevel= FFABS(level);
- int sign= (level>>31)&1;
if (alevel > rl->max_level[0][run])
code= 111; /*rl->n*/
@@ -83,25 +87,15 @@ static void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len){
code= rl->index_run[0][run] + alevel - 1;
if (code < 111 /* rl->n */) {
- /* store the vlc & sign at once */
+ /* length of vlc and sign */
len= rl->table_vlc[code][1]+1;
- bits= (rl->table_vlc[code][0]<<1) + sign;
} else {
len= rl->table_vlc[111/*rl->n*/][1]+6;
- bits= rl->table_vlc[111/*rl->n*/][0]<<6;
- bits|= run;
if (alevel < 128) {
- bits<<=8; len+=8;
- bits|= level & 0xff;
+ len += 8;
} else {
- bits<<=16; len+=16;
- bits|= level & 0xff;
- if (level < 0) {
- bits|= 0x8001 + level + 255;
- } else {
- bits|= level & 0xffff;
- }
+ len += 16;
}
}
@@ -117,7 +111,7 @@ static int find_frame_rate_index(MpegEncContext *s){
int64_t d;
for(i=1;i<14;i++) {
- int64_t n0= 1001LL/ff_frame_rate_tab[i].den*ff_frame_rate_tab[i].num*s->avctx->time_base.num;
+ int64_t n0= 1001LL/avpriv_frame_rate_tab[i].den*avpriv_frame_rate_tab[i].num*s->avctx->time_base.num;
int64_t n1= 1001LL*s->avctx->time_base.den;
if(s->avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL && i>=9) break;
@@ -140,6 +134,13 @@ static av_cold int encode_init(AVCodecContext *avctx)
if(MPV_encode_init(avctx) < 0)
return -1;
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+ if (avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE)
+ s->drop_frame_timecode = 1;
+ if (avctx->flags & CODEC_FLAG_SVCD_SCAN_OFFSET)
+ s->scan_offset = 1;
+#endif
+
if(find_frame_rate_index(s) < 0){
if(s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", avctx->time_base.den, avctx->time_base.num);
@@ -172,7 +173,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
}
}
- if((avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) && s->frame_rate_index != 4){
+ if (s->drop_frame_timecode && s->frame_rate_index != 4) {
av_log(avctx, AV_LOG_ERROR, "Drop frame time code only allowed with 1001/30000 fps\n");
return -1;
}
@@ -182,7 +183,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
static void put_header(MpegEncContext *s, int header)
{
- align_put_bits(&s->pb);
+ avpriv_align_put_bits(&s->pb);
put_bits(&s->pb, 16, header>>16);
put_sbits(&s->pb, 16, header);
}
@@ -200,8 +201,8 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
if(aspect_ratio==0.0) aspect_ratio= 1.0; //pixel aspect 1:1 (VGA)
- if (s->current_picture.key_frame) {
- AVRational framerate= ff_frame_rate_tab[s->frame_rate_index];
+ if (s->current_picture.f.key_frame) {
+ AVRational framerate= avpriv_frame_rate_tab[s->frame_rate_index];
/* mpeg1 header repeated every gop */
put_header(s, SEQ_START_CODE);
@@ -283,14 +284,14 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
}
put_header(s, GOP_START_CODE);
- put_bits(&s->pb, 1, !!(s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE)); /* drop frame flag */
+ put_bits(&s->pb, 1, s->drop_frame_timecode); /* drop frame flag */
/* time code : we must convert from the real frame rate to a
fake mpeg frame rate in case of low frame rate */
fps = (framerate.num + framerate.den/2)/ framerate.den;
- time_code = s->current_picture_ptr->coded_picture_number + s->avctx->timecode_frame_start;
+ time_code = s->current_picture_ptr->f.coded_picture_number + s->avctx->timecode_frame_start;
- s->gop_picture_number = s->current_picture_ptr->coded_picture_number;
- if (s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) {
+ s->gop_picture_number = s->current_picture_ptr->f.coded_picture_number;
+ if (s->drop_frame_timecode) {
/* only works for NTSC 29.97 */
int d = time_code / 17982;
int m = time_code % 17982;
@@ -396,7 +397,7 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
if (s->progressive_sequence) {
put_bits(&s->pb, 1, 0); /* no repeat */
} else {
- put_bits(&s->pb, 1, s->current_picture_ptr->top_field_first);
+ put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first);
}
/* XXX: optimize the generation of this flag with entropy
measures */
@@ -413,7 +414,7 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
put_bits(&s->pb, 1, s->progressive_frame);
put_bits(&s->pb, 1, 0); //composite_display_flag
}
- if(s->flags & CODEC_FLAG_SVCD_SCAN_OFFSET){
+ if (s->scan_offset) {
int i;
put_header(s, USER_START_CODE);
@@ -681,8 +682,7 @@ static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code)
int bit_size = f_or_b_code - 1;
int range = 1 << bit_size;
/* modulo encoding */
- int l= INT_BIT - 5 - bit_size;
- val= (val<<l)>>l;
+ val = sign_extend(val, 5 + bit_size);
if (val >= 0) {
val--;
@@ -925,30 +925,62 @@ static void mpeg1_encode_block(MpegEncContext *s,
put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]);
}
+#define OFFSET(x) offsetof(MpegEncContext, x)
+#define VE AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
+#define COMMON_OPTS\
+ { "intra_vlc", "Use MPEG-2 intra VLC table.", OFFSET(intra_vlc_format), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },\
+ { "drop_frame_timecode", "Timecode is in drop frame format.", OFFSET(drop_frame_timecode), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE}, \
+ { "scan_offset", "Reserve space for SVCD scan offset user data.", OFFSET(scan_offset), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+
+static const AVOption mpeg1_options[] = {
+ COMMON_OPTS
+ { NULL },
+};
+
+static const AVOption mpeg2_options[] = {
+ COMMON_OPTS
+ { "non_linear_quant", "Use nonlinear quantizer.", OFFSET(q_scale_type), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { NULL },
+};
+
+#define mpeg12_class(x)\
+static const AVClass mpeg## x ##_class = {\
+ .class_name = "mpeg" #x "video encoder",\
+ .item_name = av_default_item_name,\
+ .option = mpeg## x ##_options,\
+ .version = LIBAVUTIL_VERSION_INT,\
+};
+
+mpeg12_class(1)
+mpeg12_class(2)
+
AVCodec ff_mpeg1video_encoder = {
- "mpeg1video",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG1VIDEO,
- sizeof(MpegEncContext),
- encode_init,
- MPV_encode_picture,
- MPV_encode_end,
- .supported_framerates= ff_frame_rate_tab+1,
+ .name = "mpeg1video",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG1VIDEO,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
+ .supported_framerates= avpriv_frame_rate_tab+1,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.capabilities= CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"),
+ .priv_class = &mpeg1_class,
};
AVCodec ff_mpeg2video_encoder = {
- "mpeg2video",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG2VIDEO,
- sizeof(MpegEncContext),
- encode_init,
- MPV_encode_picture,
- MPV_encode_end,
- .supported_framerates= ff_frame_rate_tab+1,
+ .name = "mpeg2video",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG2VIDEO,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
+ .supported_framerates= avpriv_frame_rate_tab+1,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE},
.capabilities= CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-2 video"),
+ .priv_class = &mpeg2_class,
};
diff --git a/libavcodec/mpeg4audio.c b/libavcodec/mpeg4audio.c
index f0399af..0fb9b96 100644
--- a/libavcodec/mpeg4audio.c
+++ b/libavcodec/mpeg4audio.c
@@ -52,7 +52,7 @@ static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c)
return 0;
}
-const int ff_mpeg4audio_sample_rates[16] = {
+const int avpriv_mpeg4audio_sample_rates[16] = {
96000, 88200, 64000, 48000, 44100, 32000,
24000, 22050, 16000, 12000, 11025, 8000, 7350
};
@@ -73,15 +73,16 @@ static inline int get_sample_rate(GetBitContext *gb, int *index)
{
*index = get_bits(gb, 4);
return *index == 0x0f ? get_bits(gb, 24) :
- ff_mpeg4audio_sample_rates[*index];
+ avpriv_mpeg4audio_sample_rates[*index];
}
-int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size)
+int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
+ int bit_size, int sync_extension)
{
GetBitContext gb;
int specific_config_bitindex;
- init_get_bits(&gb, buf, buf_size*8);
+ init_get_bits(&gb, buf, bit_size);
c->object_type = get_object_type(&gb);
c->sample_rate = get_sample_rate(&gb, &c->sampling_index);
c->chan_config = get_bits(&gb, 4);
@@ -117,7 +118,7 @@ int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_si
return -1;
}
- if (c->ext_object_type != AOT_SBR) {
+ if (c->ext_object_type != AOT_SBR && sync_extension) {
while (get_bits_left(&gb) > 15) {
if (show_bits(&gb, 11) == 0x2b7) { // sync extension
get_bits(&gb, 11);
@@ -151,7 +152,7 @@ static av_always_inline unsigned int copy_bits(PutBitContext *pb,
return el;
}
-int ff_copy_pce_data(PutBitContext *pb, GetBitContext *gb)
+int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb)
{
int five_bit_ch, four_bit_ch, comment_size, bits;
int offset = put_bits_count(pb);
@@ -173,7 +174,7 @@ int ff_copy_pce_data(PutBitContext *pb, GetBitContext *gb)
copy_bits(pb, gb, 16);
if (bits)
copy_bits(pb, gb, bits);
- align_put_bits(pb);
+ avpriv_align_put_bits(pb);
align_get_bits(gb);
comment_size = copy_bits(pb, gb, 8);
for (; comment_size > 0; comment_size--)
diff --git a/libavcodec/mpeg4audio.h b/libavcodec/mpeg4audio.h
index 2d2b4a2..7560f3f 100644
--- a/libavcodec/mpeg4audio.h
+++ b/libavcodec/mpeg4audio.h
@@ -31,25 +31,28 @@ typedef struct {
int sampling_index;
int sample_rate;
int chan_config;
- int sbr; //< -1 implicit, 1 presence
+ int sbr; ///< -1 implicit, 1 presence
int ext_object_type;
int ext_sampling_index;
int ext_sample_rate;
int ext_chan_config;
int channels;
- int ps; //< -1 implicit, 1 presence
+ int ps; ///< -1 implicit, 1 presence
} MPEG4AudioConfig;
-extern const int ff_mpeg4audio_sample_rates[16];
+extern const int avpriv_mpeg4audio_sample_rates[16];
extern const uint8_t ff_mpeg4audio_channels[8];
+
/**
* Parse MPEG-4 systems extradata to retrieve audio configuration.
* @param[in] c MPEG4AudioConfig structure to fill.
* @param[in] buf Extradata from container.
- * @param[in] buf_size Extradata size.
+ * @param[in] bit_size Extradata size in bits.
+ * @param[in] sync_extension look for a sync extension after config if true.
* @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata.
*/
-int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size);
+int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
+ int bit_size, int sync_extension);
enum AudioObjectType {
AOT_NULL,
@@ -101,6 +104,6 @@ enum AudioObjectType {
#define MAX_PCE_SIZE 304 ///<Maximum size of a PCE including the 3-bit ID_PCE
///<marker and the comment
-int ff_copy_pce_data(PutBitContext *pb, GetBitContext *gb);
+int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb);
#endif /* AVCODEC_MPEG4AUDIO_H */
diff --git a/libavcodec/mpeg4video.c b/libavcodec/mpeg4video.c
index a4dc80a..130e9b2 100644
--- a/libavcodec/mpeg4video.c
+++ b/libavcodec/mpeg4video.c
@@ -89,7 +89,7 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my,
uint16_t time_pb= s->pb_time;
int p_mx, p_my;
- p_mx= s->next_picture.motion_val[0][xy][0];
+ p_mx = s->next_picture.f.motion_val[0][xy][0];
if((unsigned)(p_mx + tab_bias) < tab_size){
s->mv[0][i][0] = s->direct_scale_mv[0][p_mx + tab_bias] + mx;
s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx
@@ -99,7 +99,7 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my,
s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx
: p_mx*(time_pb - time_pp)/time_pp;
}
- p_my= s->next_picture.motion_val[0][xy][1];
+ p_my = s->next_picture.f.motion_val[0][xy][1];
if((unsigned)(p_my + tab_bias) < tab_size){
s->mv[0][i][1] = s->direct_scale_mv[0][p_my + tab_bias] + my;
s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my
@@ -120,7 +120,7 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my,
*/
int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){
const int mb_index= s->mb_x + s->mb_y*s->mb_stride;
- const int colocated_mb_type= s->next_picture.mb_type[mb_index];
+ const int colocated_mb_type = s->next_picture.f.mb_type[mb_index];
uint16_t time_pp;
uint16_t time_pb;
int i;
@@ -137,7 +137,7 @@ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){
} else if(IS_INTERLACED(colocated_mb_type)){
s->mv_type = MV_TYPE_FIELD;
for(i=0; i<2; i++){
- int field_select= s->next_picture.ref_index[0][4*mb_index + 2*i];
+ int field_select = s->next_picture.f.ref_index[0][4 * mb_index + 2 * i];
s->field_select[0][i]= field_select;
s->field_select[1][i]= i;
if(s->top_field_first){
diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index d34e731..ba67c21 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -119,7 +119,7 @@ extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3];
/**
- * predicts the dc.
+ * Predict the dc.
* encoding quantized level -> quantized diff
* decoding quantized diff -> quantized level
* @param n block index (0-3 are luma, 4-5 are chroma)
@@ -174,7 +174,7 @@ static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *di
}else{
level += pred;
ret= level;
- if(s->error_recognition>=3){
+ if(s->err_recognition&AV_EF_BITSTREAM){
if(level<0){
av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
return -1;
diff --git a/libavcodec/mpeg4video_parser.c b/libavcodec/mpeg4video_parser.c
index 2e498d1..162bc1d 100644
--- a/libavcodec/mpeg4video_parser.c
+++ b/libavcodec/mpeg4video_parser.c
@@ -130,10 +130,10 @@ static int mpeg4video_parse(AVCodecParserContext *s,
AVCodecParser ff_mpeg4video_parser = {
- { CODEC_ID_MPEG4 },
- sizeof(ParseContext1),
- mpeg4video_parse_init,
- mpeg4video_parse,
- ff_parse1_close,
- ff_mpeg4video_split,
+ .codec_ids = { CODEC_ID_MPEG4 },
+ .priv_data_size = sizeof(ParseContext1),
+ .parser_init = mpeg4video_parse_init,
+ .parser_parse = mpeg4video_parse,
+ .parser_close = ff_parse1_close,
+ .split = ff_mpeg4video_split,
};
diff --git a/libavcodec/mpeg4video_parser.h b/libavcodec/mpeg4video_parser.h
index d907dc4..0f56e7f 100644
--- a/libavcodec/mpeg4video_parser.h
+++ b/libavcodec/mpeg4video_parser.h
@@ -26,7 +26,7 @@
#include "parser.h"
/**
- * finds the end of the current frame in the bitstream.
+ * Find the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size);
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 22d7ace..e15c348 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -46,7 +46,7 @@ static const int mb_type_b_map[4]= {
};
/**
- * predicts the ac.
+ * Predict the ac.
* @param n block index (0-3 are luma, 4-5 are chroma)
* @param dir the ac prediction direction
*/
@@ -55,7 +55,7 @@ void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n,
{
int i;
int16_t *ac_val, *ac_val1;
- int8_t * const qscale_table= s->current_picture.qscale_table;
+ int8_t * const qscale_table = s->current_picture.f.qscale_table;
/* find prediction */
ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
@@ -343,7 +343,7 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb
}
/**
- * decodes the next video packet.
+ * Decode the next video packet.
* @return <0 if something went wrong
*/
int mpeg4_decode_video_packet_header(MpegEncContext *s)
@@ -376,7 +376,7 @@ int mpeg4_decode_video_packet_header(MpegEncContext *s)
if(s->pict_type == AV_PICTURE_TYPE_B){
int mb_x = 0, mb_y = 0;
- while(s->next_picture.mbskip_table[ s->mb_index2xy[ mb_num ] ]) {
+ while (s->next_picture.f.mbskip_table[s->mb_index2xy[mb_num]]) {
if (!mb_x) ff_thread_await_progress((AVFrame*)s->next_picture_ptr, mb_y++, 0);
mb_num++;
if (++mb_x == s->mb_width) mb_x = 0;
@@ -439,7 +439,7 @@ int mpeg4_decode_video_packet_header(MpegEncContext *s)
}
/**
- * gets the average motion vector for a GMC MB.
+ * Get the average motion vector for a GMC MB.
* @param n either 0 for the x component or 1 for y
* @return the average MV for a GMC MB
*/
@@ -485,7 +485,7 @@ static inline int get_amv(MpegEncContext *s, int n){
}
/**
- * decodes the dc value.
+ * Decode the dc value.
* @param n block index (0-3 are luma, 4-5 are chroma)
* @param dir_ptr the prediction direction will be stored here
* @return the quantized dc
@@ -520,7 +520,7 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
if (code > 8){
if(get_bits1(&s->gb)==0){ /* marker */
- if(s->error_recognition>=2){
+ if(s->err_recognition&AV_EF_BITSTREAM){
av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n");
return -1;
}
@@ -532,7 +532,7 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
}
/**
- * decodes first partition.
+ * Decode first partition.
* @return number of MBs decoded or <0 if an error occurred
*/
static int mpeg4_decode_partition_a(MpegEncContext *s){
@@ -570,13 +570,13 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){
}while(cbpc == 8);
s->cbp_table[xy]= cbpc & 3;
- s->current_picture.mb_type[xy]= MB_TYPE_INTRA;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
s->mb_intra = 1;
if(cbpc & 4) {
ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
}
- s->current_picture.qscale_table[xy]= s->qscale;
+ s->current_picture.f.qscale_table[xy]= s->qscale;
s->mbintra_table[xy]= 1;
for(i=0; i<6; i++){
@@ -592,7 +592,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){
s->pred_dir_table[xy]= dir;
}else{ /* P/S_TYPE */
int mx, my, pred_x, pred_y, bits;
- int16_t * const mot_val= s->current_picture.motion_val[0][s->block_index[0]];
+ int16_t * const mot_val = s->current_picture.f.motion_val[0][s->block_index[0]];
const int stride= s->b8_stride*2;
try_again:
@@ -604,11 +604,11 @@ try_again:
if(bits&0x10000){
/* skip mb */
if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){
- s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0;
mx= get_amv(s, 0);
my= get_amv(s, 1);
}else{
- s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
mx=my=0;
}
mot_val[0 ]= mot_val[2 ]=
@@ -634,7 +634,7 @@ try_again:
s->mb_intra = ((cbpc & 4) != 0);
if(s->mb_intra){
- s->current_picture.mb_type[xy]= MB_TYPE_INTRA;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
s->mbintra_table[xy]= 1;
mot_val[0 ]= mot_val[2 ]=
mot_val[0+stride]= mot_val[2+stride]= 0;
@@ -660,11 +660,11 @@ try_again:
my = h263_decode_motion(s, pred_y, s->f_code);
if (my >= 0xffff)
return -1;
- s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
} else {
mx = get_amv(s, 0);
my = get_amv(s, 1);
- s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0;
}
mot_val[0 ]= mot_val[2 ] =
@@ -673,7 +673,7 @@ try_again:
mot_val[1+stride]= mot_val[3+stride]= my;
} else {
int i;
- s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
for(i=0;i<4;i++) {
int16_t *mot_val= h263_pred_motion(s, i, 0, &pred_x, &pred_y);
mx = h263_decode_motion(s, pred_x, s->f_code);
@@ -725,9 +725,9 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
}
s->cbp_table[xy]|= cbpy<<2;
- s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
+ s->current_picture.f.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
}else{ /* P || S_TYPE */
- if(IS_INTRA(s->current_picture.mb_type[xy])){
+ if (IS_INTRA(s->current_picture.f.mb_type[xy])) {
int dir=0,i;
int ac_pred = get_bits1(&s->gb);
int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
@@ -740,7 +740,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
if(s->cbp_table[xy] & 8) {
ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
}
- s->current_picture.qscale_table[xy]= s->qscale;
+ s->current_picture.f.qscale_table[xy] = s->qscale;
for(i=0; i<6; i++){
int dc_pred_dir;
@@ -754,10 +754,10 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
}
s->cbp_table[xy]&= 3; //remove dquant
s->cbp_table[xy]|= cbpy<<2;
- s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
+ s->current_picture.f.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
s->pred_dir_table[xy]= dir;
- }else if(IS_SKIP(s->current_picture.mb_type[xy])){
- s->current_picture.qscale_table[xy]= s->qscale;
+ } else if (IS_SKIP(s->current_picture.f.mb_type[xy])) {
+ s->current_picture.f.qscale_table[xy] = s->qscale;
s->cbp_table[xy]= 0;
}else{
int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
@@ -770,7 +770,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
if(s->cbp_table[xy] & 8) {
ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
}
- s->current_picture.qscale_table[xy]= s->qscale;
+ s->current_picture.f.qscale_table[xy] = s->qscale;
s->cbp_table[xy]&= 3; //remove dquant
s->cbp_table[xy]|= (cbpy^0xf)<<2;
@@ -784,14 +784,14 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
}
/**
- * decodes the first & second partition
+ * Decode the first and second partition.
* @return <0 if error (and sets error type in the error_status_table)
*/
int ff_mpeg4_decode_partitions(MpegEncContext *s)
{
int mb_num;
- const int part_a_error= s->pict_type==AV_PICTURE_TYPE_I ? (DC_ERROR|MV_ERROR) : MV_ERROR;
- const int part_a_end = s->pict_type==AV_PICTURE_TYPE_I ? (DC_END |MV_END) : MV_END;
+ const int part_a_error= s->pict_type==AV_PICTURE_TYPE_I ? (ER_DC_ERROR|ER_MV_ERROR) : ER_MV_ERROR;
+ const int part_a_end = s->pict_type==AV_PICTURE_TYPE_I ? (ER_DC_END |ER_MV_END) : ER_MV_END;
mb_num= mpeg4_decode_partition_a(s);
if(mb_num<0){
@@ -826,18 +826,18 @@ int ff_mpeg4_decode_partitions(MpegEncContext *s)
if( mpeg4_decode_partition_b(s, mb_num) < 0){
if(s->pict_type==AV_PICTURE_TYPE_P)
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, DC_ERROR);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_DC_ERROR);
return -1;
}else{
if(s->pict_type==AV_PICTURE_TYPE_P)
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, DC_END);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_DC_END);
}
return 0;
}
/**
- * decodes a block.
+ * Decode a block.
* @return <0 if an error occurred
*/
static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
@@ -934,7 +934,7 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
}; SKIP_CACHE(re, &s->gb, 1);
last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
- run= SHOW_UBITS(re, &s->gb, 6); LAST_SKIP_CACHE(re, &s->gb, 6);
+ run= SHOW_UBITS(re, &s->gb, 6);
SKIP_COUNTER(re, &s->gb, 1+1+6);
UPDATE_CACHE(re, &s->gb);
@@ -951,7 +951,7 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
}; SKIP_CACHE(re, &s->gb, 5);
level= level * qmul + qadd;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_CACHE(re, &s->gb, 1);
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
SKIP_COUNTER(re, &s->gb, 1+11+5+1);
i+= run + 1;
@@ -968,7 +968,7 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
/* third escape */
SKIP_CACHE(re, &s->gb, 2);
last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
- run= SHOW_UBITS(re, &s->gb, 6); LAST_SKIP_CACHE(re, &s->gb, 6);
+ run= SHOW_UBITS(re, &s->gb, 6);
SKIP_COUNTER(re, &s->gb, 2+1+6);
UPDATE_CACHE(re, &s->gb);
@@ -985,38 +985,16 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
if(SHOW_UBITS(re, &s->gb, 1)==0){
av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in 3. esc\n");
return -1;
- }; LAST_SKIP_CACHE(re, &s->gb, 1);
+ }
SKIP_COUNTER(re, &s->gb, 1+12+1);
}
-#if 0
- if(s->error_recognition >= FF_ER_COMPLIANT){
- const int abs_level= FFABS(level);
- if(abs_level<=MAX_LEVEL && run<=MAX_RUN){
- const int run1= run - rl->max_run[last][abs_level] - 1;
- if(abs_level <= rl->max_level[last][run]){
- av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n");
- return -1;
- }
- if(s->error_recognition > FF_ER_COMPLIANT){
- if(abs_level <= rl->max_level[last][run]*2){
- av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n");
- return -1;
- }
- if(run1 >= 0 && abs_level <= rl->max_level[last][run1]){
- av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n");
- return -1;
- }
- }
- }
- }
-#endif
if (level>0) level= level * qmul + qadd;
else level= level * qmul - qadd;
if((unsigned)(level + 2048) > 4095){
- if(s->error_recognition > FF_ER_COMPLIANT){
+ if(s->err_recognition & AV_EF_BITSTREAM){
if(level > 2560 || level<-2560){
av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale);
return -1;
@@ -1091,20 +1069,20 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64])
int cbp, mb_type;
const int xy= s->mb_x + s->mb_y*s->mb_stride;
- mb_type= s->current_picture.mb_type[xy];
+ mb_type = s->current_picture.f.mb_type[xy];
cbp = s->cbp_table[xy];
s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold;
- if(s->current_picture.qscale_table[xy] != s->qscale){
- ff_set_qscale(s, s->current_picture.qscale_table[xy] );
+ if (s->current_picture.f.qscale_table[xy] != s->qscale) {
+ ff_set_qscale(s, s->current_picture.f.qscale_table[xy]);
}
if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) {
int i;
for(i=0; i<4; i++){
- s->mv[0][i][0] = s->current_picture.motion_val[0][ s->block_index[i] ][0];
- s->mv[0][i][1] = s->current_picture.motion_val[0][ s->block_index[i] ][1];
+ s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0];
+ s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1];
}
s->mb_intra = IS_INTRA(mb_type);
@@ -1122,7 +1100,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64])
s->mb_skipped = 1;
}
}else if(s->mb_intra){
- s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]);
+ s->ac_pred = IS_ACPRED(s->current_picture.f.mb_type[xy]);
}else if(!s->mb_intra){
// s->mcsel= 0; //FIXME do we need to init that
@@ -1135,7 +1113,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64])
}
} else { /* I-Frame */
s->mb_intra = 1;
- s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]);
+ s->ac_pred = IS_ACPRED(s->current_picture.f.mb_type[xy]);
}
if (!IS_SKIP(mb_type)) {
@@ -1188,14 +1166,14 @@ static int mpeg4_decode_mb(MpegEncContext *s,
s->mv_dir = MV_DIR_FORWARD;
s->mv_type = MV_TYPE_16X16;
if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){
- s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
s->mcsel=1;
s->mv[0][0][0]= get_amv(s, 0);
s->mv[0][0][1]= get_amv(s, 1);
s->mb_skipped = 0;
}else{
- s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
s->mcsel=0;
s->mv[0][0][0] = 0;
s->mv[0][0][1] = 0;
@@ -1230,7 +1208,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
s->mv_dir = MV_DIR_FORWARD;
if ((cbpc & 16) == 0) {
if(s->mcsel){
- s->current_picture.mb_type[xy]= MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
/* 16x16 global motion prediction */
s->mv_type = MV_TYPE_16X16;
mx= get_amv(s, 0);
@@ -1238,7 +1216,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
s->mv[0][0][0] = mx;
s->mv[0][0][1] = my;
}else if((!s->progressive_sequence) && get_bits1(&s->gb)){
- s->current_picture.mb_type[xy]= MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED;
/* 16x8 field motion prediction */
s->mv_type= MV_TYPE_FIELD;
@@ -1260,7 +1238,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
s->mv[0][i][1] = my;
}
}else{
- s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
/* 16x16 motion prediction */
s->mv_type = MV_TYPE_16X16;
h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
@@ -1277,7 +1255,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
s->mv[0][0][1] = my;
}
} else {
- s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
s->mv_type = MV_TYPE_8X8;
for(i=0;i<4;i++) {
mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y);
@@ -1314,7 +1292,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
}
/* if we skipped it in the future P Frame than skip it now too */
- s->mb_skipped= s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC
+ s->mb_skipped = s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC
if(s->mb_skipped){
/* skip mb */
@@ -1327,7 +1305,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
s->mv[0][0][1] = 0;
s->mv[1][0][0] = 0;
s->mv[1][0][1] = 0;
- s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
goto end;
}
@@ -1433,7 +1411,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
mb_type |= ff_mpeg4_set_direct_mv(s, mx, my);
}
- s->current_picture.mb_type[xy]= mb_type;
+ s->current_picture.f.mb_type[xy] = mb_type;
} else { /* I-Frame */
do{
cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
@@ -1448,9 +1426,9 @@ static int mpeg4_decode_mb(MpegEncContext *s,
intra:
s->ac_pred = get_bits1(&s->gb);
if(s->ac_pred)
- s->current_picture.mb_type[xy]= MB_TYPE_INTRA | MB_TYPE_ACPRED;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
else
- s->current_picture.mb_type[xy]= MB_TYPE_INTRA;
+ s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
if(cbpy<0){
@@ -1491,12 +1469,12 @@ end:
if(mpeg4_is_resync(s)){
const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
- if(s->pict_type==AV_PICTURE_TYPE_B && s->next_picture.mbskip_table[xy + delta]){
+ if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) {
ff_thread_await_progress((AVFrame*)s->next_picture_ptr,
(s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0);
}
- if(s->pict_type==AV_PICTURE_TYPE_B && s->next_picture.mbskip_table[xy + delta])
+ if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta])
return SLICE_OK;
return SLICE_END;
}
@@ -1523,6 +1501,22 @@ static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){
return 0;
}
+static int mpeg4_decode_profile_level(MpegEncContext * s, GetBitContext *gb){
+ int profile_and_level_indication;
+
+ profile_and_level_indication = get_bits(gb, 8);
+
+ s->avctx->profile = (profile_and_level_indication & 0xf0) >> 4;
+ s->avctx->level = (profile_and_level_indication & 0x0f);
+
+ // for Simple profile, level 0
+ if (s->avctx->profile == 0 && s->avctx->level == 8) {
+ s->avctx->level = 0;
+ }
+
+ return 0;
+}
+
static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
int width, height, vo_ver_id;
@@ -1830,7 +1824,7 @@ no_cplx_est:
}
/**
- * decodes the user data stuff in the header.
+ * Decode the user data stuff in the header.
* Also initializes divx/xvid/lavc_version/build.
*/
static int decode_user_data(MpegEncContext *s, GetBitContext *gb){
@@ -1860,7 +1854,7 @@ static int decode_user_data(MpegEncContext *s, GetBitContext *gb){
}
}
- /* ffmpeg detection */
+ /* libavcodec detection */
e=sscanf(buf, "FFmpe%*[^b]b%d", &build)+3;
if(e!=4)
e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build);
@@ -1961,11 +1955,12 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
}
if(s->avctx->time_base.num)
- s->current_picture_ptr->pts= (s->time + s->avctx->time_base.num/2) / s->avctx->time_base.num;
+ s->current_picture_ptr->f.pts = (s->time + s->avctx->time_base.num / 2) / s->avctx->time_base.num;
else
- s->current_picture_ptr->pts= AV_NOPTS_VALUE;
+ s->current_picture_ptr->f.pts = AV_NOPTS_VALUE;
if(s->avctx->debug&FF_DEBUG_PTS)
- av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %"PRId64"\n", s->current_picture_ptr->pts);
+ av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %"PRId64"\n",
+ s->current_picture_ptr->f.pts);
check_marker(gb, "before vop_coded");
@@ -2099,14 +2094,14 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
}
/**
- * decode mpeg4 headers
+ * Decode mpeg4 headers.
* @return <0 if no VOP found (or a damaged one)
* FRAME_SKIPPED if a not coded VOP is found
* 0 if a VOP is found
*/
int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb)
{
- int startcode, v;
+ unsigned startcode, v;
/* search next start code */
align_get_bits(gb);
@@ -2176,6 +2171,9 @@ int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb)
else if(startcode == GOP_STARTCODE){
mpeg4_decode_gop_header(s, gb);
}
+ else if(startcode == VOS_STARTCODE){
+ mpeg4_decode_profile_level(s, gb);
+ }
else if(startcode == VOP_STARTCODE){
break;
}
@@ -2236,35 +2234,53 @@ static av_cold int decode_init(AVCodecContext *avctx)
return 0;
}
+static const AVProfile mpeg4_video_profiles[] = {
+ { FF_PROFILE_MPEG4_SIMPLE, "Simple Profile" },
+ { FF_PROFILE_MPEG4_SIMPLE_SCALABLE, "Simple Scalable Profile" },
+ { FF_PROFILE_MPEG4_CORE, "Core Profile" },
+ { FF_PROFILE_MPEG4_MAIN, "Main Profile" },
+ { FF_PROFILE_MPEG4_N_BIT, "N-bit Profile" },
+ { FF_PROFILE_MPEG4_SCALABLE_TEXTURE, "Scalable Texture Profile" },
+ { FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION, "Simple Face Animation Profile" },
+ { FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE, "Basic Animated Texture Profile" },
+ { FF_PROFILE_MPEG4_HYBRID, "Hybrid Profile" },
+ { FF_PROFILE_MPEG4_ADVANCED_REAL_TIME, "Advanced Real Time Simple Profile" },
+ { FF_PROFILE_MPEG4_CORE_SCALABLE, "Code Scalable Profile" },
+ { FF_PROFILE_MPEG4_ADVANCED_CODING, "Advanced Coding Profile" },
+ { FF_PROFILE_MPEG4_ADVANCED_CORE, "Advanced Core Profile" },
+ { FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE, "Advanced Scalable Texture Profile" },
+ { FF_PROFILE_MPEG4_SIMPLE_STUDIO, "Simple Studio Profile" },
+ { FF_PROFILE_MPEG4_ADVANCED_SIMPLE, "Advanced Simple Profile" },
+};
+
AVCodec ff_mpeg4_decoder = {
- "mpeg4",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG4,
- sizeof(MpegEncContext),
- decode_init,
- NULL,
- ff_h263_decode_end,
- ff_h263_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_FRAME_THREADS,
+ .name = "mpeg4",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG4,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_FRAME_THREADS,
.flush= ff_mpeg_flush,
.max_lowres= 3,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
.pix_fmts= ff_hwaccel_pixfmt_list_420,
+ .profiles = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles),
.update_thread_context= ONLY_IF_THREADS_ENABLED(ff_mpeg_update_thread_context)
};
#if CONFIG_MPEG4_VDPAU_DECODER
AVCodec ff_mpeg4_vdpau_decoder = {
- "mpeg4_vdpau",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG4,
- sizeof(MpegEncContext),
- decode_init,
- NULL,
- ff_h263_decode_end,
- ff_h263_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
+ .name = "mpeg4_vdpau",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG4,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"),
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_VDPAU_MPEG4, PIX_FMT_NONE},
};
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 8a9bd19..41c153d 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
#include "mpegvideo.h"
#include "h263.h"
#include "mpeg4video.h"
@@ -124,7 +126,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], const
{
int score= 0;
int i, n;
- int8_t * const qscale_table= s->current_picture.qscale_table;
+ int8_t * const qscale_table = s->current_picture.f.qscale_table;
memcpy(zigzag_last_index, s->block_last_index, sizeof(int)*6);
@@ -201,7 +203,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], const
*/
void ff_clean_mpeg4_qscales(MpegEncContext *s){
int i;
- int8_t * const qscale_table= s->current_picture.qscale_table;
+ int8_t * const qscale_table = s->current_picture.f.qscale_table;
ff_clean_h263_qscales(s);
@@ -236,7 +238,7 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s){
/**
- * encodes the dc value.
+ * Encode the dc value.
* @param n block index (0-3 are luma, 4-5 are chroma)
*/
static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n)
@@ -289,17 +291,13 @@ static inline int mpeg4_get_dc_length(int level, int n){
}
/**
- * encodes a 8x8 block
+ * Encode an 8x8 block.
* @param n block index (0-3 are luma, 4-5 are chroma)
*/
static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc,
uint8_t *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb)
{
int i, last_non_zero;
-#if 0 //variables for the outcommented version
- int code, sign, last;
-#endif
- const RLTable *rl;
uint32_t *bits_tab;
uint8_t *len_tab;
const int last_index = s->block_last_index[n];
@@ -309,20 +307,17 @@ static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n
mpeg4_encode_dc(dc_pb, intra_dc, n);
if(last_index<1) return;
i = 1;
- rl = &ff_mpeg4_rl_intra;
bits_tab= uni_mpeg4_intra_rl_bits;
len_tab = uni_mpeg4_intra_rl_len;
} else {
if(last_index<0) return;
i = 0;
- rl = &ff_h263_rl_inter;
bits_tab= uni_mpeg4_inter_rl_bits;
len_tab = uni_mpeg4_inter_rl_len;
}
/* AC coefs */
last_non_zero = i - 1;
-#if 1
for (; i < last_index; i++) {
int level = block[ scan_table[i] ];
if (level) {
@@ -348,64 +343,6 @@ static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n
put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(1<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1);
}
}
-#else
- for (; i <= last_index; i++) {
- const int slevel = block[ scan_table[i] ];
- if (slevel) {
- int level;
- int run = i - last_non_zero - 1;
- last = (i == last_index);
- sign = 0;
- level = slevel;
- if (level < 0) {
- sign = 1;
- level = -level;
- }
- code = get_rl_index(rl, last, run, level);
- put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
- if (code == rl->n) {
- int level1, run1;
- level1 = level - rl->max_level[last][run];
- if (level1 < 1)
- goto esc2;
- code = get_rl_index(rl, last, run, level1);
- if (code == rl->n) {
- esc2:
- put_bits(ac_pb, 1, 1);
- if (level > MAX_LEVEL)
- goto esc3;
- run1 = run - rl->max_run[last][level] - 1;
- if (run1 < 0)
- goto esc3;
- code = get_rl_index(rl, last, run1, level);
- if (code == rl->n) {
- esc3:
- /* third escape */
- put_bits(ac_pb, 1, 1);
- put_bits(ac_pb, 1, last);
- put_bits(ac_pb, 6, run);
- put_bits(ac_pb, 1, 1);
- put_sbits(ac_pb, 12, slevel);
- put_bits(ac_pb, 1, 1);
- } else {
- /* second escape */
- put_bits(ac_pb, 1, 0);
- put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
- put_bits(ac_pb, 1, sign);
- }
- } else {
- /* first escape */
- put_bits(ac_pb, 1, 0);
- put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
- put_bits(ac_pb, 1, sign);
- }
- } else {
- put_bits(ac_pb, 1, sign);
- }
- last_non_zero = i;
- }
- }
-#endif
}
static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc,
@@ -488,6 +425,46 @@ static inline void mpeg4_encode_blocks(MpegEncContext * s, DCTELEM block[6][64],
}
}
+static inline int get_b_cbp(MpegEncContext * s, DCTELEM block[6][64],
+ int motion_x, int motion_y, int mb_type)
+{
+ int cbp = 0, i;
+
+ if (s->flags & CODEC_FLAG_CBP_RD) {
+ int score = 0;
+ const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
+
+ for (i = 0; i < 6; i++)
+ if (s->coded_score[i] < 0) {
+ score += s->coded_score[i];
+ cbp |= 1 << (5 - i);
+ }
+
+ if (cbp) {
+ int zero_score = -6;
+ if ((motion_x | motion_y | s->dquant | mb_type) == 0)
+ zero_score -= 4; //2*MV + mb_type + cbp bit
+
+ zero_score *= lambda;
+ if (zero_score <= score)
+ cbp = 0;
+ }
+
+ for (i = 0; i < 6; i++) {
+ if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i)) & 1) == 0) {
+ s->block_last_index[i] = -1;
+ s->dsp.clear_block(s->block[i]);
+ }
+ }
+ } else {
+ for (i = 0; i < 6; i++) {
+ if (s->block_last_index[i] >= 0)
+ cbp |= 1 << (5 - i);
+ }
+ }
+ return cbp;
+}
+
//FIXME this is duplicated to h263.c
static const int dquant_code[5]= {1,0,9,2,3};
@@ -522,7 +499,7 @@ void mpeg4_encode_mb(MpegEncContext * s,
assert(mb_type>=0);
/* nothing to do if this MB was skipped in the next P Frame */
- if(s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]){ //FIXME avoid DCT & ...
+ if (s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { //FIXME avoid DCT & ...
s->skip_count++;
s->mv[0][0][0]=
s->mv[0][0][1]=
@@ -654,7 +631,7 @@ void mpeg4_encode_mb(MpegEncContext * s,
if(y+16 > s->height) y= s->height-16;
offset= x + y*s->linesize;
- p_pic= s->new_picture.data[0] + offset;
+ p_pic = s->new_picture.f.data[0] + offset;
s->mb_skipped=1;
for(i=0; i<s->max_b_frames; i++){
@@ -662,10 +639,11 @@ void mpeg4_encode_mb(MpegEncContext * s,
int diff;
Picture *pic= s->reordered_input_picture[i+1];
- if(pic==NULL || pic->pict_type!=AV_PICTURE_TYPE_B) break;
+ if (pic == NULL || pic->f.pict_type != AV_PICTURE_TYPE_B)
+ break;
- b_pic= pic->data[0] + offset;
- if(pic->type != FF_BUFFER_TYPE_SHARED)
+ b_pic = pic->f.data[0] + offset;
+ if (pic->f.type != FF_BUFFER_TYPE_SHARED)
b_pic+= INPLACE_OFFSET;
diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16);
if(diff>s->qscale*70){ //FIXME check that 70 is optimal
@@ -769,8 +747,8 @@ void mpeg4_encode_mb(MpegEncContext * s,
/* motion vectors: 8x8 mode*/
h263_pred_motion(s, i, 0, &pred_x, &pred_y);
- ff_h263_encode_motion_vector(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x,
- s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code);
+ ff_h263_encode_motion_vector(s, s->current_picture.f.motion_val[0][ s->block_index[i] ][0] - pred_x,
+ s->current_picture.f.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code);
}
}
@@ -879,9 +857,9 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){
put_bits(&s->pb, 16, 0);
put_bits(&s->pb, 16, GOP_STARTCODE);
- time= s->current_picture_ptr->pts;
+ time = s->current_picture_ptr->f.pts;
if(s->reordered_input_picture[1])
- time= FFMIN(time, s->reordered_input_picture[1]->pts);
+ time = FFMIN(time, s->reordered_input_picture[1]->f.pts);
time= time*s->avctx->time_base.num;
seconds= time/s->avctx->time_base.den;
@@ -1091,7 +1069,7 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
}
put_bits(&s->pb, 3, 0); /* intra dc VLC threshold */
if(!s->progressive_sequence){
- put_bits(&s->pb, 1, s->current_picture_ptr->top_field_first);
+ put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first);
put_bits(&s->pb, 1, s->alternate_scan);
}
//FIXME sprite stuff
@@ -1265,7 +1243,6 @@ static av_cold int encode_init(AVCodecContext *avctx)
s->inter_ac_vlc_length = uni_mpeg4_inter_rl_len;
s->inter_ac_vlc_last_length= uni_mpeg4_inter_rl_len + 128*64;
s->luma_dc_vlc_length= uni_DCtab_lum_len;
- s->chroma_dc_vlc_length= uni_DCtab_chrom_len;
s->ac_esc_length= 7+2+1+6+1+12+1;
s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
@@ -1320,8 +1297,8 @@ void ff_mpeg4_merge_partitions(MpegEncContext *s)
flush_put_bits(&s->tex_pb);
set_put_bits_buffer_size(&s->pb, s->pb2.buf_end - s->pb.buf);
- ff_copy_bits(&s->pb, s->pb2.buf , pb2_len);
- ff_copy_bits(&s->pb, s->tex_pb.buf, tex_pb_len);
+ avpriv_copy_bits(&s->pb, s->pb2.buf , pb2_len);
+ avpriv_copy_bits(&s->pb, s->tex_pb.buf, tex_pb_len);
s->last_bits= put_bits_count(&s->pb);
}
@@ -1338,15 +1315,31 @@ void ff_mpeg4_encode_video_packet_header(MpegEncContext *s)
put_bits(&s->pb, 1, 0); /* no HEC */
}
+#define OFFSET(x) offsetof(MpegEncContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "data_partitioning", "Use data partitioning.", OFFSET(data_partitioning), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { NULL },
+};
+
+static const AVClass mpeg4enc_class = {
+ .class_name = "MPEG4 encoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_mpeg4_encoder = {
- "mpeg4",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MPEG4,
- sizeof(MpegEncContext),
- encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "mpeg4",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MPEG4,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.capabilities= CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
+ .priv_class = &mpeg4enc_class,
};
diff --git a/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c
index f07d34b..c6d670d 100644
--- a/libavcodec/mpegaudio_parser.c
+++ b/libavcodec/mpegaudio_parser.c
@@ -64,7 +64,7 @@ static int mpegaudio_parse(AVCodecParserContext *s1,
state= (state<<8) + buf[i++];
- ret = ff_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate);
+ ret = avpriv_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate);
if (ret < 4) {
s->header_count= -2;
} else {
@@ -100,9 +100,8 @@ static int mpegaudio_parse(AVCodecParserContext *s1,
AVCodecParser ff_mpegaudio_parser = {
- { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 },
- sizeof(MpegAudioParseContext),
- NULL,
- mpegaudio_parse,
- ff_parse_close,
+ .codec_ids = { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 },
+ .priv_data_size = sizeof(MpegAudioParseContext),
+ .parser_parse = mpegaudio_parse,
+ .parser_close = ff_parse_close,
};
diff --git a/libavcodec/mpegaudiodata.c b/libavcodec/mpegaudiodata.c
index b850d22..81a4365 100644
--- a/libavcodec/mpegaudiodata.c
+++ b/libavcodec/mpegaudiodata.c
@@ -27,7 +27,7 @@
#include "mpegaudiodata.h"
-const uint16_t ff_mpa_bitrate_tab[2][3][15] = {
+const uint16_t avpriv_mpa_bitrate_tab[2][3][15] = {
{ {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
@@ -37,7 +37,7 @@ const uint16_t ff_mpa_bitrate_tab[2][3][15] = {
}
};
-const uint16_t ff_mpa_freq_tab[3] = { 44100, 48000, 32000 };
+const uint16_t avpriv_mpa_freq_tab[3] = { 44100, 48000, 32000 };
/*******************************************************/
/* half mpeg encoding window (full precision) */
diff --git a/libavcodec/mpegaudiodata.h b/libavcodec/mpegaudiodata.h
index 8445883..24ea536 100644
--- a/libavcodec/mpegaudiodata.h
+++ b/libavcodec/mpegaudiodata.h
@@ -32,8 +32,8 @@
#define MODE_EXT_MS_STEREO 2
#define MODE_EXT_I_STEREO 1
-extern const uint16_t ff_mpa_bitrate_tab[2][3][15];
-extern const uint16_t ff_mpa_freq_tab[3];
+extern const uint16_t avpriv_mpa_bitrate_tab[2][3][15];
+extern const uint16_t avpriv_mpa_freq_tab[3];
extern const int32_t ff_mpa_enwindow[257];
extern const int ff_mpa_sblimit_table[5];
extern const int ff_mpa_quant_steps[17];
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c
index 033d76e..0c8f9c7 100644
--- a/libavcodec/mpegaudiodec.c
+++ b/libavcodec/mpegaudiodec.c
@@ -21,7 +21,7 @@
/**
* @file
- * MPEG Audio decoder.
+ * MPEG Audio decoder
*/
#include "libavutil/audioconvert.h"
@@ -63,7 +63,7 @@ typedef struct GranuleDef {
typedef struct MPADecodeContext {
MPA_DECODE_HEADER
- uint8_t last_buf[2*BACKSTEP_SIZE + EXTRABYTES];
+ uint8_t last_buf[2 * BACKSTEP_SIZE + EXTRABYTES];
int last_buf_size;
/* next header (used in free format parsing) */
uint32_t free_format_next_header;
@@ -74,14 +74,12 @@ typedef struct MPADecodeContext {
DECLARE_ALIGNED(32, INTFLOAT, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT];
INTFLOAT mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
GranuleDef granules[2][2]; /* Used in Layer 3 */
-#ifdef DEBUG
- int frame_count;
-#endif
int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
int dither_state;
- int error_recognition;
+ int err_recognition;
AVCodecContext* avctx;
MPADSPContext mpadsp;
+ AVFrame frame;
} MPADecodeContext;
#if CONFIG_FLOAT
@@ -95,7 +93,7 @@ typedef struct MPADecodeContext {
# define OUT_FMT AV_SAMPLE_FMT_FLT
#else
# define SHR(a,b) ((a)>>(b))
-/* WARNING: only correct for posititive numbers */
+/* WARNING: only correct for positive numbers */
# define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5))
# define FIXR(a) ((int)((a) * FRAC_ONE + 0.5))
# define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5))
@@ -115,18 +113,16 @@ typedef struct MPADecodeContext {
/* vlc structure for decoding layer 3 huffman tables */
static VLC huff_vlc[16];
static VLC_TYPE huff_vlc_tables[
- 0+128+128+128+130+128+154+166+
- 142+204+190+170+542+460+662+414
+ 0 + 128 + 128 + 128 + 130 + 128 + 154 + 166 +
+ 142 + 204 + 190 + 170 + 542 + 460 + 662 + 414
][2];
static const int huff_vlc_tables_sizes[16] = {
- 0, 128, 128, 128, 130, 128, 154, 166,
- 142, 204, 190, 170, 542, 460, 662, 414
+ 0, 128, 128, 128, 130, 128, 154, 166,
+ 142, 204, 190, 170, 542, 460, 662, 414
};
static VLC huff_quad_vlc[2];
-static VLC_TYPE huff_quad_vlc_tables[128+16][2];
-static const int huff_quad_vlc_tables_sizes[2] = {
- 128, 16
-};
+static VLC_TYPE huff_quad_vlc_tables[128+16][2];
+static const int huff_quad_vlc_tables_sizes[2] = { 128, 16 };
/* computed from band_size_long */
static uint16_t band_index_long[9][23];
#include "mpegaudio_tablegen.h"
@@ -163,17 +159,19 @@ static const int32_t scale_factor_mult2[3][3] = {
* Convert region offsets to region sizes and truncate
* size to big_values.
*/
-static void ff_region_offset2size(GranuleDef *g){
- int i, k, j=0;
- g->region_size[2] = (576 / 2);
- for(i=0;i<3;i++) {
+static void ff_region_offset2size(GranuleDef *g)
+{
+ int i, k, j = 0;
+ g->region_size[2] = 576 / 2;
+ for (i = 0; i < 3; i++) {
k = FFMIN(g->region_size[i], g->big_values);
g->region_size[i] = k - j;
j = k;
}
}
-static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g){
+static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g)
+{
if (g->block_type == 2)
g->region_size[0] = (36 / 2);
else {
@@ -187,17 +185,17 @@ static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g){
g->region_size[1] = (576 / 2);
}
-static void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2){
+static void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2)
+{
int l;
- g->region_size[0] =
- band_index_long[s->sample_rate_index][ra1 + 1] >> 1;
+ g->region_size[0] = band_index_long[s->sample_rate_index][ra1 + 1] >> 1;
/* should not overflow */
l = FFMIN(ra1 + ra2 + 2, 22);
- g->region_size[1] =
- band_index_long[s->sample_rate_index][l] >> 1;
+ g->region_size[1] = band_index_long[s->sample_rate_index][ l] >> 1;
}
-static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g){
+static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
+{
if (g->block_type == 2) {
if (g->switch_point) {
/* if switched mode, we handle the 36 first samples as
@@ -212,12 +210,12 @@ static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g){
g->short_start = 2 + (s->sample_rate_index != 8);
} else {
- g->long_end = 0;
+ g->long_end = 0;
g->short_start = 0;
}
} else {
g->short_start = 13;
- g->long_end = 22;
+ g->long_end = 22;
}
}
@@ -228,11 +226,11 @@ static inline int l1_unscale(int n, int mant, int scale_factor)
int shift, mod;
int64_t val;
- shift = scale_factor_modshift[scale_factor];
- mod = shift & 3;
+ shift = scale_factor_modshift[scale_factor];
+ mod = shift & 3;
shift >>= 2;
- val = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]);
- shift += n;
+ val = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]);
+ shift += n;
/* NOTE: at this point, 1 <= shift >= 21 + 15 */
return (int)((val + (1LL << (shift - 1))) >> shift);
}
@@ -241,8 +239,8 @@ static inline int l2_unscale_group(int steps, int mant, int scale_factor)
{
int shift, mod, val;
- shift = scale_factor_modshift[scale_factor];
- mod = shift & 3;
+ shift = scale_factor_modshift[scale_factor];
+ mod = shift & 3;
shift >>= 2;
val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod];
@@ -258,220 +256,229 @@ static inline int l3_unscale(int value, int exponent)
unsigned int m;
int e;
- e = table_4_3_exp [4*value + (exponent&3)];
- m = table_4_3_value[4*value + (exponent&3)];
- e -= (exponent >> 2);
- assert(e>=1);
+ e = table_4_3_exp [4 * value + (exponent & 3)];
+ m = table_4_3_value[4 * value + (exponent & 3)];
+ e -= exponent >> 2;
+ assert(e >= 1);
if (e > 31)
return 0;
- m = (m + (1 << (e-1))) >> e;
+ m = (m + (1 << (e - 1))) >> e;
return m;
}
-static av_cold int decode_init(AVCodecContext * avctx)
+static av_cold void decode_init_static(void)
{
- MPADecodeContext *s = avctx->priv_data;
- static int init=0;
int i, j, k;
+ int offset;
+
+ /* scale factors table for layer 1/2 */
+ for (i = 0; i < 64; i++) {
+ int shift, mod;
+ /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */
+ shift = i / 3;
+ mod = i % 3;
+ scale_factor_modshift[i] = mod | (shift << 2);
+ }
- s->avctx = avctx;
-
- ff_mpadsp_init(&s->mpadsp);
-
- avctx->sample_fmt= OUT_FMT;
- s->error_recognition= avctx->error_recognition;
-
- if (!init && !avctx->parse_only) {
- int offset;
-
- /* scale factors table for layer 1/2 */
- for(i=0;i<64;i++) {
- int shift, mod;
- /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */
- shift = (i / 3);
- mod = i % 3;
- scale_factor_modshift[i] = mod | (shift << 2);
- }
-
- /* scale factor multiply for layer 1 */
- for(i=0;i<15;i++) {
- int n, norm;
- n = i + 2;
- norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1);
- scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0 * 2.0), FRAC_BITS);
- scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS);
- scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS);
- av_dlog(avctx, "%d: norm=%x s=%x %x %x\n",
- i, norm,
- scale_factor_mult[i][0],
- scale_factor_mult[i][1],
- scale_factor_mult[i][2]);
- }
+ /* scale factor multiply for layer 1 */
+ for (i = 0; i < 15; i++) {
+ int n, norm;
+ n = i + 2;
+ norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1);
+ scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0 * 2.0), FRAC_BITS);
+ scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS);
+ scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS);
+ av_dlog(NULL, "%d: norm=%x s=%x %x %x\n", i, norm,
+ scale_factor_mult[i][0],
+ scale_factor_mult[i][1],
+ scale_factor_mult[i][2]);
+ }
- RENAME(ff_mpa_synth_init)(RENAME(ff_mpa_synth_window));
+ RENAME(ff_mpa_synth_init)(RENAME(ff_mpa_synth_window));
- /* huffman decode tables */
- offset = 0;
- for(i=1;i<16;i++) {
- const HuffTable *h = &mpa_huff_tables[i];
- int xsize, x, y;
- uint8_t tmp_bits [512];
- uint16_t tmp_codes[512];
+ /* huffman decode tables */
+ offset = 0;
+ for (i = 1; i < 16; i++) {
+ const HuffTable *h = &mpa_huff_tables[i];
+ int xsize, x, y;
+ uint8_t tmp_bits [512];
+ uint16_t tmp_codes[512];
- memset(tmp_bits , 0, sizeof(tmp_bits ));
- memset(tmp_codes, 0, sizeof(tmp_codes));
+ memset(tmp_bits , 0, sizeof(tmp_bits ));
+ memset(tmp_codes, 0, sizeof(tmp_codes));
- xsize = h->xsize;
+ xsize = h->xsize;
- j = 0;
- for(x=0;x<xsize;x++) {
- for(y=0;y<xsize;y++){
- tmp_bits [(x << 5) | y | ((x&&y)<<4)]= h->bits [j ];
- tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++];
- }
+ j = 0;
+ for (x = 0; x < xsize; x++) {
+ for (y = 0; y < xsize; y++) {
+ tmp_bits [(x << 5) | y | ((x&&y)<<4)]= h->bits [j ];
+ tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++];
}
-
- /* XXX: fail test */
- huff_vlc[i].table = huff_vlc_tables+offset;
- huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i];
- init_vlc(&huff_vlc[i], 7, 512,
- tmp_bits, 1, 1, tmp_codes, 2, 2,
- INIT_VLC_USE_NEW_STATIC);
- offset += huff_vlc_tables_sizes[i];
}
- assert(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
-
- offset = 0;
- for(i=0;i<2;i++) {
- huff_quad_vlc[i].table = huff_quad_vlc_tables+offset;
- huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i];
- init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
- mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1,
- INIT_VLC_USE_NEW_STATIC);
- offset += huff_quad_vlc_tables_sizes[i];
+
+ /* XXX: fail test */
+ huff_vlc[i].table = huff_vlc_tables+offset;
+ huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i];
+ init_vlc(&huff_vlc[i], 7, 512,
+ tmp_bits, 1, 1, tmp_codes, 2, 2,
+ INIT_VLC_USE_NEW_STATIC);
+ offset += huff_vlc_tables_sizes[i];
+ }
+ assert(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
+
+ offset = 0;
+ for (i = 0; i < 2; i++) {
+ huff_quad_vlc[i].table = huff_quad_vlc_tables+offset;
+ huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i];
+ init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
+ mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1,
+ INIT_VLC_USE_NEW_STATIC);
+ offset += huff_quad_vlc_tables_sizes[i];
+ }
+ assert(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
+
+ for (i = 0; i < 9; i++) {
+ k = 0;
+ for (j = 0; j < 22; j++) {
+ band_index_long[i][j] = k;
+ k += band_size_long[i][j];
}
- assert(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
+ band_index_long[i][22] = k;
+ }
- for(i=0;i<9;i++) {
- k = 0;
- for(j=0;j<22;j++) {
- band_index_long[i][j] = k;
- k += band_size_long[i][j];
+ /* compute n ^ (4/3) and store it in mantissa/exp format */
+
+ mpegaudio_tableinit();
+
+ for (i = 0; i < 4; i++) {
+ if (ff_mpa_quant_bits[i] < 0) {
+ for (j = 0; j < (1 << (-ff_mpa_quant_bits[i]+1)); j++) {
+ int val1, val2, val3, steps;
+ int val = j;
+ steps = ff_mpa_quant_steps[i];
+ val1 = val % steps;
+ val /= steps;
+ val2 = val % steps;
+ val3 = val / steps;
+ division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8);
}
- band_index_long[i][22] = k;
}
-
- /* compute n ^ (4/3) and store it in mantissa/exp format */
-
- mpegaudio_tableinit();
-
- for (i = 0; i < 4; i++)
- if (ff_mpa_quant_bits[i] < 0)
- for (j = 0; j < (1<<(-ff_mpa_quant_bits[i]+1)); j++) {
- int val1, val2, val3, steps;
- int val = j;
- steps = ff_mpa_quant_steps[i];
- val1 = val % steps;
- val /= steps;
- val2 = val % steps;
- val3 = val / steps;
- division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8);
- }
+ }
- for(i=0;i<7;i++) {
- float f;
- INTFLOAT v;
- if (i != 6) {
- f = tan((double)i * M_PI / 12.0);
- v = FIXR(f / (1.0 + f));
- } else {
- v = FIXR(1.0);
- }
- is_table[0][i] = v;
- is_table[1][6 - i] = v;
+ for (i = 0; i < 7; i++) {
+ float f;
+ INTFLOAT v;
+ if (i != 6) {
+ f = tan((double)i * M_PI / 12.0);
+ v = FIXR(f / (1.0 + f));
+ } else {
+ v = FIXR(1.0);
}
- /* invalid values */
- for(i=7;i<16;i++)
- is_table[0][i] = is_table[1][i] = 0.0;
-
- for(i=0;i<16;i++) {
- double f;
- int e, k;
-
- for(j=0;j<2;j++) {
- e = -(j + 1) * ((i + 1) >> 1);
- f = pow(2.0, e / 4.0);
- k = i & 1;
- is_table_lsf[j][k ^ 1][i] = FIXR(f);
- is_table_lsf[j][k][i] = FIXR(1.0);
- av_dlog(avctx, "is_table_lsf %d %d: %f %f\n",
- i, j, (float) is_table_lsf[j][0][i],
- (float) is_table_lsf[j][1][i]);
- }
+ is_table[0][ i] = v;
+ is_table[1][6 - i] = v;
+ }
+ /* invalid values */
+ for (i = 7; i < 16; i++)
+ is_table[0][i] = is_table[1][i] = 0.0;
+
+ for (i = 0; i < 16; i++) {
+ double f;
+ int e, k;
+
+ for (j = 0; j < 2; j++) {
+ e = -(j + 1) * ((i + 1) >> 1);
+ f = pow(2.0, e / 4.0);
+ k = i & 1;
+ is_table_lsf[j][k ^ 1][i] = FIXR(f);
+ is_table_lsf[j][k ][i] = FIXR(1.0);
+ av_dlog(NULL, "is_table_lsf %d %d: %f %f\n",
+ i, j, (float) is_table_lsf[j][0][i],
+ (float) is_table_lsf[j][1][i]);
}
+ }
- for(i=0;i<8;i++) {
- float ci, cs, ca;
- ci = ci_table[i];
- cs = 1.0 / sqrt(1.0 + ci * ci);
- ca = cs * ci;
+ for (i = 0; i < 8; i++) {
+ float ci, cs, ca;
+ ci = ci_table[i];
+ cs = 1.0 / sqrt(1.0 + ci * ci);
+ ca = cs * ci;
#if !CONFIG_FLOAT
- csa_table[i][0] = FIXHR(cs/4);
- csa_table[i][1] = FIXHR(ca/4);
- csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4);
- csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4);
+ csa_table[i][0] = FIXHR(cs/4);
+ csa_table[i][1] = FIXHR(ca/4);
+ csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4);
+ csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4);
#else
- csa_table[i][0] = cs;
- csa_table[i][1] = ca;
- csa_table[i][2] = ca + cs;
- csa_table[i][3] = ca - cs;
+ csa_table[i][0] = cs;
+ csa_table[i][1] = ca;
+ csa_table[i][2] = ca + cs;
+ csa_table[i][3] = ca - cs;
#endif
- }
+ }
- /* compute mdct windows */
- for(i=0;i<36;i++) {
- for(j=0; j<4; j++){
- double d;
-
- if(j==2 && i%3 != 1)
- continue;
-
- d= sin(M_PI * (i + 0.5) / 36.0);
- if(j==1){
- if (i>=30) d= 0;
- else if(i>=24) d= sin(M_PI * (i - 18 + 0.5) / 12.0);
- else if(i>=18) d= 1;
- }else if(j==3){
- if (i< 6) d= 0;
- else if(i< 12) d= sin(M_PI * (i - 6 + 0.5) / 12.0);
- else if(i< 18) d= 1;
- }
- //merge last stage of imdct into the window coefficients
- d*= 0.5 / cos(M_PI*(2*i + 19)/72);
+ /* compute mdct windows */
+ for (i = 0; i < 36; i++) {
+ for (j = 0; j < 4; j++) {
+ double d;
- if(j==2)
- mdct_win[j][i/3] = FIXHR((d / (1<<5)));
- else
- mdct_win[j][i ] = FIXHR((d / (1<<5)));
+ if (j == 2 && i % 3 != 1)
+ continue;
+
+ d = sin(M_PI * (i + 0.5) / 36.0);
+ if (j == 1) {
+ if (i >= 30) d = 0;
+ else if (i >= 24) d = sin(M_PI * (i - 18 + 0.5) / 12.0);
+ else if (i >= 18) d = 1;
+ } else if (j == 3) {
+ if (i < 6) d = 0;
+ else if (i < 12) d = sin(M_PI * (i - 6 + 0.5) / 12.0);
+ else if (i < 18) d = 1;
}
+ //merge last stage of imdct into the window coefficients
+ d *= 0.5 / cos(M_PI * (2 * i + 19) / 72);
+
+ if (j == 2)
+ mdct_win[j][i/3] = FIXHR((d / (1<<5)));
+ else
+ mdct_win[j][i ] = FIXHR((d / (1<<5)));
}
+ }
- /* NOTE: we do frequency inversion adter the MDCT by changing
- the sign of the right window coefs */
- for(j=0;j<4;j++) {
- for(i=0;i<36;i+=2) {
- mdct_win[j + 4][i] = mdct_win[j][i];
- mdct_win[j + 4][i + 1] = -mdct_win[j][i + 1];
- }
+ /* NOTE: we do frequency inversion adter the MDCT by changing
+ the sign of the right window coefs */
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 36; i += 2) {
+ mdct_win[j + 4][i ] = mdct_win[j][i ];
+ mdct_win[j + 4][i + 1] = -mdct_win[j][i + 1];
}
+ }
+}
+
+static av_cold int decode_init(AVCodecContext * avctx)
+{
+ static int initialized_tables = 0;
+ MPADecodeContext *s = avctx->priv_data;
- init = 1;
+ if (!initialized_tables) {
+ decode_init_static();
+ initialized_tables = 1;
}
+ s->avctx = avctx;
+
+ ff_mpadsp_init(&s->mpadsp);
+
+ avctx->sample_fmt= OUT_FMT;
+ s->err_recognition = avctx->err_recognition;
+
if (avctx->codec_id == CODEC_ID_MP3ADU)
s->adu_mode = 1;
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
@@ -509,41 +516,41 @@ static void imdct12(INTFLOAT *out, INTFLOAT *in)
{
INTFLOAT in0, in1, in2, in3, in4, in5, t1, t2;
- in0= in[0*3];
- in1= in[1*3] + in[0*3];
- in2= in[2*3] + in[1*3];
- in3= in[3*3] + in[2*3];
- in4= in[4*3] + in[3*3];
- in5= in[5*3] + in[4*3];
+ in0 = in[0*3];
+ in1 = in[1*3] + in[0*3];
+ in2 = in[2*3] + in[1*3];
+ in3 = in[3*3] + in[2*3];
+ in4 = in[4*3] + in[3*3];
+ in5 = in[5*3] + in[4*3];
in5 += in3;
in3 += in1;
- in2= MULH3(in2, C3, 2);
- in3= MULH3(in3, C3, 4);
-
- t1 = in0 - in4;
- t2 = MULH3(in1 - in5, icos36h[4], 2);
-
- out[ 7]=
- out[10]= t1 + t2;
- out[ 1]=
- out[ 4]= t1 - t2;
-
- in0 += SHR(in4, 1);
- in4 = in0 + in2;
- in5 += 2*in1;
- in1 = MULH3(in5 + in3, icos36h[1], 1);
- out[ 8]=
- out[ 9]= in4 + in1;
- out[ 2]=
- out[ 3]= in4 - in1;
-
- in0 -= in2;
- in5 = MULH3(in5 - in3, icos36h[7], 2);
- out[ 0]=
- out[ 5]= in0 - in5;
- out[ 6]=
- out[11]= in0 + in5;
+ in2 = MULH3(in2, C3, 2);
+ in3 = MULH3(in3, C3, 4);
+
+ t1 = in0 - in4;
+ t2 = MULH3(in1 - in5, icos36h[4], 2);
+
+ out[ 7] =
+ out[10] = t1 + t2;
+ out[ 1] =
+ out[ 4] = t1 - t2;
+
+ in0 += SHR(in4, 1);
+ in4 = in0 + in2;
+ in5 += 2*in1;
+ in1 = MULH3(in5 + in3, icos36h[1], 1);
+ out[ 8] =
+ out[ 9] = in4 + in1;
+ out[ 2] =
+ out[ 3] = in4 - in1;
+
+ in0 -= in2;
+ in5 = MULH3(in5 - in3, icos36h[7], 2);
+ out[ 0] =
+ out[ 5] = in0 - in5;
+ out[ 6] =
+ out[11] = in0 + in5;
}
/* cos(pi*i/18) */
@@ -564,12 +571,12 @@ static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win)
INTFLOAT t0, t1, t2, t3, s0, s1, s2, s3;
INTFLOAT tmp[18], *tmp1, *in1;
- for(i=17;i>=1;i--)
+ for (i = 17; i >= 1; i--)
in[i] += in[i-1];
- for(i=17;i>=3;i-=2)
+ for (i = 17; i >= 3; i -= 2)
in[i] += in[i-2];
- for(j=0;j<2;j++) {
+ for (j = 0; j < 2; j++) {
tmp1 = tmp + j;
in1 = in + j;
@@ -601,7 +608,7 @@ static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win)
}
i = 0;
- for(j=0;j<4;j++) {
+ for (j = 0; j < 4; j++) {
t0 = tmp[i];
t1 = tmp[i + 2];
s0 = t1 + t0;
@@ -609,22 +616,22 @@ static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win)
t2 = tmp[i + 1];
t3 = tmp[i + 3];
- s1 = MULH3(t3 + t2, icos36h[j], 2);
- s3 = MULLx(t3 - t2, icos36[8 - j], FRAC_BITS);
+ s1 = MULH3(t3 + t2, icos36h[ j], 2);
+ s3 = MULLx(t3 - t2, icos36 [8 - j], FRAC_BITS);
t0 = s0 + s1;
t1 = s0 - s1;
- out[(9 + j)*SBLIMIT] = MULH3(t1, win[9 + j], 1) + buf[9 + j];
- out[(8 - j)*SBLIMIT] = MULH3(t1, win[8 - j], 1) + buf[8 - j];
- buf[9 + j] = MULH3(t0, win[18 + 9 + j], 1);
- buf[8 - j] = MULH3(t0, win[18 + 8 - j], 1);
+ out[(9 + j) * SBLIMIT] = MULH3(t1, win[ 9 + j], 1) + buf[9 + j];
+ out[(8 - j) * SBLIMIT] = MULH3(t1, win[ 8 - j], 1) + buf[8 - j];
+ buf[ 9 + j ] = MULH3(t0, win[18 + 9 + j], 1);
+ buf[ 8 - j ] = MULH3(t0, win[18 + 8 - j], 1);
t0 = s2 + s3;
t1 = s2 - s3;
- out[(9 + 8 - j)*SBLIMIT] = MULH3(t1, win[9 + 8 - j], 1) + buf[9 + 8 - j];
- out[( j)*SBLIMIT] = MULH3(t1, win[ j], 1) + buf[ j];
- buf[9 + 8 - j] = MULH3(t0, win[18 + 9 + 8 - j], 1);
- buf[ + j] = MULH3(t0, win[18 + j], 1);
+ out[(9 + 8 - j) * SBLIMIT] = MULH3(t1, win[ 9 + 8 - j], 1) + buf[9 + 8 - j];
+ out[ j * SBLIMIT] = MULH3(t1, win[ j], 1) + buf[ j];
+ buf[ 9 + 8 - j ] = MULH3(t0, win[18 + 9 + 8 - j], 1);
+ buf[ j ] = MULH3(t0, win[18 + j], 1);
i += 4;
}
@@ -632,10 +639,10 @@ static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win)
s1 = MULH3(tmp[17], icos36h[4], 2);
t0 = s0 + s1;
t1 = s0 - s1;
- out[(9 + 4)*SBLIMIT] = MULH3(t1, win[9 + 4], 1) + buf[9 + 4];
- out[(8 - 4)*SBLIMIT] = MULH3(t1, win[8 - 4], 1) + buf[8 - 4];
- buf[9 + 4] = MULH3(t0, win[18 + 9 + 4], 1);
- buf[8 - 4] = MULH3(t0, win[18 + 8 - 4], 1);
+ out[(9 + 4) * SBLIMIT] = MULH3(t1, win[ 9 + 4], 1) + buf[9 + 4];
+ out[(8 - 4) * SBLIMIT] = MULH3(t1, win[ 8 - 4], 1) + buf[8 - 4];
+ buf[ 9 + 4 ] = MULH3(t0, win[18 + 9 + 4], 1);
+ buf[ 8 - 4 ] = MULH3(t0, win[18 + 8 - 4], 1);
}
/* return the number of decoded frames */
@@ -651,23 +658,22 @@ static int mp_decode_layer1(MPADecodeContext *s)
bound = SBLIMIT;
/* allocation bits */
- for(i=0;i<bound;i++) {
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (i = 0; i < bound; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
allocation[ch][i] = get_bits(&s->gb, 4);
}
}
- for(i=bound;i<SBLIMIT;i++) {
+ for (i = bound; i < SBLIMIT; i++)
allocation[0][i] = get_bits(&s->gb, 4);
- }
/* scale factors */
- for(i=0;i<bound;i++) {
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (i = 0; i < bound; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
if (allocation[ch][i])
scale_factors[ch][i] = get_bits(&s->gb, 6);
}
}
- for(i=bound;i<SBLIMIT;i++) {
+ for (i = bound; i < SBLIMIT; i++) {
if (allocation[0][i]) {
scale_factors[0][i] = get_bits(&s->gb, 6);
scale_factors[1][i] = get_bits(&s->gb, 6);
@@ -675,9 +681,9 @@ static int mp_decode_layer1(MPADecodeContext *s)
}
/* compute samples */
- for(j=0;j<12;j++) {
- for(i=0;i<bound;i++) {
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (j = 0; j < 12; j++) {
+ for (i = 0; i < bound; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
n = allocation[ch][i];
if (n) {
mant = get_bits(&s->gb, n + 1);
@@ -688,7 +694,7 @@ static int mp_decode_layer1(MPADecodeContext *s)
s->sb_samples[ch][j][i] = v;
}
}
- for(i=bound;i<SBLIMIT;i++) {
+ for (i = bound; i < SBLIMIT; i++) {
n = allocation[0][i];
if (n) {
mant = get_bits(&s->gb, n + 1);
@@ -717,8 +723,8 @@ static int mp_decode_layer2(MPADecodeContext *s)
/* select decoding table */
table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels,
- s->sample_rate, s->lsf);
- sblimit = ff_mpa_sblimit_table[table];
+ s->sample_rate, s->lsf);
+ sblimit = ff_mpa_sblimit_table[table];
alloc_table = ff_mpa_alloc_tables[table];
if (s->mode == MPA_JSTEREO)
@@ -729,18 +735,18 @@ static int mp_decode_layer2(MPADecodeContext *s)
av_dlog(s->avctx, "bound=%d sblimit=%d\n", bound, sblimit);
/* sanity check */
- if( bound > sblimit ) bound = sblimit;
+ if (bound > sblimit)
+ bound = sblimit;
/* parse bit allocation */
j = 0;
- for(i=0;i<bound;i++) {
+ for (i = 0; i < bound; i++) {
bit_alloc_bits = alloc_table[j];
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (ch = 0; ch < s->nb_channels; ch++)
bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits);
- }
j += 1 << bit_alloc_bits;
}
- for(i=bound;i<sblimit;i++) {
+ for (i = bound; i < sblimit; i++) {
bit_alloc_bits = alloc_table[j];
v = get_bits(&s->gb, bit_alloc_bits);
bit_alloc[0][i] = v;
@@ -749,19 +755,19 @@ static int mp_decode_layer2(MPADecodeContext *s)
}
/* scale codes */
- for(i=0;i<sblimit;i++) {
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (i = 0; i < sblimit; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
if (bit_alloc[ch][i])
scale_code[ch][i] = get_bits(&s->gb, 2);
}
}
/* scale factors */
- for(i=0;i<sblimit;i++) {
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (i = 0; i < sblimit; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
if (bit_alloc[ch][i]) {
sf = scale_factors[ch][i];
- switch(scale_code[ch][i]) {
+ switch (scale_code[ch][i]) {
default:
case 0:
sf[0] = get_bits(&s->gb, 6);
@@ -789,12 +795,12 @@ static int mp_decode_layer2(MPADecodeContext *s)
}
/* samples */
- for(k=0;k<3;k++) {
- for(l=0;l<12;l+=3) {
+ for (k = 0; k < 3; k++) {
+ for (l = 0; l < 12; l += 3) {
j = 0;
- for(i=0;i<bound;i++) {
+ for (i = 0; i < bound; i++) {
bit_alloc_bits = alloc_table[j];
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
b = bit_alloc[ch][i];
if (b) {
scale = scale_factors[ch][i][k];
@@ -808,13 +814,13 @@ static int mp_decode_layer2(MPADecodeContext *s)
steps = ff_mpa_quant_steps[qindex];
s->sb_samples[ch][k * 12 + l + 0][i] =
- l2_unscale_group(steps, v2 & 15, scale);
+ l2_unscale_group(steps, v2 & 15, scale);
s->sb_samples[ch][k * 12 + l + 1][i] =
l2_unscale_group(steps, (v2 >> 4) & 15, scale);
s->sb_samples[ch][k * 12 + l + 2][i] =
l2_unscale_group(steps, v2 >> 8 , scale);
} else {
- for(m=0;m<3;m++) {
+ for (m = 0; m < 3; m++) {
v = get_bits(&s->gb, bits);
v = l1_unscale(bits - 1, v, scale);
s->sb_samples[ch][k * 12 + l + m][i] = v;
@@ -830,7 +836,7 @@ static int mp_decode_layer2(MPADecodeContext *s)
j += 1 << bit_alloc_bits;
}
/* XXX: find a way to avoid this duplication of code */
- for(i=bound;i<sblimit;i++) {
+ for (i = bound; i < sblimit; i++) {
bit_alloc_bits = alloc_table[j];
b = bit_alloc[0][i];
if (b) {
@@ -860,7 +866,7 @@ static int mp_decode_layer2(MPADecodeContext *s)
s->sb_samples[1][k * 12 + l + 2][i] =
l2_unscale_group(steps, v, scale1);
} else {
- for(m=0;m<3;m++) {
+ for (m = 0; m < 3; m++) {
mant = get_bits(&s->gb, bits);
s->sb_samples[0][k * 12 + l + m][i] =
l1_unscale(bits - 1, mant, scale0);
@@ -880,8 +886,8 @@ static int mp_decode_layer2(MPADecodeContext *s)
j += 1 << bit_alloc_bits;
}
/* fill remaining samples to zero */
- for(i=sblimit;i<SBLIMIT;i++) {
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (i = sblimit; i < SBLIMIT; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
s->sb_samples[ch][k * 12 + l + 0][i] = 0;
s->sb_samples[ch][k * 12 + l + 1][i] = 0;
s->sb_samples[ch][k * 12 + l + 2][i] = 0;
@@ -892,28 +898,28 @@ static int mp_decode_layer2(MPADecodeContext *s)
return 3 * 12;
}
-#define SPLIT(dst,sf,n)\
- if(n==3){\
- int m= (sf*171)>>9;\
- dst= sf - 3*m;\
- sf=m;\
- }else if(n==4){\
- dst= sf&3;\
- sf>>=2;\
- }else if(n==5){\
- int m= (sf*205)>>10;\
- dst= sf - 5*m;\
- sf=m;\
- }else if(n==6){\
- int m= (sf*171)>>10;\
- dst= sf - 6*m;\
- sf=m;\
- }else{\
- dst=0;\
+#define SPLIT(dst,sf,n) \
+ if (n == 3) { \
+ int m = (sf * 171) >> 9; \
+ dst = sf - 3 * m; \
+ sf = m; \
+ } else if (n == 4) { \
+ dst = sf & 3; \
+ sf >>= 2; \
+ } else if (n == 5) { \
+ int m = (sf * 205) >> 10; \
+ dst = sf - 5 * m; \
+ sf = m; \
+ } else if (n == 6) { \
+ int m = (sf * 171) >> 10; \
+ dst = sf - 6 * m; \
+ sf = m; \
+ } else { \
+ dst = 0; \
}
-static av_always_inline void lsf_sf_expand(int *slen,
- int sf, int n1, int n2, int n3)
+static av_always_inline void lsf_sf_expand(int *slen, int sf, int n1, int n2,
+ int n3)
{
SPLIT(slen[3], sf, n3)
SPLIT(slen[2], sf, n2)
@@ -921,8 +927,7 @@ static av_always_inline void lsf_sf_expand(int *slen,
slen[0] = sf;
}
-static void exponents_from_scale_factors(MPADecodeContext *s,
- GranuleDef *g,
+static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g,
int16_t *exponents)
{
const uint8_t *bstab, *pretab;
@@ -930,30 +935,30 @@ static void exponents_from_scale_factors(MPADecodeContext *s,
int16_t *exp_ptr;
exp_ptr = exponents;
- gain = g->global_gain - 210;
- shift = g->scalefac_scale + 1;
+ gain = g->global_gain - 210;
+ shift = g->scalefac_scale + 1;
- bstab = band_size_long[s->sample_rate_index];
+ bstab = band_size_long[s->sample_rate_index];
pretab = mpa_pretab[g->preflag];
- for(i=0;i<g->long_end;i++) {
+ for (i = 0; i < g->long_end; i++) {
v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400;
len = bstab[i];
- for(j=len;j>0;j--)
+ for (j = len; j > 0; j--)
*exp_ptr++ = v0;
}
if (g->short_start < 13) {
- bstab = band_size_short[s->sample_rate_index];
+ bstab = band_size_short[s->sample_rate_index];
gains[0] = gain - (g->subblock_gain[0] << 3);
gains[1] = gain - (g->subblock_gain[1] << 3);
gains[2] = gain - (g->subblock_gain[2] << 3);
- k = g->long_end;
- for(i=g->short_start;i<13;i++) {
+ k = g->long_end;
+ for (i = g->short_start; i < 13; i++) {
len = bstab[i];
- for(l=0;l<3;l++) {
+ for (l = 0; l < 3; l++) {
v0 = gains[l] - (g->scale_factors[k++] << shift) + 400;
- for(j=len;j>0;j--)
- *exp_ptr++ = v0;
+ for (j = len; j > 0; j--)
+ *exp_ptr++ = v0;
}
}
}
@@ -962,22 +967,21 @@ static void exponents_from_scale_factors(MPADecodeContext *s,
/* handle n = 0 too */
static inline int get_bitsz(GetBitContext *s, int n)
{
- if (n == 0)
- return 0;
- else
- return get_bits(s, n);
+ return n ? get_bits(s, n) : 0;
}
-static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos, int *end_pos2){
- if(s->in_gb.buffer && *pos >= s->gb.size_in_bits){
- s->gb= s->in_gb;
- s->in_gb.buffer=NULL;
+static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos,
+ int *end_pos2)
+{
+ if (s->in_gb.buffer && *pos >= s->gb.size_in_bits) {
+ s->gb = s->in_gb;
+ s->in_gb.buffer = NULL;
assert((get_bits_count(&s->gb) & 7) == 0);
skip_bits_long(&s->gb, *pos - *end_pos);
- *end_pos2=
- *end_pos= *end_pos2 + get_bits_count(&s->gb) - *pos;
- *pos= get_bits_count(&s->gb);
+ *end_pos2 =
+ *end_pos = *end_pos2 + get_bits_count(&s->gb) - *pos;
+ *pos = get_bits_count(&s->gb);
}
}
@@ -988,13 +992,13 @@ static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos, int *end_
*dst = v;
*/
#if CONFIG_FLOAT
-#define READ_FLIP_SIGN(dst,src)\
- v = AV_RN32A(src) ^ (get_bits1(&s->gb)<<31);\
- AV_WN32A(dst, v);
+#define READ_FLIP_SIGN(dst,src) \
+ v = AV_RN32A(src) ^ (get_bits1(&s->gb) << 31); \
+ AV_WN32A(dst, v);
#else
-#define READ_FLIP_SIGN(dst,src)\
- v= -get_bits1(&s->gb);\
- *(dst) = (*(src) ^ v) - v;
+#define READ_FLIP_SIGN(dst,src) \
+ v = -get_bits1(&s->gb); \
+ *(dst) = (*(src) ^ v) - v;
#endif
static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
@@ -1004,43 +1008,43 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
int i;
int last_pos, bits_left;
VLC *vlc;
- int end_pos= FFMIN(end_pos2, s->gb.size_in_bits);
+ int end_pos = FFMIN(end_pos2, s->gb.size_in_bits);
/* low frequencies (called big values) */
s_index = 0;
- for(i=0;i<3;i++) {
+ for (i = 0; i < 3; i++) {
int j, k, l, linbits;
j = g->region_size[i];
if (j == 0)
continue;
/* select vlc table */
- k = g->table_select[i];
- l = mpa_huff_data[k][0];
+ k = g->table_select[i];
+ l = mpa_huff_data[k][0];
linbits = mpa_huff_data[k][1];
- vlc = &huff_vlc[l];
+ vlc = &huff_vlc[l];
- if(!l){
- memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*2*j);
- s_index += 2*j;
+ if (!l) {
+ memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * 2 * j);
+ s_index += 2 * j;
continue;
}
/* read huffcode and compute each couple */
- for(;j>0;j--) {
+ for (; j > 0; j--) {
int exponent, x, y;
int v;
- int pos= get_bits_count(&s->gb);
+ int pos = get_bits_count(&s->gb);
if (pos >= end_pos){
// av_log(NULL, AV_LOG_ERROR, "pos: %d %d %d %d\n", pos, end_pos, end_pos2, s_index);
switch_buffer(s, &pos, &end_pos, &end_pos2);
// av_log(NULL, AV_LOG_ERROR, "new pos: %d %d\n", pos, end_pos);
- if(pos >= end_pos)
+ if (pos >= end_pos)
break;
}
y = get_vlc2(&s->gb, vlc->table, 7, 3);
- if(!y){
+ if (!y) {
g->sb_hybrid[s_index ] =
g->sb_hybrid[s_index+1] = 0;
s_index += 2;
@@ -1051,100 +1055,100 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
av_dlog(s->avctx, "region=%d n=%d x=%d y=%d exp=%d\n",
i, g->region_size[i] - j, x, y, exponent);
- if(y&16){
+ if (y & 16) {
x = y >> 5;
y = y & 0x0f;
- if (x < 15){
- READ_FLIP_SIGN(g->sb_hybrid+s_index, RENAME(expval_table)[ exponent ]+x)
- }else{
+ if (x < 15) {
+ READ_FLIP_SIGN(g->sb_hybrid + s_index, RENAME(expval_table)[exponent] + x)
+ } else {
x += get_bitsz(&s->gb, linbits);
- v = l3_unscale(x, exponent);
+ v = l3_unscale(x, exponent);
if (get_bits1(&s->gb))
v = -v;
g->sb_hybrid[s_index] = v;
}
- if (y < 15){
- READ_FLIP_SIGN(g->sb_hybrid+s_index+1, RENAME(expval_table)[ exponent ]+y)
- }else{
+ if (y < 15) {
+ READ_FLIP_SIGN(g->sb_hybrid + s_index + 1, RENAME(expval_table)[exponent] + y)
+ } else {
y += get_bitsz(&s->gb, linbits);
- v = l3_unscale(y, exponent);
+ v = l3_unscale(y, exponent);
if (get_bits1(&s->gb))
v = -v;
g->sb_hybrid[s_index+1] = v;
}
- }else{
+ } else {
x = y >> 5;
y = y & 0x0f;
x += y;
- if (x < 15){
- READ_FLIP_SIGN(g->sb_hybrid+s_index+!!y, RENAME(expval_table)[ exponent ]+x)
- }else{
+ if (x < 15) {
+ READ_FLIP_SIGN(g->sb_hybrid + s_index + !!y, RENAME(expval_table)[exponent] + x)
+ } else {
x += get_bitsz(&s->gb, linbits);
- v = l3_unscale(x, exponent);
+ v = l3_unscale(x, exponent);
if (get_bits1(&s->gb))
v = -v;
g->sb_hybrid[s_index+!!y] = v;
}
- g->sb_hybrid[s_index+ !y] = 0;
+ g->sb_hybrid[s_index + !y] = 0;
}
- s_index+=2;
+ s_index += 2;
}
}
/* high frequencies */
vlc = &huff_quad_vlc[g->count1table_select];
- last_pos=0;
+ last_pos = 0;
while (s_index <= 572) {
int pos, code;
pos = get_bits_count(&s->gb);
if (pos >= end_pos) {
- if (pos > end_pos2 && last_pos){
+ if (pos > end_pos2 && last_pos) {
/* some encoders generate an incorrect size for this
part. We must go back into the data */
s_index -= 4;
skip_bits_long(&s->gb, last_pos - pos);
av_log(s->avctx, AV_LOG_INFO, "overread, skip %d enddists: %d %d\n", last_pos - pos, end_pos-pos, end_pos2-pos);
- if(s->error_recognition >= FF_ER_COMPLIANT)
+ if(s->err_recognition & AV_EF_BITSTREAM)
s_index=0;
break;
}
// av_log(NULL, AV_LOG_ERROR, "pos2: %d %d %d %d\n", pos, end_pos, end_pos2, s_index);
switch_buffer(s, &pos, &end_pos, &end_pos2);
// av_log(NULL, AV_LOG_ERROR, "new pos2: %d %d %d\n", pos, end_pos, s_index);
- if(pos >= end_pos)
+ if (pos >= end_pos)
break;
}
- last_pos= pos;
+ last_pos = pos;
code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1);
av_dlog(s->avctx, "t=%d code=%d\n", g->count1table_select, code);
- g->sb_hybrid[s_index+0]=
- g->sb_hybrid[s_index+1]=
- g->sb_hybrid[s_index+2]=
- g->sb_hybrid[s_index+3]= 0;
- while(code){
- static const int idxtab[16]={3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0};
+ g->sb_hybrid[s_index+0] =
+ g->sb_hybrid[s_index+1] =
+ g->sb_hybrid[s_index+2] =
+ g->sb_hybrid[s_index+3] = 0;
+ while (code) {
+ static const int idxtab[16] = { 3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0 };
int v;
- int pos= s_index+idxtab[code];
- code ^= 8>>idxtab[code];
- READ_FLIP_SIGN(g->sb_hybrid+pos, RENAME(exp_table)+exponents[pos])
+ int pos = s_index + idxtab[code];
+ code ^= 8 >> idxtab[code];
+ READ_FLIP_SIGN(g->sb_hybrid + pos, RENAME(exp_table)+exponents[pos])
}
- s_index+=4;
+ s_index += 4;
}
/* skip extension bits */
bits_left = end_pos2 - get_bits_count(&s->gb);
//av_log(NULL, AV_LOG_ERROR, "left:%d buf:%p\n", bits_left, s->in_gb.buffer);
- if (bits_left < 0 && s->error_recognition >= FF_ER_COMPLIANT) {
+ if (bits_left < 0 && (s->err_recognition & AV_EF_BITSTREAM)) {
av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
s_index=0;
- }else if(bits_left > 0 && s->error_recognition >= FF_ER_AGGRESSIVE){
+ } else if (bits_left > 0 && (s->err_recognition & AV_EF_BUFFER)) {
av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
- s_index=0;
+ s_index = 0;
}
- memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*(576 - s_index));
+ memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * (576 - s_index));
skip_bits_long(&s->gb, bits_left);
- i= get_bits_count(&s->gb);
+ i = get_bits_count(&s->gb);
switch_buffer(s, &i, &end_pos, &end_pos2);
return 0;
@@ -1163,34 +1167,32 @@ static void reorder_block(MPADecodeContext *s, GranuleDef *g)
return;
if (g->switch_point) {
- if (s->sample_rate_index != 8) {
+ if (s->sample_rate_index != 8)
ptr = g->sb_hybrid + 36;
- } else {
+ else
ptr = g->sb_hybrid + 48;
- }
} else {
ptr = g->sb_hybrid;
}
- for(i=g->short_start;i<13;i++) {
- len = band_size_short[s->sample_rate_index][i];
+ for (i = g->short_start; i < 13; i++) {
+ len = band_size_short[s->sample_rate_index][i];
ptr1 = ptr;
- dst = tmp;
- for(j=len;j>0;j--) {
+ dst = tmp;
+ for (j = len; j > 0; j--) {
*dst++ = ptr[0*len];
*dst++ = ptr[1*len];
*dst++ = ptr[2*len];
ptr++;
}
- ptr+=2*len;
+ ptr += 2 * len;
memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1));
}
}
#define ISQRT2 FIXR(0.70710678118654752440)
-static void compute_stereo(MPADecodeContext *s,
- GranuleDef *g0, GranuleDef *g1)
+static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1)
{
int i, j, k, l;
int sf_max, sf, len, non_zero_found;
@@ -1214,17 +1216,17 @@ static void compute_stereo(MPADecodeContext *s,
non_zero_found_short[1] = 0;
non_zero_found_short[2] = 0;
k = (13 - g1->short_start) * 3 + g1->long_end - 3;
- for(i = 12;i >= g1->short_start;i--) {
+ for (i = 12; i >= g1->short_start; i--) {
/* for last band, use previous scale factor */
if (i != 11)
k -= 3;
len = band_size_short[s->sample_rate_index][i];
- for(l=2;l>=0;l--) {
+ for (l = 2; l >= 0; l--) {
tab0 -= len;
tab1 -= len;
if (!non_zero_found_short[l]) {
/* test if non zero band. if so, stop doing i-stereo */
- for(j=0;j<len;j++) {
+ for (j = 0; j < len; j++) {
if (tab1[j] != 0) {
non_zero_found_short[l] = 1;
goto found1;
@@ -1236,19 +1238,19 @@ static void compute_stereo(MPADecodeContext *s,
v1 = is_tab[0][sf];
v2 = is_tab[1][sf];
- for(j=0;j<len;j++) {
- tmp0 = tab0[j];
+ for (j = 0; j < len; j++) {
+ tmp0 = tab0[j];
tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
}
} else {
- found1:
+found1:
if (s->mode_ext & MODE_EXT_MS_STEREO) {
/* lower part of the spectrum : do ms stereo
if enabled */
- for(j=0;j<len;j++) {
- tmp0 = tab0[j];
- tmp1 = tab1[j];
+ for (j = 0; j < len; j++) {
+ tmp0 = tab0[j];
+ tmp1 = tab1[j];
tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
}
@@ -1258,41 +1260,41 @@ static void compute_stereo(MPADecodeContext *s,
}
non_zero_found = non_zero_found_short[0] |
- non_zero_found_short[1] |
- non_zero_found_short[2];
+ non_zero_found_short[1] |
+ non_zero_found_short[2];
- for(i = g1->long_end - 1;i >= 0;i--) {
- len = band_size_long[s->sample_rate_index][i];
+ for (i = g1->long_end - 1;i >= 0;i--) {
+ len = band_size_long[s->sample_rate_index][i];
tab0 -= len;
tab1 -= len;
/* test if non zero band. if so, stop doing i-stereo */
if (!non_zero_found) {
- for(j=0;j<len;j++) {
+ for (j = 0; j < len; j++) {
if (tab1[j] != 0) {
non_zero_found = 1;
goto found2;
}
}
/* for last band, use previous scale factor */
- k = (i == 21) ? 20 : i;
+ k = (i == 21) ? 20 : i;
sf = g1->scale_factors[k];
if (sf >= sf_max)
goto found2;
v1 = is_tab[0][sf];
v2 = is_tab[1][sf];
- for(j=0;j<len;j++) {
- tmp0 = tab0[j];
+ for (j = 0; j < len; j++) {
+ tmp0 = tab0[j];
tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
}
} else {
- found2:
+found2:
if (s->mode_ext & MODE_EXT_MS_STEREO) {
/* lower part of the spectrum : do ms stereo
if enabled */
- for(j=0;j<len;j++) {
- tmp0 = tab0[j];
- tmp1 = tab1[j];
+ for (j = 0; j < len; j++) {
+ tmp0 = tab0[j];
+ tmp1 = tab1[j];
tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
}
@@ -1305,9 +1307,9 @@ static void compute_stereo(MPADecodeContext *s,
global gain */
tab0 = g0->sb_hybrid;
tab1 = g1->sb_hybrid;
- for(i=0;i<576;i++) {
- tmp0 = tab0[i];
- tmp1 = tab1[i];
+ for (i = 0; i < 576; i++) {
+ tmp0 = tab0[i];
+ tmp1 = tab1[i];
tab0[i] = tmp0 + tmp1;
tab1[i] = tmp0 - tmp1;
}
@@ -1326,8 +1328,8 @@ static void compute_stereo(MPADecodeContext *s,
int tmp0 = ptr[-1-j]; \
int tmp1 = ptr[ j]; \
int tmp2 = MULH(tmp0 + tmp1, csa_table[j][0]); \
- ptr[-1-j] = 4*(tmp2 - MULH(tmp1, csa_table[j][2])); \
- ptr[ j] = 4*(tmp2 + MULH(tmp0, csa_table[j][3])); \
+ ptr[-1-j] = 4 * (tmp2 - MULH(tmp1, csa_table[j][2])); \
+ ptr[ j] = 4 * (tmp2 + MULH(tmp0, csa_table[j][3])); \
} while (0)
#endif
@@ -1347,7 +1349,7 @@ static void compute_antialias(MPADecodeContext *s, GranuleDef *g)
}
ptr = g->sb_hybrid + 18;
- for(i = n;i > 0;i--) {
+ for (i = n; i > 0; i--) {
AA(0);
AA(1);
AA(2);
@@ -1361,23 +1363,21 @@ static void compute_antialias(MPADecodeContext *s, GranuleDef *g)
}
}
-static void compute_imdct(MPADecodeContext *s,
- GranuleDef *g,
- INTFLOAT *sb_samples,
- INTFLOAT *mdct_buf)
+static void compute_imdct(MPADecodeContext *s, GranuleDef *g,
+ INTFLOAT *sb_samples, INTFLOAT *mdct_buf)
{
INTFLOAT *win, *win1, *out_ptr, *ptr, *buf, *ptr1;
INTFLOAT out2[12];
int i, j, mdct_long_end, sblimit;
/* find last non zero block */
- ptr = g->sb_hybrid + 576;
+ ptr = g->sb_hybrid + 576;
ptr1 = g->sb_hybrid + 2 * 18;
while (ptr >= ptr1) {
int32_t *p;
ptr -= 6;
- p= (int32_t*)ptr;
- if(p[0] | p[1] | p[2] | p[3] | p[4] | p[5])
+ p = (int32_t*)ptr;
+ if (p[0] | p[1] | p[2] | p[3] | p[4] | p[5])
break;
}
sblimit = ((ptr - g->sb_hybrid) / 18) + 1;
@@ -1394,7 +1394,7 @@ static void compute_imdct(MPADecodeContext *s,
buf = mdct_buf;
ptr = g->sb_hybrid;
- for(j=0;j<mdct_long_end;j++) {
+ for (j = 0; j < mdct_long_end; j++) {
/* apply window & overlap with previous buffer */
out_ptr = sb_samples + j;
/* select window */
@@ -1405,33 +1405,33 @@ static void compute_imdct(MPADecodeContext *s,
/* select frequency inversion */
win = win1 + ((4 * 36) & -(j & 1));
imdct36(out_ptr, buf, ptr, win);
- out_ptr += 18*SBLIMIT;
- ptr += 18;
- buf += 18;
+ out_ptr += 18 * SBLIMIT;
+ ptr += 18;
+ buf += 18;
}
- for(j=mdct_long_end;j<sblimit;j++) {
+ for (j = mdct_long_end; j < sblimit; j++) {
/* select frequency inversion */
- win = mdct_win[2] + ((4 * 36) & -(j & 1));
+ win = mdct_win[2] + ((4 * 36) & -(j & 1));
out_ptr = sb_samples + j;
- for(i=0; i<6; i++){
+ for (i = 0; i < 6; i++) {
*out_ptr = buf[i];
out_ptr += SBLIMIT;
}
imdct12(out2, ptr + 0);
- for(i=0;i<6;i++) {
+ for (i = 0; i < 6; i++) {
*out_ptr = MULH3(out2[i ], win[i ], 1) + buf[i + 6*1];
buf[i + 6*2] = MULH3(out2[i + 6], win[i + 6], 1);
out_ptr += SBLIMIT;
}
imdct12(out2, ptr + 1);
- for(i=0;i<6;i++) {
+ for (i = 0; i < 6; i++) {
*out_ptr = MULH3(out2[i ], win[i ], 1) + buf[i + 6*2];
buf[i + 6*0] = MULH3(out2[i + 6], win[i + 6], 1);
out_ptr += SBLIMIT;
}
imdct12(out2, ptr + 2);
- for(i=0;i<6;i++) {
+ for (i = 0; i < 6; i++) {
buf[i + 6*0] = MULH3(out2[i ], win[i ], 1) + buf[i + 6*0];
buf[i + 6*1] = MULH3(out2[i + 6], win[i + 6], 1);
buf[i + 6*2] = 0;
@@ -1440,12 +1440,12 @@ static void compute_imdct(MPADecodeContext *s,
buf += 18;
}
/* zero bands */
- for(j=sblimit;j<SBLIMIT;j++) {
+ for (j = sblimit; j < SBLIMIT; j++) {
/* overlap */
out_ptr = sb_samples + j;
- for(i=0;i<18;i++) {
+ for (i = 0; i < 18; i++) {
*out_ptr = buf[i];
- buf[i] = 0;
+ buf[i] = 0;
out_ptr += SBLIMIT;
}
buf += 18;
@@ -1472,21 +1472,21 @@ static int mp_decode_layer3(MPADecodeContext *s)
else
skip_bits(&s->gb, 5);
nb_granules = 2;
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */
s->granules[ch][1].scfsi = get_bits(&s->gb, 4);
}
}
- for(gr=0;gr<nb_granules;gr++) {
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (gr = 0; gr < nb_granules; gr++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
av_dlog(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch);
g = &s->granules[ch][gr];
g->part2_3_length = get_bits(&s->gb, 12);
- g->big_values = get_bits(&s->gb, 9);
- if(g->big_values > 288){
+ g->big_values = get_bits(&s->gb, 9);
+ if (g->big_values > 288) {
av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
g->global_gain = get_bits(&s->gb, 8);
@@ -1502,21 +1502,21 @@ static int mp_decode_layer3(MPADecodeContext *s)
blocksplit_flag = get_bits1(&s->gb);
if (blocksplit_flag) {
g->block_type = get_bits(&s->gb, 2);
- if (g->block_type == 0){
+ if (g->block_type == 0) {
av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
g->switch_point = get_bits1(&s->gb);
- for(i=0;i<2;i++)
+ for (i = 0; i < 2; i++)
g->table_select[i] = get_bits(&s->gb, 5);
- for(i=0;i<3;i++)
+ for (i = 0; i < 3; i++)
g->subblock_gain[i] = get_bits(&s->gb, 3);
ff_init_short_region(s, g);
} else {
int region_address1, region_address2;
g->block_type = 0;
g->switch_point = 0;
- for(i=0;i<3;i++)
+ for (i = 0; i < 3; i++)
g->table_select[i] = get_bits(&s->gb, 5);
/* compute huffman coded region sizes */
region_address1 = get_bits(&s->gb, 4);
@@ -1531,38 +1531,41 @@ static int mp_decode_layer3(MPADecodeContext *s)
g->preflag = 0;
if (!s->lsf)
g->preflag = get_bits1(&s->gb);
- g->scalefac_scale = get_bits1(&s->gb);
+ g->scalefac_scale = get_bits1(&s->gb);
g->count1table_select = get_bits1(&s->gb);
av_dlog(s->avctx, "block_type=%d switch_point=%d\n",
g->block_type, g->switch_point);
}
}
- if (!s->adu_mode) {
- const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);
- assert((get_bits_count(&s->gb) & 7) == 0);
- /* now we get bits from the main_data_begin offset */
- av_dlog(s->avctx, "seekback: %d\n", main_data_begin);
-//av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size);
+ if (!s->adu_mode) {
+ const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);
+ assert((get_bits_count(&s->gb) & 7) == 0);
+ /* now we get bits from the main_data_begin offset */
+ av_dlog(s->avctx, "seekback: %d\n", main_data_begin);
+ //av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size);
- memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES);
- s->in_gb= s->gb;
+ memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES);
+ s->in_gb = s->gb;
init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);
+#if CONFIG_SAFE_BITSTREAM_READER
+ s->gb.size_in_bits_plus8 += EXTRABYTES * 8;
+#endif
skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin));
- }
+ }
- for(gr=0;gr<nb_granules;gr++) {
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (gr = 0; gr < nb_granules; gr++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
g = &s->granules[ch][gr];
- if(get_bits_count(&s->gb)<0){
+ if (get_bits_count(&s->gb) < 0) {
av_log(s->avctx, AV_LOG_DEBUG, "mdb:%d, lastbuf:%d skipping granule %d\n",
- main_data_begin, s->last_buf_size, gr);
+ main_data_begin, s->last_buf_size, gr);
skip_bits_long(&s->gb, g->part2_3_length);
memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
- if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer){
+ if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) {
skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);
- s->gb= s->in_gb;
- s->in_gb.buffer=NULL;
+ s->gb = s->in_gb;
+ s->in_gb.buffer = NULL;
}
continue;
}
@@ -1580,39 +1583,39 @@ static int mp_decode_layer3(MPADecodeContext *s)
if (g->block_type == 2) {
n = g->switch_point ? 17 : 18;
j = 0;
- if(slen1){
- for(i=0;i<n;i++)
+ if (slen1) {
+ for (i = 0; i < n; i++)
g->scale_factors[j++] = get_bits(&s->gb, slen1);
- }else{
- for(i=0;i<n;i++)
+ } else {
+ for (i = 0; i < n; i++)
g->scale_factors[j++] = 0;
}
- if(slen2){
- for(i=0;i<18;i++)
+ if (slen2) {
+ for (i = 0; i < 18; i++)
g->scale_factors[j++] = get_bits(&s->gb, slen2);
- for(i=0;i<3;i++)
+ for (i = 0; i < 3; i++)
g->scale_factors[j++] = 0;
- }else{
- for(i=0;i<21;i++)
+ } else {
+ for (i = 0; i < 21; i++)
g->scale_factors[j++] = 0;
}
} else {
sc = s->granules[ch][0].scale_factors;
j = 0;
- for(k=0;k<4;k++) {
- n = (k == 0 ? 6 : 5);
+ for (k = 0; k < 4; k++) {
+ n = k == 0 ? 6 : 5;
if ((g->scfsi & (0x8 >> k)) == 0) {
slen = (k < 2) ? slen1 : slen2;
- if(slen){
- for(i=0;i<n;i++)
+ if (slen) {
+ for (i = 0; i < n; i++)
g->scale_factors[j++] = get_bits(&s->gb, slen);
- }else{
- for(i=0;i<n;i++)
+ } else {
+ for (i = 0; i < n; i++)
g->scale_factors[j++] = 0;
}
} else {
/* simply copy from last granule */
- for(i=0;i<n;i++) {
+ for (i = 0; i < n; i++) {
g->scale_factors[j] = sc[j];
j++;
}
@@ -1624,11 +1627,11 @@ static int mp_decode_layer3(MPADecodeContext *s)
int tindex, tindex2, slen[4], sl, sf;
/* LSF scale factors */
- if (g->block_type == 2) {
+ if (g->block_type == 2)
tindex = g->switch_point ? 2 : 1;
- } else {
+ else
tindex = 0;
- }
+
sf = g->scalefac_compress;
if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) {
/* intensity stereo case */
@@ -1659,19 +1662,19 @@ static int mp_decode_layer3(MPADecodeContext *s)
}
j = 0;
- for(k=0;k<4;k++) {
- n = lsf_nsf_table[tindex2][tindex][k];
+ for (k = 0; k < 4; k++) {
+ n = lsf_nsf_table[tindex2][tindex][k];
sl = slen[k];
- if(sl){
- for(i=0;i<n;i++)
+ if (sl) {
+ for (i = 0; i < n; i++)
g->scale_factors[j++] = get_bits(&s->gb, sl);
- }else{
- for(i=0;i<n;i++)
+ } else {
+ for (i = 0; i < n; i++)
g->scale_factors[j++] = 0;
}
}
/* XXX: should compute exact size */
- for(;j<40;j++)
+ for (; j < 40; j++)
g->scale_factors[j] = 0;
}
@@ -1684,7 +1687,7 @@ static int mp_decode_layer3(MPADecodeContext *s)
if (s->nb_channels == 2)
compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]);
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
g = &s->granules[ch][gr];
reorder_block(s, g);
@@ -1692,24 +1695,23 @@ static int mp_decode_layer3(MPADecodeContext *s)
compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
}
} /* gr */
- if(get_bits_count(&s->gb)<0)
+ if (get_bits_count(&s->gb) < 0)
skip_bits_long(&s->gb, -get_bits_count(&s->gb));
return nb_granules * 18;
}
-static int mp_decode_frame(MPADecodeContext *s,
- OUT_INT *samples, const uint8_t *buf, int buf_size)
+static int mp_decode_frame(MPADecodeContext *s, OUT_INT *samples,
+ const uint8_t *buf, int buf_size)
{
- int i, nb_frames, ch;
+ int i, nb_frames, ch, ret;
OUT_INT *samples_ptr;
- init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE)*8);
+ init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8);
/* skip error protection field */
if (s->error_protection)
skip_bits(&s->gb, 16);
- av_dlog(s->avctx, "frame %d:\n", s->frame_count);
switch(s->layer) {
case 1:
s->avctx->frame_size = 384;
@@ -1725,38 +1727,46 @@ static int mp_decode_frame(MPADecodeContext *s,
nb_frames = mp_decode_layer3(s);
s->last_buf_size=0;
- if(s->in_gb.buffer){
+ if (s->in_gb.buffer) {
align_get_bits(&s->gb);
- i= get_bits_left(&s->gb)>>3;
- if(i >= 0 && i <= BACKSTEP_SIZE){
+ i = get_bits_left(&s->gb)>>3;
+ if (i >= 0 && i <= BACKSTEP_SIZE) {
memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i);
s->last_buf_size=i;
- }else
+ } else
av_log(s->avctx, AV_LOG_ERROR, "invalid old backstep %d\n", i);
- s->gb= s->in_gb;
- s->in_gb.buffer= NULL;
+ s->gb = s->in_gb;
+ s->in_gb.buffer = NULL;
}
align_get_bits(&s->gb);
assert((get_bits_count(&s->gb) & 7) == 0);
- i= get_bits_left(&s->gb)>>3;
+ i = get_bits_left(&s->gb) >> 3;
- if(i<0 || i > BACKSTEP_SIZE || nb_frames<0){
- if(i<0)
+ if (i < 0 || i > BACKSTEP_SIZE || nb_frames < 0) {
+ if (i < 0)
av_log(s->avctx, AV_LOG_ERROR, "invalid new backstep %d\n", i);
- i= FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE);
+ i = FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE);
}
- assert(i <= buf_size - HEADER_SIZE && i>= 0);
+ assert(i <= buf_size - HEADER_SIZE && i >= 0);
memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i);
s->last_buf_size += i;
+ }
- break;
+ /* get output buffer */
+ if (!samples) {
+ s->frame.nb_samples = s->avctx->frame_size;
+ if ((ret = s->avctx->get_buffer(s->avctx, &s->frame)) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (OUT_INT *)s->frame.data[0];
}
/* apply the synthesis filter */
- for(ch=0;ch<s->nb_channels;ch++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
samples_ptr = samples + ch;
- for(i=0;i<nb_frames;i++) {
+ for (i = 0; i < nb_frames; i++) {
RENAME(ff_mpa_synth_filter)(
&s->mpadsp,
s->synth_buf[ch], &(s->synth_buf_offset[ch]),
@@ -1770,85 +1780,87 @@ static int mp_decode_frame(MPADecodeContext *s,
return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels;
}
-static int decode_frame(AVCodecContext * avctx,
- void *data, int *data_size,
+static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr,
AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
MPADecodeContext *s = avctx->priv_data;
uint32_t header;
int out_size;
- OUT_INT *out_samples = data;
- if(buf_size < HEADER_SIZE)
- return -1;
+ if (buf_size < HEADER_SIZE)
+ return AVERROR_INVALIDDATA;
header = AV_RB32(buf);
- if(ff_mpa_check_header(header) < 0){
+ if (ff_mpa_check_header(header) < 0) {
av_log(avctx, AV_LOG_ERROR, "Header missing\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
- if (ff_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) {
+ if (avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) {
/* free format: prepare to compute frame size */
s->frame_size = -1;
- return -1;
+ return AVERROR_INVALIDDATA;
}
/* update codec info */
- avctx->channels = s->nb_channels;
+ avctx->channels = s->nb_channels;
avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
if (!avctx->bit_rate)
avctx->bit_rate = s->bit_rate;
avctx->sub_id = s->layer;
- if(*data_size < 1152*avctx->channels*sizeof(OUT_INT))
- return -1;
- *data_size = 0;
-
- if(s->frame_size<=0 || s->frame_size > buf_size){
+ if (s->frame_size <= 0 || s->frame_size > buf_size) {
av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
- return -1;
- }else if(s->frame_size < buf_size){
+ return AVERROR_INVALIDDATA;
+ } else if (s->frame_size < buf_size) {
av_log(avctx, AV_LOG_ERROR, "incorrect frame size\n");
buf_size= s->frame_size;
}
- out_size = mp_decode_frame(s, out_samples, buf, buf_size);
- if(out_size>=0){
- *data_size = out_size;
+ out_size = mp_decode_frame(s, NULL, buf, buf_size);
+ if (out_size >= 0) {
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
avctx->sample_rate = s->sample_rate;
//FIXME maybe move the other codec info stuff from above here too
- }else
- av_log(avctx, AV_LOG_DEBUG, "Error while decoding MPEG audio frame.\n"); //FIXME return -1 / but also return the number of bytes consumed
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
+ /* Only return an error if the bad frame makes up the whole packet.
+ If there is more data in the packet, just consume the bad frame
+ instead of returning an error, which would discard the whole
+ packet. */
+ *got_frame_ptr = 0;
+ if (buf_size == avpkt->size)
+ return out_size;
+ }
s->frame_size = 0;
return buf_size;
}
-static void flush(AVCodecContext *avctx){
+static void flush(AVCodecContext *avctx)
+{
MPADecodeContext *s = avctx->priv_data;
memset(s->synth_buf, 0, sizeof(s->synth_buf));
- s->last_buf_size= 0;
+ s->last_buf_size = 0;
}
#if CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER
-static int decode_frame_adu(AVCodecContext * avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int decode_frame_adu(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
MPADecodeContext *s = avctx->priv_data;
uint32_t header;
int len, out_size;
- OUT_INT *out_samples = data;
len = buf_size;
// Discard too short frames
if (buf_size < HEADER_SIZE) {
- *data_size = 0;
- return buf_size;
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+ return AVERROR_INVALIDDATA;
}
@@ -1859,27 +1871,30 @@ static int decode_frame_adu(AVCodecContext * avctx,
header = AV_RB32(buf) | 0xffe00000;
if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame
- *data_size = 0;
- return buf_size;
+ av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n");
+ return AVERROR_INVALIDDATA;
}
- ff_mpegaudio_decode_header((MPADecodeHeader *)s, header);
+ avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header);
/* update codec info */
avctx->sample_rate = s->sample_rate;
- avctx->channels = s->nb_channels;
+ avctx->channels = s->nb_channels;
if (!avctx->bit_rate)
avctx->bit_rate = s->bit_rate;
avctx->sub_id = s->layer;
s->frame_size = len;
- if (avctx->parse_only) {
+#if FF_API_PARSE_FRAME
+ if (avctx->parse_only)
out_size = buf_size;
- } else {
- out_size = mp_decode_frame(s, out_samples, buf, buf_size);
- }
+ else
+#endif
+ out_size = mp_decode_frame(s, NULL, buf, buf_size);
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
- *data_size = out_size;
return buf_size;
}
#endif /* CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER */
@@ -1890,28 +1905,58 @@ static int decode_frame_adu(AVCodecContext * avctx,
* Context for MP3On4 decoder
*/
typedef struct MP3On4DecodeContext {
- int frames; ///< number of mp3 frames per block (number of mp3 decoder instances)
- int syncword; ///< syncword patch
- const uint8_t *coff; ///< channels offsets in output buffer
+ AVFrame *frame;
+ int frames; ///< number of mp3 frames per block (number of mp3 decoder instances)
+ int syncword; ///< syncword patch
+ const uint8_t *coff; ///< channel offsets in output buffer
MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
+ OUT_INT *decoded_buf; ///< output buffer for decoded samples
} MP3On4DecodeContext;
#include "mpeg4audio.h"
/* Next 3 arrays are indexed by channel config number (passed via codecdata) */
-static const uint8_t mp3Frames[8] = {0,1,1,2,3,3,4,5}; /* number of mp3 decoder instances */
-/* offsets into output buffer, assume output order is FL FR BL BR C LFE */
+
+/* number of mp3 decoder instances */
+static const uint8_t mp3Frames[8] = { 0, 1, 1, 2, 3, 3, 4, 5 };
+
+/* offsets into output buffer, assume output order is FL FR C LFE BL BR SL SR */
static const uint8_t chan_offset[8][5] = {
- {0},
- {0}, // C
- {0}, // FLR
- {2,0}, // C FLR
- {2,0,3}, // C FLR BS
- {4,0,2}, // C FLR BLRS
- {4,0,2,5}, // C FLR BLRS LFE
- {4,0,2,6,5}, // C FLR BLRS BLR LFE
+ { 0 },
+ { 0 }, // C
+ { 0 }, // FLR
+ { 2, 0 }, // C FLR
+ { 2, 0, 3 }, // C FLR BS
+ { 2, 0, 3 }, // C FLR BLRS
+ { 2, 0, 4, 3 }, // C FLR BLRS LFE
+ { 2, 0, 6, 4, 3 }, // C FLR BLRS BLR LFE
};
+/* mp3on4 channel layouts */
+static const int16_t chan_layout[8] = {
+ 0,
+ AV_CH_LAYOUT_MONO,
+ AV_CH_LAYOUT_STEREO,
+ AV_CH_LAYOUT_SURROUND,
+ AV_CH_LAYOUT_4POINT0,
+ AV_CH_LAYOUT_5POINT0,
+ AV_CH_LAYOUT_5POINT1,
+ AV_CH_LAYOUT_7POINT1
+};
+
+static av_cold int decode_close_mp3on4(AVCodecContext * avctx)
+{
+ MP3On4DecodeContext *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < s->frames; i++)
+ av_free(s->mp3decctx[i]);
+
+ av_freep(&s->decoded_buf);
+
+ return 0;
+}
+
static int decode_init_mp3on4(AVCodecContext * avctx)
{
@@ -1921,17 +1966,19 @@ static int decode_init_mp3on4(AVCodecContext * avctx)
if ((avctx->extradata_size < 2) || (avctx->extradata == NULL)) {
av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
- ff_mpeg4audio_get_config(&cfg, avctx->extradata, avctx->extradata_size);
+ avpriv_mpeg4audio_get_config(&cfg, avctx->extradata,
+ avctx->extradata_size * 8, 1);
if (!cfg.chan_config || cfg.chan_config > 7) {
av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
- s->frames = mp3Frames[cfg.chan_config];
- s->coff = chan_offset[cfg.chan_config];
- avctx->channels = ff_mpeg4audio_channels[cfg.chan_config];
+ s->frames = mp3Frames[cfg.chan_config];
+ s->coff = chan_offset[cfg.chan_config];
+ avctx->channels = ff_mpeg4audio_channels[cfg.chan_config];
+ avctx->channel_layout = chan_layout[cfg.chan_config];
if (cfg.sample_rate < 16000)
s->syncword = 0xffe00000;
@@ -1945,9 +1992,12 @@ static int decode_init_mp3on4(AVCodecContext * avctx)
*/
// Allocate zeroed memory for the first decoder context
s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext));
+ if (!s->mp3decctx[0])
+ goto alloc_fail;
// Put decoder context in place to make init_decode() happy
avctx->priv_data = s->mp3decctx[0];
decode_init(avctx);
+ s->frame = avctx->coded_frame;
// Restore mp3on4 context pointer
avctx->priv_data = s;
s->mp3decctx[0]->adu_mode = 1; // Set adu mode
@@ -1957,84 +2007,110 @@ static int decode_init_mp3on4(AVCodecContext * avctx)
*/
for (i = 1; i < s->frames; i++) {
s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext));
+ if (!s->mp3decctx[i])
+ goto alloc_fail;
s->mp3decctx[i]->adu_mode = 1;
s->mp3decctx[i]->avctx = avctx;
+ s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp;
+ }
+
+ /* Allocate buffer for multi-channel output if needed */
+ if (s->frames > 1) {
+ s->decoded_buf = av_malloc(MPA_FRAME_SIZE * MPA_MAX_CHANNELS *
+ sizeof(*s->decoded_buf));
+ if (!s->decoded_buf)
+ goto alloc_fail;
}
return 0;
+alloc_fail:
+ decode_close_mp3on4(avctx);
+ return AVERROR(ENOMEM);
}
-static av_cold int decode_close_mp3on4(AVCodecContext * avctx)
+static void flush_mp3on4(AVCodecContext *avctx)
{
- MP3On4DecodeContext *s = avctx->priv_data;
int i;
+ MP3On4DecodeContext *s = avctx->priv_data;
- for (i = 0; i < s->frames; i++)
- av_free(s->mp3decctx[i]);
-
- return 0;
+ for (i = 0; i < s->frames; i++) {
+ MPADecodeContext *m = s->mp3decctx[i];
+ memset(m->synth_buf, 0, sizeof(m->synth_buf));
+ m->last_buf_size = 0;
+ }
}
-static int decode_frame_mp3on4(AVCodecContext * avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
MP3On4DecodeContext *s = avctx->priv_data;
MPADecodeContext *m;
int fsize, len = buf_size, out_size = 0;
uint32_t header;
- OUT_INT *out_samples = data;
- OUT_INT decoded_buf[MPA_FRAME_SIZE * MPA_MAX_CHANNELS];
+ OUT_INT *out_samples;
OUT_INT *outptr, *bp;
- int fr, j, n;
+ int fr, j, n, ch, ret;
- if(*data_size < MPA_FRAME_SIZE * MPA_MAX_CHANNELS * s->frames * sizeof(OUT_INT))
- return -1;
+ /* get output buffer */
+ s->frame->nb_samples = MPA_FRAME_SIZE;
+ if ((ret = avctx->get_buffer(avctx, s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ out_samples = (OUT_INT *)s->frame->data[0];
- *data_size = 0;
// Discard too short frames
if (buf_size < HEADER_SIZE)
- return -1;
+ return AVERROR_INVALIDDATA;
// If only one decoder interleave is not needed
- outptr = s->frames == 1 ? out_samples : decoded_buf;
+ outptr = s->frames == 1 ? out_samples : s->decoded_buf;
avctx->bit_rate = 0;
+ ch = 0;
for (fr = 0; fr < s->frames; fr++) {
fsize = AV_RB16(buf) >> 4;
fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE);
- m = s->mp3decctx[fr];
- assert (m != NULL);
+ m = s->mp3decctx[fr];
+ assert(m != NULL);
header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
if (ff_mpa_check_header(header) < 0) // Bad header, discard block
break;
- ff_mpegaudio_decode_header((MPADecodeHeader *)m, header);
+ avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);
+
+ if (ch + m->nb_channels > avctx->channels) {
+ av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec "
+ "channel count\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ch += m->nb_channels;
+
out_size += mp_decode_frame(m, outptr, buf, fsize);
- buf += fsize;
- len -= fsize;
+ buf += fsize;
+ len -= fsize;
- if(s->frames > 1) {
+ if (s->frames > 1) {
n = m->avctx->frame_size*m->nb_channels;
/* interleave output data */
bp = out_samples + s->coff[fr];
- if(m->nb_channels == 1) {
- for(j = 0; j < n; j++) {
- *bp = decoded_buf[j];
+ if (m->nb_channels == 1) {
+ for (j = 0; j < n; j++) {
+ *bp = s->decoded_buf[j];
bp += avctx->channels;
}
} else {
- for(j = 0; j < n; j++) {
- bp[0] = decoded_buf[j++];
- bp[1] = decoded_buf[j];
- bp += avctx->channels;
+ for (j = 0; j < n; j++) {
+ bp[0] = s->decoded_buf[j++];
+ bp[1] = s->decoded_buf[j];
+ bp += avctx->channels;
}
}
}
@@ -2044,89 +2120,95 @@ static int decode_frame_mp3on4(AVCodecContext * avctx,
/* update codec info */
avctx->sample_rate = s->mp3decctx[0]->sample_rate;
- *data_size = out_size;
+ s->frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT));
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = *s->frame;
+
return buf_size;
}
#endif /* CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER */
#if !CONFIG_FLOAT
#if CONFIG_MP1_DECODER
-AVCodec ff_mp1_decoder =
-{
- "mp1",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP1,
- sizeof(MPADecodeContext),
- decode_init,
- NULL,
- NULL,
- decode_frame,
- CODEC_CAP_PARSE_ONLY,
- .flush= flush,
- .long_name= NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
+AVCodec ff_mp1_decoder = {
+ .name = "mp1",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP1,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame,
+#if FF_API_PARSE_FRAME
+ .capabilities = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+ .capabilities = CODEC_CAP_DR1,
+#endif
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
};
#endif
#if CONFIG_MP2_DECODER
-AVCodec ff_mp2_decoder =
-{
- "mp2",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP2,
- sizeof(MPADecodeContext),
- decode_init,
- NULL,
- NULL,
- decode_frame,
- CODEC_CAP_PARSE_ONLY,
- .flush= flush,
- .long_name= NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
+AVCodec ff_mp2_decoder = {
+ .name = "mp2",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP2,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame,
+#if FF_API_PARSE_FRAME
+ .capabilities = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+ .capabilities = CODEC_CAP_DR1,
+#endif
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
};
#endif
#if CONFIG_MP3_DECODER
-AVCodec ff_mp3_decoder =
-{
- "mp3",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP3,
- sizeof(MPADecodeContext),
- decode_init,
- NULL,
- NULL,
- decode_frame,
- CODEC_CAP_PARSE_ONLY,
- .flush= flush,
- .long_name= NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
+AVCodec ff_mp3_decoder = {
+ .name = "mp3",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP3,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame,
+#if FF_API_PARSE_FRAME
+ .capabilities = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+ .capabilities = CODEC_CAP_DR1,
+#endif
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
};
#endif
#if CONFIG_MP3ADU_DECODER
-AVCodec ff_mp3adu_decoder =
-{
- "mp3adu",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP3ADU,
- sizeof(MPADecodeContext),
- decode_init,
- NULL,
- NULL,
- decode_frame_adu,
- CODEC_CAP_PARSE_ONLY,
- .flush= flush,
- .long_name= NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
+AVCodec ff_mp3adu_decoder = {
+ .name = "mp3adu",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP3ADU,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame_adu,
+#if FF_API_PARSE_FRAME
+ .capabilities = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+ .capabilities = CODEC_CAP_DR1,
+#endif
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
};
#endif
#if CONFIG_MP3ON4_DECODER
-AVCodec ff_mp3on4_decoder =
-{
- "mp3on4",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP3ON4,
- sizeof(MP3On4DecodeContext),
- decode_init_mp3on4,
- NULL,
- decode_close_mp3on4,
- decode_frame_mp3on4,
- .flush= flush,
- .long_name= NULL_IF_CONFIG_SMALL("MP3onMP4"),
+AVCodec ff_mp3on4_decoder = {
+ .name = "mp3on4",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP3ON4,
+ .priv_data_size = sizeof(MP3On4DecodeContext),
+ .init = decode_init_mp3on4,
+ .close = decode_close_mp3on4,
+ .decode = decode_frame_mp3on4,
+ .capabilities = CODEC_CAP_DR1,
+ .flush = flush_mp3on4,
+ .long_name = NULL_IF_CONFIG_SMALL("MP3onMP4"),
};
#endif
#endif
diff --git a/libavcodec/mpegaudiodec_float.c b/libavcodec/mpegaudiodec_float.c
index 0ff866a..02c83af 100644
--- a/libavcodec/mpegaudiodec_float.c
+++ b/libavcodec/mpegaudiodec_float.c
@@ -23,81 +23,84 @@
#include "mpegaudiodec.c"
#if CONFIG_MP1FLOAT_DECODER
-AVCodec ff_mp1float_decoder =
-{
- "mp1float",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP1,
- sizeof(MPADecodeContext),
- decode_init,
- NULL,
- .close = NULL,
- decode_frame,
- CODEC_CAP_PARSE_ONLY,
- .flush= flush,
- .long_name= NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
+AVCodec ff_mp1float_decoder = {
+ .name = "mp1float",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP1,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame,
+#if FF_API_PARSE_FRAME
+ .capabilities = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+ .capabilities = CODEC_CAP_DR1,
+#endif
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
};
#endif
#if CONFIG_MP2FLOAT_DECODER
-AVCodec ff_mp2float_decoder =
-{
- "mp2float",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP2,
- sizeof(MPADecodeContext),
- decode_init,
- NULL,
- .close = NULL,
- decode_frame,
- CODEC_CAP_PARSE_ONLY,
- .flush= flush,
- .long_name= NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
+AVCodec ff_mp2float_decoder = {
+ .name = "mp2float",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP2,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame,
+#if FF_API_PARSE_FRAME
+ .capabilities = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+ .capabilities = CODEC_CAP_DR1,
+#endif
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
};
#endif
#if CONFIG_MP3FLOAT_DECODER
-AVCodec ff_mp3float_decoder =
-{
- "mp3float",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP3,
- sizeof(MPADecodeContext),
- decode_init,
- NULL,
- .close = NULL,
- decode_frame,
- CODEC_CAP_PARSE_ONLY,
- .flush= flush,
- .long_name= NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
+AVCodec ff_mp3float_decoder = {
+ .name = "mp3float",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP3,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame,
+#if FF_API_PARSE_FRAME
+ .capabilities = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+ .capabilities = CODEC_CAP_DR1,
+#endif
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
};
#endif
#if CONFIG_MP3ADUFLOAT_DECODER
-AVCodec ff_mp3adufloat_decoder =
-{
- "mp3adufloat",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP3ADU,
- sizeof(MPADecodeContext),
- decode_init,
- NULL,
- .close = NULL,
- decode_frame_adu,
- CODEC_CAP_PARSE_ONLY,
- .flush= flush,
- .long_name= NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
+AVCodec ff_mp3adufloat_decoder = {
+ .name = "mp3adufloat",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP3ADU,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame_adu,
+#if FF_API_PARSE_FRAME
+ .capabilities = CODEC_CAP_PARSE_ONLY | CODEC_CAP_DR1,
+#else
+ .capabilities = CODEC_CAP_DR1,
+#endif
+ .flush = flush,
+ .long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
};
#endif
#if CONFIG_MP3ON4FLOAT_DECODER
-AVCodec ff_mp3on4float_decoder =
-{
- "mp3on4float",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP3ON4,
- sizeof(MP3On4DecodeContext),
- decode_init_mp3on4,
- NULL,
- decode_close_mp3on4,
- decode_frame_mp3on4,
- .flush= flush,
- .long_name= NULL_IF_CONFIG_SMALL("MP3onMP4"),
+AVCodec ff_mp3on4float_decoder = {
+ .name = "mp3on4float",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP3ON4,
+ .priv_data_size = sizeof(MP3On4DecodeContext),
+ .init = decode_init_mp3on4,
+ .close = decode_close_mp3on4,
+ .decode = decode_frame_mp3on4,
+ .capabilities = CODEC_CAP_DR1,
+ .flush = flush_mp3on4,
+ .long_name = NULL_IF_CONFIG_SMALL("MP3onMP4"),
};
#endif
diff --git a/libavcodec/mpegaudiodecheader.c b/libavcodec/mpegaudiodecheader.c
index be7abc6..dbd67ff 100644
--- a/libavcodec/mpegaudiodecheader.c
+++ b/libavcodec/mpegaudiodecheader.c
@@ -31,7 +31,7 @@
#include "mpegaudiodecheader.h"
-int ff_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header)
+int avpriv_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header)
{
int sample_rate, frame_size, mpeg25, padding;
int sample_rate_index, bitrate_index;
@@ -46,7 +46,7 @@ int ff_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header)
s->layer = 4 - ((header >> 17) & 3);
/* extract frequency */
sample_rate_index = (header >> 10) & 3;
- sample_rate = ff_mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25);
+ sample_rate = avpriv_mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25);
sample_rate_index += 3 * (s->lsf + mpeg25);
s->sample_rate_index = sample_rate_index;
s->error_protection = ((header >> 16) & 1) ^ 1;
@@ -67,7 +67,7 @@ int ff_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header)
s->nb_channels = 2;
if (bitrate_index != 0) {
- frame_size = ff_mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index];
+ frame_size = avpriv_mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index];
s->bit_rate = frame_size * 1000;
switch(s->layer) {
case 1:
@@ -109,14 +109,14 @@ int ff_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header)
return 0;
}
-int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate)
+int avpriv_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate)
{
MPADecodeHeader s1, *s = &s1;
if (ff_mpa_check_header(head) != 0)
return -1;
- if (ff_mpegaudio_decode_header(s, head) != 0) {
+ if (avpriv_mpegaudio_decode_header(s, head) != 0) {
return -1;
}
diff --git a/libavcodec/mpegaudiodecheader.h b/libavcodec/mpegaudiodecheader.h
index 2991595..764e8ab 100644
--- a/libavcodec/mpegaudiodecheader.h
+++ b/libavcodec/mpegaudiodecheader.h
@@ -50,11 +50,11 @@ typedef struct MPADecodeHeader {
/* header decoding. MUST check the header before because no
consistency check is done there. Return 1 if free format found and
that the frame size must be computed externally */
-int ff_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header);
+int avpriv_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header);
/* useful helper to get mpeg audio stream infos. Return -1 if error in
header, otherwise the coded frame size in bytes */
-int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bitrate);
+int avpriv_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bitrate);
/* fast header check for resync */
static inline int ff_mpa_check_header(uint32_t header){
diff --git a/libavcodec/mpegaudioenc.c b/libavcodec/mpegaudioenc.c
index ef265c9..71ea393 100644
--- a/libavcodec/mpegaudioenc.c
+++ b/libavcodec/mpegaudioenc.c
@@ -25,6 +25,7 @@
*/
#include "avcodec.h"
+#include "internal.h"
#include "put_bits.h"
#define FRAC_BITS 15 /* fractional bits for sb_samples and dct */
@@ -83,9 +84,9 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx)
/* encoding freq */
s->lsf = 0;
for(i=0;i<3;i++) {
- if (ff_mpa_freq_tab[i] == freq)
+ if (avpriv_mpa_freq_tab[i] == freq)
break;
- if ((ff_mpa_freq_tab[i] / 2) == freq) {
+ if ((avpriv_mpa_freq_tab[i] / 2) == freq) {
s->lsf = 1;
break;
}
@@ -98,7 +99,7 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx)
/* encoding bitrate & frequency */
for(i=0;i<15;i++) {
- if (ff_mpa_bitrate_tab[s->lsf][1][i] == bitrate)
+ if (avpriv_mpa_bitrate_tab[s->lsf][1][i] == bitrate)
break;
}
if (i == 15){
@@ -315,8 +316,6 @@ static void filter(MpegAudioContext *s, int ch, const short *samples, int incr)
int tmp1[32];
int *out;
- // print_pow1(samples, 1152);
-
offset = s->samples_offset[ch];
out = &s->sb_samples[ch][0][0][0];
for(j=0;j<36;j++) {
@@ -360,8 +359,6 @@ static void filter(MpegAudioContext *s, int ch, const short *samples, int incr)
}
}
s->samples_offset[ch] = offset;
-
- // print_pow(s->sb_samples, 1152);
}
static void compute_scale_factors(unsigned char scale_code[SBLIMIT],
@@ -763,16 +760,21 @@ static av_cold int MPA_encode_close(AVCodecContext *avctx)
return 0;
}
+static const AVCodecDefault mp2_defaults[] = {
+ { "b", "128k" },
+ { NULL },
+};
+
AVCodec ff_mp2_encoder = {
- "mp2",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_MP2,
- sizeof(MpegAudioContext),
- MPA_encode_init,
- MPA_encode_frame,
- MPA_encode_close,
- NULL,
+ .name = "mp2",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_MP2,
+ .priv_data_size = sizeof(MpegAudioContext),
+ .init = MPA_encode_init,
+ .encode = MPA_encode_frame,
+ .close = MPA_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.supported_samplerates= (const int[]){44100, 48000, 32000, 22050, 24000, 16000, 0},
.long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
+ .defaults = mp2_defaults,
};
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index ceed41f..214b64e 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -66,44 +66,61 @@ static void dct_unquantize_h263_inter_c(MpegEncContext *s,
//#define DEBUG
-static const uint8_t ff_default_chroma_qscale_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, 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
+static const uint8_t ff_default_chroma_qscale_table[32] = {
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ 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
};
-const uint8_t ff_mpeg1_dc_scale_table[128]={
-// 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
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+const uint8_t ff_mpeg1_dc_scale_table[128] = {
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
};
-static const uint8_t mpeg2_dc_scale_table1[128]={
-// 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
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+static const uint8_t mpeg2_dc_scale_table1[128] = {
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
};
-static const uint8_t mpeg2_dc_scale_table2[128]={
-// 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
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+static const uint8_t mpeg2_dc_scale_table2[128] = {
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
};
-static const uint8_t mpeg2_dc_scale_table3[128]={
-// 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
- 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,
- 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,
- 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,
- 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_table3[128] = {
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ 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,
+ 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,
+ 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,
+ 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,
};
-const uint8_t * const ff_mpeg2_dc_scale_table[4]={
+const uint8_t *const ff_mpeg2_dc_scale_table[4] = {
ff_mpeg1_dc_scale_table,
mpeg2_dc_scale_table1,
mpeg2_dc_scale_table2,
@@ -118,53 +135,59 @@ const enum PixelFormat ff_pixfmt_list_420[] = {
const enum PixelFormat ff_hwaccel_pixfmt_list_420[] = {
PIX_FMT_DXVA2_VLD,
PIX_FMT_VAAPI_VLD,
+ PIX_FMT_VDA_VLD,
PIX_FMT_YUV420P,
PIX_FMT_NONE
};
-const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state){
+const uint8_t *avpriv_mpv_find_start_code(const uint8_t *restrict p,
+ const uint8_t *end,
+ uint32_t * restrict state)
+{
int i;
- assert(p<=end);
- if(p>=end)
+ assert(p <= end);
+ if (p >= end)
return end;
- for(i=0; i<3; i++){
- uint32_t tmp= *state << 8;
- *state= tmp + *(p++);
- if(tmp == 0x100 || p==end)
+ for (i = 0; i < 3; i++) {
+ uint32_t tmp = *state << 8;
+ *state = tmp + *(p++);
+ if (tmp == 0x100 || p == end)
return p;
}
- while(p<end){
- if (p[-1] > 1 ) p+= 3;
- else if(p[-2] ) p+= 2;
- else if(p[-3]|(p[-1]-1)) p++;
- else{
+ while (p < end) {
+ if (p[-1] > 1 ) p += 3;
+ else if (p[-2] ) p += 2;
+ else if (p[-3]|(p[-1]-1)) p++;
+ else {
p++;
break;
}
}
- p= FFMIN(p, end)-4;
- *state= AV_RB32(p);
+ p = FFMIN(p, end) - 4;
+ *state = AV_RB32(p);
- return p+4;
+ return p + 4;
}
/* init common dct for both encoder and decoder */
av_cold int ff_dct_common_init(MpegEncContext *s)
{
+ dsputil_init(&s->dsp, s->avctx);
+
s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;
s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c;
s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c;
s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c;
s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c;
- if(s->flags & CODEC_FLAG_BITEXACT)
+ if (s->flags & CODEC_FLAG_BITEXACT)
s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;
s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;
-#if HAVE_MMX
+#if HAVE_MMX
MPV_common_init_mmx(s);
#elif ARCH_ALPHA
MPV_common_init_axp(s);
@@ -181,12 +204,12 @@ av_cold int ff_dct_common_init(MpegEncContext *s)
#endif
/* load & permutate scantables
- note: only wmv uses different ones
- */
- if(s->alternate_scan){
+ * note: only wmv uses different ones
+ */
+ if (s->alternate_scan) {
ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan);
ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan);
- }else{
+ } else {
ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct);
ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct);
}
@@ -196,9 +219,10 @@ av_cold int ff_dct_common_init(MpegEncContext *s)
return 0;
}
-void ff_copy_picture(Picture *dst, Picture *src){
+void ff_copy_picture(Picture *dst, Picture *src)
+{
*dst = *src;
- dst->type= FF_BUFFER_TYPE_COPY;
+ dst->f.type = FF_BUFFER_TYPE_COPY;
}
/**
@@ -206,8 +230,14 @@ void ff_copy_picture(Picture *dst, Picture *src){
*/
static void free_frame_buffer(MpegEncContext *s, Picture *pic)
{
- ff_thread_release_buffer(s->avctx, (AVFrame*)pic);
- av_freep(&pic->hwaccel_picture_private);
+ /* Windows Media Image codecs allocate internal buffers with different
+ * dimensions; ignore user defined callbacks for these
+ */
+ if (s->codec_id != CODEC_ID_WMV3IMAGE && s->codec_id != CODEC_ID_VC1IMAGE)
+ ff_thread_release_buffer(s->avctx, (AVFrame *) pic);
+ else
+ avcodec_default_release_buffer(s->avctx, (AVFrame *) pic);
+ av_freep(&pic->f.hwaccel_picture_private);
}
/**
@@ -218,32 +248,39 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
int r;
if (s->avctx->hwaccel) {
- assert(!pic->hwaccel_picture_private);
+ assert(!pic->f.hwaccel_picture_private);
if (s->avctx->hwaccel->priv_data_size) {
- pic->hwaccel_picture_private = av_mallocz(s->avctx->hwaccel->priv_data_size);
- if (!pic->hwaccel_picture_private) {
+ pic->f.hwaccel_picture_private = av_mallocz(s->avctx->hwaccel->priv_data_size);
+ if (!pic->f.hwaccel_picture_private) {
av_log(s->avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n");
return -1;
}
}
}
- r = ff_thread_get_buffer(s->avctx, (AVFrame*)pic);
+ if (s->codec_id != CODEC_ID_WMV3IMAGE && s->codec_id != CODEC_ID_VC1IMAGE)
+ r = ff_thread_get_buffer(s->avctx, (AVFrame *) pic);
+ else
+ r = avcodec_default_get_buffer(s->avctx, (AVFrame *) pic);
- if (r<0 || !pic->age || !pic->type || !pic->data[0]) {
- av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n", r, pic->age, pic->type, pic->data[0]);
- av_freep(&pic->hwaccel_picture_private);
+ if (r < 0 || !pic->f.type || !pic->f.data[0]) {
+ av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %p)\n",
+ r, pic->f.type, pic->f.data[0]);
+ av_freep(&pic->f.hwaccel_picture_private);
return -1;
}
- if (s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1])) {
- av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (stride changed)\n");
+ if (s->linesize && (s->linesize != pic->f.linesize[0] ||
+ s->uvlinesize != pic->f.linesize[1])) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "get_buffer() failed (stride changed)\n");
free_frame_buffer(s, pic);
return -1;
}
- if (pic->linesize[1] != pic->linesize[2]) {
- av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (uv stride mismatch)\n");
+ if (pic->f.linesize[1] != pic->f.linesize[2]) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "get_buffer() failed (uv stride mismatch)\n");
free_frame_buffer(s, pic);
return -1;
}
@@ -252,146 +289,170 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
}
/**
- * allocates a Picture
- * The pixels are allocated/set by calling get_buffer() if shared=0
+ * Allocate a Picture.
+ * The pixels are allocated/set by calling get_buffer() if shared = 0
*/
-int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared){
- const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) does not sig11
- const int mb_array_size= s->mb_stride*s->mb_height;
- const int b8_array_size= s->b8_stride*s->mb_height*2;
- const int b4_array_size= s->b4_stride*s->mb_height*4;
+int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared)
+{
+ const int big_mb_num = s->mb_stride * (s->mb_height + 1) + 1;
+
+ // the + 1 is needed so memset(,,stride*height) does not sig11
+
+ const int mb_array_size = s->mb_stride * s->mb_height;
+ const int b8_array_size = s->b8_stride * s->mb_height * 2;
+ const int b4_array_size = s->b4_stride * s->mb_height * 4;
int i;
- int r= -1;
+ int r = -1;
- if(shared){
- assert(pic->data[0]);
- assert(pic->type == 0 || pic->type == FF_BUFFER_TYPE_SHARED);
- pic->type= FF_BUFFER_TYPE_SHARED;
- }else{
- assert(!pic->data[0]);
+ if (shared) {
+ assert(pic->f.data[0]);
+ assert(pic->f.type == 0 || pic->f.type == FF_BUFFER_TYPE_SHARED);
+ pic->f.type = FF_BUFFER_TYPE_SHARED;
+ } else {
+ assert(!pic->f.data[0]);
if (alloc_frame_buffer(s, pic) < 0)
return -1;
- s->linesize = pic->linesize[0];
- s->uvlinesize= pic->linesize[1];
+ s->linesize = pic->f.linesize[0];
+ s->uvlinesize = pic->f.linesize[1];
}
- if(pic->qscale_table==NULL){
+ if (pic->f.qscale_table == NULL) {
if (s->encoding) {
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_var , mb_array_size * sizeof(int16_t) , fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->mc_mb_var, mb_array_size * sizeof(int16_t) , fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_mean , mb_array_size * sizeof(int8_t ) , fail)
- }
-
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->mbskip_table , mb_array_size * sizeof(uint8_t)+2, fail) //the +2 is for the slice end check
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->qscale_table_base , (big_mb_num + s->mb_stride) * sizeof(uint8_t) , fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_type_base , (big_mb_num + s->mb_stride) * sizeof(uint32_t), fail)
- pic->mb_type= pic->mb_type_base + 2*s->mb_stride+1;
- pic->qscale_table = pic->qscale_table_base + 2*s->mb_stride + 1;
- if(s->out_format == FMT_H264){
- for(i=0; i<2; i++){
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i], 2 * (b4_array_size+4) * sizeof(int16_t), fail)
- pic->motion_val[i]= pic->motion_val_base[i]+4;
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->ref_index[i], 4*mb_array_size * sizeof(uint8_t), fail)
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_var,
+ mb_array_size * sizeof(int16_t), fail)
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->mc_mb_var,
+ mb_array_size * sizeof(int16_t), fail)
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_mean,
+ mb_array_size * sizeof(int8_t ), fail)
+ }
+
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.mbskip_table,
+ mb_array_size * sizeof(uint8_t) + 2, fail)// the + 2 is for the slice end check
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->qscale_table_base,
+ (big_mb_num + s->mb_stride) * sizeof(uint8_t),
+ fail)
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_type_base,
+ (big_mb_num + s->mb_stride) * sizeof(uint32_t),
+ fail)
+ pic->f.mb_type = pic->mb_type_base + 2 * s->mb_stride + 1;
+ pic->f.qscale_table = pic->qscale_table_base + 2 * s->mb_stride + 1;
+ if (s->out_format == FMT_H264) {
+ for (i = 0; i < 2; i++) {
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i],
+ 2 * (b4_array_size + 4) * sizeof(int16_t),
+ fail)
+ pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.ref_index[i],
+ 4 * mb_array_size * sizeof(uint8_t), fail)
}
- pic->motion_subsample_log2= 2;
- }else if(s->out_format == FMT_H263 || s->encoding || (s->avctx->debug&FF_DEBUG_MV) || (s->avctx->debug_mv)){
- for(i=0; i<2; i++){
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i], 2 * (b8_array_size+4) * sizeof(int16_t), fail)
- pic->motion_val[i]= pic->motion_val_base[i]+4;
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->ref_index[i], 4*mb_array_size * sizeof(uint8_t), fail)
+ pic->f.motion_subsample_log2 = 2;
+ } else if (s->out_format == FMT_H263 || s->encoding ||
+ (s->avctx->debug & FF_DEBUG_MV) || s->avctx->debug_mv) {
+ for (i = 0; i < 2; i++) {
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i],
+ 2 * (b8_array_size + 4) * sizeof(int16_t),
+ fail)
+ pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.ref_index[i],
+ 4 * mb_array_size * sizeof(uint8_t), fail)
}
- pic->motion_subsample_log2= 3;
+ pic->f.motion_subsample_log2 = 3;
}
- if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->dct_coeff, 64 * mb_array_size * sizeof(DCTELEM)*6, fail)
+ if (s->avctx->debug&FF_DEBUG_DCT_COEFF) {
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.dct_coeff,
+ 64 * mb_array_size * sizeof(DCTELEM) * 6, fail)
}
- pic->qstride= s->mb_stride;
- FF_ALLOCZ_OR_GOTO(s->avctx, pic->pan_scan , 1 * sizeof(AVPanScan), fail)
+ pic->f.qstride = s->mb_stride;
+ FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.pan_scan,
+ 1 * sizeof(AVPanScan), fail)
}
- /* It might be nicer if the application would keep track of these
- * but it would require an API change. */
- memmove(s->prev_pict_types+1, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE-1);
- s->prev_pict_types[0]= s->dropable ? AV_PICTURE_TYPE_B : s->pict_type;
- if(pic->age < PREV_PICT_TYPES_BUFFER_SIZE && s->prev_pict_types[pic->age] == AV_PICTURE_TYPE_B)
- pic->age= INT_MAX; // Skipped MBs in B-frames are quite rare in MPEG-1/2 and it is a bit tricky to skip them anyway.
- pic->owner2 = NULL;
+ pic->owner2 = s;
return 0;
-fail: //for the FF_ALLOCZ_OR_GOTO macro
- if(r>=0)
+fail: // for the FF_ALLOCZ_OR_GOTO macro
+ if (r >= 0)
free_frame_buffer(s, pic);
return -1;
}
/**
- * deallocates a picture
+ * Deallocate a picture.
*/
-static void free_picture(MpegEncContext *s, Picture *pic){
+static void free_picture(MpegEncContext *s, Picture *pic)
+{
int i;
- if(pic->data[0] && pic->type!=FF_BUFFER_TYPE_SHARED){
+ if (pic->f.data[0] && pic->f.type != FF_BUFFER_TYPE_SHARED) {
free_frame_buffer(s, pic);
}
av_freep(&pic->mb_var);
av_freep(&pic->mc_mb_var);
av_freep(&pic->mb_mean);
- av_freep(&pic->mbskip_table);
+ av_freep(&pic->f.mbskip_table);
av_freep(&pic->qscale_table_base);
av_freep(&pic->mb_type_base);
- av_freep(&pic->dct_coeff);
- av_freep(&pic->pan_scan);
- pic->mb_type= NULL;
- for(i=0; i<2; i++){
+ av_freep(&pic->f.dct_coeff);
+ av_freep(&pic->f.pan_scan);
+ pic->f.mb_type = NULL;
+ for (i = 0; i < 2; i++) {
av_freep(&pic->motion_val_base[i]);
- av_freep(&pic->ref_index[i]);
+ av_freep(&pic->f.ref_index[i]);
}
- if(pic->type == FF_BUFFER_TYPE_SHARED){
- for(i=0; i<4; i++){
- pic->base[i]=
- pic->data[i]= NULL;
+ if (pic->f.type == FF_BUFFER_TYPE_SHARED) {
+ for (i = 0; i < 4; i++) {
+ pic->f.base[i] =
+ pic->f.data[i] = NULL;
}
- pic->type= 0;
+ pic->f.type = 0;
}
}
-static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){
+static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base)
+{
int y_size = s->b8_stride * (2 * s->mb_height + 1);
int c_size = s->mb_stride * (s->mb_height + 1);
int yc_size = y_size + 2 * c_size;
int i;
- // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->allocated_edge_emu_buffer, (s->width+64)*2*21*2, fail); //(width + edge + align)*interlaced*MBsize*tolerance
- s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21;
-
- //FIXME should be linesize instead of s->width*2 but that is not known before get_buffer()
- FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad, (s->width+64)*4*16*2*sizeof(uint8_t), fail)
- s->me.temp= s->me.scratchpad;
- s->rd_scratchpad= s->me.scratchpad;
- s->b_scratchpad= s->me.scratchpad;
- s->obmc_scratchpad= s->me.scratchpad + 16;
+ // edge emu needs blocksize + filter length - 1
+ // (= 17x17 for halfpel / 21x21 for h264)
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->edge_emu_buffer,
+ (s->width + 64) * 2 * 21 * 2, fail); // (width + edge + align)*interlaced*MBsize*tolerance
+
+ // FIXME should be linesize instead of s->width * 2
+ // but that is not known before get_buffer()
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad,
+ (s->width + 64) * 4 * 16 * 2 * sizeof(uint8_t), fail)
+ s->me.temp = s->me.scratchpad;
+ s->rd_scratchpad = s->me.scratchpad;
+ s->b_scratchpad = s->me.scratchpad;
+ s->obmc_scratchpad = s->me.scratchpad + 16;
if (s->encoding) {
- FF_ALLOCZ_OR_GOTO(s->avctx, s->me.map , ME_MAP_SIZE*sizeof(uint32_t), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->me.score_map, ME_MAP_SIZE*sizeof(uint32_t), fail)
- if(s->avctx->noise_reduction){
- FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_error_sum, 2 * 64 * sizeof(int), fail)
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->me.map,
+ ME_MAP_SIZE * sizeof(uint32_t), fail)
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->me.score_map,
+ ME_MAP_SIZE * sizeof(uint32_t), fail)
+ if (s->avctx->noise_reduction) {
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_error_sum,
+ 2 * 64 * sizeof(int), fail)
}
}
- FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64*12*2 * sizeof(DCTELEM), fail)
- s->block= s->blocks[0];
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64 * 12 * 2 * sizeof(DCTELEM), fail)
+ s->block = s->blocks[0];
- for(i=0;i<12;i++){
+ for (i = 0; i < 12; i++) {
s->pblocks[i] = &s->block[i];
}
if (s->out_format == FMT_H263) {
/* ac values */
- FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_val_base, yc_size * sizeof(int16_t) * 16, fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_val_base,
+ yc_size * sizeof(int16_t) * 16, fail);
s->ac_val[0] = s->ac_val_base + s->b8_stride + 1;
s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1;
s->ac_val[2] = s->ac_val[1] + c_size;
@@ -399,30 +460,32 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){
return 0;
fail:
- return -1; //free() through MPV_common_end()
+ return -1; // free() through MPV_common_end()
}
-static void free_duplicate_context(MpegEncContext *s){
- if(s==NULL) return;
+static void free_duplicate_context(MpegEncContext *s)
+{
+ if (s == NULL)
+ return;
- av_freep(&s->allocated_edge_emu_buffer); s->edge_emu_buffer= NULL;
+ av_freep(&s->edge_emu_buffer);
av_freep(&s->me.scratchpad);
- s->me.temp=
- s->rd_scratchpad=
- s->b_scratchpad=
- s->obmc_scratchpad= NULL;
+ s->me.temp =
+ s->rd_scratchpad =
+ s->b_scratchpad =
+ s->obmc_scratchpad = NULL;
av_freep(&s->dct_error_sum);
av_freep(&s->me.map);
av_freep(&s->me.score_map);
av_freep(&s->blocks);
av_freep(&s->ac_val_base);
- s->block= NULL;
+ s->block = NULL;
}
-static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src){
-#define COPY(a) bak->a= src->a
- COPY(allocated_edge_emu_buffer);
+static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
+{
+#define COPY(a) bak->a = src->a
COPY(edge_emu_buffer);
COPY(me.scratchpad);
COPY(me.temp);
@@ -447,28 +510,33 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src){
#undef COPY
}
-void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src){
+void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src)
+{
MpegEncContext bak;
int i;
- //FIXME copy only needed parts
-//START_TIMER
+ // FIXME copy only needed parts
+ // START_TIMER
backup_duplicate_context(&bak, dst);
memcpy(dst, src, sizeof(MpegEncContext));
backup_duplicate_context(dst, &bak);
- for(i=0;i<12;i++){
+ for (i = 0; i < 12; i++) {
dst->pblocks[i] = &dst->block[i];
}
-//STOP_TIMER("update_duplicate_context") //about 10k cycles / 0.01 sec for 1000frames on 1ghz with 2 threads
+ // STOP_TIMER("update_duplicate_context")
+ // about 10k cycles / 0.01 sec for 1000frames on 1ghz with 2 threads
}
-int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
+int ff_mpeg_update_thread_context(AVCodecContext *dst,
+ const AVCodecContext *src)
{
MpegEncContext *s = dst->priv_data, *s1 = src->priv_data;
- if(dst == src || !s1->context_initialized) return 0;
+ if (dst == src || !s1->context_initialized)
+ return 0;
- //FIXME can parameters change on I-frames? in that case dst may need a reinit
- if(!s->context_initialized){
+ // FIXME can parameters change on I-frames?
+ // in that case dst may need a reinit
+ if (!s->context_initialized) {
memcpy(s, s1, sizeof(MpegEncContext));
s->avctx = dst;
@@ -490,46 +558,53 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src
s->input_picture_number = s1->input_picture_number;
memcpy(s->picture, s1->picture, s1->picture_count * sizeof(Picture));
- memcpy(&s->last_picture, &s1->last_picture, (char*)&s1->last_picture_ptr - (char*)&s1->last_picture);
-
- s->last_picture_ptr = REBASE_PICTURE(s1->last_picture_ptr, s, s1);
- s->current_picture_ptr = REBASE_PICTURE(s1->current_picture_ptr, s, s1);
- s->next_picture_ptr = REBASE_PICTURE(s1->next_picture_ptr, s, s1);
+ memcpy(&s->last_picture, &s1->last_picture,
+ (char *) &s1->last_picture_ptr - (char *) &s1->last_picture);
- memcpy(s->prev_pict_types, s1->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE);
+ s->last_picture_ptr = REBASE_PICTURE(s1->last_picture_ptr, s, s1);
+ s->current_picture_ptr = REBASE_PICTURE(s1->current_picture_ptr, s, s1);
+ s->next_picture_ptr = REBASE_PICTURE(s1->next_picture_ptr, s, s1);
- //Error/bug resilience
+ // Error/bug resilience
s->next_p_frame_damaged = s1->next_p_frame_damaged;
s->workaround_bugs = s1->workaround_bugs;
- //MPEG4 timing info
- memcpy(&s->time_increment_bits, &s1->time_increment_bits, (char*)&s1->shape - (char*)&s1->time_increment_bits);
+ // MPEG4 timing info
+ memcpy(&s->time_increment_bits, &s1->time_increment_bits,
+ (char *) &s1->shape - (char *) &s1->time_increment_bits);
- //B-frame info
- s->max_b_frames = s1->max_b_frames;
- s->low_delay = s1->low_delay;
- s->dropable = s1->dropable;
+ // B-frame info
+ s->max_b_frames = s1->max_b_frames;
+ s->low_delay = s1->low_delay;
+ s->dropable = s1->dropable;
- //DivX handling (doesn't work)
- s->divx_packed = s1->divx_packed;
+ // DivX handling (doesn't work)
+ s->divx_packed = s1->divx_packed;
- if(s1->bitstream_buffer){
- if (s1->bitstream_buffer_size + FF_INPUT_BUFFER_PADDING_SIZE > s->allocated_bitstream_buffer_size)
- av_fast_malloc(&s->bitstream_buffer, &s->allocated_bitstream_buffer_size, s1->allocated_bitstream_buffer_size);
- s->bitstream_buffer_size = s1->bitstream_buffer_size;
- memcpy(s->bitstream_buffer, s1->bitstream_buffer, s1->bitstream_buffer_size);
- memset(s->bitstream_buffer+s->bitstream_buffer_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ if (s1->bitstream_buffer) {
+ if (s1->bitstream_buffer_size +
+ FF_INPUT_BUFFER_PADDING_SIZE > s->allocated_bitstream_buffer_size)
+ av_fast_malloc(&s->bitstream_buffer,
+ &s->allocated_bitstream_buffer_size,
+ s1->allocated_bitstream_buffer_size);
+ s->bitstream_buffer_size = s1->bitstream_buffer_size;
+ memcpy(s->bitstream_buffer, s1->bitstream_buffer,
+ s1->bitstream_buffer_size);
+ memset(s->bitstream_buffer + s->bitstream_buffer_size, 0,
+ FF_INPUT_BUFFER_PADDING_SIZE);
}
- //MPEG2/interlacing info
- memcpy(&s->progressive_sequence, &s1->progressive_sequence, (char*)&s1->rtp_mode - (char*)&s1->progressive_sequence);
+ // MPEG2/interlacing info
+ memcpy(&s->progressive_sequence, &s1->progressive_sequence,
+ (char *) &s1->rtp_mode - (char *) &s1->progressive_sequence);
- if(!s1->first_field){
- s->last_pict_type= s1->pict_type;
- if (s1->current_picture_ptr) s->last_lambda_for[s1->pict_type] = s1->current_picture_ptr->quality;
+ if (!s1->first_field) {
+ s->last_pict_type = s1->pict_type;
+ if (s1->current_picture_ptr)
+ s->last_lambda_for[s1->pict_type] = s1->current_picture_ptr->f.quality;
- if(s1->pict_type!=FF_B_TYPE){
- s->last_non_b_pict_type= s1->pict_type;
+ if (s1->pict_type != AV_PICTURE_TYPE_B) {
+ s->last_non_b_pict_type = s1->pict_type;
}
}
@@ -537,35 +612,40 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src
}
/**
- * sets the given MpegEncContext to common defaults (same for encoding and decoding).
- * the changed fields will not depend upon the prior state of the MpegEncContext.
+ * Set the given MpegEncContext to common defaults
+ * (same for encoding and decoding).
+ * The changed fields will not depend upon the
+ * prior state of the MpegEncContext.
*/
-void MPV_common_defaults(MpegEncContext *s){
- s->y_dc_scale_table=
- s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
- s->chroma_qscale_table= ff_default_chroma_qscale_table;
- s->progressive_frame= 1;
- s->progressive_sequence= 1;
- s->picture_structure= PICT_FRAME;
-
- s->coded_picture_number = 0;
- s->picture_number = 0;
- s->input_picture_number = 0;
+void MPV_common_defaults(MpegEncContext *s)
+{
+ s->y_dc_scale_table =
+ s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
+ s->chroma_qscale_table = ff_default_chroma_qscale_table;
+ s->progressive_frame = 1;
+ s->progressive_sequence = 1;
+ s->picture_structure = PICT_FRAME;
+
+ s->coded_picture_number = 0;
+ s->picture_number = 0;
+ s->input_picture_number = 0;
s->picture_in_gop_number = 0;
- s->f_code = 1;
- s->b_code = 1;
+ s->f_code = 1;
+ s->b_code = 1;
- s->picture_range_start = 0;
- s->picture_range_end = MAX_PICTURE_COUNT;
+ s->picture_range_start = 0;
+ s->picture_range_end = MAX_PICTURE_COUNT;
}
/**
- * sets the given MpegEncContext to defaults for decoding.
- * the changed fields will not depend upon the prior state of the MpegEncContext.
+ * Set the given MpegEncContext to defaults for decoding.
+ * the changed fields will not depend upon
+ * the prior state of the MpegEncContext.
*/
-void MPV_decode_defaults(MpegEncContext *s){
+void MPV_decode_defaults(MpegEncContext *s)
+{
MPV_common_defaults(s);
}
@@ -575,158 +655,209 @@ void MPV_decode_defaults(MpegEncContext *s){
*/
av_cold int MPV_common_init(MpegEncContext *s)
{
- int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y, threads;
+ int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y,
+ threads = (s->encoding ||
+ (HAVE_THREADS &&
+ s->avctx->active_thread_type & FF_THREAD_SLICE)) ?
+ s->avctx->thread_count : 1;
- if(s->codec_id == CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
+ if (s->codec_id == CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
s->mb_height = (s->height + 31) / 32 * 2;
else if (s->codec_id != CODEC_ID_H264)
s->mb_height = (s->height + 15) / 16;
- if(s->avctx->pix_fmt == PIX_FMT_NONE){
- av_log(s->avctx, AV_LOG_ERROR, "decoding to PIX_FMT_NONE is not supported.\n");
+ if (s->avctx->pix_fmt == PIX_FMT_NONE) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "decoding to PIX_FMT_NONE is not supported.\n");
return -1;
}
- if((s->encoding || (s->avctx->active_thread_type & FF_THREAD_SLICE)) &&
- (s->avctx->thread_count > MAX_THREADS || (s->avctx->thread_count > s->mb_height && s->mb_height))){
- av_log(s->avctx, AV_LOG_ERROR, "too many threads\n");
- return -1;
+ if ((s->encoding || (s->avctx->active_thread_type & FF_THREAD_SLICE)) &&
+ (s->avctx->thread_count > MAX_THREADS ||
+ (s->avctx->thread_count > s->mb_height && s->mb_height))) {
+ int max_threads = FFMIN(MAX_THREADS, s->mb_height);
+ av_log(s->avctx, AV_LOG_WARNING,
+ "too many threads (%d), reducing to %d\n",
+ s->avctx->thread_count, max_threads);
+ threads = max_threads;
}
- if((s->width || s->height) && av_image_check_size(s->width, s->height, 0, s->avctx))
+ if ((s->width || s->height) &&
+ av_image_check_size(s->width, s->height, 0, s->avctx))
return -1;
- dsputil_init(&s->dsp, s->avctx);
ff_dct_common_init(s);
- s->flags= s->avctx->flags;
- s->flags2= s->avctx->flags2;
+ s->flags = s->avctx->flags;
+ s->flags2 = s->avctx->flags2;
if (s->width && s->height) {
- s->mb_width = (s->width + 15) / 16;
- s->mb_stride = s->mb_width + 1;
- s->b8_stride = s->mb_width*2 + 1;
- s->b4_stride = s->mb_width*4 + 1;
- mb_array_size= s->mb_height * s->mb_stride;
- mv_table_size= (s->mb_height+2) * s->mb_stride + 1;
+ s->mb_width = (s->width + 15) / 16;
+ s->mb_stride = s->mb_width + 1;
+ s->b8_stride = s->mb_width * 2 + 1;
+ s->b4_stride = s->mb_width * 4 + 1;
+ mb_array_size = s->mb_height * s->mb_stride;
+ mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
/* set chroma shifts */
avcodec_get_chroma_sub_sample(s->avctx->pix_fmt,&(s->chroma_x_shift),
&(s->chroma_y_shift) );
- /* set default edge pos, will be overriden in decode_header if needed */
- s->h_edge_pos= s->mb_width*16;
- s->v_edge_pos= s->mb_height*16;
+ /* set default edge pos, will be overriden
+ * in decode_header if needed */
+ s->h_edge_pos = s->mb_width * 16;
+ s->v_edge_pos = s->mb_height * 16;
- s->mb_num = s->mb_width * s->mb_height;
+ s->mb_num = s->mb_width * s->mb_height;
- s->block_wrap[0]=
- s->block_wrap[1]=
- s->block_wrap[2]=
- s->block_wrap[3]= s->b8_stride;
- s->block_wrap[4]=
- s->block_wrap[5]= s->mb_stride;
+ s->block_wrap[0] =
+ s->block_wrap[1] =
+ s->block_wrap[2] =
+ s->block_wrap[3] = s->b8_stride;
+ s->block_wrap[4] =
+ s->block_wrap[5] = s->mb_stride;
- y_size = s->b8_stride * (2 * s->mb_height + 1);
- c_size = s->mb_stride * (s->mb_height + 1);
- yc_size = y_size + 2 * c_size;
+ y_size = s->b8_stride * (2 * s->mb_height + 1);
+ c_size = s->mb_stride * (s->mb_height + 1);
+ yc_size = y_size + 2 * c_size;
/* convert fourcc to upper case */
- s->codec_tag = ff_toupper4(s->avctx->codec_tag);
+ s->codec_tag = avpriv_toupper4(s->avctx->codec_tag);
- s->stream_codec_tag = ff_toupper4(s->avctx->stream_codec_tag);
+ s->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag);
- s->avctx->coded_frame= (AVFrame*)&s->current_picture;
+ s->avctx->coded_frame = (AVFrame *)&s->current_picture;
- FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num+1)*sizeof(int), fail) //error ressilience code looks cleaner with this
- for(y=0; y<s->mb_height; y++){
- for(x=0; x<s->mb_width; x++){
- s->mb_index2xy[ x + y*s->mb_width ] = x + y*s->mb_stride;
- }
- }
- s->mb_index2xy[ s->mb_height*s->mb_width ] = (s->mb_height-1)*s->mb_stride + s->mb_width; //FIXME really needed?
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int),
+ fail); // error ressilience code looks cleaner with this
+ for (y = 0; y < s->mb_height; y++)
+ for (x = 0; x < s->mb_width; x++)
+ s->mb_index2xy[x + y * s->mb_width] = x + y * s->mb_stride;
+
+ s->mb_index2xy[s->mb_height * s->mb_width] =
+ (s->mb_height - 1) * s->mb_stride + s->mb_width; // FIXME really needed?
if (s->encoding) {
/* Allocate MV tables */
- FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail)
- s->p_mv_table = s->p_mv_table_base + s->mb_stride + 1;
- s->b_forw_mv_table = s->b_forw_mv_table_base + s->mb_stride + 1;
- s->b_back_mv_table = s->b_back_mv_table_base + s->mb_stride + 1;
- s->b_bidir_forw_mv_table= s->b_bidir_forw_mv_table_base + s->mb_stride + 1;
- s->b_bidir_back_mv_table= s->b_bidir_back_mv_table_base + s->mb_stride + 1;
- s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1;
-
- if(s->msmpeg4_version){
- FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats, 2*2*(MAX_LEVEL+1)*(MAX_RUN+1)*2*sizeof(int), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base,
+ mv_table_size * 2 * sizeof(int16_t), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base,
+ mv_table_size * 2 * sizeof(int16_t), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base,
+ mv_table_size * 2 * sizeof(int16_t), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base,
+ mv_table_size * 2 * sizeof(int16_t), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base,
+ mv_table_size * 2 * sizeof(int16_t), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base,
+ mv_table_size * 2 * sizeof(int16_t), fail);
+ s->p_mv_table = s->p_mv_table_base +
+ s->mb_stride + 1;
+ s->b_forw_mv_table = s->b_forw_mv_table_base +
+ s->mb_stride + 1;
+ s->b_back_mv_table = s->b_back_mv_table_base +
+ s->mb_stride + 1;
+ s->b_bidir_forw_mv_table = s->b_bidir_forw_mv_table_base +
+ s->mb_stride + 1;
+ s->b_bidir_back_mv_table = s->b_bidir_back_mv_table_base +
+ s->mb_stride + 1;
+ s->b_direct_mv_table = s->b_direct_mv_table_base +
+ s->mb_stride + 1;
+
+ if (s->msmpeg4_version) {
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats,
+ 2 * 2 * (MAX_LEVEL + 1) *
+ (MAX_RUN + 1) * 2 * sizeof(int), fail);
}
FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail);
/* Allocate MB type table */
- FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type , mb_array_size * sizeof(uint16_t), fail) //needed for encoding
-
- FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail)
-
- FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix , 64*32 * sizeof(int), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix , 64*32 * sizeof(int), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16, 64*32*2 * sizeof(uint16_t), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16, 64*32*2 * sizeof(uint16_t), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail)
-
- if(s->avctx->noise_reduction){
- FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, 2 * 64 * sizeof(uint16_t), fail)
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type, mb_array_size *
+ sizeof(uint16_t), fail); // needed for encoding
+
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size *
+ sizeof(int), fail);
+
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix,
+ 64 * 32 * sizeof(int), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix,
+ 64 * 32 * sizeof(int), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16,
+ 64 * 32 * 2 * sizeof(uint16_t), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16,
+ 64 * 32 * 2 * sizeof(uint16_t), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture,
+ MAX_PICTURE_COUNT * sizeof(Picture *), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture,
+ MAX_PICTURE_COUNT * sizeof(Picture *), fail);
+
+ if (s->avctx->noise_reduction) {
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset,
+ 2 * 64 * sizeof(uint16_t), fail);
}
}
}
s->picture_count = MAX_PICTURE_COUNT * FFMAX(1, s->avctx->thread_count);
- FF_ALLOCZ_OR_GOTO(s->avctx, s->picture, s->picture_count * sizeof(Picture), fail)
- for(i = 0; i < s->picture_count; i++) {
- avcodec_get_frame_defaults((AVFrame *)&s->picture[i]);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->picture,
+ s->picture_count * sizeof(Picture), fail);
+ for (i = 0; i < s->picture_count; i++) {
+ avcodec_get_frame_defaults((AVFrame *) &s->picture[i]);
}
if (s->width && s->height) {
- FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table, mb_array_size*sizeof(uint8_t), fail)
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table,
+ mb_array_size * sizeof(uint8_t), fail);
- if(s->codec_id==CODEC_ID_MPEG4 || (s->flags & CODEC_FLAG_INTERLACED_ME)){
+ if (s->codec_id == CODEC_ID_MPEG4 ||
+ (s->flags & CODEC_FLAG_INTERLACED_ME)) {
/* interlaced direct mode decoding tables */
- for(i=0; i<2; i++){
+ for (i = 0; i < 2; i++) {
int j, k;
- for(j=0; j<2; j++){
- for(k=0; k<2; k++){
- FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_mv_table_base[i][j][k], mv_table_size * 2 * sizeof(int16_t), fail)
- s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] + s->mb_stride + 1;
+ for (j = 0; j < 2; j++) {
+ for (k = 0; k < 2; k++) {
+ FF_ALLOCZ_OR_GOTO(s->avctx,
+ s->b_field_mv_table_base[i][j][k],
+ mv_table_size * 2 * sizeof(int16_t),
+ fail);
+ s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] +
+ s->mb_stride + 1;
}
- FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], mb_array_size * 2 * sizeof(uint8_t), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], mv_table_size * 2 * sizeof(int16_t), fail)
- s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j]+ s->mb_stride + 1;
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j],
+ mb_array_size * 2 * sizeof(uint8_t),
+ fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j],
+ mv_table_size * 2 * sizeof(int16_t),
+ fail);
+ s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j]
+ + s->mb_stride + 1;
}
- FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], mb_array_size * 2 * sizeof(uint8_t), fail)
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i],
+ mb_array_size * 2 * sizeof(uint8_t),
+ fail);
}
}
if (s->out_format == FMT_H263) {
/* cbp values */
FF_ALLOCZ_OR_GOTO(s->avctx, s->coded_block_base, y_size, fail);
- s->coded_block= s->coded_block_base + s->b8_stride + 1;
+ s->coded_block = s->coded_block_base + s->b8_stride + 1;
/* cbp, ac_pred, pred_dir */
- FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table , mb_array_size * sizeof(uint8_t), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, mb_array_size * sizeof(uint8_t), fail)
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table,
+ mb_array_size * sizeof(uint8_t), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table,
+ mb_array_size * sizeof(uint8_t), fail);
}
if (s->h263_pred || s->h263_plus || !s->encoding) {
/* dc values */
- //MN: we need these for error resilience of intra-frames
- FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, yc_size * sizeof(int16_t), fail);
+ // MN: we need these for error resilience of intra-frames
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base,
+ yc_size * sizeof(int16_t), fail);
s->dc_val[0] = s->dc_val_base + s->b8_stride + 1;
s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1;
s->dc_val[2] = s->dc_val[1] + c_size;
- for(i=0;i<yc_size;i++)
+ for (i = 0; i < yc_size; i++)
s->dc_val_base[i] = 1024;
}
@@ -735,41 +866,48 @@ av_cold int MPV_common_init(MpegEncContext *s)
memset(s->mbintra_table, 1, mb_array_size);
/* init macroblock skip table */
- FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size+2, fail);
- //Note the +1 is for a quicker mpeg4 slice_end detection
- FF_ALLOCZ_OR_GOTO(s->avctx, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE, fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size + 2, fail);
+ // Note the + 1 is for a quicker mpeg4 slice_end detection
- s->parse_context.state= -1;
- if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){
- s->visualization_buffer[0] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);
- s->visualization_buffer[1] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);
- s->visualization_buffer[2] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);
+ s->parse_context.state = -1;
+ if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||
+ s->avctx->debug_mv) {
+ s->visualization_buffer[0] = av_malloc((s->mb_width * 16 +
+ 2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
+ s->visualization_buffer[1] = av_malloc((s->mb_width * 16 +
+ 2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
+ s->visualization_buffer[2] = av_malloc((s->mb_width * 16 +
+ 2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
}
}
s->context_initialized = 1;
- s->thread_context[0]= s;
+ s->thread_context[0] = s;
if (s->width && s->height) {
- if (s->encoding || (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_SLICE)) {
- threads = s->avctx->thread_count;
-
- for(i=1; i<threads; i++){
- s->thread_context[i]= av_malloc(sizeof(MpegEncContext));
- memcpy(s->thread_context[i], s, sizeof(MpegEncContext));
- }
+ if (s->encoding || (HAVE_THREADS &&
+ s->avctx->active_thread_type&FF_THREAD_SLICE)) {
+ for (i = 1; i < threads; i++) {
+ s->thread_context[i] = av_malloc(sizeof(MpegEncContext));
+ memcpy(s->thread_context[i], s, sizeof(MpegEncContext));
+ }
- for(i=0; i<threads; i++){
- if(init_duplicate_context(s->thread_context[i], s) < 0)
+ for (i = 0; i < threads; i++) {
+ if (init_duplicate_context(s->thread_context[i], s) < 0)
+ goto fail;
+ s->thread_context[i]->start_mb_y =
+ (s->mb_height * (i) + s->avctx->thread_count / 2) /
+ s->avctx->thread_count;
+ s->thread_context[i]->end_mb_y =
+ (s->mb_height * (i + 1) + s->avctx->thread_count / 2) /
+ s->avctx->thread_count;
+ }
+ } else {
+ if (init_duplicate_context(s, s) < 0)
goto fail;
- s->thread_context[i]->start_mb_y= (s->mb_height*(i ) + s->avctx->thread_count/2) / s->avctx->thread_count;
- s->thread_context[i]->end_mb_y = (s->mb_height*(i+1) + s->avctx->thread_count/2) / s->avctx->thread_count;
+ s->start_mb_y = 0;
+ s->end_mb_y = s->mb_height;
}
- } else {
- if(init_duplicate_context(s, s) < 0) goto fail;
- s->start_mb_y = 0;
- s->end_mb_y = s->mb_height;
- }
}
return 0;
@@ -783,17 +921,18 @@ void MPV_common_end(MpegEncContext *s)
{
int i, j, k;
- if (s->encoding || (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_SLICE)) {
- for(i=0; i<s->avctx->thread_count; i++){
+ if (s->encoding || (HAVE_THREADS &&
+ s->avctx->active_thread_type & FF_THREAD_SLICE)) {
+ for (i = 0; i < s->avctx->thread_count; i++) {
free_duplicate_context(s->thread_context[i]);
}
- for(i=1; i<s->avctx->thread_count; i++){
+ for (i = 1; i < s->avctx->thread_count; i++) {
av_freep(&s->thread_context[i]);
}
} else free_duplicate_context(s);
av_freep(&s->parse_context.buffer);
- s->parse_context.buffer_size=0;
+ s->parse_context.buffer_size = 0;
av_freep(&s->mb_type);
av_freep(&s->p_mv_table_base);
@@ -802,21 +941,21 @@ void MPV_common_end(MpegEncContext *s)
av_freep(&s->b_bidir_forw_mv_table_base);
av_freep(&s->b_bidir_back_mv_table_base);
av_freep(&s->b_direct_mv_table_base);
- s->p_mv_table= NULL;
- s->b_forw_mv_table= NULL;
- s->b_back_mv_table= NULL;
- s->b_bidir_forw_mv_table= NULL;
- s->b_bidir_back_mv_table= NULL;
- s->b_direct_mv_table= NULL;
- for(i=0; i<2; i++){
- for(j=0; j<2; j++){
- for(k=0; k<2; k++){
+ s->p_mv_table = NULL;
+ s->b_forw_mv_table = NULL;
+ s->b_back_mv_table = NULL;
+ s->b_bidir_forw_mv_table = NULL;
+ s->b_bidir_back_mv_table = NULL;
+ s->b_direct_mv_table = NULL;
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ for (k = 0; k < 2; k++) {
av_freep(&s->b_field_mv_table_base[i][j][k]);
- s->b_field_mv_table[i][j][k]=NULL;
+ s->b_field_mv_table[i][j][k] = NULL;
}
av_freep(&s->b_field_select_table[i][j]);
av_freep(&s->p_field_mv_table_base[i][j]);
- s->p_field_mv_table[i][j]=NULL;
+ s->p_field_mv_table[i][j] = NULL;
}
av_freep(&s->p_field_select_table[i]);
}
@@ -828,9 +967,8 @@ void MPV_common_end(MpegEncContext *s)
av_freep(&s->pred_dir_table);
av_freep(&s->mbskip_table);
- av_freep(&s->prev_pict_types);
av_freep(&s->bitstream_buffer);
- s->allocated_bitstream_buffer_size=0;
+ s->allocated_bitstream_buffer_size = 0;
av_freep(&s->avctx->stats_out);
av_freep(&s->ac_stats);
@@ -845,37 +983,38 @@ void MPV_common_end(MpegEncContext *s)
av_freep(&s->reordered_input_picture);
av_freep(&s->dct_offset);
- if(s->picture && !s->avctx->is_copy){
- for(i=0; i<s->picture_count; i++){
+ if (s->picture && !s->avctx->internal->is_copy) {
+ for (i = 0; i < s->picture_count; i++) {
free_picture(s, &s->picture[i]);
}
}
av_freep(&s->picture);
- s->context_initialized = 0;
- s->last_picture_ptr=
- s->next_picture_ptr=
- s->current_picture_ptr= NULL;
- s->linesize= s->uvlinesize= 0;
+ s->context_initialized = 0;
+ s->last_picture_ptr =
+ s->next_picture_ptr =
+ s->current_picture_ptr = NULL;
+ s->linesize = s->uvlinesize = 0;
- for(i=0; i<3; i++)
+ for (i = 0; i < 3; i++)
av_freep(&s->visualization_buffer[i]);
- if(!(s->avctx->active_thread_type&FF_THREAD_FRAME))
+ if (!(s->avctx->active_thread_type & FF_THREAD_FRAME))
avcodec_default_free_buffers(s->avctx);
}
-void init_rl(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3])
+void init_rl(RLTable *rl,
+ uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3])
{
- int8_t max_level[MAX_RUN+1], max_run[MAX_LEVEL+1];
- uint8_t index_run[MAX_RUN+1];
+ int8_t max_level[MAX_RUN + 1], max_run[MAX_LEVEL + 1];
+ uint8_t index_run[MAX_RUN + 1];
int last, run, level, start, end, i;
/* If table is static, we can quit if rl->max_level[0] is not NULL */
- if(static_store && rl->max_level[0])
+ if (static_store && rl->max_level[0])
return;
/* compute max_level[], max_run[] and index_run[] */
- for(last=0;last<2;last++) {
+ for (last = 0; last < 2; last++) {
if (last == 0) {
start = 0;
end = rl->last;
@@ -887,8 +1026,8 @@ void init_rl(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3])
memset(max_level, 0, MAX_RUN + 1);
memset(max_run, 0, MAX_LEVEL + 1);
memset(index_run, rl->n, MAX_RUN + 1);
- for(i=start;i<end;i++) {
- run = rl->table_run[i];
+ for (i = start; i < end; i++) {
+ run = rl->table_run[i];
level = rl->table_level[i];
if (index_run[run] == rl->n)
index_run[run] = i;
@@ -897,17 +1036,17 @@ void init_rl(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3])
if (run > max_run[level])
max_run[level] = run;
}
- if(static_store)
+ if (static_store)
rl->max_level[last] = static_store[last];
else
rl->max_level[last] = av_malloc(MAX_RUN + 1);
memcpy(rl->max_level[last], max_level, MAX_RUN + 1);
- if(static_store)
- rl->max_run[last] = static_store[last] + MAX_RUN + 1;
+ if (static_store)
+ rl->max_run[last] = static_store[last] + MAX_RUN + 1;
else
- rl->max_run[last] = av_malloc(MAX_LEVEL + 1);
+ rl->max_run[last] = av_malloc(MAX_LEVEL + 1);
memcpy(rl->max_run[last], max_run, MAX_LEVEL + 1);
- if(static_store)
+ if (static_store)
rl->index_run[last] = static_store[last] + MAX_RUN + MAX_LEVEL + 2;
else
rl->index_run[last] = av_malloc(MAX_RUN + 1);
@@ -919,108 +1058,104 @@ void init_vlc_rl(RLTable *rl)
{
int i, q;
- for(q=0; q<32; q++){
- int qmul= q*2;
- int qadd= (q-1)|1;
+ for (q = 0; q < 32; q++) {
+ int qmul = q * 2;
+ int qadd = (q - 1) | 1;
- if(q==0){
- qmul=1;
- qadd=0;
+ if (q == 0) {
+ qmul = 1;
+ qadd = 0;
}
- for(i=0; i<rl->vlc.table_size; i++){
- int code= rl->vlc.table[i][0];
- int len = rl->vlc.table[i][1];
+ for (i = 0; i < rl->vlc.table_size; i++) {
+ int code = rl->vlc.table[i][0];
+ int len = rl->vlc.table[i][1];
int level, run;
- if(len==0){ // illegal code
- run= 66;
- level= MAX_LEVEL;
- }else if(len<0){ //more bits needed
- run= 0;
- level= code;
- }else{
- if(code==rl->n){ //esc
- run= 66;
- level= 0;
- }else{
- run= rl->table_run [code] + 1;
- level= rl->table_level[code] * qmul + qadd;
- if(code >= rl->last) run+=192;
+ if (len == 0) { // illegal code
+ run = 66;
+ level = MAX_LEVEL;
+ } else if (len < 0) { // more bits needed
+ run = 0;
+ level = code;
+ } else {
+ if (code == rl->n) { // esc
+ run = 66;
+ level = 0;
+ } else {
+ run = rl->table_run[code] + 1;
+ level = rl->table_level[code] * qmul + qadd;
+ if (code >= rl->last) run += 192;
}
}
- rl->rl_vlc[q][i].len= len;
- rl->rl_vlc[q][i].level= level;
- rl->rl_vlc[q][i].run= run;
+ rl->rl_vlc[q][i].len = len;
+ rl->rl_vlc[q][i].level = level;
+ rl->rl_vlc[q][i].run = run;
}
}
}
-void ff_release_unused_pictures(MpegEncContext *s, int remove_current)
+void ff_release_unused_pictures(MpegEncContext*s, int remove_current)
{
int i;
/* release non reference frames */
- for(i=0; i<s->picture_count; i++){
- if(s->picture[i].data[0] && !s->picture[i].reference
- && (!s->picture[i].owner2 || s->picture[i].owner2 == s)
- && (remove_current || &s->picture[i] != s->current_picture_ptr)
- /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){
+ for (i = 0; i < s->picture_count; i++) {
+ if (s->picture[i].f.data[0] && !s->picture[i].f.reference &&
+ (!s->picture[i].owner2 || s->picture[i].owner2 == s) &&
+ (remove_current || &s->picture[i] != s->current_picture_ptr)
+ /* && s->picture[i].type!= FF_BUFFER_TYPE_SHARED */) {
free_frame_buffer(s, &s->picture[i]);
}
}
}
-int ff_find_unused_picture(MpegEncContext *s, int shared){
+int ff_find_unused_picture(MpegEncContext *s, int shared)
+{
int i;
- if(shared){
- for(i=s->picture_range_start; i<s->picture_range_end; i++){
- if(s->picture[i].data[0]==NULL && s->picture[i].type==0) return i;
+ if (shared) {
+ for (i = s->picture_range_start; i < s->picture_range_end; i++) {
+ if (s->picture[i].f.data[0] == NULL && s->picture[i].f.type == 0)
+ return i;
}
- }else{
- for(i=s->picture_range_start; i<s->picture_range_end; i++){
- if(s->picture[i].data[0]==NULL && s->picture[i].type!=0) return i; //FIXME
+ } else {
+ for (i = s->picture_range_start; i < s->picture_range_end; i++) {
+ if (s->picture[i].f.data[0] == NULL && s->picture[i].f.type != 0)
+ return i; // FIXME
}
- for(i=s->picture_range_start; i<s->picture_range_end; i++){
- if(s->picture[i].data[0]==NULL) return i;
+ for (i = s->picture_range_start; i < s->picture_range_end; i++) {
+ if (s->picture[i].f.data[0] == NULL)
+ return i;
}
}
- av_log(s->avctx, AV_LOG_FATAL, "Internal error, picture buffer overflow\n");
- /* We could return -1, but the codec would crash trying to draw into a
- * non-existing frame anyway. This is safer than waiting for a random crash.
- * Also the return of this is never useful, an encoder must only allocate
- * as much as allowed in the specification. This has no relationship to how
- * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large
- * enough for such valid streams).
- * Plus, a decoder has to check stream validity and remove frames if too
- * many reference frames are around. Waiting for "OOM" is not correct at
- * all. Similarly, missing reference frames have to be replaced by
- * interpolated/MC frames, anything else is a bug in the codec ...
- */
- abort();
- return -1;
+ return AVERROR_INVALIDDATA;
}
-static void update_noise_reduction(MpegEncContext *s){
+static void update_noise_reduction(MpegEncContext *s)
+{
int intra, i;
- for(intra=0; intra<2; intra++){
- if(s->dct_count[intra] > (1<<16)){
- for(i=0; i<64; i++){
- s->dct_error_sum[intra][i] >>=1;
+ for (intra = 0; intra < 2; intra++) {
+ if (s->dct_count[intra] > (1 << 16)) {
+ for (i = 0; i < 64; i++) {
+ s->dct_error_sum[intra][i] >>= 1;
}
s->dct_count[intra] >>= 1;
}
- for(i=0; i<64; i++){
- s->dct_offset[intra][i]= (s->avctx->noise_reduction * s->dct_count[intra] + s->dct_error_sum[intra][i]/2) / (s->dct_error_sum[intra][i]+1);
+ for (i = 0; i < 64; i++) {
+ s->dct_offset[intra][i] = (s->avctx->noise_reduction *
+ s->dct_count[intra] +
+ s->dct_error_sum[intra][i] / 2) /
+ (s->dct_error_sum[intra][i] + 1);
}
}
}
/**
- * generic function for encode/decode called after coding/decoding the header and before a frame is coded/decoded
+ * generic function for encode/decode called after coding/decoding
+ * the header and before a frame is coded/decoded.
*/
int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
{
@@ -1028,291 +1163,332 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
Picture *pic;
s->mb_skipped = 0;
- assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3);
-
- /* mark&release old frames */
- if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && s->last_picture_ptr->data[0]) {
- if(s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3){
- free_frame_buffer(s, s->last_picture_ptr);
-
- /* release forgotten pictures */
- /* if(mpeg124/h263) */
- if(!s->encoding){
- for(i=0; i<s->picture_count; i++){
- if(s->picture[i].data[0] && &s->picture[i] != s->next_picture_ptr && s->picture[i].reference){
- av_log(avctx, AV_LOG_ERROR, "releasing zombie picture\n");
- free_frame_buffer(s, &s->picture[i]);
+ assert(s->last_picture_ptr == NULL || s->out_format != FMT_H264 ||
+ s->codec_id == CODEC_ID_SVQ3);
+
+ /* mark & release old frames */
+ if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&
+ s->last_picture_ptr != s->next_picture_ptr &&
+ s->last_picture_ptr->f.data[0]) {
+ if (s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3) {
+ if (s->last_picture_ptr->owner2 == s)
+ free_frame_buffer(s, s->last_picture_ptr);
+
+ /* release forgotten pictures */
+ /* if (mpeg124/h263) */
+ if (!s->encoding) {
+ for (i = 0; i < s->picture_count; i++) {
+ if (s->picture[i].owner2 == s && s->picture[i].f.data[0] &&
+ &s->picture[i] != s->next_picture_ptr &&
+ s->picture[i].f.reference) {
+ if (!(avctx->active_thread_type & FF_THREAD_FRAME))
+ av_log(avctx, AV_LOG_ERROR,
+ "releasing zombie picture\n");
+ free_frame_buffer(s, &s->picture[i]);
+ }
}
}
}
- }
}
- if(!s->encoding){
+ if (!s->encoding) {
ff_release_unused_pictures(s, 1);
- if(s->current_picture_ptr && s->current_picture_ptr->data[0]==NULL)
- pic= s->current_picture_ptr; //we already have a unused image (maybe it was set before reading the header)
- else{
- i= ff_find_unused_picture(s, 0);
- pic= &s->picture[i];
+ if (s->current_picture_ptr &&
+ s->current_picture_ptr->f.data[0] == NULL) {
+ // we already have a unused image
+ // (maybe it was set before reading the header)
+ pic = s->current_picture_ptr;
+ } else {
+ i = ff_find_unused_picture(s, 0);
+ pic = &s->picture[i];
}
- pic->reference= 0;
- if (!s->dropable){
+ pic->f.reference = 0;
+ if (!s->dropable) {
if (s->codec_id == CODEC_ID_H264)
- pic->reference = s->picture_structure;
+ pic->f.reference = s->picture_structure;
else if (s->pict_type != AV_PICTURE_TYPE_B)
- pic->reference = 3;
+ pic->f.reference = 3;
}
- pic->coded_picture_number= s->coded_picture_number++;
+ pic->f.coded_picture_number = s->coded_picture_number++;
- if(ff_alloc_picture(s, pic, 0) < 0)
+ if (ff_alloc_picture(s, pic, 0) < 0)
return -1;
- s->current_picture_ptr= pic;
- //FIXME use only the vars from current_pic
- s->current_picture_ptr->top_field_first= s->top_field_first;
- if(s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO) {
- if(s->picture_structure != PICT_FRAME)
- s->current_picture_ptr->top_field_first= (s->picture_structure == PICT_TOP_FIELD) == s->first_field;
+ s->current_picture_ptr = pic;
+ // FIXME use only the vars from current_pic
+ s->current_picture_ptr->f.top_field_first = s->top_field_first;
+ if (s->codec_id == CODEC_ID_MPEG1VIDEO ||
+ s->codec_id == CODEC_ID_MPEG2VIDEO) {
+ if (s->picture_structure != PICT_FRAME)
+ s->current_picture_ptr->f.top_field_first =
+ (s->picture_structure == PICT_TOP_FIELD) == s->first_field;
}
- s->current_picture_ptr->interlaced_frame= !s->progressive_frame && !s->progressive_sequence;
- s->current_picture_ptr->field_picture= s->picture_structure != PICT_FRAME;
+ s->current_picture_ptr->f.interlaced_frame = !s->progressive_frame &&
+ !s->progressive_sequence;
+ s->current_picture_ptr->field_picture = s->picture_structure != PICT_FRAME;
}
- s->current_picture_ptr->pict_type= s->pict_type;
-// if(s->flags && CODEC_FLAG_QSCALE)
- // s->current_picture_ptr->quality= s->new_picture_ptr->quality;
- s->current_picture_ptr->key_frame= s->pict_type == AV_PICTURE_TYPE_I;
+ s->current_picture_ptr->f.pict_type = s->pict_type;
+ // if (s->flags && CODEC_FLAG_QSCALE)
+ // s->current_picture_ptr->quality = s->new_picture_ptr->quality;
+ s->current_picture_ptr->f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
ff_copy_picture(&s->current_picture, s->current_picture_ptr);
if (s->pict_type != AV_PICTURE_TYPE_B) {
- s->last_picture_ptr= s->next_picture_ptr;
- if(!s->dropable)
- s->next_picture_ptr= s->current_picture_ptr;
- }
-/* av_log(s->avctx, AV_LOG_DEBUG, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n", s->last_picture_ptr, s->next_picture_ptr,s->current_picture_ptr,
- s->last_picture_ptr ? s->last_picture_ptr->data[0] : NULL,
- s->next_picture_ptr ? s->next_picture_ptr->data[0] : NULL,
- s->current_picture_ptr ? s->current_picture_ptr->data[0] : NULL,
- s->pict_type, s->dropable);*/
-
- if(s->codec_id != CODEC_ID_H264){
- if((s->last_picture_ptr==NULL || s->last_picture_ptr->data[0]==NULL) &&
- (s->pict_type!=AV_PICTURE_TYPE_I || s->picture_structure != PICT_FRAME)){
+ s->last_picture_ptr = s->next_picture_ptr;
+ if (!s->dropable)
+ s->next_picture_ptr = s->current_picture_ptr;
+ }
+ /* av_log(s->avctx, AV_LOG_DEBUG, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n",
+ s->last_picture_ptr, s->next_picture_ptr,s->current_picture_ptr,
+ s->last_picture_ptr ? s->last_picture_ptr->f.data[0] : NULL,
+ s->next_picture_ptr ? s->next_picture_ptr->f.data[0] : NULL,
+ s->current_picture_ptr ? s->current_picture_ptr->f.data[0] : NULL,
+ s->pict_type, s->dropable); */
+
+ if (s->codec_id != CODEC_ID_H264) {
+ if ((s->last_picture_ptr == NULL ||
+ s->last_picture_ptr->f.data[0] == NULL) &&
+ (s->pict_type != AV_PICTURE_TYPE_I ||
+ s->picture_structure != PICT_FRAME)) {
if (s->pict_type != AV_PICTURE_TYPE_I)
- av_log(avctx, AV_LOG_ERROR, "warning: first frame is no keyframe\n");
+ av_log(avctx, AV_LOG_ERROR,
+ "warning: first frame is no keyframe\n");
else if (s->picture_structure != PICT_FRAME)
- av_log(avctx, AV_LOG_INFO, "allocate dummy last picture for field based first keyframe\n");
+ av_log(avctx, AV_LOG_INFO,
+ "allocate dummy last picture for field based first keyframe\n");
/* Allocate a dummy frame */
- i= ff_find_unused_picture(s, 0);
- s->last_picture_ptr= &s->picture[i];
- if(ff_alloc_picture(s, s->last_picture_ptr, 0) < 0)
+ i = ff_find_unused_picture(s, 0);
+ s->last_picture_ptr = &s->picture[i];
+ if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0)
return -1;
- ff_thread_report_progress((AVFrame*)s->last_picture_ptr, INT_MAX, 0);
- ff_thread_report_progress((AVFrame*)s->last_picture_ptr, INT_MAX, 1);
- }
- if((s->next_picture_ptr==NULL || s->next_picture_ptr->data[0]==NULL) && s->pict_type==AV_PICTURE_TYPE_B){
+ ff_thread_report_progress((AVFrame *) s->last_picture_ptr,
+ INT_MAX, 0);
+ ff_thread_report_progress((AVFrame *) s->last_picture_ptr,
+ INT_MAX, 1);
+ }
+ if ((s->next_picture_ptr == NULL ||
+ s->next_picture_ptr->f.data[0] == NULL) &&
+ s->pict_type == AV_PICTURE_TYPE_B) {
/* Allocate a dummy frame */
- i= ff_find_unused_picture(s, 0);
- s->next_picture_ptr= &s->picture[i];
- if(ff_alloc_picture(s, s->next_picture_ptr, 0) < 0)
+ i = ff_find_unused_picture(s, 0);
+ s->next_picture_ptr = &s->picture[i];
+ if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0)
return -1;
- ff_thread_report_progress((AVFrame*)s->next_picture_ptr, INT_MAX, 0);
- ff_thread_report_progress((AVFrame*)s->next_picture_ptr, INT_MAX, 1);
+ ff_thread_report_progress((AVFrame *) s->next_picture_ptr,
+ INT_MAX, 0);
+ ff_thread_report_progress((AVFrame *) s->next_picture_ptr,
+ INT_MAX, 1);
}
}
- if(s->last_picture_ptr) ff_copy_picture(&s->last_picture, s->last_picture_ptr);
- if(s->next_picture_ptr) ff_copy_picture(&s->next_picture, s->next_picture_ptr);
+ if (s->last_picture_ptr)
+ ff_copy_picture(&s->last_picture, s->last_picture_ptr);
+ if (s->next_picture_ptr)
+ ff_copy_picture(&s->next_picture, s->next_picture_ptr);
- assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && s->last_picture_ptr->data[0]));
+ assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
+ s->last_picture_ptr->f.data[0]));
- if(s->picture_structure!=PICT_FRAME && s->out_format != FMT_H264){
+ if (s->picture_structure!= PICT_FRAME && s->out_format != FMT_H264) {
int i;
- for(i=0; i<4; i++){
- if(s->picture_structure == PICT_BOTTOM_FIELD){
- s->current_picture.data[i] += s->current_picture.linesize[i];
+ for (i = 0; i < 4; i++) {
+ if (s->picture_structure == PICT_BOTTOM_FIELD) {
+ s->current_picture.f.data[i] +=
+ s->current_picture.f.linesize[i];
}
- s->current_picture.linesize[i] *= 2;
- s->last_picture.linesize[i] *=2;
- s->next_picture.linesize[i] *=2;
+ s->current_picture.f.linesize[i] *= 2;
+ s->last_picture.f.linesize[i] *= 2;
+ s->next_picture.f.linesize[i] *= 2;
}
}
- s->error_recognition= avctx->error_recognition;
+ s->err_recognition = avctx->err_recognition;
- /* set dequantizer, we can't do it during init as it might change for mpeg4
- and we can't do it in the header decode as init is not called for mpeg4 there yet */
- if(s->mpeg_quant || s->codec_id == CODEC_ID_MPEG2VIDEO){
+ /* set dequantizer, we can't do it during init as
+ * it might change for mpeg4 and we can't do it in the header
+ * decode as init is not called for mpeg4 there yet */
+ if (s->mpeg_quant || s->codec_id == CODEC_ID_MPEG2VIDEO) {
s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;
s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;
- }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
+ } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
s->dct_unquantize_intra = s->dct_unquantize_h263_intra;
s->dct_unquantize_inter = s->dct_unquantize_h263_inter;
- }else{
+ } else {
s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;
s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;
}
- if(s->dct_error_sum){
+ if (s->dct_error_sum) {
assert(s->avctx->noise_reduction && s->encoding);
-
update_noise_reduction(s);
}
- if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
+ if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
return ff_xvmc_field_start(s, avctx);
return 0;
}
-/* generic function for encode/decode called after a frame has been coded/decoded */
+/* generic function for encode/decode called after a
+ * frame has been coded/decoded. */
void MPV_frame_end(MpegEncContext *s)
{
int i;
/* redraw edges for the frame if decoding didn't complete */
- //just to make sure that all data is rendered.
- if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
+ // just to make sure that all data is rendered.
+ if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) {
ff_xvmc_field_end(s);
- }else if((s->error_count || s->encoding)
- && !s->avctx->hwaccel
- && !(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
- && s->unrestricted_mv
- && s->current_picture.reference
- && !s->intra_only
- && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
- int hshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_w;
- int vshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_h;
- s->dsp.draw_edges(s->current_picture.data[0], s->linesize ,
- s->h_edge_pos , s->v_edge_pos,
- EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM);
- s->dsp.draw_edges(s->current_picture.data[1], s->uvlinesize,
- s->h_edge_pos>>hshift, s->v_edge_pos>>vshift,
- EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, EDGE_TOP | EDGE_BOTTOM);
- s->dsp.draw_edges(s->current_picture.data[2], s->uvlinesize,
- s->h_edge_pos>>hshift, s->v_edge_pos>>vshift,
- EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, EDGE_TOP | EDGE_BOTTOM);
+ } else if ((s->error_count || s->encoding) &&
+ !s->avctx->hwaccel &&
+ !(s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) &&
+ s->unrestricted_mv &&
+ s->current_picture.f.reference &&
+ !s->intra_only &&
+ !(s->flags & CODEC_FLAG_EMU_EDGE)) {
+ int hshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_w;
+ int vshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_h;
+ s->dsp.draw_edges(s->current_picture.f.data[0], s->linesize,
+ s->h_edge_pos, s->v_edge_pos,
+ EDGE_WIDTH, EDGE_WIDTH,
+ EDGE_TOP | EDGE_BOTTOM);
+ s->dsp.draw_edges(s->current_picture.f.data[1], s->uvlinesize,
+ s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
+ EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
+ EDGE_TOP | EDGE_BOTTOM);
+ s->dsp.draw_edges(s->current_picture.f.data[2], s->uvlinesize,
+ s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
+ EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
+ EDGE_TOP | EDGE_BOTTOM);
}
emms_c();
- s->last_pict_type = s->pict_type;
- s->last_lambda_for[s->pict_type]= s->current_picture_ptr->quality;
- if(s->pict_type!=AV_PICTURE_TYPE_B){
- s->last_non_b_pict_type= s->pict_type;
+ s->last_pict_type = s->pict_type;
+ s->last_lambda_for [s->pict_type] = s->current_picture_ptr->f.quality;
+ if (s->pict_type!= AV_PICTURE_TYPE_B) {
+ s->last_non_b_pict_type = s->pict_type;
}
#if 0
- /* copy back current_picture variables */
- for(i=0; i<MAX_PICTURE_COUNT; i++){
- if(s->picture[i].data[0] == s->current_picture.data[0]){
- s->picture[i]= s->current_picture;
+ /* copy back current_picture variables */
+ for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+ if (s->picture[i].f.data[0] == s->current_picture.f.data[0]) {
+ s->picture[i] = s->current_picture;
break;
}
}
- assert(i<MAX_PICTURE_COUNT);
+ assert(i < MAX_PICTURE_COUNT);
#endif
- if(s->encoding){
+ if (s->encoding) {
/* release non-reference frames */
- for(i=0; i<s->picture_count; i++){
- if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){
+ for (i = 0; i < s->picture_count; i++) {
+ if (s->picture[i].f.data[0] && !s->picture[i].f.reference
+ /* && s->picture[i].type != FF_BUFFER_TYPE_SHARED */) {
free_frame_buffer(s, &s->picture[i]);
}
}
}
// clear copies, to avoid confusion
#if 0
- memset(&s->last_picture, 0, sizeof(Picture));
- memset(&s->next_picture, 0, sizeof(Picture));
+ memset(&s->last_picture, 0, sizeof(Picture));
+ memset(&s->next_picture, 0, sizeof(Picture));
memset(&s->current_picture, 0, sizeof(Picture));
#endif
- s->avctx->coded_frame= (AVFrame*)s->current_picture_ptr;
+ s->avctx->coded_frame = (AVFrame *) s->current_picture_ptr;
- if (s->codec_id != CODEC_ID_H264 && s->current_picture.reference) {
- ff_thread_report_progress((AVFrame*)s->current_picture_ptr, s->mb_height-1, 0);
+ if (s->codec_id != CODEC_ID_H264 && s->current_picture.f.reference) {
+ ff_thread_report_progress((AVFrame *) s->current_picture_ptr,
+ s->mb_height - 1, 0);
}
}
/**
- * draws an line from (ex, ey) -> (sx, sy).
+ * Draw a line from (ex, ey) -> (sx, sy).
* @param w width of the image
* @param h height of the image
* @param stride stride/linesize of the image
* @param color color of the arrow
*/
-static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int h, int stride, int color){
+static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey,
+ int w, int h, int stride, int color)
+{
int x, y, fr, f;
- sx= av_clip(sx, 0, w-1);
- sy= av_clip(sy, 0, h-1);
- ex= av_clip(ex, 0, w-1);
- ey= av_clip(ey, 0, h-1);
+ sx = av_clip(sx, 0, w - 1);
+ sy = av_clip(sy, 0, h - 1);
+ ex = av_clip(ex, 0, w - 1);
+ ey = av_clip(ey, 0, h - 1);
- buf[sy*stride + sx]+= color;
+ buf[sy * stride + sx] += color;
- if(FFABS(ex - sx) > FFABS(ey - sy)){
- if(sx > ex){
+ if (FFABS(ex - sx) > FFABS(ey - sy)) {
+ if (sx > ex) {
FFSWAP(int, sx, ex);
FFSWAP(int, sy, ey);
}
- buf+= sx + sy*stride;
- ex-= sx;
- f= ((ey-sy)<<16)/ex;
- for(x= 0; x <= ex; x++){
- y = (x*f)>>16;
- fr= (x*f)&0xFFFF;
- buf[ y *stride + x]+= (color*(0x10000-fr))>>16;
- buf[(y+1)*stride + x]+= (color* fr )>>16;
+ buf += sx + sy * stride;
+ ex -= sx;
+ f = ((ey - sy) << 16) / ex;
+ for (x = 0; x = ex; x++) {
+ y = (x * f) >> 16;
+ fr = (x * f) & 0xFFFF;
+ buf[y * stride + x] += (color * (0x10000 - fr)) >> 16;
+ buf[(y + 1) * stride + x] += (color * fr ) >> 16;
}
- }else{
- if(sy > ey){
+ } else {
+ if (sy > ey) {
FFSWAP(int, sx, ex);
FFSWAP(int, sy, ey);
}
- buf+= sx + sy*stride;
- ey-= sy;
- if(ey) f= ((ex-sx)<<16)/ey;
- else f= 0;
- for(y= 0; y <= ey; y++){
- x = (y*f)>>16;
- fr= (y*f)&0xFFFF;
- buf[y*stride + x ]+= (color*(0x10000-fr))>>16;
- buf[y*stride + x+1]+= (color* fr )>>16;
+ buf += sx + sy * stride;
+ ey -= sy;
+ if (ey)
+ f = ((ex - sx) << 16) / ey;
+ else
+ f = 0;
+ for (y = 0; y = ey; y++) {
+ x = (y * f) >> 16;
+ fr = (y * f) & 0xFFFF;
+ buf[y * stride + x] += (color * (0x10000 - fr)) >> 16;
+ buf[y * stride + x + 1] += (color * fr ) >> 16;
}
}
}
/**
- * draws an arrow from (ex, ey) -> (sx, sy).
+ * Draw an arrow from (ex, ey) -> (sx, sy).
* @param w width of the image
* @param h height of the image
* @param stride stride/linesize of the image
* @param color color of the arrow
*/
-static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int h, int stride, int color){
+static void draw_arrow(uint8_t *buf, int sx, int sy, int ex,
+ int ey, int w, int h, int stride, int color)
+{
int dx,dy;
- sx= av_clip(sx, -100, w+100);
- sy= av_clip(sy, -100, h+100);
- ex= av_clip(ex, -100, w+100);
- ey= av_clip(ey, -100, h+100);
+ sx = av_clip(sx, -100, w + 100);
+ sy = av_clip(sy, -100, h + 100);
+ ex = av_clip(ex, -100, w + 100);
+ ey = av_clip(ey, -100, h + 100);
- dx= ex - sx;
- dy= ey - sy;
+ dx = ex - sx;
+ dy = ey - sy;
- if(dx*dx + dy*dy > 3*3){
- int rx= dx + dy;
- int ry= -dx + dy;
- int length= ff_sqrt((rx*rx + ry*ry)<<8);
+ if (dx * dx + dy * dy > 3 * 3) {
+ int rx = dx + dy;
+ int ry = -dx + dy;
+ int length = ff_sqrt((rx * rx + ry * ry) << 8);
- //FIXME subpixel accuracy
- rx= ROUNDED_DIV(rx*3<<4, length);
- ry= ROUNDED_DIV(ry*3<<4, length);
+ // FIXME subpixel accuracy
+ rx = ROUNDED_DIV(rx * 3 << 4, length);
+ ry = ROUNDED_DIV(ry * 3 << 4, length);
draw_line(buf, sx, sy, sx + rx, sy + ry, w, h, stride, color);
draw_line(buf, sx, sy, sx - ry, sy + rx, w, h, stride, color);
@@ -1321,305 +1497,354 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int
}
/**
- * prints debuging info for the given picture.
+ * Print debugging info for the given picture.
*/
-void ff_print_debug_info(MpegEncContext *s, AVFrame *pict){
-
- if(s->avctx->hwaccel || !pict || !pict->mb_type) return;
+void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
+{
+ if (s->avctx->hwaccel || !pict || !pict->mb_type)
+ return;
- if(s->avctx->debug&(FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)){
+ if (s->avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) {
int x,y;
av_log(s->avctx,AV_LOG_DEBUG,"New frame, type: ");
switch (pict->pict_type) {
- case AV_PICTURE_TYPE_I: av_log(s->avctx,AV_LOG_DEBUG,"I\n"); break;
- case AV_PICTURE_TYPE_P: av_log(s->avctx,AV_LOG_DEBUG,"P\n"); break;
- case AV_PICTURE_TYPE_B: av_log(s->avctx,AV_LOG_DEBUG,"B\n"); break;
- case AV_PICTURE_TYPE_S: av_log(s->avctx,AV_LOG_DEBUG,"S\n"); break;
- case AV_PICTURE_TYPE_SI: av_log(s->avctx,AV_LOG_DEBUG,"SI\n"); break;
- case AV_PICTURE_TYPE_SP: av_log(s->avctx,AV_LOG_DEBUG,"SP\n"); break;
- }
- for(y=0; y<s->mb_height; y++){
- for(x=0; x<s->mb_width; x++){
- if(s->avctx->debug&FF_DEBUG_SKIP){
- int count= s->mbskip_table[x + y*s->mb_stride];
- if(count>9) count=9;
+ case AV_PICTURE_TYPE_I:
+ av_log(s->avctx,AV_LOG_DEBUG,"I\n");
+ break;
+ case AV_PICTURE_TYPE_P:
+ av_log(s->avctx,AV_LOG_DEBUG,"P\n");
+ break;
+ case AV_PICTURE_TYPE_B:
+ av_log(s->avctx,AV_LOG_DEBUG,"B\n");
+ break;
+ case AV_PICTURE_TYPE_S:
+ av_log(s->avctx,AV_LOG_DEBUG,"S\n");
+ break;
+ case AV_PICTURE_TYPE_SI:
+ av_log(s->avctx,AV_LOG_DEBUG,"SI\n");
+ break;
+ case AV_PICTURE_TYPE_SP:
+ av_log(s->avctx,AV_LOG_DEBUG,"SP\n");
+ break;
+ }
+ for (y = 0; y < s->mb_height; y++) {
+ for (x = 0; x < s->mb_width; x++) {
+ if (s->avctx->debug & FF_DEBUG_SKIP) {
+ int count = s->mbskip_table[x + y * s->mb_stride];
+ if (count > 9)
+ count = 9;
av_log(s->avctx, AV_LOG_DEBUG, "%1d", count);
}
- if(s->avctx->debug&FF_DEBUG_QP){
- av_log(s->avctx, AV_LOG_DEBUG, "%2d", pict->qscale_table[x + y*s->mb_stride]);
+ if (s->avctx->debug & FF_DEBUG_QP) {
+ av_log(s->avctx, AV_LOG_DEBUG, "%2d",
+ pict->qscale_table[x + y * s->mb_stride]);
}
- if(s->avctx->debug&FF_DEBUG_MB_TYPE){
- int mb_type= pict->mb_type[x + y*s->mb_stride];
- //Type & MV direction
- if(IS_PCM(mb_type))
+ if (s->avctx->debug & FF_DEBUG_MB_TYPE) {
+ int mb_type = pict->mb_type[x + y * s->mb_stride];
+ // Type & MV direction
+ if (IS_PCM(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "P");
- else if(IS_INTRA(mb_type) && IS_ACPRED(mb_type))
+ else if (IS_INTRA(mb_type) && IS_ACPRED(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "A");
- else if(IS_INTRA4x4(mb_type))
+ else if (IS_INTRA4x4(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "i");
- else if(IS_INTRA16x16(mb_type))
+ else if (IS_INTRA16x16(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "I");
- else if(IS_DIRECT(mb_type) && IS_SKIP(mb_type))
+ else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "d");
- else if(IS_DIRECT(mb_type))
+ else if (IS_DIRECT(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "D");
- else if(IS_GMC(mb_type) && IS_SKIP(mb_type))
+ else if (IS_GMC(mb_type) && IS_SKIP(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "g");
- else if(IS_GMC(mb_type))
+ else if (IS_GMC(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "G");
- else if(IS_SKIP(mb_type))
+ else if (IS_SKIP(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "S");
- else if(!USES_LIST(mb_type, 1))
+ else if (!USES_LIST(mb_type, 1))
av_log(s->avctx, AV_LOG_DEBUG, ">");
- else if(!USES_LIST(mb_type, 0))
+ else if (!USES_LIST(mb_type, 0))
av_log(s->avctx, AV_LOG_DEBUG, "<");
- else{
+ else {
assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
av_log(s->avctx, AV_LOG_DEBUG, "X");
}
- //segmentation
- if(IS_8X8(mb_type))
+ // segmentation
+ if (IS_8X8(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "+");
- else if(IS_16X8(mb_type))
+ else if (IS_16X8(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "-");
- else if(IS_8X16(mb_type))
+ else if (IS_8X16(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "|");
- else if(IS_INTRA(mb_type) || IS_16X16(mb_type))
+ else if (IS_INTRA(mb_type) || IS_16X16(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, " ");
else
av_log(s->avctx, AV_LOG_DEBUG, "?");
- if(IS_INTERLACED(mb_type))
+ if (IS_INTERLACED(mb_type))
av_log(s->avctx, AV_LOG_DEBUG, "=");
else
av_log(s->avctx, AV_LOG_DEBUG, " ");
}
-// av_log(s->avctx, AV_LOG_DEBUG, " ");
+ // av_log(s->avctx, AV_LOG_DEBUG, " ");
}
av_log(s->avctx, AV_LOG_DEBUG, "\n");
}
}
- if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){
- const int shift= 1 + s->quarter_sample;
+ if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||
+ (s->avctx->debug_mv)) {
+ const int shift = 1 + s->quarter_sample;
int mb_y;
uint8_t *ptr;
int i;
int h_chroma_shift, v_chroma_shift, block_height;
- const int width = s->avctx->width;
- const int height= s->avctx->height;
- const int mv_sample_log2= 4 - pict->motion_subsample_log2;
- const int mv_stride= (s->mb_width << mv_sample_log2) + (s->codec_id == CODEC_ID_H264 ? 0 : 1);
- s->low_delay=0; //needed to see the vectors without trashing the buffers
-
- avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);
- for(i=0; i<3; i++){
- memcpy(s->visualization_buffer[i], pict->data[i], (i==0) ? pict->linesize[i]*height:pict->linesize[i]*height >> v_chroma_shift);
- pict->data[i]= s->visualization_buffer[i];
- }
- pict->type= FF_BUFFER_TYPE_COPY;
- ptr= pict->data[0];
- block_height = 16>>v_chroma_shift;
-
- for(mb_y=0; mb_y<s->mb_height; mb_y++){
+ const int width = s->avctx->width;
+ const int height = s->avctx->height;
+ const int mv_sample_log2 = 4 - pict->motion_subsample_log2;
+ const int mv_stride = (s->mb_width << mv_sample_log2) +
+ (s->codec_id == CODEC_ID_H264 ? 0 : 1);
+ s->low_delay = 0; // needed to see the vectors without trashing the buffers
+
+ avcodec_get_chroma_sub_sample(s->avctx->pix_fmt,
+ &h_chroma_shift, &v_chroma_shift);
+ for (i = 0; i < 3; i++) {
+ memcpy(s->visualization_buffer[i], pict->data[i],
+ (i == 0) ? pict->linesize[i] * height:
+ pict->linesize[i] * height >> v_chroma_shift);
+ pict->data[i] = s->visualization_buffer[i];
+ }
+ pict->type = FF_BUFFER_TYPE_COPY;
+ ptr = pict->data[0];
+ block_height = 16 >> v_chroma_shift;
+
+ for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
int mb_x;
- for(mb_x=0; mb_x<s->mb_width; mb_x++){
- const int mb_index= mb_x + mb_y*s->mb_stride;
- if((s->avctx->debug_mv) && pict->motion_val){
- int type;
- for(type=0; type<3; type++){
- int direction = 0;
- switch (type) {
- case 0: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_P_FOR)) || (pict->pict_type!=AV_PICTURE_TYPE_P))
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ const int mb_index = mb_x + mb_y * s->mb_stride;
+ if ((s->avctx->debug_mv) && pict->motion_val) {
+ int type;
+ for (type = 0; type < 3; type++) {
+ int direction = 0;
+ switch (type) {
+ case 0:
+ if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_P_FOR)) ||
+ (pict->pict_type!= AV_PICTURE_TYPE_P))
continue;
- direction = 0;
- break;
- case 1: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_B_FOR)) || (pict->pict_type!=AV_PICTURE_TYPE_B))
+ direction = 0;
+ break;
+ case 1:
+ if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_B_FOR)) ||
+ (pict->pict_type!= AV_PICTURE_TYPE_B))
continue;
- direction = 0;
- break;
- case 2: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_B_BACK)) || (pict->pict_type!=AV_PICTURE_TYPE_B))
+ direction = 0;
+ break;
+ case 2:
+ if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_B_BACK)) ||
+ (pict->pict_type!= AV_PICTURE_TYPE_B))
continue;
- direction = 1;
- break;
- }
- if(!USES_LIST(pict->mb_type[mb_index], direction))
- continue;
-
- if(IS_8X8(pict->mb_type[mb_index])){
- int i;
- for(i=0; i<4; i++){
- int sx= mb_x*16 + 4 + 8*(i&1);
- int sy= mb_y*16 + 4 + 8*(i>>1);
- int xy= (mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*mv_stride) << (mv_sample_log2-1);
- int mx= (pict->motion_val[direction][xy][0]>>shift) + sx;
- int my= (pict->motion_val[direction][xy][1]>>shift) + sy;
- draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100);
- }
- }else if(IS_16X8(pict->mb_type[mb_index])){
- int i;
- for(i=0; i<2; i++){
- int sx=mb_x*16 + 8;
- int sy=mb_y*16 + 4 + 8*i;
- int xy= (mb_x*2 + (mb_y*2 + i)*mv_stride) << (mv_sample_log2-1);
- int mx=(pict->motion_val[direction][xy][0]>>shift);
- int my=(pict->motion_val[direction][xy][1]>>shift);
-
- if(IS_INTERLACED(pict->mb_type[mb_index]))
- my*=2;
-
- draw_arrow(ptr, sx, sy, mx+sx, my+sy, width, height, s->linesize, 100);
- }
- }else if(IS_8X16(pict->mb_type[mb_index])){
- int i;
- for(i=0; i<2; i++){
- int sx=mb_x*16 + 4 + 8*i;
- int sy=mb_y*16 + 8;
- int xy= (mb_x*2 + i + mb_y*2*mv_stride) << (mv_sample_log2-1);
- int mx=(pict->motion_val[direction][xy][0]>>shift);
- int my=(pict->motion_val[direction][xy][1]>>shift);
-
- if(IS_INTERLACED(pict->mb_type[mb_index]))
- my*=2;
-
- draw_arrow(ptr, sx, sy, mx+sx, my+sy, width, height, s->linesize, 100);
- }
- }else{
- int sx= mb_x*16 + 8;
- int sy= mb_y*16 + 8;
- int xy= (mb_x + mb_y*mv_stride) << mv_sample_log2;
- int mx= (pict->motion_val[direction][xy][0]>>shift) + sx;
- int my= (pict->motion_val[direction][xy][1]>>shift) + sy;
- draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100);
+ direction = 1;
+ break;
+ }
+ if (!USES_LIST(pict->mb_type[mb_index], direction))
+ continue;
+
+ if (IS_8X8(pict->mb_type[mb_index])) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ int sx = mb_x * 16 + 4 + 8 * (i & 1);
+ int sy = mb_y * 16 + 4 + 8 * (i >> 1);
+ int xy = (mb_x * 2 + (i & 1) +
+ (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1);
+ int mx = (pict->motion_val[direction][xy][0] >> shift) + sx;
+ int my = (pict->motion_val[direction][xy][1] >> shift) + sy;
+ draw_arrow(ptr, sx, sy, mx, my, width,
+ height, s->linesize, 100);
+ }
+ } else if (IS_16X8(pict->mb_type[mb_index])) {
+ int i;
+ for (i = 0; i < 2; i++) {
+ int sx = mb_x * 16 + 8;
+ int sy = mb_y * 16 + 4 + 8 * i;
+ int xy = (mb_x * 2 + (mb_y * 2 + i) * mv_stride) << (mv_sample_log2 - 1);
+ int mx = (pict->motion_val[direction][xy][0] >> shift);
+ int my = (pict->motion_val[direction][xy][1] >> shift);
+
+ if (IS_INTERLACED(pict->mb_type[mb_index]))
+ my *= 2;
+
+ draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,
+ height, s->linesize, 100);
+ }
+ } else if (IS_8X16(pict->mb_type[mb_index])) {
+ int i;
+ for (i = 0; i < 2; i++) {
+ int sx = mb_x * 16 + 4 + 8 * i;
+ int sy = mb_y * 16 + 8;
+ int xy = (mb_x * 2 + i + mb_y * 2 * mv_stride) << (mv_sample_log2 - 1);
+ int mx = pict->motion_val[direction][xy][0] >> shift;
+ int my = pict->motion_val[direction][xy][1] >> shift;
+
+ if (IS_INTERLACED(pict->mb_type[mb_index]))
+ my *= 2;
+
+ draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,
+ height, s->linesize, 100);
+ }
+ } else {
+ int sx = mb_x * 16 + 8;
+ int sy = mb_y * 16 + 8;
+ int xy = (mb_x + mb_y * mv_stride) << mv_sample_log2;
+ int mx = pict->motion_val[direction][xy][0] >> shift + sx;
+ int my = pict->motion_val[direction][xy][1] >> shift + sy;
+ draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100);
+ }
}
- }
}
- if((s->avctx->debug&FF_DEBUG_VIS_QP) && pict->motion_val){
- uint64_t c= (pict->qscale_table[mb_index]*128/31) * 0x0101010101010101ULL;
+ if ((s->avctx->debug & FF_DEBUG_VIS_QP) && pict->motion_val) {
+ uint64_t c = (pict->qscale_table[mb_index] * 128 / 31) *
+ 0x0101010101010101ULL;
int y;
- for(y=0; y<block_height; y++){
- *(uint64_t*)(pict->data[1] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[1])= c;
- *(uint64_t*)(pict->data[2] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[2])= c;
+ for (y = 0; y < block_height; y++) {
+ *(uint64_t *)(pict->data[1] + 8 * mb_x +
+ (block_height * mb_y + y) *
+ pict->linesize[1]) = c;
+ *(uint64_t *)(pict->data[2] + 8 * mb_x +
+ (block_height * mb_y + y) *
+ pict->linesize[2]) = c;
}
}
- if((s->avctx->debug&FF_DEBUG_VIS_MB_TYPE) && pict->motion_val){
- int mb_type= pict->mb_type[mb_index];
+ if ((s->avctx->debug & FF_DEBUG_VIS_MB_TYPE) &&
+ pict->motion_val) {
+ int mb_type = pict->mb_type[mb_index];
uint64_t u,v;
int y;
-#define COLOR(theta, r)\
-u= (int)(128 + r*cos(theta*3.141592/180));\
-v= (int)(128 + r*sin(theta*3.141592/180));
-
-
- u=v=128;
- if(IS_PCM(mb_type)){
- COLOR(120,48)
- }else if((IS_INTRA(mb_type) && IS_ACPRED(mb_type)) || IS_INTRA16x16(mb_type)){
- COLOR(30,48)
- }else if(IS_INTRA4x4(mb_type)){
- COLOR(90,48)
- }else if(IS_DIRECT(mb_type) && IS_SKIP(mb_type)){
-// COLOR(120,48)
- }else if(IS_DIRECT(mb_type)){
- COLOR(150,48)
- }else if(IS_GMC(mb_type) && IS_SKIP(mb_type)){
- COLOR(170,48)
- }else if(IS_GMC(mb_type)){
- COLOR(190,48)
- }else if(IS_SKIP(mb_type)){
-// COLOR(180,48)
- }else if(!USES_LIST(mb_type, 1)){
- COLOR(240,48)
- }else if(!USES_LIST(mb_type, 0)){
- COLOR(0,48)
- }else{
+#define COLOR(theta, r) \
+ u = (int)(128 + r * cos(theta * 3.141592 / 180)); \
+ v = (int)(128 + r * sin(theta * 3.141592 / 180));
+
+
+ u = v = 128;
+ if (IS_PCM(mb_type)) {
+ COLOR(120, 48)
+ } else if ((IS_INTRA(mb_type) && IS_ACPRED(mb_type)) ||
+ IS_INTRA16x16(mb_type)) {
+ COLOR(30, 48)
+ } else if (IS_INTRA4x4(mb_type)) {
+ COLOR(90, 48)
+ } else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type)) {
+ // COLOR(120, 48)
+ } else if (IS_DIRECT(mb_type)) {
+ COLOR(150, 48)
+ } else if (IS_GMC(mb_type) && IS_SKIP(mb_type)) {
+ COLOR(170, 48)
+ } else if (IS_GMC(mb_type)) {
+ COLOR(190, 48)
+ } else if (IS_SKIP(mb_type)) {
+ // COLOR(180, 48)
+ } else if (!USES_LIST(mb_type, 1)) {
+ COLOR(240, 48)
+ } else if (!USES_LIST(mb_type, 0)) {
+ COLOR(0, 48)
+ } else {
assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
COLOR(300,48)
}
- u*= 0x0101010101010101ULL;
- v*= 0x0101010101010101ULL;
- for(y=0; y<block_height; y++){
- *(uint64_t*)(pict->data[1] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[1])= u;
- *(uint64_t*)(pict->data[2] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[2])= v;
+ u *= 0x0101010101010101ULL;
+ v *= 0x0101010101010101ULL;
+ for (y = 0; y < block_height; y++) {
+ *(uint64_t *)(pict->data[1] + 8 * mb_x +
+ (block_height * mb_y + y) * pict->linesize[1]) = u;
+ *(uint64_t *)(pict->data[2] + 8 * mb_x +
+ (block_height * mb_y + y) * pict->linesize[2]) = v;
}
- //segmentation
- if(IS_8X8(mb_type) || IS_16X8(mb_type)){
- *(uint64_t*)(pict->data[0] + 16*mb_x + 0 + (16*mb_y + 8)*pict->linesize[0])^= 0x8080808080808080ULL;
- *(uint64_t*)(pict->data[0] + 16*mb_x + 8 + (16*mb_y + 8)*pict->linesize[0])^= 0x8080808080808080ULL;
+ // segmentation
+ if (IS_8X8(mb_type) || IS_16X8(mb_type)) {
+ *(uint64_t *)(pict->data[0] + 16 * mb_x + 0 +
+ (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL;
+ *(uint64_t *)(pict->data[0] + 16 * mb_x + 8 +
+ (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL;
}
- if(IS_8X8(mb_type) || IS_8X16(mb_type)){
- for(y=0; y<16; y++)
- pict->data[0][16*mb_x + 8 + (16*mb_y + y)*pict->linesize[0]]^= 0x80;
+ if (IS_8X8(mb_type) || IS_8X16(mb_type)) {
+ for (y = 0; y < 16; y++)
+ pict->data[0][16 * mb_x + 8 + (16 * mb_y + y) *
+ pict->linesize[0]] ^= 0x80;
}
- if(IS_8X8(mb_type) && mv_sample_log2 >= 2){
- int dm= 1 << (mv_sample_log2-2);
- for(i=0; i<4; i++){
- int sx= mb_x*16 + 8*(i&1);
- int sy= mb_y*16 + 8*(i>>1);
- int xy= (mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*mv_stride) << (mv_sample_log2-1);
- //FIXME bidir
- int32_t *mv = (int32_t*)&pict->motion_val[0][xy];
- if(mv[0] != mv[dm] || mv[dm*mv_stride] != mv[dm*(mv_stride+1)])
- for(y=0; y<8; y++)
- pict->data[0][sx + 4 + (sy + y)*pict->linesize[0]]^= 0x80;
- if(mv[0] != mv[dm*mv_stride] || mv[dm] != mv[dm*(mv_stride+1)])
- *(uint64_t*)(pict->data[0] + sx + (sy + 4)*pict->linesize[0])^= 0x8080808080808080ULL;
+ if (IS_8X8(mb_type) && mv_sample_log2 >= 2) {
+ int dm = 1 << (mv_sample_log2 - 2);
+ for (i = 0; i < 4; i++) {
+ int sx = mb_x * 16 + 8 * (i & 1);
+ int sy = mb_y * 16 + 8 * (i >> 1);
+ int xy = (mb_x * 2 + (i & 1) +
+ (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1);
+ // FIXME bidir
+ int32_t *mv = (int32_t *) &pict->motion_val[0][xy];
+ if (mv[0] != mv[dm] ||
+ mv[dm * mv_stride] != mv[dm * (mv_stride + 1)])
+ for (y = 0; y < 8; y++)
+ pict->data[0][sx + 4 + (sy + y) * pict->linesize[0]] ^= 0x80;
+ if (mv[0] != mv[dm * mv_stride] || mv[dm] != mv[dm * (mv_stride + 1)])
+ *(uint64_t *)(pict->data[0] + sx + (sy + 4) *
+ pict->linesize[0]) ^= 0x8080808080808080ULL;
}
}
- if(IS_INTERLACED(mb_type) && s->codec_id == CODEC_ID_H264){
+ if (IS_INTERLACED(mb_type) &&
+ s->codec_id == CODEC_ID_H264) {
// hmm
}
}
- s->mbskip_table[mb_index]=0;
+ s->mbskip_table[mb_index] = 0;
}
}
}
}
static inline int hpel_motion_lowres(MpegEncContext *s,
- uint8_t *dest, uint8_t *src,
- int field_based, int field_select,
- int src_x, int src_y,
- int width, int height, int stride,
- int h_edge_pos, int v_edge_pos,
- int w, int h, h264_chroma_mc_func *pix_op,
- int motion_x, int motion_y)
+ uint8_t *dest, uint8_t *src,
+ int field_based, int field_select,
+ int src_x, int src_y,
+ int width, int height, int stride,
+ int h_edge_pos, int v_edge_pos,
+ int w, int h, h264_chroma_mc_func *pix_op,
+ int motion_x, int motion_y)
{
- const int lowres= s->avctx->lowres;
- const int op_index= FFMIN(lowres, 2);
- const int s_mask= (2<<lowres)-1;
- int emu=0;
+ const int lowres = s->avctx->lowres;
+ const int op_index = FFMIN(lowres, 2);
+ const int s_mask = (2 << lowres) - 1;
+ int emu = 0;
int sx, sy;
- if(s->quarter_sample){
- motion_x/=2;
- motion_y/=2;
+ if (s->quarter_sample) {
+ motion_x /= 2;
+ motion_y /= 2;
}
- sx= motion_x & s_mask;
- sy= motion_y & s_mask;
- src_x += motion_x >> (lowres+1);
- src_y += motion_y >> (lowres+1);
+ sx = motion_x & s_mask;
+ sy = motion_y & s_mask;
+ src_x += motion_x >> lowres + 1;
+ src_y += motion_y >> lowres + 1;
- src += src_y * stride + src_x;
+ src += src_y * stride + src_x;
- if( (unsigned)src_x > h_edge_pos - (!!sx) - w
- || (unsigned)src_y >(v_edge_pos >> field_based) - (!!sy) - h){
- s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based,
- src_x, src_y<<field_based, h_edge_pos, v_edge_pos);
- src= s->edge_emu_buffer;
- emu=1;
+ if ((unsigned)src_x > h_edge_pos - (!!sx) - w ||
+ (unsigned)src_y > (v_edge_pos >> field_based) - (!!sy) - h) {
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w + 1,
+ (h + 1) << field_based, src_x,
+ src_y << field_based,
+ h_edge_pos,
+ v_edge_pos);
+ src = s->edge_emu_buffer;
+ emu = 1;
}
- sx= (sx << 2) >> lowres;
- sy= (sy << 2) >> lowres;
- if(field_select)
+ sx = (sx << 2) >> lowres;
+ sy = (sy << 2) >> lowres;
+ if (field_select)
src += s->linesize;
pix_op[op_index](dest, src, stride, h, sx, sy);
return emu;
@@ -1627,149 +1852,170 @@ static inline int hpel_motion_lowres(MpegEncContext *s,
/* apply one mpeg motion vector to the three components */
static av_always_inline void mpeg_motion_lowres(MpegEncContext *s,
- uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
- int field_based, int bottom_field, int field_select,
- uint8_t **ref_picture, h264_chroma_mc_func *pix_op,
- int motion_x, int motion_y, int h, int mb_y)
+ uint8_t *dest_y,
+ uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ int field_based,
+ int bottom_field,
+ int field_select,
+ uint8_t **ref_picture,
+ h264_chroma_mc_func *pix_op,
+ int motion_x, int motion_y,
+ int h, int mb_y)
{
uint8_t *ptr_y, *ptr_cb, *ptr_cr;
- int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy, uvsx, uvsy;
- const int lowres= s->avctx->lowres;
- const int op_index= FFMIN(lowres, 2);
- const int block_s= 8>>lowres;
- const int s_mask= (2<<lowres)-1;
+ int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy,
+ uvsx, uvsy;
+ const int lowres = s->avctx->lowres;
+ const int op_index = FFMIN(lowres, 2);
+ const int block_s = 8>>lowres;
+ const int s_mask = (2 << lowres) - 1;
const int h_edge_pos = s->h_edge_pos >> lowres;
const int v_edge_pos = s->v_edge_pos >> lowres;
- linesize = s->current_picture.linesize[0] << field_based;
- uvlinesize = s->current_picture.linesize[1] << field_based;
+ linesize = s->current_picture.f.linesize[0] << field_based;
+ uvlinesize = s->current_picture.f.linesize[1] << field_based;
- if(s->quarter_sample){ //FIXME obviously not perfect but qpel will not work in lowres anyway
- motion_x/=2;
- motion_y/=2;
+ // FIXME obviously not perfect but qpel will not work in lowres anyway
+ if (s->quarter_sample) {
+ motion_x /= 2;
+ motion_y /= 2;
}
- if(field_based){
- motion_y += (bottom_field - field_select)*((1<<lowres)-1);
+ if (field_based) {
+ motion_y += (bottom_field - field_select) * (1 << lowres - 1);
}
- sx= motion_x & s_mask;
- sy= motion_y & s_mask;
- src_x = s->mb_x*2*block_s + (motion_x >> (lowres+1));
- src_y =( mb_y*2*block_s>>field_based) + (motion_y >> (lowres+1));
+ sx = motion_x & s_mask;
+ sy = motion_y & s_mask;
+ src_x = s->mb_x * 2 * block_s + (motion_x >> lowres + 1);
+ src_y = (mb_y * 2 * block_s >> field_based) + (motion_y >> lowres + 1);
if (s->out_format == FMT_H263) {
- uvsx = ((motion_x>>1) & s_mask) | (sx&1);
- uvsy = ((motion_y>>1) & s_mask) | (sy&1);
- uvsrc_x = src_x>>1;
- uvsrc_y = src_y>>1;
- }else if(s->out_format == FMT_H261){//even chroma mv's are full pel in H261
- mx = motion_x / 4;
- my = motion_y / 4;
- uvsx = (2*mx) & s_mask;
- uvsy = (2*my) & s_mask;
- uvsrc_x = s->mb_x*block_s + (mx >> lowres);
- uvsrc_y = mb_y*block_s + (my >> lowres);
+ uvsx = ((motion_x >> 1) & s_mask) | (sx & 1);
+ uvsy = ((motion_y >> 1) & s_mask) | (sy & 1);
+ uvsrc_x = src_x >> 1;
+ uvsrc_y = src_y >> 1;
+ } else if (s->out_format == FMT_H261) {
+ // even chroma mv's are full pel in H261
+ mx = motion_x / 4;
+ my = motion_y / 4;
+ uvsx = (2 * mx) & s_mask;
+ uvsy = (2 * my) & s_mask;
+ uvsrc_x = s->mb_x * block_s + (mx >> lowres);
+ uvsrc_y = mb_y * block_s + (my >> lowres);
} else {
- mx = motion_x / 2;
- my = motion_y / 2;
- uvsx = mx & s_mask;
- uvsy = my & s_mask;
- uvsrc_x = s->mb_x*block_s + (mx >> (lowres+1));
- uvsrc_y =( mb_y*block_s>>field_based) + (my >> (lowres+1));
+ mx = motion_x / 2;
+ my = motion_y / 2;
+ uvsx = mx & s_mask;
+ uvsy = my & s_mask;
+ uvsrc_x = s->mb_x * block_s + (mx >> lowres + 1);
+ uvsrc_y = (mb_y * block_s >> field_based) + (my >> lowres + 1);
}
- ptr_y = ref_picture[0] + src_y * linesize + src_x;
+ ptr_y = ref_picture[0] + src_y * linesize + src_x;
ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
- if( (unsigned)src_x > h_edge_pos - (!!sx) - 2*block_s
- || (unsigned)src_y >(v_edge_pos >> field_based) - (!!sy) - h){
- s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, 17, 17+field_based,
- src_x, src_y<<field_based, h_edge_pos, v_edge_pos);
- ptr_y = s->edge_emu_buffer;
- if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
- uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;
- s->dsp.emulated_edge_mc(uvbuf , ptr_cb, s->uvlinesize, 9, 9+field_based,
- uvsrc_x, uvsrc_y<<field_based, h_edge_pos>>1, v_edge_pos>>1);
- s->dsp.emulated_edge_mc(uvbuf+16, ptr_cr, s->uvlinesize, 9, 9+field_based,
- uvsrc_x, uvsrc_y<<field_based, h_edge_pos>>1, v_edge_pos>>1);
- ptr_cb= uvbuf;
- ptr_cr= uvbuf+16;
- }
- }
-
- if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data
- dest_y += s->linesize;
- dest_cb+= s->uvlinesize;
- dest_cr+= s->uvlinesize;
- }
-
- if(field_select){
- ptr_y += s->linesize;
- ptr_cb+= s->uvlinesize;
- ptr_cr+= s->uvlinesize;
- }
-
- sx= (sx << 2) >> lowres;
- sy= (sy << 2) >> lowres;
- pix_op[lowres-1](dest_y, ptr_y, linesize, h, sx, sy);
-
- if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
- uvsx= (uvsx << 2) >> lowres;
- uvsy= (uvsy << 2) >> lowres;
- pix_op[op_index](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);
- pix_op[op_index](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);
- }
- //FIXME h261 lowres loop filter
+ if ((unsigned) src_x > h_edge_pos - (!!sx) - 2 * block_s ||
+ (unsigned) src_y > (v_edge_pos >> field_based) - (!!sy) - h) {
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
+ s->linesize, 17, 17 + field_based,
+ src_x, src_y << field_based, h_edge_pos,
+ v_edge_pos);
+ ptr_y = s->edge_emu_buffer;
+ if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+ uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize;
+ s->dsp.emulated_edge_mc(uvbuf , ptr_cb, s->uvlinesize, 9,
+ 9 + field_based,
+ uvsrc_x, uvsrc_y << field_based,
+ h_edge_pos >> 1, v_edge_pos >> 1);
+ s->dsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize, 9,
+ 9 + field_based,
+ uvsrc_x, uvsrc_y << field_based,
+ h_edge_pos >> 1, v_edge_pos >> 1);
+ ptr_cb = uvbuf;
+ ptr_cr = uvbuf + 16;
+ }
+ }
+
+ // FIXME use this for field pix too instead of the obnoxious hack which changes picture.f.data
+ if (bottom_field) {
+ dest_y += s->linesize;
+ dest_cb += s->uvlinesize;
+ dest_cr += s->uvlinesize;
+ }
+
+ if (field_select) {
+ ptr_y += s->linesize;
+ ptr_cb += s->uvlinesize;
+ ptr_cr += s->uvlinesize;
+ }
+
+ sx = (sx << 2) >> lowres;
+ sy = (sy << 2) >> lowres;
+ pix_op[lowres - 1](dest_y, ptr_y, linesize, h, sx, sy);
+
+ if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+ uvsx = (uvsx << 2) >> lowres;
+ uvsy = (uvsy << 2) >> lowres;
+ pix_op[op_index](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift,
+ uvsx, uvsy);
+ pix_op[op_index](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift,
+ uvsx, uvsy);
+ }
+ // FIXME h261 lowres loop filter
}
static inline void chroma_4mv_motion_lowres(MpegEncContext *s,
- uint8_t *dest_cb, uint8_t *dest_cr,
- uint8_t **ref_picture,
- h264_chroma_mc_func *pix_op,
- int mx, int my){
- const int lowres= s->avctx->lowres;
- const int op_index= FFMIN(lowres, 2);
- const int block_s= 8>>lowres;
- const int s_mask= (2<<lowres)-1;
- const int h_edge_pos = s->h_edge_pos >> (lowres+1);
- const int v_edge_pos = s->v_edge_pos >> (lowres+1);
- int emu=0, src_x, src_y, offset, sx, sy;
+ uint8_t *dest_cb, uint8_t *dest_cr,
+ uint8_t **ref_picture,
+ h264_chroma_mc_func * pix_op,
+ int mx, int my)
+{
+ const int lowres = s->avctx->lowres;
+ const int op_index = FFMIN(lowres, 2);
+ const int block_s = 8 >> lowres;
+ const int s_mask = (2 << lowres) - 1;
+ const int h_edge_pos = s->h_edge_pos >> lowres + 1;
+ const int v_edge_pos = s->v_edge_pos >> lowres + 1;
+ int emu = 0, src_x, src_y, offset, sx, sy;
uint8_t *ptr;
- if(s->quarter_sample){
- mx/=2;
- my/=2;
+ if (s->quarter_sample) {
+ mx /= 2;
+ my /= 2;
}
/* In case of 8X8, we construct a single chroma motion vector
with a special rounding */
- mx= ff_h263_round_chroma(mx);
- my= ff_h263_round_chroma(my);
+ mx = ff_h263_round_chroma(mx);
+ my = ff_h263_round_chroma(my);
- sx= mx & s_mask;
- sy= my & s_mask;
- src_x = s->mb_x*block_s + (mx >> (lowres+1));
- src_y = s->mb_y*block_s + (my >> (lowres+1));
+ sx = mx & s_mask;
+ sy = my & s_mask;
+ src_x = s->mb_x * block_s + (mx >> lowres + 1);
+ src_y = s->mb_y * block_s + (my >> lowres + 1);
offset = src_y * s->uvlinesize + src_x;
ptr = ref_picture[1] + offset;
- if(s->flags&CODEC_FLAG_EMU_EDGE){
- if( (unsigned)src_x > h_edge_pos - (!!sx) - block_s
- || (unsigned)src_y > v_edge_pos - (!!sy) - block_s){
- s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, h_edge_pos, v_edge_pos);
- ptr= s->edge_emu_buffer;
- emu=1;
+ if (s->flags & CODEC_FLAG_EMU_EDGE) {
+ if ((unsigned) src_x > h_edge_pos - (!!sx) - block_s ||
+ (unsigned) src_y > v_edge_pos - (!!sy) - block_s) {
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
+ 9, 9, src_x, src_y, h_edge_pos, v_edge_pos);
+ ptr = s->edge_emu_buffer;
+ emu = 1;
}
}
- sx= (sx << 2) >> lowres;
- sy= (sy << 2) >> lowres;
+ sx = (sx << 2) >> lowres;
+ sy = (sy << 2) >> lowres;
pix_op[op_index](dest_cb, ptr, s->uvlinesize, block_s, sx, sy);
ptr = ref_picture[2] + offset;
- if(emu){
- s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, h_edge_pos, v_edge_pos);
- ptr= s->edge_emu_buffer;
+ if (emu) {
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
+ src_x, src_y, h_edge_pos, v_edge_pos);
+ ptr = s->edge_emu_buffer;
}
pix_op[op_index](dest_cr, ptr, s->uvlinesize, block_s, sx, sy);
}
@@ -1786,117 +2032,133 @@ static inline void chroma_4mv_motion_lowres(MpegEncContext *s,
* the motion vectors are taken from s->mv and the MV type from s->mv_type
*/
static inline void MPV_motion_lowres(MpegEncContext *s,
- uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
- int dir, uint8_t **ref_picture,
- h264_chroma_mc_func *pix_op)
+ uint8_t *dest_y, uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ int dir, uint8_t **ref_picture,
+ h264_chroma_mc_func *pix_op)
{
int mx, my;
int mb_x, mb_y, i;
- const int lowres= s->avctx->lowres;
- const int block_s= 8>>lowres;
+ const int lowres = s->avctx->lowres;
+ const int block_s = 8 >>lowres;
mb_x = s->mb_x;
mb_y = s->mb_y;
- switch(s->mv_type) {
+ switch (s->mv_type) {
case MV_TYPE_16X16:
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
- 0, 0, 0,
- ref_picture, pix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], 2*block_s, mb_y);
+ 0, 0, 0,
+ ref_picture, pix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1],
+ 2 * block_s, mb_y);
break;
case MV_TYPE_8X8:
mx = 0;
my = 0;
- for(i=0;i<4;i++) {
- hpel_motion_lowres(s, dest_y + ((i & 1) + (i >> 1) * s->linesize)*block_s,
- ref_picture[0], 0, 0,
- (2*mb_x + (i & 1))*block_s, (2*mb_y + (i >>1))*block_s,
- s->width, s->height, s->linesize,
- s->h_edge_pos >> lowres, s->v_edge_pos >> lowres,
- block_s, block_s, pix_op,
- s->mv[dir][i][0], s->mv[dir][i][1]);
-
- mx += s->mv[dir][i][0];
- my += s->mv[dir][i][1];
- }
-
- if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY))
- chroma_4mv_motion_lowres(s, dest_cb, dest_cr, ref_picture, pix_op, mx, my);
+ for (i = 0; i < 4; i++) {
+ hpel_motion_lowres(s, dest_y + ((i & 1) + (i >> 1) *
+ s->linesize) * block_s,
+ ref_picture[0], 0, 0,
+ (2 * mb_x + (i & 1)) * block_s,
+ (2 * mb_y + (i >> 1)) * block_s,
+ s->width, s->height, s->linesize,
+ s->h_edge_pos >> lowres, s->v_edge_pos >> lowres,
+ block_s, block_s, pix_op,
+ s->mv[dir][i][0], s->mv[dir][i][1]);
+
+ mx += s->mv[dir][i][0];
+ my += s->mv[dir][i][1];
+ }
+
+ if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY))
+ chroma_4mv_motion_lowres(s, dest_cb, dest_cr, ref_picture,
+ pix_op, mx, my);
break;
case MV_TYPE_FIELD:
if (s->picture_structure == PICT_FRAME) {
/* top field */
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
- 1, 0, s->field_select[dir][0],
- ref_picture, pix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], block_s, mb_y);
+ 1, 0, s->field_select[dir][0],
+ ref_picture, pix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1],
+ block_s, mb_y);
/* bottom field */
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
- 1, 1, s->field_select[dir][1],
- ref_picture, pix_op,
- s->mv[dir][1][0], s->mv[dir][1][1], block_s, mb_y);
+ 1, 1, s->field_select[dir][1],
+ ref_picture, pix_op,
+ s->mv[dir][1][0], s->mv[dir][1][1],
+ block_s, mb_y);
} else {
- if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field){
- ref_picture= s->current_picture_ptr->data;
- }
+ if (s->picture_structure != s->field_select[dir][0] + 1 &&
+ s->pict_type != AV_PICTURE_TYPE_B && !s->first_field) {
+ ref_picture = s->current_picture_ptr->f.data;
+ }
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
- 0, 0, s->field_select[dir][0],
- ref_picture, pix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], 2*block_s, mb_y>>1);
- }
+ 0, 0, s->field_select[dir][0],
+ ref_picture, pix_op,
+ s->mv[dir][0][0],
+ s->mv[dir][0][1], 2 * block_s, mb_y >> 1);
+ }
break;
case MV_TYPE_16X8:
- for(i=0; i<2; i++){
- uint8_t ** ref2picture;
+ for (i = 0; i < 2; i++) {
+ uint8_t **ref2picture;
- if(s->picture_structure == s->field_select[dir][i] + 1 || s->pict_type == AV_PICTURE_TYPE_B || s->first_field){
- ref2picture= ref_picture;
- }else{
- ref2picture= s->current_picture_ptr->data;
+ if (s->picture_structure == s->field_select[dir][i] + 1 ||
+ s->pict_type == AV_PICTURE_TYPE_B || s->first_field) {
+ ref2picture = ref_picture;
+ } else {
+ ref2picture = s->current_picture_ptr->f.data;
}
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
- 0, 0, s->field_select[dir][i],
- ref2picture, pix_op,
- s->mv[dir][i][0], s->mv[dir][i][1] + 2*block_s*i, block_s, mb_y>>1);
+ 0, 0, s->field_select[dir][i],
+ ref2picture, pix_op,
+ s->mv[dir][i][0], s->mv[dir][i][1] +
+ 2 * block_s * i, block_s, mb_y >> 1);
- dest_y += 2*block_s*s->linesize;
- dest_cb+= (2*block_s>>s->chroma_y_shift)*s->uvlinesize;
- dest_cr+= (2*block_s>>s->chroma_y_shift)*s->uvlinesize;
+ dest_y += 2 * block_s * s->linesize;
+ dest_cb += (2 * block_s >> s->chroma_y_shift) * s->uvlinesize;
+ dest_cr += (2 * block_s >> s->chroma_y_shift) * s->uvlinesize;
}
break;
case MV_TYPE_DMV:
- if(s->picture_structure == PICT_FRAME){
- for(i=0; i<2; i++){
+ if (s->picture_structure == PICT_FRAME) {
+ for (i = 0; i < 2; i++) {
int j;
- for(j=0; j<2; j++){
+ for (j = 0; j < 2; j++) {
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
- 1, j, j^i,
- ref_picture, pix_op,
- s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], block_s, mb_y);
+ 1, j, j ^ i,
+ ref_picture, pix_op,
+ s->mv[dir][2 * i + j][0],
+ s->mv[dir][2 * i + j][1],
+ block_s, mb_y);
}
pix_op = s->dsp.avg_h264_chroma_pixels_tab;
}
- }else{
- for(i=0; i<2; i++){
+ } else {
+ for (i = 0; i < 2; i++) {
mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
- 0, 0, s->picture_structure != i+1,
- ref_picture, pix_op,
- s->mv[dir][2*i][0],s->mv[dir][2*i][1],2*block_s, mb_y>>1);
+ 0, 0, s->picture_structure != i + 1,
+ ref_picture, pix_op,
+ s->mv[dir][2 * i][0],s->mv[dir][2 * i][1],
+ 2 * block_s, mb_y >> 1);
// after put we make avg of the same block
pix_op = s->dsp.avg_h264_chroma_pixels_tab;
- //opposite parity is always in the same frame if this is second field
- if(!s->first_field){
- ref_picture = s->current_picture_ptr->data;
+ // opposite parity is always in the same
+ // frame if this is second field
+ if (!s->first_field) {
+ ref_picture = s->current_picture_ptr->f.data;
}
}
}
- break;
- default: assert(0);
+ break;
+ default:
+ assert(0);
}
}
@@ -1965,7 +2227,7 @@ static inline void add_dequant_dct(MpegEncContext *s,
}
/**
- * cleans dc, ac, coded_block for the current non intra MB
+ * Clean dc, ac, coded_block for the current non-intra MB.
*/
void ff_clean_intra_table_entries(MpegEncContext *s)
{
@@ -2020,7 +2282,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
/* save DCT coefficients */
int i,j;
- DCTELEM *dct = &s->current_picture.dct_coeff[mb_xy*64*6];
+ DCTELEM *dct = &s->current_picture.f.dct_coeff[mb_xy * 64 * 6];
av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y);
for(i=0; i<6; i++){
for(j=0; j<64; j++){
@@ -2031,7 +2293,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
}
}
- s->current_picture.qscale_table[mb_xy]= s->qscale;
+ s->current_picture.f.qscale_table[mb_xy] = s->qscale;
/* update DC predictors for P macroblocks */
if (!s->mb_intra) {
@@ -2052,8 +2314,8 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
int dct_linesize, dct_offset;
op_pixels_func (*op_pix)[4];
qpel_mc_func (*op_qpix)[16];
- const int linesize= s->current_picture.linesize[0]; //not s->linesize as this would be wrong for field pics
- const int uvlinesize= s->current_picture.linesize[1];
+ const int linesize = s->current_picture.f.linesize[0]; //not s->linesize as this would be wrong for field pics
+ const int uvlinesize = s->current_picture.f.linesize[1];
const int readable= s->pict_type != AV_PICTURE_TYPE_B || s->encoding || s->avctx->draw_horiz_band || lowres_flag;
const int block_size= lowres_flag ? 8>>s->avctx->lowres : 8;
@@ -2061,24 +2323,13 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
/* skip only during decoding as we might trash the buffers during encoding a bit */
if(!s->encoding){
uint8_t *mbskip_ptr = &s->mbskip_table[mb_xy];
- const int age= s->current_picture.age;
-
- assert(age);
if (s->mb_skipped) {
s->mb_skipped= 0;
assert(s->pict_type!=AV_PICTURE_TYPE_I);
-
- (*mbskip_ptr) ++; /* indicate that this time we skipped it */
- if(*mbskip_ptr >99) *mbskip_ptr= 99;
-
- /* if previous was skipped too, then nothing to do ! */
- if (*mbskip_ptr >= age && s->current_picture.reference){
- return;
- }
- } else if(!s->current_picture.reference){
- (*mbskip_ptr) ++; /* increase counter so the age can be compared cleanly */
- if(*mbskip_ptr >99) *mbskip_ptr= 99;
+ *mbskip_ptr = 1;
+ } else if(!s->current_picture.f.reference) {
+ *mbskip_ptr = 1;
} else{
*mbskip_ptr = 0; /* not skipped */
}
@@ -2102,7 +2353,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
/* decoding or more than one mb_type (MC was already done otherwise) */
if(!s->encoding){
- if(HAVE_PTHREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) {
+ if(HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) {
if (s->mv_dir & MV_DIR_FORWARD) {
ff_thread_await_progress((AVFrame*)s->last_picture_ptr, MPV_lowest_referenced_row(s, 0), 0);
}
@@ -2115,11 +2366,11 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
h264_chroma_mc_func *op_pix = s->dsp.put_h264_chroma_pixels_tab;
if (s->mv_dir & MV_DIR_FORWARD) {
- MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix);
+ MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f.data, op_pix);
op_pix = s->dsp.avg_h264_chroma_pixels_tab;
}
if (s->mv_dir & MV_DIR_BACKWARD) {
- MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix);
+ MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data, op_pix);
}
}else{
op_qpix= s->me.qpel_put;
@@ -2129,12 +2380,12 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
op_pix = s->dsp.put_no_rnd_pixels_tab;
}
if (s->mv_dir & MV_DIR_FORWARD) {
- MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix);
+ MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f.data, op_pix, op_qpix);
op_pix = s->dsp.avg_pixels_tab;
op_qpix= s->me.qpel_avg;
}
if (s->mv_dir & MV_DIR_BACKWARD) {
- MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix);
+ MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data, op_pix, op_qpix);
}
}
}
@@ -2270,7 +2521,6 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){
}
/**
- *
* @param h is the normal height, this will be reduced automatically if needed for the last row
*/
void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
@@ -2283,7 +2533,7 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
if (!s->avctx->hwaccel
&& !(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
&& s->unrestricted_mv
- && s->current_picture.reference
+ && s->current_picture.f.reference
&& !s->intra_only
&& !(s->flags&CODEC_FLAG_EMU_EDGE)) {
int sides = 0, edge_h;
@@ -2294,12 +2544,15 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
edge_h= FFMIN(h, s->v_edge_pos - y);
- s->dsp.draw_edges(s->current_picture_ptr->data[0] + y *s->linesize , s->linesize,
- s->h_edge_pos , edge_h , EDGE_WIDTH , EDGE_WIDTH , sides);
- s->dsp.draw_edges(s->current_picture_ptr->data[1] + (y>>vshift)*s->uvlinesize, s->uvlinesize,
- s->h_edge_pos>>hshift, edge_h>>hshift, EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides);
- s->dsp.draw_edges(s->current_picture_ptr->data[2] + (y>>vshift)*s->uvlinesize, s->uvlinesize,
- s->h_edge_pos>>hshift, edge_h>>hshift, EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides);
+ s->dsp.draw_edges(s->current_picture_ptr->f.data[0] + y *s->linesize,
+ s->linesize, s->h_edge_pos, edge_h,
+ EDGE_WIDTH, EDGE_WIDTH, sides);
+ s->dsp.draw_edges(s->current_picture_ptr->f.data[1] + (y>>vshift)*s->uvlinesize,
+ s->uvlinesize, s->h_edge_pos>>hshift, edge_h>>vshift,
+ EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides);
+ s->dsp.draw_edges(s->current_picture_ptr->f.data[2] + (y>>vshift)*s->uvlinesize,
+ s->uvlinesize, s->h_edge_pos>>hshift, edge_h>>vshift,
+ EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides);
}
h= FFMIN(h, s->avctx->height - y);
@@ -2308,7 +2561,8 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
if (s->avctx->draw_horiz_band) {
AVFrame *src;
- int offset[4];
+ int offset[AV_NUM_DATA_POINTERS];
+ int i;
if(s->pict_type==AV_PICTURE_TYPE_B || s->low_delay || (s->avctx->slice_flags&SLICE_FLAG_CODED_ORDER))
src= (AVFrame*)s->current_picture_ptr;
@@ -2318,15 +2572,14 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
return;
if(s->pict_type==AV_PICTURE_TYPE_B && s->picture_structure == PICT_FRAME && s->out_format != FMT_H264){
- offset[0]=
- offset[1]=
- offset[2]=
- offset[3]= 0;
+ for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
+ offset[i] = 0;
}else{
offset[0]= y * s->linesize;
offset[1]=
offset[2]= (y >> s->chroma_y_shift) * s->uvlinesize;
- offset[3]= 0;
+ for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
+ offset[i] = 0;
}
emms_c();
@@ -2337,8 +2590,8 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
}
void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
- const int linesize= s->current_picture.linesize[0]; //not s->linesize as this would be wrong for field pics
- const int uvlinesize= s->current_picture.linesize[1];
+ const int linesize = s->current_picture.f.linesize[0]; //not s->linesize as this would be wrong for field pics
+ const int uvlinesize = s->current_picture.f.linesize[1];
const int mb_size= 4 - s->avctx->lowres;
s->block_index[0]= s->b8_stride*(s->mb_y*2 ) - 2 + s->mb_x*2;
@@ -2349,9 +2602,9 @@ void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x - 1;
//block_index is not used by mpeg2, so it is not affected by chroma_format
- s->dest[0] = s->current_picture.data[0] + ((s->mb_x - 1) << mb_size);
- s->dest[1] = s->current_picture.data[1] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
- s->dest[2] = s->current_picture.data[2] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
+ s->dest[0] = s->current_picture.f.data[0] + ((s->mb_x - 1) << mb_size);
+ s->dest[1] = s->current_picture.f.data[1] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
+ s->dest[2] = s->current_picture.f.data[2] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));
if(!(s->pict_type==AV_PICTURE_TYPE_B && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME))
{
@@ -2376,14 +2629,14 @@ void ff_mpeg_flush(AVCodecContext *avctx){
return;
for(i=0; i<s->picture_count; i++){
- if(s->picture[i].data[0] && ( s->picture[i].type == FF_BUFFER_TYPE_INTERNAL
- || s->picture[i].type == FF_BUFFER_TYPE_USER))
+ if (s->picture[i].f.data[0] &&
+ (s->picture[i].f.type == FF_BUFFER_TYPE_INTERNAL ||
+ s->picture[i].f.type == FF_BUFFER_TYPE_USER))
free_frame_buffer(s, &s->picture[i]);
}
s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL;
s->mb_x= s->mb_y= 0;
- s->closed_gop= 0;
s->parse_context.state= -1;
s->parse_context.frame_start_found= 0;
@@ -2632,6 +2885,6 @@ void ff_set_qscale(MpegEncContext * s, int qscale)
void MPV_report_decode_progress(MpegEncContext *s)
{
- if (s->pict_type != FF_B_TYPE && !s->partitioned_frame && !s->error_occurred)
+ if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->error_occurred)
ff_thread_report_progress((AVFrame*)s->current_picture_ptr, s->mb_y, 0);
}
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index f37977c..6483893 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -28,6 +28,7 @@
#ifndef AVCODEC_MPEGVIDEO_H
#define AVCODEC_MPEGVIDEO_H
+#include "avcodec.h"
#include "dsputil.h"
#include "get_bits.h"
#include "put_bits.h"
@@ -82,7 +83,7 @@ struct MpegEncContext;
* Picture.
*/
typedef struct Picture{
- FF_COMMON_FRAME
+ struct AVFrame f;
/**
* halfpel luma planes.
@@ -126,7 +127,7 @@ typedef struct Picture{
int ref_poc[2][2][16]; ///< h264 POCs of the frames used as reference (FIXME need per slice)
int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice)
int mbaff; ///< h264 1 -> MBAFF frame 0-> not MBAFF
- int field_picture; ///< whether or not the picture was encoded in seperate fields
+ int field_picture; ///< whether or not the picture was encoded in separate fields
int mb_var_sum; ///< sum of MB variance for current frame
int mc_mb_var_sum; ///< motion compensated MB variance for current frame
@@ -153,9 +154,9 @@ typedef struct MotionEstContext{
int best_bits;
uint32_t *map; ///< map to avoid duplicate evaluations
uint32_t *score_map; ///< map to store the scores
- int map_generation;
+ unsigned map_generation;
int pre_penalty_factor;
- int penalty_factor; /*!< an estimate of the bits required to
+ int penalty_factor; /**< an estimate of the bits required to
code a given mv value, e.g. (1,0) takes
more bits than (0,0). We have to
estimate whether any reduction in
@@ -198,6 +199,7 @@ typedef struct MotionEstContext{
* MpegEncContext.
*/
typedef struct MpegEncContext {
+ AVClass *class;
struct AVCodecContext *avctx;
/* the following parameters must be initialized before encoding */
int width, height;///< picture size. must be a multiple of 16
@@ -232,8 +234,6 @@ typedef struct MpegEncContext {
int coded_picture_number; ///< used to set pic->coded_picture_number, should not be used for/by anything else
int picture_number; //FIXME remove, unclear definition
int picture_in_gop_number; ///< 0-> first pic in gop, ...
- int b_frames_since_non_b; ///< used for encoding, relative to not yet reordered input
- int64_t user_specified_pts;///< last non zero pts from AVFrame which was passed into avcodec_encode_video()
int mb_width, mb_height; ///< number of MBs horizontally & vertically
int mb_stride; ///< mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11
int b8_stride; ///< 2*mb_width+1 used for some 8x8 block arrays to allow simple addressing
@@ -260,6 +260,8 @@ typedef struct MpegEncContext {
/* WARNING: changes above this line require updates to hardcoded
* offsets used in asm. */
+ int64_t user_specified_pts;///< last non zero pts from AVFrame which was passed into avcodec_encode_video()
+
/** bit output */
PutBitContext pb;
@@ -296,11 +298,10 @@ typedef struct MpegEncContext {
Picture *current_picture_ptr; ///< pointer to the current picture
int picture_count; ///< number of allocated pictures (MAX_PICTURE_COUNT * avctx->thread_count)
int picture_range_start, picture_range_end; ///< the part of picture that this context can allocate in
- uint8_t *visualization_buffer[3]; //< temporary buffer vor MV visualization
+ uint8_t *visualization_buffer[3]; ///< temporary buffer vor MV visualization
int last_dc[3]; ///< last DC values for MPEG1
int16_t *dc_val_base;
int16_t *dc_val[3]; ///< used for mpeg4 DC prediction, all 3 arrays must be continuous
- int16_t dc_cache[4*5];
const uint8_t *y_dc_scale_table; ///< qscale -> y_dc_scale table
const uint8_t *c_dc_scale_table; ///< qscale -> c_dc_scale table
const uint8_t *chroma_qscale_table; ///< qscale -> chroma_qscale (h263)
@@ -308,16 +309,13 @@ typedef struct MpegEncContext {
uint8_t *coded_block; ///< used for coded block pattern prediction (msmpeg4v3, wmv1)
int16_t (*ac_val_base)[16];
int16_t (*ac_val[3])[16]; ///< used for for mpeg4 AC prediction, all 3 arrays must be continuous
- uint8_t *prev_pict_types; ///< previous picture types in bitstream order, used for mb skip
-#define PREV_PICT_TYPES_BUFFER_SIZE 256
int mb_skipped; ///< MUST BE SET only during DECODING
uint8_t *mbskip_table; /**< used to avoid copy if macroblock skipped (for black regions for example)
and used for b-frame encoding & decoding (contains skip table of next P Frame) */
uint8_t *mbintra_table; ///< used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding
uint8_t *cbp_table; ///< used to store cbp, ac_pred for partitioned decoding
uint8_t *pred_dir_table; ///< used to store pred_dir for partitioned decoding
- uint8_t *allocated_edge_emu_buffer;
- uint8_t *edge_emu_buffer; ///< points into the middle of allocated_edge_emu_buffer
+ uint8_t *edge_emu_buffer; ///< temporary buffer for if MVs point to out-of-frame data
uint8_t *rd_scratchpad; ///< scratchpad for rate distortion mb decision
uint8_t *obmc_scratchpad;
uint8_t *b_scratchpad; ///< scratchpad used for writing into write only buffers
@@ -329,7 +327,6 @@ typedef struct MpegEncContext {
int *lambda_table;
int adaptive_quant; ///< use adaptive quantization
int dquant; ///< qscale difference to prev qscale
- int closed_gop; ///< MPEG1/2 GOP is closed
int pict_type; ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
int last_pict_type; //FIXME removes
int last_non_b_pict_type; ///< used for mpeg4 gmc b-frames & ratecontrol
@@ -341,7 +338,6 @@ typedef struct MpegEncContext {
/* motion compensation */
int unrestricted_mv; ///< mv can point outside of the coded picture
int h263_long_vectors; ///< use horrible h263v1 long vector mode
- int decode; ///< if 0 then decoding will be skipped (for encoding b frames for example)
DSPContext dsp; ///< pointers for accelerated dsp functions
int f_code; ///< forward MV resolution
@@ -436,7 +432,6 @@ typedef struct MpegEncContext {
uint8_t *inter_ac_vlc_length;
uint8_t *inter_ac_vlc_last_length;
uint8_t *luma_dc_vlc_length;
- uint8_t *chroma_dc_vlc_length;
#define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level))
int coded_score[8];
@@ -456,7 +451,6 @@ typedef struct MpegEncContext {
void *opaque; ///< private data for the user
/* bit rate control */
- int64_t wanted_bits;
int64_t total_bits;
int frame_bits; ///< bits used for the current frame
int next_lambda; ///< next lambda used for retrying to encode a frame
@@ -478,20 +472,22 @@ typedef struct MpegEncContext {
int error_count, error_occurred;
uint8_t *error_status_table; ///< table of the error status of each MB
#define VP_START 1 ///< current MB is the first after a resync marker
-#define AC_ERROR 2
-#define DC_ERROR 4
-#define MV_ERROR 8
-#define AC_END 16
-#define DC_END 32
-#define MV_END 64
-//FIXME some prefix?
+#define ER_AC_ERROR 2
+#define ER_DC_ERROR 4
+#define ER_MV_ERROR 8
+#define ER_AC_END 16
+#define ER_DC_END 32
+#define ER_MV_END 64
+
+#define ER_MB_ERROR (ER_AC_ERROR|ER_DC_ERROR|ER_MV_ERROR)
+#define ER_MB_END (ER_AC_END|ER_DC_END|ER_MV_END)
int resync_mb_x; ///< x position of last resync marker
int resync_mb_y; ///< y position of last resync marker
GetBitContext last_resync_gb; ///< used to search for the next resync marker
int mb_num_left; ///< number of MBs left in this video packet (for partitioned Slices only)
int next_p_frame_damaged; ///< set if the next p frame is damaged, to avoid showing trashed b frames
- int error_recognition;
+ int err_recognition;
ParseContext parse_context;
@@ -641,6 +637,8 @@ typedef struct MpegEncContext {
int interlaced_dct;
int first_slice;
int first_field; ///< is 1 for the first field of a field picture 0 otherwise
+ int drop_frame_timecode; ///< timecode is in drop frame format.
+ int scan_offset; ///< reserve space for SVCD scan offset user data.
/* RTP specific */
int rtp_mode;
@@ -715,7 +713,7 @@ void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);
int MPV_lowest_referenced_row(MpegEncContext *s, int dir);
void MPV_report_decode_progress(MpegEncContext *s);
int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src);
-const uint8_t *ff_find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state);
+const uint8_t *avpriv_mpv_find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state);
void ff_set_qscale(MpegEncContext * s, int qscale);
void ff_er_frame_start(MpegEncContext *s);
@@ -730,8 +728,8 @@ void ff_init_block_index(MpegEncContext *s);
void ff_copy_picture(Picture *dst, Picture *src);
/**
- * allocates a Picture
- * The pixels are allocated/set by calling get_buffer() if shared=0
+ * Allocate a Picture.
+ * The pixels are allocated/set by calling get_buffer() if shared = 0.
*/
int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared);
diff --git a/libavcodec/mpegvideo_common.h b/libavcodec/mpegvideo_common.h
index d0093ce..d64404d 100644
--- a/libavcodec/mpegvideo_common.h
+++ b/libavcodec/mpegvideo_common.h
@@ -42,14 +42,14 @@
int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
/**
- * allocates a Picture
- * The pixels are allocated/set by calling get_buffer() if shared=0
+ * Allocate a Picture.
+ * The pixels are allocated/set by calling get_buffer() if shared = 0.
*/
int alloc_picture(MpegEncContext *s, Picture *pic, int shared);
/**
- * sets the given MpegEncContext to common defaults (same for encoding and decoding).
- * the changed fields will not depend upon the prior state of the MpegEncContext.
+ * Set the given MpegEncContext to common defaults (same for encoding and decoding).
+ * The changed fields will not depend upon the prior state of the MpegEncContext.
*/
void MPV_common_defaults(MpegEncContext *s);
@@ -255,8 +255,8 @@ if(s->quarter_sample)
#endif
v_edge_pos = s->v_edge_pos >> field_based;
- linesize = s->current_picture.linesize[0] << field_based;
- uvlinesize = s->current_picture.linesize[1] << field_based;
+ linesize = s->current_picture.f.linesize[0] << field_based;
+ uvlinesize = s->current_picture.f.linesize[1] << field_based;
dxy = ((motion_y & 1) << 1) | (motion_x & 1);
src_x = s->mb_x* 16 + (motion_x >> 1);
@@ -585,7 +585,7 @@ static inline void chroma_4mv_motion(MpegEncContext *s,
if (src_y == (s->height >> 1))
dxy &= ~2;
- offset = (src_y * (s->uvlinesize)) + src_x;
+ offset = src_y * s->uvlinesize + src_x;
ptr = ref_picture[1] + offset;
if(s->flags&CODEC_FLAG_EMU_EDGE){
if( (unsigned)src_x > (s->h_edge_pos>>1) - (dxy &1) - 8
@@ -657,30 +657,30 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
assert(!s->mb_skipped);
- memcpy(mv_cache[1][1], s->current_picture.motion_val[0][mot_xy ], sizeof(int16_t)*4);
- memcpy(mv_cache[2][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4);
- memcpy(mv_cache[3][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4);
+ memcpy(mv_cache[1][1], s->current_picture.f.motion_val[0][mot_xy ], sizeof(int16_t) * 4);
+ memcpy(mv_cache[2][1], s->current_picture.f.motion_val[0][mot_xy + mot_stride], sizeof(int16_t) * 4);
+ memcpy(mv_cache[3][1], s->current_picture.f.motion_val[0][mot_xy + mot_stride], sizeof(int16_t) * 4);
- if(mb_y==0 || IS_INTRA(s->current_picture.mb_type[xy-s->mb_stride])){
+ if (mb_y == 0 || IS_INTRA(s->current_picture.f.mb_type[xy - s->mb_stride])) {
memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4);
}else{
- memcpy(mv_cache[0][1], s->current_picture.motion_val[0][mot_xy-mot_stride], sizeof(int16_t)*4);
+ memcpy(mv_cache[0][1], s->current_picture.f.motion_val[0][mot_xy - mot_stride], sizeof(int16_t) * 4);
}
- if(mb_x==0 || IS_INTRA(s->current_picture.mb_type[xy-1])){
+ if (mb_x == 0 || IS_INTRA(s->current_picture.f.mb_type[xy - 1])) {
AV_COPY32(mv_cache[1][0], mv_cache[1][1]);
AV_COPY32(mv_cache[2][0], mv_cache[2][1]);
}else{
- AV_COPY32(mv_cache[1][0], s->current_picture.motion_val[0][mot_xy-1]);
- AV_COPY32(mv_cache[2][0], s->current_picture.motion_val[0][mot_xy-1+mot_stride]);
+ AV_COPY32(mv_cache[1][0], s->current_picture.f.motion_val[0][mot_xy - 1]);
+ AV_COPY32(mv_cache[2][0], s->current_picture.f.motion_val[0][mot_xy - 1 + mot_stride]);
}
- if(mb_x+1>=s->mb_width || IS_INTRA(s->current_picture.mb_type[xy+1])){
+ if (mb_x + 1 >= s->mb_width || IS_INTRA(s->current_picture.f.mb_type[xy + 1])) {
AV_COPY32(mv_cache[1][3], mv_cache[1][2]);
AV_COPY32(mv_cache[2][3], mv_cache[2][2]);
}else{
- AV_COPY32(mv_cache[1][3], s->current_picture.motion_val[0][mot_xy+2]);
- AV_COPY32(mv_cache[2][3], s->current_picture.motion_val[0][mot_xy+2+mot_stride]);
+ AV_COPY32(mv_cache[1][3], s->current_picture.f.motion_val[0][mot_xy + 2]);
+ AV_COPY32(mv_cache[2][3], s->current_picture.f.motion_val[0][mot_xy + 2 + mot_stride]);
}
mx = 0;
@@ -817,7 +817,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
}
} else {
if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field){
- ref_picture= s->current_picture_ptr->data;
+ ref_picture = s->current_picture_ptr->f.data;
}
mpeg_motion(s, dest_y, dest_cb, dest_cr,
@@ -834,7 +834,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
|| s->pict_type == AV_PICTURE_TYPE_B || s->first_field){
ref2picture= ref_picture;
}else{
- ref2picture= s->current_picture_ptr->data;
+ ref2picture = s->current_picture_ptr->f.data;
}
mpeg_motion(s, dest_y, dest_cb, dest_cr,
@@ -871,7 +871,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
//opposite parity is always in the same frame if this is second field
if(!s->first_field){
- ref_picture = s->current_picture_ptr->data;
+ ref_picture = s->current_picture_ptr->f.data;
}
}
}
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 51713a2..af303d8 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -28,6 +28,8 @@
*/
#include "libavutil/intmath.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
@@ -57,156 +59,188 @@ static int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int
//#define DEBUG
-static uint8_t default_mv_penalty[MAX_FCODE+1][MAX_MV*2+1];
-static uint8_t default_fcode_tab[MAX_MV*2+1];
+static uint8_t default_mv_penalty[MAX_FCODE + 1][MAX_MV * 2 + 1];
+static uint8_t default_fcode_tab[MAX_MV * 2 + 1];
-void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64],
- const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra)
+void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64],
+ uint16_t (*qmat16)[2][64],
+ const uint16_t *quant_matrix,
+ int bias, int qmin, int qmax, int intra)
{
int qscale;
- int shift=0;
+ int shift = 0;
- for(qscale=qmin; qscale<=qmax; qscale++){
+ for (qscale = qmin; qscale <= qmax; qscale++) {
int i;
- if (dsp->fdct == ff_jpeg_fdct_islow
+ if (dsp->fdct == ff_jpeg_fdct_islow_8 ||
+ dsp->fdct == ff_jpeg_fdct_islow_10
#ifdef FAAN_POSTSCALE
|| dsp->fdct == ff_faandct
#endif
) {
- for(i=0;i<64;i++) {
- const int j= dsp->idct_permutation[i];
- /* 16 <= qscale * quant_matrix[i] <= 7905 */
- /* 19952 <= ff_aanscales[i] * qscale * quant_matrix[i] <= 249205026 */
- /* (1 << 36) / 19952 >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= (1 << 36) / 249205026 */
- /* 3444240 >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= 275 */
+ for (i = 0; i < 64; i++) {
+ const int j = dsp->idct_permutation[i];
+ /* 16 <= qscale * quant_matrix[i] <= 7905
+ * Assume x = ff_aanscales[i] * qscale * quant_matrix[i]
+ * 19952 <= x <= 249205026
+ * (1 << 36) / 19952 >= (1 << 36) / (x) >= (1 << 36) / 249205026
+ * 3444240 >= (1 << 36) / (x) >= 275 */
qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) /
- (qscale * quant_matrix[j]));
+ (qscale * quant_matrix[j]));
}
} else if (dsp->fdct == fdct_ifast
#ifndef FAAN_POSTSCALE
|| dsp->fdct == ff_faandct
#endif
) {
- for(i=0;i<64;i++) {
- const int j= dsp->idct_permutation[i];
- /* 16 <= qscale * quant_matrix[i] <= 7905 */
- /* 19952 <= ff_aanscales[i] * qscale * quant_matrix[i] <= 249205026 */
- /* (1 << 36) / 19952 >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */
- /* 3444240 >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= 275 */
+ for (i = 0; i < 64; i++) {
+ const int j = dsp->idct_permutation[i];
+ /* 16 <= qscale * quant_matrix[i] <= 7905
+ * Assume x = ff_aanscales[i] * qscale * quant_matrix[i]
+ * 19952 <= x <= 249205026
+ * (1 << 36) / 19952 >= (1 << 36) / (x) >= (1 << 36) / 249205026
+ * 3444240 >= (1 << 36) / (x) >= 275 */
qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) /
- (ff_aanscales[i] * qscale * quant_matrix[j]));
+ (ff_aanscales[i] * qscale *
+ quant_matrix[j]));
}
} else {
- for(i=0;i<64;i++) {
- const int j= dsp->idct_permutation[i];
+ for (i = 0; i < 64; i++) {
+ const int j = dsp->idct_permutation[i];
/* We can safely suppose that 16 <= quant_matrix[i] <= 255
- So 16 <= qscale * quant_matrix[i] <= 7905
- so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905
- so 32768 >= (1<<19) / (qscale * quant_matrix[i]) >= 67
- */
- qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / (qscale * quant_matrix[j]));
-// qmat [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]);
- qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]);
-
- if(qmat16[qscale][0][i]==0 || qmat16[qscale][0][i]==128*256) qmat16[qscale][0][i]=128*256-1;
- qmat16[qscale][1][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][0][i]);
+ * Assume x = qscale * quant_matrix[i]
+ * So 16 <= x <= 7905
+ * so (1 << 19) / 16 >= (1 << 19) / (x) >= (1 << 19) / 7905
+ * so 32768 >= (1 << 19) / (x) >= 67 */
+ qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) /
+ (qscale * quant_matrix[j]));
+ //qmat [qscale][i] = (1 << QMAT_SHIFT_MMX) /
+ // (qscale * quant_matrix[i]);
+ qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) /
+ (qscale * quant_matrix[j]);
+
+ if (qmat16[qscale][0][i] == 0 ||
+ qmat16[qscale][0][i] == 128 * 256)
+ qmat16[qscale][0][i] = 128 * 256 - 1;
+ qmat16[qscale][1][i] =
+ ROUNDED_DIV(bias << (16 - QUANT_BIAS_SHIFT),
+ qmat16[qscale][0][i]);
}
}
- for(i=intra; i<64; i++){
- int64_t max= 8191;
+ for (i = intra; i < 64; i++) {
+ int64_t max = 8191;
if (dsp->fdct == fdct_ifast
#ifndef FAAN_POSTSCALE
- || dsp->fdct == ff_faandct
+ || dsp->fdct == ff_faandct
#endif
- ) {
- max = (8191LL*ff_aanscales[i]) >> 14;
+ ) {
+ max = (8191LL * ff_aanscales[i]) >> 14;
}
- while(((max * qmat[qscale][i]) >> shift) > INT_MAX){
+ while (((max * qmat[qscale][i]) >> shift) > INT_MAX) {
shift++;
}
}
}
- if(shift){
- av_log(NULL, AV_LOG_INFO, "Warning, QMAT_SHIFT is larger than %d, overflows possible\n", QMAT_SHIFT - shift);
+ if (shift) {
+ av_log(NULL, AV_LOG_INFO,
+ "Warning, QMAT_SHIFT is larger than %d, overflows possible\n",
+ QMAT_SHIFT - shift);
}
}
-static inline void update_qscale(MpegEncContext *s){
- s->qscale= (s->lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
- s->qscale= av_clip(s->qscale, s->avctx->qmin, s->avctx->qmax);
+static inline void update_qscale(MpegEncContext *s)
+{
+ s->qscale = (s->lambda * 139 + FF_LAMBDA_SCALE * 64) >>
+ (FF_LAMBDA_SHIFT + 7);
+ s->qscale = av_clip(s->qscale, s->avctx->qmin, s->avctx->qmax);
- s->lambda2= (s->lambda*s->lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
+ s->lambda2 = (s->lambda * s->lambda + FF_LAMBDA_SCALE / 2) >>
+ FF_LAMBDA_SHIFT;
}
-void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix){
+void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix)
+{
int i;
- if(matrix){
+ if (matrix) {
put_bits(pb, 1, 1);
- for(i=0;i<64;i++) {
- put_bits(pb, 8, matrix[ ff_zigzag_direct[i] ]);
+ for (i = 0; i < 64; i++) {
+ put_bits(pb, 8, matrix[ff_zigzag_direct[i]]);
}
- }else
+ } else
put_bits(pb, 1, 0);
}
/**
* init s->current_picture.qscale_table from s->lambda_table
*/
-void ff_init_qscale_tab(MpegEncContext *s){
- int8_t * const qscale_table= s->current_picture.qscale_table;
+void ff_init_qscale_tab(MpegEncContext *s)
+{
+ int8_t * const qscale_table = s->current_picture.f.qscale_table;
int i;
- for(i=0; i<s->mb_num; i++){
- unsigned int lam= s->lambda_table[ s->mb_index2xy[i] ];
- int qp= (lam*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
- qscale_table[ s->mb_index2xy[i] ]= av_clip(qp, s->avctx->qmin, s->avctx->qmax);
+ for (i = 0; i < s->mb_num; i++) {
+ unsigned int lam = s->lambda_table[s->mb_index2xy[i]];
+ int qp = (lam * 139 + FF_LAMBDA_SCALE * 64) >> (FF_LAMBDA_SHIFT + 7);
+ qscale_table[s->mb_index2xy[i]] = av_clip(qp, s->avctx->qmin,
+ s->avctx->qmax);
}
}
-static void copy_picture_attributes(MpegEncContext *s, AVFrame *dst, AVFrame *src){
+static void copy_picture_attributes(MpegEncContext *s,
+ AVFrame *dst,
+ AVFrame *src)
+{
int i;
dst->pict_type = src->pict_type;
dst->quality = src->quality;
dst->coded_picture_number = src->coded_picture_number;
dst->display_picture_number = src->display_picture_number;
-// dst->reference = src->reference;
+ //dst->reference = src->reference;
dst->pts = src->pts;
dst->interlaced_frame = src->interlaced_frame;
dst->top_field_first = src->top_field_first;
- if(s->avctx->me_threshold){
- if(!src->motion_val[0])
+ if (s->avctx->me_threshold) {
+ if (!src->motion_val[0])
av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_val not set!\n");
- if(!src->mb_type)
+ if (!src->mb_type)
av_log(s->avctx, AV_LOG_ERROR, "AVFrame.mb_type not set!\n");
- if(!src->ref_index[0])
+ if (!src->ref_index[0])
av_log(s->avctx, AV_LOG_ERROR, "AVFrame.ref_index not set!\n");
- if(src->motion_subsample_log2 != dst->motion_subsample_log2)
- av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_subsample_log2 doesn't match! (%d!=%d)\n",
- src->motion_subsample_log2, dst->motion_subsample_log2);
-
- memcpy(dst->mb_type, src->mb_type, s->mb_stride * s->mb_height * sizeof(dst->mb_type[0]));
-
- for(i=0; i<2; i++){
- int stride= ((16*s->mb_width )>>src->motion_subsample_log2) + 1;
- int height= ((16*s->mb_height)>>src->motion_subsample_log2);
-
- if(src->motion_val[i] && src->motion_val[i] != dst->motion_val[i]){
- memcpy(dst->motion_val[i], src->motion_val[i], 2*stride*height*sizeof(int16_t));
+ if (src->motion_subsample_log2 != dst->motion_subsample_log2)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "AVFrame.motion_subsample_log2 doesn't match! (%d!=%d)\n",
+ src->motion_subsample_log2, dst->motion_subsample_log2);
+
+ memcpy(dst->mb_type, src->mb_type,
+ s->mb_stride * s->mb_height * sizeof(dst->mb_type[0]));
+
+ for (i = 0; i < 2; i++) {
+ int stride = ((16 * s->mb_width ) >>
+ src->motion_subsample_log2) + 1;
+ int height = ((16 * s->mb_height) >> src->motion_subsample_log2);
+
+ if (src->motion_val[i] &&
+ src->motion_val[i] != dst->motion_val[i]) {
+ memcpy(dst->motion_val[i], src->motion_val[i],
+ 2 * stride * height * sizeof(int16_t));
}
- if(src->ref_index[i] && src->ref_index[i] != dst->ref_index[i]){
- memcpy(dst->ref_index[i], src->ref_index[i], s->mb_stride*4*s->mb_height*sizeof(int8_t));
+ if (src->ref_index[i] && src->ref_index[i] != dst->ref_index[i]) {
+ memcpy(dst->ref_index[i], src->ref_index[i],
+ s->mb_stride * 4 * s->mb_height * sizeof(int8_t));
}
}
}
}
-static void update_duplicate_context_after_me(MpegEncContext *dst, MpegEncContext *src){
+static void update_duplicate_context_after_me(MpegEncContext *dst,
+ MpegEncContext *src)
+{
#define COPY(a) dst->a= src->a
COPY(pict_type);
COPY(current_picture);
@@ -217,25 +251,26 @@ static void update_duplicate_context_after_me(MpegEncContext *dst, MpegEncContex
COPY(lambda2);
COPY(picture_in_gop_number);
COPY(gop_picture_number);
- COPY(frame_pred_frame_dct); //FIXME don't set in encode_header
- COPY(progressive_frame); //FIXME don't set in encode_header
- COPY(partitioned_frame); //FIXME don't set in encode_header
+ COPY(frame_pred_frame_dct); // FIXME don't set in encode_header
+ COPY(progressive_frame); // FIXME don't set in encode_header
+ COPY(partitioned_frame); // FIXME don't set in encode_header
#undef COPY
}
/**
- * sets the given MpegEncContext to defaults for encoding.
+ * Set the given MpegEncContext to defaults for encoding.
* the changed fields will not depend upon the prior state of the MpegEncContext.
*/
-static void MPV_encode_defaults(MpegEncContext *s){
+static void MPV_encode_defaults(MpegEncContext *s)
+{
int i;
MPV_common_defaults(s);
- for(i=-16; i<16; i++){
- default_fcode_tab[i + MAX_MV]= 1;
+ for (i = -16; i < 16; i++) {
+ default_fcode_tab[i + MAX_MV] = 1;
}
- s->me.mv_penalty= default_mv_penalty;
- s->fcode_tab= default_fcode_tab;
+ s->me.mv_penalty = default_mv_penalty;
+ s->fcode_tab = default_fcode_tab;
}
/* init video encoder */
@@ -249,27 +284,38 @@ av_cold int MPV_encode_init(AVCodecContext *avctx)
switch (avctx->codec_id) {
case CODEC_ID_MPEG2VIDEO:
- if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P){
- av_log(avctx, AV_LOG_ERROR, "only YUV420 and YUV422 are supported\n");
+ if (avctx->pix_fmt != PIX_FMT_YUV420P &&
+ avctx->pix_fmt != PIX_FMT_YUV422P) {
+ av_log(avctx, AV_LOG_ERROR,
+ "only YUV420 and YUV422 are supported\n");
return -1;
}
break;
case CODEC_ID_LJPEG:
- if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P && avctx->pix_fmt != PIX_FMT_YUVJ444P && avctx->pix_fmt != PIX_FMT_BGRA &&
- ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P && avctx->pix_fmt != PIX_FMT_YUV444P) || avctx->strict_std_compliance>FF_COMPLIANCE_UNOFFICIAL)){
+ if (avctx->pix_fmt != PIX_FMT_YUVJ420P &&
+ avctx->pix_fmt != PIX_FMT_YUVJ422P &&
+ avctx->pix_fmt != PIX_FMT_YUVJ444P &&
+ avctx->pix_fmt != PIX_FMT_BGRA &&
+ ((avctx->pix_fmt != PIX_FMT_YUV420P &&
+ avctx->pix_fmt != PIX_FMT_YUV422P &&
+ avctx->pix_fmt != PIX_FMT_YUV444P) ||
+ avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)) {
av_log(avctx, AV_LOG_ERROR, "colorspace not supported in LJPEG\n");
return -1;
}
break;
case CODEC_ID_MJPEG:
- if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P &&
- ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P) || avctx->strict_std_compliance>FF_COMPLIANCE_UNOFFICIAL)){
+ if (avctx->pix_fmt != PIX_FMT_YUVJ420P &&
+ avctx->pix_fmt != PIX_FMT_YUVJ422P &&
+ ((avctx->pix_fmt != PIX_FMT_YUV420P &&
+ avctx->pix_fmt != PIX_FMT_YUV422P) ||
+ avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)) {
av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n");
return -1;
}
break;
default:
- if(avctx->pix_fmt != PIX_FMT_YUV420P){
+ if (avctx->pix_fmt != PIX_FMT_YUV420P) {
av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n");
return -1;
}
@@ -288,31 +334,36 @@ av_cold int MPV_encode_init(AVCodecContext *avctx)
}
s->bit_rate = avctx->bit_rate;
- s->width = avctx->width;
- s->height = avctx->height;
- if(avctx->gop_size > 600 && avctx->strict_std_compliance>FF_COMPLIANCE_EXPERIMENTAL){
- av_log(avctx, AV_LOG_ERROR, "Warning keyframe interval too large! reducing it ...\n");
- avctx->gop_size=600;
- }
- s->gop_size = avctx->gop_size;
- s->avctx = avctx;
- s->flags= avctx->flags;
- s->flags2= avctx->flags2;
- s->max_b_frames= avctx->max_b_frames;
- s->codec_id= avctx->codec->id;
- s->luma_elim_threshold = avctx->luma_elim_threshold;
- s->chroma_elim_threshold= avctx->chroma_elim_threshold;
- s->strict_std_compliance= avctx->strict_std_compliance;
- s->data_partitioning= avctx->flags & CODEC_FLAG_PART;
- s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0;
- s->mpeg_quant= avctx->mpeg_quant;
- s->rtp_mode= !!avctx->rtp_payload_size;
- s->intra_dc_precision= avctx->intra_dc_precision;
+ s->width = avctx->width;
+ s->height = avctx->height;
+ if (avctx->gop_size > 600 &&
+ avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Warning keyframe interval too large! reducing it ...\n");
+ avctx->gop_size = 600;
+ }
+ s->gop_size = avctx->gop_size;
+ s->avctx = avctx;
+ s->flags = avctx->flags;
+ s->flags2 = avctx->flags2;
+ s->max_b_frames = avctx->max_b_frames;
+ s->codec_id = avctx->codec->id;
+ s->luma_elim_threshold = avctx->luma_elim_threshold;
+ s->chroma_elim_threshold = avctx->chroma_elim_threshold;
+ s->strict_std_compliance = avctx->strict_std_compliance;
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+ if (avctx->flags & CODEC_FLAG_PART)
+ s->data_partitioning = 1;
+#endif
+ s->quarter_sample = (avctx->flags & CODEC_FLAG_QPEL) != 0;
+ s->mpeg_quant = avctx->mpeg_quant;
+ s->rtp_mode = !!avctx->rtp_payload_size;
+ s->intra_dc_precision = avctx->intra_dc_precision;
s->user_specified_pts = AV_NOPTS_VALUE;
if (s->gop_size <= 1) {
s->intra_only = 1;
- s->gop_size = 12;
+ s->gop_size = 12;
} else {
s->intra_only = 0;
}
@@ -322,384 +373,462 @@ av_cold int MPV_encode_init(AVCodecContext *avctx)
/* Fixed QSCALE */
s->fixed_qscale = !!(avctx->flags & CODEC_FLAG_QSCALE);
- s->adaptive_quant= ( s->avctx->lumi_masking
- || s->avctx->dark_masking
- || s->avctx->temporal_cplx_masking
- || s->avctx->spatial_cplx_masking
- || s->avctx->p_masking
- || s->avctx->border_masking
- || (s->flags&CODEC_FLAG_QP_RD))
- && !s->fixed_qscale;
-
- s->obmc= !!(s->flags & CODEC_FLAG_OBMC);
- s->loop_filter= !!(s->flags & CODEC_FLAG_LOOP_FILTER);
- s->alternate_scan= !!(s->flags & CODEC_FLAG_ALT_SCAN);
- s->intra_vlc_format= !!(s->flags2 & CODEC_FLAG2_INTRA_VLC);
- s->q_scale_type= !!(s->flags2 & CODEC_FLAG2_NON_LINEAR_QUANT);
-
- if(avctx->rc_max_rate && !avctx->rc_buffer_size){
- av_log(avctx, AV_LOG_ERROR, "a vbv buffer size is needed, for encoding with a maximum bitrate\n");
+ s->adaptive_quant = (s->avctx->lumi_masking ||
+ s->avctx->dark_masking ||
+ s->avctx->temporal_cplx_masking ||
+ s->avctx->spatial_cplx_masking ||
+ s->avctx->p_masking ||
+ s->avctx->border_masking ||
+ (s->flags & CODEC_FLAG_QP_RD)) &&
+ !s->fixed_qscale;
+
+ s->loop_filter = !!(s->flags & CODEC_FLAG_LOOP_FILTER);
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+ s->alternate_scan = !!(s->flags & CODEC_FLAG_ALT_SCAN);
+ s->intra_vlc_format = !!(s->flags2 & CODEC_FLAG2_INTRA_VLC);
+ s->q_scale_type = !!(s->flags2 & CODEC_FLAG2_NON_LINEAR_QUANT);
+ s->obmc = !!(s->flags & CODEC_FLAG_OBMC);
+#endif
+
+ if (avctx->rc_max_rate && !avctx->rc_buffer_size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "a vbv buffer size is needed, "
+ "for encoding with a maximum bitrate\n");
return -1;
}
- if(avctx->rc_min_rate && avctx->rc_max_rate != avctx->rc_min_rate){
- av_log(avctx, AV_LOG_INFO, "Warning min_rate > 0 but min_rate != max_rate isn't recommended!\n");
+ if (avctx->rc_min_rate && avctx->rc_max_rate != avctx->rc_min_rate) {
+ av_log(avctx, AV_LOG_INFO,
+ "Warning min_rate > 0 but min_rate != max_rate isn't recommended!\n");
}
- if(avctx->rc_min_rate && avctx->rc_min_rate > avctx->bit_rate){
+ if (avctx->rc_min_rate && avctx->rc_min_rate > avctx->bit_rate) {
av_log(avctx, AV_LOG_ERROR, "bitrate below min bitrate\n");
return -1;
}
- if(avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate){
+ if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) {
av_log(avctx, AV_LOG_INFO, "bitrate above max bitrate\n");
return -1;
}
- if(avctx->rc_max_rate && avctx->rc_max_rate == avctx->bit_rate && avctx->rc_max_rate != avctx->rc_min_rate){
- av_log(avctx, AV_LOG_INFO, "impossible bitrate constraints, this will fail\n");
+ if (avctx->rc_max_rate &&
+ avctx->rc_max_rate == avctx->bit_rate &&
+ avctx->rc_max_rate != avctx->rc_min_rate) {
+ av_log(avctx, AV_LOG_INFO,
+ "impossible bitrate constraints, this will fail\n");
}
- if(avctx->rc_buffer_size && avctx->bit_rate*(int64_t)avctx->time_base.num > avctx->rc_buffer_size * (int64_t)avctx->time_base.den){
+ if (avctx->rc_buffer_size &&
+ avctx->bit_rate * (int64_t)avctx->time_base.num >
+ avctx->rc_buffer_size * (int64_t)avctx->time_base.den) {
av_log(avctx, AV_LOG_ERROR, "VBV buffer too small for bitrate\n");
return -1;
}
- if(!s->fixed_qscale && avctx->bit_rate*av_q2d(avctx->time_base) > avctx->bit_rate_tolerance){
- av_log(avctx, AV_LOG_ERROR, "bitrate tolerance too small for bitrate\n");
+ if (!s->fixed_qscale &&
+ avctx->bit_rate * av_q2d(avctx->time_base) >
+ avctx->bit_rate_tolerance) {
+ av_log(avctx, AV_LOG_ERROR,
+ "bitrate tolerance too small for bitrate\n");
return -1;
}
- if( s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate
- && (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO)
- && 90000LL * (avctx->rc_buffer_size-1) > s->avctx->rc_max_rate*0xFFFFLL){
-
- av_log(avctx, AV_LOG_INFO, "Warning vbv_delay will be set to 0xFFFF (=VBR) as the specified vbv buffer is too large for the given bitrate!\n");
+ if (s->avctx->rc_max_rate &&
+ s->avctx->rc_min_rate == s->avctx->rc_max_rate &&
+ (s->codec_id == CODEC_ID_MPEG1VIDEO ||
+ s->codec_id == CODEC_ID_MPEG2VIDEO) &&
+ 90000LL * (avctx->rc_buffer_size - 1) >
+ s->avctx->rc_max_rate * 0xFFFFLL) {
+ av_log(avctx, AV_LOG_INFO,
+ "Warning vbv_delay will be set to 0xFFFF (=VBR) as the "
+ "specified vbv buffer is too large for the given bitrate!\n");
}
- if((s->flags & CODEC_FLAG_4MV) && s->codec_id != CODEC_ID_MPEG4
- && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P && s->codec_id != CODEC_ID_FLV1){
+ if ((s->flags & CODEC_FLAG_4MV) && s->codec_id != CODEC_ID_MPEG4 &&
+ s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P &&
+ s->codec_id != CODEC_ID_FLV1) {
av_log(avctx, AV_LOG_ERROR, "4MV not supported by codec\n");
return -1;
}
- if(s->obmc && s->avctx->mb_decision != FF_MB_DECISION_SIMPLE){
- av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with simple mb decision\n");
+ if (s->obmc && s->avctx->mb_decision != FF_MB_DECISION_SIMPLE) {
+ av_log(avctx, AV_LOG_ERROR,
+ "OBMC is only supported with simple mb decision\n");
return -1;
}
- if(s->obmc && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P){
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+ if (s->obmc && s->codec_id != CODEC_ID_H263 &&
+ s->codec_id != CODEC_ID_H263P) {
av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with H263(+)\n");
return -1;
}
+#endif
- if(s->quarter_sample && s->codec_id != CODEC_ID_MPEG4){
+ if (s->quarter_sample && s->codec_id != CODEC_ID_MPEG4) {
av_log(avctx, AV_LOG_ERROR, "qpel not supported by codec\n");
return -1;
}
- if(s->data_partitioning && s->codec_id != CODEC_ID_MPEG4){
- av_log(avctx, AV_LOG_ERROR, "data partitioning not supported by codec\n");
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+ if (s->data_partitioning && s->codec_id != CODEC_ID_MPEG4) {
+ av_log(avctx, AV_LOG_ERROR,
+ "data partitioning not supported by codec\n");
return -1;
}
+#endif
- if(s->max_b_frames && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO){
+ if (s->max_b_frames &&
+ s->codec_id != CODEC_ID_MPEG4 &&
+ s->codec_id != CODEC_ID_MPEG1VIDEO &&
+ s->codec_id != CODEC_ID_MPEG2VIDEO) {
av_log(avctx, AV_LOG_ERROR, "b frames not supported by codec\n");
return -1;
}
- if ((s->codec_id == CODEC_ID_MPEG4 || s->codec_id == CODEC_ID_H263 ||
+ if ((s->codec_id == CODEC_ID_MPEG4 ||
+ s->codec_id == CODEC_ID_H263 ||
s->codec_id == CODEC_ID_H263P) &&
- (avctx->sample_aspect_ratio.num > 255 || avctx->sample_aspect_ratio.den > 255)) {
- av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i, limit is 255/255\n",
+ (avctx->sample_aspect_ratio.num > 255 ||
+ avctx->sample_aspect_ratio.den > 255)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid pixel aspect ratio %i/%i, limit is 255/255\n",
avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
return -1;
}
- if((s->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN))
- && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG2VIDEO){
+ if ((s->flags & (CODEC_FLAG_INTERLACED_DCT | CODEC_FLAG_INTERLACED_ME |
+ CODEC_FLAG_ALT_SCAN)) &&
+ s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG2VIDEO) {
av_log(avctx, AV_LOG_ERROR, "interlacing not supported by codec\n");
return -1;
}
- if(s->mpeg_quant && s->codec_id != CODEC_ID_MPEG4){ //FIXME mpeg2 uses that too
- av_log(avctx, AV_LOG_ERROR, "mpeg2 style quantization not supported by codec\n");
+ // FIXME mpeg2 uses that too
+ if (s->mpeg_quant && s->codec_id != CODEC_ID_MPEG4) {
+ av_log(avctx, AV_LOG_ERROR,
+ "mpeg2 style quantization not supported by codec\n");
return -1;
}
- if((s->flags & CODEC_FLAG_CBP_RD) && !avctx->trellis){
+ if ((s->flags & CODEC_FLAG_CBP_RD) && !avctx->trellis) {
av_log(avctx, AV_LOG_ERROR, "CBP RD needs trellis quant\n");
return -1;
}
- if((s->flags & CODEC_FLAG_QP_RD) && s->avctx->mb_decision != FF_MB_DECISION_RD){
+ if ((s->flags & CODEC_FLAG_QP_RD) &&
+ s->avctx->mb_decision != FF_MB_DECISION_RD) {
av_log(avctx, AV_LOG_ERROR, "QP RD needs mbd=2\n");
return -1;
}
- if(s->avctx->scenechange_threshold < 1000000000 && (s->flags & CODEC_FLAG_CLOSED_GOP)){
- av_log(avctx, AV_LOG_ERROR, "closed gop with scene change detection are not supported yet, set threshold to 1000000000\n");
+ if (s->avctx->scenechange_threshold < 1000000000 &&
+ (s->flags & CODEC_FLAG_CLOSED_GOP)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "closed gop with scene change detection are not supported yet, "
+ "set threshold to 1000000000\n");
return -1;
}
- if((s->flags2 & CODEC_FLAG2_INTRA_VLC) && s->codec_id != CODEC_ID_MPEG2VIDEO){
- av_log(avctx, AV_LOG_ERROR, "intra vlc table not supported by codec\n");
+ if ((s->flags2 & CODEC_FLAG2_INTRA_VLC) &&
+ s->codec_id != CODEC_ID_MPEG2VIDEO) {
+ av_log(avctx, AV_LOG_ERROR,
+ "intra vlc table not supported by codec\n");
return -1;
}
- if(s->flags & CODEC_FLAG_LOW_DELAY){
- if (s->codec_id != CODEC_ID_MPEG2VIDEO){
- av_log(avctx, AV_LOG_ERROR, "low delay forcing is only available for mpeg2\n");
+ if (s->flags & CODEC_FLAG_LOW_DELAY) {
+ if (s->codec_id != CODEC_ID_MPEG2VIDEO) {
+ av_log(avctx, AV_LOG_ERROR,
+ "low delay forcing is only available for mpeg2\n");
return -1;
}
- if (s->max_b_frames != 0){
- av_log(avctx, AV_LOG_ERROR, "b frames cannot be used with low delay\n");
+ if (s->max_b_frames != 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "b frames cannot be used with low delay\n");
return -1;
}
}
- if(s->q_scale_type == 1){
- if(s->codec_id != CODEC_ID_MPEG2VIDEO){
- av_log(avctx, AV_LOG_ERROR, "non linear quant is only available for mpeg2\n");
+ if (s->q_scale_type == 1) {
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+ if (s->codec_id != CODEC_ID_MPEG2VIDEO) {
+ av_log(avctx, AV_LOG_ERROR,
+ "non linear quant is only available for mpeg2\n");
return -1;
}
- if(avctx->qmax > 12){
- av_log(avctx, AV_LOG_ERROR, "non linear quant only supports qmax <= 12 currently\n");
+#endif
+ if (avctx->qmax > 12) {
+ av_log(avctx, AV_LOG_ERROR,
+ "non linear quant only supports qmax <= 12 currently\n");
return -1;
}
}
- if(s->avctx->thread_count > 1 && s->codec_id != CODEC_ID_MPEG4
- && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO
- && (s->codec_id != CODEC_ID_H263P || !(s->flags & CODEC_FLAG_H263P_SLICE_STRUCT))){
- av_log(avctx, AV_LOG_ERROR, "multi threaded encoding not supported by codec\n");
+ if (s->avctx->thread_count > 1 &&
+ s->codec_id != CODEC_ID_MPEG4 &&
+ s->codec_id != CODEC_ID_MPEG1VIDEO &&
+ s->codec_id != CODEC_ID_MPEG2VIDEO &&
+ (s->codec_id != CODEC_ID_H263P ||
+ !(s->flags & CODEC_FLAG_H263P_SLICE_STRUCT))) {
+ av_log(avctx, AV_LOG_ERROR,
+ "multi threaded encoding not supported by codec\n");
return -1;
}
- if(s->avctx->thread_count < 1){
- av_log(avctx, AV_LOG_ERROR, "automatic thread number detection not supported by codec, patch welcome\n");
+ if (s->avctx->thread_count < 1) {
+ av_log(avctx, AV_LOG_ERROR,
+ "automatic thread number detection not supported by codec,"
+ "patch welcome\n");
return -1;
}
- if(s->avctx->thread_count > 1)
- s->rtp_mode= 1;
+ if (s->avctx->thread_count > 1)
+ s->rtp_mode = 1;
- if(!avctx->time_base.den || !avctx->time_base.num){
+ if (!avctx->time_base.den || !avctx->time_base.num) {
av_log(avctx, AV_LOG_ERROR, "framerate not set\n");
return -1;
}
- i= (INT_MAX/2+128)>>8;
- if(avctx->me_threshold >= i){
- av_log(avctx, AV_LOG_ERROR, "me_threshold too large, max is %d\n", i - 1);
+ i = (INT_MAX / 2 + 128) >> 8;
+ if (avctx->me_threshold >= i) {
+ av_log(avctx, AV_LOG_ERROR, "me_threshold too large, max is %d\n",
+ i - 1);
return -1;
}
- if(avctx->mb_threshold >= i){
- av_log(avctx, AV_LOG_ERROR, "mb_threshold too large, max is %d\n", i - 1);
+ if (avctx->mb_threshold >= i) {
+ av_log(avctx, AV_LOG_ERROR, "mb_threshold too large, max is %d\n",
+ i - 1);
return -1;
}
- if(avctx->b_frame_strategy && (avctx->flags&CODEC_FLAG_PASS2)){
- av_log(avctx, AV_LOG_INFO, "notice: b_frame_strategy only affects the first pass\n");
+ if (avctx->b_frame_strategy && (avctx->flags & CODEC_FLAG_PASS2)) {
+ av_log(avctx, AV_LOG_INFO,
+ "notice: b_frame_strategy only affects the first pass\n");
avctx->b_frame_strategy = 0;
}
- i= av_gcd(avctx->time_base.den, avctx->time_base.num);
- if(i > 1){
+ i = av_gcd(avctx->time_base.den, avctx->time_base.num);
+ if (i > 1) {
av_log(avctx, AV_LOG_INFO, "removing common factors from framerate\n");
avctx->time_base.den /= i;
avctx->time_base.num /= i;
-// return -1;
+ //return -1;
}
- if(s->mpeg_quant || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO || s->codec_id==CODEC_ID_MJPEG){
- s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x
- s->inter_quant_bias= 0;
- }else{
- s->intra_quant_bias=0;
- s->inter_quant_bias=-(1<<(QUANT_BIAS_SHIFT-2)); //(a - x/4)/x
+ if (s->mpeg_quant || s->codec_id == CODEC_ID_MPEG1VIDEO ||
+ s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG) {
+ // (a + x * 3 / 8) / x
+ s->intra_quant_bias = 3 << (QUANT_BIAS_SHIFT - 3);
+ s->inter_quant_bias = 0;
+ } else {
+ s->intra_quant_bias = 0;
+ // (a - x / 4) / x
+ s->inter_quant_bias = -(1 << (QUANT_BIAS_SHIFT - 2));
}
- if(avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS)
- s->intra_quant_bias= avctx->intra_quant_bias;
- if(avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS)
- s->inter_quant_bias= avctx->inter_quant_bias;
-
- avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift);
-
- if(avctx->codec_id == CODEC_ID_MPEG4 && s->avctx->time_base.den > (1<<16)-1){
- av_log(avctx, AV_LOG_ERROR, "timebase %d/%d not supported by MPEG 4 standard, "
- "the maximum admitted value for the timebase denominator is %d\n",
- s->avctx->time_base.num, s->avctx->time_base.den, (1<<16)-1);
+ if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS)
+ s->intra_quant_bias = avctx->intra_quant_bias;
+ if (avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS)
+ s->inter_quant_bias = avctx->inter_quant_bias;
+
+ avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift,
+ &chroma_v_shift);
+
+ if (avctx->codec_id == CODEC_ID_MPEG4 &&
+ s->avctx->time_base.den > (1 << 16) - 1) {
+ av_log(avctx, AV_LOG_ERROR,
+ "timebase %d/%d not supported by MPEG 4 standard, "
+ "the maximum admitted value for the timebase denominator "
+ "is %d\n", s->avctx->time_base.num, s->avctx->time_base.den,
+ (1 << 16) - 1);
return -1;
}
s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;
- switch(avctx->codec->id) {
+ switch (avctx->codec->id) {
case CODEC_ID_MPEG1VIDEO:
s->out_format = FMT_MPEG1;
- s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY);
- avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);
+ s->low_delay = !!(s->flags & CODEC_FLAG_LOW_DELAY);
+ avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1);
break;
case CODEC_ID_MPEG2VIDEO:
s->out_format = FMT_MPEG1;
- s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY);
- avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);
- s->rtp_mode= 1;
+ s->low_delay = !!(s->flags & CODEC_FLAG_LOW_DELAY);
+ avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1);
+ s->rtp_mode = 1;
break;
case CODEC_ID_LJPEG:
case CODEC_ID_MJPEG:
s->out_format = FMT_MJPEG;
s->intra_only = 1; /* force intra only for jpeg */
- if(avctx->codec->id == CODEC_ID_LJPEG && avctx->pix_fmt == PIX_FMT_BGRA){
+ if (avctx->codec->id == CODEC_ID_LJPEG &&
+ avctx->pix_fmt == PIX_FMT_BGRA) {
s->mjpeg_vsample[0] = s->mjpeg_hsample[0] =
s->mjpeg_vsample[1] = s->mjpeg_hsample[1] =
s->mjpeg_vsample[2] = s->mjpeg_hsample[2] = 1;
- }else{
+ } else {
s->mjpeg_vsample[0] = 2;
- s->mjpeg_vsample[1] = 2>>chroma_v_shift;
- s->mjpeg_vsample[2] = 2>>chroma_v_shift;
+ s->mjpeg_vsample[1] = 2 >> chroma_v_shift;
+ s->mjpeg_vsample[2] = 2 >> chroma_v_shift;
s->mjpeg_hsample[0] = 2;
- s->mjpeg_hsample[1] = 2>>chroma_h_shift;
- s->mjpeg_hsample[2] = 2>>chroma_h_shift;
+ s->mjpeg_hsample[1] = 2 >> chroma_h_shift;
+ s->mjpeg_hsample[2] = 2 >> chroma_h_shift;
}
- if (!(CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER)
- || ff_mjpeg_encode_init(s) < 0)
+ if (!(CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) ||
+ ff_mjpeg_encode_init(s) < 0)
return -1;
- avctx->delay=0;
- s->low_delay=1;
+ avctx->delay = 0;
+ s->low_delay = 1;
break;
case CODEC_ID_H261:
- if (!CONFIG_H261_ENCODER) return -1;
+ if (!CONFIG_H261_ENCODER)
+ return -1;
if (ff_h261_get_picture_format(s->width, s->height) < 0) {
- av_log(avctx, AV_LOG_ERROR, "The specified picture size of %dx%d is not valid for the H.261 codec.\nValid sizes are 176x144, 352x288\n", s->width, s->height);
+ av_log(avctx, AV_LOG_ERROR,
+ "The specified picture size of %dx%d is not valid for the "
+ "H.261 codec.\nValid sizes are 176x144, 352x288\n",
+ s->width, s->height);
return -1;
}
s->out_format = FMT_H261;
- avctx->delay=0;
- s->low_delay=1;
+ avctx->delay = 0;
+ s->low_delay = 1;
break;
case CODEC_ID_H263:
- if (!CONFIG_H263_ENCODER) return -1;
- if (ff_match_2uint16(h263_format, FF_ARRAY_ELEMS(h263_format), s->width, s->height) == 8) {
- av_log(avctx, AV_LOG_INFO, "The specified picture size of %dx%d is not valid for the H.263 codec.\nValid sizes are 128x96, 176x144, 352x288, 704x576, and 1408x1152. Try H.263+.\n", s->width, s->height);
+ if (!CONFIG_H263_ENCODER)
+ return -1;
+ if (ff_match_2uint16(h263_format, FF_ARRAY_ELEMS(h263_format),
+ s->width, s->height) == 8) {
+ av_log(avctx, AV_LOG_INFO,
+ "The specified picture size of %dx%d is not valid for "
+ "the H.263 codec.\nValid sizes are 128x96, 176x144, "
+ "352x288, 704x576, and 1408x1152."
+ "Try H.263+.\n", s->width, s->height);
return -1;
}
s->out_format = FMT_H263;
- s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0;
- avctx->delay=0;
- s->low_delay=1;
+ avctx->delay = 0;
+ s->low_delay = 1;
break;
case CODEC_ID_H263P:
s->out_format = FMT_H263;
- s->h263_plus = 1;
+ s->h263_plus = 1;
/* Fx */
- s->umvplus = (avctx->flags & CODEC_FLAG_H263P_UMV) ? 1:0;
- s->h263_aic= (avctx->flags & CODEC_FLAG_AC_PRED) ? 1:0;
- s->modified_quant= s->h263_aic;
- s->alt_inter_vlc= (avctx->flags & CODEC_FLAG_H263P_AIV) ? 1:0;
- s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0;
- s->loop_filter= (avctx->flags & CODEC_FLAG_LOOP_FILTER) ? 1:0;
- s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus;
- s->h263_slice_structured= (s->flags & CODEC_FLAG_H263P_SLICE_STRUCT) ? 1:0;
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+ if (avctx->flags & CODEC_FLAG_H263P_UMV)
+ s->umvplus = 1;
+ if (avctx->flags & CODEC_FLAG_H263P_AIV)
+ s->alt_inter_vlc = 1;
+ if (avctx->flags & CODEC_FLAG_H263P_SLICE_STRUCT)
+ s->h263_slice_structured = 1;
+#endif
+ s->h263_aic = (avctx->flags & CODEC_FLAG_AC_PRED) ? 1 : 0;
+ s->modified_quant = s->h263_aic;
+ s->loop_filter = (avctx->flags & CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
+ s->unrestricted_mv = s->obmc || s->loop_filter || s->umvplus;
/* /Fx */
/* These are just to be sure */
- avctx->delay=0;
- s->low_delay=1;
+ avctx->delay = 0;
+ s->low_delay = 1;
break;
case CODEC_ID_FLV1:
- s->out_format = FMT_H263;
- s->h263_flv = 2; /* format = 1; 11-bit codes */
+ s->out_format = FMT_H263;
+ s->h263_flv = 2; /* format = 1; 11-bit codes */
s->unrestricted_mv = 1;
- s->rtp_mode=0; /* don't allow GOB */
- avctx->delay=0;
- s->low_delay=1;
+ s->rtp_mode = 0; /* don't allow GOB */
+ avctx->delay = 0;
+ s->low_delay = 1;
break;
case CODEC_ID_RV10:
s->out_format = FMT_H263;
- avctx->delay=0;
- s->low_delay=1;
+ avctx->delay = 0;
+ s->low_delay = 1;
break;
case CODEC_ID_RV20:
- s->out_format = FMT_H263;
- avctx->delay=0;
- s->low_delay=1;
- s->modified_quant=1;
- s->h263_aic=1;
- s->h263_plus=1;
- s->loop_filter=1;
- s->unrestricted_mv= 0;
+ s->out_format = FMT_H263;
+ avctx->delay = 0;
+ s->low_delay = 1;
+ s->modified_quant = 1;
+ s->h263_aic = 1;
+ s->h263_plus = 1;
+ s->loop_filter = 1;
+ s->unrestricted_mv = 0;
break;
case CODEC_ID_MPEG4:
- s->out_format = FMT_H263;
- s->h263_pred = 1;
+ s->out_format = FMT_H263;
+ s->h263_pred = 1;
s->unrestricted_mv = 1;
- s->low_delay= s->max_b_frames ? 0 : 1;
- avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);
+ s->low_delay = s->max_b_frames ? 0 : 1;
+ avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1);
break;
case CODEC_ID_MSMPEG4V2:
- s->out_format = FMT_H263;
- s->h263_pred = 1;
+ s->out_format = FMT_H263;
+ s->h263_pred = 1;
s->unrestricted_mv = 1;
- s->msmpeg4_version= 2;
- avctx->delay=0;
- s->low_delay=1;
+ s->msmpeg4_version = 2;
+ avctx->delay = 0;
+ s->low_delay = 1;
break;
case CODEC_ID_MSMPEG4V3:
- s->out_format = FMT_H263;
- s->h263_pred = 1;
- s->unrestricted_mv = 1;
- s->msmpeg4_version= 3;
- s->flipflop_rounding=1;
- avctx->delay=0;
- s->low_delay=1;
+ s->out_format = FMT_H263;
+ s->h263_pred = 1;
+ s->unrestricted_mv = 1;
+ s->msmpeg4_version = 3;
+ s->flipflop_rounding = 1;
+ avctx->delay = 0;
+ s->low_delay = 1;
break;
case CODEC_ID_WMV1:
- s->out_format = FMT_H263;
- s->h263_pred = 1;
- s->unrestricted_mv = 1;
- s->msmpeg4_version= 4;
- s->flipflop_rounding=1;
- avctx->delay=0;
- s->low_delay=1;
+ s->out_format = FMT_H263;
+ s->h263_pred = 1;
+ s->unrestricted_mv = 1;
+ s->msmpeg4_version = 4;
+ s->flipflop_rounding = 1;
+ avctx->delay = 0;
+ s->low_delay = 1;
break;
case CODEC_ID_WMV2:
- s->out_format = FMT_H263;
- s->h263_pred = 1;
- s->unrestricted_mv = 1;
- s->msmpeg4_version= 5;
- s->flipflop_rounding=1;
- avctx->delay=0;
- s->low_delay=1;
+ s->out_format = FMT_H263;
+ s->h263_pred = 1;
+ s->unrestricted_mv = 1;
+ s->msmpeg4_version = 5;
+ s->flipflop_rounding = 1;
+ avctx->delay = 0;
+ s->low_delay = 1;
break;
default:
return -1;
}
- avctx->has_b_frames= !s->low_delay;
+ avctx->has_b_frames = !s->low_delay;
s->encoding = 1;
- s->progressive_frame=
- s->progressive_sequence= !(avctx->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN));
+ s->progressive_frame =
+ s->progressive_sequence = !(avctx->flags & (CODEC_FLAG_INTERLACED_DCT |
+ CODEC_FLAG_INTERLACED_ME |
+ CODEC_FLAG_ALT_SCAN));
/* init */
if (MPV_common_init(s) < 0)
return -1;
- if(!s->dct_quantize)
+ if (!s->dct_quantize)
s->dct_quantize = dct_quantize_c;
- if(!s->denoise_dct)
- s->denoise_dct = denoise_dct_c;
+ if (!s->denoise_dct)
+ s->denoise_dct = denoise_dct_c;
s->fast_dct_quantize = s->dct_quantize;
- if(avctx->trellis)
- s->dct_quantize = dct_quantize_trellis_c;
+ if (avctx->trellis)
+ s->dct_quantize = dct_quantize_trellis_c;
- if((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant)
- s->chroma_qscale_table= ff_h263_chroma_qscale_table;
+ if ((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant)
+ s->chroma_qscale_table = ff_h263_chroma_qscale_table;
- s->quant_precision=5;
+ s->quant_precision = 5;
ff_set_cmp(&s->dsp, s->dsp.ildct_cmp, s->avctx->ildct_cmp);
ff_set_cmp(&s->dsp, s->dsp.frame_skip_cmp, s->avctx->frame_skip_cmp);
@@ -715,22 +844,23 @@ av_cold int MPV_encode_init(AVCodecContext *avctx)
ff_mpeg1_encode_init(s);
/* init q matrix */
- for(i=0;i<64;i++) {
- int j= s->dsp.idct_permutation[i];
- if(CONFIG_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->mpeg_quant){
+ for (i = 0; i < 64; i++) {
+ int j = s->dsp.idct_permutation[i];
+ if (CONFIG_MPEG4_ENCODER && s->codec_id == CODEC_ID_MPEG4 &&
+ s->mpeg_quant) {
s->intra_matrix[j] = ff_mpeg4_default_intra_matrix[i];
s->inter_matrix[j] = ff_mpeg4_default_non_intra_matrix[i];
- }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
+ } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) {
s->intra_matrix[j] =
s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
- }else
- { /* mpeg1/2 */
+ } else {
+ /* mpeg1/2 */
s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i];
s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
}
- if(s->avctx->intra_matrix)
+ if (s->avctx->intra_matrix)
s->intra_matrix[j] = s->avctx->intra_matrix[i];
- if(s->avctx->inter_matrix)
+ if (s->avctx->inter_matrix)
s->inter_matrix[j] = s->avctx->inter_matrix[i];
}
@@ -738,12 +868,14 @@ av_cold int MPV_encode_init(AVCodecContext *avctx)
/* for mjpeg, we do include qscale in the matrix */
if (s->out_format != FMT_MJPEG) {
ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16,
- s->intra_matrix, s->intra_quant_bias, avctx->qmin, 31, 1);
+ s->intra_matrix, s->intra_quant_bias, avctx->qmin,
+ 31, 1);
ff_convert_matrix(&s->dsp, s->q_inter_matrix, s->q_inter_matrix16,
- s->inter_matrix, s->inter_quant_bias, avctx->qmin, 31, 0);
+ s->inter_matrix, s->inter_quant_bias, avctx->qmin,
+ 31, 0);
}
- if(ff_rate_control_init(s) < 0)
+ if (ff_rate_control_init(s) < 0)
return -1;
return 0;
@@ -756,7 +888,8 @@ av_cold int MPV_encode_end(AVCodecContext *avctx)
ff_rate_control_uninit(s);
MPV_common_end(s);
- if ((CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) && s->out_format == FMT_MJPEG)
+ if ((CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) &&
+ s->out_format == FMT_MJPEG)
ff_mjpeg_encode_close(s);
av_freep(&avctx->extradata);
@@ -764,129 +897,148 @@ av_cold int MPV_encode_end(AVCodecContext *avctx)
return 0;
}
-static int get_sae(uint8_t *src, int ref, int stride){
+static int get_sae(uint8_t *src, int ref, int stride)
+{
int x,y;
- int acc=0;
+ int acc = 0;
- for(y=0; y<16; y++){
- for(x=0; x<16; x++){
- acc+= FFABS(src[x+y*stride] - ref);
+ for (y = 0; y < 16; y++) {
+ for (x = 0; x < 16; x++) {
+ acc += FFABS(src[x + y * stride] - ref);
}
}
return acc;
}
-static int get_intra_count(MpegEncContext *s, uint8_t *src, uint8_t *ref, int stride){
+static int get_intra_count(MpegEncContext *s, uint8_t *src,
+ uint8_t *ref, int stride)
+{
int x, y, w, h;
- int acc=0;
+ int acc = 0;
- w= s->width &~15;
- h= s->height&~15;
+ w = s->width & ~15;
+ h = s->height & ~15;
- for(y=0; y<h; y+=16){
- for(x=0; x<w; x+=16){
- int offset= x + y*stride;
- int sad = s->dsp.sad[0](NULL, src + offset, ref + offset, stride, 16);
- int mean= (s->dsp.pix_sum(src + offset, stride) + 128)>>8;
- int sae = get_sae(src + offset, mean, stride);
+ for (y = 0; y < h; y += 16) {
+ for (x = 0; x < w; x += 16) {
+ int offset = x + y * stride;
+ int sad = s->dsp.sad[0](NULL, src + offset, ref + offset, stride,
+ 16);
+ int mean = (s->dsp.pix_sum(src + offset, stride) + 128) >> 8;
+ int sae = get_sae(src + offset, mean, stride);
- acc+= sae + 500 < sad;
+ acc += sae + 500 < sad;
}
}
return acc;
}
-static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
- AVFrame *pic=NULL;
+static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg)
+{
+ AVFrame *pic = NULL;
int64_t pts;
int i;
- const int encoding_delay= s->max_b_frames;
- int direct=1;
-
- if(pic_arg){
- pts= pic_arg->pts;
- pic_arg->display_picture_number= s->input_picture_number++;
-
- if(pts != AV_NOPTS_VALUE){
- if(s->user_specified_pts != AV_NOPTS_VALUE){
- int64_t time= pts;
- int64_t last= s->user_specified_pts;
-
- if(time <= last){
- av_log(s->avctx, AV_LOG_ERROR, "Error, Invalid timestamp=%"PRId64", last=%"PRId64"\n", pts, s->user_specified_pts);
+ const int encoding_delay = s->max_b_frames;
+ int direct = 1;
+
+ if (pic_arg) {
+ pts = pic_arg->pts;
+ pic_arg->display_picture_number = s->input_picture_number++;
+
+ if (pts != AV_NOPTS_VALUE) {
+ if (s->user_specified_pts != AV_NOPTS_VALUE) {
+ int64_t time = pts;
+ int64_t last = s->user_specified_pts;
+
+ if (time <= last) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, Invalid timestamp=%"PRId64", "
+ "last=%"PRId64"\n", pts, s->user_specified_pts);
return -1;
}
}
- s->user_specified_pts= pts;
- }else{
- if(s->user_specified_pts != AV_NOPTS_VALUE){
- s->user_specified_pts=
- pts= s->user_specified_pts + 1;
- av_log(s->avctx, AV_LOG_INFO, "Warning: AVFrame.pts=? trying to guess (%"PRId64")\n", pts);
- }else{
- pts= pic_arg->display_picture_number;
+ s->user_specified_pts = pts;
+ } else {
+ if (s->user_specified_pts != AV_NOPTS_VALUE) {
+ s->user_specified_pts =
+ pts = s->user_specified_pts + 1;
+ av_log(s->avctx, AV_LOG_INFO,
+ "Warning: AVFrame.pts=? trying to guess (%"PRId64")\n",
+ pts);
+ } else {
+ pts = pic_arg->display_picture_number;
}
}
}
- if(pic_arg){
- if(encoding_delay && !(s->flags&CODEC_FLAG_INPUT_PRESERVED)) direct=0;
- if(pic_arg->linesize[0] != s->linesize) direct=0;
- if(pic_arg->linesize[1] != s->uvlinesize) direct=0;
- if(pic_arg->linesize[2] != s->uvlinesize) direct=0;
-
-// av_log(AV_LOG_DEBUG, "%d %d %d %d\n",pic_arg->linesize[0], pic_arg->linesize[1], s->linesize, s->uvlinesize);
-
- if(direct){
- i= ff_find_unused_picture(s, 1);
-
- pic= (AVFrame*)&s->picture[i];
- pic->reference= 3;
-
- for(i=0; i<4; i++){
- pic->data[i]= pic_arg->data[i];
- pic->linesize[i]= pic_arg->linesize[i];
+ if (pic_arg) {
+ if (encoding_delay && !(s->flags & CODEC_FLAG_INPUT_PRESERVED))
+ direct = 0;
+ if (pic_arg->linesize[0] != s->linesize)
+ direct = 0;
+ if (pic_arg->linesize[1] != s->uvlinesize)
+ direct = 0;
+ if (pic_arg->linesize[2] != s->uvlinesize)
+ direct = 0;
+
+ //av_log(AV_LOG_DEBUG, "%d %d %d %d\n",pic_arg->linesize[0],
+ // pic_arg->linesize[1], s->linesize, s->uvlinesize);
+
+ if (direct) {
+ i = ff_find_unused_picture(s, 1);
+ if (i < 0)
+ return i;
+
+ pic = (AVFrame *) &s->picture[i];
+ pic->reference = 3;
+
+ for (i = 0; i < 4; i++) {
+ pic->data[i] = pic_arg->data[i];
+ pic->linesize[i] = pic_arg->linesize[i];
}
- if(ff_alloc_picture(s, (Picture*)pic, 1) < 0){
+ if (ff_alloc_picture(s, (Picture *) pic, 1) < 0) {
return -1;
}
- }else{
- i= ff_find_unused_picture(s, 0);
+ } else {
+ i = ff_find_unused_picture(s, 0);
+ if (i < 0)
+ return i;
- pic= (AVFrame*)&s->picture[i];
- pic->reference= 3;
+ pic = (AVFrame *) &s->picture[i];
+ pic->reference = 3;
- if(ff_alloc_picture(s, (Picture*)pic, 0) < 0){
+ if (ff_alloc_picture(s, (Picture *) pic, 0) < 0) {
return -1;
}
- if( pic->data[0] + INPLACE_OFFSET == pic_arg->data[0]
- && pic->data[1] + INPLACE_OFFSET == pic_arg->data[1]
- && pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]){
- // empty
- }else{
+ if (pic->data[0] + INPLACE_OFFSET == pic_arg->data[0] &&
+ pic->data[1] + INPLACE_OFFSET == pic_arg->data[1] &&
+ pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]) {
+ // empty
+ } else {
int h_chroma_shift, v_chroma_shift;
- avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);
-
- for(i=0; i<3; i++){
- int src_stride= pic_arg->linesize[i];
- int dst_stride= i ? s->uvlinesize : s->linesize;
- int h_shift= i ? h_chroma_shift : 0;
- int v_shift= i ? v_chroma_shift : 0;
- int w= s->width >>h_shift;
- int h= s->height>>v_shift;
- uint8_t *src= pic_arg->data[i];
- uint8_t *dst= pic->data[i];
-
- if(!s->avctx->rc_buffer_size)
- dst +=INPLACE_OFFSET;
-
- if(src_stride==dst_stride)
- memcpy(dst, src, src_stride*h);
- else{
- while(h--){
+ avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift,
+ &v_chroma_shift);
+
+ for (i = 0; i < 3; i++) {
+ int src_stride = pic_arg->linesize[i];
+ int dst_stride = i ? s->uvlinesize : s->linesize;
+ int h_shift = i ? h_chroma_shift : 0;
+ int v_shift = i ? v_chroma_shift : 0;
+ int w = s->width >> h_shift;
+ int h = s->height >> v_shift;
+ uint8_t *src = pic_arg->data[i];
+ uint8_t *dst = pic->data[i];
+
+ if (!s->avctx->rc_buffer_size)
+ dst += INPLACE_OFFSET;
+
+ if (src_stride == dst_stride)
+ memcpy(dst, src, src_stride * h);
+ else {
+ while (h--) {
memcpy(dst, src, w);
dst += dst_stride;
src += src_stride;
@@ -896,146 +1048,166 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
}
}
copy_picture_attributes(s, pic, pic_arg);
- pic->pts= pts; //we set this here to avoid modifiying pic_arg
+ pic->pts = pts; // we set this here to avoid modifiying pic_arg
}
/* shift buffer entries */
- for(i=1; i<MAX_PICTURE_COUNT /*s->encoding_delay+1*/; i++)
- s->input_picture[i-1]= s->input_picture[i];
+ for (i = 1; i < MAX_PICTURE_COUNT /*s->encoding_delay + 1*/; i++)
+ s->input_picture[i - 1] = s->input_picture[i];
- s->input_picture[encoding_delay]= (Picture*)pic;
+ s->input_picture[encoding_delay] = (Picture*) pic;
return 0;
}
-static int skip_check(MpegEncContext *s, Picture *p, Picture *ref){
+static int skip_check(MpegEncContext *s, Picture *p, Picture *ref)
+{
int x, y, plane;
- int score=0;
- int64_t score64=0;
-
- for(plane=0; plane<3; plane++){
- const int stride= p->linesize[plane];
- const int bw= plane ? 1 : 2;
- for(y=0; y<s->mb_height*bw; y++){
- for(x=0; x<s->mb_width*bw; x++){
- int off= p->type == FF_BUFFER_TYPE_SHARED ? 0: 16;
- int v= s->dsp.frame_skip_cmp[1](s, p->data[plane] + 8*(x + y*stride)+off, ref->data[plane] + 8*(x + y*stride), stride, 8);
-
- switch(s->avctx->frame_skip_exp){
- case 0: score= FFMAX(score, v); break;
- case 1: score+= FFABS(v);break;
- case 2: score+= v*v;break;
- case 3: score64+= FFABS(v*v*(int64_t)v);break;
- case 4: score64+= v*v*(int64_t)(v*v);break;
+ int score = 0;
+ int64_t score64 = 0;
+
+ for (plane = 0; plane < 3; plane++) {
+ const int stride = p->f.linesize[plane];
+ const int bw = plane ? 1 : 2;
+ for (y = 0; y < s->mb_height * bw; y++) {
+ for (x = 0; x < s->mb_width * bw; x++) {
+ int off = p->f.type == FF_BUFFER_TYPE_SHARED ? 0 : 16;
+ uint8_t *dptr = p->f.data[plane] + 8 * (x + y * stride) + off;
+ uint8_t *rptr = ref->f.data[plane] + 8 * (x + y * stride);
+ int v = s->dsp.frame_skip_cmp[1](s, dptr, rptr, stride, 8);
+
+ switch (s->avctx->frame_skip_exp) {
+ case 0: score = FFMAX(score, v); break;
+ case 1: score += FFABS(v); break;
+ case 2: score += v * v; break;
+ case 3: score64 += FFABS(v * v * (int64_t)v); break;
+ case 4: score64 += v * v * (int64_t)(v * v); break;
}
}
}
}
- if(score) score64= score;
+ if (score)
+ score64 = score;
- if(score64 < s->avctx->frame_skip_threshold)
+ if (score64 < s->avctx->frame_skip_threshold)
return 1;
- if(score64 < ((s->avctx->frame_skip_factor * (int64_t)s->lambda)>>8))
+ if (score64 < ((s->avctx->frame_skip_factor * (int64_t)s->lambda) >> 8))
return 1;
return 0;
}
-static int estimate_best_b_count(MpegEncContext *s){
- AVCodec *codec= avcodec_find_encoder(s->avctx->codec_id);
- AVCodecContext *c= avcodec_alloc_context();
- AVFrame input[FF_MAX_B_FRAMES+2];
- const int scale= s->avctx->brd_scale;
+static int estimate_best_b_count(MpegEncContext *s)
+{
+ AVCodec *codec = avcodec_find_encoder(s->avctx->codec_id);
+ AVCodecContext *c = avcodec_alloc_context3(NULL);
+ AVFrame input[FF_MAX_B_FRAMES + 2];
+ const int scale = s->avctx->brd_scale;
int i, j, out_size, p_lambda, b_lambda, lambda2;
- int outbuf_size= s->width * s->height; //FIXME
- uint8_t *outbuf= av_malloc(outbuf_size);
- int64_t best_rd= INT64_MAX;
- int best_b_count= -1;
-
- assert(scale>=0 && scale <=3);
-
-// emms_c();
- p_lambda= s->last_lambda_for[AV_PICTURE_TYPE_P]; //s->next_picture_ptr->quality;
- b_lambda= s->last_lambda_for[AV_PICTURE_TYPE_B]; //p_lambda *FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset;
- if(!b_lambda) b_lambda= p_lambda; //FIXME we should do this somewhere else
- lambda2= (b_lambda*b_lambda + (1<<FF_LAMBDA_SHIFT)/2 ) >> FF_LAMBDA_SHIFT;
-
- c->width = s->width >> scale;
- c->height= s->height>> scale;
- c->flags= CODEC_FLAG_QSCALE | CODEC_FLAG_PSNR | CODEC_FLAG_INPUT_PRESERVED /*| CODEC_FLAG_EMU_EDGE*/;
- c->flags|= s->avctx->flags & CODEC_FLAG_QPEL;
- c->mb_decision= s->avctx->mb_decision;
- c->me_cmp= s->avctx->me_cmp;
- c->mb_cmp= s->avctx->mb_cmp;
- c->me_sub_cmp= s->avctx->me_sub_cmp;
- c->pix_fmt = PIX_FMT_YUV420P;
- c->time_base= s->avctx->time_base;
- c->max_b_frames= s->max_b_frames;
+ int outbuf_size = s->width * s->height; // FIXME
+ uint8_t *outbuf = av_malloc(outbuf_size);
+ int64_t best_rd = INT64_MAX;
+ int best_b_count = -1;
+
+ assert(scale >= 0 && scale <= 3);
+
+ //emms_c();
+ //s->next_picture_ptr->quality;
+ p_lambda = s->last_lambda_for[AV_PICTURE_TYPE_P];
+ //p_lambda * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset;
+ b_lambda = s->last_lambda_for[AV_PICTURE_TYPE_B];
+ if (!b_lambda) // FIXME we should do this somewhere else
+ b_lambda = p_lambda;
+ lambda2 = (b_lambda * b_lambda + (1 << FF_LAMBDA_SHIFT) / 2) >>
+ FF_LAMBDA_SHIFT;
+
+ c->width = s->width >> scale;
+ c->height = s->height >> scale;
+ c->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_PSNR |
+ CODEC_FLAG_INPUT_PRESERVED /*| CODEC_FLAG_EMU_EDGE*/;
+ c->flags |= s->avctx->flags & CODEC_FLAG_QPEL;
+ c->mb_decision = s->avctx->mb_decision;
+ c->me_cmp = s->avctx->me_cmp;
+ c->mb_cmp = s->avctx->mb_cmp;
+ c->me_sub_cmp = s->avctx->me_sub_cmp;
+ c->pix_fmt = PIX_FMT_YUV420P;
+ c->time_base = s->avctx->time_base;
+ c->max_b_frames = s->max_b_frames;
if (avcodec_open2(c, codec, NULL) < 0)
return -1;
- for(i=0; i<s->max_b_frames+2; i++){
- int ysize= c->width*c->height;
- int csize= (c->width/2)*(c->height/2);
- Picture pre_input, *pre_input_ptr= i ? s->input_picture[i-1] : s->next_picture_ptr;
+ for (i = 0; i < s->max_b_frames + 2; i++) {
+ int ysize = c->width * c->height;
+ int csize = (c->width / 2) * (c->height / 2);
+ Picture pre_input, *pre_input_ptr = i ? s->input_picture[i - 1] :
+ s->next_picture_ptr;
avcodec_get_frame_defaults(&input[i]);
- input[i].data[0]= av_malloc(ysize + 2*csize);
- input[i].data[1]= input[i].data[0] + ysize;
- input[i].data[2]= input[i].data[1] + csize;
- input[i].linesize[0]= c->width;
- input[i].linesize[1]=
- input[i].linesize[2]= c->width/2;
-
- if(pre_input_ptr && (!i || s->input_picture[i-1])) {
- pre_input= *pre_input_ptr;
-
- if(pre_input.type != FF_BUFFER_TYPE_SHARED && i) {
- pre_input.data[0]+=INPLACE_OFFSET;
- pre_input.data[1]+=INPLACE_OFFSET;
- pre_input.data[2]+=INPLACE_OFFSET;
+ input[i].data[0] = av_malloc(ysize + 2 * csize);
+ input[i].data[1] = input[i].data[0] + ysize;
+ input[i].data[2] = input[i].data[1] + csize;
+ input[i].linesize[0] = c->width;
+ input[i].linesize[1] =
+ input[i].linesize[2] = c->width / 2;
+
+ if (pre_input_ptr && (!i || s->input_picture[i - 1])) {
+ pre_input = *pre_input_ptr;
+
+ if (pre_input.f.type != FF_BUFFER_TYPE_SHARED && i) {
+ pre_input.f.data[0] += INPLACE_OFFSET;
+ pre_input.f.data[1] += INPLACE_OFFSET;
+ pre_input.f.data[2] += INPLACE_OFFSET;
}
- s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0], pre_input.data[0], pre_input.linesize[0], c->width, c->height);
- s->dsp.shrink[scale](input[i].data[1], input[i].linesize[1], pre_input.data[1], pre_input.linesize[1], c->width>>1, c->height>>1);
- s->dsp.shrink[scale](input[i].data[2], input[i].linesize[2], pre_input.data[2], pre_input.linesize[2], c->width>>1, c->height>>1);
+ s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0],
+ pre_input.f.data[0], pre_input.f.linesize[0],
+ c->width, c->height);
+ s->dsp.shrink[scale](input[i].data[1], input[i].linesize[1],
+ pre_input.f.data[1], pre_input.f.linesize[1],
+ c->width >> 1, c->height >> 1);
+ s->dsp.shrink[scale](input[i].data[2], input[i].linesize[2],
+ pre_input.f.data[2], pre_input.f.linesize[2],
+ c->width >> 1, c->height >> 1);
}
}
- for(j=0; j<s->max_b_frames+1; j++){
- int64_t rd=0;
+ for (j = 0; j < s->max_b_frames + 1; j++) {
+ int64_t rd = 0;
- if(!s->input_picture[j])
+ if (!s->input_picture[j])
break;
- c->error[0]= c->error[1]= c->error[2]= 0;
+ c->error[0] = c->error[1] = c->error[2] = 0;
- input[0].pict_type= AV_PICTURE_TYPE_I;
- input[0].quality= 1 * FF_QP2LAMBDA;
- out_size = avcodec_encode_video(c, outbuf, outbuf_size, &input[0]);
-// rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT;
+ input[0].pict_type = AV_PICTURE_TYPE_I;
+ input[0].quality = 1 * FF_QP2LAMBDA;
+ out_size = avcodec_encode_video(c, outbuf,
+ outbuf_size, &input[0]);
+ //rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT;
- for(i=0; i<s->max_b_frames+1; i++){
- int is_p= i % (j+1) == j || i==s->max_b_frames;
+ for (i = 0; i < s->max_b_frames + 1; i++) {
+ int is_p = i % (j + 1) == j || i == s->max_b_frames;
- input[i+1].pict_type= is_p ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B;
- input[i+1].quality= is_p ? p_lambda : b_lambda;
- out_size = avcodec_encode_video(c, outbuf, outbuf_size, &input[i+1]);
+ input[i + 1].pict_type = is_p ?
+ AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B;
+ input[i + 1].quality = is_p ? p_lambda : b_lambda;
+ out_size = avcodec_encode_video(c, outbuf, outbuf_size,
+ &input[i + 1]);
rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3);
}
/* get the delayed frames */
- while(out_size){
+ while (out_size) {
out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3);
}
rd += c->error[0] + c->error[1] + c->error[2];
- if(rd < best_rd){
- best_rd= rd;
- best_b_count= j;
+ if (rd < best_rd) {
+ best_rd = rd;
+ best_b_count = j;
}
}
@@ -1043,43 +1215,50 @@ static int estimate_best_b_count(MpegEncContext *s){
avcodec_close(c);
av_freep(&c);
- for(i=0; i<s->max_b_frames+2; i++){
+ for (i = 0; i < s->max_b_frames + 2; i++) {
av_freep(&input[i].data[0]);
}
return best_b_count;
}
-static int select_input_picture(MpegEncContext *s){
+static int select_input_picture(MpegEncContext *s)
+{
int i;
- for(i=1; i<MAX_PICTURE_COUNT; i++)
- s->reordered_input_picture[i-1]= s->reordered_input_picture[i];
- s->reordered_input_picture[MAX_PICTURE_COUNT-1]= NULL;
+ for (i = 1; i < MAX_PICTURE_COUNT; i++)
+ s->reordered_input_picture[i - 1] = s->reordered_input_picture[i];
+ s->reordered_input_picture[MAX_PICTURE_COUNT - 1] = NULL;
/* set next picture type & ordering */
- if(s->reordered_input_picture[0]==NULL && s->input_picture[0]){
- if(/*s->picture_in_gop_number >= s->gop_size ||*/ s->next_picture_ptr==NULL || s->intra_only){
- s->reordered_input_picture[0]= s->input_picture[0];
- s->reordered_input_picture[0]->pict_type= AV_PICTURE_TYPE_I;
- s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++;
- }else{
+ if (s->reordered_input_picture[0] == NULL && s->input_picture[0]) {
+ if (/*s->picture_in_gop_number >= s->gop_size ||*/
+ s->next_picture_ptr == NULL || s->intra_only) {
+ s->reordered_input_picture[0] = s->input_picture[0];
+ s->reordered_input_picture[0]->f.pict_type = AV_PICTURE_TYPE_I;
+ s->reordered_input_picture[0]->f.coded_picture_number =
+ s->coded_picture_number++;
+ } else {
int b_frames;
- if(s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor){
- if(s->picture_in_gop_number < s->gop_size && skip_check(s, s->input_picture[0], s->next_picture_ptr)){
- //FIXME check that te gop check above is +-1 correct
-//av_log(NULL, AV_LOG_DEBUG, "skip %p %"PRId64"\n", s->input_picture[0]->data[0], s->input_picture[0]->pts);
-
- if(s->input_picture[0]->type == FF_BUFFER_TYPE_SHARED){
- for(i=0; i<4; i++)
- s->input_picture[0]->data[i]= NULL;
- s->input_picture[0]->type= 0;
- }else{
- assert( s->input_picture[0]->type==FF_BUFFER_TYPE_USER
- || s->input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL);
-
- s->avctx->release_buffer(s->avctx, (AVFrame*)s->input_picture[0]);
+ if (s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor) {
+ if (s->picture_in_gop_number < s->gop_size &&
+ skip_check(s, s->input_picture[0], s->next_picture_ptr)) {
+ // FIXME check that te gop check above is +-1 correct
+ //av_log(NULL, AV_LOG_DEBUG, "skip %p %"PRId64"\n",
+ // s->input_picture[0]->f.data[0],
+ // s->input_picture[0]->pts);
+
+ if (s->input_picture[0]->f.type == FF_BUFFER_TYPE_SHARED) {
+ for (i = 0; i < 4; i++)
+ s->input_picture[0]->f.data[i] = NULL;
+ s->input_picture[0]->f.type = 0;
+ } else {
+ assert(s->input_picture[0]->f.type == FF_BUFFER_TYPE_USER ||
+ s->input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL);
+
+ s->avctx->release_buffer(s->avctx,
+ (AVFrame *) s->input_picture[0]);
}
emms_c();
@@ -1089,134 +1268,157 @@ static int select_input_picture(MpegEncContext *s){
}
}
- if(s->flags&CODEC_FLAG_PASS2){
- for(i=0; i<s->max_b_frames+1; i++){
- int pict_num= s->input_picture[0]->display_picture_number + i;
+ if (s->flags & CODEC_FLAG_PASS2) {
+ for (i = 0; i < s->max_b_frames + 1; i++) {
+ int pict_num = s->input_picture[0]->f.display_picture_number + i;
- if(pict_num >= s->rc_context.num_entries)
+ if (pict_num >= s->rc_context.num_entries)
break;
- if(!s->input_picture[i]){
- s->rc_context.entry[pict_num-1].new_pict_type = AV_PICTURE_TYPE_P;
+ if (!s->input_picture[i]) {
+ s->rc_context.entry[pict_num - 1].new_pict_type = AV_PICTURE_TYPE_P;
break;
}
- s->input_picture[i]->pict_type=
+ s->input_picture[i]->f.pict_type =
s->rc_context.entry[pict_num].new_pict_type;
}
}
- if(s->avctx->b_frame_strategy==0){
- b_frames= s->max_b_frames;
- while(b_frames && !s->input_picture[b_frames]) b_frames--;
- }else if(s->avctx->b_frame_strategy==1){
- for(i=1; i<s->max_b_frames+1; i++){
- if(s->input_picture[i] && s->input_picture[i]->b_frame_score==0){
- s->input_picture[i]->b_frame_score=
- get_intra_count(s, s->input_picture[i ]->data[0],
- s->input_picture[i-1]->data[0], s->linesize) + 1;
+ if (s->avctx->b_frame_strategy == 0) {
+ b_frames = s->max_b_frames;
+ while (b_frames && !s->input_picture[b_frames])
+ b_frames--;
+ } else if (s->avctx->b_frame_strategy == 1) {
+ for (i = 1; i < s->max_b_frames + 1; i++) {
+ if (s->input_picture[i] &&
+ s->input_picture[i]->b_frame_score == 0) {
+ s->input_picture[i]->b_frame_score =
+ get_intra_count(s,
+ s->input_picture[i ]->f.data[0],
+ s->input_picture[i - 1]->f.data[0],
+ s->linesize) + 1;
}
}
- for(i=0; i<s->max_b_frames+1; i++){
- if(s->input_picture[i]==NULL || s->input_picture[i]->b_frame_score - 1 > s->mb_num/s->avctx->b_sensitivity) break;
+ for (i = 0; i < s->max_b_frames + 1; i++) {
+ if (s->input_picture[i] == NULL ||
+ s->input_picture[i]->b_frame_score - 1 >
+ s->mb_num / s->avctx->b_sensitivity)
+ break;
}
- b_frames= FFMAX(0, i-1);
+ b_frames = FFMAX(0, i - 1);
/* reset scores */
- for(i=0; i<b_frames+1; i++){
- s->input_picture[i]->b_frame_score=0;
+ for (i = 0; i < b_frames + 1; i++) {
+ s->input_picture[i]->b_frame_score = 0;
}
- }else if(s->avctx->b_frame_strategy==2){
- b_frames= estimate_best_b_count(s);
- }else{
+ } else if (s->avctx->b_frame_strategy == 2) {
+ b_frames = estimate_best_b_count(s);
+ } else {
av_log(s->avctx, AV_LOG_ERROR, "illegal b frame strategy\n");
- b_frames=0;
+ b_frames = 0;
}
emms_c();
-//static int b_count=0;
-//b_count+= b_frames;
-//av_log(s->avctx, AV_LOG_DEBUG, "b_frames: %d\n", b_count);
-
- for(i= b_frames - 1; i>=0; i--){
- int type= s->input_picture[i]->pict_type;
- if(type && type != AV_PICTURE_TYPE_B)
- b_frames= i;
+ //static int b_count = 0;
+ //b_count += b_frames;
+ //av_log(s->avctx, AV_LOG_DEBUG, "b_frames: %d\n", b_count);
+
+ for (i = b_frames - 1; i >= 0; i--) {
+ int type = s->input_picture[i]->f.pict_type;
+ if (type && type != AV_PICTURE_TYPE_B)
+ b_frames = i;
}
- if(s->input_picture[b_frames]->pict_type == AV_PICTURE_TYPE_B && b_frames == s->max_b_frames){
- av_log(s->avctx, AV_LOG_ERROR, "warning, too many b frames in a row\n");
+ if (s->input_picture[b_frames]->f.pict_type == AV_PICTURE_TYPE_B &&
+ b_frames == s->max_b_frames) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "warning, too many b frames in a row\n");
}
- if(s->picture_in_gop_number + b_frames >= s->gop_size){
- if((s->flags2 & CODEC_FLAG2_STRICT_GOP) && s->gop_size > s->picture_in_gop_number){
- b_frames= s->gop_size - s->picture_in_gop_number - 1;
- }else{
- if(s->flags & CODEC_FLAG_CLOSED_GOP)
- b_frames=0;
- s->input_picture[b_frames]->pict_type= AV_PICTURE_TYPE_I;
- }
+ if (s->picture_in_gop_number + b_frames >= s->gop_size) {
+ if ((s->flags2 & CODEC_FLAG2_STRICT_GOP) &&
+ s->gop_size > s->picture_in_gop_number) {
+ b_frames = s->gop_size - s->picture_in_gop_number - 1;
+ } else {
+ if (s->flags & CODEC_FLAG_CLOSED_GOP)
+ b_frames = 0;
+ s->input_picture[b_frames]->f.pict_type = AV_PICTURE_TYPE_I;
+ }
}
- if( (s->flags & CODEC_FLAG_CLOSED_GOP)
- && b_frames
- && s->input_picture[b_frames]->pict_type== AV_PICTURE_TYPE_I)
+ if ((s->flags & CODEC_FLAG_CLOSED_GOP) && b_frames &&
+ s->input_picture[b_frames]->f.pict_type == AV_PICTURE_TYPE_I)
b_frames--;
- s->reordered_input_picture[0]= s->input_picture[b_frames];
- if(s->reordered_input_picture[0]->pict_type != AV_PICTURE_TYPE_I)
- s->reordered_input_picture[0]->pict_type= AV_PICTURE_TYPE_P;
- s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++;
- for(i=0; i<b_frames; i++){
- s->reordered_input_picture[i+1]= s->input_picture[i];
- s->reordered_input_picture[i+1]->pict_type= AV_PICTURE_TYPE_B;
- s->reordered_input_picture[i+1]->coded_picture_number= s->coded_picture_number++;
+ s->reordered_input_picture[0] = s->input_picture[b_frames];
+ if (s->reordered_input_picture[0]->f.pict_type != AV_PICTURE_TYPE_I)
+ s->reordered_input_picture[0]->f.pict_type = AV_PICTURE_TYPE_P;
+ s->reordered_input_picture[0]->f.coded_picture_number =
+ s->coded_picture_number++;
+ for (i = 0; i < b_frames; i++) {
+ s->reordered_input_picture[i + 1] = s->input_picture[i];
+ s->reordered_input_picture[i + 1]->f.pict_type =
+ AV_PICTURE_TYPE_B;
+ s->reordered_input_picture[i + 1]->f.coded_picture_number =
+ s->coded_picture_number++;
}
}
}
no_output_pic:
- if(s->reordered_input_picture[0]){
- s->reordered_input_picture[0]->reference= s->reordered_input_picture[0]->pict_type!=AV_PICTURE_TYPE_B ? 3 : 0;
+ if (s->reordered_input_picture[0]) {
+ s->reordered_input_picture[0]->f.reference =
+ s->reordered_input_picture[0]->f.pict_type !=
+ AV_PICTURE_TYPE_B ? 3 : 0;
ff_copy_picture(&s->new_picture, s->reordered_input_picture[0]);
- if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_SHARED || s->avctx->rc_buffer_size){
- // input is a shared pix, so we can't modifiy it -> alloc a new one & ensure that the shared one is reuseable
+ if (s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_SHARED ||
+ s->avctx->rc_buffer_size) {
+ // input is a shared pix, so we can't modifiy it -> alloc a new
+ // one & ensure that the shared one is reuseable
- int i= ff_find_unused_picture(s, 0);
- Picture *pic= &s->picture[i];
+ Picture *pic;
+ int i = ff_find_unused_picture(s, 0);
+ if (i < 0)
+ return i;
+ pic = &s->picture[i];
- pic->reference = s->reordered_input_picture[0]->reference;
- if(ff_alloc_picture(s, pic, 0) < 0){
+ pic->f.reference = s->reordered_input_picture[0]->f.reference;
+ if (ff_alloc_picture(s, pic, 0) < 0) {
return -1;
}
/* mark us unused / free shared pic */
- if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_INTERNAL)
- s->avctx->release_buffer(s->avctx, (AVFrame*)s->reordered_input_picture[0]);
- for(i=0; i<4; i++)
- s->reordered_input_picture[0]->data[i]= NULL;
- s->reordered_input_picture[0]->type= 0;
+ if (s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL)
+ s->avctx->release_buffer(s->avctx,
+ (AVFrame *) s->reordered_input_picture[0]);
+ for (i = 0; i < 4; i++)
+ s->reordered_input_picture[0]->f.data[i] = NULL;
+ s->reordered_input_picture[0]->f.type = 0;
- copy_picture_attributes(s, (AVFrame*)pic, (AVFrame*)s->reordered_input_picture[0]);
+ copy_picture_attributes(s, (AVFrame *) pic,
+ (AVFrame *) s->reordered_input_picture[0]);
- s->current_picture_ptr= pic;
- }else{
+ s->current_picture_ptr = pic;
+ } else {
// input is not a shared pix -> reuse buffer for current_pix
- assert( s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_USER
- || s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL);
+ assert(s->reordered_input_picture[0]->f.type ==
+ FF_BUFFER_TYPE_USER ||
+ s->reordered_input_picture[0]->f.type ==
+ FF_BUFFER_TYPE_INTERNAL);
- s->current_picture_ptr= s->reordered_input_picture[0];
- for(i=0; i<4; i++){
- s->new_picture.data[i]+= INPLACE_OFFSET;
+ s->current_picture_ptr = s->reordered_input_picture[0];
+ for (i = 0; i < 4; i++) {
+ s->new_picture.f.data[i] += INPLACE_OFFSET;
}
}
ff_copy_picture(&s->current_picture, s->current_picture_ptr);
- s->picture_number= s->new_picture.display_picture_number;
-//printf("dpn:%d\n", s->picture_number);
- }else{
- memset(&s->new_picture, 0, sizeof(Picture));
+ s->picture_number = s->new_picture.f.display_picture_number;
+ //printf("dpn:%d\n", s->picture_number);
+ } else {
+ memset(&s->new_picture, 0, sizeof(Picture));
}
return 0;
}
@@ -1225,33 +1427,34 @@ int MPV_encode_picture(AVCodecContext *avctx,
unsigned char *buf, int buf_size, void *data)
{
MpegEncContext *s = avctx->priv_data;
- AVFrame *pic_arg = data;
+ AVFrame *pic_arg = data;
int i, stuffing_count, context_count = avctx->thread_count;
- for(i=0; i<context_count; i++){
- int start_y= s->thread_context[i]->start_mb_y;
- int end_y= s->thread_context[i]-> end_mb_y;
- int h= s->mb_height;
- uint8_t *start= buf + (size_t)(((int64_t) buf_size)*start_y/h);
- uint8_t *end = buf + (size_t)(((int64_t) buf_size)* end_y/h);
+ for (i = 0; i < context_count; i++) {
+ int start_y = s->thread_context[i]->start_mb_y;
+ int end_y = s->thread_context[i]-> end_mb_y;
+ int h = s->mb_height;
+ uint8_t *start = buf + (size_t)(((int64_t) buf_size) * start_y / h);
+ uint8_t *end = buf + (size_t)(((int64_t) buf_size) * end_y / h);
init_put_bits(&s->thread_context[i]->pb, start, end - start);
}
s->picture_in_gop_number++;
- if(load_input_picture(s, pic_arg) < 0)
+ if (load_input_picture(s, pic_arg) < 0)
return -1;
- if(select_input_picture(s) < 0){
+ if (select_input_picture(s) < 0) {
return -1;
}
/* output? */
- if(s->new_picture.data[0]){
- s->pict_type= s->new_picture.pict_type;
-//emms_c();
-//printf("qs:%f %f %d\n", s->new_picture.quality, s->current_picture.quality, s->qscale);
+ if (s->new_picture.f.data[0]) {
+ s->pict_type = s->new_picture.f.pict_type;
+ //emms_c();
+ //printf("qs:%f %f %d\n", s->new_picture.quality,
+ // s->current_picture.quality, s->qscale);
MPV_frame_start(s, avctx);
vbv_retry:
if (encode_picture(s, s->picture_number) < 0)
@@ -1263,7 +1466,8 @@ vbv_retry:
avctx->i_tex_bits = s->i_tex_bits;
avctx->p_tex_bits = s->p_tex_bits;
avctx->i_count = s->i_count;
- avctx->p_count = s->mb_num - s->i_count - s->skip_count; //FIXME f/b_count in avctx
+ // FIXME f/b_count in avctx
+ avctx->p_count = s->mb_num - s->i_count - s->skip_count;
avctx->skip_count = s->skip_count;
MPV_frame_end(s);
@@ -1271,29 +1475,37 @@ vbv_retry:
if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG)
ff_mjpeg_encode_picture_trailer(s);
- if(avctx->rc_buffer_size){
- RateControlContext *rcc= &s->rc_context;
- int max_size= rcc->buffer_index * avctx->rc_max_available_vbv_use;
+ if (avctx->rc_buffer_size) {
+ RateControlContext *rcc = &s->rc_context;
+ int max_size = rcc->buffer_index * avctx->rc_max_available_vbv_use;
- if(put_bits_count(&s->pb) > max_size && s->lambda < s->avctx->lmax){
- s->next_lambda= FFMAX(s->lambda+1, s->lambda*(s->qscale+1) / s->qscale);
- if(s->adaptive_quant){
+ if (put_bits_count(&s->pb) > max_size &&
+ s->lambda < s->avctx->lmax) {
+ s->next_lambda = FFMAX(s->lambda + 1, s->lambda *
+ (s->qscale + 1) / s->qscale);
+ if (s->adaptive_quant) {
int i;
- for(i=0; i<s->mb_height*s->mb_stride; i++)
- s->lambda_table[i]= FFMAX(s->lambda_table[i]+1, s->lambda_table[i]*(s->qscale+1) / s->qscale);
+ for (i = 0; i < s->mb_height * s->mb_stride; i++)
+ s->lambda_table[i] =
+ FFMAX(s->lambda_table[i] + 1,
+ s->lambda_table[i] * (s->qscale + 1) /
+ s->qscale);
}
- s->mb_skipped = 0; //done in MPV_frame_start()
- if(s->pict_type==AV_PICTURE_TYPE_P){ //done in encode_picture() so we must undo it
- if(s->flipflop_rounding || s->codec_id == CODEC_ID_H263P || s->codec_id == CODEC_ID_MPEG4)
+ s->mb_skipped = 0; // done in MPV_frame_start()
+ // done in encode_picture() so we must undo it
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ if (s->flipflop_rounding ||
+ s->codec_id == CODEC_ID_H263P ||
+ s->codec_id == CODEC_ID_MPEG4)
s->no_rounding ^= 1;
}
- if(s->pict_type!=AV_PICTURE_TYPE_B){
- s->time_base= s->last_time_base;
- s->last_non_b_time= s->time - s->pp_time;
+ if (s->pict_type != AV_PICTURE_TYPE_B) {
+ s->time_base = s->last_time_base;
+ s->last_non_b_time = s->time - s->pp_time;
}
-// av_log(NULL, AV_LOG_ERROR, "R:%d ", s->next_lambda);
- for(i=0; i<context_count; i++){
- PutBitContext *pb= &s->thread_context[i]->pb;
+ //av_log(NULL, AV_LOG_ERROR, "R:%d ", s->next_lambda);
+ for (i = 0; i < context_count; i++) {
+ PutBitContext *pb = &s->thread_context[i]->pb;
init_put_bits(pb, pb->buf, pb->buf_end - pb->buf);
}
goto vbv_retry;
@@ -1302,30 +1514,33 @@ vbv_retry:
assert(s->avctx->rc_max_rate);
}
- if(s->flags&CODEC_FLAG_PASS1)
+ if (s->flags & CODEC_FLAG_PASS1)
ff_write_pass1_stats(s);
- for(i=0; i<4; i++){
- s->current_picture_ptr->error[i]= s->current_picture.error[i];
- avctx->error[i] += s->current_picture_ptr->error[i];
+ for (i = 0; i < 4; i++) {
+ s->current_picture_ptr->f.error[i] = s->current_picture.f.error[i];
+ avctx->error[i] += s->current_picture_ptr->f.error[i];
}
- if(s->flags&CODEC_FLAG_PASS1)
- assert(avctx->header_bits + avctx->mv_bits + avctx->misc_bits + avctx->i_tex_bits + avctx->p_tex_bits == put_bits_count(&s->pb));
+ if (s->flags & CODEC_FLAG_PASS1)
+ assert(avctx->header_bits + avctx->mv_bits + avctx->misc_bits +
+ avctx->i_tex_bits + avctx->p_tex_bits ==
+ put_bits_count(&s->pb));
flush_put_bits(&s->pb);
s->frame_bits = put_bits_count(&s->pb);
- stuffing_count= ff_vbv_update(s, s->frame_bits);
- if(stuffing_count){
- if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < stuffing_count + 50){
+ stuffing_count = ff_vbv_update(s, s->frame_bits);
+ if (stuffing_count) {
+ if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) <
+ stuffing_count + 50) {
av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n");
return -1;
}
- switch(s->codec_id){
+ switch (s->codec_id) {
case CODEC_ID_MPEG1VIDEO:
case CODEC_ID_MPEG2VIDEO:
- while(stuffing_count--){
+ while (stuffing_count--) {
put_bits(&s->pb, 8, 0);
}
break;
@@ -1333,7 +1548,7 @@ vbv_retry:
put_bits(&s->pb, 16, 0);
put_bits(&s->pb, 16, 0x1C3);
stuffing_count -= 4;
- while(stuffing_count--){
+ while (stuffing_count--) {
put_bits(&s->pb, 8, 0xFF);
}
break;
@@ -1345,245 +1560,281 @@ vbv_retry:
}
/* update mpeg1/2 vbv_delay for CBR */
- if(s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate && s->out_format == FMT_MPEG1
- && 90000LL * (avctx->rc_buffer_size-1) <= s->avctx->rc_max_rate*0xFFFFLL){
+ if (s->avctx->rc_max_rate &&
+ s->avctx->rc_min_rate == s->avctx->rc_max_rate &&
+ s->out_format == FMT_MPEG1 &&
+ 90000LL * (avctx->rc_buffer_size - 1) <=
+ s->avctx->rc_max_rate * 0xFFFFLL) {
int vbv_delay, min_delay;
- double inbits = s->avctx->rc_max_rate*av_q2d(s->avctx->time_base);
- int minbits= s->frame_bits - 8*(s->vbv_delay_ptr - s->pb.buf - 1);
- double bits = s->rc_context.buffer_index + minbits - inbits;
+ double inbits = s->avctx->rc_max_rate *
+ av_q2d(s->avctx->time_base);
+ int minbits = s->frame_bits - 8 *
+ (s->vbv_delay_ptr - s->pb.buf - 1);
+ double bits = s->rc_context.buffer_index + minbits - inbits;
- if(bits<0)
- av_log(s->avctx, AV_LOG_ERROR, "Internal error, negative bits\n");
+ if (bits < 0)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Internal error, negative bits\n");
- assert(s->repeat_first_field==0);
+ assert(s->repeat_first_field == 0);
- vbv_delay= bits * 90000 / s->avctx->rc_max_rate;
- min_delay= (minbits * 90000LL + s->avctx->rc_max_rate - 1)/ s->avctx->rc_max_rate;
+ vbv_delay = bits * 90000 / s->avctx->rc_max_rate;
+ min_delay = (minbits * 90000LL + s->avctx->rc_max_rate - 1) /
+ s->avctx->rc_max_rate;
- vbv_delay= FFMAX(vbv_delay, min_delay);
+ vbv_delay = FFMAX(vbv_delay, min_delay);
assert(vbv_delay < 0xFFFF);
s->vbv_delay_ptr[0] &= 0xF8;
- s->vbv_delay_ptr[0] |= vbv_delay>>13;
- s->vbv_delay_ptr[1] = vbv_delay>>5;
+ s->vbv_delay_ptr[0] |= vbv_delay >> 13;
+ s->vbv_delay_ptr[1] = vbv_delay >> 5;
s->vbv_delay_ptr[2] &= 0x07;
- s->vbv_delay_ptr[2] |= vbv_delay<<3;
- avctx->vbv_delay = vbv_delay*300;
+ s->vbv_delay_ptr[2] |= vbv_delay << 3;
+ avctx->vbv_delay = vbv_delay * 300;
}
- s->total_bits += s->frame_bits;
+ s->total_bits += s->frame_bits;
avctx->frame_bits = s->frame_bits;
- }else{
+ } else {
assert((put_bits_ptr(&s->pb) == s->pb.buf));
- s->frame_bits=0;
+ s->frame_bits = 0;
}
- assert((s->frame_bits&7)==0);
+ assert((s->frame_bits & 7) == 0);
- return s->frame_bits/8;
+ return s->frame_bits / 8;
}
-static inline void dct_single_coeff_elimination(MpegEncContext *s, int n, int threshold)
+static inline void dct_single_coeff_elimination(MpegEncContext *s,
+ int n, int threshold)
{
- static const char tab[64]=
- {3,2,2,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,
- 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,0,0,
- 0,0,0,0,0,0,0,0};
- int score=0;
- int run=0;
+ static const char tab[64] = {
+ 3, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ int score = 0;
+ int run = 0;
int i;
- DCTELEM *block= s->block[n];
- const int last_index= s->block_last_index[n];
+ DCTELEM *block = s->block[n];
+ const int last_index = s->block_last_index[n];
int skip_dc;
- if(threshold<0){
- skip_dc=0;
- threshold= -threshold;
- }else
- skip_dc=1;
+ if (threshold < 0) {
+ skip_dc = 0;
+ threshold = -threshold;
+ } else
+ skip_dc = 1;
/* Are all we could set to zero already zero? */
- if(last_index<=skip_dc - 1) return;
+ if (last_index <= skip_dc - 1)
+ return;
- for(i=0; i<=last_index; i++){
+ for (i = 0; i <= last_index; i++) {
const int j = s->intra_scantable.permutated[i];
const int level = FFABS(block[j]);
- if(level==1){
- if(skip_dc && i==0) continue;
- score+= tab[run];
- run=0;
- }else if(level>1){
+ if (level == 1) {
+ if (skip_dc && i == 0)
+ continue;
+ score += tab[run];
+ run = 0;
+ } else if (level > 1) {
return;
- }else{
+ } else {
run++;
}
}
- if(score >= threshold) return;
- for(i=skip_dc; i<=last_index; i++){
+ if (score >= threshold)
+ return;
+ for (i = skip_dc; i <= last_index; i++) {
const int j = s->intra_scantable.permutated[i];
- block[j]=0;
+ block[j] = 0;
}
- if(block[0]) s->block_last_index[n]= 0;
- else s->block_last_index[n]= -1;
+ if (block[0])
+ s->block_last_index[n] = 0;
+ else
+ s->block_last_index[n] = -1;
}
-static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block, int last_index)
+static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block,
+ int last_index)
{
int i;
- const int maxlevel= s->max_qcoeff;
- const int minlevel= s->min_qcoeff;
- int overflow=0;
+ const int maxlevel = s->max_qcoeff;
+ const int minlevel = s->min_qcoeff;
+ int overflow = 0;
- if(s->mb_intra){
- i=1; //skip clipping of intra dc
- }else
- i=0;
+ if (s->mb_intra) {
+ i = 1; // skip clipping of intra dc
+ } else
+ i = 0;
- for(;i<=last_index; i++){
- const int j= s->intra_scantable.permutated[i];
+ for (; i <= last_index; i++) {
+ const int j = s->intra_scantable.permutated[i];
int level = block[j];
- if (level>maxlevel){
- level=maxlevel;
+ if (level > maxlevel) {
+ level = maxlevel;
overflow++;
- }else if(level<minlevel){
- level=minlevel;
+ } else if (level < minlevel) {
+ level = minlevel;
overflow++;
}
- block[j]= level;
+ block[j] = level;
}
- if(overflow && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE)
- av_log(s->avctx, AV_LOG_INFO, "warning, clipping %d dct coefficients to %d..%d\n", overflow, minlevel, maxlevel);
+ if (overflow && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE)
+ av_log(s->avctx, AV_LOG_INFO,
+ "warning, clipping %d dct coefficients to %d..%d\n",
+ overflow, minlevel, maxlevel);
}
-static void get_visual_weight(int16_t *weight, uint8_t *ptr, int stride){
+static void get_visual_weight(int16_t *weight, uint8_t *ptr, int stride)
+{
int x, y;
-//FIXME optimize
- for(y=0; y<8; y++){
- for(x=0; x<8; x++){
+ // FIXME optimize
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++) {
int x2, y2;
- int sum=0;
- int sqr=0;
- int count=0;
+ int sum = 0;
+ int sqr = 0;
+ int count = 0;
- for(y2= FFMAX(y-1, 0); y2 < FFMIN(8, y+2); y2++){
- for(x2= FFMAX(x-1, 0); x2 < FFMIN(8, x+2); x2++){
- int v= ptr[x2 + y2*stride];
+ for (y2 = FFMAX(y - 1, 0); y2 < FFMIN(8, y + 2); y2++) {
+ for (x2= FFMAX(x - 1, 0); x2 < FFMIN(8, x + 2); x2++) {
+ int v = ptr[x2 + y2 * stride];
sum += v;
- sqr += v*v;
+ sqr += v * v;
count++;
}
}
- weight[x + 8*y]= (36*ff_sqrt(count*sqr - sum*sum)) / count;
+ weight[x + 8 * y]= (36 * ff_sqrt(count * sqr - sum * sum)) / count;
}
}
}
-static av_always_inline void encode_mb_internal(MpegEncContext *s, int motion_x, int motion_y, int mb_block_height, int mb_block_count)
+static av_always_inline void encode_mb_internal(MpegEncContext *s,
+ int motion_x, int motion_y,
+ int mb_block_height,
+ int mb_block_count)
{
int16_t weight[8][64];
DCTELEM orig[8][64];
- const int mb_x= s->mb_x;
- const int mb_y= s->mb_y;
+ const int mb_x = s->mb_x;
+ const int mb_y = s->mb_y;
int i;
int skip_dct[8];
- int dct_offset = s->linesize*8; //default for progressive frames
+ int dct_offset = s->linesize * 8; // default for progressive frames
uint8_t *ptr_y, *ptr_cb, *ptr_cr;
int wrap_y, wrap_c;
- for(i=0; i<mb_block_count; i++) skip_dct[i]=s->skipdct;
+ for (i = 0; i < mb_block_count; i++)
+ skip_dct[i] = s->skipdct;
- if(s->adaptive_quant){
- const int last_qp= s->qscale;
- const int mb_xy= mb_x + mb_y*s->mb_stride;
+ if (s->adaptive_quant) {
+ const int last_qp = s->qscale;
+ const int mb_xy = mb_x + mb_y * s->mb_stride;
- s->lambda= s->lambda_table[mb_xy];
+ s->lambda = s->lambda_table[mb_xy];
update_qscale(s);
- if(!(s->flags&CODEC_FLAG_QP_RD)){
- s->qscale= s->current_picture_ptr->qscale_table[mb_xy];
- s->dquant= s->qscale - last_qp;
+ if (!(s->flags & CODEC_FLAG_QP_RD)) {
+ s->qscale = s->current_picture_ptr->f.qscale_table[mb_xy];
+ s->dquant = s->qscale - last_qp;
- if(s->out_format==FMT_H263){
- s->dquant= av_clip(s->dquant, -2, 2);
+ if (s->out_format == FMT_H263) {
+ s->dquant = av_clip(s->dquant, -2, 2);
- if(s->codec_id==CODEC_ID_MPEG4){
- if(!s->mb_intra){
- if(s->pict_type == AV_PICTURE_TYPE_B){
- if(s->dquant&1 || s->mv_dir&MV_DIRECT)
- s->dquant= 0;
+ if (s->codec_id == CODEC_ID_MPEG4) {
+ if (!s->mb_intra) {
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
+ if (s->dquant & 1 || s->mv_dir & MV_DIRECT)
+ s->dquant = 0;
}
- if(s->mv_type==MV_TYPE_8X8)
- s->dquant=0;
+ if (s->mv_type == MV_TYPE_8X8)
+ s->dquant = 0;
}
}
}
}
ff_set_qscale(s, last_qp + s->dquant);
- }else if(s->flags&CODEC_FLAG_QP_RD)
+ } else if (s->flags & CODEC_FLAG_QP_RD)
ff_set_qscale(s, s->qscale + s->dquant);
wrap_y = s->linesize;
wrap_c = s->uvlinesize;
- ptr_y = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
- ptr_cb = s->new_picture.data[1] + (mb_y * mb_block_height * wrap_c) + mb_x * 8;
- ptr_cr = s->new_picture.data[2] + (mb_y * mb_block_height * wrap_c) + mb_x * 8;
-
- if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
- uint8_t *ebuf= s->edge_emu_buffer + 32;
- s->dsp.emulated_edge_mc(ebuf , ptr_y , wrap_y,16,16,mb_x*16,mb_y*16, s->width , s->height);
- ptr_y= ebuf;
- s->dsp.emulated_edge_mc(ebuf+18*wrap_y , ptr_cb, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
- ptr_cb= ebuf+18*wrap_y;
- s->dsp.emulated_edge_mc(ebuf+18*wrap_y+8, ptr_cr, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
- ptr_cr= ebuf+18*wrap_y+8;
+ ptr_y = s->new_picture.f.data[0] +
+ (mb_y * 16 * wrap_y) + mb_x * 16;
+ ptr_cb = s->new_picture.f.data[1] +
+ (mb_y * mb_block_height * wrap_c) + mb_x * 8;
+ ptr_cr = s->new_picture.f.data[2] +
+ (mb_y * mb_block_height * wrap_c) + mb_x * 8;
+
+ if (mb_x * 16 + 16 > s->width || mb_y * 16 + 16 > s->height) {
+ uint8_t *ebuf = s->edge_emu_buffer + 32;
+ s->dsp.emulated_edge_mc(ebuf, ptr_y, wrap_y, 16, 16, mb_x * 16,
+ mb_y * 16, s->width, s->height);
+ ptr_y = ebuf;
+ s->dsp.emulated_edge_mc(ebuf + 18 * wrap_y, ptr_cb, wrap_c, 8,
+ mb_block_height, mb_x * 8, mb_y * 8,
+ s->width >> 1, s->height >> 1);
+ ptr_cb = ebuf + 18 * wrap_y;
+ s->dsp.emulated_edge_mc(ebuf + 18 * wrap_y + 8, ptr_cr, wrap_c, 8,
+ mb_block_height, mb_x * 8, mb_y * 8,
+ s->width >> 1, s->height >> 1);
+ ptr_cr = ebuf + 18 * wrap_y + 8;
}
if (s->mb_intra) {
- if(s->flags&CODEC_FLAG_INTERLACED_DCT){
+ if (s->flags & CODEC_FLAG_INTERLACED_DCT) {
int progressive_score, interlaced_score;
- s->interlaced_dct=0;
- progressive_score= s->dsp.ildct_cmp[4](s, ptr_y , NULL, wrap_y, 8)
- +s->dsp.ildct_cmp[4](s, ptr_y + wrap_y*8, NULL, wrap_y, 8) - 400;
-
- if(progressive_score > 0){
- interlaced_score = s->dsp.ildct_cmp[4](s, ptr_y , NULL, wrap_y*2, 8)
- +s->dsp.ildct_cmp[4](s, ptr_y + wrap_y , NULL, wrap_y*2, 8);
- if(progressive_score > interlaced_score){
- s->interlaced_dct=1;
-
- dct_offset= wrap_y;
- wrap_y<<=1;
+ s->interlaced_dct = 0;
+ progressive_score = s->dsp.ildct_cmp[4](s, ptr_y,
+ NULL, wrap_y, 8) +
+ s->dsp.ildct_cmp[4](s, ptr_y + wrap_y * 8,
+ NULL, wrap_y, 8) - 400;
+
+ if (progressive_score > 0) {
+ interlaced_score = s->dsp.ildct_cmp[4](s, ptr_y,
+ NULL, wrap_y * 2, 8) +
+ s->dsp.ildct_cmp[4](s, ptr_y + wrap_y,
+ NULL, wrap_y * 2, 8);
+ if (progressive_score > interlaced_score) {
+ s->interlaced_dct = 1;
+
+ dct_offset = wrap_y;
+ wrap_y <<= 1;
if (s->chroma_format == CHROMA_422)
- wrap_c<<=1;
+ wrap_c <<= 1;
}
}
}
- s->dsp.get_pixels(s->block[0], ptr_y , wrap_y);
- s->dsp.get_pixels(s->block[1], ptr_y + 8, wrap_y);
- s->dsp.get_pixels(s->block[2], ptr_y + dct_offset , wrap_y);
- s->dsp.get_pixels(s->block[3], ptr_y + dct_offset + 8, wrap_y);
+ s->dsp.get_pixels(s->block[0], ptr_y , wrap_y);
+ s->dsp.get_pixels(s->block[1], ptr_y + 8 , wrap_y);
+ s->dsp.get_pixels(s->block[2], ptr_y + dct_offset , wrap_y);
+ s->dsp.get_pixels(s->block[3], ptr_y + dct_offset + 8 , wrap_y);
- if(s->flags&CODEC_FLAG_GRAY){
- skip_dct[4]= 1;
- skip_dct[5]= 1;
- }else{
+ if (s->flags & CODEC_FLAG_GRAY) {
+ skip_dct[4] = 1;
+ skip_dct[5] = 1;
+ } else {
s->dsp.get_pixels(s->block[4], ptr_cb, wrap_c);
s->dsp.get_pixels(s->block[5], ptr_cr, wrap_c);
- if(!s->chroma_y_shift){ /* 422 */
- s->dsp.get_pixels(s->block[6], ptr_cb + (dct_offset>>1), wrap_c);
- s->dsp.get_pixels(s->block[7], ptr_cr + (dct_offset>>1), wrap_c);
+ if (!s->chroma_y_shift) { /* 422 */
+ s->dsp.get_pixels(s->block[6],
+ ptr_cb + (dct_offset >> 1), wrap_c);
+ s->dsp.get_pixels(s->block[7],
+ ptr_cr + (dct_offset >> 1), wrap_c);
}
}
- }else{
+ } else {
op_pixels_func (*op_pix)[4];
qpel_mc_func (*op_qpix)[16];
uint8_t *dest_y, *dest_cb, *dest_cr;
@@ -1592,146 +1843,197 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s, int motion_x,
dest_cb = s->dest[1];
dest_cr = s->dest[2];
- if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
- op_pix = s->dsp.put_pixels_tab;
- op_qpix= s->dsp.put_qpel_pixels_tab;
- }else{
- op_pix = s->dsp.put_no_rnd_pixels_tab;
- op_qpix= s->dsp.put_no_rnd_qpel_pixels_tab;
+ if ((!s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) {
+ op_pix = s->dsp.put_pixels_tab;
+ op_qpix = s->dsp.put_qpel_pixels_tab;
+ } else {
+ op_pix = s->dsp.put_no_rnd_pixels_tab;
+ op_qpix = s->dsp.put_no_rnd_qpel_pixels_tab;
}
if (s->mv_dir & MV_DIR_FORWARD) {
- MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix);
- op_pix = s->dsp.avg_pixels_tab;
- op_qpix= s->dsp.avg_qpel_pixels_tab;
+ MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f.data,
+ op_pix, op_qpix);
+ op_pix = s->dsp.avg_pixels_tab;
+ op_qpix = s->dsp.avg_qpel_pixels_tab;
}
if (s->mv_dir & MV_DIR_BACKWARD) {
- MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix);
+ MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data,
+ op_pix, op_qpix);
}
- if(s->flags&CODEC_FLAG_INTERLACED_DCT){
+ if (s->flags & CODEC_FLAG_INTERLACED_DCT) {
int progressive_score, interlaced_score;
- s->interlaced_dct=0;
- progressive_score= s->dsp.ildct_cmp[0](s, dest_y , ptr_y , wrap_y, 8)
- +s->dsp.ildct_cmp[0](s, dest_y + wrap_y*8, ptr_y + wrap_y*8, wrap_y, 8) - 400;
-
- if(s->avctx->ildct_cmp == FF_CMP_VSSE) progressive_score -= 400;
-
- if(progressive_score>0){
- interlaced_score = s->dsp.ildct_cmp[0](s, dest_y , ptr_y , wrap_y*2, 8)
- +s->dsp.ildct_cmp[0](s, dest_y + wrap_y , ptr_y + wrap_y , wrap_y*2, 8);
-
- if(progressive_score > interlaced_score){
- s->interlaced_dct=1;
-
- dct_offset= wrap_y;
- wrap_y<<=1;
+ s->interlaced_dct = 0;
+ progressive_score = s->dsp.ildct_cmp[0](s, dest_y,
+ ptr_y, wrap_y,
+ 8) +
+ s->dsp.ildct_cmp[0](s, dest_y + wrap_y * 8,
+ ptr_y + wrap_y * 8, wrap_y,
+ 8) - 400;
+
+ if (s->avctx->ildct_cmp == FF_CMP_VSSE)
+ progressive_score -= 400;
+
+ if (progressive_score > 0) {
+ interlaced_score = s->dsp.ildct_cmp[0](s, dest_y,
+ ptr_y,
+ wrap_y * 2, 8) +
+ s->dsp.ildct_cmp[0](s, dest_y + wrap_y,
+ ptr_y + wrap_y,
+ wrap_y * 2, 8);
+
+ if (progressive_score > interlaced_score) {
+ s->interlaced_dct = 1;
+
+ dct_offset = wrap_y;
+ wrap_y <<= 1;
if (s->chroma_format == CHROMA_422)
- wrap_c<<=1;
+ wrap_c <<= 1;
}
}
}
- s->dsp.diff_pixels(s->block[0], ptr_y , dest_y , wrap_y);
- s->dsp.diff_pixels(s->block[1], ptr_y + 8, dest_y + 8, wrap_y);
- s->dsp.diff_pixels(s->block[2], ptr_y + dct_offset , dest_y + dct_offset , wrap_y);
- s->dsp.diff_pixels(s->block[3], ptr_y + dct_offset + 8, dest_y + dct_offset + 8, wrap_y);
+ s->dsp.diff_pixels(s->block[0], ptr_y, dest_y, wrap_y);
+ s->dsp.diff_pixels(s->block[1], ptr_y + 8, dest_y + 8, wrap_y);
+ s->dsp.diff_pixels(s->block[2], ptr_y + dct_offset,
+ dest_y + dct_offset, wrap_y);
+ s->dsp.diff_pixels(s->block[3], ptr_y + dct_offset + 8,
+ dest_y + dct_offset + 8, wrap_y);
- if(s->flags&CODEC_FLAG_GRAY){
- skip_dct[4]= 1;
- skip_dct[5]= 1;
- }else{
+ if (s->flags & CODEC_FLAG_GRAY) {
+ skip_dct[4] = 1;
+ skip_dct[5] = 1;
+ } else {
s->dsp.diff_pixels(s->block[4], ptr_cb, dest_cb, wrap_c);
s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c);
- if(!s->chroma_y_shift){ /* 422 */
- s->dsp.diff_pixels(s->block[6], ptr_cb + (dct_offset>>1), dest_cb + (dct_offset>>1), wrap_c);
- s->dsp.diff_pixels(s->block[7], ptr_cr + (dct_offset>>1), dest_cr + (dct_offset>>1), wrap_c);
+ if (!s->chroma_y_shift) { /* 422 */
+ s->dsp.diff_pixels(s->block[6], ptr_cb + (dct_offset >> 1),
+ dest_cb + (dct_offset >> 1), wrap_c);
+ s->dsp.diff_pixels(s->block[7], ptr_cr + (dct_offset >> 1),
+ dest_cr + (dct_offset >> 1), wrap_c);
}
}
/* pre quantization */
- if(s->current_picture.mc_mb_var[s->mb_stride*mb_y+ mb_x]<2*s->qscale*s->qscale){
- //FIXME optimize
- if(s->dsp.sad[1](NULL, ptr_y , dest_y , wrap_y, 8) < 20*s->qscale) skip_dct[0]= 1;
- if(s->dsp.sad[1](NULL, ptr_y + 8, dest_y + 8, wrap_y, 8) < 20*s->qscale) skip_dct[1]= 1;
- if(s->dsp.sad[1](NULL, ptr_y +dct_offset , dest_y +dct_offset , wrap_y, 8) < 20*s->qscale) skip_dct[2]= 1;
- if(s->dsp.sad[1](NULL, ptr_y +dct_offset+ 8, dest_y +dct_offset+ 8, wrap_y, 8) < 20*s->qscale) skip_dct[3]= 1;
- if(s->dsp.sad[1](NULL, ptr_cb , dest_cb , wrap_c, 8) < 20*s->qscale) skip_dct[4]= 1;
- if(s->dsp.sad[1](NULL, ptr_cr , dest_cr , wrap_c, 8) < 20*s->qscale) skip_dct[5]= 1;
- if(!s->chroma_y_shift){ /* 422 */
- if(s->dsp.sad[1](NULL, ptr_cb +(dct_offset>>1), dest_cb +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[6]= 1;
- if(s->dsp.sad[1](NULL, ptr_cr +(dct_offset>>1), dest_cr +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[7]= 1;
+ if (s->current_picture.mc_mb_var[s->mb_stride * mb_y + mb_x] <
+ 2 * s->qscale * s->qscale) {
+ // FIXME optimize
+ if (s->dsp.sad[1](NULL, ptr_y , dest_y,
+ wrap_y, 8) < 20 * s->qscale)
+ skip_dct[0] = 1;
+ if (s->dsp.sad[1](NULL, ptr_y + 8,
+ dest_y + 8, wrap_y, 8) < 20 * s->qscale)
+ skip_dct[1] = 1;
+ if (s->dsp.sad[1](NULL, ptr_y + dct_offset,
+ dest_y + dct_offset, wrap_y, 8) < 20 * s->qscale)
+ skip_dct[2] = 1;
+ if (s->dsp.sad[1](NULL, ptr_y + dct_offset + 8,
+ dest_y + dct_offset + 8,
+ wrap_y, 8) < 20 * s->qscale)
+ skip_dct[3] = 1;
+ if (s->dsp.sad[1](NULL, ptr_cb, dest_cb,
+ wrap_c, 8) < 20 * s->qscale)
+ skip_dct[4] = 1;
+ if (s->dsp.sad[1](NULL, ptr_cr, dest_cr,
+ wrap_c, 8) < 20 * s->qscale)
+ skip_dct[5] = 1;
+ if (!s->chroma_y_shift) { /* 422 */
+ if (s->dsp.sad[1](NULL, ptr_cb + (dct_offset >> 1),
+ dest_cb + (dct_offset >> 1),
+ wrap_c, 8) < 20 * s->qscale)
+ skip_dct[6] = 1;
+ if (s->dsp.sad[1](NULL, ptr_cr + (dct_offset >> 1),
+ dest_cr + (dct_offset >> 1),
+ wrap_c, 8) < 20 * s->qscale)
+ skip_dct[7] = 1;
}
}
}
- if(s->avctx->quantizer_noise_shaping){
- if(!skip_dct[0]) get_visual_weight(weight[0], ptr_y , wrap_y);
- if(!skip_dct[1]) get_visual_weight(weight[1], ptr_y + 8, wrap_y);
- if(!skip_dct[2]) get_visual_weight(weight[2], ptr_y + dct_offset , wrap_y);
- if(!skip_dct[3]) get_visual_weight(weight[3], ptr_y + dct_offset + 8, wrap_y);
- if(!skip_dct[4]) get_visual_weight(weight[4], ptr_cb , wrap_c);
- if(!skip_dct[5]) get_visual_weight(weight[5], ptr_cr , wrap_c);
- if(!s->chroma_y_shift){ /* 422 */
- if(!skip_dct[6]) get_visual_weight(weight[6], ptr_cb + (dct_offset>>1), wrap_c);
- if(!skip_dct[7]) get_visual_weight(weight[7], ptr_cr + (dct_offset>>1), wrap_c);
+ if (s->avctx->quantizer_noise_shaping) {
+ if (!skip_dct[0])
+ get_visual_weight(weight[0], ptr_y , wrap_y);
+ if (!skip_dct[1])
+ get_visual_weight(weight[1], ptr_y + 8, wrap_y);
+ if (!skip_dct[2])
+ get_visual_weight(weight[2], ptr_y + dct_offset , wrap_y);
+ if (!skip_dct[3])
+ get_visual_weight(weight[3], ptr_y + dct_offset + 8, wrap_y);
+ if (!skip_dct[4])
+ get_visual_weight(weight[4], ptr_cb , wrap_c);
+ if (!skip_dct[5])
+ get_visual_weight(weight[5], ptr_cr , wrap_c);
+ if (!s->chroma_y_shift) { /* 422 */
+ if (!skip_dct[6])
+ get_visual_weight(weight[6], ptr_cb + (dct_offset >> 1),
+ wrap_c);
+ if (!skip_dct[7])
+ get_visual_weight(weight[7], ptr_cr + (dct_offset >> 1),
+ wrap_c);
}
- memcpy(orig[0], s->block[0], sizeof(DCTELEM)*64*mb_block_count);
+ memcpy(orig[0], s->block[0], sizeof(DCTELEM) * 64 * mb_block_count);
}
/* DCT & quantize */
- assert(s->out_format!=FMT_MJPEG || s->qscale==8);
+ assert(s->out_format != FMT_MJPEG || s->qscale == 8);
{
- for(i=0;i<mb_block_count;i++) {
- if(!skip_dct[i]){
+ for (i = 0; i < mb_block_count; i++) {
+ if (!skip_dct[i]) {
int overflow;
s->block_last_index[i] = s->dct_quantize(s, s->block[i], i, s->qscale, &overflow);
- // FIXME we could decide to change to quantizer instead of clipping
- // JS: I don't think that would be a good idea it could lower quality instead
- // of improve it. Just INTRADC clipping deserves changes in quantizer
- if (overflow) clip_coeffs(s, s->block[i], s->block_last_index[i]);
- }else
- s->block_last_index[i]= -1;
- }
- if(s->avctx->quantizer_noise_shaping){
- for(i=0;i<mb_block_count;i++) {
- if(!skip_dct[i]){
- s->block_last_index[i] = dct_quantize_refine(s, s->block[i], weight[i], orig[i], i, s->qscale);
+ // FIXME we could decide to change to quantizer instead of
+ // clipping
+ // JS: I don't think that would be a good idea it could lower
+ // quality instead of improve it. Just INTRADC clipping
+ // deserves changes in quantizer
+ if (overflow)
+ clip_coeffs(s, s->block[i], s->block_last_index[i]);
+ } else
+ s->block_last_index[i] = -1;
+ }
+ if (s->avctx->quantizer_noise_shaping) {
+ for (i = 0; i < mb_block_count; i++) {
+ if (!skip_dct[i]) {
+ s->block_last_index[i] =
+ dct_quantize_refine(s, s->block[i], weight[i],
+ orig[i], i, s->qscale);
}
}
}
- if(s->luma_elim_threshold && !s->mb_intra)
- for(i=0; i<4; i++)
+ if (s->luma_elim_threshold && !s->mb_intra)
+ for (i = 0; i < 4; i++)
dct_single_coeff_elimination(s, i, s->luma_elim_threshold);
- if(s->chroma_elim_threshold && !s->mb_intra)
- for(i=4; i<mb_block_count; i++)
+ if (s->chroma_elim_threshold && !s->mb_intra)
+ for (i = 4; i < mb_block_count; i++)
dct_single_coeff_elimination(s, i, s->chroma_elim_threshold);
- if(s->flags & CODEC_FLAG_CBP_RD){
- for(i=0;i<mb_block_count;i++) {
- if(s->block_last_index[i] == -1)
- s->coded_score[i]= INT_MAX/256;
+ if (s->flags & CODEC_FLAG_CBP_RD) {
+ for (i = 0; i < mb_block_count; i++) {
+ if (s->block_last_index[i] == -1)
+ s->coded_score[i] = INT_MAX / 256;
}
}
}
- if((s->flags&CODEC_FLAG_GRAY) && s->mb_intra){
- s->block_last_index[4]=
- s->block_last_index[5]= 0;
- s->block[4][0]=
- s->block[5][0]= (1024 + s->c_dc_scale/2)/ s->c_dc_scale;
+ if ((s->flags & CODEC_FLAG_GRAY) && s->mb_intra) {
+ s->block_last_index[4] =
+ s->block_last_index[5] = 0;
+ s->block[4][0] =
+ s->block[5][0] = (1024 + s->c_dc_scale / 2) / s->c_dc_scale;
}
- //non c quantize code returns incorrect block_last_index FIXME
- if(s->alternate_scan && s->dct_quantize != dct_quantize_c){
- for(i=0; i<mb_block_count; i++){
+ // non c quantize code returns incorrect block_last_index FIXME
+ if (s->alternate_scan && s->dct_quantize != dct_quantize_c) {
+ for (i = 0; i < mb_block_count; i++) {
int j;
- if(s->block_last_index[i]>0){
- for(j=63; j>0; j--){
- if(s->block[i][ s->intra_scantable.permutated[j] ]) break;
+ if (s->block_last_index[i] > 0) {
+ for (j = 63; j > 0; j--) {
+ if (s->block[i][s->intra_scantable.permutated[j]])
+ break;
}
- s->block_last_index[i]= j;
+ s->block_last_index[i] = j;
}
}
}
@@ -1787,12 +2089,12 @@ static av_always_inline void encode_mb(MpegEncContext *s, int motion_x, int moti
static inline void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int type){
int i;
- memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop?
+ memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster than a loop?
/* mpeg1 */
d->mb_skip_run= s->mb_skip_run;
for(i=0; i<3; i++)
- d->last_dc[i]= s->last_dc[i];
+ d->last_dc[i] = s->last_dc[i];
/* statistics */
d->mv_bits= s->mv_bits;
@@ -1816,12 +2118,12 @@ static inline void copy_context_after_encode(MpegEncContext *d, MpegEncContext *
int i;
memcpy(d->mv, s->mv, 2*4*2*sizeof(int));
- memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop?
+ memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster than a loop?
/* mpeg1 */
d->mb_skip_run= s->mb_skip_run;
for(i=0; i<3; i++)
- d->last_dc[i]= s->last_dc[i];
+ d->last_dc[i] = s->last_dc[i];
/* statistics */
d->mv_bits= s->mv_bits;
@@ -1932,18 +2234,18 @@ static int sse_mb(MpegEncContext *s){
if(w==16 && h==16)
if(s->avctx->mb_cmp == FF_CMP_NSSE){
- return s->dsp.nsse[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16)
- +s->dsp.nsse[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8)
- +s->dsp.nsse[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8);
+ return s->dsp.nsse[0](s, s->new_picture.f.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16)
+ +s->dsp.nsse[1](s, s->new_picture.f.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8)
+ +s->dsp.nsse[1](s, s->new_picture.f.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8);
}else{
- return s->dsp.sse[0](NULL, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16)
- +s->dsp.sse[1](NULL, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8)
- +s->dsp.sse[1](NULL, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8);
+ return s->dsp.sse[0](NULL, s->new_picture.f.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16)
+ +s->dsp.sse[1](NULL, s->new_picture.f.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8)
+ +s->dsp.sse[1](NULL, s->new_picture.f.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8);
}
else
- return sse(s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], w, h, s->linesize)
- +sse(s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], w>>1, h>>1, s->uvlinesize)
- +sse(s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], w>>1, h>>1, s->uvlinesize);
+ return sse(s, s->new_picture.f.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], w, h, s->linesize)
+ +sse(s, s->new_picture.f.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], w>>1, h>>1, s->uvlinesize)
+ +sse(s, s->new_picture.f.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], w>>1, h>>1, s->uvlinesize);
}
static int pre_estimate_motion_thread(AVCodecContext *c, void *arg){
@@ -2002,11 +2304,11 @@ static int mb_var_thread(AVCodecContext *c, void *arg){
for(mb_x=0; mb_x < s->mb_width; mb_x++) {
int xx = mb_x * 16;
int yy = mb_y * 16;
- uint8_t *pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
+ uint8_t *pix = s->new_picture.f.data[0] + (yy * s->linesize) + xx;
int varc;
int sum = s->dsp.pix_sum(pix, s->linesize);
- varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;
+ varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)sum*sum)>>8) + 500 + 128)>>8;
s->current_picture.mb_var [s->mb_stride * mb_y + mb_x] = varc;
s->current_picture.mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
@@ -2027,7 +2329,7 @@ static void write_slice_end(MpegEncContext *s){
ff_mjpeg_encode_stuffing(&s->pb);
}
- align_put_bits(&s->pb);
+ avpriv_align_put_bits(&s->pb);
flush_put_bits(&s->pb);
if((s->flags&CODEC_FLAG_PASS1) && !s->partitioned_frame)
@@ -2069,7 +2371,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
/* note: quant matrix value (8) is implied here */
s->last_dc[i] = 128 << s->intra_dc_precision;
- s->current_picture.error[i] = 0;
+ s->current_picture.f.error[i] = 0;
}
s->mb_skip_run = 0;
memset(s->last_mv, 0, sizeof(s->last_mv));
@@ -2170,9 +2472,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
int d= 100 / s->avctx->error_rate;
if(r % d == 0){
current_packet_size=0;
-#ifndef ALT_BITSTREAM_WRITER
s->pb.buf_ptr= s->ptr_lastgob;
-#endif
assert(put_bits_ptr(&s->pb) == s->ptr_lastgob);
}
}
@@ -2272,8 +2572,8 @@ static int encode_thread(AVCodecContext *c, void *arg){
s->mv_type = MV_TYPE_8X8;
s->mb_intra= 0;
for(i=0; i<4; i++){
- s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
- s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
+ s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0];
+ s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1];
}
encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER4V, pb, pb2, tex_pb,
&dmin, &next_block, 0, 0);
@@ -2459,24 +2759,24 @@ static int encode_thread(AVCodecContext *c, void *arg){
}
}
- s->current_picture.qscale_table[xy]= best_s.qscale;
+ s->current_picture.f.qscale_table[xy] = best_s.qscale;
copy_context_after_encode(s, &best_s, -1);
pb_bits_count= put_bits_count(&s->pb);
flush_put_bits(&s->pb);
- ff_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count);
+ avpriv_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count);
s->pb= backup_s.pb;
if(s->data_partitioning){
pb2_bits_count= put_bits_count(&s->pb2);
flush_put_bits(&s->pb2);
- ff_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count);
+ avpriv_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count);
s->pb2= backup_s.pb2;
tex_pb_bits_count= put_bits_count(&s->tex_pb);
flush_put_bits(&s->tex_pb);
- ff_copy_bits(&backup_s.tex_pb, bit_buf_tex[next_block^1], tex_pb_bits_count);
+ avpriv_copy_bits(&backup_s.tex_pb, bit_buf_tex[next_block^1], tex_pb_bits_count);
s->tex_pb= backup_s.tex_pb;
}
s->last_bits= put_bits_count(&s->pb);
@@ -2526,8 +2826,8 @@ static int encode_thread(AVCodecContext *c, void *arg){
s->mv_type = MV_TYPE_8X8;
s->mb_intra= 0;
for(i=0; i<4; i++){
- s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
- s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
+ s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0];
+ s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1];
}
break;
case CANDIDATE_MB_TYPE_DIRECT:
@@ -2628,14 +2928,14 @@ static int encode_thread(AVCodecContext *c, void *arg){
if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16;
if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16;
- s->current_picture.error[0] += sse(
- s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16,
+ s->current_picture.f.error[0] += sse(
+ s, s->new_picture.f.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16,
s->dest[0], w, h, s->linesize);
- s->current_picture.error[1] += sse(
- s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*chr_h,
+ s->current_picture.f.error[1] += sse(
+ s, s->new_picture.f.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*chr_h,
s->dest[1], w>>1, h>>s->chroma_y_shift, s->uvlinesize);
- s->current_picture.error[2] += sse(
- s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*chr_h,
+ s->current_picture.f.error[2] += sse(
+ s, s->new_picture.f.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*chr_h,
s->dest[2], w>>1, h>>s->chroma_y_shift, s->uvlinesize);
}
if(s->loop_filter){
@@ -2686,9 +2986,9 @@ static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src)
MERGE(misc_bits);
MERGE(error_count);
MERGE(padding_bug_score);
- MERGE(current_picture.error[0]);
- MERGE(current_picture.error[1]);
- MERGE(current_picture.error[2]);
+ MERGE(current_picture.f.error[0]);
+ MERGE(current_picture.f.error[1]);
+ MERGE(current_picture.f.error[2]);
if(dst->avctx->noise_reduction){
for(i=0; i<64; i++){
@@ -2699,19 +2999,19 @@ static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src)
assert(put_bits_count(&src->pb) % 8 ==0);
assert(put_bits_count(&dst->pb) % 8 ==0);
- ff_copy_bits(&dst->pb, src->pb.buf, put_bits_count(&src->pb));
+ avpriv_copy_bits(&dst->pb, src->pb.buf, put_bits_count(&src->pb));
flush_put_bits(&dst->pb);
}
static int estimate_qp(MpegEncContext *s, int dry_run){
if (s->next_lambda){
- s->current_picture_ptr->quality=
- s->current_picture.quality = s->next_lambda;
+ s->current_picture_ptr->f.quality =
+ s->current_picture.f.quality = s->next_lambda;
if(!dry_run) s->next_lambda= 0;
} else if (!s->fixed_qscale) {
- s->current_picture_ptr->quality=
- s->current_picture.quality = ff_rate_estimate_qscale(s, dry_run);
- if (s->current_picture.quality < 0)
+ s->current_picture_ptr->f.quality =
+ s->current_picture.f.quality = ff_rate_estimate_qscale(s, dry_run);
+ if (s->current_picture.f.quality < 0)
return -1;
}
@@ -2734,7 +3034,7 @@ static int estimate_qp(MpegEncContext *s, int dry_run){
s->lambda= s->lambda_table[0];
//FIXME broken
}else
- s->lambda= s->current_picture.quality;
+ s->lambda = s->current_picture.f.quality;
//printf("%d %d\n", s->avctx->global_quality, s->current_picture.quality);
update_qscale(s);
return 0;
@@ -2742,8 +3042,8 @@ static int estimate_qp(MpegEncContext *s, int dry_run){
/* must be called before writing the header */
static void set_frame_distances(MpegEncContext * s){
- assert(s->current_picture_ptr->pts != AV_NOPTS_VALUE);
- s->time= s->current_picture_ptr->pts*s->avctx->time_base.num;
+ assert(s->current_picture_ptr->f.pts != AV_NOPTS_VALUE);
+ s->time = s->current_picture_ptr->f.pts * s->avctx->time_base.num;
if(s->pict_type==AV_PICTURE_TYPE_B){
s->pb_time= s->pp_time - (s->last_non_b_time - s->time);
@@ -2917,12 +3217,12 @@ static int encode_picture(MpegEncContext *s, int picture_number)
}
//FIXME var duplication
- s->current_picture_ptr->key_frame=
- s->current_picture.key_frame= s->pict_type == AV_PICTURE_TYPE_I; //FIXME pic_ptr
- s->current_picture_ptr->pict_type=
- s->current_picture.pict_type= s->pict_type;
+ s->current_picture_ptr->f.key_frame =
+ s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I; //FIXME pic_ptr
+ s->current_picture_ptr->f.pict_type =
+ s->current_picture.f.pict_type = s->pict_type;
- if(s->current_picture.key_frame)
+ if (s->current_picture.f.key_frame)
s->picture_in_gop_number=0;
s->last_bits= put_bits_count(&s->pb);
@@ -3769,63 +4069,94 @@ int dct_quantize_c(MpegEncContext *s,
return last_non_zero;
}
+#define OFFSET(x) offsetof(MpegEncContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption h263_options[] = {
+ { "obmc", "use overlapped block motion compensation.", OFFSET(obmc), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { "structured_slices","Write slice start position at every GOB header instead of just GOB number.", OFFSET(h263_slice_structured), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE},
+ { NULL },
+};
+
+static const AVClass h263_class = {
+ .class_name = "H.263 encoder",
+ .item_name = av_default_item_name,
+ .option = h263_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_h263_encoder = {
- "h263",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_H263,
- sizeof(MpegEncContext),
- MPV_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "h263",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_H263,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = MPV_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("H.263 / H.263-1996"),
+ .priv_class = &h263_class,
+};
+
+static const AVOption h263p_options[] = {
+ { "umv", "Use unlimited motion vectors.", OFFSET(umvplus), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { "aiv", "Use alternative inter VLC.", OFFSET(alt_inter_vlc), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { "obmc", "use overlapped block motion compensation.", OFFSET(obmc), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { "structured_slices", "Write slice start position at every GOB header instead of just GOB number.", OFFSET(h263_slice_structured), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE},
+ { NULL },
+};
+static const AVClass h263p_class = {
+ .class_name = "H.263p encoder",
+ .item_name = av_default_item_name,
+ .option = h263p_options,
+ .version = LIBAVUTIL_VERSION_INT,
};
AVCodec ff_h263p_encoder = {
- "h263p",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_H263P,
- sizeof(MpegEncContext),
- MPV_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "h263p",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_H263P,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = MPV_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.capabilities = CODEC_CAP_SLICE_THREADS,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"),
+ .priv_class = &h263p_class,
};
AVCodec ff_msmpeg4v2_encoder = {
- "msmpeg4v2",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MSMPEG4V2,
- sizeof(MpegEncContext),
- MPV_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "msmpeg4v2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MSMPEG4V2,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = MPV_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
};
AVCodec ff_msmpeg4v3_encoder = {
- "msmpeg4",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MSMPEG4V3,
- sizeof(MpegEncContext),
- MPV_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "msmpeg4",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MSMPEG4V3,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = MPV_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
};
AVCodec ff_wmv1_encoder = {
- "wmv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_WMV1,
- sizeof(MpegEncContext),
- MPV_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "wmv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_WMV1,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = MPV_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
};
diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c
index 9688e18..1798f83 100644
--- a/libavcodec/mpegvideo_parser.c
+++ b/libavcodec/mpegvideo_parser.c
@@ -40,7 +40,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
while (buf < buf_end) {
start_code= -1;
- buf= ff_find_start_code(buf, buf_end, &start_code);
+ buf= avpriv_mpv_find_start_code(buf, buf_end, &start_code);
bytes_left = buf_end - buf;
switch(start_code) {
case PICTURE_START_CODE:
@@ -57,8 +57,8 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
did_set_size=1;
}
frame_rate_index = buf[3] & 0xf;
- pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num;
- pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den;
+ pc->frame_rate.den = avctx->time_base.den = avpriv_frame_rate_tab[frame_rate_index].num;
+ pc->frame_rate.num = avctx->time_base.num = avpriv_frame_rate_tab[frame_rate_index].den;
avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400;
avctx->codec_id = CODEC_ID_MPEG1VIDEO;
avctx->sub_id = 1;
@@ -174,10 +174,9 @@ static int mpegvideo_split(AVCodecContext *avctx,
}
AVCodecParser ff_mpegvideo_parser = {
- { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
- sizeof(ParseContext1),
- NULL,
- mpegvideo_parse,
- ff_parse1_close,
- mpegvideo_split,
+ .codec_ids = { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
+ .priv_data_size = sizeof(ParseContext1),
+ .parser_parse = mpegvideo_parse,
+ .parser_close = ff_parse1_close,
+ .split = mpegvideo_split,
};
diff --git a/libavcodec/mpegvideo_xvmc.c b/libavcodec/mpegvideo_xvmc.c
index 29d8bbb..159fe21 100644
--- a/libavcodec/mpegvideo_xvmc.c
+++ b/libavcodec/mpegvideo_xvmc.c
@@ -41,7 +41,7 @@
*/
void ff_xvmc_init_block(MpegEncContext *s)
{
- struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.data[2];
+ struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2];
assert(render && render->xvmc_id == AV_XVMC_ID);
s->block = (DCTELEM (*)[64])(render->data_blocks + render->next_free_data_block_num * 64);
@@ -73,7 +73,7 @@ void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp)
*/
int ff_xvmc_field_start(MpegEncContext *s, AVCodecContext *avctx)
{
- struct xvmc_pix_fmt *last, *next, *render = (struct xvmc_pix_fmt*)s->current_picture.data[2];
+ struct xvmc_pix_fmt *last, *next, *render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2];
const int mb_block_count = 4 + (1 << s->chroma_format);
assert(avctx);
@@ -113,7 +113,7 @@ int ff_xvmc_field_start(MpegEncContext *s, AVCodecContext *avctx)
case AV_PICTURE_TYPE_I:
return 0; // no prediction from other frames
case AV_PICTURE_TYPE_B:
- next = (struct xvmc_pix_fmt*)s->next_picture.data[2];
+ next = (struct xvmc_pix_fmt*)s->next_picture.f.data[2];
if (!next)
return -1;
if (next->xvmc_id != AV_XVMC_ID)
@@ -121,7 +121,7 @@ int ff_xvmc_field_start(MpegEncContext *s, AVCodecContext *avctx)
render->p_future_surface = next->p_surface;
// no return here, going to set forward prediction
case AV_PICTURE_TYPE_P:
- last = (struct xvmc_pix_fmt*)s->last_picture.data[2];
+ last = (struct xvmc_pix_fmt*)s->last_picture.f.data[2];
if (!last)
last = render; // predict second field from the first
if (last->xvmc_id != AV_XVMC_ID)
@@ -141,7 +141,7 @@ return -1;
*/
void ff_xvmc_field_end(MpegEncContext *s)
{
- struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.data[2];
+ struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2];
assert(render);
if (render->filled_mv_blocks_num > 0)
@@ -179,10 +179,10 @@ void ff_xvmc_decode_mb(MpegEncContext *s)
// Do I need to export quant when I could not perform postprocessing?
// Anyway, it doesn't hurt.
- s->current_picture.qscale_table[mb_xy] = s->qscale;
+ s->current_picture.f.qscale_table[mb_xy] = s->qscale;
// start of XVMC-specific code
- render = (struct xvmc_pix_fmt*)s->current_picture.data[2];
+ render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2];
assert(render);
assert(render->xvmc_id == AV_XVMC_ID);
assert(render->mv_blocks);
diff --git a/libavcodec/msgsmdec.c b/libavcodec/msgsmdec.c
index ff9b275..1a288ee 100644
--- a/libavcodec/msgsmdec.c
+++ b/libavcodec/msgsmdec.c
@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "msgsmdec.h"
#include "gsmdec_template.c"
diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index c740cfa..11a1915 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -1,5 +1,5 @@
/*
- * MSMPEG4 backend for ffmpeg encoder and decoder
+ * MSMPEG4 backend for encoder and decoder
* Copyright (c) 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
*
@@ -24,7 +24,7 @@
/**
* @file
- * MSMPEG4 backend for ffmpeg encoder and decoder.
+ * MSMPEG4 backend for encoder and decoder
*/
#include "avcodec.h"
@@ -62,10 +62,6 @@ static uint32_t v2_dc_chroma_table[512][2];
/* vc1 externs */
extern const uint8_t wmv3_dc_scale_table[32];
-#ifdef DEBUG
-int frame_count = 0;
-#endif
-
#include "msmpeg4data.h"
#if CONFIG_ENCODERS //strangely gcc includes this even if it is not referenced
@@ -270,7 +266,7 @@ av_cold void ff_msmpeg4_encode_init(MpegEncContext *s)
for(i=0; i<NB_RL_TABLES; i++){
int level;
- for(level=0; level<=MAX_LEVEL; level++){
+ for (level = 1; level <= MAX_LEVEL; level++) {
int run;
for(run=0; run<=MAX_RUN; run++){
int last;
@@ -355,7 +351,7 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
{
find_best_tables(s);
- align_put_bits(&s->pb);
+ avpriv_align_put_bits(&s->pb);
put_bits(&s->pb, 2, s->pict_type - 1);
put_bits(&s->pb, 5, s->qscale);
@@ -780,10 +776,10 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n,
}else{
if(n<4){
wrap= s->linesize;
- dest= s->current_picture.data[0] + (((n>>1) + 2*s->mb_y) * 8* wrap ) + ((n&1) + 2*s->mb_x) * 8;
+ dest= s->current_picture.f.data[0] + (((n >> 1) + 2*s->mb_y) * 8* wrap ) + ((n & 1) + 2*s->mb_x) * 8;
}else{
wrap= s->uvlinesize;
- dest= s->current_picture.data[n-3] + (s->mb_y * 8 * wrap) + s->mb_x * 8;
+ dest= s->current_picture.f.data[n - 3] + (s->mb_y * 8 * wrap) + s->mb_x * 8;
}
if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
else a= get_dc(dest-8, wrap, scale*8);
@@ -1172,7 +1168,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
{
int cbp, code, i;
uint8_t *coded_val;
- uint32_t * const mb_type_ptr= &s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ];
+ uint32_t * const mb_type_ptr = &s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride];
if (s->pict_type == AV_PICTURE_TYPE_P) {
if (s->use_skip_mb_code) {
@@ -1695,7 +1691,7 @@ int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
if(s->msmpeg4_version<=3){
last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
run= SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6);
- level= SHOW_SBITS(re, &s->gb, 8); LAST_SKIP_CACHE(re, &s->gb, 8);
+ level= SHOW_SBITS(re, &s->gb, 8);
SKIP_COUNTER(re, &s->gb, 1+6+8);
}else{
int sign;
@@ -1814,7 +1810,7 @@ int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
i-= 192;
if(i&(~63)){
const int left= get_bits_left(&s->gb);
- if(((i+192 == 64 && level/qmul==-1) || s->error_recognition<=1) && left>=0){
+ if(((i+192 == 64 && level/qmul==-1) || !(s->err_recognition&AV_EF_BITSTREAM)) && left>=0){
av_log(s->avctx, AV_LOG_ERROR, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);
break;
}else{
@@ -1884,60 +1880,56 @@ int ff_msmpeg4_decode_motion(MpegEncContext * s,
}
AVCodec ff_msmpeg4v1_decoder = {
- "msmpeg4v1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MSMPEG4V1,
- sizeof(MpegEncContext),
- ff_msmpeg4_decode_init,
- NULL,
- ff_h263_decode_end,
- ff_h263_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+ .name = "msmpeg4v1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MSMPEG4V1,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_msmpeg4_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
.max_lowres= 3,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"),
.pix_fmts= ff_pixfmt_list_420,
};
AVCodec ff_msmpeg4v2_decoder = {
- "msmpeg4v2",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MSMPEG4V2,
- sizeof(MpegEncContext),
- ff_msmpeg4_decode_init,
- NULL,
- ff_h263_decode_end,
- ff_h263_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+ .name = "msmpeg4v2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MSMPEG4V2,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_msmpeg4_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
.max_lowres= 3,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
.pix_fmts= ff_pixfmt_list_420,
};
AVCodec ff_msmpeg4v3_decoder = {
- "msmpeg4",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MSMPEG4V3,
- sizeof(MpegEncContext),
- ff_msmpeg4_decode_init,
- NULL,
- ff_h263_decode_end,
- ff_h263_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+ .name = "msmpeg4",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MSMPEG4V3,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_msmpeg4_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
.max_lowres= 3,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
.pix_fmts= ff_pixfmt_list_420,
};
AVCodec ff_wmv1_decoder = {
- "wmv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_WMV1,
- sizeof(MpegEncContext),
- ff_msmpeg4_decode_init,
- NULL,
- ff_h263_decode_end,
- ff_h263_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+ .name = "wmv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_WMV1,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_msmpeg4_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
.max_lowres= 3,
.long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
.pix_fmts= ff_pixfmt_list_420,
diff --git a/libavcodec/msmpeg4.h b/libavcodec/msmpeg4.h
index 8a0a066..77b1944 100644
--- a/libavcodec/msmpeg4.h
+++ b/libavcodec/msmpeg4.h
@@ -1,5 +1,5 @@
/*
- * MSMPEG4 backend for ffmpeg encoder and decoder
+ * MSMPEG4 backend for encoder and decoder
* copyright (c) 2007 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of Libav.
@@ -19,10 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/**
- * @file
- */
-
#ifndef AVCODEC_MSMPEG4_H
#define AVCODEC_MSMPEG4_H
diff --git a/libavcodec/msmpeg4data.c b/libavcodec/msmpeg4data.c
index eeb8122..6799a9c 100644
--- a/libavcodec/msmpeg4data.c
+++ b/libavcodec/msmpeg4data.c
@@ -1,5 +1,5 @@
/*
- * MSMPEG4 backend for ffmpeg encoder and decoder
+ * MSMPEG4 backend for encoder and decoder
* copyright (c) 2001 Fabrice Bellard
* copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
*
diff --git a/libavcodec/msmpeg4data.h b/libavcodec/msmpeg4data.h
index bbb802e..0907c7a 100644
--- a/libavcodec/msmpeg4data.h
+++ b/libavcodec/msmpeg4data.h
@@ -1,5 +1,5 @@
/*
- * MSMPEG4 backend for ffmpeg encoder and decoder
+ * MSMPEG4 backend for encoder and decoder
* copyright (c) 2001 Fabrice Bellard
* copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
*
diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c
index f426b05..11ac7be 100644
--- a/libavcodec/msrle.c
+++ b/libavcodec/msrle.c
@@ -145,14 +145,13 @@ static av_cold int msrle_decode_end(AVCodecContext *avctx)
}
AVCodec ff_msrle_decoder = {
- "msrle",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MSRLE,
- sizeof(MsrleContext),
- msrle_decode_init,
- NULL,
- msrle_decode_end,
- msrle_decode_frame,
- CODEC_CAP_DR1,
+ .name = "msrle",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MSRLE,
+ .priv_data_size = sizeof(MsrleContext),
+ .init = msrle_decode_init,
+ .close = msrle_decode_end,
+ .decode = msrle_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name= NULL_IF_CONFIG_SMALL("Microsoft RLE"),
};
diff --git a/libavcodec/msrledec.c b/libavcodec/msrledec.c
index 46cd50d..5e33a59 100644
--- a/libavcodec/msrledec.c
+++ b/libavcodec/msrledec.c
@@ -138,8 +138,8 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de
uint32_t av_uninit(pix32);
unsigned int width= FFABS(pic->linesize[0]) / (depth >> 3);
- output = pic->data[0] + (avctx->height - 1) * pic->linesize[0];
- output_end = pic->data[0] + (avctx->height) * pic->linesize[0];
+ output = pic->data[0] + (avctx->height - 1) * pic->linesize[0];
+ output_end = pic->data[0] + avctx->height * pic->linesize[0];
while(src < data + srcsize) {
p1 = *src++;
if(p1 == 0) { //Escape code
diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c
index a89ec6a..a5fef4d 100644
--- a/libavcodec/msvideo1.c
+++ b/libavcodec/msvideo1.c
@@ -334,14 +334,13 @@ static av_cold int msvideo1_decode_end(AVCodecContext *avctx)
}
AVCodec ff_msvideo1_decoder = {
- "msvideo1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MSVIDEO1,
- sizeof(Msvideo1Context),
- msvideo1_decode_init,
- NULL,
- msvideo1_decode_end,
- msvideo1_decode_frame,
- CODEC_CAP_DR1,
+ .name = "msvideo1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MSVIDEO1,
+ .priv_data_size = sizeof(Msvideo1Context),
+ .init = msvideo1_decode_init,
+ .close = msvideo1_decode_end,
+ .decode = msvideo1_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name= NULL_IF_CONFIG_SMALL("Microsoft Video 1"),
};
diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c
index e710291..6f0d045 100644
--- a/libavcodec/mxpegdec.c
+++ b/libavcodec/mxpegdec.c
@@ -47,9 +47,7 @@ static av_cold int mxpeg_decode_init(AVCodecContext *avctx)
s->picture[0].reference = s->picture[1].reference = 3;
s->jpg.picture_ptr = &s->picture[0];
- ff_mjpeg_decode_init(avctx);
-
- return 0;
+ return ff_mjpeg_decode_init(avctx);
}
static int mxpeg_decode_app(MXpegDecodeContext *s,
@@ -275,9 +273,13 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
return AVERROR(ENOMEM);
}
- ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, reference_ptr);
+ ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, reference_ptr);
+ if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
+ return ret;
} else {
- ff_mjpeg_decode_sos(jpg, NULL, NULL);
+ ret = ff_mjpeg_decode_sos(jpg, NULL, NULL);
+ if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
+ return ret;
}
break;
diff --git a/libavcodec/nellymoser.c b/libavcodec/nellymoser.c
index 0716c25..cbcc4f9 100644
--- a/libavcodec/nellymoser.c
+++ b/libavcodec/nellymoser.c
@@ -35,7 +35,7 @@
#include "avcodec.h"
#include "dsputil.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
const float ff_nelly_dequantization_table[127] = {
diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c
index 59c1b3b..7f585e4 100644
--- a/libavcodec/nellymoserdec.c
+++ b/libavcodec/nellymoserdec.c
@@ -41,14 +41,15 @@
#include "fmtconvert.h"
#include "sinewin.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
typedef struct NellyMoserDecodeContext {
AVCodecContext* avctx;
- DECLARE_ALIGNED(32, float, float_buf)[NELLY_SAMPLES];
- float state[128];
+ AVFrame frame;
+ float *float_buf;
+ DECLARE_ALIGNED(16, float, state)[NELLY_BUF_LEN];
AVLFG random_state;
GetBitContext gb;
float scale_bias;
@@ -58,23 +59,6 @@ typedef struct NellyMoserDecodeContext {
DECLARE_ALIGNED(32, float, imdct_out)[NELLY_BUF_LEN * 2];
} NellyMoserDecodeContext;
-static void overlap_and_window(NellyMoserDecodeContext *s, float *state, float *audio, float *a_in)
-{
- int bot, top;
-
- bot = 0;
- top = NELLY_BUF_LEN-1;
-
- while (bot < NELLY_BUF_LEN) {
- audio[bot] = a_in [bot]*ff_sine_128[bot]
- +state[bot]*ff_sine_128[top];
-
- bot++;
- top--;
- }
- memcpy(state, a_in + NELLY_BUF_LEN, sizeof(float)*NELLY_BUF_LEN);
-}
-
static void nelly_decode_block(NellyMoserDecodeContext *s,
const unsigned char block[NELLY_BLOCK_LEN],
float audio[NELLY_SAMPLES])
@@ -125,7 +109,9 @@ static void nelly_decode_block(NellyMoserDecodeContext *s,
s->imdct_ctx.imdct_calc(&s->imdct_ctx, s->imdct_out, aptr);
/* XXX: overlapping and windowing should be part of a more
generic imdct function */
- overlap_and_window(s, s->state, aptr, s->imdct_out);
+ s->dsp.vector_fmul_reverse(s->state, s->state, ff_sine_128, NELLY_BUF_LEN);
+ s->dsp.vector_fmul_add(aptr, s->imdct_out, ff_sine_128, s->state, NELLY_BUF_LEN);
+ memcpy(s->state, s->imdct_out + NELLY_BUF_LEN, sizeof(float)*NELLY_BUF_LEN);
}
}
@@ -137,38 +123,52 @@ static av_cold int decode_init(AVCodecContext * avctx) {
ff_mdct_init(&s->imdct_ctx, 8, 1, 1.0);
dsputil_init(&s->dsp, avctx);
- ff_fmt_convert_init(&s->fmt_conv, avctx);
- s->scale_bias = 1.0/(1*8);
+ if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
+ s->scale_bias = 1.0/(32768*8);
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ } else {
+ s->scale_bias = 1.0/(1*8);
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ ff_fmt_convert_init(&s->fmt_conv, avctx);
+ s->float_buf = av_mallocz(NELLY_SAMPLES * sizeof(*s->float_buf));
+ if (!s->float_buf) {
+ av_log(avctx, AV_LOG_ERROR, "error allocating float buffer\n");
+ return AVERROR(ENOMEM);
+ }
+ }
/* Generate overlap window */
if (!ff_sine_128[127])
ff_init_ff_sine_windows(7);
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
avctx->channel_layout = AV_CH_LAYOUT_MONO;
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
-static int decode_tag(AVCodecContext * avctx,
- void *data, int *data_size,
- AVPacket *avpkt) {
+static int decode_tag(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
NellyMoserDecodeContext *s = avctx->priv_data;
- int blocks, i;
- int16_t* samples;
- *data_size = 0;
- samples = (int16_t*)data;
-
- if (buf_size < avctx->block_align)
- return buf_size;
-
- if (buf_size % 64) {
- av_log(avctx, AV_LOG_ERROR, "Tag size %d.\n", buf_size);
- return buf_size;
+ int blocks, i, ret;
+ int16_t *samples_s16;
+ float *samples_flt;
+
+ blocks = buf_size / NELLY_BLOCK_LEN;
+ if (blocks <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (buf_size % NELLY_BLOCK_LEN) {
+ av_log(avctx, AV_LOG_WARNING, "Leftover bytes: %d.\n",
+ buf_size % NELLY_BLOCK_LEN);
}
- blocks = buf_size / 64;
/* Normal numbers of blocks for sample rates:
* 8000 Hz - 1
* 11025 Hz - 2
@@ -177,31 +177,54 @@ static int decode_tag(AVCodecContext * avctx,
* 44100 Hz - 8
*/
+ /* get output buffer */
+ s->frame.nb_samples = NELLY_SAMPLES * blocks;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples_s16 = (int16_t *)s->frame.data[0];
+ samples_flt = (float *)s->frame.data[0];
+
for (i=0 ; i<blocks ; i++) {
- nelly_decode_block(s, &buf[i*NELLY_BLOCK_LEN], s->float_buf);
- s->fmt_conv.float_to_int16(&samples[i*NELLY_SAMPLES], s->float_buf, NELLY_SAMPLES);
- *data_size += NELLY_SAMPLES*sizeof(int16_t);
+ if (avctx->sample_fmt == SAMPLE_FMT_FLT) {
+ nelly_decode_block(s, buf, samples_flt);
+ samples_flt += NELLY_SAMPLES;
+ } else {
+ nelly_decode_block(s, buf, s->float_buf);
+ s->fmt_conv.float_to_int16(samples_s16, s->float_buf, NELLY_SAMPLES);
+ samples_s16 += NELLY_SAMPLES;
+ }
+ buf += NELLY_BLOCK_LEN;
}
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return buf_size;
}
static av_cold int decode_end(AVCodecContext * avctx) {
NellyMoserDecodeContext *s = avctx->priv_data;
+ av_freep(&s->float_buf);
ff_mdct_end(&s->imdct_ctx);
+
return 0;
}
AVCodec ff_nellymoser_decoder = {
- "nellymoser",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_NELLYMOSER,
- sizeof(NellyMoserDecodeContext),
- decode_init,
- NULL,
- decode_end,
- decode_tag,
+ .name = "nellymoser",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_NELLYMOSER,
+ .priv_data_size = sizeof(NellyMoserDecodeContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_tag,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_PARAM_CHANGE,
.long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
+ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
};
diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c
index 0f94e75..d3715ac 100644
--- a/libavcodec/nellymoserenc.c
+++ b/libavcodec/nellymoserenc.c
@@ -35,6 +35,7 @@
* http://wiki.multimedia.cx/index.php?title=Nellymoser
*/
+#include "libavutil/mathematics.h"
#include "nellymoser.h"
#include "avcodec.h"
#include "dsputil.h"
@@ -146,7 +147,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
avctx->frame_size = NELLY_SAMPLES;
s->avctx = avctx;
- ff_mdct_init(&s->mdct_ctx, 8, 0, 1.0);
+ ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0);
dsputil_init(&s->dsp, avctx);
/* Generate overlap window */
@@ -352,17 +353,15 @@ static void encode_block(NellyMoserEncodeContext *s, unsigned char *output, int
static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, void *data)
{
NellyMoserEncodeContext *s = avctx->priv_data;
- const int16_t *samples = data;
+ const float *samples = data;
int i;
if (s->last_frame)
return 0;
if (data) {
- for (i = 0; i < avctx->frame_size; i++) {
- s->buf[s->bufsel][i] = samples[i];
- }
- for (; i < NELLY_SAMPLES; i++) {
+ memcpy(s->buf[s->bufsel], samples, avctx->frame_size * sizeof(*samples));
+ for (i = avctx->frame_size; i < NELLY_SAMPLES; i++) {
s->buf[s->bufsel][i] = 0;
}
s->bufsel = 1 - s->bufsel;
@@ -393,5 +392,5 @@ AVCodec ff_nellymoser_encoder = {
.close = encode_end,
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
.long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
- .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
+ .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE},
};
diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c
index 0c5e42f..94962b5 100644
--- a/libavcodec/nuv.c
+++ b/libavcodec/nuv.c
@@ -63,11 +63,11 @@ static const uint8_t fallback_cquant[] = {
};
/**
- * \brief copy frame data from buffer to AVFrame, handling stride.
- * \param f destination AVFrame
- * \param src source buffer, does not use any line-stride
- * \param width width of the video frame
- * \param height height of the video frame
+ * @brief copy frame data from buffer to AVFrame, handling stride.
+ * @param f destination AVFrame
+ * @param src source buffer, does not use any line-stride
+ * @param width width of the video frame
+ * @param height height of the video frame
*/
static void copy_frame(AVFrame *f, const uint8_t *src,
int width, int height) {
@@ -77,7 +77,7 @@ static void copy_frame(AVFrame *f, const uint8_t *src,
}
/**
- * \brief extract quantization tables from codec data into our context
+ * @brief extract quantization tables from codec data into our context
*/
static int get_quant(AVCodecContext *avctx, NuvContext *c,
const uint8_t *buf, int size) {
@@ -94,7 +94,7 @@ static int get_quant(AVCodecContext *avctx, NuvContext *c,
}
/**
- * \brief set quantization tables from a quality value
+ * @brief set quantization tables from a quality value
*/
static void get_quant_quality(NuvContext *c, int quality) {
int i;
@@ -107,8 +107,8 @@ static void get_quant_quality(NuvContext *c, int quality) {
static int codec_reinit(AVCodecContext *avctx, int width, int height, int quality) {
NuvContext *c = avctx->priv_data;
- width = (width + 1) & ~1;
- height = (height + 1) & ~1;
+ width = FFALIGN(width, 2);
+ height = FFALIGN(height, 2);
if (quality >= 0)
get_quant_quality(c, quality);
if (width != c->width || height != c->height) {
@@ -184,9 +184,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
}
if (c->codec_frameheader) {
int w, h, q;
- if (buf_size < 12) {
- av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n");
- return -1;
+ if (buf[0] != 'V' || buf_size < 12) {
+ av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame (wrong codec_tag?)\n");
+ return AVERROR_INVALIDDATA;
}
w = AV_RL16(&buf[6]);
h = AV_RL16(&buf[8]);
@@ -273,15 +273,14 @@ static av_cold int decode_end(AVCodecContext *avctx) {
}
AVCodec ff_nuv_decoder = {
- "nuv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_NUV,
- sizeof(NuvContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "nuv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_NUV,
+ .priv_data_size = sizeof(NuvContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("NuppelVideo/RTJPEG"),
};
diff --git a/libavcodec/options.c b/libavcodec/options.c
index 6f25ebe..4ac9313 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -25,6 +25,8 @@
*/
#include "avcodec.h"
+#include "internal.h"
+#include "libavutil/avassert.h"
#include "libavutil/opt.h"
#include <float.h> /* FLT_MIN, FLT_MAX */
@@ -37,22 +39,27 @@ static const char* context_to_name(void* ptr) {
return "NULL";
}
-static const AVOption *opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
+static void *codec_child_next(void *obj, void *prev)
{
AVCodecContext *s = obj;
- AVCodec *c = NULL;
+ if (!prev && s->codec && s->codec->priv_class && s->priv_data)
+ return s->priv_data;
+ return NULL;
+}
- if (s->priv_data) {
- if (s->codec->priv_class)
- return av_opt_find(s->priv_data, name, unit, opt_flags, search_flags);
- return NULL;
- }
+static const AVClass *codec_child_class_next(const AVClass *prev)
+{
+ AVCodec *c = NULL;
- while ((c = av_codec_next(c))) {
- const AVOption *o;
- if (c->priv_class && (o = av_opt_find(&c->priv_class, name, unit, opt_flags, search_flags)))
- return o;
- }
+ /* find the codec that corresponds to prev */
+ while (prev && (c = av_codec_next(c)))
+ if (c->priv_class == prev)
+ break;
+
+ /* find next codec with priv options */
+ while (c = av_codec_next(c))
+ if (c->priv_class)
+ return c->priv_class;
return NULL;
}
@@ -68,404 +75,457 @@ static const AVOption *opt_find(void *obj, const char *name, const char *unit, i
#define AV_CODEC_DEFAULT_BITRATE 200*1000
static const AVOption options[]={
-{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), FF_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE }, INT_MIN, INT_MAX, V|E},
-{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), FF_OPT_TYPE_INT, {.dbl = 64*1000 }, INT_MIN, INT_MAX, A|E},
-{"bt", "set video bitrate tolerance (in bits/s)", OFFSET(bit_rate_tolerance), FF_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E},
-{"flags", NULL, OFFSET(flags), FF_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, UINT_MAX, V|A|E|D, "flags"},
-{"mv4", "use four motion vector by macroblock (mpeg4)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"},
-{"obmc", "use overlapped block motion compensation (h263+)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_OBMC }, INT_MIN, INT_MAX, V|E, "flags"},
-{"qpel", "use 1/4 pel motion compensation", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
-{"loop", "use loop filter", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
-{"qscale", "use fixed qscale", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
-{"gmc", "use gmc", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_GMC }, INT_MIN, INT_MAX, V|E, "flags"},
-{"mv0", "always try a mb with mv=<0,0>", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_MV0 }, INT_MIN, INT_MAX, V|E, "flags"},
-{"part", "use data partitioning", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_PART }, INT_MIN, INT_MAX, V|E, "flags"},
-{"input_preserved", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_INPUT_PRESERVED }, INT_MIN, INT_MAX, 0, "flags"},
-{"pass1", "use internal 2pass ratecontrol in first pass mode", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
-{"pass2", "use internal 2pass ratecontrol in second pass mode", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
-{"extern_huff", "use external huffman table (for mjpeg)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_EXTERN_HUFF }, INT_MIN, INT_MAX, 0, "flags"},
-{"gray", "only decode/encode grayscale", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
-{"emu_edge", "don't draw edges", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_EMU_EDGE }, INT_MIN, INT_MAX, 0, "flags"},
-{"psnr", "error[?] variables will be set during encoding", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, "flags"},
-{"truncated", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, 0, "flags"},
-{"naq", "normalize adaptive quantization", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_NORMALIZE_AQP }, INT_MIN, INT_MAX, V|E, "flags"},
-{"ildct", "use interlaced dct", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"},
-{"low_delay", "force low delay", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"},
-{"alt", "enable alternate scantable (mpeg2/mpeg4)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_ALT_SCAN }, INT_MIN, INT_MAX, V|E, "flags"},
-{"global_header", "place global headers in extradata instead of every keyframe", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"},
-{"bitexact", "use only bitexact stuff (except (i)dct)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"},
-{"aic", "h263 advanced intra coding / mpeg4 ac prediction", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"},
-{"umv", "use unlimited motion vectors", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_H263P_UMV }, INT_MIN, INT_MAX, V|E, "flags"},
-{"cbp", "use rate distortion optimization for cbp", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_CBP_RD }, INT_MIN, INT_MAX, V|E, "flags"},
-{"qprd", "use rate distortion optimization for qp selection", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_QP_RD }, INT_MIN, INT_MAX, V|E, "flags"},
-{"aiv", "h263 alternative inter vlc", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_H263P_AIV }, INT_MIN, INT_MAX, V|E, "flags"},
-{"slice", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_H263P_SLICE_STRUCT }, INT_MIN, INT_MAX, V|E, "flags"},
-{"ilme", "interlaced motion estimation", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"},
-{"scan_offset", "will reserve space for svcd scan offset user data", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_SVCD_SCAN_OFFSET }, INT_MIN, INT_MAX, V|E, "flags"},
-{"cgop", "closed gop", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
-{"fast", "allow non spec compliant speedup tricks", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"sgop", "strictly enforce gop size", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_STRICT_GOP }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"noout", "skip bitstream encoding", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"local_header", "place global headers at every keyframe instead of in extradata", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"sub_id", NULL, OFFSET(sub_id), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"me_method", "set motion estimation method", OFFSET(me_method), FF_OPT_TYPE_INT, {.dbl = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method"},
-{"zero", "zero motion estimation (fastest)", 0, FF_OPT_TYPE_CONST, {.dbl = ME_ZERO }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"full", "full motion estimation (slowest)", 0, FF_OPT_TYPE_CONST, {.dbl = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"epzs", "EPZS motion estimation (default)", 0, FF_OPT_TYPE_CONST, {.dbl = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"esa", "esa motion estimation (alias for full)", 0, FF_OPT_TYPE_CONST, {.dbl = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"tesa", "tesa motion estimation", 0, FF_OPT_TYPE_CONST, {.dbl = ME_TESA }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"dia", "dia motion estimation (alias for epzs)", 0, FF_OPT_TYPE_CONST, {.dbl = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"log", "log motion estimation", 0, FF_OPT_TYPE_CONST, {.dbl = ME_LOG }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"phods", "phods motion estimation", 0, FF_OPT_TYPE_CONST, {.dbl = ME_PHODS }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"x1", "X1 motion estimation", 0, FF_OPT_TYPE_CONST, {.dbl = ME_X1 }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"hex", "hex motion estimation", 0, FF_OPT_TYPE_CONST, {.dbl = ME_HEX }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"umh", "umh motion estimation", 0, FF_OPT_TYPE_CONST, {.dbl = ME_UMH }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"iter", "iter motion estimation", 0, FF_OPT_TYPE_CONST, {.dbl = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"extradata_size", NULL, OFFSET(extradata_size), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"time_base", NULL, OFFSET(time_base), FF_OPT_TYPE_RATIONAL, {.dbl = 0}, INT_MIN, INT_MAX},
-{"g", "set the group of picture size", OFFSET(gop_size), FF_OPT_TYPE_INT, {.dbl = 12 }, INT_MIN, INT_MAX, V|E},
-{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"ac", "set number of audio channels", OFFSET(channels), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"cutoff", "set cutoff bandwidth", OFFSET(cutoff), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, A|E},
-{"frame_size", NULL, OFFSET(frame_size), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, A|E},
-{"frame_number", NULL, OFFSET(frame_number), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"delay", NULL, OFFSET(delay), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"qcomp", "video quantizer scale compression (VBR)", OFFSET(qcompress), FF_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E},
-{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), FF_OPT_TYPE_FLOAT, {.dbl = 0.5 }, 0, FLT_MAX, V|E},
-{"qmin", "min video quantizer scale (VBR)", OFFSET(qmin), FF_OPT_TYPE_INT, {.dbl = 2 }, 0, 69, V|E},
-{"qmax", "max video quantizer scale (VBR)", OFFSET(qmax), FF_OPT_TYPE_INT, {.dbl = 31 }, 0, 69, V|E},
-{"qdiff", "max difference between the quantizer scale (VBR)", OFFSET(max_qdiff), FF_OPT_TYPE_INT, {.dbl = 3 }, INT_MIN, INT_MAX, V|E},
-{"bf", "use 'frames' B frames", OFFSET(max_b_frames), FF_OPT_TYPE_INT, {.dbl = 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, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
-{"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), FF_OPT_TYPE_INT, {.dbl = 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, {.dbl = 0 }, INT_MIN, INT_MAX, V|E},
-{"wpredp", "weighted prediction analysis method", OFFSET(weighted_p_pred), FF_OPT_TYPE_INT, {.dbl = 0 }, INT_MIN, INT_MAX, V|E},
-{"ps", "rtp payload size in bytes", OFFSET(rtp_payload_size), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"mv_bits", NULL, OFFSET(mv_bits), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"header_bits", NULL, OFFSET(header_bits), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"i_tex_bits", NULL, OFFSET(i_tex_bits), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"p_tex_bits", NULL, OFFSET(p_tex_bits), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"i_count", NULL, OFFSET(i_count), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"p_count", NULL, OFFSET(p_count), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"skip_count", NULL, OFFSET(skip_count), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"misc_bits", NULL, OFFSET(misc_bits), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"frame_bits", NULL, OFFSET(frame_bits), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"codec_tag", NULL, OFFSET(codec_tag), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"bug", "workaround not auto detected encoder bugs", OFFSET(workaround_bugs), FF_OPT_TYPE_FLAGS, {.dbl = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
-{"autodetect", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
-{"old_msmpeg4", "some old lavc generated msmpeg4v3 files (no autodetection)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"},
-{"xvid_ilace", "Xvid interlacing bug (autodetected if fourcc==XVIX)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"},
-{"ump4", "(autodetected if fourcc==UMP4)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"},
-{"no_padding", "padding bug (autodetected)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"},
-{"amv", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"},
-{"ac_vlc", "illegal vlc bug (autodetected per fourcc)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"},
-{"qpel_chroma", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
-{"std_qpel", "old standard qpel (autodetected per fourcc/version)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"},
-{"qpel_chroma2", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"},
-{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per fourcc/version)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, "bug"},
-{"edge", "edge padding bug (autodetected per fourcc/version)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"},
-{"hpel_chroma", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
-{"dc_clip", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"},
-{"ms", "workaround various bugs in microsofts broken decoders", 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"},
-{"trunc", "trancated frames", 0, FF_OPT_TYPE_CONST, {.dbl = FF_BUG_TRUNCATED}, 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, {.dbl = 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, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), FF_OPT_TYPE_INT, {.dbl = 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, {.dbl = 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, {.dbl = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, V|D|E, "strict"},
-{"normal", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
-{"unofficial", "allow unofficial extensions", 0, FF_OPT_TYPE_CONST, {.dbl = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
-{"experimental", "allow non standardized experimental things", 0, FF_OPT_TYPE_CONST, {.dbl = 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, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
-{"er", "set error detection aggressivity", OFFSET(error_recognition), FF_OPT_TYPE_INT, {.dbl = FF_ER_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "er"},
-{"careful", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_ER_CAREFUL }, INT_MIN, INT_MAX, V|D, "er"},
-{"compliant", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_ER_COMPLIANT }, INT_MIN, INT_MAX, V|D, "er"},
-{"aggressive", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_ER_AGGRESSIVE }, INT_MIN, INT_MAX, V|D, "er"},
-{"very_aggressive", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_ER_VERY_AGGRESSIVE }, INT_MIN, INT_MAX, V|D, "er"},
-{"has_b_frames", NULL, OFFSET(has_b_frames), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"block_align", NULL, OFFSET(block_align), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"parse_only", NULL, OFFSET(parse_only), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"stats_out", NULL, OFFSET(stats_out), FF_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX},
-{"stats_in", NULL, OFFSET(stats_in), FF_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX},
-{"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", OFFSET(rc_qsquish), FF_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 99, V|E},
-{"rc_qmod_amp", "experimental quantizer modulation", OFFSET(rc_qmod_amp), FF_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
-{"rc_qmod_freq", "experimental quantizer modulation", OFFSET(rc_qmod_freq), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"rc_override_count", NULL, OFFSET(rc_override_count), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"rc_eq", "set rate control equation", OFFSET(rc_eq), FF_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E},
-{"maxrate", "set max video bitrate tolerance (in bits/s)", OFFSET(rc_max_rate), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"minrate", "set min video bitrate tolerance (in bits/s)", OFFSET(rc_min_rate), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, A|V|E},
-{"rc_buf_aggressivity", "currently useless", OFFSET(rc_buffer_aggressivity), FF_OPT_TYPE_FLOAT, {.dbl = 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, {.dbl = -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, {.dbl = 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, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
-{"dct", "DCT algorithm", OFFSET(dct_algo), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, V|E, "dct"},
-{"auto", "autoselect a good one (default)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"},
-{"fastint", "fast integer", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"},
-{"int", "accurate integer", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"},
-{"mmx", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"},
-{"mlib", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_DCT_MLIB }, INT_MIN, INT_MAX, V|E, "dct"},
-{"altivec", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"},
-{"faan", "floating point AAN DCT", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"},
-{"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), FF_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
-{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), FF_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
-{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), FF_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
-{"p_mask", "inter masking", OFFSET(p_masking), FF_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
-{"dark_mask", "compresses dark areas stronger than medium ones", OFFSET(dark_masking), FF_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
-{"idct", "select IDCT implementation", OFFSET(idct_algo), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, V|E|D, "idct"},
-{"auto", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"int", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simple", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplemmx", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"libmpeg2mmx", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_LIBMPEG2MMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"ps2", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_PS2 }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"mlib", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_MLIB }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"arm", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"altivec", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"sh4", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_SH4 }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplearm", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplearmv5te", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplearmv6", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simpleneon", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplealpha", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"h264", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_H264 }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"vp3", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_VP3 }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"ipp", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"xvidmmx", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_XVIDMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"faani", "floating point AAN IDCT", 0, FF_OPT_TYPE_CONST, {.dbl = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
-{"slice_count", NULL, OFFSET(slice_count), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"ec", "set error concealment strategy", OFFSET(error_concealment), FF_OPT_TYPE_FLAGS, {.dbl = 3 }, INT_MIN, INT_MAX, V|D, "ec"},
-{"guess_mvs", "iterative motion vector (MV) search (slow)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, "ec"},
-{"deblock", "use strong deblock filter for damaged MBs", 0, FF_OPT_TYPE_CONST, {.dbl = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"},
-{"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"pred", "prediction method", OFFSET(prediction_method), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "pred"},
-{"left", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PRED_LEFT }, INT_MIN, INT_MAX, V|E, "pred"},
-{"plane", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PRED_PLANE }, INT_MIN, INT_MAX, V|E, "pred"},
-{"median", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PRED_MEDIAN }, INT_MIN, INT_MAX, V|E, "pred"},
-{"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), FF_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E},
-{"debug", "print specific debug info", OFFSET(debug), FF_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, INT_MAX, V|A|S|E|D, "debug"},
-{"pict", "picture info", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, "debug"},
-{"rc", "rate control", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, "debug"},
-{"bitstream", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"},
-{"mb_type", "macroblock (MB) type", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
-{"qp", "per-block quantization parameter (QP)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"},
-{"mv", "motion vector", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_MV }, INT_MIN, INT_MAX, V|D, "debug"},
-{"dct_coeff", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"},
-{"skip", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"},
-{"startcode", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"},
-{"pts", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_PTS }, INT_MIN, INT_MAX, V|D, "debug"},
-{"er", "error recognition", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"},
-{"mmco", "memory management control operations (H.264)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"},
-{"bugs", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"},
-{"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"},
-{"vis_mb_type", "visualize block types", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
-{"buffers", "picture buffer allocations", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"},
-{"thread_ops", "threading operations", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|D, "debug"},
-{"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, V|D, "debug_mv"},
-{"pf", "forward predicted MVs of P-frames", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_VIS_MV_P_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
-{"bf", "forward predicted MVs of B-frames", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_VIS_MV_B_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
-{"bb", "backward predicted MVs of B-frames", 0, FF_OPT_TYPE_CONST, {.dbl = FF_DEBUG_VIS_MV_B_BACK }, INT_MIN, INT_MAX, V|D, "debug_mv"},
-{"cmp", "full pel me compare function", OFFSET(me_cmp), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"subcmp", "sub pel me compare function", OFFSET(me_sub_cmp), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"ildctcmp", "interlaced dct compare function", OFFSET(ildct_cmp), FF_OPT_TYPE_INT, {.dbl = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"preme", "pre motion estimation", OFFSET(pre_me), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"sad", "sum of absolute differences, fast (default)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"sse", "sum of squared errors", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"satd", "sum of absolute Hadamard transformed differences", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"dct", "sum of absolute DCT transformed differences", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"psnr", "sum of squared quantization errors (avoid, low quality)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_PSNR }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"bit", "number of bits needed for the block", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_BIT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"rd", "rate distortion optimal, slow", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_RD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"zero", "0", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"vsad", "sum of absolute vertical differences", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"vsse", "sum of squared vertical differences", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"nsse", "noise preserving sum of squared differences", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE }, INT_MIN, INT_MAX, V|A|E},
+{"ab", "this option is deprecated, use b", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE }, INT_MIN, INT_MAX, A|E},
+{"bt", "set video bitrate tolerance (in bits/s)", OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E},
+{"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, UINT_MAX, V|A|E|D, "flags"},
+{"mv4", "use four motion vector by macroblock (mpeg4)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"},
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+{"obmc", "use overlapped block motion compensation (h263+)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_OBMC }, INT_MIN, INT_MAX, V|E, "flags"},
+#endif
+{"qpel", "use 1/4 pel motion compensation", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
+{"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
+{"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
+{"gmc", "use gmc", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_GMC }, INT_MIN, INT_MAX, V|E, "flags"},
+{"mv0", "always try a mb with mv=<0,0>", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_MV0 }, INT_MIN, INT_MAX, V|E, "flags"},
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+{"part", "use data partitioning", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_PART }, INT_MIN, INT_MAX, V|E, "flags"},
+#endif
+{"input_preserved", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_INPUT_PRESERVED }, INT_MIN, INT_MAX, 0, "flags"},
+{"pass1", "use internal 2pass ratecontrol in first pass mode", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
+{"pass2", "use internal 2pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
+#if FF_API_MJPEG_GLOBAL_OPTS
+{"extern_huff", "use external huffman table (for mjpeg)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_EXTERN_HUFF }, INT_MIN, INT_MAX, 0, "flags"},
+#endif
+{"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
+{"emu_edge", "don't draw edges", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_EMU_EDGE }, INT_MIN, INT_MAX, 0, "flags"},
+{"psnr", "error[?] variables will be set during encoding", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, "flags"},
+{"truncated", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, 0, "flags"},
+{"naq", "normalize adaptive quantization", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_NORMALIZE_AQP }, INT_MIN, INT_MAX, V|E, "flags"},
+{"ildct", "use interlaced dct", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"},
+{"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"},
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+{"alt", "enable alternate scantable (mpeg2/mpeg4)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_ALT_SCAN }, INT_MIN, INT_MAX, V|E, "flags"},
+#endif
+{"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"},
+{"bitexact", "use only bitexact stuff (except (i)dct)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"},
+{"aic", "h263 advanced intra coding / mpeg4 ac prediction", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"},
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+{"umv", "use unlimited motion vectors", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_H263P_UMV }, INT_MIN, INT_MAX, V|E, "flags"},
+#endif
+{"cbp", "use rate distortion optimization for cbp", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_CBP_RD }, INT_MIN, INT_MAX, V|E, "flags"},
+{"qprd", "use rate distortion optimization for qp selection", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_QP_RD }, INT_MIN, INT_MAX, V|E, "flags"},
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+{"aiv", "h263 alternative inter vlc", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_H263P_AIV }, INT_MIN, INT_MAX, V|E, "flags"},
+{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_H263P_SLICE_STRUCT }, INT_MIN, INT_MAX, V|E, "flags"},
+#endif
+{"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"},
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+{"scan_offset", "will reserve space for svcd scan offset user data", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_SVCD_SCAN_OFFSET }, INT_MIN, INT_MAX, V|E, "flags"},
+#endif
+{"cgop", "closed gop", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
+{"fast", "allow non spec compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"sgop", "strictly enforce gop size", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_STRICT_GOP }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"sub_id", NULL, OFFSET(sub_id), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"me_method", "set motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.dbl = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method"},
+{"zero", "zero motion estimation (fastest)", 0, AV_OPT_TYPE_CONST, {.dbl = ME_ZERO }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"full", "full motion estimation (slowest)", 0, AV_OPT_TYPE_CONST, {.dbl = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"epzs", "EPZS motion estimation (default)", 0, AV_OPT_TYPE_CONST, {.dbl = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"esa", "esa motion estimation (alias for full)", 0, AV_OPT_TYPE_CONST, {.dbl = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"tesa", "tesa motion estimation", 0, AV_OPT_TYPE_CONST, {.dbl = ME_TESA }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"dia", "dia motion estimation (alias for epzs)", 0, AV_OPT_TYPE_CONST, {.dbl = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"log", "log motion estimation", 0, AV_OPT_TYPE_CONST, {.dbl = ME_LOG }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"phods", "phods motion estimation", 0, AV_OPT_TYPE_CONST, {.dbl = ME_PHODS }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"x1", "X1 motion estimation", 0, AV_OPT_TYPE_CONST, {.dbl = ME_X1 }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"hex", "hex motion estimation", 0, AV_OPT_TYPE_CONST, {.dbl = ME_HEX }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"umh", "umh motion estimation", 0, AV_OPT_TYPE_CONST, {.dbl = ME_UMH }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"iter", "iter motion estimation", 0, AV_OPT_TYPE_CONST, {.dbl = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" },
+{"extradata_size", NULL, OFFSET(extradata_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, INT_MIN, INT_MAX},
+{"g", "set the group of picture size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.dbl = 12 }, INT_MIN, INT_MAX, V|E},
+{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, A|D|E},
+{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, A|D|E},
+{"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, A|E},
+{"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, A|E},
+{"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"delay", NULL, OFFSET(delay), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"qcomp", "video quantizer scale compression (VBR)", OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E},
+{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -1, FLT_MAX, V|E},
+{"qmin", "min video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.dbl = 2 }, -1, 69, V|E},
+{"qmax", "max video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.dbl = 31 }, -1, 69, V|E},
+{"qdiff", "max difference between the quantizer scale (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.dbl = 3 }, INT_MIN, INT_MAX, V|E},
+{"bf", "use 'frames' B frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, -1, FF_MAX_B_FRAMES, V|E},
+{"b_qfactor", "qp factor between p and b frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
+{"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.dbl = 0 }, INT_MIN, INT_MAX, V|E},
+#if FF_API_X264_GLOBAL_OPTS
+{"wpredp", "weighted prediction analysis method", OFFSET(weighted_p_pred), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, V|E},
+#endif
+{"ps", "rtp payload size in bytes", OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"mv_bits", NULL, OFFSET(mv_bits), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"header_bits", NULL, OFFSET(header_bits), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"i_tex_bits", NULL, OFFSET(i_tex_bits), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"p_tex_bits", NULL, OFFSET(p_tex_bits), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"i_count", NULL, OFFSET(i_count), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"p_count", NULL, OFFSET(p_count), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"skip_count", NULL, OFFSET(skip_count), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"misc_bits", NULL, OFFSET(misc_bits), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"frame_bits", NULL, OFFSET(frame_bits), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"bug", "workaround not auto detected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.dbl = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
+{"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
+{"old_msmpeg4", "some old lavc generated msmpeg4v3 files (no autodetection)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"},
+{"xvid_ilace", "Xvid interlacing bug (autodetected if fourcc==XVIX)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"},
+{"ump4", "(autodetected if fourcc==UMP4)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"},
+{"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"},
+{"amv", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"},
+{"ac_vlc", "illegal vlc bug (autodetected per fourcc)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"},
+{"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
+{"std_qpel", "old standard qpel (autodetected per fourcc/version)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"},
+{"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"},
+{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per fourcc/version)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, "bug"},
+{"edge", "edge padding bug (autodetected per fourcc/version)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"},
+{"hpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
+{"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"},
+{"ms", "workaround various bugs in microsofts broken decoders", 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"},
+{"trunc", "trancated frames", 0, AV_OPT_TYPE_CONST, {.dbl = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"},
+{"lelim", "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)", OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"celim", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)", OFFSET(chroma_elim_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.dbl = 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, AV_OPT_TYPE_CONST, {.dbl = 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, AV_OPT_TYPE_CONST, {.dbl = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, V|D|E, "strict"},
+{"normal", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
+{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.dbl = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
+{"experimental", "allow non standardized experimental things", 0, AV_OPT_TYPE_CONST, {.dbl = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
+{"b_qoffset", "qp offset between P and B frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
+#if FF_API_ER
+{"er", "set error detection aggressivity", OFFSET(error_recognition), AV_OPT_TYPE_INT, {.dbl = FF_ER_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "er"},
+{"careful", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_ER_CAREFUL }, INT_MIN, INT_MAX, V|D, "er"},
+{"compliant", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_ER_COMPLIANT }, INT_MIN, INT_MAX, V|D, "er"},
+{"aggressive", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_ER_AGGRESSIVE }, INT_MIN, INT_MAX, V|D, "er"},
+{"very_aggressive", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_ER_VERY_AGGRESSIVE }, INT_MIN, INT_MAX, V|D, "er"},
+{"explode", "abort decoding on error recognition", 0, AV_OPT_TYPE_CONST, {.dbl = FF_ER_EXPLODE }, INT_MIN, INT_MAX, V|D, "er"},
+#endif /* FF_API_ER */
+{"err_filter", "set error detection filter flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.dbl = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_filter"},
+{"crccheck", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, V|D, "err_filter"},
+{"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, V|D, "err_filter"},
+{"buffer", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_BUFFER }, INT_MIN, INT_MAX, V|D, "err_filter"},
+{"explode", "abort decoding on minor error recognition", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_EXPLODE }, INT_MIN, INT_MAX, V|D, "err_filter"},
+{"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"parse_only", NULL, OFFSET(parse_only), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"stats_out", NULL, OFFSET(stats_out), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX},
+{"stats_in", NULL, OFFSET(stats_in), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX},
+{"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 99, V|E},
+{"rc_qmod_amp", "experimental quantizer modulation", OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
+{"rc_qmod_freq", "experimental quantizer modulation", OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"rc_eq", "set rate control equation", OFFSET(rc_eq), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E},
+{"maxrate", "set max video bitrate tolerance (in bits/s)", OFFSET(rc_max_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"minrate", "set min video bitrate tolerance (in bits/s)", OFFSET(rc_min_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, A|V|E},
+{"rc_buf_aggressivity", "currently useless", OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, V|E},
+{"i_qfactor", "qp factor between P and I frames", OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = -0.8 }, -FLT_MAX, FLT_MAX, V|E},
+{"i_qoffset", "qp offset between P and I frames", OFFSET(i_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, -FLT_MAX, FLT_MAX, V|E},
+{"rc_init_cplx", "initial complexity for 1-pass encoding", OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
+{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, V|E, "dct"},
+{"auto", "autoselect a good one (default)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"},
+{"fastint", "fast integer", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"},
+{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"},
+{"mmx", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"},
+{"mlib", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_DCT_MLIB }, INT_MIN, INT_MAX, V|E, "dct"},
+{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"},
+{"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"},
+{"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
+{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
+{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
+{"p_mask", "inter masking", OFFSET(p_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
+{"dark_mask", "compresses dark areas stronger than medium ones", OFFSET(dark_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
+{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, V|E|D, "idct"},
+{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"int", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"simple", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"libmpeg2mmx", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_LIBMPEG2MMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"ps2", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_PS2 }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"mlib", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_MLIB }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"arm", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"sh4", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_SH4 }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"simplearm", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"simplealpha", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"h264", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_H264 }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"vp3", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_VP3 }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"ipp", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"xvidmmx", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_XVIDMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.dbl = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
+{"slice_count", NULL, OFFSET(slice_count), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"ec", "set error concealment strategy", OFFSET(error_concealment), AV_OPT_TYPE_FLAGS, {.dbl = 3 }, INT_MIN, INT_MAX, V|D, "ec"},
+{"guess_mvs", "iterative motion vector (MV) search (slow)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, "ec"},
+{"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.dbl = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"},
+{"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"pred", "prediction method", OFFSET(prediction_method), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "pred"},
+{"left", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PRED_LEFT }, INT_MIN, INT_MAX, V|E, "pred"},
+{"plane", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PRED_PLANE }, INT_MIN, INT_MAX, V|E, "pred"},
+{"median", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PRED_MEDIAN }, INT_MIN, INT_MAX, V|E, "pred"},
+{"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E},
+{"debug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, INT_MAX, V|A|S|E|D, "debug"},
+{"pict", "picture info", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, "debug"},
+{"rc", "rate control", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, "debug"},
+{"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"},
+{"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
+{"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"},
+{"mv", "motion vector", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_MV }, INT_MIN, INT_MAX, V|D, "debug"},
+{"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"},
+{"skip", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"},
+{"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"},
+{"pts", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_PTS }, INT_MIN, INT_MAX, V|D, "debug"},
+{"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"},
+{"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"},
+{"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"},
+{"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"},
+{"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
+{"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"},
+{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|D, "debug"},
+{"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, V|D, "debug_mv"},
+{"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_VIS_MV_P_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
+{"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_VIS_MV_B_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
+{"bb", "backward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.dbl = FF_DEBUG_VIS_MV_B_BACK }, INT_MIN, INT_MAX, V|D, "debug_mv"},
+{"cmp", "full pel me compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"subcmp", "sub pel me compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"ildctcmp", "interlaced dct compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.dbl = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"preme", "pre motion estimation", OFFSET(pre_me), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"sad", "sum of absolute differences, fast (default)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"sse", "sum of squared errors", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"satd", "sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"dct", "sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"psnr", "sum of squared quantization errors (avoid, low quality)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_PSNR }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"bit", "number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_BIT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"rd", "rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_RD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"zero", "0", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"vsad", "sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"vsse", "sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"nsse", "noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
#if CONFIG_SNOW_ENCODER
-{"w53", "5/3 wavelet, only used in snow", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"w97", "9/7 wavelet, only used in snow", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"w53", "5/3 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"w97", "9/7 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+#endif
+{"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"subq", "sub pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.dbl = 8 }, INT_MIN, INT_MAX, V|E},
+{"dtg_active_format", NULL, OFFSET(dtg_active_format), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"ibias", "intra quant bias", OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.dbl = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
+{"pbias", "inter quant bias", OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.dbl = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
+{"color_table_id", NULL, OFFSET(color_table_id), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
+{"coder", NULL, OFFSET(coder_type), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "coder"},
+{"vlc", "variable length coder / huffman coder", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"},
+{"ac", "arithmetic coder", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_AC }, INT_MIN, INT_MAX, V|E, "coder"},
+{"raw", "raw (no encoding)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_RAW }, INT_MIN, INT_MAX, V|E, "coder"},
+{"rle", "run-length coder", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_RLE }, INT_MIN, INT_MAX, V|E, "coder"},
+{"deflate", "deflate-based coder", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"},
+{"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "mbd"},
+{"simple", "use mbcmp (default)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"},
+{"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"},
+{"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"},
+{"stream_codec_tag", NULL, OFFSET(stream_codec_tag), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"lmin", "min lagrange factor (VBR)", OFFSET(lmin), AV_OPT_TYPE_INT, {.dbl = 2*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
+{"lmax", "max lagrange factor (VBR)", OFFSET(lmax), AV_OPT_TYPE_INT, {.dbl = 31*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
+{"nr", "noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"inter_threshold", NULL, OFFSET(inter_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+#if FF_API_X264_GLOBAL_OPTS
+#define X264_DEFAULTS CODEC_FLAG2_FASTPSKIP|CODEC_FLAG2_PSY|CODEC_FLAG2_MBTREE
+#else
+#define X264_DEFAULTS 0
+#endif
+#if FF_API_LAME_GLOBAL_OPTS
+#define LAME_DEFAULTS CODEC_FLAG2_BIT_RESERVOIR
+#else
+#define LAME_DEFAULTS 0
#endif
-{"dctmax", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"chroma", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"subq", "sub pel motion estimation quality", OFFSET(me_subpel_quality), FF_OPT_TYPE_INT, {.dbl = 8 }, INT_MIN, INT_MAX, V|E},
-{"dtg_active_format", NULL, OFFSET(dtg_active_format), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"ibias", "intra quant bias", OFFSET(intra_quant_bias), FF_OPT_TYPE_INT, {.dbl = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
-{"pbias", "inter quant bias", OFFSET(inter_quant_bias), FF_OPT_TYPE_INT, {.dbl = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
-{"color_table_id", NULL, OFFSET(color_table_id), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"internal_buffer_count", NULL, OFFSET(internal_buffer_count), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"global_quality", NULL, OFFSET(global_quality), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"coder", NULL, OFFSET(coder_type), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "coder"},
-{"vlc", "variable length coder / huffman coder", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"},
-{"ac", "arithmetic coder", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_AC }, INT_MIN, INT_MAX, V|E, "coder"},
-{"raw", "raw (no encoding)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_RAW }, INT_MIN, INT_MAX, V|E, "coder"},
-{"rle", "run-length coder", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_RLE }, INT_MIN, INT_MAX, V|E, "coder"},
-{"deflate", "deflate-based coder", 0, FF_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"},
-{"context", "context model", OFFSET(context_model), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"slice_flags", NULL, OFFSET(slice_flags), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "mbd"},
-{"simple", "use mbcmp (default)", 0, FF_OPT_TYPE_CONST, {.dbl = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"},
-{"bits", "use fewest bits", 0, FF_OPT_TYPE_CONST, {.dbl = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"},
-{"rd", "use best rate distortion", 0, FF_OPT_TYPE_CONST, {.dbl = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"},
-{"stream_codec_tag", NULL, OFFSET(stream_codec_tag), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"lmin", "min lagrange factor (VBR)", OFFSET(lmin), FF_OPT_TYPE_INT, {.dbl = 2*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
-{"lmax", "max lagrange factor (VBR)", OFFSET(lmax), FF_OPT_TYPE_INT, {.dbl = 31*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
-{"nr", "noise reduction", OFFSET(noise_reduction), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"inter_threshold", NULL, OFFSET(inter_threshold), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"flags2", NULL, OFFSET(flags2), FF_OPT_TYPE_FLAGS, {.dbl = CODEC_FLAG2_FASTPSKIP|CODEC_FLAG2_BIT_RESERVOIR|CODEC_FLAG2_PSY|CODEC_FLAG2_MBTREE }, 0, UINT_MAX, V|A|E|D, "flags2"},
-{"error", NULL, OFFSET(error_rate), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.dbl = X264_DEFAULTS|LAME_DEFAULTS }, 0, UINT_MAX, V|A|E|D, "flags2"},
+{"error", NULL, OFFSET(error_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
#if FF_API_ANTIALIAS_ALGO
-{"antialias", "MP3 antialias algorithm", OFFSET(antialias_algo), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|D, "aa"},
-{"auto", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_AA_AUTO }, INT_MIN, INT_MAX, V|D, "aa"},
-{"fastint", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_AA_FASTINT }, INT_MIN, INT_MAX, V|D, "aa"},
-{"int", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_AA_INT }, INT_MIN, INT_MAX, V|D, "aa"},
-{"float", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_AA_FLOAT }, INT_MIN, INT_MAX, V|D, "aa"},
+{"antialias", "MP3 antialias algorithm", OFFSET(antialias_algo), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|D, "aa"},
+{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_AA_AUTO }, INT_MIN, INT_MAX, V|D, "aa"},
+{"fastint", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_AA_FASTINT }, INT_MIN, INT_MAX, V|D, "aa"},
+{"int", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_AA_INT }, INT_MIN, INT_MAX, V|D, "aa"},
+{"float", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_AA_FLOAT }, INT_MIN, INT_MAX, V|D, "aa"},
+#endif
+{"qns", "quantizer noise shaping", OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.dbl = 1 }, 0, INT_MAX, V|E|D, "threads"},
+{"auto", "detect a good number of threads", 0, AV_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
+{"me_threshold", "motion estimaton threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"dc", "intra_dc_precision", OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.dbl = 0 }, INT_MIN, INT_MAX, V|E},
+{"nssew", "nsse weight", OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.dbl = 8 }, INT_MIN, INT_MAX, V|E},
+{"skip_top", "number of macroblock rows at the top which are skipped", OFFSET(skip_top), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|D},
+{"skip_bottom", "number of macroblock rows at the bottom which are skipped", OFFSET(skip_bottom), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|D},
+{"profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.dbl = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"},
+{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"},
+{"aac_main", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PROFILE_AAC_MAIN }, INT_MIN, INT_MAX, A|E, "profile"},
+{"aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PROFILE_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"},
+{"aac_ssr", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PROFILE_AAC_SSR }, INT_MIN, INT_MAX, A|E, "profile"},
+{"aac_ltp", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PROFILE_AAC_LTP }, INT_MIN, INT_MAX, A|E, "profile"},
+{"dts", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PROFILE_DTS }, INT_MIN, INT_MAX, A|E, "profile"},
+{"dts_es", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PROFILE_DTS_ES }, INT_MIN, INT_MAX, A|E, "profile"},
+{"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"},
+{"dts_hd_hra", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PROFILE_DTS_HD_HRA }, INT_MIN, INT_MAX, A|E, "profile"},
+{"dts_hd_ma", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_PROFILE_DTS_HD_MA }, INT_MIN, INT_MAX, A|E, "profile"},
+{"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.dbl = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
+{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
+{"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|A|D},
+{"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+{"skipcmp", "frame skip compare function", OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.dbl = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"border_mask", "increases the quantizer for macroblocks close to borders", OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
+{"mblmin", "min macroblock lagrange factor (VBR)", OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.dbl = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E},
+{"mblmax", "max macroblock lagrange factor (VBR)", OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.dbl = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E},
+{"mepc", "motion estimation bitrate penalty compensation (1.0 = 256)", OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.dbl = 256 }, INT_MIN, INT_MAX, V|E},
+{"skip_loop_filter", NULL, OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.dbl = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+{"skip_idct" , NULL, OFFSET(skip_idct) , AV_OPT_TYPE_INT, {.dbl = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+{"skip_frame" , NULL, OFFSET(skip_frame) , AV_OPT_TYPE_INT, {.dbl = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+{"none" , NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AVDISCARD_NONE }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+{"default" , NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+{"noref" , NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AVDISCARD_NONREF }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+{"bidir" , NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AVDISCARD_BIDIR }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+{"nokey" , NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AVDISCARD_NONKEY }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+{"all" , NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AVDISCARD_ALL }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+{"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.dbl = 1 }, 0, 4, V|E},
+{"brd_scale", "downscales frames for dynamic B-frame decision", OFFSET(brd_scale), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, 10, V|E},
+#if FF_API_X264_GLOBAL_OPTS
+{"crf", "enables constant quality mode, and selects the quality (x264)", OFFSET(crf), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 51, V|E},
+{"cqp", "constant quantization parameter rate control method", OFFSET(cqp), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, V|E},
+#endif
+{"keyint_min", "minimum interval between IDR-frames (x264)", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.dbl = 25 }, INT_MIN, INT_MAX, V|E},
+{"refs", "reference frames to consider for motion compensation (Snow)", OFFSET(refs), AV_OPT_TYPE_INT, {.dbl = 1 }, INT_MIN, INT_MAX, V|E},
+{"chromaoffset", "chroma qp offset from luma", OFFSET(chromaoffset), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+#if FF_API_X264_GLOBAL_OPTS
+{"bframebias", "influences how often B-frames are used", OFFSET(bframebias), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
+#endif
+{"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
+#if FF_API_X264_GLOBAL_OPTS
+{"directpred", "direct mv prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto)", OFFSET(directpred), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, V|E},
+{"bpyramid", "allows B-frames to be used as references for predicting", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_BPYRAMID }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"wpred", "weighted biprediction for b-frames (H.264)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_WPRED }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"mixed_refs", "one reference per partition, as opposed to one reference per macroblock", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_MIXED_REFS }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"dct8x8", "high profile 8x8 transform (H.264)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_8X8DCT }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"fastpskip", "fast pskip (H.264)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_FASTPSKIP }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"aud", "access unit delimiters (H.264)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_AUD }, INT_MIN, INT_MAX, V|E, "flags2"},
+#endif
+{"skiprd", "RD optimal MB level residual skipping", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_SKIP_RD }, INT_MIN, INT_MAX, V|E, "flags2"},
+#if FF_API_X264_GLOBAL_OPTS
+{"complexityblur", "reduce fluctuations in qp (before curve compression)", OFFSET(complexityblur), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, V|E},
+{"deblockalpha", "in-loop deblocking filter alphac0 parameter", OFFSET(deblockalpha), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, -6, 6, V|E},
+{"deblockbeta", "in-loop deblocking filter beta parameter", OFFSET(deblockbeta), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, -6, 6, V|E},
+{"partitions", "macroblock subpartition sizes to consider", OFFSET(partitions), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "partitions"},
+{"parti4x4", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = X264_PART_I4X4 }, INT_MIN, INT_MAX, V|E, "partitions"},
+{"parti8x8", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = X264_PART_I8X8 }, INT_MIN, INT_MAX, V|E, "partitions"},
+{"partp4x4", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = X264_PART_P4X4 }, INT_MIN, INT_MAX, V|E, "partitions"},
+{"partp8x8", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = X264_PART_P8X8 }, INT_MIN, INT_MAX, V|E, "partitions"},
+{"partb8x8", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = X264_PART_B8X8 }, INT_MIN, INT_MAX, V|E, "partitions"},
+#endif
+{"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), AV_OPT_TYPE_INT, {.dbl = 6 }, 0, INT_MAX, V|E},
+{"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.dbl = 256 }, 0, INT_MAX, V|E},
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+{"ivlc", "intra vlc table", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_INTRA_VLC }, INT_MIN, INT_MAX, V|E, "flags2"},
#endif
-{"qns", "quantizer noise shaping", OFFSET(quantizer_noise_shaping), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"threads", NULL, OFFSET(thread_count), FF_OPT_TYPE_INT, {.dbl = 1 }, INT_MIN, INT_MAX, V|E|D},
-{"me_threshold", "motion estimaton threshold", OFFSET(me_threshold), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"dc", "intra_dc_precision", OFFSET(intra_dc_precision), FF_OPT_TYPE_INT, {.dbl = 0 }, INT_MIN, INT_MAX, V|E},
-{"nssew", "nsse weight", OFFSET(nsse_weight), FF_OPT_TYPE_INT, {.dbl = 8 }, INT_MIN, INT_MAX, V|E},
-{"skip_top", "number of macroblock rows at the top which are skipped", OFFSET(skip_top), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|D},
-{"skip_bottom", "number of macroblock rows at the bottom which are skipped", OFFSET(skip_bottom), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|D},
-{"profile", NULL, OFFSET(profile), FF_OPT_TYPE_INT, {.dbl = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"},
-{"unknown", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"},
-{"aac_main", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PROFILE_AAC_MAIN }, INT_MIN, INT_MAX, A|E, "profile"},
-{"aac_low", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PROFILE_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"},
-{"aac_ssr", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PROFILE_AAC_SSR }, INT_MIN, INT_MAX, A|E, "profile"},
-{"aac_ltp", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PROFILE_AAC_LTP }, INT_MIN, INT_MAX, A|E, "profile"},
-{"dts", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PROFILE_DTS }, INT_MIN, INT_MAX, A|E, "profile"},
-{"dts_es", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PROFILE_DTS_ES }, INT_MIN, INT_MAX, A|E, "profile"},
-{"dts_96_24", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"},
-{"dts_hd_hra", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PROFILE_DTS_HD_HRA }, INT_MIN, INT_MAX, A|E, "profile"},
-{"dts_hd_ma", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_PROFILE_DTS_HD_MA }, INT_MIN, INT_MAX, A|E, "profile"},
-{"level", NULL, OFFSET(level), FF_OPT_TYPE_INT, {.dbl = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
-{"unknown", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
-{"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|A|D},
-{"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"skipcmp", "frame skip compare function", OFFSET(frame_skip_cmp), FF_OPT_TYPE_INT, {.dbl = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"border_mask", "increases the quantizer for macroblocks close to borders", OFFSET(border_masking), FF_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
-{"mblmin", "min macroblock lagrange factor (VBR)", OFFSET(mb_lmin), FF_OPT_TYPE_INT, {.dbl = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E},
-{"mblmax", "max macroblock lagrange factor (VBR)", OFFSET(mb_lmax), FF_OPT_TYPE_INT, {.dbl = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E},
-{"mepc", "motion estimation bitrate penalty compensation (1.0 = 256)", OFFSET(me_penalty_compensation), FF_OPT_TYPE_INT, {.dbl = 256 }, INT_MIN, INT_MAX, V|E},
-{"skip_loop_filter", NULL, OFFSET(skip_loop_filter), FF_OPT_TYPE_INT, {.dbl = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"skip_idct" , NULL, OFFSET(skip_idct) , FF_OPT_TYPE_INT, {.dbl = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"skip_frame" , NULL, OFFSET(skip_frame) , FF_OPT_TYPE_INT, {.dbl = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"none" , NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AVDISCARD_NONE }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"default" , NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"noref" , NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AVDISCARD_NONREF }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"bidir" , NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AVDISCARD_BIDIR }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"nokey" , NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AVDISCARD_NONKEY }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"all" , NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AVDISCARD_ALL }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 4, V|E},
-{"brd_scale", "downscales frames for dynamic B-frame decision", OFFSET(brd_scale), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, 10, V|E},
-{"crf", "enables constant quality mode, and selects the quality (x264)", OFFSET(crf), FF_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 51, V|E},
-{"cqp", "constant quantization parameter rate control method", OFFSET(cqp), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, V|E},
-{"keyint_min", "minimum interval between IDR-frames (x264)", OFFSET(keyint_min), FF_OPT_TYPE_INT, {.dbl = 25 }, INT_MIN, INT_MAX, V|E},
-{"refs", "reference frames to consider for motion compensation (Snow)", OFFSET(refs), FF_OPT_TYPE_INT, {.dbl = 1 }, INT_MIN, INT_MAX, V|E},
-{"chromaoffset", "chroma qp offset from luma", OFFSET(chromaoffset), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"bframebias", "influences how often B-frames are used", OFFSET(bframebias), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"trellis", "rate-distortion optimal quantization", OFFSET(trellis), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
-{"directpred", "direct mv prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto)", OFFSET(directpred), FF_OPT_TYPE_INT, {.dbl = 2 }, INT_MIN, INT_MAX, V|E},
-{"bpyramid", "allows B-frames to be used as references for predicting", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_BPYRAMID }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"wpred", "weighted biprediction for b-frames (H.264)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_WPRED }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"mixed_refs", "one reference per partition, as opposed to one reference per macroblock", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_MIXED_REFS }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"dct8x8", "high profile 8x8 transform (H.264)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_8X8DCT }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"fastpskip", "fast pskip (H.264)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_FASTPSKIP }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"aud", "access unit delimiters (H.264)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_AUD }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"skiprd", "RD optimal MB level residual skipping", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_SKIP_RD }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"complexityblur", "reduce fluctuations in qp (before curve compression)", OFFSET(complexityblur), FF_OPT_TYPE_FLOAT, {.dbl = 20.0 }, FLT_MIN, FLT_MAX, V|E},
-{"deblockalpha", "in-loop deblocking filter alphac0 parameter", OFFSET(deblockalpha), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, -6, 6, V|E},
-{"deblockbeta", "in-loop deblocking filter beta parameter", OFFSET(deblockbeta), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, -6, 6, V|E},
-{"partitions", "macroblock subpartition sizes to consider", OFFSET(partitions), FF_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "partitions"},
-{"parti4x4", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = X264_PART_I4X4 }, INT_MIN, INT_MAX, V|E, "partitions"},
-{"parti8x8", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = X264_PART_I8X8 }, INT_MIN, INT_MAX, V|E, "partitions"},
-{"partp4x4", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = X264_PART_P4X4 }, INT_MIN, INT_MAX, V|E, "partitions"},
-{"partp8x8", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = X264_PART_P8X8 }, INT_MIN, INT_MAX, V|E, "partitions"},
-{"partb8x8", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = X264_PART_B8X8 }, INT_MIN, INT_MAX, V|E, "partitions"},
-{"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), FF_OPT_TYPE_INT, {.dbl = 6 }, 0, INT_MAX, V|E},
-{"mv0_threshold", NULL, OFFSET(mv0_threshold), FF_OPT_TYPE_INT, {.dbl = 256 }, 0, INT_MAX, V|E},
-{"ivlc", "intra vlc table", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_INTRA_VLC }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"b_sensitivity", "adjusts sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), FF_OPT_TYPE_INT, {.dbl = 40 }, 1, INT_MAX, V|E},
-{"compression_level", NULL, OFFSET(compression_level), FF_OPT_TYPE_INT, {.dbl = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E},
-{"min_prediction_order", NULL, OFFSET(min_prediction_order), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
-{"max_prediction_order", NULL, OFFSET(max_prediction_order), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
+{"b_sensitivity", "adjusts sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.dbl = 40 }, 1, INT_MAX, V|E},
+{"compression_level", NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.dbl = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E},
+{"min_prediction_order", NULL, OFFSET(min_prediction_order), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
+{"max_prediction_order", NULL, OFFSET(max_prediction_order), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
#if FF_API_FLAC_GLOBAL_OPTS
-{"lpc_coeff_precision", "deprecated, use flac-specific options", OFFSET(lpc_coeff_precision), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, A|E},
-{"prediction_order_method", "deprecated, use flac-specific options", OFFSET(prediction_order_method), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
-{"min_partition_order", "deprecated, use flac-specific options", OFFSET(min_partition_order), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
-{"max_partition_order", "deprecated, use flac-specific options", OFFSET(max_partition_order), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
+{"lpc_coeff_precision", "deprecated, use flac-specific options", OFFSET(lpc_coeff_precision), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, A|E},
+{"prediction_order_method", "deprecated, use flac-specific options", OFFSET(prediction_order_method), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
+{"min_partition_order", "deprecated, use flac-specific options", OFFSET(min_partition_order), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
+{"max_partition_order", "deprecated, use flac-specific options", OFFSET(max_partition_order), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
+#endif
+{"timecode_frame_start", "GOP timecode frame start number, in non drop frame format", OFFSET(timecode_frame_start), AV_OPT_TYPE_INT64, {.dbl = 0 }, 0, INT64_MAX, V|E},
+#if FF_API_MPEGVIDEO_GLOBAL_OPTS
+{"drop_frame_timecode", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_DROP_FRAME_TIMECODE }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"non_linear_q", "use non linear quantizer", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_NON_LINEAR_QUANT }, INT_MIN, INT_MAX, V|E, "flags2"},
#endif
-{"timecode_frame_start", "GOP timecode frame start number, in non drop frame format", OFFSET(timecode_frame_start), FF_OPT_TYPE_INT64, {.dbl = 0 }, 0, INT64_MAX, V|E},
-{"drop_frame_timecode", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_DROP_FRAME_TIMECODE }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"non_linear_q", "use non linear quantizer", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_NON_LINEAR_QUANT }, INT_MIN, INT_MAX, V|E, "flags2"},
#if FF_API_REQUEST_CHANNELS
-{"request_channels", "set desired number of audio channels", OFFSET(request_channels), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, A|D},
+{"request_channels", "set desired number of audio channels", OFFSET(request_channels), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, A|D},
+#endif
+#if FF_API_DRC_SCALE
+{"drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, 0.0, 1.0, A|D},
+#endif
+#if FF_API_LAME_GLOBAL_OPTS
+{"reservoir", "use bit reservoir", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_BIT_RESERVOIR }, INT_MIN, INT_MAX, A|E, "flags2"},
#endif
-{"drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), FF_OPT_TYPE_FLOAT, {.dbl = 1.0 }, 0.0, 1.0, A|D},
-{"reservoir", "use bit reservoir", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_BIT_RESERVOIR }, INT_MIN, INT_MAX, A|E, "flags2"},
-{"mbtree", "use macroblock tree ratecontrol (x264 only)", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_MBTREE }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
-{"channel_layout", NULL, OFFSET(channel_layout), FF_OPT_TYPE_INT64, {.dbl = DEFAULT }, 0, INT64_MAX, A|E|D, "channel_layout"},
-{"request_channel_layout", NULL, OFFSET(request_channel_layout), FF_OPT_TYPE_INT64, {.dbl = DEFAULT }, 0, INT64_MAX, A|D, "request_channel_layout"},
-{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), FF_OPT_TYPE_FLOAT, {.dbl = 1.0/3 }, 0.0, FLT_MAX, V|E},
-{"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), FF_OPT_TYPE_FLOAT, {.dbl = 3 }, 0.0, FLT_MAX, V|E},
-{"ticks_per_frame", NULL, OFFSET(ticks_per_frame), FF_OPT_TYPE_INT, {.dbl = 1 }, 1, INT_MAX, A|V|E|D},
-{"color_primaries", NULL, OFFSET(color_primaries), FF_OPT_TYPE_INT, {.dbl = AVCOL_PRI_UNSPECIFIED }, 1, AVCOL_PRI_NB-1, V|E|D},
-{"color_trc", NULL, OFFSET(color_trc), FF_OPT_TYPE_INT, {.dbl = AVCOL_TRC_UNSPECIFIED }, 1, AVCOL_TRC_NB-1, V|E|D},
-{"colorspace", NULL, OFFSET(colorspace), FF_OPT_TYPE_INT, {.dbl = AVCOL_SPC_UNSPECIFIED }, 1, AVCOL_SPC_NB-1, V|E|D},
-{"color_range", NULL, OFFSET(color_range), FF_OPT_TYPE_INT, {.dbl = AVCOL_RANGE_UNSPECIFIED }, 0, AVCOL_RANGE_NB-1, V|E|D},
-{"chroma_sample_location", NULL, OFFSET(chroma_sample_location), FF_OPT_TYPE_INT, {.dbl = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, V|E|D},
-{"psy", "use psycho visual optimization", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_PSY }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"psy_rd", "specify psycho visual strength", OFFSET(psy_rd), FF_OPT_TYPE_FLOAT, {.dbl = 1.0 }, 0, FLT_MAX, V|E},
-{"psy_trellis", "specify psycho visual trellis", OFFSET(psy_trellis), FF_OPT_TYPE_FLOAT, {.dbl = 0 }, 0, FLT_MAX, V|E},
-{"aq_mode", "specify aq method", OFFSET(aq_mode), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, INT_MAX, V|E},
-{"aq_strength", "specify aq strength", OFFSET(aq_strength), FF_OPT_TYPE_FLOAT, {.dbl = 1.0 }, 0, FLT_MAX, V|E},
-{"rc_lookahead", "specify number of frames to look ahead for frametype", OFFSET(rc_lookahead), FF_OPT_TYPE_INT, {.dbl = 40 }, 0, INT_MAX, V|E},
-{"ssim", "ssim will be calculated during encoding", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_SSIM }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"intra_refresh", "use periodic insertion of intra blocks instead of keyframes", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_INTRA_REFRESH }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"crf_max", "in crf mode, prevents vbv from lowering quality beyond this point", OFFSET(crf_max), FF_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 51, V|E},
-{"log_level_offset", "set the log level offset", OFFSET(log_level_offset), FF_OPT_TYPE_INT, {.dbl = 0 }, INT_MIN, INT_MAX },
+#if FF_API_X264_GLOBAL_OPTS
+{"mbtree", "use macroblock tree ratecontrol (x264 only)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_MBTREE }, INT_MIN, INT_MAX, V|E, "flags2"},
+#endif
+{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},
+{"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_INT64, {.dbl = DEFAULT }, 0, INT64_MAX, A|E|D, "channel_layout"},
+{"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_INT64, {.dbl = DEFAULT }, 0, INT64_MAX, A|D, "request_channel_layout"},
+{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 1.0/3 }, 0.0, FLT_MAX, V|E},
+{"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), AV_OPT_TYPE_FLOAT, {.dbl = 3 }, 0.0, FLT_MAX, V|E},
+{"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.dbl = 1 }, 1, INT_MAX, A|V|E|D},
+{"color_primaries", NULL, OFFSET(color_primaries), AV_OPT_TYPE_INT, {.dbl = AVCOL_PRI_UNSPECIFIED }, 1, AVCOL_PRI_NB-1, V|E|D},
+{"color_trc", NULL, OFFSET(color_trc), AV_OPT_TYPE_INT, {.dbl = AVCOL_TRC_UNSPECIFIED }, 1, AVCOL_TRC_NB-1, V|E|D},
+{"colorspace", NULL, OFFSET(colorspace), AV_OPT_TYPE_INT, {.dbl = AVCOL_SPC_UNSPECIFIED }, 1, AVCOL_SPC_NB-1, V|E|D},
+{"color_range", NULL, OFFSET(color_range), AV_OPT_TYPE_INT, {.dbl = AVCOL_RANGE_UNSPECIFIED }, 0, AVCOL_RANGE_NB-1, V|E|D},
+{"chroma_sample_location", NULL, OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.dbl = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, V|E|D},
+#if FF_API_X264_GLOBAL_OPTS
+{"psy", "use psycho visual optimization", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_PSY }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"psy_rd", "specify psycho visual strength", OFFSET(psy_rd), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1, FLT_MAX, V|E},
+{"psy_trellis", "specify psycho visual trellis", OFFSET(psy_trellis), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, V|E},
+{"aq_mode", "specify aq method", OFFSET(aq_mode), AV_OPT_TYPE_INT, {.dbl = -1 }, -1, INT_MAX, V|E},
+{"aq_strength", "specify aq strength", OFFSET(aq_strength), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1, FLT_MAX, V|E},
+{"rc_lookahead", "specify number of frames to look ahead for frametype", OFFSET(rc_lookahead), AV_OPT_TYPE_INT, {.dbl = -1 }, -1, INT_MAX, V|E},
+{"ssim", "ssim will be calculated during encoding", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_SSIM }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"intra_refresh", "use periodic insertion of intra blocks instead of keyframes", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_INTRA_REFRESH }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"crf_max", "in crf mode, prevents vbv from lowering quality beyond this point", OFFSET(crf_max), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 51, V|E},
+#endif
+{"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.dbl = 0 }, INT_MIN, INT_MAX },
#if FF_API_FLAC_GLOBAL_OPTS
-{"lpc_type", "deprecated, use flac-specific options", OFFSET(lpc_type), FF_OPT_TYPE_INT, {.dbl = AV_LPC_TYPE_DEFAULT }, AV_LPC_TYPE_DEFAULT, AV_LPC_TYPE_NB-1, A|E},
-{"none", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_NONE }, INT_MIN, INT_MAX, A|E, "lpc_type"},
-{"fixed", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_FIXED }, INT_MIN, INT_MAX, A|E, "lpc_type"},
-{"levinson", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_LEVINSON }, INT_MIN, INT_MAX, A|E, "lpc_type"},
-{"cholesky", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_CHOLESKY }, INT_MIN, INT_MAX, A|E, "lpc_type"},
-{"lpc_passes", "deprecated, use flac-specific options", OFFSET(lpc_passes), FF_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
+{"lpc_type", "deprecated, use flac-specific options", OFFSET(lpc_type), AV_OPT_TYPE_INT, {.dbl = AV_LPC_TYPE_DEFAULT }, AV_LPC_TYPE_DEFAULT, AV_LPC_TYPE_NB-1, A|E},
+{"none", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_NONE }, INT_MIN, INT_MAX, A|E, "lpc_type"},
+{"fixed", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_FIXED }, INT_MIN, INT_MAX, A|E, "lpc_type"},
+{"levinson", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_LEVINSON }, INT_MIN, INT_MAX, A|E, "lpc_type"},
+{"cholesky", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_CHOLESKY }, INT_MIN, INT_MAX, A|E, "lpc_type"},
+{"lpc_passes", "deprecated, use flac-specific options", OFFSET(lpc_passes), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
#endif
-{"slices", "number of slices, used in parallelized decoding", OFFSET(slices), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E},
-{"thread_type", "select multithreading type", OFFSET(thread_type), FF_OPT_TYPE_FLAGS, {.dbl = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"},
-{"slice", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
-{"frame", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
-{"vbv_delay", "initial buffer fill time in periods of 27Mhz clock", 0, FF_OPT_TYPE_INT64, {.dbl = 0 }, 0, INT64_MAX},
-{"audio_service_type", "audio service type", OFFSET(audio_service_type), FF_OPT_TYPE_INT, {.dbl = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"},
-{"ma", "Main Audio Service", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_MAIN }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"ef", "Effects", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_EFFECTS }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"vi", "Visually Impaired", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"hi", "Hearing Impaired", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"di", "Dialogue", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_DIALOGUE }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"co", "Commentary", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_COMMENTARY }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"em", "Emergency", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"vo", "Voice Over", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"ka", "Karaoke", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"request_sample_fmt", NULL, OFFSET(request_sample_fmt), FF_OPT_TYPE_INT, {.dbl = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, A|D, "request_sample_fmt"},
-{"u8" , "8-bit unsigned integer", 0, FF_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_U8 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
-{"s16", "16-bit signed integer", 0, FF_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S16 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
-{"s32", "32-bit signed integer", 0, FF_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S32 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
-{"flt", "32-bit float", 0, FF_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_FLT }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
-{"dbl", "64-bit double", 0, FF_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_DBL }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"slices", "number of slices, used in parallelized decoding", OFFSET(slices), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E},
+{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.dbl = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"},
+{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
+{"frame", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
+{"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.dbl = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"},
+{"ma", "Main Audio Service", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_MAIN }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
+{"ef", "Effects", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_EFFECTS }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
+{"vi", "Visually Impaired", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
+{"hi", "Hearing Impaired", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
+{"di", "Dialogue", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_DIALOGUE }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
+{"co", "Commentary", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_COMMENTARY }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
+{"em", "Emergency", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
+{"vo", "Voice Over", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
+{"ka", "Karaoke", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
+{"request_sample_fmt", NULL, OFFSET(request_sample_fmt), AV_OPT_TYPE_INT, {.dbl = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, A|D, "request_sample_fmt"},
+{"u8" , "8-bit unsigned integer", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_U8 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"s16", "16-bit signed integer", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S16 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"s32", "32-bit signed integer", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S32 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"flt", "32-bit float", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_FLT }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"dbl", "64-bit double", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_DBL }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
{NULL},
};
@@ -476,40 +536,43 @@ static const AVOption options[]={
#undef D
#undef DEFAULT
-static const AVClass av_codec_context_class = { "AVCodecContext", context_to_name, options, LIBAVUTIL_VERSION_INT, OFFSET(log_level_offset), .opt_find = opt_find};
+static const AVClass av_codec_context_class = {
+ .class_name = "AVCodecContext",
+ .item_name = context_to_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+ .log_level_offset_offset = OFFSET(log_level_offset),
+ .child_next = codec_child_next,
+ .child_class_next = codec_child_class_next,
+};
+#if FF_API_ALLOC_CONTEXT
void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){
- int flags=0;
- memset(s, 0, sizeof(AVCodecContext));
-
- s->av_class= &av_codec_context_class;
-
+ avcodec_get_context_defaults3(s, NULL);
s->codec_type = codec_type;
- if(codec_type == AVMEDIA_TYPE_AUDIO)
- flags= AV_OPT_FLAG_AUDIO_PARAM;
- else if(codec_type == AVMEDIA_TYPE_VIDEO)
- flags= AV_OPT_FLAG_VIDEO_PARAM;
- else if(codec_type == AVMEDIA_TYPE_SUBTITLE)
- flags= AV_OPT_FLAG_SUBTITLE_PARAM;
- av_opt_set_defaults2(s, flags, flags);
-
- s->time_base= (AVRational){0,1};
- s->get_buffer= avcodec_default_get_buffer;
- s->release_buffer= avcodec_default_release_buffer;
- s->get_format= avcodec_default_get_format;
- s->execute= avcodec_default_execute;
- s->execute2= avcodec_default_execute2;
- s->sample_aspect_ratio= (AVRational){0,1};
- s->pix_fmt= PIX_FMT_NONE;
- s->sample_fmt= AV_SAMPLE_FMT_NONE;
-
- s->palctrl = NULL;
- s->reget_buffer= avcodec_default_reget_buffer;
- s->reordered_opaque= AV_NOPTS_VALUE;
}
+#endif
int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){
- avcodec_get_context_defaults2(s, codec ? codec->type : AVMEDIA_TYPE_UNKNOWN);
+ memset(s, 0, sizeof(AVCodecContext));
+
+ s->av_class = &av_codec_context_class;
+
+ s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN;
+ av_opt_set_defaults(s);
+
+ s->time_base = (AVRational){0,1};
+ s->get_buffer = avcodec_default_get_buffer;
+ s->release_buffer = avcodec_default_release_buffer;
+ s->get_format = avcodec_default_get_format;
+ s->execute = avcodec_default_execute;
+ s->execute2 = avcodec_default_execute2;
+ s->sample_aspect_ratio = (AVRational){0,1};
+ s->pix_fmt = PIX_FMT_NONE;
+ s->sample_fmt = AV_SAMPLE_FMT_NONE;
+
+ s->reget_buffer = avcodec_default_reget_buffer;
+ s->reordered_opaque = AV_NOPTS_VALUE;
if(codec && codec->priv_data_size){
if(!s->priv_data){
s->priv_data= av_mallocz(codec->priv_data_size);
@@ -518,10 +581,19 @@ int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){
}
}
if(codec->priv_class){
- *(AVClass**)s->priv_data= codec->priv_class;
+ *(const AVClass**)s->priv_data = codec->priv_class;
av_opt_set_defaults(s->priv_data);
}
}
+ if (codec && codec->defaults) {
+ int ret;
+ const AVCodecDefault *d = codec->defaults;
+ while (d->key) {
+ ret = av_opt_set(s, d->key, d->value, 0);
+ av_assert0(ret >= 0);
+ d++;
+ }
+ }
return 0;
}
@@ -538,6 +610,7 @@ AVCodecContext *avcodec_alloc_context3(AVCodec *codec){
return avctx;
}
+#if FF_API_ALLOC_CONTEXT
AVCodecContext *avcodec_alloc_context2(enum AVMediaType codec_type){
AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));
@@ -555,6 +628,7 @@ void avcodec_get_context_defaults(AVCodecContext *s){
AVCodecContext *avcodec_alloc_context(void){
return avcodec_alloc_context2(AVMEDIA_TYPE_UNKNOWN);
}
+#endif
int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)
{
@@ -569,11 +643,10 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)
/* set values specific to opened codecs back to their default state */
dest->priv_data = NULL;
dest->codec = NULL;
- dest->palctrl = NULL;
dest->slice_offset = NULL;
- dest->internal_buffer = NULL;
dest->hwaccel = NULL;
dest->thread_opaque = NULL;
+ dest->internal = NULL;
/* reallocate values that should be allocated separately */
dest->rc_eq = NULL;
@@ -613,3 +686,8 @@ fail:
av_freep(&dest->rc_eq);
return AVERROR(ENOMEM);
}
+
+const AVClass *avcodec_get_class(void)
+{
+ return &av_codec_context_class;
+}
diff --git a/libavcodec/pamenc.c b/libavcodec/pamenc.c
index fbf9fd8..10960d5 100644
--- a/libavcodec/pamenc.c
+++ b/libavcodec/pamenc.c
@@ -109,12 +109,12 @@ static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf,
AVCodec ff_pam_encoder = {
- "pam",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PAM,
- sizeof(PNMContext),
- ff_pnm_init,
- pam_encode_frame,
+ .name = "pam",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PAM,
+ .priv_data_size = sizeof(PNMContext),
+ .init = ff_pnm_init,
+ .encode = pam_encode_frame,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
};
diff --git a/libavcodec/parser.c b/libavcodec/parser.c
index 03f548e..9fd7af6 100644
--- a/libavcodec/parser.c
+++ b/libavcodec/parser.c
@@ -216,7 +216,7 @@ void av_parser_close(AVCodecParserContext *s)
/*****************************************************/
/**
- * combines the (truncated) bitstream to a complete frame
+ * Combine the (truncated) bitstream to a complete frame.
* @return -1 if no complete frame could be created, AVERROR(ENOMEM) if there was a memory allocation error
*/
int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size)
diff --git a/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c
index a55d48c..9ab6fc3 100644
--- a/libavcodec/pcm-mpeg.c
+++ b/libavcodec/pcm-mpeg.c
@@ -119,17 +119,30 @@ static int pcm_bluray_parse_header(AVCodecContext *avctx,
return 0;
}
-static int pcm_bluray_decode_frame(AVCodecContext *avctx,
- void *data,
- int *data_size,
- AVPacket *avpkt)
+typedef struct PCMBRDecode {
+ AVFrame frame;
+} PCMBRDecode;
+
+static av_cold int pcm_bluray_decode_init(AVCodecContext * avctx)
+{
+ PCMBRDecode *s = avctx->priv_data;
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
+ return 0;
+}
+
+static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *src = avpkt->data;
int buf_size = avpkt->size;
+ PCMBRDecode *s = avctx->priv_data;
int num_source_channels, channel, retval;
- int sample_size, samples, output_size;
- int16_t *dst16 = data;
- int32_t *dst32 = data;
+ int sample_size, samples;
+ int16_t *dst16;
+ int32_t *dst32;
if (buf_size < 4) {
av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n");
@@ -146,15 +159,14 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx,
sample_size = (num_source_channels * avctx->bits_per_coded_sample) >> 3;
samples = buf_size / sample_size;
- output_size = samples * avctx->channels *
- (avctx->sample_fmt == AV_SAMPLE_FMT_S32 ? 4 : 2);
- if (output_size > *data_size) {
- av_log(avctx, AV_LOG_ERROR,
- "Insufficient output buffer space (%d bytes, needed %d bytes)\n",
- *data_size, output_size);
- return -1;
+ /* get output buffer */
+ s->frame.nb_samples = samples;
+ if ((retval = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return retval;
}
- *data_size = output_size;
+ dst16 = (int16_t *)s->frame.data[0];
+ dst32 = (int32_t *)s->frame.data[0];
if (samples) {
switch (avctx->channel_layout) {
@@ -165,7 +177,7 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx,
samples *= num_source_channels;
if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
#if HAVE_BIGENDIAN
- memcpy(dst16, src, output_size);
+ memcpy(dst16, src, buf_size);
#else
do {
*dst16++ = bytestream_get_be16(&src);
@@ -289,22 +301,24 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx,
}
}
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
retval = src - avpkt->data;
if (avctx->debug & FF_DEBUG_BITSTREAM)
av_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n",
- retval, *data_size);
+ retval, buf_size);
return retval;
}
AVCodec ff_pcm_bluray_decoder = {
- "pcm_bluray",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_PCM_BLURAY,
- 0,
- NULL,
- NULL,
- NULL,
- pcm_bluray_decode_frame,
+ .name = "pcm_bluray",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_PCM_BLURAY,
+ .priv_data_size = sizeof(PCMBRDecode),
+ .init = pcm_bluray_decode_init,
+ .decode = pcm_bluray_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"),
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index 9100646..76d5c10 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -95,11 +95,6 @@ static int pcm_encode_frame(AVCodecContext *avctx,
samples = data;
dst = frame;
- if (avctx->sample_fmt!=avctx->codec->sample_fmts[0]) {
- av_log(avctx, AV_LOG_ERROR, "invalid sample_fmt\n");
- return -1;
- }
-
switch(avctx->codec->id) {
case CODEC_ID_PCM_U32LE:
ENCODE(uint32_t, le32, samples, dst, n, 0, 0x80000000)
@@ -176,14 +171,6 @@ static int pcm_encode_frame(AVCodecContext *avctx,
memcpy(dst, samples, n*sample_size);
dst += n*sample_size;
break;
- case CODEC_ID_PCM_ZORK:
- for(;n>0;n--) {
- v= *samples++ >> 8;
- if(v<0) v = -v;
- else v+= 128;
- *dst++ = v;
- }
- break;
case CODEC_ID_PCM_ALAW:
for(;n>0;n--) {
v = *samples++;
@@ -205,6 +192,7 @@ static int pcm_encode_frame(AVCodecContext *avctx,
}
typedef struct PCMDecode {
+ AVFrame frame;
short table[256];
} PCMDecode;
@@ -213,6 +201,11 @@ static av_cold int pcm_decode_init(AVCodecContext * avctx)
PCMDecode *s = avctx->priv_data;
int i;
+ if (avctx->channels <= 0 || avctx->channels > MAX_CHANNELS) {
+ av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n");
+ return AVERROR(EINVAL);
+ }
+
switch(avctx->codec->id) {
case CODEC_ID_PCM_ALAW:
for(i=0;i<256;i++)
@@ -231,12 +224,15 @@ static av_cold int pcm_decode_init(AVCodecContext * avctx)
if (avctx->sample_fmt == AV_SAMPLE_FMT_S32)
avctx->bits_per_raw_sample = av_get_bits_per_sample(avctx->codec->id);
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
/**
* Read PCM samples macro
- * @param type Datatype of native machine format
+ * @param size Data size of native machine format
* @param endian bytestream_get_xxx() endian suffix
* @param src Source pointer (variable name)
* @param dst Destination pointer (variable name)
@@ -244,53 +240,41 @@ static av_cold int pcm_decode_init(AVCodecContext * avctx)
* @param shift Bitshift (bits)
* @param offset Sample value offset
*/
-#define DECODE(type, endian, src, dst, n, shift, offset) \
- dst_##type = (type*)dst; \
+#define DECODE(size, endian, src, dst, n, shift, offset) \
for(;n>0;n--) { \
- register type v = bytestream_get_##endian(&src); \
- *dst_##type++ = (v - offset) << shift; \
- } \
- dst = (short*)dst_##type;
-
-static int pcm_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+ uint##size##_t v = bytestream_get_##endian(&src); \
+ AV_WN##size##A(dst, (v - offset) << shift); \
+ dst += size / 8; \
+ }
+
+static int pcm_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
+ const uint8_t *src = avpkt->data;
int buf_size = avpkt->size;
PCMDecode *s = avctx->priv_data;
- int sample_size, c, n, i;
- short *samples;
- const uint8_t *src, *src8, *src2[MAX_CHANNELS];
- uint8_t *dstu8;
- int16_t *dst_int16_t;
+ int sample_size, c, n, ret, samples_per_block;
+ uint8_t *samples;
int32_t *dst_int32_t;
- int64_t *dst_int64_t;
- uint16_t *dst_uint16_t;
- uint32_t *dst_uint32_t;
-
- samples = data;
- src = buf;
-
- if (avctx->sample_fmt!=avctx->codec->sample_fmts[0]) {
- av_log(avctx, AV_LOG_ERROR, "invalid sample_fmt\n");
- return -1;
- }
-
- if(avctx->channels <= 0 || avctx->channels > MAX_CHANNELS){
- av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n");
- return -1;
- }
sample_size = av_get_bits_per_sample(avctx->codec_id)/8;
/* av_get_bits_per_sample returns 0 for CODEC_ID_PCM_DVD */
- if (CODEC_ID_PCM_DVD == avctx->codec_id)
+ samples_per_block = 1;
+ if (CODEC_ID_PCM_DVD == avctx->codec_id) {
+ if (avctx->bits_per_coded_sample != 20 &&
+ avctx->bits_per_coded_sample != 24) {
+ av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n");
+ return AVERROR(EINVAL);
+ }
/* 2 samples are interleaved per block in PCM_DVD */
+ samples_per_block = 2;
sample_size = avctx->bits_per_coded_sample * 2 / 8;
- else if (avctx->codec_id == CODEC_ID_PCM_LXF)
+ } else if (avctx->codec_id == CODEC_ID_PCM_LXF) {
/* we process 40-bit blocks per channel for LXF */
+ samples_per_block = 2;
sample_size = 5;
+ }
if (sample_size == 0) {
av_log(avctx, AV_LOG_ERROR, "Invalid sample_size\n");
@@ -307,70 +291,78 @@ static int pcm_decode_frame(AVCodecContext *avctx,
buf_size -= buf_size % n;
}
- buf_size= FFMIN(buf_size, *data_size/2);
- *data_size=0;
-
n = buf_size/sample_size;
+ /* get output buffer */
+ s->frame.nb_samples = n * samples_per_block / avctx->channels;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = s->frame.data[0];
+
switch(avctx->codec->id) {
case CODEC_ID_PCM_U32LE:
- DECODE(uint32_t, le32, src, samples, n, 0, 0x80000000)
+ DECODE(32, le32, src, samples, n, 0, 0x80000000)
break;
case CODEC_ID_PCM_U32BE:
- DECODE(uint32_t, be32, src, samples, n, 0, 0x80000000)
+ DECODE(32, be32, src, samples, n, 0, 0x80000000)
break;
case CODEC_ID_PCM_S24LE:
- DECODE(int32_t, le24, src, samples, n, 8, 0)
+ DECODE(32, le24, src, samples, n, 8, 0)
break;
case CODEC_ID_PCM_S24BE:
- DECODE(int32_t, be24, src, samples, n, 8, 0)
+ DECODE(32, be24, src, samples, n, 8, 0)
break;
case CODEC_ID_PCM_U24LE:
- DECODE(uint32_t, le24, src, samples, n, 8, 0x800000)
+ DECODE(32, le24, src, samples, n, 8, 0x800000)
break;
case CODEC_ID_PCM_U24BE:
- DECODE(uint32_t, be24, src, samples, n, 8, 0x800000)
+ DECODE(32, be24, src, samples, n, 8, 0x800000)
break;
case CODEC_ID_PCM_S24DAUD:
for(;n>0;n--) {
uint32_t v = bytestream_get_be24(&src);
v >>= 4; // sync flags are here
- *samples++ = av_reverse[(v >> 8) & 0xff] +
- (av_reverse[v & 0xff] << 8);
+ AV_WN16A(samples, av_reverse[(v >> 8) & 0xff] +
+ (av_reverse[v & 0xff] << 8));
+ samples += 2;
}
break;
case CODEC_ID_PCM_S16LE_PLANAR:
+ {
+ const uint8_t *src2[MAX_CHANNELS];
n /= avctx->channels;
for(c=0;c<avctx->channels;c++)
src2[c] = &src[c*n*2];
for(;n>0;n--)
- for(c=0;c<avctx->channels;c++)
- *samples++ = bytestream_get_le16(&src2[c]);
- src = src2[avctx->channels-1];
+ for(c=0;c<avctx->channels;c++) {
+ AV_WN16A(samples, bytestream_get_le16(&src2[c]));
+ samples += 2;
+ }
break;
+ }
case CODEC_ID_PCM_U16LE:
- DECODE(uint16_t, le16, src, samples, n, 0, 0x8000)
+ DECODE(16, le16, src, samples, n, 0, 0x8000)
break;
case CODEC_ID_PCM_U16BE:
- DECODE(uint16_t, be16, src, samples, n, 0, 0x8000)
+ DECODE(16, be16, src, samples, n, 0, 0x8000)
break;
case CODEC_ID_PCM_S8:
- dstu8= (uint8_t*)samples;
for(;n>0;n--) {
- *dstu8++ = *src++ + 128;
+ *samples++ = *src++ + 128;
}
- samples= (short*)dstu8;
break;
#if HAVE_BIGENDIAN
case CODEC_ID_PCM_F64LE:
- DECODE(int64_t, le64, src, samples, n, 0, 0)
+ DECODE(64, le64, src, samples, n, 0, 0)
break;
case CODEC_ID_PCM_S32LE:
case CODEC_ID_PCM_F32LE:
- DECODE(int32_t, le32, src, samples, n, 0, 0)
+ DECODE(32, le32, src, samples, n, 0, 0)
break;
case CODEC_ID_PCM_S16LE:
- DECODE(int16_t, le16, src, samples, n, 0, 0)
+ DECODE(16, le16, src, samples, n, 0, 0)
break;
case CODEC_ID_PCM_F64BE:
case CODEC_ID_PCM_F32BE:
@@ -378,14 +370,14 @@ static int pcm_decode_frame(AVCodecContext *avctx,
case CODEC_ID_PCM_S16BE:
#else
case CODEC_ID_PCM_F64BE:
- DECODE(int64_t, be64, src, samples, n, 0, 0)
+ DECODE(64, be64, src, samples, n, 0, 0)
break;
case CODEC_ID_PCM_F32BE:
case CODEC_ID_PCM_S32BE:
- DECODE(int32_t, be32, src, samples, n, 0, 0)
+ DECODE(32, be32, src, samples, n, 0, 0)
break;
case CODEC_ID_PCM_S16BE:
- DECODE(int16_t, be16, src, samples, n, 0, 0)
+ DECODE(16, be16, src, samples, n, 0, 0)
break;
case CODEC_ID_PCM_F64LE:
case CODEC_ID_PCM_F32LE:
@@ -394,25 +386,26 @@ static int pcm_decode_frame(AVCodecContext *avctx,
#endif /* HAVE_BIGENDIAN */
case CODEC_ID_PCM_U8:
memcpy(samples, src, n*sample_size);
- src += n*sample_size;
- samples = (short*)((uint8_t*)data + n*sample_size);
break;
case CODEC_ID_PCM_ZORK:
- for(;n>0;n--) {
- int x= *src++;
- if(x&128) x-= 128;
- else x = -x;
- *samples++ = x << 8;
+ for (; n > 0; n--) {
+ int v = *src++;
+ if (v < 128)
+ v = 128 - v;
+ *samples++ = v;
}
break;
case CODEC_ID_PCM_ALAW:
case CODEC_ID_PCM_MULAW:
for(;n>0;n--) {
- *samples++ = s->table[*src++];
+ AV_WN16A(samples, s->table[*src++]);
+ samples += 2;
}
break;
case CODEC_ID_PCM_DVD:
- dst_int32_t = data;
+ {
+ const uint8_t *src8;
+ dst_int32_t = (int32_t *)s->frame.data[0];
n /= avctx->channels;
switch (avctx->bits_per_coded_sample) {
case 20:
@@ -437,15 +430,14 @@ static int pcm_decode_frame(AVCodecContext *avctx,
src = src8;
}
break;
- default:
- av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n");
- return -1;
- break;
}
- samples = (short *) dst_int32_t;
break;
+ }
case CODEC_ID_PCM_LXF:
- dst_int32_t = data;
+ {
+ int i;
+ const uint8_t *src8;
+ dst_int32_t = (int32_t *)s->frame.data[0];
n /= avctx->channels;
//unpack and de-planerize
for (i = 0; i < n; i++) {
@@ -461,14 +453,16 @@ static int pcm_decode_frame(AVCodecContext *avctx,
((src8[2] & 0xF0) << 8) | (src8[4] << 4) | (src8[3] >> 4);
}
}
- src += n * avctx->channels * 5;
- samples = (short *) dst_int32_t;
break;
+ }
default:
return -1;
}
- *data_size = (uint8_t *)samples - (uint8_t *)data;
- return src - buf;
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
+ return buf_size;
}
#if CONFIG_ENCODERS
@@ -496,6 +490,7 @@ AVCodec ff_ ## name_ ## _decoder = { \
.priv_data_size = sizeof(PCMDecode), \
.init = pcm_decode_init, \
.decode = pcm_decode_frame, \
+ .capabilities = CODEC_CAP_DR1, \
.sample_fmts = (const enum AVSampleFormat[]){sample_fmt_,AV_SAMPLE_FMT_NONE}, \
.long_name = NULL_IF_CONFIG_SMALL(long_name_), \
}
@@ -531,4 +526,4 @@ PCM_CODEC (CODEC_ID_PCM_U24BE, AV_SAMPLE_FMT_S32, pcm_u24be, "PCM unsigned 24-b
PCM_CODEC (CODEC_ID_PCM_U24LE, AV_SAMPLE_FMT_S32, pcm_u24le, "PCM unsigned 24-bit little-endian");
PCM_CODEC (CODEC_ID_PCM_U32BE, AV_SAMPLE_FMT_S32, pcm_u32be, "PCM unsigned 32-bit big-endian");
PCM_CODEC (CODEC_ID_PCM_U32LE, AV_SAMPLE_FMT_S32, pcm_u32le, "PCM unsigned 32-bit little-endian");
-PCM_CODEC (CODEC_ID_PCM_ZORK, AV_SAMPLE_FMT_S16, pcm_zork, "PCM Zork");
+PCM_DECODER(CODEC_ID_PCM_ZORK, AV_SAMPLE_FMT_U8, pcm_zork, "PCM Zork");
diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c
index 35f85f9..7eb1daa 100644
--- a/libavcodec/pcx.c
+++ b/libavcodec/pcx.c
@@ -248,15 +248,13 @@ static av_cold int pcx_end(AVCodecContext *avctx) {
}
AVCodec ff_pcx_decoder = {
- "pcx",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PCX,
- sizeof(PCXContext),
- pcx_init,
- NULL,
- pcx_end,
- pcx_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "pcx",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PCX,
+ .priv_data_size = sizeof(PCXContext),
+ .init = pcx_init,
+ .close = pcx_end,
+ .decode = pcx_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
};
diff --git a/libavcodec/pcxenc.c b/libavcodec/pcxenc.c
index 81629d0..3084568 100644
--- a/libavcodec/pcxenc.c
+++ b/libavcodec/pcxenc.c
@@ -20,10 +20,10 @@
*/
/**
- * PCX image encoder
* @file
+ * PCX image encoder
* @author Daniel Verkamp
- * @sa http://www.qzx.com/pc-gpe/pcx.txt
+ * @see http://www.qzx.com/pc-gpe/pcx.txt
*/
#include "avcodec.h"
@@ -190,13 +190,12 @@ static int pcx_encode_frame(AVCodecContext *avctx,
}
AVCodec ff_pcx_encoder = {
- "pcx",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PCX,
- sizeof(PCXContext),
- pcx_encode_init,
- pcx_encode_frame,
- NULL,
+ .name = "pcx",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PCX,
+ .priv_data_size = sizeof(PCXContext),
+ .init = pcx_encode_init,
+ .encode = pcx_encode_frame,
.pix_fmts = (const enum PixelFormat[]){
PIX_FMT_RGB24,
PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, PIX_FMT_GRAY8, PIX_FMT_PAL8,
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index 9546c38..bcc47f3 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -198,7 +198,7 @@ static int parse_picture_segment(AVCodecContext *avctx,
/* Make sure the bitmap is not too large */
if (avctx->width < width || avctx->height < height) {
- av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger then video.\n");
+ av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger than video.\n");
return -1;
}
@@ -469,13 +469,12 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size,
}
AVCodec ff_pgssub_decoder = {
- "pgssub",
- AVMEDIA_TYPE_SUBTITLE,
- CODEC_ID_HDMV_PGS_SUBTITLE,
- sizeof(PGSSubContext),
- init_decoder,
- NULL,
- close_decoder,
- decode,
+ .name = "pgssub",
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = CODEC_ID_HDMV_PGS_SUBTITLE,
+ .priv_data_size = sizeof(PGSSubContext),
+ .init = init_decoder,
+ .close = close_decoder,
+ .decode = decode,
.long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"),
};
diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c
index 23f299c..732583e 100644
--- a/libavcodec/pictordec.c
+++ b/libavcodec/pictordec.c
@@ -238,14 +238,12 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_pictor_decoder = {
- "pictor",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PICTOR,
- sizeof(PicContext),
- NULL,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "pictor",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PICTOR,
+ .priv_data_size = sizeof(PicContext),
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"),
};
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 1268c9e..a40cebb 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -657,15 +657,13 @@ static av_cold int png_dec_end(AVCodecContext *avctx)
}
AVCodec ff_png_decoder = {
- "png",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PNG,
- sizeof(PNGDecContext),
- png_dec_init,
- NULL,
- png_dec_end,
- decode_frame,
- CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
- NULL,
+ .name = "png",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PNG,
+ .priv_data_size = sizeof(PNGDecContext),
+ .init = png_dec_init,
+ .close = png_dec_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
.long_name = NULL_IF_CONFIG_SMALL("PNG image"),
};
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index c2ac490..9325348 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -437,13 +437,12 @@ static av_cold int png_enc_init(AVCodecContext *avctx){
}
AVCodec ff_png_encoder = {
- "png",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PNG,
- sizeof(PNGEncContext),
- png_enc_init,
- encode_frame,
- NULL, //encode_end,
+ .name = "png",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PNG,
+ .priv_data_size = sizeof(PNGEncContext),
+ .init = png_enc_init,
+ .encode = encode_frame,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_MONOBLACK, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("PNG image"),
};
diff --git a/libavcodec/pnm_parser.c b/libavcodec/pnm_parser.c
index 2dc2987..89f9871 100644
--- a/libavcodec/pnm_parser.c
+++ b/libavcodec/pnm_parser.c
@@ -84,9 +84,9 @@ retry:
}
AVCodecParser ff_pnm_parser = {
- { CODEC_ID_PGM, CODEC_ID_PGMYUV, CODEC_ID_PPM, CODEC_ID_PBM, CODEC_ID_PAM},
- sizeof(ParseContext),
- NULL,
- pnm_parse,
- ff_parse_close,
+ .codec_ids = { CODEC_ID_PGM, CODEC_ID_PGMYUV, CODEC_ID_PPM,
+ CODEC_ID_PBM, CODEC_ID_PAM },
+ .priv_data_size = sizeof(ParseContext),
+ .parser_parse = pnm_parse,
+ .parser_close = ff_parse_close,
};
diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c
index 988ea0c..e0e9f66 100644
--- a/libavcodec/pnmdec.c
+++ b/libavcodec/pnmdec.c
@@ -189,15 +189,14 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
#if CONFIG_PGM_DECODER
AVCodec ff_pgm_decoder = {
- "pgm",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PGM,
- sizeof(PNMContext),
- ff_pnm_init,
- NULL,
- ff_pnm_end,
- pnm_decode_frame,
- CODEC_CAP_DR1,
+ .name = "pgm",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PGM,
+ .priv_data_size = sizeof(PNMContext),
+ .init = ff_pnm_init,
+ .close = ff_pnm_end,
+ .decode = pnm_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_GRAY8, PIX_FMT_GRAY16BE, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
};
@@ -205,15 +204,14 @@ AVCodec ff_pgm_decoder = {
#if CONFIG_PGMYUV_DECODER
AVCodec ff_pgmyuv_decoder = {
- "pgmyuv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PGMYUV,
- sizeof(PNMContext),
- ff_pnm_init,
- NULL,
- ff_pnm_end,
- pnm_decode_frame,
- CODEC_CAP_DR1,
+ .name = "pgmyuv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PGMYUV,
+ .priv_data_size = sizeof(PNMContext),
+ .init = ff_pnm_init,
+ .close = ff_pnm_end,
+ .decode = pnm_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
};
@@ -221,15 +219,14 @@ AVCodec ff_pgmyuv_decoder = {
#if CONFIG_PPM_DECODER
AVCodec ff_ppm_decoder = {
- "ppm",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PPM,
- sizeof(PNMContext),
- ff_pnm_init,
- NULL,
- ff_pnm_end,
- pnm_decode_frame,
- CODEC_CAP_DR1,
+ .name = "ppm",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PPM,
+ .priv_data_size = sizeof(PNMContext),
+ .init = ff_pnm_init,
+ .close = ff_pnm_end,
+ .decode = pnm_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB48BE, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
};
@@ -237,15 +234,14 @@ AVCodec ff_ppm_decoder = {
#if CONFIG_PBM_DECODER
AVCodec ff_pbm_decoder = {
- "pbm",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PBM,
- sizeof(PNMContext),
- ff_pnm_init,
- NULL,
- ff_pnm_end,
- pnm_decode_frame,
- CODEC_CAP_DR1,
+ .name = "pbm",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PBM,
+ .priv_data_size = sizeof(PNMContext),
+ .init = ff_pnm_init,
+ .close = ff_pnm_end,
+ .decode = pnm_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_MONOWHITE, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
};
@@ -253,15 +249,14 @@ AVCodec ff_pbm_decoder = {
#if CONFIG_PAM_DECODER
AVCodec ff_pam_decoder = {
- "pam",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PAM,
- sizeof(PNMContext),
- ff_pnm_init,
- NULL,
- ff_pnm_end,
- pnm_decode_frame,
- CODEC_CAP_DR1,
+ .name = "pam",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PAM,
+ .priv_data_size = sizeof(PNMContext),
+ .init = ff_pnm_init,
+ .close = ff_pnm_end,
+ .decode = pnm_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
};
diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c
index 57cb90c..a27a278 100644
--- a/libavcodec/pnmenc.c
+++ b/libavcodec/pnmenc.c
@@ -114,12 +114,12 @@ static int pnm_encode_frame(AVCodecContext *avctx, unsigned char *outbuf,
#if CONFIG_PGM_ENCODER
AVCodec ff_pgm_encoder = {
- "pgm",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PGM,
- sizeof(PNMContext),
- ff_pnm_init,
- pnm_encode_frame,
+ .name = "pgm",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PGM,
+ .priv_data_size = sizeof(PNMContext),
+ .init = ff_pnm_init,
+ .encode = pnm_encode_frame,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_GRAY8, PIX_FMT_GRAY16BE, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
};
@@ -127,12 +127,12 @@ AVCodec ff_pgm_encoder = {
#if CONFIG_PGMYUV_ENCODER
AVCodec ff_pgmyuv_encoder = {
- "pgmyuv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PGMYUV,
- sizeof(PNMContext),
- ff_pnm_init,
- pnm_encode_frame,
+ .name = "pgmyuv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PGMYUV,
+ .priv_data_size = sizeof(PNMContext),
+ .init = ff_pnm_init,
+ .encode = pnm_encode_frame,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
};
@@ -140,12 +140,12 @@ AVCodec ff_pgmyuv_encoder = {
#if CONFIG_PPM_ENCODER
AVCodec ff_ppm_encoder = {
- "ppm",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PPM,
- sizeof(PNMContext),
- ff_pnm_init,
- pnm_encode_frame,
+ .name = "ppm",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PPM,
+ .priv_data_size = sizeof(PNMContext),
+ .init = ff_pnm_init,
+ .encode = pnm_encode_frame,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB48BE, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
};
@@ -153,12 +153,12 @@ AVCodec ff_ppm_encoder = {
#if CONFIG_PBM_ENCODER
AVCodec ff_pbm_encoder = {
- "pbm",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PBM,
- sizeof(PNMContext),
- ff_pnm_init,
- pnm_encode_frame,
+ .name = "pbm",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PBM,
+ .priv_data_size = sizeof(PNMContext),
+ .init = ff_pnm_init,
+ .encode = pnm_encode_frame,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_MONOWHITE, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
};
diff --git a/libavcodec/ppc/dsputil_altivec.c b/libavcodec/ppc/dsputil_altivec.c
index adce61b..7ab5336 100644
--- a/libavcodec/ppc/dsputil_altivec.c
+++ b/libavcodec/ppc/dsputil_altivec.c
@@ -627,16 +627,6 @@ void put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size,
// it's faster than -funroll-loops, but using
// -funroll-loops w/ this is bad - 74 cycles again.
// all this is on a 7450, tuning for the 7450
-#if 0
- for (i = 0; i < h; i++) {
- pixelsv1 = vec_ld(0, pixels);
- pixelsv2 = vec_ld(16, pixels);
- vec_st(vec_perm(pixelsv1, pixelsv2, perm),
- 0, block);
- pixels+=line_size;
- block +=line_size;
- }
-#else
for (i = 0; i < h; i += 4) {
pixelsv1 = vec_ld( 0, pixels);
pixelsv2 = vec_ld(15, pixels);
@@ -657,7 +647,6 @@ void put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size,
pixels+=line_size_4;
block +=line_size_4;
}
-#endif
}
/* next one assumes that ((line_size % 16) == 0) */
@@ -1384,7 +1373,7 @@ static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int l
void dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx)
{
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
c->pix_abs[0][1] = sad16_x2_altivec;
c->pix_abs[0][2] = sad16_y2_altivec;
@@ -1398,11 +1387,10 @@ void dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx)
c->sse[0]= sse16_altivec;
c->pix_sum = pix_sum_altivec;
c->diff_pixels = diff_pixels_altivec;
- c->get_pixels = get_pixels_altivec;
- if (!high_bit_depth)
- c->clear_block = clear_block_altivec;
c->add_bytes= add_bytes_altivec;
if (!high_bit_depth) {
+ c->get_pixels = get_pixels_altivec;
+ c->clear_block = clear_block_altivec;
c->put_pixels_tab[0][0] = put_pixels16_altivec;
/* the two functions do the same thing, so use the same code */
c->put_no_rnd_pixels_tab[0][0] = put_pixels16_altivec;
diff --git a/libavcodec/ppc/dsputil_ppc.c b/libavcodec/ppc/dsputil_ppc.c
index 5f131f3..24b12ee 100644
--- a/libavcodec/ppc/dsputil_ppc.c
+++ b/libavcodec/ppc/dsputil_ppc.c
@@ -48,7 +48,6 @@ static void clear_blocks_dcbz32_ppc(DCTELEM *blocks)
{
register int misal = ((unsigned long)blocks & 0x00000010);
register int i = 0;
-#if 1
if (misal) {
((unsigned long*)blocks)[0] = 0L;
((unsigned long*)blocks)[1] = 0L;
@@ -66,9 +65,6 @@ static void clear_blocks_dcbz32_ppc(DCTELEM *blocks)
((unsigned long*)blocks)[191] = 0L;
i += 16;
}
-#else
- memset(blocks, 0, sizeof(DCTELEM)*6*64);
-#endif
}
/* same as above, when dcbzl clear a whole 128B cache line
@@ -78,7 +74,6 @@ static void clear_blocks_dcbz128_ppc(DCTELEM *blocks)
{
register int misal = ((unsigned long)blocks & 0x0000007f);
register int i = 0;
-#if 1
if (misal) {
// we could probably also optimize this case,
// but there's not much point as the machines
@@ -89,9 +84,6 @@ static void clear_blocks_dcbz128_ppc(DCTELEM *blocks)
for ( ; i < sizeof(DCTELEM)*6*64 ; i += 128) {
__asm__ volatile("dcbzl %0,%1" : : "b" (blocks), "r" (i) : "memory");
}
-#else
- memset(blocks, 0, sizeof(DCTELEM)*6*64);
-#endif
}
#else
static void clear_blocks_dcbz128_ppc(DCTELEM *blocks)
@@ -153,7 +145,7 @@ static void prefetch_ppc(void *mem, int stride, int h)
void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx)
{
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
// Common optimizations whether AltiVec is available or not
c->prefetch = prefetch_ppc;
@@ -180,13 +172,14 @@ void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx)
c->gmc1 = gmc1_altivec;
#if CONFIG_ENCODERS
- if (avctx->dct_algo == FF_DCT_AUTO ||
- avctx->dct_algo == FF_DCT_ALTIVEC) {
+ if (avctx->bits_per_raw_sample <= 8 &&
+ (avctx->dct_algo == FF_DCT_AUTO ||
+ avctx->dct_algo == FF_DCT_ALTIVEC)) {
c->fdct = fdct_altivec;
}
#endif //CONFIG_ENCODERS
- if (avctx->lowres==0) {
+ if (avctx->lowres == 0 && avctx->bits_per_raw_sample <= 8) {
if ((avctx->idct_algo == FF_IDCT_AUTO) ||
(avctx->idct_algo == FF_IDCT_ALTIVEC)) {
c->idct_put = idct_put_altivec;
diff --git a/libavcodec/ppc/fdct_altivec.c b/libavcodec/ppc/fdct_altivec.c
index 8dbfe33..2644c96 100644
--- a/libavcodec/ppc/fdct_altivec.c
+++ b/libavcodec/ppc/fdct_altivec.c
@@ -265,7 +265,6 @@ void fdct_altivec(int16_t *block)
* conversion to vector float. The following code section takes advantage
* of this.
*/
-#if 1
/* fdct rows {{{ */
x0 = ((vector float)vec_add(vs16(b00), vs16(b70)));
x7 = ((vector float)vec_sub(vs16(b00), vs16(b70)));
@@ -389,29 +388,6 @@ void fdct_altivec(int16_t *block)
b31 = vec_add(b31, x2);
b11 = vec_add(b11, x3);
/* }}} */
-#else
- /* convert to float {{{ */
-#define CTF(n) \
- vs32(b##n##1) = vec_unpackl(vs16(b##n##0)); \
- vs32(b##n##0) = vec_unpackh(vs16(b##n##0)); \
- b##n##1 = vec_ctf(vs32(b##n##1), 0); \
- b##n##0 = vec_ctf(vs32(b##n##0), 0); \
-
- CTF(0);
- CTF(1);
- CTF(2);
- CTF(3);
- CTF(4);
- CTF(5);
- CTF(6);
- CTF(7);
-
-#undef CTF
- /* }}} */
-
- FDCTROW(b00, b10, b20, b30, b40, b50, b60, b70);
- FDCTROW(b01, b11, b21, b31, b41, b51, b61, b71);
-#endif
/* 8x8 matrix transpose (vector float[8][2]) {{{ */
diff --git a/libavcodec/ppc/fft_altivec.c b/libavcodec/ppc/fft_altivec.c
index 435024a..39830b2 100644
--- a/libavcodec/ppc/fft_altivec.c
+++ b/libavcodec/ppc/fft_altivec.c
@@ -141,7 +141,9 @@ av_cold void ff_fft_init_altivec(FFTContext *s)
{
#if HAVE_GNU_AS
s->fft_calc = ff_fft_calc_interleave_altivec;
- s->imdct_calc = ff_imdct_calc_altivec;
- s->imdct_half = ff_imdct_half_altivec;
+ if (s->mdct_bits >= 5) {
+ s->imdct_calc = ff_imdct_calc_altivec;
+ s->imdct_half = ff_imdct_half_altivec;
+ }
#endif
}
diff --git a/libavcodec/ppc/h264_altivec.c b/libavcodec/ppc/h264_altivec.c
index 05fae83..c8baee4 100644
--- a/libavcodec/ppc/h264_altivec.c
+++ b/libavcodec/ppc/h264_altivec.c
@@ -616,8 +616,8 @@ static inline void write16x4(uint8_t *dst, int dst_stride,
*(dst_int+15*int_dst_stride) = *(src_int + 15);
}
-/** \brief performs a 6x16 transpose of data in src, and stores it to dst
- \todo FIXME: see if we can't spare some vec_lvsl() by them factorizing
+/** @brief performs a 6x16 transpose of data in src, and stores it to dst
+ @todo FIXME: see if we can't spare some vec_lvsl() by them factorizing
out of unaligned_load() */
#define readAndTranspose16x6(src, src_stride, r8, r9, r10, r11, r12, r13) {\
register vec_u8 r0 = unaligned_load(0, src); \
@@ -843,7 +843,8 @@ static void h264_h_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha,
}
static av_always_inline
-void weight_h264_WxH_altivec(uint8_t *block, int stride, int log2_denom, int weight, int offset, int w, int h)
+void weight_h264_W_altivec(uint8_t *block, int stride, int height,
+ int log2_denom, int weight, int offset, int w)
{
int y, aligned;
vec_u8 vblock;
@@ -864,7 +865,7 @@ void weight_h264_WxH_altivec(uint8_t *block, int stride, int log2_denom, int wei
voffset = vec_splat(vtemp, 5);
aligned = !((unsigned long)block & 0xf);
- for (y=0; y<h; y++) {
+ for (y = 0; y < height; y++) {
vblock = vec_ld(0, block);
v0 = (vec_s16)vec_mergeh(zero_u8v, vblock);
@@ -888,8 +889,8 @@ void weight_h264_WxH_altivec(uint8_t *block, int stride, int log2_denom, int wei
}
static av_always_inline
-void biweight_h264_WxH_altivec(uint8_t *dst, uint8_t *src, int stride, int log2_denom,
- int weightd, int weights, int offset, int w, int h)
+void biweight_h264_W_altivec(uint8_t *dst, uint8_t *src, int stride, int height,
+ int log2_denom, int weightd, int weights, int offset, int w)
{
int y, dst_aligned, src_aligned;
vec_u8 vsrc, vdst;
@@ -912,7 +913,7 @@ void biweight_h264_WxH_altivec(uint8_t *dst, uint8_t *src, int stride, int log2_
dst_aligned = !((unsigned long)dst & 0xf);
src_aligned = !((unsigned long)src & 0xf);
- for (y=0; y<h; y++) {
+ for (y = 0; y < height; y++) {
vdst = vec_ld(0, dst);
vsrc = vec_ld(0, src);
@@ -952,22 +953,21 @@ void biweight_h264_WxH_altivec(uint8_t *dst, uint8_t *src, int stride, int log2_
}
}
-#define H264_WEIGHT(W,H) \
-static void ff_weight_h264_pixels ## W ## x ## H ## _altivec(uint8_t *block, int stride, int log2_denom, int weight, int offset){ \
- weight_h264_WxH_altivec(block, stride, log2_denom, weight, offset, W, H); \
+#define H264_WEIGHT(W) \
+static void ff_weight_h264_pixels ## W ## _altivec(uint8_t *block, int stride, int height, \
+ int log2_denom, int weight, int offset){ \
+ weight_h264_W_altivec(block, stride, height, log2_denom, weight, offset, W); \
}\
-static void ff_biweight_h264_pixels ## W ## x ## H ## _altivec(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offset){ \
- biweight_h264_WxH_altivec(dst, src, stride, log2_denom, weightd, weights, offset, W, H); \
+static void ff_biweight_h264_pixels ## W ## _altivec(uint8_t *dst, uint8_t *src, int stride, int height, \
+ int log2_denom, int weightd, int weights, int offset){ \
+ biweight_h264_W_altivec(dst, src, stride, height, log2_denom, weightd, weights, offset, W); \
}
-H264_WEIGHT(16,16)
-H264_WEIGHT(16, 8)
-H264_WEIGHT( 8,16)
-H264_WEIGHT( 8, 8)
-H264_WEIGHT( 8, 4)
+H264_WEIGHT(16)
+H264_WEIGHT( 8)
void dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx) {
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
if (!high_bit_depth) {
@@ -999,12 +999,13 @@ void dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx) {
}
}
-void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth)
+void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
{
if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
if (bit_depth == 8) {
c->h264_idct_add = ff_h264_idct_add_altivec;
- c->h264_idct_add8 = ff_h264_idct_add8_altivec;
+ if (chroma_format_idc == 1)
+ c->h264_idct_add8 = ff_h264_idct_add8_altivec;
c->h264_idct_add16 = ff_h264_idct_add16_altivec;
c->h264_idct_add16intra = ff_h264_idct_add16intra_altivec;
c->h264_idct_dc_add= h264_idct_dc_add_altivec;
@@ -1014,16 +1015,10 @@ void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth)
c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_altivec;
c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_altivec;
- c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels16x16_altivec;
- c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels16x8_altivec;
- c->weight_h264_pixels_tab[2] = ff_weight_h264_pixels8x16_altivec;
- c->weight_h264_pixels_tab[3] = ff_weight_h264_pixels8x8_altivec;
- c->weight_h264_pixels_tab[4] = ff_weight_h264_pixels8x4_altivec;
- c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels16x16_altivec;
- c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels16x8_altivec;
- c->biweight_h264_pixels_tab[2] = ff_biweight_h264_pixels8x16_altivec;
- c->biweight_h264_pixels_tab[3] = ff_biweight_h264_pixels8x8_altivec;
- c->biweight_h264_pixels_tab[4] = ff_biweight_h264_pixels8x4_altivec;
+ c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels16_altivec;
+ c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels8_altivec;
+ c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels16_altivec;
+ c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels8_altivec;
}
}
}
diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c
index e02c094..2d3bf89 100644
--- a/libavcodec/ppc/mpegvideo_altivec.c
+++ b/libavcodec/ppc/mpegvideo_altivec.c
@@ -515,21 +515,6 @@ static void dct_unquantize_h263_altivec(MpegEncContext *s,
qaddv = vec_splat((vec_s16)vec_lde(0, &qadd8), 0);
nqaddv = vec_sub(vczero, qaddv);
-#if 0 // block *is* 16 bytes-aligned, it seems.
- // first make sure block[j] is 16 bytes-aligned
- for(j = 0; (j <= nCoeffs) && ((((unsigned long)block) + (j << 1)) & 0x0000000F) ; j++) {
- level = block[j];
- if (level) {
- if (level < 0) {
- level = level * qmul - qadd;
- } else {
- level = level * qmul + qadd;
- }
- block[j] = level;
- }
- }
-#endif
-
// vectorize all the 16 bytes-aligned blocks
// of 8 elements
for(; (j + 7) <= nCoeffs ; j+=8) {
@@ -573,15 +558,6 @@ void MPV_common_init_altivec(MpegEncContext *s)
{
if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return;
- if (s->avctx->lowres==0) {
- if ((s->avctx->idct_algo == FF_IDCT_AUTO) ||
- (s->avctx->idct_algo == FF_IDCT_ALTIVEC)) {
- s->dsp.idct_put = idct_put_altivec;
- s->dsp.idct_add = idct_add_altivec;
- s->dsp.idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
- }
- }
-
// Test to make sure that the dct required alignments are met.
if ((((long)(s->q_intra_matrix) & 0x0f) != 0) ||
(((long)(s->q_inter_matrix) & 0x0f) != 0)) {
@@ -599,9 +575,6 @@ void MPV_common_init_altivec(MpegEncContext *s)
if ((s->avctx->dct_algo == FF_DCT_AUTO) ||
(s->avctx->dct_algo == FF_DCT_ALTIVEC)) {
-#if 0 /* seems to cause trouble under some circumstances */
- s->dct_quantize = dct_quantize_altivec;
-#endif
s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec;
s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec;
}
diff --git a/libavcodec/ppc/util_altivec.h b/libavcodec/ppc/util_altivec.h
index e68e5b5..19ea962 100644
--- a/libavcodec/ppc/util_altivec.h
+++ b/libavcodec/ppc/util_altivec.h
@@ -94,7 +94,7 @@ do { \
} while (0)
-/** \brief loads unaligned vector \a *src with offset \a offset
+/** @brief loads unaligned vector @a *src with offset @a offset
and returns it */
static inline vector unsigned char unaligned_load(int offset, uint8_t *src)
{
diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c
new file mode 100644
index 0000000..031760c
--- /dev/null
+++ b/libavcodec/proresdec.c
@@ -0,0 +1,706 @@
+/*
+ * Apple ProRes compatible decoder
+ *
+ * Copyright (c) 2010-2011 Maxim Poliakovski
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * This is a decoder for Apple ProRes 422 SD/HQ/LT/Proxy and ProRes 4444.
+ * It is used for storing and editing high definition video data in Apple's Final Cut Pro.
+ *
+ * @see http://wiki.multimedia.cx/index.php?title=Apple_ProRes
+ */
+
+#define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once
+
+#include <stdint.h>
+
+#include "libavutil/intmath.h"
+#include "avcodec.h"
+#include "proresdsp.h"
+#include "get_bits.h"
+
+typedef struct {
+ const uint8_t *index; ///< pointers to the data of this slice
+ int slice_num;
+ int x_pos, y_pos;
+ int slice_width;
+ DECLARE_ALIGNED(16, DCTELEM, blocks[8 * 4 * 64]);
+} ProresThreadData;
+
+typedef struct {
+ ProresDSPContext dsp;
+ AVFrame picture;
+ ScanTable scantable;
+ int scantable_type; ///< -1 = uninitialized, 0 = progressive, 1/2 = interlaced
+
+ int frame_type; ///< 0 = progressive, 1 = top-field first, 2 = bottom-field first
+ int pic_format; ///< 2 = 422, 3 = 444
+ uint8_t qmat_luma[64]; ///< dequantization matrix for luma
+ uint8_t qmat_chroma[64]; ///< dequantization matrix for chroma
+ int qmat_changed; ///< 1 - global quantization matrices changed
+ int prev_slice_sf; ///< scalefactor of the previous decoded slice
+ DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled[64]);
+ DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled[64]);
+ int total_slices; ///< total number of slices in a picture
+ ProresThreadData *slice_data;
+ int pic_num;
+ int chroma_factor;
+ int mb_chroma_factor;
+ int num_chroma_blocks; ///< number of chrominance blocks in a macroblock
+ int num_x_slices;
+ int num_y_slices;
+ int slice_width_factor;
+ int slice_height_factor;
+ int num_x_mbs;
+ int num_y_mbs;
+ int alpha_info;
+} ProresContext;
+
+
+static const uint8_t progressive_scan[64] = {
+ 0, 1, 8, 9, 2, 3, 10, 11,
+ 16, 17, 24, 25, 18, 19, 26, 27,
+ 4, 5, 12, 20, 13, 6, 7, 14,
+ 21, 28, 29, 22, 15, 23, 30, 31,
+ 32, 33, 40, 48, 41, 34, 35, 42,
+ 49, 56, 57, 50, 43, 36, 37, 44,
+ 51, 58, 59, 52, 45, 38, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+static const uint8_t interlaced_scan[64] = {
+ 0, 8, 1, 9, 16, 24, 17, 25,
+ 2, 10, 3, 11, 18, 26, 19, 27,
+ 32, 40, 33, 34, 41, 48, 56, 49,
+ 42, 35, 43, 50, 57, 58, 51, 59,
+ 4, 12, 5, 6, 13, 20, 28, 21,
+ 14, 7, 15, 22, 29, 36, 44, 37,
+ 30, 23, 31, 38, 45, 52, 60, 53,
+ 46, 39, 47, 54, 61, 62, 55, 63
+};
+
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ ProresContext *ctx = avctx->priv_data;
+
+ ctx->total_slices = 0;
+ ctx->slice_data = NULL;
+
+ avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE;
+ ff_proresdsp_init(&ctx->dsp);
+
+ avctx->coded_frame = &ctx->picture;
+ avcodec_get_frame_defaults(&ctx->picture);
+ ctx->picture.type = AV_PICTURE_TYPE_I;
+ ctx->picture.key_frame = 1;
+
+ ctx->scantable_type = -1; // set scantable type to uninitialized
+ memset(ctx->qmat_luma, 4, 64);
+ memset(ctx->qmat_chroma, 4, 64);
+ ctx->prev_slice_sf = 0;
+
+ return 0;
+}
+
+
+static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
+ const int data_size, AVCodecContext *avctx)
+{
+ int hdr_size, version, width, height, flags;
+ const uint8_t *ptr;
+
+ hdr_size = AV_RB16(buf);
+ if (hdr_size > data_size) {
+ av_log(avctx, AV_LOG_ERROR, "frame data too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ version = AV_RB16(buf + 2);
+ if (version >= 2) {
+ av_log(avctx, AV_LOG_ERROR,
+ "unsupported header version: %d\n", version);
+ return AVERROR_INVALIDDATA;
+ }
+
+ width = AV_RB16(buf + 8);
+ height = AV_RB16(buf + 10);
+ if (width != avctx->width || height != avctx->height) {
+ av_log(avctx, AV_LOG_ERROR,
+ "picture dimension changed: old: %d x %d, new: %d x %d\n",
+ avctx->width, avctx->height, width, height);
+ return AVERROR_INVALIDDATA;
+ }
+
+ ctx->frame_type = (buf[12] >> 2) & 3;
+ if (ctx->frame_type > 2) {
+ av_log(avctx, AV_LOG_ERROR,
+ "unsupported frame type: %d\n", ctx->frame_type);
+ return AVERROR_INVALIDDATA;
+ }
+
+ ctx->chroma_factor = (buf[12] >> 6) & 3;
+ ctx->mb_chroma_factor = ctx->chroma_factor + 2;
+ ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1;
+ switch (ctx->chroma_factor) {
+ case 2:
+ avctx->pix_fmt = PIX_FMT_YUV422P10;
+ break;
+ case 3:
+ avctx->pix_fmt = PIX_FMT_YUV444P10;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR,
+ "unsupported picture format: %d\n", ctx->pic_format);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (ctx->scantable_type != ctx->frame_type) {
+ if (!ctx->frame_type)
+ ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
+ progressive_scan);
+ else
+ ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
+ interlaced_scan);
+ ctx->scantable_type = ctx->frame_type;
+ }
+
+ if (ctx->frame_type) { /* if interlaced */
+ ctx->picture.interlaced_frame = 1;
+ ctx->picture.top_field_first = ctx->frame_type & 1;
+ }
+
+ ctx->alpha_info = buf[17] & 0xf;
+ if (ctx->alpha_info)
+ av_log_missing_feature(avctx, "alpha channel", 0);
+
+ ctx->qmat_changed = 0;
+ ptr = buf + 20;
+ flags = buf[19];
+ if (flags & 2) {
+ if (ptr - buf > hdr_size - 64) {
+ av_log(avctx, AV_LOG_ERROR, "header data too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (memcmp(ctx->qmat_luma, ptr, 64)) {
+ memcpy(ctx->qmat_luma, ptr, 64);
+ ctx->qmat_changed = 1;
+ }
+ ptr += 64;
+ } else {
+ memset(ctx->qmat_luma, 4, 64);
+ ctx->qmat_changed = 1;
+ }
+
+ if (flags & 1) {
+ if (ptr - buf > hdr_size - 64) {
+ av_log(avctx, AV_LOG_ERROR, "header data too small\n");
+ return -1;
+ }
+ if (memcmp(ctx->qmat_chroma, ptr, 64)) {
+ memcpy(ctx->qmat_chroma, ptr, 64);
+ ctx->qmat_changed = 1;
+ }
+ } else {
+ memset(ctx->qmat_chroma, 4, 64);
+ ctx->qmat_changed = 1;
+ }
+
+ return hdr_size;
+}
+
+
+static int decode_picture_header(ProresContext *ctx, const uint8_t *buf,
+ const int data_size, AVCodecContext *avctx)
+{
+ int i, hdr_size, pic_data_size, num_slices;
+ int slice_width_factor, slice_height_factor;
+ int remainder, num_x_slices;
+ const uint8_t *data_ptr, *index_ptr;
+
+ hdr_size = data_size > 0 ? buf[0] >> 3 : 0;
+ if (hdr_size < 8 || hdr_size > data_size) {
+ av_log(avctx, AV_LOG_ERROR, "picture header too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ pic_data_size = AV_RB32(buf + 1);
+ if (pic_data_size > data_size) {
+ av_log(avctx, AV_LOG_ERROR, "picture data too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ slice_width_factor = buf[7] >> 4;
+ slice_height_factor = buf[7] & 0xF;
+ if (slice_width_factor > 3 || slice_height_factor) {
+ av_log(avctx, AV_LOG_ERROR,
+ "unsupported slice dimension: %d x %d\n",
+ 1 << slice_width_factor, 1 << slice_height_factor);
+ return AVERROR_INVALIDDATA;
+ }
+
+ ctx->slice_width_factor = slice_width_factor;
+ ctx->slice_height_factor = slice_height_factor;
+
+ ctx->num_x_mbs = (avctx->width + 15) >> 4;
+ ctx->num_y_mbs = (avctx->height +
+ (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
+ (4 + ctx->picture.interlaced_frame);
+
+ remainder = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
+ num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
+ ((remainder >> 1) & 1) + ((remainder >> 2) & 1);
+
+ num_slices = num_x_slices * ctx->num_y_mbs;
+ if (num_slices != AV_RB16(buf + 5)) {
+ av_log(avctx, AV_LOG_ERROR, "invalid number of slices\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (ctx->total_slices != num_slices) {
+ av_freep(&ctx->slice_data);
+ ctx->slice_data = av_malloc((num_slices + 1) * sizeof(ctx->slice_data[0]));
+ if (!ctx->slice_data)
+ return AVERROR(ENOMEM);
+ ctx->total_slices = num_slices;
+ }
+
+ if (hdr_size + num_slices * 2 > data_size) {
+ av_log(avctx, AV_LOG_ERROR, "slice table too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* parse slice table allowing quick access to the slice data */
+ index_ptr = buf + hdr_size;
+ data_ptr = index_ptr + num_slices * 2;
+
+ for (i = 0; i < num_slices; i++) {
+ ctx->slice_data[i].index = data_ptr;
+ data_ptr += AV_RB16(index_ptr + i * 2);
+ }
+ ctx->slice_data[i].index = data_ptr;
+
+ if (data_ptr > buf + data_size) {
+ av_log(avctx, AV_LOG_ERROR, "out of slice data\n");
+ return -1;
+ }
+
+ return pic_data_size;
+}
+
+
+/**
+ * Read an unsigned rice/exp golomb codeword.
+ */
+static inline int decode_vlc_codeword(GetBitContext *gb, uint8_t codebook)
+{
+ unsigned int rice_order, exp_order, switch_bits;
+ unsigned int buf, code;
+ int log, prefix_len, len;
+
+ OPEN_READER(re, gb);
+ UPDATE_CACHE(re, gb);
+ buf = GET_CACHE(re, gb);
+
+ /* number of prefix bits to switch between Rice and expGolomb */
+ switch_bits = (codebook & 3) + 1;
+ rice_order = codebook >> 5; /* rice code order */
+ exp_order = (codebook >> 2) & 7; /* exp golomb code order */
+
+ log = 31 - av_log2(buf); /* count prefix bits (zeroes) */
+
+ if (log < switch_bits) { /* ok, we got a rice code */
+ if (!rice_order) {
+ /* shortcut for faster decoding of rice codes without remainder */
+ code = log;
+ LAST_SKIP_BITS(re, gb, log + 1);
+ } else {
+ prefix_len = log + 1;
+ code = (log << rice_order) + NEG_USR32(buf << prefix_len, rice_order);
+ LAST_SKIP_BITS(re, gb, prefix_len + rice_order);
+ }
+ } else { /* otherwise we got a exp golomb code */
+ len = (log << 1) - switch_bits + exp_order + 1;
+ code = NEG_USR32(buf, len) - (1 << exp_order) + (switch_bits << rice_order);
+ LAST_SKIP_BITS(re, gb, len);
+ }
+
+ CLOSE_READER(re, gb);
+
+ return code;
+}
+
+#define LSB2SIGN(x) (-((x) & 1))
+#define TOSIGNED(x) (((x) >> 1) ^ LSB2SIGN(x))
+
+#define FIRST_DC_CB 0xB8 // rice_order = 5, exp_golomb_order = 6, switch_bits = 0
+
+static uint8_t dc_codebook[4] = {
+ 0x04, // rice_order = 0, exp_golomb_order = 1, switch_bits = 0
+ 0x28, // rice_order = 1, exp_golomb_order = 2, switch_bits = 0
+ 0x4D, // rice_order = 2, exp_golomb_order = 3, switch_bits = 1
+ 0x70 // rice_order = 3, exp_golomb_order = 4, switch_bits = 0
+};
+
+
+/**
+ * Decode DC coefficients for all blocks in a slice.
+ */
+static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
+ int nblocks)
+{
+ DCTELEM prev_dc;
+ int i, sign;
+ int16_t delta;
+ unsigned int code;
+
+ code = decode_vlc_codeword(gb, FIRST_DC_CB);
+ out[0] = prev_dc = TOSIGNED(code);
+
+ out += 64; /* move to the DC coeff of the next block */
+ delta = 3;
+
+ for (i = 1; i < nblocks; i++, out += 64) {
+ code = decode_vlc_codeword(gb, dc_codebook[FFMIN(FFABS(delta), 3)]);
+
+ sign = -(((delta >> 15) & 1) ^ (code & 1));
+ delta = (((code + 1) >> 1) ^ sign) - sign;
+ prev_dc += delta;
+ out[0] = prev_dc;
+ }
+}
+
+
+static uint8_t ac_codebook[7] = {
+ 0x04, // rice_order = 0, exp_golomb_order = 1, switch_bits = 0
+ 0x28, // rice_order = 1, exp_golomb_order = 2, switch_bits = 0
+ 0x4C, // rice_order = 2, exp_golomb_order = 3, switch_bits = 0
+ 0x05, // rice_order = 0, exp_golomb_order = 1, switch_bits = 1
+ 0x29, // rice_order = 1, exp_golomb_order = 2, switch_bits = 1
+ 0x06, // rice_order = 0, exp_golomb_order = 1, switch_bits = 2
+ 0x0A, // rice_order = 0, exp_golomb_order = 2, switch_bits = 2
+};
+
+/**
+ * Lookup tables for adaptive switching between codebooks
+ * according with previous run/level value.
+ */
+static uint8_t run_to_cb_index[16] =
+ { 5, 5, 3, 3, 0, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 2 };
+
+static uint8_t lev_to_cb_index[10] = { 0, 6, 3, 5, 0, 1, 1, 1, 1, 2 };
+
+
+/**
+ * Decode AC coefficients for all blocks in a slice.
+ */
+static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
+ int blocks_per_slice,
+ int plane_size_factor,
+ const uint8_t *scan)
+{
+ int pos, block_mask, run, level, sign, run_cb_index, lev_cb_index;
+ int max_coeffs, bits_left;
+
+ /* set initial prediction values */
+ run = 4;
+ level = 2;
+
+ max_coeffs = blocks_per_slice << 6;
+ block_mask = blocks_per_slice - 1;
+
+ for (pos = blocks_per_slice - 1; pos < max_coeffs;) {
+ run_cb_index = run_to_cb_index[FFMIN(run, 15)];
+ lev_cb_index = lev_to_cb_index[FFMIN(level, 9)];
+
+ bits_left = get_bits_left(gb);
+ if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
+ return;
+
+ run = decode_vlc_codeword(gb, ac_codebook[run_cb_index]);
+
+ bits_left = get_bits_left(gb);
+ if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
+ return;
+
+ level = decode_vlc_codeword(gb, ac_codebook[lev_cb_index]) + 1;
+
+ pos += run + 1;
+ if (pos >= max_coeffs)
+ break;
+
+ sign = get_sbits(gb, 1);
+ out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] =
+ (level ^ sign) - sign;
+ }
+}
+
+
+/**
+ * Decode a slice plane (luma or chroma).
+ */
+static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
+ const uint8_t *buf,
+ int data_size, uint16_t *out_ptr,
+ int linesize, int mbs_per_slice,
+ int blocks_per_mb, int plane_size_factor,
+ const int16_t *qmat)
+{
+ GetBitContext gb;
+ DCTELEM *block_ptr;
+ int mb_num, blocks_per_slice;
+
+ blocks_per_slice = mbs_per_slice * blocks_per_mb;
+
+ memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
+
+ init_get_bits(&gb, buf, data_size << 3);
+
+ decode_dc_coeffs(&gb, td->blocks, blocks_per_slice);
+
+ decode_ac_coeffs(&gb, td->blocks, blocks_per_slice,
+ plane_size_factor, ctx->scantable.permutated);
+
+ /* inverse quantization, inverse transform and output */
+ block_ptr = td->blocks;
+
+ for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
+ ctx->dsp.idct_put(out_ptr, linesize, block_ptr, qmat);
+ block_ptr += 64;
+ if (blocks_per_mb > 2) {
+ ctx->dsp.idct_put(out_ptr + 8, linesize, block_ptr, qmat);
+ block_ptr += 64;
+ }
+ ctx->dsp.idct_put(out_ptr + linesize * 4, linesize, block_ptr, qmat);
+ block_ptr += 64;
+ if (blocks_per_mb > 2) {
+ ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
+ block_ptr += 64;
+ }
+ }
+}
+
+
+static int decode_slice(AVCodecContext *avctx, void *tdata)
+{
+ ProresThreadData *td = tdata;
+ ProresContext *ctx = avctx->priv_data;
+ int mb_x_pos = td->x_pos;
+ int mb_y_pos = td->y_pos;
+ int pic_num = ctx->pic_num;
+ int slice_num = td->slice_num;
+ int mbs_per_slice = td->slice_width;
+ const uint8_t *buf;
+ uint8_t *y_data, *u_data, *v_data;
+ AVFrame *pic = avctx->coded_frame;
+ int i, sf, slice_width_factor;
+ int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
+ int y_linesize, u_linesize, v_linesize;
+
+ buf = ctx->slice_data[slice_num].index;
+ slice_data_size = ctx->slice_data[slice_num + 1].index - buf;
+
+ slice_width_factor = av_log2(mbs_per_slice);
+
+ y_data = pic->data[0];
+ u_data = pic->data[1];
+ v_data = pic->data[2];
+ y_linesize = pic->linesize[0];
+ u_linesize = pic->linesize[1];
+ v_linesize = pic->linesize[2];
+
+ if (pic->interlaced_frame) {
+ if (!(pic_num ^ pic->top_field_first)) {
+ y_data += y_linesize;
+ u_data += u_linesize;
+ v_data += v_linesize;
+ }
+ y_linesize <<= 1;
+ u_linesize <<= 1;
+ v_linesize <<= 1;
+ }
+
+ if (slice_data_size < 6) {
+ av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* parse slice header */
+ hdr_size = buf[0] >> 3;
+ y_data_size = AV_RB16(buf + 2);
+ u_data_size = AV_RB16(buf + 4);
+ v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
+ slice_data_size - y_data_size - u_data_size - hdr_size;
+
+ if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
+ v_data_size < 0 || hdr_size < 6) {
+ av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ sf = av_clip(buf[1], 1, 224);
+ sf = sf > 128 ? (sf - 96) << 2 : sf;
+
+ /* scale quantization matrixes according with slice's scale factor */
+ /* TODO: this can be SIMD-optimized a lot */
+ if (ctx->qmat_changed || sf != ctx->prev_slice_sf) {
+ ctx->prev_slice_sf = sf;
+ for (i = 0; i < 64; i++) {
+ ctx->qmat_luma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_luma[i] * sf;
+ ctx->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_chroma[i] * sf;
+ }
+ }
+
+ /* decode luma plane */
+ decode_slice_plane(ctx, td, buf + hdr_size, y_data_size,
+ (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize +
+ (mb_x_pos << 5)), y_linesize,
+ mbs_per_slice, 4, slice_width_factor + 2,
+ ctx->qmat_luma_scaled);
+
+ /* decode U chroma plane */
+ decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size,
+ (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize +
+ (mb_x_pos << ctx->mb_chroma_factor)),
+ u_linesize, mbs_per_slice, ctx->num_chroma_blocks,
+ slice_width_factor + ctx->chroma_factor - 1,
+ ctx->qmat_chroma_scaled);
+
+ /* decode V chroma plane */
+ decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size,
+ v_data_size,
+ (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize +
+ (mb_x_pos << ctx->mb_chroma_factor)),
+ v_linesize, mbs_per_slice, ctx->num_chroma_blocks,
+ slice_width_factor + ctx->chroma_factor - 1,
+ ctx->qmat_chroma_scaled);
+
+ return 0;
+}
+
+
+static int decode_picture(ProresContext *ctx, int pic_num,
+ AVCodecContext *avctx)
+{
+ int slice_num, slice_width, x_pos, y_pos;
+
+ slice_num = 0;
+
+ ctx->pic_num = pic_num;
+ for (y_pos = 0; y_pos < ctx->num_y_mbs; y_pos++) {
+ slice_width = 1 << ctx->slice_width_factor;
+
+ for (x_pos = 0; x_pos < ctx->num_x_mbs && slice_width;
+ x_pos += slice_width) {
+ while (ctx->num_x_mbs - x_pos < slice_width)
+ slice_width >>= 1;
+
+ ctx->slice_data[slice_num].slice_num = slice_num;
+ ctx->slice_data[slice_num].x_pos = x_pos;
+ ctx->slice_data[slice_num].y_pos = y_pos;
+ ctx->slice_data[slice_num].slice_width = slice_width;
+
+ slice_num++;
+ }
+ }
+
+ return avctx->execute(avctx, decode_slice,
+ ctx->slice_data, NULL, slice_num,
+ sizeof(ctx->slice_data[0]));
+}
+
+
+#define FRAME_ID MKBETAG('i', 'c', 'p', 'f')
+#define MOVE_DATA_PTR(nbytes) buf += (nbytes); buf_size -= (nbytes)
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ ProresContext *ctx = avctx->priv_data;
+ AVFrame *picture = avctx->coded_frame;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int frame_hdr_size, pic_num, pic_data_size;
+
+ /* check frame atom container */
+ if (buf_size < 28 || buf_size < AV_RB32(buf) ||
+ AV_RB32(buf + 4) != FRAME_ID) {
+ av_log(avctx, AV_LOG_ERROR, "invalid frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ MOVE_DATA_PTR(8);
+
+ frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
+ if (frame_hdr_size < 0)
+ return AVERROR_INVALIDDATA;
+
+ MOVE_DATA_PTR(frame_hdr_size);
+
+ if (picture->data[0])
+ avctx->release_buffer(avctx, picture);
+
+ picture->reference = 0;
+ if (avctx->get_buffer(avctx, picture) < 0)
+ return -1;
+
+ for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
+ pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx);
+ if (pic_data_size < 0)
+ return AVERROR_INVALIDDATA;
+
+ if (decode_picture(ctx, pic_num, avctx))
+ return -1;
+
+ MOVE_DATA_PTR(pic_data_size);
+ }
+
+ *data_size = sizeof(AVPicture);
+ *(AVFrame*) data = *avctx->coded_frame;
+
+ return avpkt->size;
+}
+
+
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+ ProresContext *ctx = avctx->priv_data;
+
+ if (ctx->picture.data[0])
+ avctx->release_buffer(avctx, &ctx->picture);
+
+ av_freep(&ctx->slice_data);
+
+ return 0;
+}
+
+
+AVCodec ff_prores_decoder = {
+ .name = "prores",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PRORES,
+ .priv_data_size = sizeof(ProresContext),
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
+ .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)")
+};
diff --git a/libavcodec/proresdsp.c b/libavcodec/proresdsp.c
new file mode 100644
index 0000000..7e753e9
--- /dev/null
+++ b/libavcodec/proresdsp.c
@@ -0,0 +1,63 @@
+/*
+ * Apple ProRes compatible decoder
+ *
+ * Copyright (c) 2010-2011 Maxim Poliakovski
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "proresdsp.h"
+#include "simple_idct.h"
+
+#define BIAS (1 << (PRORES_BITS_PER_SAMPLE - 1)) ///< bias value for converting signed pixels into unsigned ones
+#define CLIP_MIN (1 << (PRORES_BITS_PER_SAMPLE - 8)) ///< minimum value for clipping resulting pixels
+#define CLIP_MAX (1 << PRORES_BITS_PER_SAMPLE) - CLIP_MIN - 1 ///< maximum value for clipping resulting pixels
+
+#define CLIP_AND_BIAS(x) (av_clip((x) + BIAS, CLIP_MIN, CLIP_MAX))
+
+/**
+ * Add bias value, clamp and output pixels of a slice
+ */
+static void put_pixels(uint16_t *dst, int stride, const DCTELEM *in)
+{
+ int x, y, src_offset, dst_offset;
+
+ for (y = 0, dst_offset = 0; y < 8; y++, dst_offset += stride) {
+ for (x = 0; x < 8; x++) {
+ src_offset = (y << 3) + x;
+
+ dst[dst_offset + x] = CLIP_AND_BIAS(in[src_offset]);
+ }
+ }
+}
+
+static void prores_idct_put_c(uint16_t *out, int linesize, DCTELEM *block, const int16_t *qmat)
+{
+ ff_prores_idct(block, qmat);
+ put_pixels(out, linesize >> 1, block);
+}
+
+void ff_proresdsp_init(ProresDSPContext *dsp)
+{
+ dsp->idct_put = prores_idct_put_c;
+ dsp->idct_permutation_type = FF_NO_IDCT_PERM;
+
+ if (HAVE_MMX) ff_proresdsp_x86_init(dsp);
+
+ ff_init_scantable_permutation(dsp->idct_permutation,
+ dsp->idct_permutation_type);
+}
diff --git a/libavcodec/proresdsp.h b/libavcodec/proresdsp.h
new file mode 100644
index 0000000..8b864fa
--- /dev/null
+++ b/libavcodec/proresdsp.h
@@ -0,0 +1,40 @@
+/*
+ * Apple ProRes compatible decoder
+ *
+ * Copyright (c) 2010-2011 Maxim Poliakovski
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_PRORESDSP_H
+#define AVCODEC_PRORESDSP_H
+
+#include "dsputil.h"
+
+#define PRORES_BITS_PER_SAMPLE 10 ///< output precision of prores decoder
+
+typedef struct {
+ int idct_permutation_type;
+ uint8_t idct_permutation[64];
+ void (* idct_put) (uint16_t *out, int linesize, DCTELEM *block, const int16_t *qmat);
+} ProresDSPContext;
+
+void ff_proresdsp_init(ProresDSPContext *dsp);
+
+void ff_proresdsp_x86_init(ProresDSPContext *dsp);
+
+#endif /* AVCODEC_PRORESDSP_H */
diff --git a/libavcodec/ps2/dsputil_mmi.c b/libavcodec/ps2/dsputil_mmi.c
index f4503a9..77755b0 100644
--- a/libavcodec/ps2/dsputil_mmi.c
+++ b/libavcodec/ps2/dsputil_mmi.c
@@ -142,7 +142,7 @@ static void put_pixels16_mmi(uint8_t *block, const uint8_t *pixels, int line_siz
void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx)
{
const int idct_algo= avctx->idct_algo;
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
if (!high_bit_depth) {
c->clear_blocks = clear_blocks_mmi;
@@ -152,11 +152,12 @@ void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx)
c->put_pixels_tab[0][0] = put_pixels16_mmi;
c->put_no_rnd_pixels_tab[0][0] = put_pixels16_mmi;
- }
c->get_pixels = get_pixels_mmi;
+ }
- if(idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_PS2){
+ if (avctx->bits_per_raw_sample <= 8 &&
+ (idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_PS2)) {
c->idct_put= ff_mmi_idct_put;
c->idct_add= ff_mmi_idct_add;
c->idct = ff_mmi_idct;
diff --git a/libavcodec/psymodel.c b/libavcodec/psymodel.c
index fe9363c..740d859 100644
--- a/libavcodec/psymodel.c
+++ b/libavcodec/psymodel.c
@@ -25,16 +25,31 @@
extern const FFPsyModel ff_aac_psy_model;
-av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx,
- int num_lens,
- const uint8_t **bands, const int* num_bands)
+av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
+ const uint8_t **bands, const int* num_bands,
+ int num_groups, const uint8_t *group_map)
{
+ int i, j, k = 0;
+
ctx->avctx = avctx;
- ctx->psy_bands = av_mallocz(sizeof(FFPsyBand) * PSY_MAX_BANDS * avctx->channels);
+ ctx->ch = av_mallocz(sizeof(ctx->ch[0]) * avctx->channels * 2);
+ ctx->group = av_mallocz(sizeof(ctx->group[0]) * num_groups);
ctx->bands = av_malloc (sizeof(ctx->bands[0]) * num_lens);
ctx->num_bands = av_malloc (sizeof(ctx->num_bands[0]) * num_lens);
memcpy(ctx->bands, bands, sizeof(ctx->bands[0]) * num_lens);
memcpy(ctx->num_bands, num_bands, sizeof(ctx->num_bands[0]) * num_lens);
+
+ /* assign channels to groups (with virtual channels for coupling) */
+ for (i = 0; i < num_groups; i++) {
+ /* NOTE: Add 1 to handle the AAC chan_config without modification.
+ * This has the side effect of allowing an array of 0s to map
+ * to one channel per group.
+ */
+ ctx->group[i].num_ch = group_map[i] + 1;
+ for (j = 0; j < ctx->group[i].num_ch * 2; j++)
+ ctx->group[i].ch[j] = &ctx->ch[k++];
+ }
+
switch (ctx->avctx->codec_id) {
case CODEC_ID_AAC:
ctx->model = &ff_aac_psy_model;
@@ -45,13 +60,24 @@ av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx,
return 0;
}
+FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel)
+{
+ int i = 0, ch = 0;
+
+ while (ch <= channel)
+ ch += ctx->group[i++].num_ch;
+
+ return &ctx->group[i-1];
+}
+
av_cold void ff_psy_end(FFPsyContext *ctx)
{
if (ctx->model->end)
ctx->model->end(ctx);
av_freep(&ctx->bands);
av_freep(&ctx->num_bands);
- av_freep(&ctx->psy_bands);
+ av_freep(&ctx->group);
+ av_freep(&ctx->ch);
}
typedef struct FFPsyPreprocessContext{
diff --git a/libavcodec/psymodel.h b/libavcodec/psymodel.h
index 02dc9c9..3e866e4 100644
--- a/libavcodec/psymodel.h
+++ b/libavcodec/psymodel.h
@@ -41,6 +41,23 @@ typedef struct FFPsyBand {
} FFPsyBand;
/**
+ * single channel psychoacoustic information
+ */
+typedef struct FFPsyChannel {
+ FFPsyBand psy_bands[PSY_MAX_BANDS]; ///< channel bands information
+ float entropy; ///< total PE for this channel
+} FFPsyChannel;
+
+/**
+ * psychoacoustic information for an arbitrary group of channels
+ */
+typedef struct FFPsyChannelGroup {
+ FFPsyChannel *ch[PSY_MAX_CHANS]; ///< pointers to the individual channels in the group
+ uint8_t num_ch; ///< number of channels in this group
+ uint8_t coupling[PSY_MAX_BANDS]; ///< allow coupling for this band in the group
+} FFPsyChannelGroup;
+
+/**
* windowing related information
*/
typedef struct FFPsyWindowInfo {
@@ -58,14 +75,14 @@ typedef struct FFPsyContext {
AVCodecContext *avctx; ///< encoder context
const struct FFPsyModel *model; ///< encoder-specific model functions
- FFPsyBand *psy_bands; ///< frame bands information
+ FFPsyChannel *ch; ///< single channel information
+ FFPsyChannelGroup *group; ///< channel group information
+ int num_groups; ///< number of channel groups
uint8_t **bands; ///< scalefactor band sizes for possible frame sizes
int *num_bands; ///< number of scalefactor bands for possible frame sizes
int num_lens; ///< number of scalefactor band sets
- float pe[PSY_MAX_CHANS]; ///< total PE for each channel in the frame
-
struct {
int size; ///< size of the bitresevoir in bits
int bits; ///< number of bits used in the bitresevoir
@@ -95,14 +112,14 @@ typedef struct FFPsyModel {
FFPsyWindowInfo (*window)(FFPsyContext *ctx, const int16_t *audio, const int16_t *la, int channel, int prev_type);
/**
- * Perform psychoacoustic analysis and set band info (threshold, energy).
+ * Perform psychoacoustic analysis and set band info (threshold, energy) for a group of channels.
*
- * @param ctx model context
- * @param channel audio channel number
- * @param coeffs pointer to the transformed coefficients
- * @param wi window information
+ * @param ctx model context
+ * @param channel channel number of the first channel in the group to perform analysis on
+ * @param coeffs array of pointers to the transformed coefficients
+ * @param wi window information for the channels in the group
*/
- void (*analyze)(FFPsyContext *ctx, int channel, const float *coeffs, const FFPsyWindowInfo *wi);
+ void (*analyze)(FFPsyContext *ctx, int channel, const float **coeffs, const FFPsyWindowInfo *wi);
void (*end) (FFPsyContext *apc);
} FFPsyModel;
@@ -115,12 +132,24 @@ typedef struct FFPsyModel {
* @param num_lens number of possible frame lengths
* @param bands scalefactor band lengths for all frame lengths
* @param num_bands number of scalefactor bands for all frame lengths
+ * @param num_groups number of channel groups
+ * @param group_map array with # of channels in group - 1, for each group
*
* @return zero if successful, a negative value if not
*/
-av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx,
- int num_lens,
- const uint8_t **bands, const int* num_bands);
+av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
+ const uint8_t **bands, const int* num_bands,
+ int num_groups, const uint8_t *group_map);
+
+/**
+ * Determine what group a channel belongs to.
+ *
+ * @param ctx psymodel context
+ * @param channel channel to locate the group for
+ *
+ * @return pointer to the FFPsyChannelGroup this channel belongs to
+ */
+FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel);
/**
* Cleanup model context at the end.
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index e546c21..4356b32 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -29,11 +29,31 @@
* @see doc/multithreading.txt
*/
-#include <pthread.h>
+#include "config.h"
+
+#if HAVE_SCHED_GETAFFINITY
+#define _GNU_SOURCE
+#include <sched.h>
+#elif HAVE_GETSYSTEMINFO
+#include <windows.h>
+#elif HAVE_SYSCTL
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
#include "avcodec.h"
+#include "internal.h"
#include "thread.h"
+#if HAVE_PTHREADS
+#include <pthread.h>
+#elif HAVE_W32THREADS
+#include "w32pthreads.h"
+#endif
+
typedef int (action_func)(AVCodecContext *c, void *arg);
typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
@@ -64,6 +84,7 @@ typedef struct PerThreadContext {
struct FrameThreadContext *parent;
pthread_t thread;
+ int thread_init;
pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread.
pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change.
pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish.
@@ -126,6 +147,40 @@ typedef struct FrameThreadContext {
int die; ///< Set when threads should exit.
} FrameThreadContext;
+
+/* H264 slice threading seems to be buggy with more than 16 threads,
+ * limit the number of threads to 16 for automatic detection */
+#define MAX_AUTO_THREADS 16
+
+static int get_logical_cpus(AVCodecContext *avctx)
+{
+ int ret, nb_cpus = 1;
+#if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT)
+ cpu_set_t cpuset;
+
+ CPU_ZERO(&cpuset);
+
+ ret = sched_getaffinity(0, sizeof(cpuset), &cpuset);
+ if (!ret) {
+ nb_cpus = CPU_COUNT(&cpuset);
+ }
+#elif HAVE_GETSYSTEMINFO
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ nb_cpus = sysinfo.dwNumberOfProcessors;
+#elif HAVE_SYSCTL && defined(HW_NCPU)
+ int mib[2] = { CTL_HW, HW_NCPU };
+ size_t len = sizeof(nb_cpus);
+
+ ret = sysctl(mib, 2, &nb_cpus, &len, NULL, 0);
+ if (ret == -1)
+ nb_cpus = 0;
+#endif
+ av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
+ return FFMIN(nb_cpus, MAX_AUTO_THREADS);
+}
+
+
static void* attribute_align_arg worker(void *v)
{
AVCodecContext *avctx = v;
@@ -230,8 +285,17 @@ static int thread_init(AVCodecContext *avctx)
ThreadContext *c;
int thread_count = avctx->thread_count;
- if (thread_count <= 1)
+ if (!thread_count) {
+ int nb_cpus = get_logical_cpus(avctx);
+ // use number of cores + 1 as thread count if there is motre than one
+ if (nb_cpus > 1)
+ thread_count = avctx->thread_count = nb_cpus + 1;
+ }
+
+ if (thread_count <= 1) {
+ avctx->active_thread_type = 0;
return 0;
+ }
c = av_mallocz(sizeof(ThreadContext));
if (!c)
@@ -315,7 +379,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg)
}
/**
- * Updates the next thread's AVCodecContext with values from the reference thread's context.
+ * Update the next thread's AVCodecContext with values from the reference thread's context.
*
* @param dst The destination context.
* @param src The source context.
@@ -332,6 +396,9 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src,
dst->height = src->height;
dst->pix_fmt = src->pix_fmt;
+ dst->coded_width = src->coded_width;
+ dst->coded_height = src->coded_height;
+
dst->has_b_frames = src->has_b_frames;
dst->idct_algo = src->idct_algo;
dst->slice_count = src->slice_count;
@@ -354,8 +421,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src,
}
if (for_user) {
- dst->coded_frame = src->coded_frame;
- dst->has_b_frames += src->thread_count - 1;
+ dst->coded_frame = src->coded_frame;
} else {
if (dst->codec->update_thread_context)
err = dst->codec->update_thread_context(dst, src);
@@ -482,6 +548,7 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
}
fctx->prev_thread = p;
+ fctx->next_decoding++;
return 0;
}
@@ -504,8 +571,6 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
err = submit_packet(p, avpkt);
if (err) return err;
- fctx->next_decoding++;
-
/*
* If we're still receiving the initial packets, don't return a frame.
*/
@@ -514,7 +579,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
if (fctx->next_decoding >= (avctx->thread_count-1)) fctx->delaying = 0;
*got_picture_ptr=0;
- return 0;
+ return avpkt->size;
}
/*
@@ -537,6 +602,10 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
*picture = p->frame;
*got_picture_ptr = p->got_frame;
picture->pkt_dts = p->avpkt.dts;
+ picture->sample_aspect_ratio = avctx->sample_aspect_ratio;
+ picture->width = avctx->width;
+ picture->height = avctx->height;
+ picture->format = avctx->pix_fmt;
/*
* A later call with avkpt->size == 0 may loop over all threads,
@@ -555,7 +624,8 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
fctx->next_finished = finished;
- return p->result;
+ /* return the size of the consumed packet if no error occurred */
+ return (p->result >= 0) ? avpkt->size : p->result;
}
void ff_thread_report_progress(AVFrame *f, int n, int field)
@@ -630,7 +700,7 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count)
park_frame_worker_threads(fctx, thread_count);
- if (fctx->prev_thread)
+ if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0);
fctx->die = 1;
@@ -642,7 +712,8 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count)
pthread_cond_signal(&p->input_cond);
pthread_mutex_unlock(&p->mutex);
- pthread_join(p->thread, NULL);
+ if (p->thread_init)
+ pthread_join(p->thread, NULL);
if (codec->close)
codec->close(p->avctx);
@@ -664,8 +735,10 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count)
pthread_cond_destroy(&p->output_cond);
av_freep(&p->avpkt.data);
- if (i)
+ if (i) {
av_freep(&p->avctx->priv_data);
+ av_freep(&p->avctx->internal);
+ }
av_freep(&p->avctx);
}
@@ -683,6 +756,13 @@ static int frame_thread_init(AVCodecContext *avctx)
FrameThreadContext *fctx;
int i, err = 0;
+ if (!thread_count) {
+ int nb_cpus = get_logical_cpus(avctx);
+ // use number of cores + 1 as thread count if there is motre than one
+ if (nb_cpus > 1)
+ thread_count = avctx->thread_count = nb_cpus + 1;
+ }
+
if (thread_count <= 1) {
avctx->active_thread_type = 0;
return 0;
@@ -707,6 +787,11 @@ static int frame_thread_init(AVCodecContext *avctx)
p->parent = fctx;
p->avctx = copy;
+ if (!copy) {
+ err = AVERROR(ENOMEM);
+ goto error;
+ }
+
*copy = *src;
copy->thread_opaque = p;
copy->pkt = &p->avpkt;
@@ -719,9 +804,19 @@ static int frame_thread_init(AVCodecContext *avctx)
update_context_from_thread(avctx, copy, 1);
} else {
- copy->is_copy = 1;
copy->priv_data = av_malloc(codec->priv_data_size);
+ if (!copy->priv_data) {
+ err = AVERROR(ENOMEM);
+ goto error;
+ }
memcpy(copy->priv_data, src->priv_data, codec->priv_data_size);
+ copy->internal = av_malloc(sizeof(AVCodecInternal));
+ if (!copy->internal) {
+ err = AVERROR(ENOMEM);
+ goto error;
+ }
+ *(copy->internal) = *(src->internal);
+ copy->internal->is_copy = 1;
if (codec->init_thread_copy)
err = codec->init_thread_copy(copy);
@@ -729,7 +824,8 @@ static int frame_thread_init(AVCodecContext *avctx)
if (err) goto error;
- pthread_create(&p->thread, NULL, frame_worker_thread, p);
+ if (!pthread_create(&p->thread, NULL, frame_worker_thread, p))
+ p->thread_init = 1;
}
return 0;
@@ -827,13 +923,6 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
pthread_mutex_unlock(&p->parent->buffer_mutex);
- /*
- * Buffer age is difficult to keep track of between
- * multiple threads, and the optimizations it allows
- * are not worth the effort. It is disabled for now.
- */
- f->age = INT_MAX;
-
return err;
}
@@ -853,8 +942,7 @@ void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
}
if(avctx->debug & FF_DEBUG_BUFFERS)
- av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p, %d buffers used\n",
- f, f->owner->internal_buffer_count);
+ av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
fctx = p->parent;
pthread_mutex_lock(&fctx->buffer_mutex);
@@ -895,6 +983,10 @@ int ff_thread_init(AVCodecContext *avctx)
return -1;
}
+#if HAVE_W32THREADS
+ w32thread_init();
+#endif
+
if (avctx->codec) {
validate_thread_parameters(avctx);
diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c
index c993f6c..fd4933c 100644
--- a/libavcodec/ptx.c
+++ b/libavcodec/ptx.c
@@ -39,12 +39,15 @@ static av_cold int ptx_init(AVCodecContext *avctx) {
static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
AVPacket *avpkt) {
const uint8_t *buf = avpkt->data;
+ const uint8_t *buf_end = avpkt->data + avpkt->size;
PTXContext * const s = avctx->priv_data;
AVFrame *picture = data;
AVFrame * const p = &s->picture;
unsigned int offset, w, h, y, stride, bytes_per_pixel;
uint8_t *ptr;
+ if (buf_end - buf < 14)
+ return AVERROR_INVALIDDATA;
offset = AV_RL16(buf);
w = AV_RL16(buf+8);
h = AV_RL16(buf+10);
@@ -57,6 +60,8 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
avctx->pix_fmt = PIX_FMT_RGB555;
+ if (buf_end - buf < offset)
+ return AVERROR_INVALIDDATA;
if (offset != 0x2c)
av_log_ask_for_sample(avctx, "offset != 0x2c\n");
@@ -79,7 +84,7 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
ptr = p->data[0];
stride = p->linesize[0];
- for (y=0; y<h; y++) {
+ for (y = 0; y < h && buf_end - buf >= w * bytes_per_pixel; y++) {
#if HAVE_BIGENDIAN
unsigned int x;
for (x=0; x<w*bytes_per_pixel; x+=bytes_per_pixel)
@@ -94,6 +99,11 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
*picture = s->picture;
*data_size = sizeof(AVPicture);
+ if (y < h) {
+ av_log(avctx, AV_LOG_WARNING, "incomplete packet\n");
+ return avpkt->size;
+ }
+
return offset + w*h*bytes_per_pixel;
}
@@ -107,15 +117,13 @@ static av_cold int ptx_end(AVCodecContext *avctx) {
}
AVCodec ff_ptx_decoder = {
- "ptx",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PTX,
- sizeof(PTXContext),
- ptx_init,
- NULL,
- ptx_end,
- ptx_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "ptx",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PTX,
+ .priv_data_size = sizeof(PTXContext),
+ .init = ptx_init,
+ .close = ptx_end,
+ .decode = ptx_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("V.Flash PTX image"),
};
diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h
index 3849e6d..6e81267 100644
--- a/libavcodec/put_bits.h
+++ b/libavcodec/put_bits.h
@@ -36,19 +36,10 @@
#include "mathops.h"
#include "config.h"
-//#define ALT_BITSTREAM_WRITER
-//#define ALIGNED_BITSTREAM_WRITER
-
-/* buf and buf_end must be present and used by every alternative writer. */
typedef struct PutBitContext {
-#ifdef ALT_BITSTREAM_WRITER
- uint8_t *buf, *buf_end;
- int index;
-#else
uint32_t bit_buf;
int bit_left;
uint8_t *buf, *buf_ptr, *buf_end;
-#endif
int size_in_bits;
} PutBitContext;
@@ -68,15 +59,9 @@ static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_s
s->size_in_bits= 8*buffer_size;
s->buf = buffer;
s->buf_end = s->buf + buffer_size;
-#ifdef ALT_BITSTREAM_WRITER
- s->index=0;
- ((uint32_t*)(s->buf))[0]=0;
-// memset(buffer, 0, buffer_size);
-#else
s->buf_ptr = s->buf;
s->bit_left=32;
s->bit_buf=0;
-#endif
}
/**
@@ -84,11 +69,7 @@ static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_s
*/
static inline int put_bits_count(PutBitContext *s)
{
-#ifdef ALT_BITSTREAM_WRITER
- return s->index;
-#else
return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
-#endif
}
/**
@@ -96,11 +77,9 @@ static inline int put_bits_count(PutBitContext *s)
*/
static inline void flush_put_bits(PutBitContext *s)
{
-#ifdef ALT_BITSTREAM_WRITER
- align_put_bits(s);
-#else
#ifndef BITSTREAM_WRITER_LE
- s->bit_buf<<= s->bit_left;
+ if (s->bit_left < 32)
+ s->bit_buf<<= s->bit_left;
#endif
while (s->bit_left < 32) {
/* XXX: should test end of buffer */
@@ -115,18 +94,17 @@ static inline void flush_put_bits(PutBitContext *s)
}
s->bit_left=32;
s->bit_buf=0;
-#endif
}
-#if defined(ALT_BITSTREAM_WRITER) || defined(BITSTREAM_WRITER_LE)
-#define align_put_bits align_put_bits_unsupported_here
+#ifdef BITSTREAM_WRITER_LE
+#define avpriv_align_put_bits align_put_bits_unsupported_here
#define ff_put_string ff_put_string_unsupported_here
-#define ff_copy_bits ff_copy_bits_unsupported_here
+#define avpriv_copy_bits avpriv_copy_bits_unsupported_here
#else
/**
* Pad the bitstream with zeros up to the next byte boundary.
*/
-void align_put_bits(PutBitContext *s);
+void avpriv_align_put_bits(PutBitContext *s);
/**
* Put the string string in the bitstream.
@@ -140,7 +118,7 @@ void ff_put_string(PutBitContext *pb, const char *string, int terminate_string);
*
* @param length the number of bits of src to copy
*/
-void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
+void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
#endif
/**
@@ -148,7 +126,6 @@ void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
* Use put_bits32 to write 32 bits.
*/
static inline void put_bits(PutBitContext *s, int n, unsigned int value)
-#ifndef ALT_BITSTREAM_WRITER
{
unsigned int bit_buf;
int bit_left;
@@ -164,12 +141,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
#ifdef BITSTREAM_WRITER_LE
bit_buf |= value << (32 - bit_left);
if (n >= bit_left) {
-#if !HAVE_FAST_UNALIGNED
- if (3 & (intptr_t) s->buf_ptr) {
- AV_WL32(s->buf_ptr, bit_buf);
- } else
-#endif
- *(uint32_t *)s->buf_ptr = av_le2ne32(bit_buf);
+ AV_WL32(s->buf_ptr, bit_buf);
s->buf_ptr+=4;
bit_buf = (bit_left==32)?0:value >> bit_left;
bit_left+=32;
@@ -182,12 +154,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
} else {
bit_buf<<=bit_left;
bit_buf |= value >> (n - bit_left);
-#if !HAVE_FAST_UNALIGNED
- if (3 & (intptr_t) s->buf_ptr) {
- AV_WB32(s->buf_ptr, bit_buf);
- } else
-#endif
- *(uint32_t *)s->buf_ptr = av_be2ne32(bit_buf);
+ AV_WB32(s->buf_ptr, bit_buf);
//printf("bitbuf = %08x\n", bit_buf);
s->buf_ptr+=4;
bit_left+=32 - n;
@@ -198,70 +165,6 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
s->bit_buf = bit_buf;
s->bit_left = bit_left;
}
-#else /* ALT_BITSTREAM_WRITER defined */
-{
-# ifdef ALIGNED_BITSTREAM_WRITER
-# if ARCH_X86
- __asm__ volatile(
- "movl %0, %%ecx \n\t"
- "xorl %%eax, %%eax \n\t"
- "shrdl %%cl, %1, %%eax \n\t"
- "shrl %%cl, %1 \n\t"
- "movl %0, %%ecx \n\t"
- "shrl $3, %%ecx \n\t"
- "andl $0xFFFFFFFC, %%ecx \n\t"
- "bswapl %1 \n\t"
- "orl %1, (%2, %%ecx) \n\t"
- "bswapl %%eax \n\t"
- "addl %3, %0 \n\t"
- "movl %%eax, 4(%2, %%ecx) \n\t"
- : "=&r" (s->index), "=&r" (value)
- : "r" (s->buf), "r" (n), "0" (s->index), "1" (value<<(-n))
- : "%eax", "%ecx"
- );
-# else
- int index= s->index;
- uint32_t *ptr= ((uint32_t *)s->buf)+(index>>5);
-
- value<<= 32-n;
-
- ptr[0] |= av_be2ne32(value>>(index&31));
- ptr[1] = av_be2ne32(value<<(32-(index&31)));
-//if(n>24) printf("%d %d\n", n, value);
- index+= n;
- s->index= index;
-# endif
-# else //ALIGNED_BITSTREAM_WRITER
-# if ARCH_X86
- __asm__ volatile(
- "movl $7, %%ecx \n\t"
- "andl %0, %%ecx \n\t"
- "addl %3, %%ecx \n\t"
- "negl %%ecx \n\t"
- "shll %%cl, %1 \n\t"
- "bswapl %1 \n\t"
- "movl %0, %%ecx \n\t"
- "shrl $3, %%ecx \n\t"
- "orl %1, (%%ecx, %2) \n\t"
- "addl %3, %0 \n\t"
- "movl $0, 4(%%ecx, %2) \n\t"
- : "=&r" (s->index), "=&r" (value)
- : "r" (s->buf), "r" (n), "0" (s->index), "1" (value)
- : "%ecx"
- );
-# else
- int index= s->index;
- uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3));
-
- ptr[0] |= av_be2ne32(value<<(32-n-(index&7) ));
- ptr[1] = 0;
-//if(n>24) printf("%d %d\n", n, value);
- index+= n;
- s->index= index;
-# endif
-# endif //!ALIGNED_BITSTREAM_WRITER
-}
-#endif
static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
{
@@ -292,11 +195,7 @@ static void av_unused put_bits32(PutBitContext *s, uint32_t value)
*/
static inline uint8_t* put_bits_ptr(PutBitContext *s)
{
-#ifdef ALT_BITSTREAM_WRITER
- return s->buf + (s->index>>3);
-#else
return s->buf_ptr;
-#endif
}
/**
@@ -306,13 +205,8 @@ static inline uint8_t* put_bits_ptr(PutBitContext *s)
static inline void skip_put_bytes(PutBitContext *s, int n)
{
assert((put_bits_count(s)&7)==0);
-#ifdef ALT_BITSTREAM_WRITER
- FIXME may need some cleaning of the buffer
- s->index += n<<3;
-#else
assert(s->bit_left==32);
s->buf_ptr += n;
-#endif
}
/**
@@ -322,13 +216,9 @@ static inline void skip_put_bytes(PutBitContext *s, int n)
*/
static inline void skip_put_bits(PutBitContext *s, int n)
{
-#ifdef ALT_BITSTREAM_WRITER
- s->index += n;
-#else
s->bit_left -= n;
s->buf_ptr-= 4*(s->bit_left>>5);
s->bit_left &= 31;
-#endif
}
/**
diff --git a/libavcodec/qcelpdata.h b/libavcodec/qcelpdata.h
index 672da49..4c6cf15 100644
--- a/libavcodec/qcelpdata.h
+++ b/libavcodec/qcelpdata.h
@@ -40,16 +40,16 @@
typedef struct {
/// @name QCELP excitation codebook parameters
/// @{
- uint8_t cbsign[16]; ///!< sign of the codebook gain for each codebook subframe
- uint8_t cbgain[16]; ///!< unsigned codebook gain for each codebook subframe
- uint8_t cindex[16]; ///!< codebook index for each codebook subframe
+ uint8_t cbsign[16]; ///< sign of the codebook gain for each codebook subframe
+ uint8_t cbgain[16]; ///< unsigned codebook gain for each codebook subframe
+ uint8_t cindex[16]; ///< codebook index for each codebook subframe
/// @}
/// @name QCELP pitch prediction parameters
/// @{
- uint8_t plag[4]; ///!< pitch lag for each pitch subframe
- uint8_t pfrac[4]; ///!< fractional pitch lag for each pitch subframe
- uint8_t pgain[4]; ///!< pitch gain for each pitch subframe
+ uint8_t plag[4]; ///< pitch lag for each pitch subframe
+ uint8_t pfrac[4]; ///< fractional pitch lag for each pitch subframe
+ uint8_t pgain[4]; ///< pitch gain for each pitch subframe
/// @}
/**
@@ -74,9 +74,9 @@ typedef struct {
static const float qcelp_hammsinc_table[4] = { -0.006822, 0.041249, -0.143459, 0.588863};
typedef struct {
- uint8_t index; /*!< index into the QCELPContext structure */
- uint8_t bitpos; /*!< position of the lowest bit in the value's byte */
- uint8_t bitlen; /*!< number of bits to read */
+ uint8_t index; /**< index into the QCELPContext structure */
+ uint8_t bitpos; /**< position of the lowest bit in the value's byte */
+ uint8_t bitlen; /**< number of bits to read */
} QCELPBitmap;
#define QCELP_OF(variable, bit, len) {offsetof(QCELPFrame, variable), bit, len}
@@ -266,7 +266,7 @@ static const QCELPBitmap qcelp_rate_octave_bitmap[] = {
* the QCELPContext
*/
static const QCELPBitmap * const qcelp_unpacking_bitmaps_per_rate[5] = {
- NULL, ///!< for SILENCE rate
+ NULL, ///< for SILENCE rate
qcelp_rate_octave_bitmap,
qcelp_rate_quarter_bitmap,
qcelp_rate_half_bitmap,
@@ -274,7 +274,7 @@ static const QCELPBitmap * const qcelp_unpacking_bitmaps_per_rate[5] = {
};
static const uint16_t qcelp_unpacking_bitmaps_lengths[5] = {
- 0, ///!< for SILENCE rate
+ 0, ///< for SILENCE rate
FF_ARRAY_ELEMS(qcelp_rate_octave_bitmap),
FF_ARRAY_ELEMS(qcelp_rate_quarter_bitmap),
FF_ARRAY_ELEMS(qcelp_rate_half_bitmap),
diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c
index 3095a24..a3af237 100644
--- a/libavcodec/qcelpdec.c
+++ b/libavcodec/qcelpdec.c
@@ -44,9 +44,8 @@
#undef NDEBUG
#include <assert.h>
-typedef enum
-{
- I_F_Q = -1, /*!< insufficient frame quality */
+typedef enum {
+ I_F_Q = -1, /**< insufficient frame quality */
SILENCE,
RATE_OCTAVE,
RATE_QUARTER,
@@ -54,16 +53,16 @@ typedef enum
RATE_FULL
} qcelp_packet_rate;
-typedef struct
-{
+typedef struct {
+ AVFrame avframe;
GetBitContext gb;
qcelp_packet_rate bitrate;
- QCELPFrame frame; /*!< unpacked data frame */
+ QCELPFrame frame; /**< unpacked data frame */
uint8_t erasure_count;
- uint8_t octave_count; /*!< count the consecutive RATE_OCTAVE frames */
+ uint8_t octave_count; /**< count the consecutive RATE_OCTAVE frames */
float prev_lspf[10];
- float predictor_lspf[10];/*!< LSP predictor for RATE_OCTAVE and I_F_Q */
+ float predictor_lspf[10];/**< LSP predictor for RATE_OCTAVE and I_F_Q */
float pitch_synthesis_filter_mem[303];
float pitch_pre_filter_mem[303];
float rnd_fir_filter_mem[180];
@@ -94,8 +93,11 @@ static av_cold int qcelp_decode_init(AVCodecContext *avctx)
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
- for(i=0; i<10; i++)
- q->prev_lspf[i] = (i+1)/11.;
+ for (i = 0; i < 10; i++)
+ q->prev_lspf[i] = (i + 1) / 11.;
+
+ avcodec_get_frame_defaults(&q->avframe);
+ avctx->coded_frame = &q->avframe;
return 0;
}
@@ -117,79 +119,70 @@ static int decode_lspf(QCELPContext *q, float *lspf)
float tmp_lspf, smooth, erasure_coeff;
const float *predictors;
- if(q->bitrate == RATE_OCTAVE || q->bitrate == I_F_Q)
- {
- predictors = (q->prev_bitrate != RATE_OCTAVE &&
- q->prev_bitrate != I_F_Q ?
- q->prev_lspf : q->predictor_lspf);
+ if (q->bitrate == RATE_OCTAVE || q->bitrate == I_F_Q) {
+ predictors = q->prev_bitrate != RATE_OCTAVE &&
+ q->prev_bitrate != I_F_Q ? q->prev_lspf
+ : q->predictor_lspf;
- if(q->bitrate == RATE_OCTAVE)
- {
+ if (q->bitrate == RATE_OCTAVE) {
q->octave_count++;
- for(i=0; i<10; i++)
- {
+ for (i = 0; i < 10; i++) {
q->predictor_lspf[i] =
lspf[i] = (q->frame.lspv[i] ? QCELP_LSP_SPREAD_FACTOR
- : -QCELP_LSP_SPREAD_FACTOR)
- + predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR
- + (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR)/11);
+ : -QCELP_LSP_SPREAD_FACTOR) +
+ predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR +
+ (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR) / 11);
}
- smooth = (q->octave_count < 10 ? .875 : 0.1);
- }else
- {
+ smooth = q->octave_count < 10 ? .875 : 0.1;
+ } else {
erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR;
assert(q->bitrate == I_F_Q);
- if(q->erasure_count > 1)
- erasure_coeff *= (q->erasure_count < 4 ? 0.9 : 0.7);
+ if (q->erasure_count > 1)
+ erasure_coeff *= q->erasure_count < 4 ? 0.9 : 0.7;
- for(i=0; i<10; i++)
- {
+ for (i = 0; i < 10; i++) {
q->predictor_lspf[i] =
- lspf[i] = (i + 1) * ( 1 - erasure_coeff)/11
- + erasure_coeff * predictors[i];
+ lspf[i] = (i + 1) * (1 - erasure_coeff) / 11 +
+ erasure_coeff * predictors[i];
}
smooth = 0.125;
}
// Check the stability of the LSP frequencies.
lspf[0] = FFMAX(lspf[0], QCELP_LSP_SPREAD_FACTOR);
- for(i=1; i<10; i++)
- lspf[i] = FFMAX(lspf[i], (lspf[i-1] + QCELP_LSP_SPREAD_FACTOR));
+ for (i = 1; i < 10; i++)
+ lspf[i] = FFMAX(lspf[i], lspf[i - 1] + QCELP_LSP_SPREAD_FACTOR);
- lspf[9] = FFMIN(lspf[9], (1.0 - QCELP_LSP_SPREAD_FACTOR));
- for(i=9; i>0; i--)
- lspf[i-1] = FFMIN(lspf[i-1], (lspf[i] - QCELP_LSP_SPREAD_FACTOR));
+ lspf[9] = FFMIN(lspf[9], 1.0 - QCELP_LSP_SPREAD_FACTOR);
+ for (i = 9; i > 0; i--)
+ lspf[i - 1] = FFMIN(lspf[i - 1], lspf[i] - QCELP_LSP_SPREAD_FACTOR);
// Low-pass filter the LSP frequencies.
- ff_weighted_vector_sumf(lspf, lspf, q->prev_lspf, smooth, 1.0-smooth, 10);
- }else
- {
+ ff_weighted_vector_sumf(lspf, lspf, q->prev_lspf, smooth, 1.0 - smooth, 10);
+ } else {
q->octave_count = 0;
tmp_lspf = 0.;
- for(i=0; i<5 ; i++)
- {
- lspf[2*i+0] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][0] * 0.0001;
- lspf[2*i+1] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][1] * 0.0001;
+ for (i = 0; i < 5; i++) {
+ lspf[2 * i + 0] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][0] * 0.0001;
+ lspf[2 * i + 1] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][1] * 0.0001;
}
// Check for badly received packets.
- if(q->bitrate == RATE_QUARTER)
- {
- if(lspf[9] <= .70 || lspf[9] >= .97)
+ if (q->bitrate == RATE_QUARTER) {
+ if (lspf[9] <= .70 || lspf[9] >= .97)
return -1;
- for(i=3; i<10; i++)
- if(fabs(lspf[i] - lspf[i-2]) < .08)
+ for (i = 3; i < 10; i++)
+ if (fabs(lspf[i] - lspf[i - 2]) < .08)
return -1;
- }else
- {
- if(lspf[9] <= .66 || lspf[9] >= .985)
+ } else {
+ if (lspf[9] <= .66 || lspf[9] >= .985)
return -1;
- for(i=4; i<10; i++)
- if (fabs(lspf[i] - lspf[i-4]) < .0931)
+ for (i = 4; i < 10; i++)
+ if (fabs(lspf[i] - lspf[i - 4]) < .0931)
return -1;
}
}
@@ -204,82 +197,72 @@ static int decode_lspf(QCELPContext *q, float *lspf)
*
* TIA/EIA/IS-733 2.4.6.2
*/
-static void decode_gain_and_index(QCELPContext *q,
- float *gain) {
- int i, subframes_count, g1[16];
+static void decode_gain_and_index(QCELPContext *q, float *gain)
+{
+ int i, subframes_count, g1[16];
float slope;
- if(q->bitrate >= RATE_QUARTER)
- {
- switch(q->bitrate)
- {
- case RATE_FULL: subframes_count = 16; break;
- case RATE_HALF: subframes_count = 4; break;
- default: subframes_count = 5;
+ if (q->bitrate >= RATE_QUARTER) {
+ switch (q->bitrate) {
+ case RATE_FULL: subframes_count = 16; break;
+ case RATE_HALF: subframes_count = 4; break;
+ default: subframes_count = 5;
}
- for(i=0; i<subframes_count; i++)
- {
+ for (i = 0; i < subframes_count; i++) {
g1[i] = 4 * q->frame.cbgain[i];
- if(q->bitrate == RATE_FULL && !((i+1) & 3))
- {
- g1[i] += av_clip((g1[i-1] + g1[i-2] + g1[i-3]) / 3 - 6, 0, 32);
+ if (q->bitrate == RATE_FULL && !((i + 1) & 3)) {
+ g1[i] += av_clip((g1[i - 1] + g1[i - 2] + g1[i - 3]) / 3 - 6, 0, 32);
}
gain[i] = qcelp_g12ga[g1[i]];
- if(q->frame.cbsign[i])
- {
+ if (q->frame.cbsign[i]) {
gain[i] = -gain[i];
- q->frame.cindex[i] = (q->frame.cindex[i]-89) & 127;
+ q->frame.cindex[i] = (q->frame.cindex[i] - 89) & 127;
}
}
- q->prev_g1[0] = g1[i-2];
- q->prev_g1[1] = g1[i-1];
- q->last_codebook_gain = qcelp_g12ga[g1[i-1]];
+ q->prev_g1[0] = g1[i - 2];
+ q->prev_g1[1] = g1[i - 1];
+ q->last_codebook_gain = qcelp_g12ga[g1[i - 1]];
- if(q->bitrate == RATE_QUARTER)
- {
+ if (q->bitrate == RATE_QUARTER) {
// Provide smoothing of the unvoiced excitation energy.
- gain[7] = gain[4];
- gain[6] = 0.4*gain[3] + 0.6*gain[4];
- gain[5] = gain[3];
- gain[4] = 0.8*gain[2] + 0.2*gain[3];
- gain[3] = 0.2*gain[1] + 0.8*gain[2];
- gain[2] = gain[1];
- gain[1] = 0.6*gain[0] + 0.4*gain[1];
+ gain[7] = gain[4];
+ gain[6] = 0.4 * gain[3] + 0.6 * gain[4];
+ gain[5] = gain[3];
+ gain[4] = 0.8 * gain[2] + 0.2 * gain[3];
+ gain[3] = 0.2 * gain[1] + 0.8 * gain[2];
+ gain[2] = gain[1];
+ gain[1] = 0.6 * gain[0] + 0.4 * gain[1];
}
- }else if (q->bitrate != SILENCE)
- {
- if(q->bitrate == RATE_OCTAVE)
- {
- g1[0] = 2 * q->frame.cbgain[0]
- + av_clip((q->prev_g1[0] + q->prev_g1[1]) / 2 - 5, 0, 54);
+ } else if (q->bitrate != SILENCE) {
+ if (q->bitrate == RATE_OCTAVE) {
+ g1[0] = 2 * q->frame.cbgain[0] +
+ av_clip((q->prev_g1[0] + q->prev_g1[1]) / 2 - 5, 0, 54);
subframes_count = 8;
- }else
- {
+ } else {
assert(q->bitrate == I_F_Q);
g1[0] = q->prev_g1[1];
- switch(q->erasure_count)
- {
- case 1 : break;
- case 2 : g1[0] -= 1; break;
- case 3 : g1[0] -= 2; break;
- default: g1[0] -= 6;
+ switch (q->erasure_count) {
+ case 1 : break;
+ case 2 : g1[0] -= 1; break;
+ case 3 : g1[0] -= 2; break;
+ default: g1[0] -= 6;
}
- if(g1[0] < 0)
+ if (g1[0] < 0)
g1[0] = 0;
subframes_count = 4;
}
// This interpolation is done to produce smoother background noise.
- slope = 0.5*(qcelp_g12ga[g1[0]] - q->last_codebook_gain) / subframes_count;
- for(i=1; i<=subframes_count; i++)
- gain[i-1] = q->last_codebook_gain + slope * i;
+ slope = 0.5 * (qcelp_g12ga[g1[0]] - q->last_codebook_gain) / subframes_count;
+ for (i = 1; i <= subframes_count; i++)
+ gain[i - 1] = q->last_codebook_gain + slope * i;
- q->last_codebook_gain = gain[i-2];
- q->prev_g1[0] = q->prev_g1[1];
- q->prev_g1[1] = g1[0];
+ q->last_codebook_gain = gain[i - 2];
+ q->prev_g1[0] = q->prev_g1[1];
+ q->prev_g1[1] = g1[0];
}
}
@@ -294,14 +277,13 @@ static void decode_gain_and_index(QCELPContext *q,
*/
static int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain)
{
- int i, diff, prev_diff=0;
+ int i, diff, prev_diff = 0;
- for(i=1; i<5; i++)
- {
+ for (i = 1; i < 5; i++) {
diff = cbgain[i] - cbgain[i-1];
- if(FFABS(diff) > 10)
+ if (FFABS(diff) > 10)
return -1;
- else if(FFABS(diff - prev_diff) > 12)
+ else if (FFABS(diff - prev_diff) > 12)
return -1;
prev_diff = diff;
}
@@ -332,81 +314,74 @@ static int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain)
static void compute_svector(QCELPContext *q, const float *gain,
float *cdn_vector)
{
- int i, j, k;
+ int i, j, k;
uint16_t cbseed, cindex;
- float *rnd, tmp_gain, fir_filter_value;
-
- switch(q->bitrate)
- {
- case RATE_FULL:
- for(i=0; i<16; i++)
- {
- tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
- cindex = -q->frame.cindex[i];
- for(j=0; j<10; j++)
- *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cindex++ & 127];
- }
+ float *rnd, tmp_gain, fir_filter_value;
+
+ switch (q->bitrate) {
+ case RATE_FULL:
+ for (i = 0; i < 16; i++) {
+ tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
+ cindex = -q->frame.cindex[i];
+ for (j = 0; j < 10; j++)
+ *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cindex++ & 127];
+ }
break;
- case RATE_HALF:
- for(i=0; i<4; i++)
- {
- tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO;
- cindex = -q->frame.cindex[i];
- for (j = 0; j < 40; j++)
+ case RATE_HALF:
+ for (i = 0; i < 4; i++) {
+ tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO;
+ cindex = -q->frame.cindex[i];
+ for (j = 0; j < 40; j++)
*cdn_vector++ = tmp_gain * qcelp_rate_half_codebook[cindex++ & 127];
- }
+ }
break;
- case RATE_QUARTER:
- cbseed = (0x0003 & q->frame.lspv[4])<<14 |
- (0x003F & q->frame.lspv[3])<< 8 |
- (0x0060 & q->frame.lspv[2])<< 1 |
- (0x0007 & q->frame.lspv[1])<< 3 |
- (0x0038 & q->frame.lspv[0])>> 3 ;
- rnd = q->rnd_fir_filter_mem + 20;
- for(i=0; i<8; i++)
- {
- tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0);
- for(k=0; k<20; k++)
- {
- cbseed = 521 * cbseed + 259;
- *rnd = (int16_t)cbseed;
+ case RATE_QUARTER:
+ cbseed = (0x0003 & q->frame.lspv[4]) << 14 |
+ (0x003F & q->frame.lspv[3]) << 8 |
+ (0x0060 & q->frame.lspv[2]) << 1 |
+ (0x0007 & q->frame.lspv[1]) << 3 |
+ (0x0038 & q->frame.lspv[0]) >> 3;
+ rnd = q->rnd_fir_filter_mem + 20;
+ for (i = 0; i < 8; i++) {
+ tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0);
+ for (k = 0; k < 20; k++) {
+ cbseed = 521 * cbseed + 259;
+ *rnd = (int16_t) cbseed;
// FIR filter
- fir_filter_value = 0.0;
- for(j=0; j<10; j++)
- fir_filter_value += qcelp_rnd_fir_coefs[j ]
- * (rnd[-j ] + rnd[-20+j]);
-
- fir_filter_value += qcelp_rnd_fir_coefs[10] * rnd[-10];
- *cdn_vector++ = tmp_gain * fir_filter_value;
- rnd++;
- }
+ fir_filter_value = 0.0;
+ for (j = 0; j < 10; j++)
+ fir_filter_value += qcelp_rnd_fir_coefs[j] *
+ (rnd[-j] + rnd[-20+j]);
+
+ fir_filter_value += qcelp_rnd_fir_coefs[10] * rnd[-10];
+ *cdn_vector++ = tmp_gain * fir_filter_value;
+ rnd++;
}
- memcpy(q->rnd_fir_filter_mem, q->rnd_fir_filter_mem + 160, 20 * sizeof(float));
+ }
+ memcpy(q->rnd_fir_filter_mem, q->rnd_fir_filter_mem + 160,
+ 20 * sizeof(float));
break;
- case RATE_OCTAVE:
- cbseed = q->first16bits;
- for(i=0; i<8; i++)
- {
- tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0);
- for(j=0; j<20; j++)
- {
- cbseed = 521 * cbseed + 259;
- *cdn_vector++ = tmp_gain * (int16_t)cbseed;
- }
+ case RATE_OCTAVE:
+ cbseed = q->first16bits;
+ for (i = 0; i < 8; i++) {
+ tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0);
+ for (j = 0; j < 20; j++) {
+ cbseed = 521 * cbseed + 259;
+ *cdn_vector++ = tmp_gain * (int16_t) cbseed;
}
+ }
break;
- case I_F_Q:
- cbseed = -44; // random codebook index
- for(i=0; i<4; i++)
- {
- tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
- for(j=0; j<40; j++)
- *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cbseed++ & 127];
- }
+ case I_F_Q:
+ cbseed = -44; // random codebook index
+ for (i = 0; i < 4; i++) {
+ tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
+ for (j = 0; j < 40; j++)
+ *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cbseed++ & 127];
+ }
break;
- case SILENCE:
- memset(cdn_vector, 0, 160 * sizeof(float));
+ case SILENCE:
+ memset(cdn_vector, 0, 160 * sizeof(float));
break;
}
}
@@ -420,8 +395,7 @@ static void compute_svector(QCELPContext *q, const float *gain,
*
* TIA/EIA/IS-733 2.4.8.3, 2.4.8.6
*/
-static void apply_gain_ctrl(float *v_out, const float *v_ref,
- const float *v_in)
+static void apply_gain_ctrl(float *v_out, const float *v_ref, const float *v_in)
{
int i;
@@ -453,24 +427,20 @@ static const float *do_pitchfilter(float memory[303], const float v_in[160],
const float gain[4], const uint8_t *lag,
const uint8_t pfrac[4])
{
- int i, j;
- float *v_lag, *v_out;
+ int i, j;
+ float *v_lag, *v_out;
const float *v_len;
v_out = memory + 143; // Output vector starts at memory[143].
- for(i=0; i<4; i++)
- {
- if(gain[i])
- {
+ for (i = 0; i < 4; i++) {
+ if (gain[i]) {
v_lag = memory + 143 + 40 * i - lag[i];
- for(v_len=v_in+40; v_in<v_len; v_in++)
- {
- if(pfrac[i]) // If it is a fractional lag...
- {
- for(j=0, *v_out=0.; j<4; j++)
- *v_out += qcelp_hammsinc_table[j] * (v_lag[j-4] + v_lag[3-j]);
- }else
+ for (v_len = v_in + 40; v_in < v_len; v_in++) {
+ if (pfrac[i]) { // If it is a fractional lag...
+ for (j = 0, *v_out = 0.; j < 4; j++)
+ *v_out += qcelp_hammsinc_table[j] * (v_lag[j - 4] + v_lag[3 - j]);
+ } else
*v_out = *v_lag;
*v_out = *v_in + gain[i] * *v_out;
@@ -478,8 +448,7 @@ static const float *do_pitchfilter(float memory[303], const float v_in[160],
v_lag++;
v_out++;
}
- }else
- {
+ } else {
memcpy(v_out, v_in, 40 * sizeof(float));
v_in += 40;
v_out += 40;
@@ -499,40 +468,32 @@ static const float *do_pitchfilter(float memory[303], const float v_in[160],
*/
static void apply_pitch_filters(QCELPContext *q, float *cdn_vector)
{
- int i;
+ int i;
const float *v_synthesis_filtered, *v_pre_filtered;
- if(q->bitrate >= RATE_HALF ||
- q->bitrate == SILENCE ||
- (q->bitrate == I_F_Q && (q->prev_bitrate >= RATE_HALF)))
- {
-
- if(q->bitrate >= RATE_HALF)
- {
+ if (q->bitrate >= RATE_HALF || q->bitrate == SILENCE ||
+ (q->bitrate == I_F_Q && (q->prev_bitrate >= RATE_HALF))) {
+ if (q->bitrate >= RATE_HALF) {
// Compute gain & lag for the whole frame.
- for(i=0; i<4; i++)
- {
+ for (i = 0; i < 4; i++) {
q->pitch_gain[i] = q->frame.plag[i] ? (q->frame.pgain[i] + 1) * 0.25 : 0.0;
q->pitch_lag[i] = q->frame.plag[i] + 16;
}
- }else
- {
+ } else {
float max_pitch_gain;
- if (q->bitrate == I_F_Q)
- {
+ if (q->bitrate == I_F_Q) {
if (q->erasure_count < 3)
max_pitch_gain = 0.9 - 0.3 * (q->erasure_count - 1);
else
max_pitch_gain = 0.0;
- }else
- {
+ } else {
assert(q->bitrate == SILENCE);
max_pitch_gain = 1.0;
}
- for(i=0; i<4; i++)
+ for (i = 0; i < 4; i++)
q->pitch_gain[i] = FFMIN(q->pitch_gain[i], max_pitch_gain);
memset(q->frame.pfrac, 0, sizeof(q->frame.pfrac));
@@ -544,19 +505,17 @@ static void apply_pitch_filters(QCELPContext *q, float *cdn_vector)
q->pitch_lag, q->frame.pfrac);
// pitch prefilter update
- for(i=0; i<4; i++)
+ for (i = 0; i < 4; i++)
q->pitch_gain[i] = 0.5 * FFMIN(q->pitch_gain[i], 1.0);
- v_pre_filtered = do_pitchfilter(q->pitch_pre_filter_mem,
- v_synthesis_filtered,
- q->pitch_gain, q->pitch_lag,
- q->frame.pfrac);
+ v_pre_filtered = do_pitchfilter(q->pitch_pre_filter_mem,
+ v_synthesis_filtered,
+ q->pitch_gain, q->pitch_lag,
+ q->frame.pfrac);
apply_gain_ctrl(cdn_vector, v_synthesis_filtered, v_pre_filtered);
- }else
- {
- memcpy(q->pitch_synthesis_filter_mem, cdn_vector + 17,
- 143 * sizeof(float));
+ } else {
+ memcpy(q->pitch_synthesis_filter_mem, cdn_vector + 17, 143 * sizeof(float));
memcpy(q->pitch_pre_filter_mem, cdn_vector + 17, 143 * sizeof(float));
memset(q->pitch_gain, 0, sizeof(q->pitch_gain));
memset(q->pitch_lag, 0, sizeof(q->pitch_lag));
@@ -579,16 +538,15 @@ static void lspf2lpc(const float *lspf, float *lpc)
{
double lsp[10];
double bandwidth_expansion_coeff = QCELP_BANDWIDTH_EXPANSION_COEFF;
- int i;
+ int i;
- for (i=0; i<10; i++)
+ for (i = 0; i < 10; i++)
lsp[i] = cos(M_PI * lspf[i]);
ff_acelp_lspd2lpc(lsp, lpc, 5);
- for (i=0; i<10; i++)
- {
- lpc[i] *= bandwidth_expansion_coeff;
+ for (i = 0; i < 10; i++) {
+ lpc[i] *= bandwidth_expansion_coeff;
bandwidth_expansion_coeff *= QCELP_BANDWIDTH_EXPANSION_COEFF;
}
}
@@ -610,34 +568,32 @@ static void interpolate_lpc(QCELPContext *q, const float *curr_lspf,
float interpolated_lspf[10];
float weight;
- if(q->bitrate >= RATE_QUARTER)
+ if (q->bitrate >= RATE_QUARTER)
weight = 0.25 * (subframe_num + 1);
- else if(q->bitrate == RATE_OCTAVE && !subframe_num)
+ else if (q->bitrate == RATE_OCTAVE && !subframe_num)
weight = 0.625;
else
weight = 1.0;
- if(weight != 1.0)
- {
+ if (weight != 1.0) {
ff_weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf,
weight, 1.0 - weight, 10);
lspf2lpc(interpolated_lspf, lpc);
- }else if(q->bitrate >= RATE_QUARTER ||
- (q->bitrate == I_F_Q && !subframe_num))
+ } else if (q->bitrate >= RATE_QUARTER ||
+ (q->bitrate == I_F_Q && !subframe_num))
lspf2lpc(curr_lspf, lpc);
- else if(q->bitrate == SILENCE && !subframe_num)
+ else if (q->bitrate == SILENCE && !subframe_num)
lspf2lpc(q->prev_lspf, lpc);
}
static qcelp_packet_rate buf_size2bitrate(const int buf_size)
{
- switch(buf_size)
- {
- case 35: return RATE_FULL;
- case 17: return RATE_HALF;
- case 8: return RATE_QUARTER;
- case 4: return RATE_OCTAVE;
- case 1: return SILENCE;
+ switch (buf_size) {
+ case 35: return RATE_FULL;
+ case 17: return RATE_HALF;
+ case 8: return RATE_QUARTER;
+ case 4: return RATE_OCTAVE;
+ case 1: return SILENCE;
}
return I_F_Q;
@@ -655,39 +611,34 @@ static qcelp_packet_rate buf_size2bitrate(const int buf_size)
*
* TIA/EIA/IS-733 2.4.8.7.1
*/
-static qcelp_packet_rate determine_bitrate(AVCodecContext *avctx, const int buf_size,
- const uint8_t **buf)
+static qcelp_packet_rate determine_bitrate(AVCodecContext *avctx,
+ const int buf_size,
+ const uint8_t **buf)
{
qcelp_packet_rate bitrate;
- if((bitrate = buf_size2bitrate(buf_size)) >= 0)
- {
- if(bitrate > **buf)
- {
+ if ((bitrate = buf_size2bitrate(buf_size)) >= 0) {
+ if (bitrate > **buf) {
QCELPContext *q = avctx->priv_data;
- if (!q->warned_buf_mismatch_bitrate)
- {
+ if (!q->warned_buf_mismatch_bitrate) {
av_log(avctx, AV_LOG_WARNING,
"Claimed bitrate and buffer size mismatch.\n");
q->warned_buf_mismatch_bitrate = 1;
}
bitrate = **buf;
- }else if(bitrate < **buf)
- {
+ } else if (bitrate < **buf) {
av_log(avctx, AV_LOG_ERROR,
"Buffer is too small for the claimed bitrate.\n");
return I_F_Q;
}
(*buf)++;
- }else if((bitrate = buf_size2bitrate(buf_size + 1)) >= 0)
- {
+ } else if ((bitrate = buf_size2bitrate(buf_size + 1)) >= 0) {
av_log(avctx, AV_LOG_WARNING,
"Bitrate byte is missing, guessing the bitrate from packet size.\n");
- }else
+ } else
return I_F_Q;
- if(bitrate == SILENCE)
- {
+ if (bitrate == SILENCE) {
//FIXME: Remove experimental warning when tested with samples.
av_log_ask_for_sample(avctx, "'Blank frame handling is experimental.");
}
@@ -697,8 +648,8 @@ static qcelp_packet_rate determine_bitrate(AVCodecContext *avctx, const int buf_
static void warn_insufficient_frame_quality(AVCodecContext *avctx,
const char *message)
{
- av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n", avctx->frame_number,
- message);
+ av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n",
+ avctx->frame_number, message);
}
static void postfilter(QCELPContext *q, float *samples, float *lpc)
@@ -720,75 +671,76 @@ static void postfilter(QCELPContext *q, float *samples, float *lpc)
ff_celp_lp_zero_synthesis_filterf(zero_out, lpc_s,
q->formant_mem + 10, 160, 10);
- memcpy(pole_out, q->postfilter_synth_mem, sizeof(float) * 10);
+ memcpy(pole_out, q->postfilter_synth_mem, sizeof(float) * 10);
ff_celp_lp_synthesis_filterf(pole_out + 10, lpc_p, zero_out, 160, 10);
memcpy(q->postfilter_synth_mem, pole_out + 160, sizeof(float) * 10);
ff_tilt_compensation(&q->postfilter_tilt_mem, 0.3, pole_out + 10, 160);
ff_adaptive_gain_control(samples, pole_out + 10,
- ff_dot_productf(q->formant_mem + 10, q->formant_mem + 10, 160),
- 160, 0.9375, &q->postfilter_agc_mem);
+ ff_dot_productf(q->formant_mem + 10,
+ q->formant_mem + 10, 160),
+ 160, 0.9375, &q->postfilter_agc_mem);
}
-static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
- AVPacket *avpkt)
+static int qcelp_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- QCELPContext *q = avctx->priv_data;
- float *outbuffer = data;
- int i;
+ int buf_size = avpkt->size;
+ QCELPContext *q = avctx->priv_data;
+ float *outbuffer;
+ int i, ret;
float quantized_lspf[10], lpc[10];
float gain[16];
float *formant_mem;
- if((q->bitrate = determine_bitrate(avctx, buf_size, &buf)) == I_F_Q)
- {
+ /* get output buffer */
+ q->avframe.nb_samples = 160;
+ if ((ret = avctx->get_buffer(avctx, &q->avframe)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ outbuffer = (float *)q->avframe.data[0];
+
+ if ((q->bitrate = determine_bitrate(avctx, buf_size, &buf)) == I_F_Q) {
warn_insufficient_frame_quality(avctx, "bitrate cannot be determined.");
goto erasure;
}
- if(q->bitrate == RATE_OCTAVE &&
- (q->first16bits = AV_RB16(buf)) == 0xFFFF)
- {
+ if (q->bitrate == RATE_OCTAVE &&
+ (q->first16bits = AV_RB16(buf)) == 0xFFFF) {
warn_insufficient_frame_quality(avctx, "Bitrate is 1/8 and first 16 bits are on.");
goto erasure;
}
- if(q->bitrate > SILENCE)
- {
+ if (q->bitrate > SILENCE) {
const QCELPBitmap *bitmaps = qcelp_unpacking_bitmaps_per_rate[q->bitrate];
- const QCELPBitmap *bitmaps_end = qcelp_unpacking_bitmaps_per_rate[q->bitrate]
- + qcelp_unpacking_bitmaps_lengths[q->bitrate];
- uint8_t *unpacked_data = (uint8_t *)&q->frame;
+ const QCELPBitmap *bitmaps_end = qcelp_unpacking_bitmaps_per_rate[q->bitrate] +
+ qcelp_unpacking_bitmaps_lengths[q->bitrate];
+ uint8_t *unpacked_data = (uint8_t *)&q->frame;
- init_get_bits(&q->gb, buf, 8*buf_size);
+ init_get_bits(&q->gb, buf, 8 * buf_size);
memset(&q->frame, 0, sizeof(QCELPFrame));
- for(; bitmaps < bitmaps_end; bitmaps++)
+ for (; bitmaps < bitmaps_end; bitmaps++)
unpacked_data[bitmaps->index] |= get_bits(&q->gb, bitmaps->bitlen) << bitmaps->bitpos;
// Check for erasures/blanks on rates 1, 1/4 and 1/8.
- if(q->frame.reserved)
- {
+ if (q->frame.reserved) {
warn_insufficient_frame_quality(avctx, "Wrong data in reserved frame area.");
goto erasure;
}
- if(q->bitrate == RATE_QUARTER &&
- codebook_sanity_check_for_rate_quarter(q->frame.cbgain))
- {
+ if (q->bitrate == RATE_QUARTER &&
+ codebook_sanity_check_for_rate_quarter(q->frame.cbgain)) {
warn_insufficient_frame_quality(avctx, "Codebook gain sanity check failed.");
goto erasure;
}
- if(q->bitrate >= RATE_HALF)
- {
- for(i=0; i<4; i++)
- {
- if(q->frame.pfrac[i] && q->frame.plag[i] >= 124)
- {
+ if (q->bitrate >= RATE_HALF) {
+ for (i = 0; i < 4; i++) {
+ if (q->frame.pfrac[i] && q->frame.plag[i] >= 124) {
warn_insufficient_frame_quality(avctx, "Cannot initialize pitch filter.");
goto erasure;
}
@@ -799,17 +751,14 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
decode_gain_and_index(q, gain);
compute_svector(q, gain, outbuffer);
- if(decode_lspf(q, quantized_lspf) < 0)
- {
+ if (decode_lspf(q, quantized_lspf) < 0) {
warn_insufficient_frame_quality(avctx, "Badly received packets in frame.");
goto erasure;
}
-
apply_pitch_filters(q, outbuffer);
- if(q->bitrate == I_F_Q)
- {
+ if (q->bitrate == I_F_Q) {
erasure:
q->bitrate = I_F_Q;
q->erasure_count++;
@@ -817,15 +766,13 @@ erasure:
compute_svector(q, gain, outbuffer);
decode_lspf(q, quantized_lspf);
apply_pitch_filters(q, outbuffer);
- }else
+ } else
q->erasure_count = 0;
formant_mem = q->formant_mem + 10;
- for(i=0; i<4; i++)
- {
+ for (i = 0; i < 4; i++) {
interpolate_lpc(q, quantized_lspf, lpc, i);
- ff_celp_lp_synthesis_filterf(formant_mem, lpc, outbuffer + i * 40, 40,
- 10);
+ ff_celp_lp_synthesis_filterf(formant_mem, lpc, outbuffer + i * 40, 40, 10);
formant_mem += 40;
}
@@ -835,20 +782,21 @@ erasure:
memcpy(q->formant_mem, q->formant_mem + 160, 10 * sizeof(float));
memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf));
- q->prev_bitrate = q->bitrate;
+ q->prev_bitrate = q->bitrate;
- *data_size = 160 * sizeof(*outbuffer);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = q->avframe;
- return *data_size;
+ return buf_size;
}
-AVCodec ff_qcelp_decoder =
-{
- .name = "qcelp",
- .type = AVMEDIA_TYPE_AUDIO,
- .id = CODEC_ID_QCELP,
- .init = qcelp_decode_init,
- .decode = qcelp_decode_frame,
+AVCodec ff_qcelp_decoder = {
+ .name = "qcelp",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_QCELP,
+ .init = qcelp_decode_init,
+ .decode = qcelp_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.priv_data_size = sizeof(QCELPContext),
- .long_name = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"),
+ .long_name = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"),
};
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index 7e7051f..91c47a8 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -26,6 +26,7 @@
* @file
* QDM2 decoder
* @author Ewald Snel, Benjamin Larsson, Alex Beregszaszi, Roberto Togni
+ *
* The decoder is not perfect yet, there are still some distortions
* especially on files encoded with 16 or 8 subbands.
*/
@@ -34,7 +35,7 @@
#include <stddef.h>
#include <stdio.h>
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
@@ -129,6 +130,8 @@ typedef struct {
* QDM2 decoder context
*/
typedef struct {
+ AVFrame frame;
+
/// Parameters from codec header, do not change during playback
int nb_channels; ///< number of channels
int channels; ///< number of channels
@@ -1874,6 +1877,9 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
// dump_context(s);
return 0;
}
@@ -1951,30 +1957,27 @@ static int qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out)
}
-static int qdm2_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int qdm2_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
QDM2Context *s = avctx->priv_data;
- int16_t *out = data;
- int i, out_size;
+ int16_t *out;
+ int i, ret;
if(!buf)
return 0;
if(buf_size < s->checksum_size)
return -1;
- out_size = 16 * s->channels * s->frame_size *
- av_get_bytes_per_sample(avctx->sample_fmt);
- if (*data_size < out_size) {
- av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
- return AVERROR(EINVAL);
+ /* get output buffer */
+ s->frame.nb_samples = 16 * s->frame_size;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
-
- av_log(avctx, AV_LOG_DEBUG, "decode(%d): %p[%d] -> %p[%d]\n",
- buf_size, buf, s->checksum_size, data, *data_size);
+ out = (int16_t *)s->frame.data[0];
for (i = 0; i < 16; i++) {
if (qdm2_decode(s, buf, out) < 0)
@@ -1982,7 +1985,8 @@ static int qdm2_decode_frame(AVCodecContext *avctx,
out += s->channels * s->frame_size;
}
- *data_size = out_size;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
return s->checksum_size;
}
@@ -1996,5 +2000,6 @@ AVCodec ff_qdm2_decoder =
.init = qdm2_decode_init,
.close = qdm2_decode_close,
.decode = qdm2_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"),
};
diff --git a/libavcodec/qdm2_tablegen.h b/libavcodec/qdm2_tablegen.h
index b2bb294..bb73d92 100644
--- a/libavcodec/qdm2_tablegen.h
+++ b/libavcodec/qdm2_tablegen.h
@@ -90,7 +90,7 @@ static av_cold void rnd_table_init(void) {
static av_cold void init_noise_samples(void) {
int i;
- int random_seed = 0;
+ unsigned random_seed = 0;
float delta = 1.0 / 16384.0;
for (i = 0; i < 128;i++) {
random_seed = random_seed * 214013 + 2531011;
diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c
index 07ac9aa..7410f6e 100644
--- a/libavcodec/qdrw.c
+++ b/libavcodec/qdrw.c
@@ -37,6 +37,7 @@ static int decode_frame(AVCodecContext *avctx,
AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
+ const uint8_t *buf_end = avpkt->data + avpkt->size;
int buf_size = avpkt->size;
QdrawContext * const a = avctx->priv_data;
AVFrame * const p= (AVFrame*)&a->pic;
@@ -59,6 +60,8 @@ static int decode_frame(AVCodecContext *avctx,
outdata = a->pic.data[0];
+ if (buf_end - buf < 0x68 + 4)
+ return AVERROR_INVALIDDATA;
buf += 0x68; /* jump to palette */
colors = AV_RB32(buf);
buf += 4;
@@ -67,6 +70,8 @@ static int decode_frame(AVCodecContext *avctx,
av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors);
return -1;
}
+ if (buf_end - buf < (colors + 1) * 8)
+ return AVERROR_INVALIDDATA;
pal = (uint32_t*)p->data[1];
for (i = 0; i <= colors; i++) {
@@ -89,6 +94,8 @@ static int decode_frame(AVCodecContext *avctx,
}
p->palette_has_changed = 1;
+ if (buf_end - buf < 18)
+ return AVERROR_INVALIDDATA;
buf += 18; /* skip unneeded data */
for (i = 0; i < avctx->height; i++) {
int size, left, code, pix;
@@ -100,6 +107,9 @@ static int decode_frame(AVCodecContext *avctx,
out = outdata;
size = AV_RB16(buf); /* size of packed line */
buf += 2;
+ if (buf_end - buf < size)
+ return AVERROR_INVALIDDATA;
+
left = size;
next = buf + size;
while (left > 0) {
@@ -115,6 +125,8 @@ static int decode_frame(AVCodecContext *avctx,
} else { /* copy */
if ((out + code) > (outdata + a->pic.linesize[0]))
break;
+ if (buf_end - buf < code + 1)
+ return AVERROR_INVALIDDATA;
memcpy(out, buf, code + 1);
out += code + 1;
buf += code + 1;
@@ -151,14 +163,13 @@ static av_cold int decode_end(AVCodecContext *avctx){
}
AVCodec ff_qdraw_decoder = {
- "qdraw",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_QDRAW,
- sizeof(QdrawContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "qdraw",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_QDRAW,
+ .priv_data_size = sizeof(QdrawContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Apple QuickDraw"),
};
diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c
index 5dd2a2d..9513dd0 100644
--- a/libavcodec/qpeg.c
+++ b/libavcodec/qpeg.c
@@ -307,14 +307,13 @@ static av_cold int decode_end(AVCodecContext *avctx){
}
AVCodec ff_qpeg_decoder = {
- "qpeg",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_QPEG,
- sizeof(QpegContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "qpeg",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_QPEG,
+ .priv_data_size = sizeof(QpegContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Q-team QPEG"),
};
diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c
index e14c306..0c74798 100644
--- a/libavcodec/qtrle.c
+++ b/libavcodec/qtrle.c
@@ -328,7 +328,6 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int
int rle_code;
int pixel_ptr;
int row_inc = s->frame.linesize[0];
- unsigned char a, r, g, b;
unsigned int argb;
unsigned char *rgb = s->frame.data[0];
int pixel_limit = s->frame.linesize[0] * s->avctx->height;
@@ -347,16 +346,13 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int
/* decode the run length code */
rle_code = -rle_code;
CHECK_STREAM_PTR(4);
- a = s->buf[stream_ptr++];
- r = s->buf[stream_ptr++];
- g = s->buf[stream_ptr++];
- b = s->buf[stream_ptr++];
- argb = (a << 24) | (r << 16) | (g << 8) | (b << 0);
+ argb = AV_RB32(s->buf + stream_ptr);
+ stream_ptr += 4;
CHECK_PIXEL_PTR(rle_code * 4);
while (rle_code--) {
- *(unsigned int *)(&rgb[pixel_ptr]) = argb;
+ AV_WN32A(rgb + pixel_ptr, argb);
pixel_ptr += 4;
}
} else {
@@ -365,13 +361,10 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int
/* copy pixels directly to output */
while (rle_code--) {
- a = s->buf[stream_ptr++];
- r = s->buf[stream_ptr++];
- g = s->buf[stream_ptr++];
- b = s->buf[stream_ptr++];
- argb = (a << 24) | (r << 16) | (g << 8) | (b << 0);
- *(unsigned int *)(&rgb[pixel_ptr]) = argb;
- pixel_ptr += 4;
+ argb = AV_RB32(s->buf + stream_ptr);
+ AV_WN32A(rgb + pixel_ptr, argb);
+ stream_ptr += 4;
+ pixel_ptr += 4;
}
}
}
@@ -542,15 +535,14 @@ static av_cold int qtrle_decode_end(AVCodecContext *avctx)
}
AVCodec ff_qtrle_decoder = {
- "qtrle",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_QTRLE,
- sizeof(QtrleContext),
- qtrle_decode_init,
- NULL,
- qtrle_decode_end,
- qtrle_decode_frame,
- CODEC_CAP_DR1,
+ .name = "qtrle",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_QTRLE,
+ .priv_data_size = sizeof(QtrleContext),
+ .init = qtrle_decode_init,
+ .close = qtrle_decode_end,
+ .decode = qtrle_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
};
diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c
index 3cad37f..ede03d2 100644
--- a/libavcodec/qtrleenc.c
+++ b/libavcodec/qtrleenc.c
@@ -322,13 +322,13 @@ static av_cold int qtrle_encode_end(AVCodecContext *avctx)
}
AVCodec ff_qtrle_encoder = {
- "qtrle",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_QTRLE,
- sizeof(QtrleEncContext),
- qtrle_encode_init,
- qtrle_encode_frame,
- qtrle_encode_end,
+ .name = "qtrle",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_QTRLE,
+ .priv_data_size = sizeof(QtrleEncContext),
+ .init = qtrle_encode_init,
+ .encode = qtrle_encode_frame,
+ .close = qtrle_encode_end,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB555BE, PIX_FMT_ARGB, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
};
diff --git a/libavcodec/r210dec.c b/libavcodec/r210dec.c
index 9d5f7ee..0f85f58 100644
--- a/libavcodec/r210dec.c
+++ b/libavcodec/r210dec.c
@@ -98,29 +98,25 @@ static av_cold int decode_close(AVCodecContext *avctx)
#if CONFIG_R210_DECODER
AVCodec ff_r210_decoder = {
- "r210",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_R210,
- 0,
- decode_init,
- NULL,
- decode_close,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "r210",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_R210,
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"),
};
#endif
#if CONFIG_R10K_DECODER
AVCodec ff_r10k_decoder = {
- "r10k",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_R10K,
- 0,
- decode_init,
- NULL,
- decode_close,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "r10k",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_R10K,
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"),
};
#endif
diff --git a/libavcodec/ra144.c b/libavcodec/ra144.c
index fd2ed32..e6442d6 100644
--- a/libavcodec/ra144.c
+++ b/libavcodec/ra144.c
@@ -1544,22 +1544,22 @@ void ff_copy_and_dup(int16_t *target, const int16_t *source, int offset)
int ff_eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
{
int b, i, j;
- int buffer1[10];
- int buffer2[10];
+ int buffer1[LPC_ORDER];
+ int buffer2[LPC_ORDER];
int *bp1 = buffer1;
int *bp2 = buffer2;
- for (i=0; i < 10; i++)
+ for (i=0; i < LPC_ORDER; i++)
buffer2[i] = coefs[i];
- refl[9] = bp2[9];
+ refl[LPC_ORDER-1] = bp2[LPC_ORDER-1];
- if ((unsigned) bp2[9] + 0x1000 > 0x1fff) {
+ if ((unsigned) bp2[LPC_ORDER-1] + 0x1000 > 0x1fff) {
av_log(avctx, AV_LOG_ERROR, "Overflow. Broken sample?\n");
return 1;
}
- for (i=8; i >= 0; i--) {
+ for (i = LPC_ORDER-2; i >= 0; i--) {
b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12);
if (!b)
@@ -1584,12 +1584,12 @@ int ff_eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
*/
void ff_eval_coefs(int *coefs, const int *refl)
{
- int buffer[10];
+ int buffer[LPC_ORDER];
int *b1 = buffer;
int *b2 = coefs;
int i, j;
- for (i=0; i < 10; i++) {
+ for (i=0; i < LPC_ORDER; i++) {
b1[i] = refl[i] << 4;
for (j=0; j < i; j++)
@@ -1598,7 +1598,7 @@ void ff_eval_coefs(int *coefs, const int *refl)
FFSWAP(int *, b1, b2);
}
- for (i=0; i < 10; i++)
+ for (i=0; i < LPC_ORDER; i++)
coefs[i] >>= 4;
}
@@ -1606,7 +1606,7 @@ void ff_int_to_int16(int16_t *out, const int *inp)
{
int i;
- for (i=0; i < 10; i++)
+ for (i = 0; i < LPC_ORDER; i++)
*out++ = *inp++;
}
@@ -1629,9 +1629,9 @@ unsigned int ff_rms(const int *data)
{
int i;
unsigned int res = 0x10000;
- int b = 10;
+ int b = LPC_ORDER;
- for (i=0; i < 10; i++) {
+ for (i = 0; i < LPC_ORDER; i++) {
res = (((0x1000000 - data[i]*data[i]) >> 12) * res) >> 12;
if (res == 0)
@@ -1648,13 +1648,13 @@ unsigned int ff_rms(const int *data)
int ff_interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy)
{
- int work[10];
+ int work[LPC_ORDER];
int b = NBLOCKS - a;
int i;
// Interpolate block coefficients from the this frame's forth block and
// last frame's forth block.
- for (i=0; i<10; i++)
+ for (i = 0; i < LPC_ORDER; i++)
out[i] = (a * ractx->lpc_coef[0][i] + b * ractx->lpc_coef[1][i])>> 2;
if (ff_eval_refl(work, out, ractx->avctx)) {
@@ -1690,7 +1690,7 @@ void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs,
int cba_idx, int cb1_idx, int cb2_idx,
int gval, int gain)
{
- uint16_t buffer_a[40];
+ uint16_t buffer_a[BLOCKSIZE];
uint16_t *block;
int m[3];
@@ -1711,10 +1711,10 @@ void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs,
ff_add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL,
ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);
- memcpy(ractx->curr_sblock, ractx->curr_sblock + 40,
- 10*sizeof(*ractx->curr_sblock));
+ memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE,
+ LPC_ORDER*sizeof(*ractx->curr_sblock));
- if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + 10, lpc_coefs,
- block, BLOCKSIZE, 10, 1, 0xfff))
- memset(ractx->curr_sblock, 0, 50*sizeof(*ractx->curr_sblock));
+ if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + LPC_ORDER, lpc_coefs,
+ block, BLOCKSIZE, LPC_ORDER, 1, 0xfff))
+ memset(ractx->curr_sblock, 0, (LPC_ORDER+BLOCKSIZE)*sizeof(*ractx->curr_sblock));
}
diff --git a/libavcodec/ra144.h b/libavcodec/ra144.h
index dcdfbb8..f6475d4 100644
--- a/libavcodec/ra144.h
+++ b/libavcodec/ra144.h
@@ -34,6 +34,7 @@
typedef struct {
AVCodecContext *avctx;
+ AVFrame frame;
LPCContext lpc_ctx;
unsigned int old_energy; ///< previous frame energy
diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c
index e64b6c2..dd8838c 100644
--- a/libavcodec/ra144dec.c
+++ b/libavcodec/ra144dec.c
@@ -38,6 +38,10 @@ static av_cold int ra144_decode_init(AVCodecContext * avctx)
ractx->lpc_coef[1] = ractx->lpc_tables[1];
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ avcodec_get_frame_defaults(&ractx->frame);
+ avctx->coded_frame = &ractx->frame;
+
return 0;
}
@@ -54,34 +58,40 @@ static void do_output_subblock(RA144Context *ractx, const uint16_t *lpc_coefs,
}
/** Uncompress one block (20 bytes -> 160*2 bytes). */
-static int ra144_decode_frame(AVCodecContext * avctx, void *vdata,
- int *data_size, AVPacket *avpkt)
+static int ra144_decode_frame(AVCodecContext * avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->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
- uint16_t block_coefs[4][10]; // LPC coefficients of each sub-block
- unsigned int lpc_refl[10]; // LPC reflection coefficients of the frame
+ static const uint8_t sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
+ unsigned int refl_rms[NBLOCKS]; // RMS of the reflection coefficients
+ uint16_t block_coefs[NBLOCKS][LPC_ORDER]; // LPC coefficients of each sub-block
+ unsigned int lpc_refl[LPC_ORDER]; // LPC reflection coefficients of the frame
int i, j;
- int16_t *data = vdata;
+ int ret;
+ int16_t *samples;
unsigned int energy;
RA144Context *ractx = avctx->priv_data;
GetBitContext gb;
- if (*data_size < 2*160)
- return -1;
+ /* get output buffer */
+ ractx->frame.nb_samples = NBLOCKS * BLOCKSIZE;
+ if ((ret = avctx->get_buffer(avctx, &ractx->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (int16_t *)ractx->frame.data[0];
- if(buf_size < 20) {
+ if(buf_size < FRAMESIZE) {
av_log(avctx, AV_LOG_ERROR,
"Frame too small (%d bytes). Truncated file?\n", buf_size);
- *data_size = 0;
+ *got_frame_ptr = 0;
return buf_size;
}
- init_get_bits(&gb, buf, 20 * 8);
+ init_get_bits(&gb, buf, FRAMESIZE * 8);
- for (i=0; i<10; i++)
+ for (i = 0; i < LPC_ORDER; i++)
lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])];
ff_eval_coefs(ractx->lpc_coef[0], lpc_refl);
@@ -98,11 +108,11 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata,
ff_int_to_int16(block_coefs[3], ractx->lpc_coef[0]);
- for (i=0; i < 4; i++) {
+ for (i=0; i < NBLOCKS; i++) {
do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb);
for (j=0; j < BLOCKSIZE; j++)
- *data++ = av_clip_int16(ractx->curr_sblock[j + 10] << 2);
+ *samples++ = av_clip_int16(ractx->curr_sblock[j + 10] << 2);
}
ractx->old_energy = energy;
@@ -110,19 +120,19 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata,
FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);
- *data_size = 2*160;
- return 20;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = ractx->frame;
+
+ return FRAMESIZE;
}
-AVCodec ff_ra_144_decoder =
-{
- "real_144",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_RA_144,
- sizeof(RA144Context),
- ra144_decode_init,
- NULL,
- NULL,
- ra144_decode_frame,
- .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
+AVCodec ff_ra_144_decoder = {
+ .name = "real_144",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_RA_144,
+ .priv_data_size = sizeof(RA144Context),
+ .init = ra144_decode_init,
+ .decode = ra144_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
};
diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c
index 6eab6c3..ee38bd5 100644
--- a/libavcodec/ra144enc.c
+++ b/libavcodec/ra144enc.c
@@ -477,7 +477,10 @@ static int ra144_encode_frame(AVCodecContext *avctx, uint8_t *frame,
* The filter is unstable: use the coefficients of the previous frame.
*/
ff_int_to_int16(block_coefs[NBLOCKS - 1], ractx->lpc_coef[1]);
- ff_eval_refl(lpc_refl, block_coefs[NBLOCKS - 1], avctx);
+ if (ff_eval_refl(lpc_refl, block_coefs[NBLOCKS - 1], avctx)) {
+ /* the filter is still unstable. set reflection coeffs to zero. */
+ memset(lpc_refl, 0, sizeof(lpc_refl));
+ }
}
init_put_bits(&pb, frame, buf_size);
for (i = 0; i < LPC_ORDER; i++) {
@@ -508,14 +511,15 @@ static int ra144_encode_frame(AVCodecContext *avctx, uint8_t *frame,
}
-AVCodec ff_ra_144_encoder =
-{
- "real_144",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_RA_144,
- sizeof(RA144Context),
- ra144_encode_init,
- ra144_encode_frame,
- ra144_encode_close,
- .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K) encoder"),
+AVCodec ff_ra_144_encoder = {
+ .name = "real_144",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_RA_144,
+ .priv_data_size = sizeof(RA144Context),
+ .init = ra144_encode_init,
+ .encode = ra144_encode_frame,
+ .close = ra144_encode_close,
+ .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+ .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K) encoder"),
};
diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c
index 64d765c..4cb2493 100644
--- a/libavcodec/ra288.c
+++ b/libavcodec/ra288.c
@@ -20,20 +20,26 @@
*/
#include "avcodec.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
#include "ra288.h"
#include "lpc.h"
#include "celp_math.h"
#include "celp_filters.h"
+#include "dsputil.h"
#define MAX_BACKWARD_FILTER_ORDER 36
#define MAX_BACKWARD_FILTER_LEN 40
#define MAX_BACKWARD_FILTER_NONREC 35
+#define RA288_BLOCK_SIZE 5
+#define RA288_BLOCKS_PER_FRAME 32
+
typedef struct {
- float sp_lpc[36]; ///< LPC coefficients for speech data (spec: A)
- float gain_lpc[10]; ///< LPC coefficients for gain (spec: GB)
+ AVFrame frame;
+ DSPContext dsp;
+ DECLARE_ALIGNED(16, float, sp_lpc)[FFALIGN(36, 8)]; ///< LPC coefficients for speech data (spec: A)
+ DECLARE_ALIGNED(16, float, gain_lpc)[FFALIGN(10, 8)]; ///< LPC coefficients for gain (spec: GB)
/** speech data history (spec: SB).
* Its first 70 coefficients are updated only at backward filtering.
@@ -54,14 +60,14 @@ typedef struct {
static av_cold int ra288_decode_init(AVCodecContext *avctx)
{
+ RA288Context *ractx = avctx->priv_data;
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
- return 0;
-}
+ dsputil_init(&ractx->dsp, avctx);
-static void apply_window(float *tgt, const float *m1, const float *m2, int n)
-{
- while (n--)
- *tgt++ = *m1++ * *m2++;
+ avcodec_get_frame_defaults(&ractx->frame);
+ avctx->coded_frame = &ractx->frame;
+
+ return 0;
}
static void convolve(float *tgt, const float *src, int len, int n)
@@ -120,15 +126,18 @@ static void decode(RA288Context *ractx, float gain, int cb_coef)
* @param out2 pointer to the recursive part of the output
* @param window pointer to the windowing function table
*/
-static void do_hybrid_window(int order, int n, int non_rec, float *out,
+static void do_hybrid_window(RA288Context *ractx,
+ int order, int n, int non_rec, float *out,
float *hist, float *out2, const float *window)
{
int i;
float buffer1[MAX_BACKWARD_FILTER_ORDER + 1];
float buffer2[MAX_BACKWARD_FILTER_ORDER + 1];
- float work[MAX_BACKWARD_FILTER_ORDER + MAX_BACKWARD_FILTER_LEN + MAX_BACKWARD_FILTER_NONREC];
+ LOCAL_ALIGNED_16(float, work, [FFALIGN(MAX_BACKWARD_FILTER_ORDER +
+ MAX_BACKWARD_FILTER_LEN +
+ MAX_BACKWARD_FILTER_NONREC, 8)]);
- apply_window(work, window, hist, order + n + non_rec);
+ ractx->dsp.vector_fmul(work, window, hist, FFALIGN(order + n + non_rec, 8));
convolve(buffer1, work + order , n , order);
convolve(buffer2, work + order + n, non_rec, order);
@@ -145,27 +154,28 @@ static void do_hybrid_window(int order, int n, int non_rec, float *out,
/**
* Backward synthesis filter, find the LPC coefficients from past speech data.
*/
-static void backward_filter(float *hist, float *rec, const float *window,
+static void backward_filter(RA288Context *ractx,
+ float *hist, float *rec, const float *window,
float *lpc, const float *tab,
int order, int n, int non_rec, int move_size)
{
float temp[MAX_BACKWARD_FILTER_ORDER+1];
- do_hybrid_window(order, n, non_rec, temp, hist, rec, window);
+ do_hybrid_window(ractx, order, n, non_rec, temp, hist, rec, window);
if (!compute_lpc_coefs(temp, order, lpc, 0, 1, 1))
- apply_window(lpc, lpc, tab, order);
+ ractx->dsp.vector_fmul(lpc, lpc, tab, FFALIGN(order, 8));
memmove(hist, hist + n, move_size*sizeof(*hist));
}
static int ra288_decode_frame(AVCodecContext * avctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- float *out = data;
- int i, j;
+ float *out;
+ int i, ret;
RA288Context *ractx = avctx->priv_data;
GetBitContext gb;
@@ -173,45 +183,50 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data,
av_log(avctx, AV_LOG_ERROR,
"Error! Input buffer is too small [%d<%d]\n",
buf_size, avctx->block_align);
- return 0;
+ return AVERROR_INVALIDDATA;
}
- if (*data_size < 32*5*4)
- return -1;
+ /* get output buffer */
+ ractx->frame.nb_samples = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME;
+ if ((ret = avctx->get_buffer(avctx, &ractx->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ out = (float *)ractx->frame.data[0];
init_get_bits(&gb, buf, avctx->block_align * 8);
- for (i=0; i < 32; i++) {
+ for (i=0; i < RA288_BLOCKS_PER_FRAME; i++) {
float gain = amptable[get_bits(&gb, 3)];
int cb_coef = get_bits(&gb, 6 + (i&1));
decode(ractx, gain, cb_coef);
- for (j=0; j < 5; j++)
- *(out++) = ractx->sp_hist[70 + 36 + j];
+ memcpy(out, &ractx->sp_hist[70 + 36], RA288_BLOCK_SIZE * sizeof(*out));
+ out += RA288_BLOCK_SIZE;
if ((i & 7) == 3) {
- backward_filter(ractx->sp_hist, ractx->sp_rec, syn_window,
+ backward_filter(ractx, ractx->sp_hist, ractx->sp_rec, syn_window,
ractx->sp_lpc, syn_bw_tab, 36, 40, 35, 70);
- backward_filter(ractx->gain_hist, ractx->gain_rec, gain_window,
+ backward_filter(ractx, ractx->gain_hist, ractx->gain_rec, gain_window,
ractx->gain_lpc, gain_bw_tab, 10, 8, 20, 28);
}
}
- *data_size = (char *)out - (char *)data;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = ractx->frame;
+
return avctx->block_align;
}
-AVCodec ff_ra_288_decoder =
-{
- "real_288",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_RA_288,
- sizeof(RA288Context),
- ra288_decode_init,
- NULL,
- NULL,
- ra288_decode_frame,
- .long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"),
+AVCodec ff_ra_288_decoder = {
+ .name = "real_288",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_RA_288,
+ .priv_data_size = sizeof(RA288Context),
+ .init = ra288_decode_init,
+ .decode = ra288_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"),
};
diff --git a/libavcodec/ra288.h b/libavcodec/ra288.h
index 8857f40..1c98c16 100644
--- a/libavcodec/ra288.h
+++ b/libavcodec/ra288.h
@@ -23,6 +23,7 @@
#define AVCODEC_RA288_H
#include <stdint.h>
+#include "dsputil.h"
static const float amptable[8]={
0.515625, 0.90234375, 1.57910156, 2.76342773,
@@ -96,7 +97,7 @@ static const int16_t codetable[128][5]={
{ 3746, -606, 53, -269, -3301}, { 606, 2018, -1316, 4064, 398}
};
-static const float syn_window[111]={
+DECLARE_ALIGNED(16, static const float, syn_window)[FFALIGN(111, 8)]={
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,
@@ -118,7 +119,7 @@ static const float syn_window[111]={
0.142852783, 0.0954284668,0.0477600098
};
-static const float gain_window[38]={
+DECLARE_ALIGNED(16, static const float, gain_window)[FFALIGN(38, 8)]={
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,
@@ -129,7 +130,7 @@ static const float gain_window[38]={
};
/** synthesis bandwidth broadening table */
-static const float syn_bw_tab[36]={
+DECLARE_ALIGNED(16, static const float, syn_bw_tab)[FFALIGN(36, 8)] = {
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,
@@ -139,7 +140,7 @@ static const float syn_bw_tab[36]={
};
/** gain bandwidth broadening table */
-static const float gain_bw_tab[10]={
+DECLARE_ALIGNED(16, static const float, gain_bw_tab)[FFALIGN(10, 8)] = {
0.90625, 0.821289063, 0.74432373, 0.674499512, 0.61126709,
0.553955078, 0.50201416, 0.454956055, 0.41229248, 0.373657227
};
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 0d7b995..5e4b49a 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -44,9 +44,9 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_f
void ff_write_pass1_stats(MpegEncContext *s){
snprintf(s->avctx->stats_out, 256, "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d;\n",
- s->current_picture_ptr->display_picture_number, s->current_picture_ptr->coded_picture_number, s->pict_type,
- s->current_picture.quality, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits,
- s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count, s->skip_count, s->header_bits);
+ s->current_picture_ptr->f.display_picture_number, s->current_picture_ptr->f.coded_picture_number, s->pict_type,
+ s->current_picture.f.quality, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits,
+ s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count, s->skip_count, s->header_bits);
}
static inline double qp2bits(RateControlEntry *rce, double qp){
@@ -300,7 +300,7 @@ int ff_vbv_update(MpegEncContext *s, int frame_size){
}
/**
- * modifies the bitrate curve from pass1 for one frame
+ * Modify the bitrate curve from pass1 for one frame.
*/
static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num){
RateControlContext *rcc= &s->rc_context;
@@ -404,7 +404,7 @@ static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, doubl
}
/**
- * gets the qmin & qmax for pict_type
+ * Get the qmin & qmax for pict_type.
*/
static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type){
int qmin= s->avctx->lmin;
@@ -707,10 +707,10 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
//if(dts_pic)
// av_log(NULL, AV_LOG_ERROR, "%Ld %Ld %Ld %d\n", s->current_picture_ptr->pts, s->user_specified_pts, dts_pic->pts, picture_number);
- if(!dts_pic || dts_pic->pts == AV_NOPTS_VALUE)
+ if (!dts_pic || dts_pic->f.pts == AV_NOPTS_VALUE)
wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps);
else
- wanted_bits= (uint64_t)(s->bit_rate*(double)dts_pic->pts/fps);
+ wanted_bits = (uint64_t)(s->bit_rate*(double)dts_pic->f.pts / fps);
}
diff= s->total_bits - wanted_bits;
@@ -861,7 +861,9 @@ static int init_pass2(MpegEncContext *s)
/* find qscale */
for(i=0; i<rcc->num_entries; i++){
+ RateControlEntry *rce= &rcc->entry[i];
qscale[i]= get_qscale(s, &rcc->entry[i], rate_factor, i);
+ rcc->last_qscale_for[rce->pict_type] = qscale[i];
}
assert(filter_size%2==1);
diff --git a/libavcodec/raw.c b/libavcodec/raw.c
index aa1ea30..c41f756 100644
--- a/libavcodec/raw.c
+++ b/libavcodec/raw.c
@@ -36,6 +36,7 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = {
{ PIX_FMT_YUV411P, MKTAG('Y', '4', '1', 'B') },
{ PIX_FMT_YUV422P, MKTAG('Y', '4', '2', 'B') },
{ PIX_FMT_YUV422P, MKTAG('P', '4', '2', '2') },
+ { PIX_FMT_YUV422P, MKTAG('Y', 'V', '1', '6') },
/* yuvjXXX formats are deprecated hacks specific to libav*,
they are identical to yuvXXX */
{ PIX_FMT_YUVJ420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */
@@ -44,7 +45,7 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = {
{ PIX_FMT_YUVJ422P, MKTAG('Y', '4', '2', 'B') },
{ PIX_FMT_YUVJ422P, MKTAG('P', '4', '2', '2') },
{ PIX_FMT_GRAY8, MKTAG('Y', '8', '0', '0') },
- { PIX_FMT_GRAY8, MKTAG(' ', ' ', 'Y', '8') },
+ { PIX_FMT_GRAY8, MKTAG('Y', '8', ' ', ' ') },
{ PIX_FMT_YUYV422, MKTAG('Y', 'U', 'Y', '2') }, /* Packed formats */
{ PIX_FMT_YUYV422, MKTAG('Y', '4', '2', '2') },
@@ -107,6 +108,12 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = {
{ PIX_FMT_BGR48BE, MKTAG( 48, 'B', 'G', 'R') },
{ PIX_FMT_GRAY16LE, MKTAG('Y', '1', 0 , 16 ) },
{ PIX_FMT_GRAY16BE, MKTAG(16 , 0 , '1', 'Y') },
+ { PIX_FMT_YUV420P10LE, MKTAG('Y', '3', 11 , 10 ) },
+ { PIX_FMT_YUV420P10BE, MKTAG(10 , 11 , '3', 'Y') },
+ { PIX_FMT_YUV422P10LE, MKTAG('Y', '3', 10 , 10 ) },
+ { PIX_FMT_YUV422P10BE, MKTAG(10 , 10 , '3', 'Y') },
+ { PIX_FMT_YUV444P10LE, MKTAG('Y', '3', 0 , 10 ) },
+ { PIX_FMT_YUV444P10BE, MKTAG(10 , 0 , '3', 'Y') },
{ PIX_FMT_YUV420P16LE, MKTAG('Y', '3', 11 , 16 ) },
{ PIX_FMT_YUV420P16BE, MKTAG(16 , 11 , '3', 'Y') },
{ PIX_FMT_YUV422P16LE, MKTAG('Y', '3', 10 , 16 ) },
@@ -135,6 +142,7 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = {
/* special */
{ PIX_FMT_RGB565LE,MKTAG( 3 , 0 , 0 , 0 ) }, /* flipped RGB565LE */
+ { PIX_FMT_YUV444P, MKTAG('Y', 'V', '2', '4') }, /* YUV444P, swapped UV */
{ PIX_FMT_NONE, 0 },
};
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index 5e8e6c4..9989a36 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -202,13 +202,12 @@ static av_cold int raw_close_decoder(AVCodecContext *avctx)
}
AVCodec ff_rawvideo_decoder = {
- "rawvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_RAWVIDEO,
- sizeof(RawVideoContext),
- raw_init_decoder,
- NULL,
- raw_close_decoder,
- raw_decode,
+ .name = "rawvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_RAWVIDEO,
+ .priv_data_size = sizeof(RawVideoContext),
+ .init = raw_init_decoder,
+ .close = raw_close_decoder,
+ .decode = raw_decode,
.long_name = NULL_IF_CONFIG_SMALL("raw video"),
};
diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c
index 926124c..6640db0 100644
--- a/libavcodec/rawenc.c
+++ b/libavcodec/rawenc.c
@@ -56,11 +56,11 @@ static int raw_encode(AVCodecContext *avctx,
}
AVCodec ff_rawvideo_encoder = {
- "rawvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_RAWVIDEO,
- sizeof(AVFrame),
- raw_init_encoder,
- raw_encode,
+ .name = "rawvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_RAWVIDEO,
+ .priv_data_size = sizeof(AVFrame),
+ .init = raw_init_encoder,
+ .encode = raw_encode,
.long_name = NULL_IF_CONFIG_SMALL("raw video"),
};
diff --git a/libavcodec/resample.c b/libavcodec/resample.c
index 0bebe1a..ba8ce89 100644
--- a/libavcodec/resample.c
+++ b/libavcodec/resample.c
@@ -162,9 +162,10 @@ ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
MAX_CHANNELS);
return NULL;
}
- if (output_channels > 2 &&
- !(output_channels == 6 && input_channels == 2) &&
- output_channels != input_channels) {
+ if (output_channels != input_channels &&
+ (input_channels > 2 ||
+ output_channels > 2 &&
+ !(output_channels == 6 && input_channels == 2))) {
av_log(NULL, AV_LOG_ERROR,
"Resampling output channel count must be 1 or 2 for mono input; 1, 2 or 6 for stereo input; or N for N channel input.\n");
return NULL;
@@ -187,8 +188,8 @@ ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
s->sample_fmt[0] = sample_fmt_in;
s->sample_fmt[1] = sample_fmt_out;
- s->sample_size[0] = av_get_bits_per_sample_fmt(s->sample_fmt[0]) >> 3;
- s->sample_size[1] = av_get_bits_per_sample_fmt(s->sample_fmt[1]) >> 3;
+ s->sample_size[0] = av_get_bytes_per_sample(s->sample_fmt[0]);
+ s->sample_size[1] = av_get_bytes_per_sample(s->sample_fmt[1]);
if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) {
if (!(s->convert_ctx[0] = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,
@@ -213,7 +214,6 @@ ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
}
}
-#define TAPS 16
s->resample_context = av_resample_init(output_rate, input_rate,
filter_length, log2_phase_count,
linear, cutoff);
diff --git a/libavcodec/resample2.c b/libavcodec/resample2.c
index 7560d84..48c20c2 100644
--- a/libavcodec/resample2.c
+++ b/libavcodec/resample2.c
@@ -90,7 +90,7 @@ static double bessel(double x){
}
/**
- * builds a polyphase filterbank.
+ * Build a polyphase filterbank.
* @param factor resampling factor
* @param scale wanted sum of coefficients for each filter
* @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16
diff --git a/libavcodec/rl2.c b/libavcodec/rl2.c
index 3d1cea3..7e3bd9c 100644
--- a/libavcodec/rl2.c
+++ b/libavcodec/rl2.c
@@ -20,11 +20,10 @@
*/
/**
- * RL2 Video Decoder
* @file
+ * RL2 Video Decoder
* @author Sascha Sommer (saschasommer at freenet.de)
- * For more information about the RL2 format, visit:
- * http://wiki.multimedia.cx/index.php?title=RL2
+ * @see http://wiki.multimedia.cx/index.php?title=RL2
*/
#include <stdio.h>
@@ -220,15 +219,14 @@ static av_cold int rl2_decode_end(AVCodecContext *avctx)
AVCodec ff_rl2_decoder = {
- "rl2",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_RL2,
- sizeof(Rl2Context),
- rl2_decode_init,
- NULL,
- rl2_decode_end,
- rl2_decode_frame,
- CODEC_CAP_DR1,
+ .name = "rl2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_RL2,
+ .priv_data_size = sizeof(Rl2Context),
+ .init = rl2_decode_init,
+ .close = rl2_decode_end,
+ .decode = rl2_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("RL2 video"),
};
diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c
index 46aefb4..e540e14 100644
--- a/libavcodec/roqaudioenc.c
+++ b/libavcodec/roqaudioenc.c
@@ -154,14 +154,13 @@ static av_cold int roq_dpcm_encode_close(AVCodecContext *avctx)
}
AVCodec ff_roq_dpcm_encoder = {
- "roq_dpcm",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_ROQ_DPCM,
- sizeof(ROQDPCMContext),
- roq_dpcm_encode_init,
- roq_dpcm_encode_frame,
- roq_dpcm_encode_close,
- NULL,
+ .name = "roq_dpcm",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_ROQ_DPCM,
+ .priv_data_size = sizeof(ROQDPCMContext),
+ .init = roq_dpcm_encode_init,
+ .encode = roq_dpcm_encode_frame,
+ .close = roq_dpcm_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("id RoQ DPCM"),
};
diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c
index 06d1309..527ba51 100644
--- a/libavcodec/roqvideodec.c
+++ b/libavcodec/roqvideodec.c
@@ -175,6 +175,7 @@ static int roq_decode_frame(AVCodecContext *avctx,
RoqContext *s = avctx->priv_data;
int copy= !s->current_frame->data[0];
+ s->current_frame->reference = 3;
if (avctx->reget_buffer(avctx, s->current_frame)) {
av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n");
return -1;
@@ -211,14 +212,13 @@ static av_cold int roq_decode_end(AVCodecContext *avctx)
}
AVCodec ff_roq_decoder = {
- "roqvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ROQ,
- sizeof(RoqContext),
- roq_decode_init,
- NULL,
- roq_decode_end,
- roq_decode_frame,
- CODEC_CAP_DR1,
+ .name = "roqvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ROQ,
+ .priv_data_size = sizeof(RoqContext),
+ .init = roq_decode_init,
+ .close = roq_decode_end,
+ .decode = roq_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("id RoQ video"),
};
diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c
index 052dcef..2a62d55 100644
--- a/libavcodec/roqvideoenc.c
+++ b/libavcodec/roqvideoenc.c
@@ -1065,16 +1065,15 @@ static int roq_encode_end(AVCodecContext *avctx)
return 0;
}
-AVCodec ff_roq_encoder =
-{
- "roqvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ROQ,
- sizeof(RoqContext),
- roq_encode_init,
- roq_encode_frame,
- roq_encode_end,
+AVCodec ff_roq_encoder = {
+ .name = "roqvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ROQ,
+ .priv_data_size = sizeof(RoqContext),
+ .init = roq_encode_init,
+ .encode = roq_encode_frame,
+ .close = roq_encode_end,
.supported_framerates = (const AVRational[]){{30,1}, {0,0}},
- .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV444P, PIX_FMT_NONE},
- .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"),
+ .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV444P, PIX_FMT_NONE},
+ .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"),
};
diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c
index 958f103..7350ef2 100644
--- a/libavcodec/rpza.c
+++ b/libavcodec/rpza.c
@@ -30,8 +30,8 @@
* Note that this decoder reads big endian RGB555 pixel values from the
* bytestream, arranges them in the host's endian order, and outputs
* them to the final rendered map in the same host endian order. This is
- * intended behavior as the ffmpeg documentation states that RGB555 pixels
- * shall be stored in native CPU endianness.
+ * intended behavior as the libavcodec documentation states that RGB555
+ * pixels shall be stored in native CPU endianness.
*/
#include <stdio.h>
@@ -276,14 +276,13 @@ static av_cold int rpza_decode_end(AVCodecContext *avctx)
}
AVCodec ff_rpza_decoder = {
- "rpza",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_RPZA,
- sizeof(RpzaContext),
- rpza_decode_init,
- NULL,
- rpza_decode_end,
- rpza_decode_frame,
- CODEC_CAP_DR1,
+ .name = "rpza",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_RPZA,
+ .priv_data_size = sizeof(RpzaContext),
+ .init = rpza_decode_init,
+ .close = rpza_decode_end,
+ .decode = rpza_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("QuickTime video (RPZA)"),
};
diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c
index 616c402..2c5ef0a 100644
--- a/libavcodec/rtjpeg.c
+++ b/libavcodec/rtjpeg.c
@@ -27,18 +27,18 @@
i = scan[coeff--]; \
block[i] = (c) * quant[i];
-//! aligns the bitstream to the give power of two
+/// aligns the bitstream to the given power of two
#define ALIGN(a) \
n = (-get_bits_count(gb)) & (a - 1); \
if (n) {skip_bits(gb, n);}
/**
- * \brief read one block from stream
- * \param gb contains stream data
- * \param block where data is written to
- * \param scan array containing the mapping stream address -> block position
- * \param quant quantization factors
- * \return 0 means the block is not coded, < 0 means an error occurred.
+ * @brief read one block from stream
+ * @param gb contains stream data
+ * @param block where data is written to
+ * @param scan array containing the mapping stream address -> block position
+ * @param quant quantization factors
+ * @return 0 means the block is not coded, < 0 means an error occurred.
*
* Note: GetBitContext is used to make the code simpler, since all data is
* aligned this could be done faster in a different way, e.g. as it is done
@@ -56,7 +56,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc
// number of non-zero coefficients
coeff = get_bits(gb, 6);
- if (get_bits_count(gb) + (coeff << 1) >= gb->size_in_bits)
+ if (get_bits_left(gb) < (coeff << 1))
return -1;
// normally we would only need to clear the (63 - coeff) last values,
@@ -73,7 +73,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc
// 4 bits per coefficient
ALIGN(4);
- if (get_bits_count(gb) + (coeff << 2) >= gb->size_in_bits)
+ if (get_bits_left(gb) < (coeff << 2))
return -1;
while (coeff) {
ac = get_sbits(gb, 4);
@@ -84,7 +84,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc
// 8 bits per coefficient
ALIGN(8);
- if (get_bits_count(gb) + (coeff << 3) >= gb->size_in_bits)
+ if (get_bits_left(gb) < (coeff << 3))
return -1;
while (coeff) {
ac = get_sbits(gb, 8);
@@ -96,13 +96,13 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc
}
/**
- * \brief decode one rtjpeg YUV420 frame
- * \param c context, must be initialized via rtjpeg_decode_init
- * \param f AVFrame to place decoded frame into. If parts of the frame
+ * @brief decode one rtjpeg YUV420 frame
+ * @param c context, must be initialized via rtjpeg_decode_init
+ * @param f AVFrame to place decoded frame into. If parts of the frame
* are not coded they are left unchanged, so consider initializing it
- * \param buf buffer containing input data
- * \param buf_size length of input data in bytes
- * \return number of bytes consumed from the input buffer
+ * @param buf buffer containing input data
+ * @param buf_size length of input data in bytes
+ * @return number of bytes consumed from the input buffer
*/
int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f,
const uint8_t *buf, int buf_size) {
@@ -114,24 +114,25 @@ int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f,
init_get_bits(&gb, buf, buf_size * 8);
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
+#define BLOCK(quant, dst, stride) do { \
+ int res = get_block(&gb, block, c->scan, quant); \
+ if (res < 0) \
+ return res; \
+ if (res > 0) \
+ c->dsp->idct_put(dst, stride, block); \
+} while (0)
DCTELEM *block = c->block;
- if (get_block(&gb, block, c->scan, c->lquant) > 0)
- c->dsp->idct_put(y1, f->linesize[0], block);
+ BLOCK(c->lquant, y1, f->linesize[0]);
y1 += 8;
- if (get_block(&gb, block, c->scan, c->lquant) > 0)
- c->dsp->idct_put(y1, f->linesize[0], block);
+ BLOCK(c->lquant, y1, f->linesize[0]);
y1 += 8;
- if (get_block(&gb, block, c->scan, c->lquant) > 0)
- c->dsp->idct_put(y2, f->linesize[0], block);
+ BLOCK(c->lquant, y2, f->linesize[0]);
y2 += 8;
- if (get_block(&gb, block, c->scan, c->lquant) > 0)
- c->dsp->idct_put(y2, f->linesize[0], block);
+ BLOCK(c->lquant, y2, f->linesize[0]);
y2 += 8;
- if (get_block(&gb, block, c->scan, c->cquant) > 0)
- c->dsp->idct_put(u, f->linesize[1], block);
+ BLOCK(c->cquant, u, f->linesize[1]);
u += 8;
- if (get_block(&gb, block, c->scan, c->cquant) > 0)
- c->dsp->idct_put(v, f->linesize[2], block);
+ BLOCK(c->cquant, v, f->linesize[2]);
v += 8;
}
y1 += 2 * 8 * (f->linesize[0] - w);
@@ -143,15 +144,15 @@ int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f,
}
/**
- * \brief initialize an RTJpegContext, may be called multiple times
- * \param c context to initialize
- * \param dsp specifies the idct to use for decoding
- * \param width width of image, will be rounded down to the nearest multiple
+ * @brief initialize an RTJpegContext, may be called multiple times
+ * @param c context to initialize
+ * @param dsp specifies the idct to use for decoding
+ * @param width width of image, will be rounded down to the nearest multiple
* of 16 for decoding
- * \param height height of image, will be rounded down to the nearest multiple
+ * @param height height of image, will be rounded down to the nearest multiple
* of 16 for decoding
- * \param lquant luma quantization table to use
- * \param cquant chroma quantization table to use
+ * @param lquant luma quantization table to use
+ * @param cquant chroma quantization table to use
*/
void rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp,
int width, int height,
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 223500c..1d78c92 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -34,6 +34,10 @@
//#define DEBUG
+#define RV_GET_MAJOR_VER(x) ((x) >> 28)
+#define RV_GET_MINOR_VER(x) (((x) >> 20) & 0xFF)
+#define RV_GET_MICRO_VER(x) (((x) >> 12) & 0xFF)
+
#define DC_VLC_BITS 14 //FIXME find a better solution
static const uint16_t rv_lum_code[256] =
@@ -292,13 +296,7 @@ static int rv10_decode_picture_header(MpegEncContext *s)
static int rv20_decode_picture_header(MpegEncContext *s)
{
int seq, mb_pos, i;
-
- if(s->avctx->sub_id == 0x30202002 || s->avctx->sub_id == 0x30203002){
- if (get_bits(&s->gb, 3)){
- av_log(s->avctx, AV_LOG_ERROR, "unknown triplet set\n");
- return -1;
- }
- }
+ int rpr_bits;
i= get_bits(&s->gb, 2);
switch(i){
@@ -317,7 +315,7 @@ static int rv20_decode_picture_header(MpegEncContext *s)
}
if (get_bits1(&s->gb)){
- av_log(s->avctx, AV_LOG_ERROR, "unknown bit set\n");
+ av_log(s->avctx, AV_LOG_ERROR, "reserved bit set\n");
return -1;
}
@@ -326,23 +324,21 @@ static int rv20_decode_picture_header(MpegEncContext *s)
av_log(s->avctx, AV_LOG_ERROR, "error, qscale:0\n");
return -1;
}
- if(s->avctx->sub_id == 0x30203002){
- if (get_bits1(&s->gb)){
- av_log(s->avctx, AV_LOG_ERROR, "unknown bit2 set\n");
- return -1;
- }
- }
- if(s->avctx->has_b_frames){
- int f, new_w, new_h;
- int v= s->avctx->extradata_size >= 4 ? 7&((uint8_t*)s->avctx->extradata)[1] : 0;
+ if(RV_GET_MINOR_VER(s->avctx->sub_id) >= 2)
+ s->loop_filter = get_bits1(&s->gb);
- if (get_bits1(&s->gb)){
- av_log(s->avctx, AV_LOG_ERROR, "unknown bit3 set\n");
- }
- seq= get_bits(&s->gb, 13)<<2;
+ if(RV_GET_MINOR_VER(s->avctx->sub_id) <= 1)
+ seq = get_bits(&s->gb, 8) << 7;
+ else
+ seq = get_bits(&s->gb, 13) << 2;
+
+ rpr_bits = s->avctx->extradata[1] & 7;
+ if(rpr_bits){
+ int f, new_w, new_h;
+ rpr_bits = FFMIN((rpr_bits >> 1) + 1, 3);
- f= get_bits(&s->gb, av_log2(v)+1);
+ f = get_bits(&s->gb, rpr_bits);
if(f){
new_w= 4*((uint8_t*)s->avctx->extradata)[6+2*f];
@@ -364,19 +360,12 @@ static int rv20_decode_picture_header(MpegEncContext *s)
}
if(s->avctx->debug & FF_DEBUG_PICT_INFO){
- av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d\n", f, v);
+ av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d\n", f, rpr_bits);
}
- }else{
- seq= get_bits(&s->gb, 8)*128;
}
-// if(s->avctx->sub_id <= 0x20201002){ //0x20201002 definitely needs this
- mb_pos= ff_h263_decode_mba(s);
-/* }else{
- mb_pos= get_bits(&s->gb, av_log2(s->mb_num-1)+1);
- s->mb_x= mb_pos % s->mb_width;
- s->mb_y= mb_pos / s->mb_width;
- }*/
+ mb_pos = ff_h263_decode_mba(s);
+
//av_log(s->avctx, AV_LOG_DEBUG, "%d\n", seq);
seq |= s->time &~0x7FFF;
if(seq - s->time > 0x4000) seq -= 0x8000;
@@ -403,6 +392,9 @@ static int rv20_decode_picture_header(MpegEncContext *s)
av_log(s->avctx, AV_LOG_DEBUG, "\n");*/
s->no_rounding= get_bits1(&s->gb);
+ if(RV_GET_MINOR_VER(s->avctx->sub_id) <= 1 && s->pict_type == AV_PICTURE_TYPE_B)
+ skip_bits(&s->gb, 5); // binary decoder reads 3+2 bits here but they don't seem to be used
+
s->f_code = 1;
s->unrestricted_mv = 1;
s->h263_aic= s->pict_type == AV_PICTURE_TYPE_I;
@@ -427,6 +419,7 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
static int done=0;
+ int major_ver, minor_ver, micro_ver;
if (avctx->extradata_size < 8) {
av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n");
@@ -446,32 +439,27 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx)
s->h263_long_vectors= ((uint8_t*)avctx->extradata)[3] & 1;
avctx->sub_id= AV_RB32((uint8_t*)avctx->extradata + 4);
- if (avctx->sub_id == 0x10000000) {
- s->rv10_version= 0;
- s->low_delay=1;
- } else if (avctx->sub_id == 0x10001000) {
- s->rv10_version= 3;
- s->low_delay=1;
- } else if (avctx->sub_id == 0x10002000) {
- s->rv10_version= 3;
- s->low_delay=1;
- s->obmc=1;
- } else if (avctx->sub_id == 0x10003000) {
- s->rv10_version= 3;
- s->low_delay=1;
- } else if (avctx->sub_id == 0x10003001) {
- s->rv10_version= 3;
- s->low_delay=1;
- } else if ( avctx->sub_id == 0x20001000
- || (avctx->sub_id >= 0x20100000 && avctx->sub_id < 0x201a0000)) {
- s->low_delay=1;
- } else if ( avctx->sub_id == 0x30202002
- || avctx->sub_id == 0x30203002
- || (avctx->sub_id >= 0x20200002 && avctx->sub_id < 0x20300000)) {
- s->low_delay=0;
- s->avctx->has_b_frames=1;
- } else
+ major_ver = RV_GET_MAJOR_VER(avctx->sub_id);
+ minor_ver = RV_GET_MINOR_VER(avctx->sub_id);
+ micro_ver = RV_GET_MICRO_VER(avctx->sub_id);
+
+ s->low_delay = 1;
+ switch (major_ver) {
+ case 1:
+ s->rv10_version = micro_ver ? 3 : 1;
+ s->obmc = micro_ver == 2;
+ break;
+ case 2:
+ if (minor_ver >= 2) {
+ s->low_delay = 0;
+ s->avctx->has_b_frames = 1;
+ }
+ break;
+ default:
av_log(s->avctx, AV_LOG_ERROR, "unknown header %X\n", avctx->sub_id);
+ av_log_missing_feature(avctx, "RV1/2 version", 1);
+ return AVERROR_PATCHWELCOME;
+ }
if(avctx->debug & FF_DEBUG_PICT_INFO){
av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", avctx->sub_id, avctx->extradata_size >= 4 ? ((uint32_t*)avctx->extradata)[0] : -1);
@@ -544,7 +532,7 @@ static int rv10_decode_packet(AVCodecContext *avctx,
return -1;
ff_er_frame_start(s);
} else {
- if (s->current_picture_ptr->pict_type != s->pict_type) {
+ if (s->current_picture_ptr->f.pict_type != s->pict_type) {
av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
return -1;
}
@@ -621,7 +609,7 @@ static int rv10_decode_packet(AVCodecContext *avctx,
if(ret == SLICE_END) break;
}
- ff_er_add_slice(s, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
+ ff_er_add_slice(s, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
return s->gb.size_in_bits;
}
@@ -697,30 +685,28 @@ static int rv10_decode_frame(AVCodecContext *avctx,
}
AVCodec ff_rv10_decoder = {
- "rv10",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_RV10,
- sizeof(MpegEncContext),
- rv10_decode_init,
- NULL,
- rv10_decode_end,
- rv10_decode_frame,
- CODEC_CAP_DR1,
+ .name = "rv10",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_RV10,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = rv10_decode_init,
+ .close = rv10_decode_end,
+ .decode = rv10_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
.pix_fmts= ff_pixfmt_list_420,
};
AVCodec ff_rv20_decoder = {
- "rv20",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_RV20,
- sizeof(MpegEncContext),
- rv10_decode_init,
- NULL,
- rv10_decode_end,
- rv10_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+ .name = "rv20",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_RV20,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = rv10_decode_init,
+ .close = rv10_decode_end,
+ .decode = rv10_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
.flush= ff_mpeg_flush,
.max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c
index 1cb36fd..e96e473 100644
--- a/libavcodec/rv10enc.c
+++ b/libavcodec/rv10enc.c
@@ -32,7 +32,7 @@ void rv10_encode_picture_header(MpegEncContext *s, int picture_number)
{
int full_frame= 0;
- align_put_bits(&s->pb);
+ avpriv_align_put_bits(&s->pb);
put_bits(&s->pb, 1, 1); /* marker */
@@ -57,13 +57,13 @@ void rv10_encode_picture_header(MpegEncContext *s, int picture_number)
}
AVCodec ff_rv10_encoder = {
- "rv10",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_RV10,
- sizeof(MpegEncContext),
- MPV_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "rv10",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_RV10,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = MPV_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
};
diff --git a/libavcodec/rv20enc.c b/libavcodec/rv20enc.c
index 8eba76b..bf09d8a 100644
--- a/libavcodec/rv20enc.c
+++ b/libavcodec/rv20enc.c
@@ -58,13 +58,13 @@ void rv20_encode_picture_header(MpegEncContext *s, int picture_number){
}
AVCodec ff_rv20_encoder = {
- "rv20",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_RV20,
- sizeof(MpegEncContext),
- MPV_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "rv20",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_RV20,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = MPV_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
};
diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c
index b7f43a4..26708db 100644
--- a/libavcodec/rv30.c
+++ b/libavcodec/rv30.c
@@ -142,7 +142,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
mb_pos = row * s->mb_stride;
for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
- int mbtype = s->current_picture_ptr->mb_type[mb_pos];
+ int mbtype = s->current_picture_ptr->f.mb_type[mb_pos];
if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype))
r->deblock_coefs[mb_pos] = 0xFFFF;
if(IS_INTRA(mbtype))
@@ -154,11 +154,11 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
*/
mb_pos = row * s->mb_stride;
for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
- cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]];
+ cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos]];
if(mb_x)
- left_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - 1]];
+ left_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos - 1]];
for(j = 0; j < 16; j += 4){
- Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize + 4 * !mb_x;
+ Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize + 4 * !mb_x;
for(i = !mb_x; i < 4; i++, Y += 4){
int ij = i + j;
loc_lim = 0;
@@ -178,7 +178,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
if(mb_x)
left_cbp = (r->cbp_chroma[mb_pos - 1] >> (k*4)) & 0xF;
for(j = 0; j < 8; j += 4){
- C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize + 4 * !mb_x;
+ C = s->current_picture_ptr->f.data[k + 1] + mb_x*8 + (row*8 + j) * s->uvlinesize + 4 * !mb_x;
for(i = !mb_x; i < 2; i++, C += 4){
int ij = i + (j >> 1);
loc_lim = 0;
@@ -196,11 +196,11 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
}
mb_pos = row * s->mb_stride;
for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
- cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]];
+ cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos]];
if(row)
- top_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - s->mb_stride]];
+ top_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos - s->mb_stride]];
for(j = 4*!row; j < 16; j += 4){
- Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize;
+ Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize;
for(i = 0; i < 4; i++, Y += 4){
int ij = i + j;
loc_lim = 0;
@@ -220,7 +220,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
if(row)
top_cbp = (r->cbp_chroma[mb_pos - s->mb_stride] >> (k*4)) & 0xF;
for(j = 4*!row; j < 8; j += 4){
- C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize;
+ C = s->current_picture_ptr->f.data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize;
for(i = 0; i < 2; i++, C += 4){
int ij = i + (j >> 1);
loc_lim = 0;
@@ -268,16 +268,15 @@ static av_cold int rv30_decode_init(AVCodecContext *avctx)
}
AVCodec ff_rv30_decoder = {
- "rv30",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_RV30,
- sizeof(RV34DecContext),
- rv30_decode_init,
- NULL,
- ff_rv34_decode_end,
- ff_rv34_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY,
- .flush = ff_mpeg_flush,
- .long_name = NULL_IF_CONFIG_SMALL("RealVideo 3.0"),
- .pix_fmts= ff_pixfmt_list_420,
+ .name = "rv30",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_RV30,
+ .priv_data_size = sizeof(RV34DecContext),
+ .init = rv30_decode_init,
+ .close = ff_rv34_decode_end,
+ .decode = ff_rv34_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+ .flush = ff_mpeg_flush,
+ .long_name = NULL_IF_CONFIG_SMALL("RealVideo 3.0"),
+ .pix_fmts = ff_pixfmt_list_420,
};
diff --git a/libavcodec/rv30dsp.c b/libavcodec/rv30dsp.c
index c6e0614..bcd1a46 100644
--- a/libavcodec/rv30dsp.c
+++ b/libavcodec/rv30dsp.c
@@ -26,13 +26,14 @@
#include "avcodec.h"
#include "dsputil.h"
+#include "rv34dsp.h"
#define RV30_LOWPASS(OPNAME, OP) \
static av_unused void OPNAME ## rv30_tpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\
- const int h=8;\
+ const int h = 8;\
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
int i;\
- for(i=0; i<h; i++)\
+ for(i = 0; i < h; i++)\
{\
OP(dst[0], (-(src[-1]+src[2]) + src[0]*C1 + src[1]*C2 + 8)>>4);\
OP(dst[1], (-(src[ 0]+src[3]) + src[1]*C1 + src[2]*C2 + 8)>>4);\
@@ -42,28 +43,28 @@ static av_unused void OPNAME ## rv30_tpel8_h_lowpass(uint8_t *dst, uint8_t *src,
OP(dst[5], (-(src[ 4]+src[7]) + src[5]*C1 + src[6]*C2 + 8)>>4);\
OP(dst[6], (-(src[ 5]+src[8]) + src[6]*C1 + src[7]*C2 + 8)>>4);\
OP(dst[7], (-(src[ 6]+src[9]) + src[7]*C1 + src[8]*C2 + 8)>>4);\
- dst+=dstStride;\
- src+=srcStride;\
+ dst += dstStride;\
+ src += srcStride;\
}\
}\
\
static void OPNAME ## rv30_tpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\
- const int w=8;\
+ const int w = 8;\
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
int i;\
- for(i=0; i<w; i++)\
+ for(i = 0; i < w; i++)\
{\
- const int srcA= src[-1*srcStride];\
- const int src0= src[0 *srcStride];\
- const int src1= src[1 *srcStride];\
- const int src2= src[2 *srcStride];\
- const int src3= src[3 *srcStride];\
- const int src4= src[4 *srcStride];\
- const int src5= src[5 *srcStride];\
- const int src6= src[6 *srcStride];\
- const int src7= src[7 *srcStride];\
- const int src8= src[8 *srcStride];\
- const int src9= src[9 *srcStride];\
+ const int srcA = src[-1*srcStride];\
+ const int src0 = src[0 *srcStride];\
+ const int src1 = src[1 *srcStride];\
+ const int src2 = src[2 *srcStride];\
+ const int src3 = src[3 *srcStride];\
+ const int src4 = src[4 *srcStride];\
+ const int src5 = src[5 *srcStride];\
+ const int src6 = src[6 *srcStride];\
+ const int src7 = src[7 *srcStride];\
+ const int src8 = src[8 *srcStride];\
+ const int src9 = src[9 *srcStride];\
OP(dst[0*dstStride], (-(srcA+src2) + src0*C1 + src1*C2 + 8)>>4);\
OP(dst[1*dstStride], (-(src0+src3) + src1*C1 + src2*C2 + 8)>>4);\
OP(dst[2*dstStride], (-(src1+src4) + src2*C1 + src3*C2 + 8)>>4);\
@@ -251,41 +252,49 @@ RV30_MC(put_, 16)
RV30_MC(avg_, 8)
RV30_MC(avg_, 16)
-av_cold void ff_rv30dsp_init(DSPContext* c, AVCodecContext *avctx) {
- c->put_rv30_tpel_pixels_tab[0][ 0] = c->put_h264_qpel_pixels_tab[0][0];
- c->put_rv30_tpel_pixels_tab[0][ 1] = put_rv30_tpel16_mc10_c;
- c->put_rv30_tpel_pixels_tab[0][ 2] = put_rv30_tpel16_mc20_c;
- c->put_rv30_tpel_pixels_tab[0][ 4] = put_rv30_tpel16_mc01_c;
- c->put_rv30_tpel_pixels_tab[0][ 5] = put_rv30_tpel16_mc11_c;
- c->put_rv30_tpel_pixels_tab[0][ 6] = put_rv30_tpel16_mc21_c;
- c->put_rv30_tpel_pixels_tab[0][ 8] = put_rv30_tpel16_mc02_c;
- c->put_rv30_tpel_pixels_tab[0][ 9] = put_rv30_tpel16_mc12_c;
- c->put_rv30_tpel_pixels_tab[0][10] = put_rv30_tpel16_mc22_c;
- c->avg_rv30_tpel_pixels_tab[0][ 0] = c->avg_h264_qpel_pixels_tab[0][0];
- c->avg_rv30_tpel_pixels_tab[0][ 1] = avg_rv30_tpel16_mc10_c;
- c->avg_rv30_tpel_pixels_tab[0][ 2] = avg_rv30_tpel16_mc20_c;
- c->avg_rv30_tpel_pixels_tab[0][ 4] = avg_rv30_tpel16_mc01_c;
- c->avg_rv30_tpel_pixels_tab[0][ 5] = avg_rv30_tpel16_mc11_c;
- c->avg_rv30_tpel_pixels_tab[0][ 6] = avg_rv30_tpel16_mc21_c;
- c->avg_rv30_tpel_pixels_tab[0][ 8] = avg_rv30_tpel16_mc02_c;
- c->avg_rv30_tpel_pixels_tab[0][ 9] = avg_rv30_tpel16_mc12_c;
- c->avg_rv30_tpel_pixels_tab[0][10] = avg_rv30_tpel16_mc22_c;
- c->put_rv30_tpel_pixels_tab[1][ 0] = c->put_h264_qpel_pixels_tab[1][0];
- c->put_rv30_tpel_pixels_tab[1][ 1] = put_rv30_tpel8_mc10_c;
- c->put_rv30_tpel_pixels_tab[1][ 2] = put_rv30_tpel8_mc20_c;
- c->put_rv30_tpel_pixels_tab[1][ 4] = put_rv30_tpel8_mc01_c;
- c->put_rv30_tpel_pixels_tab[1][ 5] = put_rv30_tpel8_mc11_c;
- c->put_rv30_tpel_pixels_tab[1][ 6] = put_rv30_tpel8_mc21_c;
- c->put_rv30_tpel_pixels_tab[1][ 8] = put_rv30_tpel8_mc02_c;
- c->put_rv30_tpel_pixels_tab[1][ 9] = put_rv30_tpel8_mc12_c;
- c->put_rv30_tpel_pixels_tab[1][10] = put_rv30_tpel8_mc22_c;
- c->avg_rv30_tpel_pixels_tab[1][ 0] = c->avg_h264_qpel_pixels_tab[1][0];
- c->avg_rv30_tpel_pixels_tab[1][ 1] = avg_rv30_tpel8_mc10_c;
- c->avg_rv30_tpel_pixels_tab[1][ 2] = avg_rv30_tpel8_mc20_c;
- c->avg_rv30_tpel_pixels_tab[1][ 4] = avg_rv30_tpel8_mc01_c;
- c->avg_rv30_tpel_pixels_tab[1][ 5] = avg_rv30_tpel8_mc11_c;
- c->avg_rv30_tpel_pixels_tab[1][ 6] = avg_rv30_tpel8_mc21_c;
- c->avg_rv30_tpel_pixels_tab[1][ 8] = avg_rv30_tpel8_mc02_c;
- c->avg_rv30_tpel_pixels_tab[1][ 9] = avg_rv30_tpel8_mc12_c;
- c->avg_rv30_tpel_pixels_tab[1][10] = avg_rv30_tpel8_mc22_c;
+av_cold void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp) {
+
+ ff_rv34dsp_init(c, dsp);
+
+ c->put_pixels_tab[0][ 0] = dsp->put_h264_qpel_pixels_tab[0][0];
+ c->put_pixels_tab[0][ 1] = put_rv30_tpel16_mc10_c;
+ c->put_pixels_tab[0][ 2] = put_rv30_tpel16_mc20_c;
+ c->put_pixels_tab[0][ 4] = put_rv30_tpel16_mc01_c;
+ c->put_pixels_tab[0][ 5] = put_rv30_tpel16_mc11_c;
+ c->put_pixels_tab[0][ 6] = put_rv30_tpel16_mc21_c;
+ c->put_pixels_tab[0][ 8] = put_rv30_tpel16_mc02_c;
+ c->put_pixels_tab[0][ 9] = put_rv30_tpel16_mc12_c;
+ c->put_pixels_tab[0][10] = put_rv30_tpel16_mc22_c;
+ c->avg_pixels_tab[0][ 0] = dsp->avg_h264_qpel_pixels_tab[0][0];
+ c->avg_pixels_tab[0][ 1] = avg_rv30_tpel16_mc10_c;
+ c->avg_pixels_tab[0][ 2] = avg_rv30_tpel16_mc20_c;
+ c->avg_pixels_tab[0][ 4] = avg_rv30_tpel16_mc01_c;
+ c->avg_pixels_tab[0][ 5] = avg_rv30_tpel16_mc11_c;
+ c->avg_pixels_tab[0][ 6] = avg_rv30_tpel16_mc21_c;
+ c->avg_pixels_tab[0][ 8] = avg_rv30_tpel16_mc02_c;
+ c->avg_pixels_tab[0][ 9] = avg_rv30_tpel16_mc12_c;
+ c->avg_pixels_tab[0][10] = avg_rv30_tpel16_mc22_c;
+ c->put_pixels_tab[1][ 0] = dsp->put_h264_qpel_pixels_tab[1][0];
+ c->put_pixels_tab[1][ 1] = put_rv30_tpel8_mc10_c;
+ c->put_pixels_tab[1][ 2] = put_rv30_tpel8_mc20_c;
+ c->put_pixels_tab[1][ 4] = put_rv30_tpel8_mc01_c;
+ c->put_pixels_tab[1][ 5] = put_rv30_tpel8_mc11_c;
+ c->put_pixels_tab[1][ 6] = put_rv30_tpel8_mc21_c;
+ c->put_pixels_tab[1][ 8] = put_rv30_tpel8_mc02_c;
+ c->put_pixels_tab[1][ 9] = put_rv30_tpel8_mc12_c;
+ c->put_pixels_tab[1][10] = put_rv30_tpel8_mc22_c;
+ c->avg_pixels_tab[1][ 0] = dsp->avg_h264_qpel_pixels_tab[1][0];
+ c->avg_pixels_tab[1][ 1] = avg_rv30_tpel8_mc10_c;
+ c->avg_pixels_tab[1][ 2] = avg_rv30_tpel8_mc20_c;
+ c->avg_pixels_tab[1][ 4] = avg_rv30_tpel8_mc01_c;
+ c->avg_pixels_tab[1][ 5] = avg_rv30_tpel8_mc11_c;
+ c->avg_pixels_tab[1][ 6] = avg_rv30_tpel8_mc21_c;
+ c->avg_pixels_tab[1][ 8] = avg_rv30_tpel8_mc02_c;
+ c->avg_pixels_tab[1][ 9] = avg_rv30_tpel8_mc12_c;
+ c->avg_pixels_tab[1][10] = avg_rv30_tpel8_mc22_c;
+
+ c->put_chroma_pixels_tab[0] = dsp->put_h264_chroma_pixels_tab[0];
+ c->put_chroma_pixels_tab[1] = dsp->put_h264_chroma_pixels_tab[1];
+ c->avg_chroma_pixels_tab[0] = dsp->avg_h264_chroma_pixels_tab[0];
+ c->avg_chroma_pixels_tab[1] = dsp->avg_h264_chroma_pixels_tab[1];
}
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index 70c35ef..1a126be 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -171,82 +171,6 @@ static av_cold void rv34_init_tables(void)
/** @} */ // vlc group
-
-/**
- * @name RV30/40 inverse transform functions
- * @{
- */
-
-static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block)
-{
- int i;
-
- for(i=0; i<4; i++){
- const int z0= 13*(block[i+8*0] + block[i+8*2]);
- const int z1= 13*(block[i+8*0] - block[i+8*2]);
- const int z2= 7* block[i+8*1] - 17*block[i+8*3];
- const int z3= 17* block[i+8*1] + 7*block[i+8*3];
-
- temp[4*i+0]= z0+z3;
- temp[4*i+1]= z1+z2;
- temp[4*i+2]= z1-z2;
- temp[4*i+3]= z0-z3;
- }
-}
-
-/**
- * Real Video 3.0/4.0 inverse transform
- * Code is almost the same as in SVQ3, only scaling is different.
- */
-static void rv34_inv_transform(DCTELEM *block){
- int temp[16];
- int i;
-
- rv34_row_transform(temp, block);
-
- for(i=0; i<4; i++){
- const int z0= 13*(temp[4*0+i] + temp[4*2+i]) + 0x200;
- const int z1= 13*(temp[4*0+i] - temp[4*2+i]) + 0x200;
- const int z2= 7* temp[4*1+i] - 17*temp[4*3+i];
- const int z3= 17* temp[4*1+i] + 7*temp[4*3+i];
-
- block[i*8+0]= (z0 + z3)>>10;
- block[i*8+1]= (z1 + z2)>>10;
- block[i*8+2]= (z1 - z2)>>10;
- block[i*8+3]= (z0 - z3)>>10;
- }
-
-}
-
-/**
- * RealVideo 3.0/4.0 inverse transform for DC block
- *
- * Code is almost the same as rv34_inv_transform()
- * but final coefficients are multiplied by 1.5 and have no rounding.
- */
-static void rv34_inv_transform_noround(DCTELEM *block){
- int temp[16];
- int i;
-
- rv34_row_transform(temp, block);
-
- for(i=0; i<4; i++){
- const int z0= 13*(temp[4*0+i] + temp[4*2+i]);
- const int z1= 13*(temp[4*0+i] - temp[4*2+i]);
- const int z2= 7* temp[4*1+i] - 17*temp[4*3+i];
- const int z3= 17* temp[4*1+i] + 7*temp[4*3+i];
-
- block[i*8+0]= ((z0 + z3)*3)>>11;
- block[i*8+1]= ((z1 + z2)*3)>>11;
- block[i*8+2]= ((z1 - z2)*3)>>11;
- block[i*8+3]= ((z0 - z3)*3)>>11;
- }
-
-}
-
-/** @} */ // transform
-
-
/**
* @name RV30/40 4x4 block decoding functions
* @{
@@ -365,20 +289,6 @@ static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *r
}
/**
- * Dequantize ordinary 4x4 block.
- * @todo optimize
- */
-static inline void rv34_dequant4x4(DCTELEM *block, int Qdc, int Q)
-{
- int i, j;
-
- block[0] = (block[0] * Qdc + 8) >> 4;
- for(i = 0; i < 4; i++)
- for(j = !i; j < 4; j++)
- block[j + i*8] = (block[j + i*8] * Q + 8) >> 4;
-}
-
-/**
* Dequantize 4x4 block of DC values for 16x16 macroblock.
* @todo optimize
*/
@@ -424,17 +334,6 @@ static inline RV34VLC* choose_vlc_set(int quant, int mod, int type)
}
/**
- * Decode quantizer difference and return modified quantizer.
- */
-static inline int rv34_decode_dquant(GetBitContext *gb, int quant)
-{
- if(get_bits1(gb))
- return rv34_dquant_tab[get_bits1(gb)][quant];
- else
- return get_bits(gb, 5);
-}
-
-/**
* Decode macroblock header and return CBP in case of success, -1 otherwise.
*/
static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types)
@@ -450,13 +349,13 @@ static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types)
if(!get_bits1(gb))
av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
}
- s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA;
+ s->current_picture_ptr->f.mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA;
r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA;
}else{
r->block_type = r->decode_mb_info(r);
if(r->block_type == -1)
return -1;
- s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
+ s->current_picture_ptr->f.mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
r->mb_type[mb_pos] = r->block_type;
if(r->block_type == RV34_MB_SKIP){
if(s->pict_type == AV_PICTURE_TYPE_P)
@@ -464,7 +363,7 @@ static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types)
if(s->pict_type == AV_PICTURE_TYPE_B)
r->mb_type[mb_pos] = RV34_MB_B_DIRECT;
}
- r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]);
+ r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->f.mb_type[mb_pos]);
rv34_decode_mv(r, r->block_type);
if(r->block_type == RV34_MB_SKIP){
fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0]));
@@ -473,7 +372,7 @@ static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types)
r->chroma_vlc = 1;
r->luma_vlc = 0;
}
- if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
+ if(IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){
if(r->is16){
t = get_bits(gb, 2);
fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
@@ -538,27 +437,27 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int
c_off = -1;
if(r->avail_cache[avail_index - 1]){
- A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0];
- A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1];
+ A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][0];
+ A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][1];
}
if(r->avail_cache[avail_index - 4]){
- B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0];
- B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1];
+ B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][0];
+ B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][1];
}else{
B[0] = A[0];
B[1] = A[1];
}
if(!r->avail_cache[avail_index - 4 + c_off]){
if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1] || r->rv30)){
- C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0];
- C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1];
+ C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][0];
+ C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][1];
}else{
C[0] = A[0];
C[1] = A[1];
}
}else{
- C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][0];
- C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][1];
+ C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][0];
+ C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][1];
}
mx = mid_pred(A[0], B[0], C[0]);
my = mid_pred(A[1], B[1], C[1]);
@@ -566,8 +465,8 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int
my += r->dmv[dmv_no][1];
for(j = 0; j < part_sizes_h[block_type]; j++){
for(i = 0; i < part_sizes_w[block_type]; i++){
- s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
- s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
+ s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
+ s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
}
}
}
@@ -579,12 +478,8 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int
*/
static int calc_add_mv(RV34DecContext *r, int dir, int val)
{
- int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
- int dist = dir ? -GET_PTS_DIFF(r->next_pts, r->cur_pts) : GET_PTS_DIFF(r->cur_pts, r->last_pts);
- int mul;
+ int mul = dir ? -r->weight2 : r->weight1;
- if(!refdist) return 0;
- mul = (dist << 14) / refdist;
return (val * mul + 0x2000) >> 14;
}
@@ -622,28 +517,28 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
int i, j;
Picture *cur_pic = s->current_picture_ptr;
const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0;
- int type = cur_pic->mb_type[mb_pos];
+ int type = cur_pic->f.mb_type[mb_pos];
memset(A, 0, sizeof(A));
memset(B, 0, sizeof(B));
memset(C, 0, sizeof(C));
if((r->avail_cache[6-1] & type) & mask){
- A[0] = cur_pic->motion_val[dir][mv_pos - 1][0];
- A[1] = cur_pic->motion_val[dir][mv_pos - 1][1];
+ A[0] = cur_pic->f.motion_val[dir][mv_pos - 1][0];
+ A[1] = cur_pic->f.motion_val[dir][mv_pos - 1][1];
has_A = 1;
}
if((r->avail_cache[6-4] & type) & mask){
- B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0];
- B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1];
+ B[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][0];
+ B[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][1];
has_B = 1;
}
if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){
- C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0];
- C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1];
+ C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][0];
+ C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][1];
has_C = 1;
}else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){
- C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0];
- C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1];
+ C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][0];
+ C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][1];
has_C = 1;
}
@@ -654,12 +549,12 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
for(j = 0; j < 2; j++){
for(i = 0; i < 2; i++){
- cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
- cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
+ cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
+ cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
}
}
if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){
- ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride);
+ ZERO8x2(cur_pic->f.motion_val[!dir][mv_pos], s->b8_stride);
}
}
@@ -676,27 +571,27 @@ static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
int avail_index = avail_indexes[0];
if(r->avail_cache[avail_index - 1]){
- A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0];
- A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1];
+ A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][0];
+ A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][1];
}
if(r->avail_cache[avail_index - 4]){
- B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0];
- B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1];
+ B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][0];
+ B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][1];
}else{
B[0] = A[0];
B[1] = A[1];
}
if(!r->avail_cache[avail_index - 4 + 2]){
if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1])){
- C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0];
- C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1];
+ C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][0];
+ C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][1];
}else{
C[0] = A[0];
C[1] = A[1];
}
}else{
- C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+2][0];
- C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+2][1];
+ C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][0];
+ C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][1];
}
mx = mid_pred(A[0], B[0], C[0]);
my = mid_pred(A[1], B[1], C[1]);
@@ -705,8 +600,8 @@ static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
for(j = 0; j < 2; j++){
for(i = 0; i < 2; i++){
for(k = 0; k < 2; k++){
- s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
- s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
+ s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
+ s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
}
}
}
@@ -732,7 +627,7 @@ static const int chroma_coeffs[3] = { 0, 3, 5 };
static inline void rv34_mc(RV34DecContext *r, const int block_type,
const int xoff, const int yoff, int mv_off,
const int width, const int height, int dir,
- const int thirdpel,
+ const int thirdpel, int weighted,
qpel_mc_func (*qpel_mc)[16],
h264_chroma_mc_func (*chroma_mc))
{
@@ -744,24 +639,24 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
if(thirdpel){
int chroma_mx, chroma_my;
- mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
- my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
- lx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
- ly = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
- chroma_mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + 1) >> 1;
- chroma_my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + 1) >> 1;
+ mx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
+ my = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
+ lx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
+ ly = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
+ chroma_mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2;
+ chroma_my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2;
umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24);
umy = (chroma_my + (3 << 24)) / 3 - (1 << 24);
uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3];
uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3];
}else{
int cx, cy;
- mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2;
- my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2;
- lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3;
- ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3;
- cx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
- cy = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
+ mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] >> 2;
+ my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] >> 2;
+ lx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] & 3;
+ ly = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] & 3;
+ cx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2;
+ cy = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2;
umx = cx >> 2;
umy = cy >> 2;
uvmx = (cx & 3) << 1;
@@ -771,9 +666,9 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
uvmx = uvmy = 4;
}
dxy = ly*4 + lx;
- srcY = dir ? s->next_picture_ptr->data[0] : s->last_picture_ptr->data[0];
- srcU = dir ? s->next_picture_ptr->data[1] : s->last_picture_ptr->data[1];
- srcV = dir ? s->next_picture_ptr->data[2] : s->last_picture_ptr->data[2];
+ srcY = dir ? s->next_picture_ptr->f.data[0] : s->last_picture_ptr->f.data[0];
+ srcU = dir ? s->next_picture_ptr->f.data[1] : s->last_picture_ptr->f.data[1];
+ srcV = dir ? s->next_picture_ptr->f.data[2] : s->last_picture_ptr->f.data[2];
src_x = s->mb_x * 16 + xoff + mx;
src_y = s->mb_y * 16 + yoff + my;
uvsrc_x = s->mb_x * 8 + (xoff >> 1) + umx;
@@ -783,7 +678,7 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
if( (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4
|| (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4){
- uint8_t *uvbuf= s->edge_emu_buffer + 22 * s->linesize;
+ uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize;
srcY -= 2 + 2*s->linesize;
s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6,
@@ -796,9 +691,15 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
srcU = uvbuf;
srcV = uvbuf + 16;
}
- Y = s->dest[0] + xoff + yoff *s->linesize;
- U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
- V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ if(!weighted){
+ Y = s->dest[0] + xoff + yoff *s->linesize;
+ U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ }else{
+ Y = r->tmp_b_block_y [dir] + xoff + yoff *s->linesize;
+ U = r->tmp_b_block_uv[dir*2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ V = r->tmp_b_block_uv[dir*2+1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ }
if(block_type == RV34_MB_P_16x8){
qpel_mc[1][dxy](Y, srcY, s->linesize);
@@ -819,43 +720,70 @@ static void rv34_mc_1mv(RV34DecContext *r, const int block_type,
const int xoff, const int yoff, int mv_off,
const int width, const int height, int dir)
{
- rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30,
- r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
- : r->s.dsp.put_rv40_qpel_pixels_tab,
- r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
- : r->s.dsp.put_rv40_chroma_pixels_tab);
+ rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30, 0,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
+}
+
+static void rv4_weight(RV34DecContext *r)
+{
+ r->rdsp.rv40_weight_pixels_tab[0](r->s.dest[0],
+ r->tmp_b_block_y[0],
+ r->tmp_b_block_y[1],
+ r->weight1,
+ r->weight2,
+ r->s.linesize);
+ r->rdsp.rv40_weight_pixels_tab[1](r->s.dest[1],
+ r->tmp_b_block_uv[0],
+ r->tmp_b_block_uv[2],
+ r->weight1,
+ r->weight2,
+ r->s.uvlinesize);
+ r->rdsp.rv40_weight_pixels_tab[1](r->s.dest[2],
+ r->tmp_b_block_uv[1],
+ r->tmp_b_block_uv[3],
+ r->weight1,
+ r->weight2,
+ r->s.uvlinesize);
}
static void rv34_mc_2mv(RV34DecContext *r, const int block_type)
{
- rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30,
- r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
- : r->s.dsp.put_rv40_qpel_pixels_tab,
- r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
- : r->s.dsp.put_rv40_chroma_pixels_tab);
- rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30,
- r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab
- : r->s.dsp.avg_rv40_qpel_pixels_tab,
- r->rv30 ? r->s.dsp.avg_h264_chroma_pixels_tab
- : r->s.dsp.avg_rv40_chroma_pixels_tab);
+ int weighted = !r->rv30 && block_type != RV34_MB_B_BIDIR && r->weight1 != 8192;
+
+ rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30, weighted,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
+ if(!weighted){
+ rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 0,
+ r->rdsp.avg_pixels_tab,
+ r->rdsp.avg_chroma_pixels_tab);
+ }else{
+ rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 1,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
+ rv4_weight(r);
+ }
}
static void rv34_mc_2mv_skip(RV34DecContext *r)
{
int i, j;
+ int weighted = !r->rv30 && r->weight1 != 8192;
+
for(j = 0; j < 2; j++)
for(i = 0; i < 2; i++){
rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30,
- r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
- : r->s.dsp.put_rv40_qpel_pixels_tab,
- r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
- : r->s.dsp.put_rv40_chroma_pixels_tab);
+ weighted,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30,
- r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab
- : r->s.dsp.avg_rv40_qpel_pixels_tab,
- r->rv30 ? r->s.dsp.avg_h264_chroma_pixels_tab
- : r->s.dsp.avg_rv40_chroma_pixels_tab);
+ weighted,
+ weighted ? r->rdsp.put_pixels_tab : r->rdsp.avg_pixels_tab,
+ weighted ? r->rdsp.put_chroma_pixels_tab : r->rdsp.avg_chroma_pixels_tab);
}
+ if(weighted)
+ rv4_weight(r);
}
/** number of motion vectors in each macroblock type */
@@ -881,31 +809,31 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
switch(block_type){
case RV34_MB_TYPE_INTRA:
case RV34_MB_TYPE_INTRA16x16:
- ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+ ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
return 0;
case RV34_MB_SKIP:
if(s->pict_type == AV_PICTURE_TYPE_P){
- ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+ ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
break;
}
case RV34_MB_B_DIRECT:
//surprisingly, it uses motion scheme from next reference frame
- next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride];
+ next_bt = s->next_picture_ptr->f.mb_type[s->mb_x + s->mb_y * s->mb_stride];
if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){
- ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
- ZERO8x2(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+ ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+ ZERO8x2(s->current_picture_ptr->f.motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
}else
for(j = 0; j < 2; j++)
for(i = 0; i < 2; i++)
for(k = 0; k < 2; k++)
for(l = 0; l < 2; l++)
- s->current_picture_ptr->motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k]);
+ s->current_picture_ptr->f.motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][k]);
if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) //we can use whole macroblock MC
rv34_mc_2mv(r, block_type);
else
rv34_mc_2mv_skip(r);
- ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+ ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
break;
case RV34_MB_P_16x16:
case RV34_MB_P_MIX16x16:
@@ -991,7 +919,7 @@ static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int
if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN;
}
if(!right && up){
- topleft = dst[-stride + 3] * 0x01010101;
+ topleft = dst[-stride + 3] * 0x01010101u;
prev = (uint8_t*)&topleft;
}
r->h.pred4x4[itype](dst, prev, stride);
@@ -1139,7 +1067,7 @@ static int rv34_set_deblock_coef(RV34DecContext *r)
MpegEncContext *s = &r->s;
int hmvmask = 0, vmvmask = 0, i, j;
int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
- int16_t (*motion_val)[2] = &s->current_picture_ptr->motion_val[0][midx];
+ int16_t (*motion_val)[2] = &s->current_picture_ptr->f.motion_val[0][midx];
for(j = 0; j < 16; j += 8){
for(i = 0; i < 2; i++){
if(is_mv_diff_gt_3(motion_val + i, 1))
@@ -1170,7 +1098,7 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
GetBitContext *gb = &s->gb;
int cbp, cbp2;
int i, blknum, blkoff;
- DCTELEM block16[64];
+ LOCAL_ALIGNED_16(DCTELEM, block16, [64]);
int luma_dc_quant;
int dist;
int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
@@ -1181,14 +1109,14 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
if(s->mb_x && dist)
r->avail_cache[5] =
- r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
+ r->avail_cache[9] = s->current_picture_ptr->f.mb_type[mb_pos - 1];
if(dist >= s->mb_width)
r->avail_cache[2] =
- r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
+ r->avail_cache[3] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride];
if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
- r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
+ r->avail_cache[4] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride + 1];
if(s->mb_x && dist > s->mb_width)
- r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
+ r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1];
s->qscale = r->si.quant;
cbp = cbp2 = rv34_decode_mb_header(r, intra_types);
@@ -1198,17 +1126,17 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
r->deblock_coefs[mb_pos] = 0xFFFF;
else
r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
- s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
+ s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale;
if(cbp == -1)
return -1;
luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16 ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale];
if(r->is16){
- memset(block16, 0, sizeof(block16));
+ memset(block16, 0, 64 * sizeof(*block16));
rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0);
rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
- rv34_inv_transform_noround(block16);
+ r->rdsp.rv34_inv_transform_tab[1](block16);
}
for(i = 0; i < 16; i++, cbp >>= 1){
@@ -1217,10 +1145,10 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
blkoff = ((i & 1) << 2) + ((i & 4) << 3);
if(cbp & 1)
rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0);
- rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]);
+ r->rdsp.rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]);
if(r->is16) //FIXME: optimize
s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)];
- rv34_inv_transform(s->block[blknum] + blkoff);
+ r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
}
if(r->block_type == RV34_MB_P_MIX16x16)
r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
@@ -1229,10 +1157,10 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
blknum = ((i & 4) >> 2) + 4;
blkoff = ((i & 1) << 2) + ((i & 2) << 4);
rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1);
- rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
- rv34_inv_transform(s->block[blknum] + blkoff);
+ r->rdsp.rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
+ r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
}
- if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos]))
+ if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos]))
rv34_output_macroblock(r, intra_types, cbp2, r->is16);
else
rv34_apply_differences(r, cbp2);
@@ -1255,15 +1183,6 @@ static int check_slice_end(RV34DecContext *r, MpegEncContext *s)
return 0;
}
-static inline int slice_compare(SliceInfo *si1, SliceInfo *si2)
-{
- return si1->type != si2->type ||
- si1->start >= si2->start ||
- si1->width != si2->width ||
- si1->height != si2->height||
- si1->pts != si2->pts;
-}
-
static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size)
{
MpegEncContext *s = &r->s;
@@ -1294,17 +1213,46 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
r->cbp_luma = av_realloc(r->cbp_luma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma));
r->cbp_chroma = av_realloc(r->cbp_chroma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma));
r->deblock_coefs = av_realloc(r->deblock_coefs, r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs));
+ av_freep(&r->tmp_b_block_base);
}
s->pict_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
if(MPV_frame_start(s, s->avctx) < 0)
return -1;
ff_er_frame_start(s);
+ if (!r->tmp_b_block_base) {
+ int i;
+
+ r->tmp_b_block_base = av_malloc(s->linesize * 48);
+ for (i = 0; i < 2; i++)
+ r->tmp_b_block_y[i] = r->tmp_b_block_base + i * 16 * s->linesize;
+ for (i = 0; i < 4; i++)
+ r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize
+ + (i >> 1) * 8 * s->uvlinesize + (i & 1) * 16;
+ }
r->cur_pts = r->si.pts;
if(s->pict_type != AV_PICTURE_TYPE_B){
r->last_pts = r->next_pts;
r->next_pts = r->cur_pts;
+ }else{
+ int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
+ int dist0 = GET_PTS_DIFF(r->cur_pts, r->last_pts);
+ int dist1 = GET_PTS_DIFF(r->next_pts, r->cur_pts);
+
+ if(!refdist){
+ r->weight1 = r->weight2 = 8192;
+ }else{
+ r->weight1 = (dist0 << 14) / refdist;
+ r->weight2 = (dist1 << 14) / refdist;
+ }
}
s->mb_x = s->mb_y = 0;
+ } else {
+ int slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
+
+ if (slice_type != s->pict_type) {
+ av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
+ return AVERROR_INVALIDDATA;
+ }
}
r->si.end = end;
@@ -1321,8 +1269,8 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
}
memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
s->first_slice_line = 1;
- s->resync_mb_x= s->mb_x;
- s->resync_mb_y= s->mb_y;
+ s->resync_mb_x = s->mb_x;
+ s->resync_mb_y = s->mb_y;
ff_init_block_index(s);
while(!check_slice_end(r, s)) {
@@ -1330,7 +1278,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
s->dsp.clear_blocks(s->block[0]);
if(rv34_decode_macroblock(r, r->intra_types + s->mb_x * 4 + 4) < 0){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_ERROR|DC_ERROR|MV_ERROR);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_ERROR);
return -1;
}
if (++s->mb_x == s->mb_width) {
@@ -1348,7 +1296,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
s->first_slice_line=0;
s->mb_num_left--;
}
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
return s->mb_y == s->mb_height;
}
@@ -1364,11 +1312,11 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
MpegEncContext *s = &r->s;
MPV_decode_defaults(s);
- s->avctx= avctx;
+ s->avctx = avctx;
s->out_format = FMT_H263;
- s->codec_id= avctx->codec_id;
+ s->codec_id = avctx->codec_id;
- s->width = avctx->width;
+ s->width = avctx->width;
s->height = avctx->height;
r->s.avctx = avctx;
@@ -1381,7 +1329,16 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
if (MPV_common_init(s) < 0)
return -1;
- ff_h264_pred_init(&r->h, CODEC_ID_RV40, 8);
+ ff_h264_pred_init(&r->h, CODEC_ID_RV40, 8, 1);
+
+#if CONFIG_RV30_DECODER
+ if (avctx->codec_id == CODEC_ID_RV30)
+ ff_rv30dsp_init(&r->rdsp, &r->s.dsp);
+#endif
+#if CONFIG_RV40_DECODER
+ if (avctx->codec_id == CODEC_ID_RV40)
+ ff_rv40dsp_init(&r->rdsp, &r->s.dsp);
+#endif
r->intra_types_stride = 4*s->mb_stride + 4;
r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
@@ -1424,8 +1381,8 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
if (buf_size == 0) {
/* special case for last picture */
if (s->low_delay==0 && s->next_picture_ptr) {
- *pict= *(AVFrame*)s->next_picture_ptr;
- s->next_picture_ptr= NULL;
+ *pict = *(AVFrame*)s->next_picture_ptr;
+ s->next_picture_ptr = NULL;
*data_size = sizeof(AVFrame);
}
@@ -1451,28 +1408,33 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");
return -1;
}
- if((!s->last_picture_ptr || !s->last_picture_ptr->data[0]) && si.type == AV_PICTURE_TYPE_B)
+ if ((!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) && si.type == AV_PICTURE_TYPE_B)
return -1;
if( (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B)
|| (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I)
|| avctx->skip_frame >= AVDISCARD_ALL)
return avpkt->size;
- for(i=0; i<slice_count; i++){
- int offset= get_slice_offset(avctx, slices_hdr, i);
+ for(i = 0; i < slice_count; i++){
+ int offset = get_slice_offset(avctx, slices_hdr, i);
int size;
if(i+1 == slice_count)
- size= buf_size - offset;
+ size = buf_size - offset;
else
- size= get_slice_offset(avctx, slices_hdr, i+1) - offset;
+ size = get_slice_offset(avctx, slices_hdr, i+1) - offset;
- if(offset < 0 || offset > buf_size || size < 0){
+ if(offset < 0 || offset > buf_size){
av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
break;
}
r->si.end = s->mb_width * s->mb_height;
if(i+1 < slice_count){
+ if (get_slice_offset(avctx, slices_hdr, i+1) < 0 ||
+ get_slice_offset(avctx, slices_hdr, i+1) > buf_size) {
+ av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
+ break;
+ }
init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8);
if(r->parse_slice_header(r, &r->s.gb, &si) < 0){
if(i+2 < slice_count)
@@ -1482,6 +1444,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
}else
r->si.end = si.start;
}
+ if (size < 0 || size > buf_size - offset) {
+ av_log(avctx, AV_LOG_ERROR, "Slice size is invalid\n");
+ break;
+ }
last = rv34_decode_slice(r, r->si.end, buf + offset, size);
s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;
if(last)
@@ -1494,16 +1460,16 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
ff_er_frame_end(s);
MPV_frame_end(s);
if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
- *pict= *(AVFrame*)s->current_picture_ptr;
+ *pict = *(AVFrame*)s->current_picture_ptr;
} else if (s->last_picture_ptr != NULL) {
- *pict= *(AVFrame*)s->last_picture_ptr;
+ *pict = *(AVFrame*)s->last_picture_ptr;
}
if(s->last_picture_ptr || s->low_delay){
*data_size = sizeof(AVFrame);
ff_print_debug_info(s, pict);
}
- s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
+ s->current_picture_ptr = NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
}
return avpkt->size;
}
@@ -1516,6 +1482,7 @@ av_cold int ff_rv34_decode_end(AVCodecContext *avctx)
av_freep(&r->intra_types_hist);
r->intra_types = NULL;
+ av_freep(&r->tmp_b_block_base);
av_freep(&r->mb_type);
av_freep(&r->cbp_luma);
av_freep(&r->cbp_chroma);
diff --git a/libavcodec/rv34.h b/libavcodec/rv34.h
index c9f4ff7..12607fb 100644
--- a/libavcodec/rv34.h
+++ b/libavcodec/rv34.h
@@ -32,6 +32,7 @@
#include "mpegvideo.h"
#include "h264pred.h"
+#include "rv34dsp.h"
#define MB_TYPE_SEPARATE_DC 0x01000000
#define IS_SEPARATE_DC(a) ((a) & MB_TYPE_SEPARATE_DC)
@@ -83,6 +84,7 @@ typedef struct SliceInfo{
/** decoder context */
typedef struct RV34DecContext{
MpegEncContext s;
+ RV34DSPContext rdsp;
int8_t *intra_types_hist;///< old block types, used for prediction
int8_t *intra_types; ///< block types
int intra_types_stride;///< block types array stride
@@ -105,6 +107,7 @@ typedef struct RV34DecContext{
int rpr; ///< one field size in RV30 slice header
int cur_pts, last_pts, next_pts;
+ int weight1, weight2; ///< B frame distance fractions (0.14) used in motion compensation
uint16_t *cbp_luma; ///< CBP values for luma subblocks
uint8_t *cbp_chroma; ///< CBP values for chroma subblocks
@@ -113,6 +116,11 @@ typedef struct RV34DecContext{
/** 8x8 block available flags (for MV prediction) */
DECLARE_ALIGNED(8, uint32_t, avail_cache)[3*4];
+ /** temporary blocks for RV4 weighted MC */
+ uint8_t *tmp_b_block_y[2];
+ uint8_t *tmp_b_block_uv[4];
+ uint8_t *tmp_b_block_base;
+
int (*parse_slice_header)(struct RV34DecContext *r, GetBitContext *gb, SliceInfo *si);
int (*decode_mb_info)(struct RV34DecContext *r);
int (*decode_intra_types)(struct RV34DecContext *r, GetBitContext *gb, int8_t *dst);
diff --git a/libavcodec/rv34_parser.c b/libavcodec/rv34_parser.c
new file mode 100644
index 0000000..4c1d2e3
--- /dev/null
+++ b/libavcodec/rv34_parser.c
@@ -0,0 +1,93 @@
+/*
+ * RV30/40 parser
+ * Copyright (c) 2011 Konstantin Shishkov
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * RV30/40 parser
+ */
+
+#include "parser.h"
+#include "libavutil/intreadwrite.h"
+
+typedef struct {
+ ParseContext pc;
+ int64_t key_dts;
+ int key_pts;
+} RV34ParseContext;
+
+static const int rv_to_av_frame_type[4] = {
+ AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B,
+};
+
+static int rv34_parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ RV34ParseContext *pc = s->priv_data;
+ int type, pts, hdr;
+
+ if (buf_size < 13 + *buf * 8) {
+ *poutbuf = buf;
+ *poutbuf_size = buf_size;
+ return buf_size;
+ }
+
+ hdr = AV_RB32(buf + 9 + *buf * 8);
+ if (avctx->codec_id == CODEC_ID_RV30) {
+ type = (hdr >> 27) & 3;
+ pts = (hdr >> 7) & 0x1FFF;
+ } else {
+ type = (hdr >> 29) & 3;
+ pts = (hdr >> 6) & 0x1FFF;
+ }
+
+ if (type != 3 && s->pts != AV_NOPTS_VALUE) {
+ pc->key_dts = s->pts;
+ pc->key_pts = pts;
+ } else {
+ if (type != 3)
+ s->pts = pc->key_dts + ((pts - pc->key_pts) & 0x1FFF);
+ else
+ s->pts = pc->key_dts - ((pc->key_pts - pts) & 0x1FFF);
+ }
+ s->pict_type = rv_to_av_frame_type[type];
+
+ *poutbuf = buf;
+ *poutbuf_size = buf_size;
+ return buf_size;
+}
+
+#ifdef CONFIG_RV30_PARSER
+AVCodecParser ff_rv30_parser = {
+ .codec_ids = { CODEC_ID_RV30 },
+ .priv_data_size = sizeof(RV34ParseContext),
+ .parser_parse = rv34_parse,
+};
+#endif
+
+#ifdef CONFIG_RV40_PARSER
+AVCodecParser ff_rv40_parser = {
+ .codec_ids = { CODEC_ID_RV40 },
+ .priv_data_size = sizeof(RV34ParseContext),
+ .parser_parse = rv34_parse,
+};
+#endif
diff --git a/libavcodec/rv34dsp.c b/libavcodec/rv34dsp.c
new file mode 100644
index 0000000..974bf9e
--- /dev/null
+++ b/libavcodec/rv34dsp.c
@@ -0,0 +1,125 @@
+/*
+ * RV30/40 decoder common dsp functions
+ * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
+ * Copyright (c) 2011 Janne Grunau
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * RV30/40 decoder common dsp functions
+ */
+#include "dsputil.h"
+#include "rv34dsp.h"
+
+/**
+ * @name RV30/40 inverse transform functions
+ * @{
+ */
+
+static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block)
+{
+ int i;
+
+ for(i = 0; i < 4; i++){
+ const int z0 = 13*(block[i+8*0] + block[i+8*2]);
+ const int z1 = 13*(block[i+8*0] - block[i+8*2]);
+ const int z2 = 7* block[i+8*1] - 17*block[i+8*3];
+ const int z3 = 17* block[i+8*1] + 7*block[i+8*3];
+
+ temp[4*i+0] = z0 + z3;
+ temp[4*i+1] = z1 + z2;
+ temp[4*i+2] = z1 - z2;
+ temp[4*i+3] = z0 - z3;
+ }
+}
+
+/**
+ * Real Video 3.0/4.0 inverse transform
+ * Code is almost the same as in SVQ3, only scaling is different.
+ */
+static void rv34_inv_transform_c(DCTELEM *block){
+ int temp[16];
+ int i;
+
+ rv34_row_transform(temp, block);
+
+ for(i = 0; i < 4; i++){
+ const int z0 = 13*(temp[4*0+i] + temp[4*2+i]) + 0x200;
+ const int z1 = 13*(temp[4*0+i] - temp[4*2+i]) + 0x200;
+ const int z2 = 7* temp[4*1+i] - 17*temp[4*3+i];
+ const int z3 = 17* temp[4*1+i] + 7*temp[4*3+i];
+
+ block[i*8+0] = (z0 + z3) >> 10;
+ block[i*8+1] = (z1 + z2) >> 10;
+ block[i*8+2] = (z1 - z2) >> 10;
+ block[i*8+3] = (z0 - z3) >> 10;
+ }
+}
+
+/**
+ * RealVideo 3.0/4.0 inverse transform for DC block
+ *
+ * Code is almost the same as rv34_inv_transform()
+ * but final coefficients are multiplied by 1.5 and have no rounding.
+ */
+static void rv34_inv_transform_noround_c(DCTELEM *block){
+ int temp[16];
+ int i;
+
+ rv34_row_transform(temp, block);
+
+ for(i = 0; i < 4; i++){
+ const int z0 = 13*(temp[4*0+i] + temp[4*2+i]);
+ const int z1 = 13*(temp[4*0+i] - temp[4*2+i]);
+ const int z2 = 7* temp[4*1+i] - 17*temp[4*3+i];
+ const int z3 = 17* temp[4*1+i] + 7*temp[4*3+i];
+
+ block[i*8+0] = ((z0 + z3) * 3) >> 11;
+ block[i*8+1] = ((z1 + z2) * 3) >> 11;
+ block[i*8+2] = ((z1 - z2) * 3) >> 11;
+ block[i*8+3] = ((z0 - z3) * 3) >> 11;
+ }
+}
+
+/** @} */ // transform
+
+
+/**
+ * Dequantize ordinary 4x4 block.
+ */
+void ff_rv34_dequant4x4_neon(DCTELEM *block, int Qdc, int Q);
+static void rv34_dequant4x4_c(DCTELEM *block, int Qdc, int Q)
+{
+ int i, j;
+
+ block[0] = (block[0] * Qdc + 8) >> 4;
+ for (i = 0; i < 4; i++)
+ for (j = !i; j < 4; j++)
+ block[j + i*8] = (block[j + i*8] * Q + 8) >> 4;
+}
+
+av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) {
+ c->rv34_inv_transform_tab[0] = rv34_inv_transform_c;
+ c->rv34_inv_transform_tab[1] = rv34_inv_transform_noround_c;
+
+ c->rv34_dequant4x4 = rv34_dequant4x4_c;
+
+ if (HAVE_NEON)
+ ff_rv34dsp_init_neon(c, dsp);
+}
diff --git a/libavcodec/rv34dsp.h b/libavcodec/rv34dsp.h
new file mode 100644
index 0000000..01352ea
--- /dev/null
+++ b/libavcodec/rv34dsp.h
@@ -0,0 +1,74 @@
+/*
+ * RV30/40 decoder motion compensation functions
+ * Copyright (c) 2008 Konstantin Shishkov
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * RV30/40 decoder motion compensation functions
+ */
+
+#ifndef AVCODEC_RV34DSP_H
+#define AVCODEC_RV34DSP_H
+
+#include "dsputil.h"
+
+typedef void (*rv40_weight_func)(uint8_t *dst/*align width (8 or 16)*/,
+ uint8_t *src1/*align width (8 or 16)*/,
+ uint8_t *src2/*align width (8 or 16)*/,
+ int w1, int w2, int stride);
+
+typedef void (*rv34_inv_transform_func)(DCTELEM *block);
+
+typedef void (*rv40_weak_loop_filter_func)(uint8_t *src, int stride,
+ int filter_p1, int filter_q1,
+ int alpha, int beta,
+ int lims, int lim_q1, int lim_p1);
+
+typedef void (*rv40_strong_loop_filter_func)(uint8_t *src, int stride,
+ int alpha, int lims,
+ int dmode, int chroma);
+
+typedef int (*rv40_loop_filter_strength_func)(uint8_t *src, int stride,
+ int beta, int beta2, int edge,
+ int *p1, int *q1);
+
+typedef struct RV34DSPContext {
+ qpel_mc_func put_pixels_tab[4][16];
+ qpel_mc_func avg_pixels_tab[4][16];
+ h264_chroma_mc_func put_chroma_pixels_tab[3];
+ h264_chroma_mc_func avg_chroma_pixels_tab[3];
+ rv40_weight_func rv40_weight_pixels_tab[2];
+ rv34_inv_transform_func rv34_inv_transform_tab[2];
+ void (*rv34_dequant4x4)(DCTELEM *block, int Qdc, int Q);
+ rv40_weak_loop_filter_func rv40_weak_loop_filter[2];
+ rv40_strong_loop_filter_func rv40_strong_loop_filter[2];
+ rv40_loop_filter_strength_func rv40_loop_filter_strength[2];
+} RV34DSPContext;
+
+void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp);
+void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp);
+void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp);
+
+void ff_rv34dsp_init_neon(RV34DSPContext *c, DSPContext *dsp);
+
+void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp);
+void ff_rv40dsp_init_neon(RV34DSPContext *c, DSPContext *dsp);
+
+#endif /* AVCODEC_RV34DSP_H */
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c
index 46e77bc..bde63e1 100644
--- a/libavcodec/rv40.c
+++ b/libavcodec/rv40.c
@@ -271,148 +271,6 @@ static int rv40_decode_mb_info(RV34DecContext *r)
return 0;
}
-#define CLIP_SYMM(a, b) av_clip(a, -(b), b)
-/**
- * weaker deblocking very similar to the one described in 4.4.2 of JVT-A003r1
- */
-static inline void rv40_weak_loop_filter(uint8_t *src, const int step,
- const int filter_p1, const int filter_q1,
- const int alpha, const int beta,
- const int lim_p0q0,
- const int lim_q1, const int lim_p1,
- const int diff_p1p0, const int diff_q1q0,
- const int diff_p1p2, const int diff_q1q2)
-{
- uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
- int t, u, diff;
-
- t = src[0*step] - src[-1*step];
- if(!t)
- return;
- u = (alpha * FFABS(t)) >> 7;
- if(u > 3 - (filter_p1 && filter_q1))
- return;
-
- t <<= 2;
- if(filter_p1 && filter_q1)
- t += src[-2*step] - src[1*step];
- diff = CLIP_SYMM((t + 4) >> 3, lim_p0q0);
- src[-1*step] = cm[src[-1*step] + diff];
- src[ 0*step] = cm[src[ 0*step] - diff];
- if(FFABS(diff_p1p2) <= beta && filter_p1){
- t = (diff_p1p0 + diff_p1p2 - diff) >> 1;
- src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim_p1)];
- }
- if(FFABS(diff_q1q2) <= beta && filter_q1){
- t = (diff_q1q0 + diff_q1q2 + diff) >> 1;
- src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim_q1)];
- }
-}
-
-static av_always_inline void rv40_adaptive_loop_filter(uint8_t *src, const int step,
- const int stride, const int dmode,
- const int lim_q1, const int lim_p1,
- const int alpha,
- const int beta, const int beta2,
- const int chroma, const int edge)
-{
- int diff_p1p0[4], diff_q1q0[4], diff_p1p2[4], diff_q1q2[4];
- int sum_p1p0 = 0, sum_q1q0 = 0, sum_p1p2 = 0, sum_q1q2 = 0;
- uint8_t *ptr;
- int flag_strong0 = 1, flag_strong1 = 1;
- int filter_p1, filter_q1;
- int i;
- int lims;
-
- for(i = 0, ptr = src; i < 4; i++, ptr += stride){
- diff_p1p0[i] = ptr[-2*step] - ptr[-1*step];
- diff_q1q0[i] = ptr[ 1*step] - ptr[ 0*step];
- sum_p1p0 += diff_p1p0[i];
- sum_q1q0 += diff_q1q0[i];
- }
- filter_p1 = FFABS(sum_p1p0) < (beta<<2);
- filter_q1 = FFABS(sum_q1q0) < (beta<<2);
- if(!filter_p1 && !filter_q1)
- return;
-
- for(i = 0, ptr = src; i < 4; i++, ptr += stride){
- diff_p1p2[i] = ptr[-2*step] - ptr[-3*step];
- diff_q1q2[i] = ptr[ 1*step] - ptr[ 2*step];
- sum_p1p2 += diff_p1p2[i];
- sum_q1q2 += diff_q1q2[i];
- }
-
- if(edge){
- flag_strong0 = filter_p1 && (FFABS(sum_p1p2) < beta2);
- flag_strong1 = filter_q1 && (FFABS(sum_q1q2) < beta2);
- }else{
- flag_strong0 = flag_strong1 = 0;
- }
-
- lims = filter_p1 + filter_q1 + ((lim_q1 + lim_p1) >> 1) + 1;
- if(flag_strong0 && flag_strong1){ /* strong filtering */
- for(i = 0; i < 4; i++, src += stride){
- int sflag, p0, q0, p1, q1;
- int t = src[0*step] - src[-1*step];
-
- if(!t) continue;
- sflag = (alpha * FFABS(t)) >> 7;
- if(sflag > 1) continue;
-
- p0 = (25*src[-3*step] + 26*src[-2*step]
- + 26*src[-1*step]
- + 26*src[ 0*step] + 25*src[ 1*step] + rv40_dither_l[dmode + i]) >> 7;
- q0 = (25*src[-2*step] + 26*src[-1*step]
- + 26*src[ 0*step]
- + 26*src[ 1*step] + 25*src[ 2*step] + rv40_dither_r[dmode + i]) >> 7;
- if(sflag){
- p0 = av_clip(p0, src[-1*step] - lims, src[-1*step] + lims);
- q0 = av_clip(q0, src[ 0*step] - lims, src[ 0*step] + lims);
- }
- p1 = (25*src[-4*step] + 26*src[-3*step]
- + 26*src[-2*step]
- + 26*p0 + 25*src[ 0*step] + rv40_dither_l[dmode + i]) >> 7;
- q1 = (25*src[-1*step] + 26*q0
- + 26*src[ 1*step]
- + 26*src[ 2*step] + 25*src[ 3*step] + rv40_dither_r[dmode + i]) >> 7;
- if(sflag){
- p1 = av_clip(p1, src[-2*step] - lims, src[-2*step] + lims);
- q1 = av_clip(q1, src[ 1*step] - lims, src[ 1*step] + lims);
- }
- src[-2*step] = p1;
- src[-1*step] = p0;
- src[ 0*step] = q0;
- src[ 1*step] = q1;
- if(!chroma){
- src[-3*step] = (25*src[-1*step] + 26*src[-2*step] + 51*src[-3*step] + 26*src[-4*step] + 64) >> 7;
- src[ 2*step] = (25*src[ 0*step] + 26*src[ 1*step] + 51*src[ 2*step] + 26*src[ 3*step] + 64) >> 7;
- }
- }
- }else if(filter_p1 && filter_q1){
- for(i = 0; i < 4; i++, src += stride)
- rv40_weak_loop_filter(src, step, 1, 1, alpha, beta, lims, lim_q1, lim_p1,
- diff_p1p0[i], diff_q1q0[i], diff_p1p2[i], diff_q1q2[i]);
- }else{
- for(i = 0; i < 4; i++, src += stride)
- rv40_weak_loop_filter(src, step, filter_p1, filter_q1,
- alpha, beta, lims>>1, lim_q1>>1, lim_p1>>1,
- diff_p1p0[i], diff_q1q0[i], diff_p1p2[i], diff_q1q2[i]);
- }
-}
-
-static void rv40_v_loop_filter(uint8_t *src, int stride, int dmode,
- int lim_q1, int lim_p1,
- int alpha, int beta, int beta2, int chroma, int edge){
- rv40_adaptive_loop_filter(src, 1, stride, dmode, lim_q1, lim_p1,
- alpha, beta, beta2, chroma, edge);
-}
-static void rv40_h_loop_filter(uint8_t *src, int stride, int dmode,
- int lim_q1, int lim_p1,
- int alpha, int beta, int beta2, int chroma, int edge){
- rv40_adaptive_loop_filter(src, stride, 1, dmode, lim_q1, lim_p1,
- alpha, beta, beta2, chroma, edge);
-}
-
enum RV40BlockPos{
POS_CUR,
POS_TOP,
@@ -436,6 +294,34 @@ enum RV40BlockPos{
static const int neighbour_offs_x[4] = { 0, 0, -1, 0 };
static const int neighbour_offs_y[4] = { 0, -1, 0, 1 };
+static void rv40_adaptive_loop_filter(RV34DSPContext *rdsp,
+ uint8_t *src, int stride, int dmode,
+ int lim_q1, int lim_p1,
+ int alpha, int beta, int beta2,
+ int chroma, int edge, int dir)
+{
+ int filter_p1, filter_q1;
+ int strong;
+ int lims;
+
+ strong = rdsp->rv40_loop_filter_strength[dir](src, stride, beta, beta2,
+ edge, &filter_p1, &filter_q1);
+
+ lims = filter_p1 + filter_q1 + ((lim_q1 + lim_p1) >> 1) + 1;
+
+ if (strong) {
+ rdsp->rv40_strong_loop_filter[dir](src, stride, alpha,
+ lims, dmode, chroma);
+ } else if (filter_p1 & filter_q1) {
+ rdsp->rv40_weak_loop_filter[dir](src, stride, 1, 1, alpha, beta,
+ lims, lim_q1, lim_p1);
+ } else if (filter_p1 | filter_q1) {
+ rdsp->rv40_weak_loop_filter[dir](src, stride, filter_p1, filter_q1,
+ alpha, beta, lims >> 1, lim_q1 >> 1,
+ lim_p1 >> 1);
+ }
+}
+
/**
* RV40 loop filtering function
*/
@@ -475,7 +361,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
mb_pos = row * s->mb_stride;
for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
- int mbtype = s->current_picture_ptr->mb_type[mb_pos];
+ int mbtype = s->current_picture_ptr->f.mb_type[mb_pos];
if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype))
r->cbp_luma [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF;
if(IS_INTRA(mbtype))
@@ -489,7 +375,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
int avail[4];
int y_to_deblock, c_to_deblock[2];
- q = s->current_picture_ptr->qscale_table[mb_pos];
+ q = s->current_picture_ptr->f.qscale_table[mb_pos];
alpha = rv40_alpha_tab[q];
beta = rv40_beta_tab [q];
betaY = betaC = beta * 3;
@@ -504,7 +390,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
if(avail[i]){
int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride;
mvmasks[i] = r->deblock_coefs[pos];
- mbtype [i] = s->current_picture_ptr->mb_type[pos];
+ mbtype [i] = s->current_picture_ptr->f.mb_type[pos];
cbp [i] = r->cbp_luma[pos];
uvcbp[i][0] = r->cbp_chroma[pos] & 0xF;
uvcbp[i][1] = r->cbp_chroma[pos] >> 4;
@@ -563,7 +449,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
}
for(j = 0; j < 16; j += 4){
- Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize;
+ Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize;
for(i = 0; i < 4; i++, Y += 4){
int ij = i + j;
int clip_cur = y_to_deblock & (MASK_CUR << ij) ? clip[POS_CUR] : 0;
@@ -572,10 +458,11 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
// if bottom block is coded then we can filter its top edge
// (or bottom edge of this block, which is the same)
if(y_h_deblock & (MASK_BOTTOM << ij)){
- rv40_h_loop_filter(Y+4*s->linesize, s->linesize, dither,
- y_to_deblock & (MASK_BOTTOM << ij) ? clip[POS_CUR] : 0,
- clip_cur,
- alpha, beta, betaY, 0, 0);
+ rv40_adaptive_loop_filter(&r->rdsp, Y+4*s->linesize,
+ s->linesize, dither,
+ y_to_deblock & (MASK_BOTTOM << ij) ? clip[POS_CUR] : 0,
+ clip_cur, alpha, beta, betaY,
+ 0, 0, 0);
}
// filter left block edge in ordinary mode (with low filtering strength)
if(y_v_deblock & (MASK_CUR << ij) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){
@@ -583,64 +470,64 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0;
else
clip_left = y_to_deblock & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0;
- rv40_v_loop_filter(Y, s->linesize, dither,
- clip_cur,
- clip_left,
- alpha, beta, betaY, 0, 0);
+ rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
+ clip_cur,
+ clip_left,
+ alpha, beta, betaY, 0, 0, 1);
}
// filter top edge of the current macroblock when filtering strength is high
if(!j && y_h_deblock & (MASK_CUR << i) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){
- rv40_h_loop_filter(Y, s->linesize, dither,
+ rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
clip_cur,
mvmasks[POS_TOP] & (MASK_TOP << i) ? clip[POS_TOP] : 0,
- alpha, beta, betaY, 0, 1);
+ alpha, beta, betaY, 0, 1, 0);
}
// filter left block edge in edge mode (with high filtering strength)
if(y_v_deblock & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){
clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0;
- rv40_v_loop_filter(Y, s->linesize, dither,
+ rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
clip_cur,
clip_left,
- alpha, beta, betaY, 0, 1);
+ alpha, beta, betaY, 0, 1, 1);
}
}
}
for(k = 0; k < 2; k++){
for(j = 0; j < 2; j++){
- C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize;
+ C = s->current_picture_ptr->f.data[k + 1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize;
for(i = 0; i < 2; i++, C += 4){
int ij = i + j*2;
int clip_cur = c_to_deblock[k] & (MASK_CUR << ij) ? clip[POS_CUR] : 0;
if(c_h_deblock[k] & (MASK_CUR << (ij+2))){
int clip_bot = c_to_deblock[k] & (MASK_CUR << (ij+2)) ? clip[POS_CUR] : 0;
- rv40_h_loop_filter(C+4*s->uvlinesize, s->uvlinesize, i*8,
+ rv40_adaptive_loop_filter(&r->rdsp, C+4*s->uvlinesize, s->uvlinesize, i*8,
clip_bot,
clip_cur,
- alpha, beta, betaC, 1, 0);
+ alpha, beta, betaC, 1, 0, 0);
}
if((c_v_deblock[k] & (MASK_CUR << ij)) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){
if(!i)
clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0;
else
clip_left = c_to_deblock[k] & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0;
- rv40_v_loop_filter(C, s->uvlinesize, j*8,
+ rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, j*8,
clip_cur,
clip_left,
- alpha, beta, betaC, 1, 0);
+ alpha, beta, betaC, 1, 0, 1);
}
if(!j && c_h_deblock[k] & (MASK_CUR << ij) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){
int clip_top = uvcbp[POS_TOP][k] & (MASK_CUR << (ij+2)) ? clip[POS_TOP] : 0;
- rv40_h_loop_filter(C, s->uvlinesize, i*8,
+ rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, i*8,
clip_cur,
clip_top,
- alpha, beta, betaC, 1, 1);
+ alpha, beta, betaC, 1, 1, 0);
}
if(c_v_deblock[k] & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){
clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0;
- rv40_v_loop_filter(C, s->uvlinesize, j*8,
+ rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, j*8,
clip_cur,
clip_left,
- alpha, beta, betaC, 1, 1);
+ alpha, beta, betaC, 1, 1, 1);
}
}
}
@@ -669,16 +556,15 @@ static av_cold int rv40_decode_init(AVCodecContext *avctx)
}
AVCodec ff_rv40_decoder = {
- "rv40",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_RV40,
- sizeof(RV34DecContext),
- rv40_decode_init,
- NULL,
- ff_rv34_decode_end,
- ff_rv34_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY,
- .flush = ff_mpeg_flush,
- .long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"),
- .pix_fmts= ff_pixfmt_list_420,
+ .name = "rv40",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_RV40,
+ .priv_data_size = sizeof(RV34DecContext),
+ .init = rv40_decode_init,
+ .close = ff_rv34_decode_end,
+ .decode = ff_rv34_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+ .flush = ff_mpeg_flush,
+ .long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"),
+ .pix_fmts = ff_pixfmt_list_420,
};
diff --git a/libavcodec/rv40data.h b/libavcodec/rv40data.h
index 1b6e8c3..42328af 100644
--- a/libavcodec/rv40data.h
+++ b/libavcodec/rv40data.h
@@ -68,20 +68,6 @@ static const uint8_t rv40_luma_dc_quant[2][32] = {
* @name Coefficients used by the RV40 loop filter
* @{
*/
-/**
- * dither values for deblocking filter - left/top values
- */
-static const uint8_t rv40_dither_l[16] = {
- 0x40, 0x50, 0x20, 0x60, 0x30, 0x50, 0x40, 0x30,
- 0x50, 0x40, 0x50, 0x30, 0x60, 0x20, 0x50, 0x40
-};
-/**
- * dither values for deblocking filter - right/bottom values
- */
-static const uint8_t rv40_dither_r[16] = {
- 0x40, 0x30, 0x60, 0x20, 0x50, 0x30, 0x30, 0x40,
- 0x40, 0x40, 0x50, 0x30, 0x20, 0x60, 0x30, 0x40
-};
/** alpha parameter for RV40 loop filter - almost the same as in JVT-A003r1 */
static const uint8_t rv40_alpha_tab[32] = {
diff --git a/libavcodec/rv40dsp.c b/libavcodec/rv40dsp.c
index 2271f54..909ccd1 100644
--- a/libavcodec/rv40dsp.c
+++ b/libavcodec/rv40dsp.c
@@ -26,13 +26,14 @@
#include "avcodec.h"
#include "dsputil.h"
+#include "rv34dsp.h"
#define RV40_LOWPASS(OPNAME, OP) \
static av_unused void OPNAME ## rv40_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,\
const int h, const int C1, const int C2, const int SHIFT){\
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
int i;\
- for(i=0; i<h; i++)\
+ for(i = 0; i < h; i++)\
{\
OP(dst[0], (src[-2] + src[ 3] - 5*(src[-1]+src[2]) + src[0]*C1 + src[1]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
OP(dst[1], (src[-1] + src[ 4] - 5*(src[ 0]+src[3]) + src[1]*C1 + src[2]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
@@ -42,8 +43,8 @@ static av_unused void OPNAME ## rv40_qpel8_h_lowpass(uint8_t *dst, uint8_t *src,
OP(dst[5], (src[ 3] + src[ 8] - 5*(src[ 4]+src[7]) + src[5]*C1 + src[6]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
OP(dst[6], (src[ 4] + src[ 9] - 5*(src[ 5]+src[8]) + src[6]*C1 + src[7]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
OP(dst[7], (src[ 5] + src[10] - 5*(src[ 6]+src[9]) + src[7]*C1 + src[8]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- dst+=dstStride;\
- src+=srcStride;\
+ dst += dstStride;\
+ src += srcStride;\
}\
}\
\
@@ -51,21 +52,21 @@ static void OPNAME ## rv40_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstSt
const int w, const int C1, const int C2, const int SHIFT){\
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
int i;\
- for(i=0; i<w; i++)\
+ for(i = 0; i < w; i++)\
{\
- const int srcB = src[-2*srcStride];\
- const int srcA = src[-1*srcStride];\
- const int src0 = src[0 *srcStride];\
- const int src1 = src[1 *srcStride];\
- const int src2 = src[2 *srcStride];\
- const int src3 = src[3 *srcStride];\
- const int src4 = src[4 *srcStride];\
- const int src5 = src[5 *srcStride];\
- const int src6 = src[6 *srcStride];\
- const int src7 = src[7 *srcStride];\
- const int src8 = src[8 *srcStride];\
- const int src9 = src[9 *srcStride];\
- const int src10= src[10*srcStride];\
+ const int srcB = src[-2*srcStride];\
+ const int srcA = src[-1*srcStride];\
+ const int src0 = src[0 *srcStride];\
+ const int src1 = src[1 *srcStride];\
+ const int src2 = src[2 *srcStride];\
+ const int src3 = src[3 *srcStride];\
+ const int src4 = src[4 *srcStride];\
+ const int src5 = src[5 *srcStride];\
+ const int src6 = src[6 *srcStride];\
+ const int src7 = src[7 *srcStride];\
+ const int src8 = src[8 *srcStride];\
+ const int src9 = src[9 *srcStride];\
+ const int src10 = src[10*srcStride];\
OP(dst[0*dstStride], (srcB + src3 - 5*(srcA+src2) + src0*C1 + src1*C2 + (1<<(SHIFT-1))) >> SHIFT);\
OP(dst[1*dstStride], (srcA + src4 - 5*(src0+src3) + src1*C1 + src2*C2 + (1<<(SHIFT-1))) >> SHIFT);\
OP(dst[2*dstStride], (src0 + src5 - 5*(src1+src4) + src2*C1 + src3*C2 + (1<<(SHIFT-1))) >> SHIFT);\
@@ -105,10 +106,6 @@ static void OPNAME ## rv40_qpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, i
OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 52, 20, 6);\
}\
\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, int stride){\
- OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 20, 20, 5);\
-}\
-\
static void OPNAME ## rv40_qpel ## SIZE ## _mc30_c(uint8_t *dst, uint8_t *src, int stride){\
OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 20, 52, 6);\
}\
@@ -119,46 +116,42 @@ static void OPNAME ## rv40_qpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, i
\
static void OPNAME ## rv40_qpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, int stride){\
uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid= full + SIZE*2;\
+ uint8_t * const full_mid = full + SIZE*2;\
put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
}\
\
static void OPNAME ## rv40_qpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, int stride){\
uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid= full + SIZE*2;\
+ uint8_t * const full_mid = full + SIZE*2;\
put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
}\
\
static void OPNAME ## rv40_qpel ## SIZE ## _mc31_c(uint8_t *dst, uint8_t *src, int stride){\
uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid= full + SIZE*2;\
+ uint8_t * const full_mid = full + SIZE*2;\
put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 52, 6);\
OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
}\
\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, int stride){\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, src, stride, stride, SIZE, 20, 20, 5);\
-}\
-\
static void OPNAME ## rv40_qpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, int stride){\
uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid= full + SIZE*2;\
+ uint8_t * const full_mid = full + SIZE*2;\
put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
}\
\
static void OPNAME ## rv40_qpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, int stride){\
uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid= full + SIZE*2;\
+ uint8_t * const full_mid = full + SIZE*2;\
put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
}\
\
static void OPNAME ## rv40_qpel ## SIZE ## _mc32_c(uint8_t *dst, uint8_t *src, int stride){\
uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid= full + SIZE*2;\
+ uint8_t * const full_mid = full + SIZE*2;\
put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 52, 6);\
OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
}\
@@ -169,14 +162,14 @@ static void OPNAME ## rv40_qpel ## SIZE ## _mc03_c(uint8_t *dst, uint8_t *src, i
\
static void OPNAME ## rv40_qpel ## SIZE ## _mc13_c(uint8_t *dst, uint8_t *src, int stride){\
uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid= full + SIZE*2;\
+ uint8_t * const full_mid = full + SIZE*2;\
put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 52, 6);\
}\
\
static void OPNAME ## rv40_qpel ## SIZE ## _mc23_c(uint8_t *dst, uint8_t *src, int stride){\
uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid= full + SIZE*2;\
+ uint8_t * const full_mid = full + SIZE*2;\
put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 52, 6);\
}\
@@ -205,50 +198,50 @@ static const int rv40_bias[4][4] = {
#define RV40_CHROMA_MC(OPNAME, OP)\
static void OPNAME ## rv40_chroma_mc4_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\
- const int A=(8-x)*(8-y);\
- const int B=( x)*(8-y);\
- const int C=(8-x)*( y);\
- const int D=( x)*( y);\
+ const int A = (8-x) * (8-y);\
+ const int B = ( x) * (8-y);\
+ const int C = (8-x) * ( y);\
+ const int D = ( x) * ( y);\
int i;\
int bias = rv40_bias[y>>1][x>>1];\
\
assert(x<8 && y<8 && x>=0 && y>=0);\
\
if(D){\
- for(i=0; i<h; i++){\
+ for(i = 0; i < h; i++){\
OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + bias));\
OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + bias));\
OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + bias));\
OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + bias));\
- dst+= stride;\
- src+= stride;\
+ dst += stride;\
+ src += stride;\
}\
}else{\
- const int E= B+C;\
- const int step= C ? stride : 1;\
- for(i=0; i<h; i++){\
+ const int E = B + C;\
+ const int step = C ? stride : 1;\
+ for(i = 0; i < h; i++){\
OP(dst[0], (A*src[0] + E*src[step+0] + bias));\
OP(dst[1], (A*src[1] + E*src[step+1] + bias));\
OP(dst[2], (A*src[2] + E*src[step+2] + bias));\
OP(dst[3], (A*src[3] + E*src[step+3] + bias));\
- dst+= stride;\
- src+= stride;\
+ dst += stride;\
+ src += stride;\
}\
}\
}\
\
static void OPNAME ## rv40_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\
- const int A=(8-x)*(8-y);\
- const int B=( x)*(8-y);\
- const int C=(8-x)*( y);\
- const int D=( x)*( y);\
+ const int A = (8-x) * (8-y);\
+ const int B = ( x) * (8-y);\
+ const int C = (8-x) * ( y);\
+ const int D = ( x) * ( y);\
int i;\
int bias = rv40_bias[y>>1][x>>1];\
\
assert(x<8 && y<8 && x>=0 && y>=0);\
\
if(D){\
- for(i=0; i<h; i++){\
+ for(i = 0; i < h; i++){\
OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + bias));\
OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + bias));\
OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + bias));\
@@ -257,13 +250,13 @@ static void OPNAME ## rv40_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a
OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + bias));\
OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + bias));\
OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + bias));\
- dst+= stride;\
- src+= stride;\
+ dst += stride;\
+ src += stride;\
}\
}else{\
- const int E= B+C;\
- const int step= C ? stride : 1;\
- for(i=0; i<h; i++){\
+ const int E = B + C;\
+ const int step = C ? stride : 1;\
+ for(i = 0; i < h; i++){\
OP(dst[0], (A*src[0] + E*src[step+0] + bias));\
OP(dst[1], (A*src[1] + E*src[step+1] + bias));\
OP(dst[2], (A*src[2] + E*src[step+2] + bias));\
@@ -272,8 +265,8 @@ static void OPNAME ## rv40_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a
OP(dst[5], (A*src[5] + E*src[step+5] + bias));\
OP(dst[6], (A*src[6] + E*src[step+6] + bias));\
OP(dst[7], (A*src[7] + E*src[step+7] + bias));\
- dst+= stride;\
- src+= stride;\
+ dst += stride;\
+ src += stride;\
}\
}\
}
@@ -284,70 +277,319 @@ static void OPNAME ## rv40_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a
RV40_CHROMA_MC(put_, op_put)
RV40_CHROMA_MC(avg_, op_avg)
-void ff_rv40dsp_init(DSPContext* c, AVCodecContext *avctx) {
- c->put_rv40_qpel_pixels_tab[0][ 0] = c->put_h264_qpel_pixels_tab[0][0];
- c->put_rv40_qpel_pixels_tab[0][ 1] = put_rv40_qpel16_mc10_c;
- c->put_rv40_qpel_pixels_tab[0][ 2] = put_rv40_qpel16_mc20_c;
- c->put_rv40_qpel_pixels_tab[0][ 3] = put_rv40_qpel16_mc30_c;
- c->put_rv40_qpel_pixels_tab[0][ 4] = put_rv40_qpel16_mc01_c;
- c->put_rv40_qpel_pixels_tab[0][ 5] = put_rv40_qpel16_mc11_c;
- c->put_rv40_qpel_pixels_tab[0][ 6] = put_rv40_qpel16_mc21_c;
- c->put_rv40_qpel_pixels_tab[0][ 7] = put_rv40_qpel16_mc31_c;
- c->put_rv40_qpel_pixels_tab[0][ 8] = put_rv40_qpel16_mc02_c;
- c->put_rv40_qpel_pixels_tab[0][ 9] = put_rv40_qpel16_mc12_c;
- c->put_rv40_qpel_pixels_tab[0][10] = put_rv40_qpel16_mc22_c;
- c->put_rv40_qpel_pixels_tab[0][11] = put_rv40_qpel16_mc32_c;
- c->put_rv40_qpel_pixels_tab[0][12] = put_rv40_qpel16_mc03_c;
- c->put_rv40_qpel_pixels_tab[0][13] = put_rv40_qpel16_mc13_c;
- c->put_rv40_qpel_pixels_tab[0][14] = put_rv40_qpel16_mc23_c;
- c->avg_rv40_qpel_pixels_tab[0][ 0] = c->avg_h264_qpel_pixels_tab[0][0];
- c->avg_rv40_qpel_pixels_tab[0][ 1] = avg_rv40_qpel16_mc10_c;
- c->avg_rv40_qpel_pixels_tab[0][ 2] = avg_rv40_qpel16_mc20_c;
- c->avg_rv40_qpel_pixels_tab[0][ 3] = avg_rv40_qpel16_mc30_c;
- c->avg_rv40_qpel_pixels_tab[0][ 4] = avg_rv40_qpel16_mc01_c;
- c->avg_rv40_qpel_pixels_tab[0][ 5] = avg_rv40_qpel16_mc11_c;
- c->avg_rv40_qpel_pixels_tab[0][ 6] = avg_rv40_qpel16_mc21_c;
- c->avg_rv40_qpel_pixels_tab[0][ 7] = avg_rv40_qpel16_mc31_c;
- c->avg_rv40_qpel_pixels_tab[0][ 8] = avg_rv40_qpel16_mc02_c;
- c->avg_rv40_qpel_pixels_tab[0][ 9] = avg_rv40_qpel16_mc12_c;
- c->avg_rv40_qpel_pixels_tab[0][10] = avg_rv40_qpel16_mc22_c;
- c->avg_rv40_qpel_pixels_tab[0][11] = avg_rv40_qpel16_mc32_c;
- c->avg_rv40_qpel_pixels_tab[0][12] = avg_rv40_qpel16_mc03_c;
- c->avg_rv40_qpel_pixels_tab[0][13] = avg_rv40_qpel16_mc13_c;
- c->avg_rv40_qpel_pixels_tab[0][14] = avg_rv40_qpel16_mc23_c;
- c->put_rv40_qpel_pixels_tab[1][ 0] = c->put_h264_qpel_pixels_tab[1][0];
- c->put_rv40_qpel_pixels_tab[1][ 1] = put_rv40_qpel8_mc10_c;
- c->put_rv40_qpel_pixels_tab[1][ 2] = put_rv40_qpel8_mc20_c;
- c->put_rv40_qpel_pixels_tab[1][ 3] = put_rv40_qpel8_mc30_c;
- c->put_rv40_qpel_pixels_tab[1][ 4] = put_rv40_qpel8_mc01_c;
- c->put_rv40_qpel_pixels_tab[1][ 5] = put_rv40_qpel8_mc11_c;
- c->put_rv40_qpel_pixels_tab[1][ 6] = put_rv40_qpel8_mc21_c;
- c->put_rv40_qpel_pixels_tab[1][ 7] = put_rv40_qpel8_mc31_c;
- c->put_rv40_qpel_pixels_tab[1][ 8] = put_rv40_qpel8_mc02_c;
- c->put_rv40_qpel_pixels_tab[1][ 9] = put_rv40_qpel8_mc12_c;
- c->put_rv40_qpel_pixels_tab[1][10] = put_rv40_qpel8_mc22_c;
- c->put_rv40_qpel_pixels_tab[1][11] = put_rv40_qpel8_mc32_c;
- c->put_rv40_qpel_pixels_tab[1][12] = put_rv40_qpel8_mc03_c;
- c->put_rv40_qpel_pixels_tab[1][13] = put_rv40_qpel8_mc13_c;
- c->put_rv40_qpel_pixels_tab[1][14] = put_rv40_qpel8_mc23_c;
- c->avg_rv40_qpel_pixels_tab[1][ 0] = c->avg_h264_qpel_pixels_tab[1][0];
- c->avg_rv40_qpel_pixels_tab[1][ 1] = avg_rv40_qpel8_mc10_c;
- c->avg_rv40_qpel_pixels_tab[1][ 2] = avg_rv40_qpel8_mc20_c;
- c->avg_rv40_qpel_pixels_tab[1][ 3] = avg_rv40_qpel8_mc30_c;
- c->avg_rv40_qpel_pixels_tab[1][ 4] = avg_rv40_qpel8_mc01_c;
- c->avg_rv40_qpel_pixels_tab[1][ 5] = avg_rv40_qpel8_mc11_c;
- c->avg_rv40_qpel_pixels_tab[1][ 6] = avg_rv40_qpel8_mc21_c;
- c->avg_rv40_qpel_pixels_tab[1][ 7] = avg_rv40_qpel8_mc31_c;
- c->avg_rv40_qpel_pixels_tab[1][ 8] = avg_rv40_qpel8_mc02_c;
- c->avg_rv40_qpel_pixels_tab[1][ 9] = avg_rv40_qpel8_mc12_c;
- c->avg_rv40_qpel_pixels_tab[1][10] = avg_rv40_qpel8_mc22_c;
- c->avg_rv40_qpel_pixels_tab[1][11] = avg_rv40_qpel8_mc32_c;
- c->avg_rv40_qpel_pixels_tab[1][12] = avg_rv40_qpel8_mc03_c;
- c->avg_rv40_qpel_pixels_tab[1][13] = avg_rv40_qpel8_mc13_c;
- c->avg_rv40_qpel_pixels_tab[1][14] = avg_rv40_qpel8_mc23_c;
-
- c->put_rv40_chroma_pixels_tab[0]= put_rv40_chroma_mc8_c;
- c->put_rv40_chroma_pixels_tab[1]= put_rv40_chroma_mc4_c;
- c->avg_rv40_chroma_pixels_tab[0]= avg_rv40_chroma_mc8_c;
- c->avg_rv40_chroma_pixels_tab[1]= avg_rv40_chroma_mc4_c;
+#define RV40_WEIGHT_FUNC(size) \
+static void rv40_weight_func_ ## size (uint8_t *dst, uint8_t *src1, uint8_t *src2, int w1, int w2, int stride)\
+{\
+ int i, j;\
+\
+ for (j = 0; j < size; j++) {\
+ for (i = 0; i < size; i++)\
+ dst[i] = (((w2 * src1[i]) >> 9) + ((w1 * src2[i]) >> 9) + 0x10) >> 5;\
+ src1 += stride;\
+ src2 += stride;\
+ dst += stride;\
+ }\
+}
+
+RV40_WEIGHT_FUNC(16)
+RV40_WEIGHT_FUNC(8)
+
+/**
+ * dither values for deblocking filter - left/top values
+ */
+static const uint8_t rv40_dither_l[16] = {
+ 0x40, 0x50, 0x20, 0x60, 0x30, 0x50, 0x40, 0x30,
+ 0x50, 0x40, 0x50, 0x30, 0x60, 0x20, 0x50, 0x40
+};
+
+/**
+ * dither values for deblocking filter - right/bottom values
+ */
+static const uint8_t rv40_dither_r[16] = {
+ 0x40, 0x30, 0x60, 0x20, 0x50, 0x30, 0x30, 0x40,
+ 0x40, 0x40, 0x50, 0x30, 0x20, 0x60, 0x30, 0x40
+};
+
+#define CLIP_SYMM(a, b) av_clip(a, -(b), b)
+/**
+ * weaker deblocking very similar to the one described in 4.4.2 of JVT-A003r1
+ */
+static av_always_inline void rv40_weak_loop_filter(uint8_t *src,
+ const int step,
+ const int stride,
+ const int filter_p1,
+ const int filter_q1,
+ const int alpha,
+ const int beta,
+ const int lim_p0q0,
+ const int lim_q1,
+ const int lim_p1)
+{
+ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+ int i, t, u, diff;
+
+ for (i = 0; i < 4; i++, src += stride) {
+ int diff_p1p0 = src[-2*step] - src[-1*step];
+ int diff_q1q0 = src[ 1*step] - src[ 0*step];
+ int diff_p1p2 = src[-2*step] - src[-3*step];
+ int diff_q1q2 = src[ 1*step] - src[ 2*step];
+
+ t = src[0*step] - src[-1*step];
+ if (!t)
+ continue;
+
+ u = (alpha * FFABS(t)) >> 7;
+ if (u > 3 - (filter_p1 && filter_q1))
+ continue;
+
+ t <<= 2;
+ if (filter_p1 && filter_q1)
+ t += src[-2*step] - src[1*step];
+
+ diff = CLIP_SYMM((t + 4) >> 3, lim_p0q0);
+ src[-1*step] = cm[src[-1*step] + diff];
+ src[ 0*step] = cm[src[ 0*step] - diff];
+
+ if (filter_p1 && FFABS(diff_p1p2) <= beta) {
+ t = (diff_p1p0 + diff_p1p2 - diff) >> 1;
+ src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim_p1)];
+ }
+
+ if (filter_q1 && FFABS(diff_q1q2) <= beta) {
+ t = (diff_q1q0 + diff_q1q2 + diff) >> 1;
+ src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim_q1)];
+ }
+ }
+}
+
+static void rv40_h_weak_loop_filter(uint8_t *src, const int stride,
+ const int filter_p1, const int filter_q1,
+ const int alpha, const int beta,
+ const int lim_p0q0, const int lim_q1,
+ const int lim_p1)
+{
+ rv40_weak_loop_filter(src, stride, 1, filter_p1, filter_q1,
+ alpha, beta, lim_p0q0, lim_q1, lim_p1);
+}
+
+static void rv40_v_weak_loop_filter(uint8_t *src, const int stride,
+ const int filter_p1, const int filter_q1,
+ const int alpha, const int beta,
+ const int lim_p0q0, const int lim_q1,
+ const int lim_p1)
+{
+ rv40_weak_loop_filter(src, 1, stride, filter_p1, filter_q1,
+ alpha, beta, lim_p0q0, lim_q1, lim_p1);
+}
+
+static av_always_inline void rv40_strong_loop_filter(uint8_t *src,
+ const int step,
+ const int stride,
+ const int alpha,
+ const int lims,
+ const int dmode,
+ const int chroma)
+{
+ int i;
+
+ for(i = 0; i < 4; i++, src += stride){
+ int sflag, p0, q0, p1, q1;
+ int t = src[0*step] - src[-1*step];
+
+ if (!t)
+ continue;
+
+ sflag = (alpha * FFABS(t)) >> 7;
+ if (sflag > 1)
+ continue;
+
+ p0 = (25*src[-3*step] + 26*src[-2*step] + 26*src[-1*step] +
+ 26*src[ 0*step] + 25*src[ 1*step] +
+ rv40_dither_l[dmode + i]) >> 7;
+
+ q0 = (25*src[-2*step] + 26*src[-1*step] + 26*src[ 0*step] +
+ 26*src[ 1*step] + 25*src[ 2*step] +
+ rv40_dither_r[dmode + i]) >> 7;
+
+ if (sflag) {
+ p0 = av_clip(p0, src[-1*step] - lims, src[-1*step] + lims);
+ q0 = av_clip(q0, src[ 0*step] - lims, src[ 0*step] + lims);
+ }
+
+ p1 = (25*src[-4*step] + 26*src[-3*step] + 26*src[-2*step] + 26*p0 +
+ 25*src[ 0*step] + rv40_dither_l[dmode + i]) >> 7;
+ q1 = (25*src[-1*step] + 26*q0 + 26*src[ 1*step] + 26*src[ 2*step] +
+ 25*src[ 3*step] + rv40_dither_r[dmode + i]) >> 7;
+
+ if (sflag) {
+ p1 = av_clip(p1, src[-2*step] - lims, src[-2*step] + lims);
+ q1 = av_clip(q1, src[ 1*step] - lims, src[ 1*step] + lims);
+ }
+
+ src[-2*step] = p1;
+ src[-1*step] = p0;
+ src[ 0*step] = q0;
+ src[ 1*step] = q1;
+
+ if(!chroma){
+ src[-3*step] = (25*src[-1*step] + 26*src[-2*step] +
+ 51*src[-3*step] + 26*src[-4*step] + 64) >> 7;
+ src[ 2*step] = (25*src[ 0*step] + 26*src[ 1*step] +
+ 51*src[ 2*step] + 26*src[ 3*step] + 64) >> 7;
+ }
+ }
+}
+
+static void rv40_h_strong_loop_filter(uint8_t *src, const int stride,
+ const int alpha, const int lims,
+ const int dmode, const int chroma)
+{
+ rv40_strong_loop_filter(src, stride, 1, alpha, lims, dmode, chroma);
+}
+
+static void rv40_v_strong_loop_filter(uint8_t *src, const int stride,
+ const int alpha, const int lims,
+ const int dmode, const int chroma)
+{
+ rv40_strong_loop_filter(src, 1, stride, alpha, lims, dmode, chroma);
+}
+
+static av_always_inline int rv40_loop_filter_strength(uint8_t *src,
+ int step, int stride,
+ int beta, int beta2,
+ int edge,
+ int *p1, int *q1)
+{
+ int sum_p1p0 = 0, sum_q1q0 = 0, sum_p1p2 = 0, sum_q1q2 = 0;
+ int strong0 = 0, strong1 = 0;
+ uint8_t *ptr;
+ int i;
+
+ for (i = 0, ptr = src; i < 4; i++, ptr += stride) {
+ sum_p1p0 += ptr[-2*step] - ptr[-1*step];
+ sum_q1q0 += ptr[ 1*step] - ptr[ 0*step];
+ }
+
+ *p1 = FFABS(sum_p1p0) < (beta << 2);
+ *q1 = FFABS(sum_q1q0) < (beta << 2);
+
+ if(!*p1 && !*q1)
+ return 0;
+
+ if (!edge)
+ return 0;
+
+ for (i = 0, ptr = src; i < 4; i++, ptr += stride) {
+ sum_p1p2 += ptr[-2*step] - ptr[-3*step];
+ sum_q1q2 += ptr[ 1*step] - ptr[ 2*step];
+ }
+
+ strong0 = *p1 && (FFABS(sum_p1p2) < beta2);
+ strong1 = *q1 && (FFABS(sum_q1q2) < beta2);
+
+ return strong0 && strong1;
+}
+
+static int rv40_h_loop_filter_strength(uint8_t *src, int stride,
+ int beta, int beta2, int edge,
+ int *p1, int *q1)
+{
+ return rv40_loop_filter_strength(src, stride, 1, beta, beta2, edge, p1, q1);
+}
+
+static int rv40_v_loop_filter_strength(uint8_t *src, int stride,
+ int beta, int beta2, int edge,
+ int *p1, int *q1)
+{
+ return rv40_loop_filter_strength(src, 1, stride, beta, beta2, edge, p1, q1);
+}
+
+av_cold void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp) {
+
+ ff_rv34dsp_init(c, dsp);
+
+ c->put_pixels_tab[0][ 0] = dsp->put_h264_qpel_pixels_tab[0][0];
+ c->put_pixels_tab[0][ 1] = put_rv40_qpel16_mc10_c;
+ c->put_pixels_tab[0][ 2] = dsp->put_h264_qpel_pixels_tab[0][2];
+ c->put_pixels_tab[0][ 3] = put_rv40_qpel16_mc30_c;
+ c->put_pixels_tab[0][ 4] = put_rv40_qpel16_mc01_c;
+ c->put_pixels_tab[0][ 5] = put_rv40_qpel16_mc11_c;
+ c->put_pixels_tab[0][ 6] = put_rv40_qpel16_mc21_c;
+ c->put_pixels_tab[0][ 7] = put_rv40_qpel16_mc31_c;
+ c->put_pixels_tab[0][ 8] = dsp->put_h264_qpel_pixels_tab[0][8];
+ c->put_pixels_tab[0][ 9] = put_rv40_qpel16_mc12_c;
+ c->put_pixels_tab[0][10] = put_rv40_qpel16_mc22_c;
+ c->put_pixels_tab[0][11] = put_rv40_qpel16_mc32_c;
+ c->put_pixels_tab[0][12] = put_rv40_qpel16_mc03_c;
+ c->put_pixels_tab[0][13] = put_rv40_qpel16_mc13_c;
+ c->put_pixels_tab[0][14] = put_rv40_qpel16_mc23_c;
+ c->put_pixels_tab[0][15] = ff_put_rv40_qpel16_mc33_c;
+ c->avg_pixels_tab[0][ 0] = dsp->avg_h264_qpel_pixels_tab[0][0];
+ c->avg_pixels_tab[0][ 1] = avg_rv40_qpel16_mc10_c;
+ c->avg_pixels_tab[0][ 2] = dsp->avg_h264_qpel_pixels_tab[0][2];
+ c->avg_pixels_tab[0][ 3] = avg_rv40_qpel16_mc30_c;
+ c->avg_pixels_tab[0][ 4] = avg_rv40_qpel16_mc01_c;
+ c->avg_pixels_tab[0][ 5] = avg_rv40_qpel16_mc11_c;
+ c->avg_pixels_tab[0][ 6] = avg_rv40_qpel16_mc21_c;
+ c->avg_pixels_tab[0][ 7] = avg_rv40_qpel16_mc31_c;
+ c->avg_pixels_tab[0][ 8] = dsp->avg_h264_qpel_pixels_tab[0][8];
+ c->avg_pixels_tab[0][ 9] = avg_rv40_qpel16_mc12_c;
+ c->avg_pixels_tab[0][10] = avg_rv40_qpel16_mc22_c;
+ c->avg_pixels_tab[0][11] = avg_rv40_qpel16_mc32_c;
+ c->avg_pixels_tab[0][12] = avg_rv40_qpel16_mc03_c;
+ c->avg_pixels_tab[0][13] = avg_rv40_qpel16_mc13_c;
+ c->avg_pixels_tab[0][14] = avg_rv40_qpel16_mc23_c;
+ c->avg_pixels_tab[0][15] = ff_avg_rv40_qpel16_mc33_c;
+ c->put_pixels_tab[1][ 0] = dsp->put_h264_qpel_pixels_tab[1][0];
+ c->put_pixels_tab[1][ 1] = put_rv40_qpel8_mc10_c;
+ c->put_pixels_tab[1][ 2] = dsp->put_h264_qpel_pixels_tab[1][2];
+ c->put_pixels_tab[1][ 3] = put_rv40_qpel8_mc30_c;
+ c->put_pixels_tab[1][ 4] = put_rv40_qpel8_mc01_c;
+ c->put_pixels_tab[1][ 5] = put_rv40_qpel8_mc11_c;
+ c->put_pixels_tab[1][ 6] = put_rv40_qpel8_mc21_c;
+ c->put_pixels_tab[1][ 7] = put_rv40_qpel8_mc31_c;
+ c->put_pixels_tab[1][ 8] = dsp->put_h264_qpel_pixels_tab[1][8];
+ c->put_pixels_tab[1][ 9] = put_rv40_qpel8_mc12_c;
+ c->put_pixels_tab[1][10] = put_rv40_qpel8_mc22_c;
+ c->put_pixels_tab[1][11] = put_rv40_qpel8_mc32_c;
+ c->put_pixels_tab[1][12] = put_rv40_qpel8_mc03_c;
+ c->put_pixels_tab[1][13] = put_rv40_qpel8_mc13_c;
+ c->put_pixels_tab[1][14] = put_rv40_qpel8_mc23_c;
+ c->put_pixels_tab[1][15] = ff_put_rv40_qpel8_mc33_c;
+ c->avg_pixels_tab[1][ 0] = dsp->avg_h264_qpel_pixels_tab[1][0];
+ c->avg_pixels_tab[1][ 1] = avg_rv40_qpel8_mc10_c;
+ c->avg_pixels_tab[1][ 2] = dsp->avg_h264_qpel_pixels_tab[1][2];
+ c->avg_pixels_tab[1][ 3] = avg_rv40_qpel8_mc30_c;
+ c->avg_pixels_tab[1][ 4] = avg_rv40_qpel8_mc01_c;
+ c->avg_pixels_tab[1][ 5] = avg_rv40_qpel8_mc11_c;
+ c->avg_pixels_tab[1][ 6] = avg_rv40_qpel8_mc21_c;
+ c->avg_pixels_tab[1][ 7] = avg_rv40_qpel8_mc31_c;
+ c->avg_pixels_tab[1][ 8] = dsp->avg_h264_qpel_pixels_tab[1][8];
+ c->avg_pixels_tab[1][ 9] = avg_rv40_qpel8_mc12_c;
+ c->avg_pixels_tab[1][10] = avg_rv40_qpel8_mc22_c;
+ c->avg_pixels_tab[1][11] = avg_rv40_qpel8_mc32_c;
+ c->avg_pixels_tab[1][12] = avg_rv40_qpel8_mc03_c;
+ c->avg_pixels_tab[1][13] = avg_rv40_qpel8_mc13_c;
+ c->avg_pixels_tab[1][14] = avg_rv40_qpel8_mc23_c;
+ c->avg_pixels_tab[1][15] = ff_avg_rv40_qpel8_mc33_c;
+
+ c->put_chroma_pixels_tab[0] = put_rv40_chroma_mc8_c;
+ c->put_chroma_pixels_tab[1] = put_rv40_chroma_mc4_c;
+ c->avg_chroma_pixels_tab[0] = avg_rv40_chroma_mc8_c;
+ c->avg_chroma_pixels_tab[1] = avg_rv40_chroma_mc4_c;
+
+ c->rv40_weight_pixels_tab[0] = rv40_weight_func_16;
+ c->rv40_weight_pixels_tab[1] = rv40_weight_func_8;
+
+ c->rv40_weak_loop_filter[0] = rv40_h_weak_loop_filter;
+ c->rv40_weak_loop_filter[1] = rv40_v_weak_loop_filter;
+ c->rv40_strong_loop_filter[0] = rv40_h_strong_loop_filter;
+ c->rv40_strong_loop_filter[1] = rv40_v_strong_loop_filter;
+ c->rv40_loop_filter_strength[0] = rv40_h_loop_filter_strength;
+ c->rv40_loop_filter_strength[1] = rv40_v_loop_filter_strength;
+
+ if (HAVE_MMX)
+ ff_rv40dsp_init_x86(c, dsp);
+ if (HAVE_NEON)
+ ff_rv40dsp_init_neon(c, dsp);
}
diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c
index 2e261b6..34018ae 100644
--- a/libavcodec/s302m.c
+++ b/libavcodec/s302m.c
@@ -25,6 +25,10 @@
#define AES3_HEADER_LEN 4
+typedef struct S302MDecodeContext {
+ AVFrame frame;
+} S302MDecodeContext;
+
static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
int buf_size)
{
@@ -58,9 +62,9 @@ static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
/* Set output properties */
avctx->bits_per_coded_sample = bits;
if (bits > 16)
- avctx->sample_fmt = SAMPLE_FMT_S32;
+ avctx->sample_fmt = AV_SAMPLE_FMT_S32;
else
- avctx->sample_fmt = SAMPLE_FMT_S16;
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
avctx->channels = channels;
avctx->sample_rate = 48000;
@@ -73,10 +77,12 @@ static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
}
static int s302m_decode_frame(AVCodecContext *avctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame_ptr, AVPacket *avpkt)
{
+ S302MDecodeContext *s = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
+ int block_size, ret;
int frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
if (frame_size < 0)
@@ -85,11 +91,18 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data,
buf_size -= AES3_HEADER_LEN;
buf += AES3_HEADER_LEN;
- if (*data_size < 4 * buf_size * 8 / (avctx->bits_per_coded_sample + 4))
- return -1;
+ /* get output buffer */
+ block_size = (avctx->bits_per_coded_sample + 4) / 4;
+ s->frame.nb_samples = 2 * (buf_size / block_size) / avctx->channels;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+
+ buf_size = (s->frame.nb_samples * avctx->channels / 2) * block_size;
if (avctx->bits_per_coded_sample == 24) {
- uint32_t *o = data;
+ uint32_t *o = (uint32_t *)s->frame.data[0];
for (; buf_size > 6; buf_size -= 7) {
*o++ = (av_reverse[buf[2]] << 24) |
(av_reverse[buf[1]] << 16) |
@@ -100,9 +113,8 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data,
(av_reverse[buf[3] & 0x0f] << 4);
buf += 7;
}
- *data_size = (uint8_t*) o - (uint8_t*) data;
} else if (avctx->bits_per_coded_sample == 20) {
- uint32_t *o = data;
+ uint32_t *o = (uint32_t *)s->frame.data[0];
for (; buf_size > 5; buf_size -= 6) {
*o++ = (av_reverse[buf[2] & 0xf0] << 28) |
(av_reverse[buf[1]] << 20) |
@@ -112,9 +124,8 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data,
(av_reverse[buf[3]] << 12);
buf += 6;
}
- *data_size = (uint8_t*) o - (uint8_t*) data;
} else {
- uint16_t *o = data;
+ uint16_t *o = (uint16_t *)s->frame.data[0];
for (; buf_size > 4; buf_size -= 5) {
*o++ = (av_reverse[buf[1]] << 8) |
av_reverse[buf[0]];
@@ -123,10 +134,22 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data,
(av_reverse[buf[2]] >> 4);
buf += 5;
}
- *data_size = (uint8_t*) o - (uint8_t*) data;
}
- return buf - avpkt->data;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
+ return avpkt->size;
+}
+
+static int s302m_decode_init(AVCodecContext *avctx)
+{
+ S302MDecodeContext *s = avctx->priv_data;
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
+ return 0;
}
@@ -134,7 +157,9 @@ AVCodec ff_s302m_decoder = {
.name = "s302m",
.type = AVMEDIA_TYPE_AUDIO,
.id = CODEC_ID_S302M,
- .priv_data_size = 0,
+ .priv_data_size = sizeof(S302MDecodeContext),
+ .init = s302m_decode_init,
.decode = s302m_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
};
diff --git a/libavcodec/s3tc.c b/libavcodec/s3tc.c
index e8ca688..d0c4eb8 100644
--- a/libavcodec/s3tc.c
+++ b/libavcodec/s3tc.c
@@ -28,7 +28,7 @@
static inline void dxt1_decode_pixels(const uint8_t *s, uint32_t *d,
unsigned int qstride, unsigned int flag,
uint64_t alpha) {
- unsigned int x, y, c0, c1, a = (!flag * 255) << 24;
+ unsigned int x, y, c0, c1, a = (!flag * 255u) << 24;
unsigned int rb0, rb1, rb2, rb3, g0, g1, g2, g3;
uint32_t colors[4], pixels;
diff --git a/libavcodec/s3tc.h b/libavcodec/s3tc.h
index 45da6fa..6e10f43 100644
--- a/libavcodec/s3tc.h
+++ b/libavcodec/s3tc.h
@@ -29,8 +29,8 @@
/**
* Decode DXT1 encoded data to RGB32
- * @param *src source buffer, has to be aligned on a 4-byte boundary
- * @param *dst destination buffer
+ * @param src source buffer, has to be aligned on a 4-byte boundary
+ * @param dst destination buffer
* @param w width of output image
* @param h height of output image
* @param stride line size of output image
@@ -40,8 +40,8 @@ void ff_decode_dxt1(const uint8_t *src, uint8_t *dst,
const unsigned int stride);
/**
* Decode DXT3 encoded data to RGB32
- * @param *src source buffer, has to be aligned on a 4-byte boundary
- * @param *dst destination buffer
+ * @param src source buffer, has to be aligned on a 4-byte boundary
+ * @param dst destination buffer
* @param w width of output image
* @param h height of output image
* @param stride line size of output image
diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c
index 84cff35..e5b3c59 100644
--- a/libavcodec/sgidec.c
+++ b/libavcodec/sgidec.c
@@ -260,14 +260,13 @@ static av_cold int sgi_end(AVCodecContext *avctx)
}
AVCodec ff_sgi_decoder = {
- "sgi",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SGI,
- sizeof(SgiState),
- sgi_init,
- NULL,
- sgi_end,
- decode_frame,
+ .name = "sgi",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SGI,
+ .priv_data_size = sizeof(SgiState),
+ .init = sgi_init,
+ .close = sgi_end,
+ .decode = decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("SGI image"),
};
diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c
index 202f676..9d02eea 100644
--- a/libavcodec/sgienc.c
+++ b/libavcodec/sgienc.c
@@ -160,13 +160,12 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf,
}
AVCodec ff_sgi_encoder = {
- "sgi",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SGI,
- sizeof(SgiContext),
- encode_init,
- encode_frame,
- NULL,
+ .name = "sgi",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SGI,
+ .priv_data_size = sizeof(SgiContext),
+ .init = encode_init,
+ .encode = encode_frame,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_GRAY8, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("SGI image"),
};
diff --git a/libavcodec/sh4/dsputil_align.c b/libavcodec/sh4/dsputil_align.c
index db40ece..0c293a1 100644
--- a/libavcodec/sh4/dsputil_align.c
+++ b/libavcodec/sh4/dsputil_align.c
@@ -333,7 +333,7 @@ DEFFUNC(avg,no_rnd,xy,16,OP_XY,PACK)
void dsputil_init_align(DSPContext* c, AVCodecContext *avctx)
{
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
if (!high_bit_depth) {
c->put_pixels_tab[0][0] = put_rnd_pixels16_o;
diff --git a/libavcodec/sh4/dsputil_sh4.c b/libavcodec/sh4/dsputil_sh4.c
index 9ea48ad..51c1a53 100644
--- a/libavcodec/sh4/dsputil_sh4.c
+++ b/libavcodec/sh4/dsputil_sh4.c
@@ -92,12 +92,13 @@ static void idct_add(uint8_t *dest, int line_size, DCTELEM *block)
void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx)
{
const int idct_algo= avctx->idct_algo;
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
dsputil_init_align(c,avctx);
if (!high_bit_depth)
c->clear_blocks = clear_blocks_sh4;
- if(idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_SH4){
+ if (avctx->bits_per_raw_sample <= 8 &&
+ (idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_SH4)) {
c->idct_put = idct_put;
c->idct_add = idct_add;
c->idct = idct_sh4;
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c
index a6e0075..eb67df7 100644
--- a/libavcodec/shorten.c
+++ b/libavcodec/shorten.c
@@ -28,6 +28,7 @@
#include <limits.h>
#include "avcodec.h"
+#include "bytestream.h"
#include "get_bits.h"
#include "golomb.h"
@@ -69,12 +70,16 @@
#define FN_ZERO 8
#define FN_VERBATIM 9
+/** indicates if the FN_* command is audio or non-audio */
+static const uint8_t is_audio_command[10] = { 1, 1, 1, 1, 0, 0, 0, 1, 1, 0 };
+
#define VERBATIM_CKSIZE_SIZE 5
#define VERBATIM_BYTE_SIZE 8
#define CANONICAL_HEADER_SIZE 44
typedef struct ShortenContext {
AVCodecContext *avctx;
+ AVFrame frame;
GetBitContext gb;
int min_framesize, max_framesize;
@@ -98,6 +103,8 @@ typedef struct ShortenContext {
int blocksize;
int bitindex;
int32_t lpcqoffset;
+ int got_header;
+ int got_quit_command;
} ShortenContext;
static av_cold int shorten_decode_init(AVCodecContext * avctx)
@@ -106,6 +113,9 @@ static av_cold int shorten_decode_init(AVCodecContext * avctx)
s->avctx = avctx;
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
@@ -113,6 +123,7 @@ static int allocate_buffers(ShortenContext *s)
{
int i, chan;
int *coeffs;
+ void *tmp_ptr;
for (chan=0; chan<s->channels; chan++) {
if(FFMAX(1, s->nmean) >= UINT_MAX/sizeof(int32_t)){
@@ -124,9 +135,15 @@ static int allocate_buffers(ShortenContext *s)
return -1;
}
- s->offset[chan] = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean));
+ tmp_ptr = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean));
+ if (!tmp_ptr)
+ return AVERROR(ENOMEM);
+ s->offset[chan] = tmp_ptr;
- s->decoded[chan] = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap));
+ tmp_ptr = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap));
+ if (!tmp_ptr)
+ return AVERROR(ENOMEM);
+ s->decoded[chan] = tmp_ptr;
for (i=0; i<s->nwrap; i++)
s->decoded[chan][i] = 0;
s->decoded[chan] += s->nwrap;
@@ -155,11 +172,11 @@ static void fix_bitshift(ShortenContext *s, int32_t *buffer)
if (s->bitshift != 0)
for (i = 0; i < s->blocksize; i++)
- buffer[s->nwrap + i] <<= s->bitshift;
+ buffer[i] <<= s->bitshift;
}
-static void init_offset(ShortenContext *s)
+static int init_offset(ShortenContext *s)
{
int32_t mean = 0;
int chan, i;
@@ -173,55 +190,46 @@ static void init_offset(ShortenContext *s)
break;
default:
av_log(s->avctx, AV_LOG_ERROR, "unknown audio type");
- abort();
+ return AVERROR_INVALIDDATA;
}
for (chan = 0; chan < s->channels; chan++)
for (i = 0; i < nblock; i++)
s->offset[chan][i] = mean;
+ return 0;
}
-static inline int get_le32(GetBitContext *gb)
-{
- return av_bswap32(get_bits_long(gb, 32));
-}
-
-static inline short get_le16(GetBitContext *gb)
-{
- return av_bswap16(get_bits_long(gb, 16));
-}
-
-static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header_size)
+static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header,
+ int header_size)
{
- GetBitContext hb;
int len;
short wave_format;
- init_get_bits(&hb, header, header_size*8);
- if (get_le32(&hb) != MKTAG('R','I','F','F')) {
+
+ if (bytestream_get_le32(&header) != MKTAG('R','I','F','F')) {
av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
return -1;
}
- skip_bits_long(&hb, 32); /* chunk_size */
+ header += 4; /* chunk size */;
- if (get_le32(&hb) != MKTAG('W','A','V','E')) {
+ if (bytestream_get_le32(&header) != MKTAG('W','A','V','E')) {
av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n");
return -1;
}
- while (get_le32(&hb) != MKTAG('f','m','t',' ')) {
- len = get_le32(&hb);
- skip_bits(&hb, 8*len);
+ while (bytestream_get_le32(&header) != MKTAG('f','m','t',' ')) {
+ len = bytestream_get_le32(&header);
+ header += len;
}
- len = get_le32(&hb);
+ len = bytestream_get_le32(&header);
if (len < 16) {
av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n");
return -1;
}
- wave_format = get_le16(&hb);
+ wave_format = bytestream_get_le16(&header);
switch (wave_format) {
case WAVE_FORMAT_PCM:
@@ -231,11 +239,11 @@ static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header
return -1;
}
- avctx->channels = get_le16(&hb);
- avctx->sample_rate = get_le32(&hb);
- avctx->bit_rate = get_le32(&hb) * 8;
- avctx->block_align = get_le16(&hb);
- avctx->bits_per_coded_sample = get_le16(&hb);
+ header += 2; // skip channels (already got from shorten header)
+ avctx->sample_rate = bytestream_get_le32(&header);
+ header += 4; // skip bit rate (represents original uncompressed bit rate)
+ header += 2; // skip block align (not needed)
+ avctx->bits_per_coded_sample = bytestream_get_le16(&header);
if (avctx->bits_per_coded_sample != 16) {
av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n");
@@ -249,257 +257,342 @@ static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header
return 0;
}
-static int16_t * interleave_buffer(int16_t *samples, int nchan, int blocksize, int32_t **buffer) {
+static void interleave_buffer(int16_t *samples, int nchan, int blocksize,
+ int32_t **buffer)
+{
int i, chan;
for (i=0; i<blocksize; i++)
for (chan=0; chan < nchan; chan++)
- *samples++ = FFMIN(buffer[chan][i], 32768);
- return samples;
+ *samples++ = av_clip_int16(buffer[chan][i]);
}
-static void decode_subframe_lpc(ShortenContext *s, int channel, int residual_size, int pred_order)
+static const int fixed_coeffs[3][3] = {
+ { 1, 0, 0 },
+ { 2, -1, 0 },
+ { 3, -3, 1 }
+};
+
+static int decode_subframe_lpc(ShortenContext *s, int command, int channel,
+ int residual_size, int32_t coffset)
{
- int sum, i, j;
- int *coeffs = s->coeffs;
+ int pred_order, sum, qshift, init_sum, i, j;
+ const int *coeffs;
+
+ if (command == FN_QLPC) {
+ /* read/validate prediction order */
+ pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE);
+ if (pred_order > s->nwrap) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", pred_order);
+ return AVERROR(EINVAL);
+ }
+ /* read LPC coefficients */
+ for (i=0; i<pred_order; i++)
+ s->coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT);
+ coeffs = s->coeffs;
+
+ qshift = LPCQUANT;
+ } else {
+ /* fixed LPC coeffs */
+ pred_order = command;
+ coeffs = fixed_coeffs[pred_order-1];
+ qshift = 0;
+ }
- for (i=0; i<pred_order; i++)
- coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT);
+ /* subtract offset from previous samples to use in prediction */
+ if (command == FN_QLPC && coffset)
+ for (i = -pred_order; i < 0; i++)
+ s->decoded[channel][i] -= coffset;
+ /* decode residual and do LPC prediction */
+ init_sum = pred_order ? (command == FN_QLPC ? s->lpcqoffset : 0) : coffset;
for (i=0; i < s->blocksize; i++) {
- sum = s->lpcqoffset;
+ sum = init_sum;
for (j=0; j<pred_order; j++)
sum += coeffs[j] * s->decoded[channel][i-j-1];
- s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> LPCQUANT);
+ s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> qshift);
}
+
+ /* add offset to current samples */
+ if (command == FN_QLPC && coffset)
+ for (i = 0; i < s->blocksize; i++)
+ s->decoded[channel][i] += coffset;
+
+ return 0;
}
+static int read_header(ShortenContext *s)
+{
+ int i, ret;
+ int maxnlpc = 0;
+ /* shorten signature */
+ if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) {
+ av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n");
+ return -1;
+ }
+
+ s->lpcqoffset = 0;
+ s->blocksize = DEFAULT_BLOCK_SIZE;
+ s->nmean = -1;
+ s->version = get_bits(&s->gb, 8);
+ s->internal_ftype = get_uint(s, TYPESIZE);
+
+ s->channels = get_uint(s, CHANSIZE);
+ if (s->channels > MAX_CHANNELS) {
+ av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
+ return -1;
+ }
+ s->avctx->channels = s->channels;
+
+ /* get blocksize if version > 0 */
+ if (s->version > 0) {
+ int skip_bytes, blocksize;
+
+ blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE));
+ if (!blocksize || blocksize > MAX_BLOCKSIZE) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid or unsupported block size: %d\n",
+ blocksize);
+ return AVERROR(EINVAL);
+ }
+ s->blocksize = blocksize;
+
+ maxnlpc = get_uint(s, LPCQSIZE);
+ s->nmean = get_uint(s, 0);
+
+ skip_bytes = get_uint(s, NSKIPSIZE);
+ for (i=0; i<skip_bytes; i++) {
+ skip_bits(&s->gb, 8);
+ }
+ }
+ s->nwrap = FFMAX(NWRAP, maxnlpc);
+
+ if ((ret = allocate_buffers(s)) < 0)
+ return ret;
+
+ if ((ret = init_offset(s)) < 0)
+ return ret;
+
+ if (s->version > 1)
+ s->lpcqoffset = V2LPCQOFFSET;
+
+ if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) {
+ av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at beginning of stream\n");
+ return -1;
+ }
+
+ s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
+ if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) {
+ av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", s->header_size);
+ return -1;
+ }
-static int shorten_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+ for (i=0; i<s->header_size; i++)
+ s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
+
+ if (decode_wave_header(s->avctx, s->header, s->header_size) < 0)
+ return -1;
+
+ s->cur_chan = 0;
+ s->bitshift = 0;
+
+ s->got_header = 1;
+
+ return 0;
+}
+
+static int shorten_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
ShortenContext *s = avctx->priv_data;
int i, input_buf_size = 0;
- int16_t *samples = data;
+ int ret;
+
+ /* allocate internal bitstream buffer */
if(s->max_framesize == 0){
+ void *tmp_ptr;
s->max_framesize= 1024; // should hopefully be enough for the first header
- s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize);
+ tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size,
+ s->max_framesize);
+ if (!tmp_ptr) {
+ av_log(avctx, AV_LOG_ERROR, "error allocating bitstream buffer\n");
+ return AVERROR(ENOMEM);
+ }
+ s->bitstream = tmp_ptr;
}
+ /* append current packet data to bitstream buffer */
if(1 && s->max_framesize){//FIXME truncated
buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size);
input_buf_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);
s->bitstream_index=0;
}
- memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);
+ if (buf)
+ memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);
buf= &s->bitstream[s->bitstream_index];
buf_size += s->bitstream_size;
s->bitstream_size= buf_size;
- if(buf_size < s->max_framesize){
- *data_size = 0;
+ /* do not decode until buffer has at least max_framesize bytes or
+ the end of the file has been reached */
+ if (buf_size < s->max_framesize && avpkt->data) {
+ *got_frame_ptr = 0;
return input_buf_size;
}
}
+ /* init and position bitstream reader */
init_get_bits(&s->gb, buf, buf_size*8);
skip_bits(&s->gb, s->bitindex);
- if (!s->blocksize)
- {
- int maxnlpc = 0;
- /* shorten signature */
- if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) {
- av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n");
- return -1;
- }
- s->lpcqoffset = 0;
- s->blocksize = DEFAULT_BLOCK_SIZE;
- s->channels = 1;
- s->nmean = -1;
- s->version = get_bits(&s->gb, 8);
- s->internal_ftype = get_uint(s, TYPESIZE);
+ /* process header or next subblock */
+ if (!s->got_header) {
+ if ((ret = read_header(s)) < 0)
+ return ret;
+ *got_frame_ptr = 0;
+ goto finish_frame;
+ }
- s->channels = get_uint(s, CHANSIZE);
- if (s->channels > MAX_CHANNELS) {
- av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
- return -1;
- }
+ /* if quit command was read previously, don't decode anything */
+ if (s->got_quit_command) {
+ *got_frame_ptr = 0;
+ return avpkt->size;
+ }
- /* get blocksize if version > 0 */
- if (s->version > 0) {
- int skip_bytes;
- s->blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE));
- maxnlpc = get_uint(s, LPCQSIZE);
- s->nmean = get_uint(s, 0);
+ s->cur_chan = 0;
+ while (s->cur_chan < s->channels) {
+ int cmd;
+ int len;
- skip_bytes = get_uint(s, NSKIPSIZE);
- for (i=0; i<skip_bytes; i++) {
- skip_bits(&s->gb, 8);
- }
+ if (get_bits_left(&s->gb) < 3+FNSIZE) {
+ *got_frame_ptr = 0;
+ break;
}
- s->nwrap = FFMAX(NWRAP, maxnlpc);
- if (allocate_buffers(s))
- return -1;
-
- init_offset(s);
-
- if (s->version > 1)
- s->lpcqoffset = V2LPCQOFFSET;
-
- if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) {
- av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at beginning of stream\n");
- return -1;
- }
+ cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);
- s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
- if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) {
- av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", s->header_size);
- return -1;
+ if (cmd > FN_VERBATIM) {
+ av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd);
+ *got_frame_ptr = 0;
+ break;
}
- for (i=0; i<s->header_size; i++)
- s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
-
- if (decode_wave_header(avctx, s->header, s->header_size) < 0)
- return -1;
-
- s->cur_chan = 0;
- s->bitshift = 0;
- }
- else
- {
- int cmd;
- int len;
- cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);
- switch (cmd) {
- case FN_ZERO:
- case FN_DIFF0:
- case FN_DIFF1:
- case FN_DIFF2:
- case FN_DIFF3:
- case FN_QLPC:
- {
- int residual_size = 0;
- int channel = s->cur_chan;
- int32_t coffset;
- if (cmd != FN_ZERO) {
- residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);
- /* this is a hack as version 0 differed in defintion of get_sr_golomb_shorten */
- if (s->version == 0)
- residual_size--;
- }
-
- if (s->nmean == 0)
- coffset = s->offset[channel][0];
- else {
- int32_t sum = (s->version < 2) ? 0 : s->nmean / 2;
- for (i=0; i<s->nmean; i++)
- sum += s->offset[channel][i];
- coffset = sum / s->nmean;
- if (s->version >= 2)
- coffset >>= FFMIN(1, s->bitshift);
- }
- switch (cmd) {
- case FN_ZERO:
- for (i=0; i<s->blocksize; i++)
- s->decoded[channel][i] = 0;
- break;
- case FN_DIFF0:
- for (i=0; i<s->blocksize; i++)
- s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + coffset;
- break;
- case FN_DIFF1:
- for (i=0; i<s->blocksize; i++)
- s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + s->decoded[channel][i - 1];
- break;
- case FN_DIFF2:
- for (i=0; i<s->blocksize; i++)
- s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 2*s->decoded[channel][i-1]
- - s->decoded[channel][i-2];
- break;
- case FN_DIFF3:
- for (i=0; i<s->blocksize; i++)
- s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 3*s->decoded[channel][i-1]
- - 3*s->decoded[channel][i-2]
- + s->decoded[channel][i-3];
- break;
- case FN_QLPC:
- {
- int pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE);
- if (pred_order > s->nwrap) {
- av_log(avctx, AV_LOG_ERROR,
- "invalid pred_order %d\n",
- pred_order);
- return -1;
- }
- for (i=0; i<pred_order; i++)
- s->decoded[channel][i - pred_order] -= coffset;
- decode_subframe_lpc(s, channel, residual_size, pred_order);
- if (coffset != 0)
- for (i=0; i < s->blocksize; i++)
- s->decoded[channel][i] += coffset;
- }
+ if (!is_audio_command[cmd]) {
+ /* process non-audio command */
+ switch (cmd) {
+ case FN_VERBATIM:
+ len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
+ while (len--) {
+ get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
}
- if (s->nmean > 0) {
- int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2;
- for (i=0; i<s->blocksize; i++)
- sum += s->decoded[channel][i];
-
- for (i=1; i<s->nmean; i++)
- s->offset[channel][i-1] = s->offset[channel][i];
-
- if (s->version < 2)
- s->offset[channel][s->nmean - 1] = sum / s->blocksize;
- else
- s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift;
+ break;
+ case FN_BITSHIFT:
+ s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE);
+ break;
+ case FN_BLOCKSIZE: {
+ int blocksize = get_uint(s, av_log2(s->blocksize));
+ if (blocksize > s->blocksize) {
+ av_log(avctx, AV_LOG_ERROR, "Increasing block size is not supported\n");
+ return AVERROR_PATCHWELCOME;
}
- for (i=-s->nwrap; i<0; i++)
- s->decoded[channel][i] = s->decoded[channel][i + s->blocksize];
-
- fix_bitshift(s, s->decoded[channel]);
-
- s->cur_chan++;
- if (s->cur_chan == s->channels) {
- samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded);
- s->cur_chan = 0;
- goto frame_done;
+ if (!blocksize || blocksize > MAX_BLOCKSIZE) {
+ av_log(avctx, AV_LOG_ERROR, "invalid or unsupported "
+ "block size: %d\n", blocksize);
+ return AVERROR(EINVAL);
}
+ s->blocksize = blocksize;
break;
}
+ case FN_QUIT:
+ s->got_quit_command = 1;
+ break;
+ }
+ if (cmd == FN_BLOCKSIZE || cmd == FN_QUIT) {
+ *got_frame_ptr = 0;
break;
- case FN_VERBATIM:
- len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
- while (len--) {
- get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
+ }
+ } else {
+ /* process audio command */
+ int residual_size = 0;
+ int channel = s->cur_chan;
+ int32_t coffset;
+
+ /* get Rice code for residual decoding */
+ if (cmd != FN_ZERO) {
+ residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);
+ /* this is a hack as version 0 differed in defintion of get_sr_golomb_shorten */
+ if (s->version == 0)
+ residual_size--;
+ }
+
+ /* calculate sample offset using means from previous blocks */
+ if (s->nmean == 0)
+ coffset = s->offset[channel][0];
+ else {
+ int32_t sum = (s->version < 2) ? 0 : s->nmean / 2;
+ for (i=0; i<s->nmean; i++)
+ sum += s->offset[channel][i];
+ coffset = sum / s->nmean;
+ if (s->version >= 2)
+ coffset >>= FFMIN(1, s->bitshift);
+ }
+
+ /* decode samples for this channel */
+ if (cmd == FN_ZERO) {
+ for (i=0; i<s->blocksize; i++)
+ s->decoded[channel][i] = 0;
+ } else {
+ if ((ret = decode_subframe_lpc(s, cmd, channel, residual_size, coffset)) < 0)
+ return ret;
+ }
+
+ /* update means with info from the current block */
+ if (s->nmean > 0) {
+ int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2;
+ for (i=0; i<s->blocksize; i++)
+ sum += s->decoded[channel][i];
+
+ for (i=1; i<s->nmean; i++)
+ s->offset[channel][i-1] = s->offset[channel][i];
+
+ if (s->version < 2)
+ s->offset[channel][s->nmean - 1] = sum / s->blocksize;
+ else
+ s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift;
+ }
+
+ /* copy wrap samples for use with next block */
+ for (i=-s->nwrap; i<0; i++)
+ s->decoded[channel][i] = s->decoded[channel][i + s->blocksize];
+
+ /* shift samples to add in unused zero bits which were removed
+ during encoding */
+ fix_bitshift(s, s->decoded[channel]);
+
+ /* if this is the last channel in the block, output the samples */
+ s->cur_chan++;
+ if (s->cur_chan == s->channels) {
+ /* get output buffer */
+ s->frame.nb_samples = s->blocksize;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
- break;
- case FN_BITSHIFT:
- s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE);
- break;
- case FN_BLOCKSIZE:
- s->blocksize = get_uint(s, av_log2(s->blocksize));
- break;
- case FN_QUIT:
- *data_size = 0;
- return buf_size;
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd);
- return -1;
- break;
+ /* interleave output */
+ interleave_buffer((int16_t *)s->frame.data[0], s->channels,
+ s->blocksize, s->decoded);
+
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+ }
}
}
-frame_done:
- *data_size = (int8_t *)samples - (int8_t *)data;
+ if (s->cur_chan < s->channels)
+ *got_frame_ptr = 0;
- // s->last_blocksize = s->blocksize;
+finish_frame:
s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8);
i= (get_bits_count(&s->gb))/8;
if (i > buf_size) {
@@ -528,25 +621,18 @@ static av_cold int shorten_decode_close(AVCodecContext *avctx)
}
av_freep(&s->bitstream);
av_freep(&s->coeffs);
- return 0;
-}
-static void shorten_flush(AVCodecContext *avctx){
- ShortenContext *s = avctx->priv_data;
-
- s->bitstream_size=
- s->bitstream_index= 0;
+ return 0;
}
AVCodec ff_shorten_decoder = {
- "shorten",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_SHORTEN,
- sizeof(ShortenContext),
- shorten_decode_init,
- NULL,
- shorten_decode_close,
- shorten_decode_frame,
- .flush= shorten_flush,
+ .name = "shorten",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_SHORTEN,
+ .priv_data_size = sizeof(ShortenContext),
+ .init = shorten_decode_init,
+ .close = shorten_decode_close,
+ .decode = shorten_decode_frame,
+ .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1,
.long_name= NULL_IF_CONFIG_SMALL("Shorten"),
};
diff --git a/libavcodec/simple_idct.c b/libavcodec/simple_idct.c
index 4af11be..0c75261 100644
--- a/libavcodec/simple_idct.c
+++ b/libavcodec/simple_idct.c
@@ -25,378 +25,19 @@
* simpleidct in C.
*/
-/*
- based upon some outcommented c code from mpeg2dec (idct_mmx.c
- written by Aaron Holtzman <aholtzma at ess.engr.uvic.ca>)
- */
+#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "dsputil.h"
#include "mathops.h"
#include "simple_idct.h"
-#if 0
-#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
-#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
-#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
-#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
-#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
-#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
-#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
-#define ROW_SHIFT 8
-#define COL_SHIFT 17
-#else
-#define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-#define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-#define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-#define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-#define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-#define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-#define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-#define ROW_SHIFT 11
-#define COL_SHIFT 20 // 6
-#endif
-
-static inline void idctRowCondDC (DCTELEM * row)
-{
- int a0, a1, a2, a3, b0, b1, b2, b3;
-#if HAVE_FAST_64BIT
- uint64_t temp;
-#else
- uint32_t temp;
-#endif
-
-#if HAVE_FAST_64BIT
-#if HAVE_BIGENDIAN
-#define ROW0_MASK 0xffff000000000000LL
-#else
-#define ROW0_MASK 0xffffLL
-#endif
- if(sizeof(DCTELEM)==2){
- if ( ((((uint64_t *)row)[0] & ~ROW0_MASK) |
- ((uint64_t *)row)[1]) == 0) {
- temp = (row[0] << 3) & 0xffff;
- temp += temp << 16;
- temp += temp << 32;
- ((uint64_t *)row)[0] = temp;
- ((uint64_t *)row)[1] = temp;
- return;
- }
- }else{
- if (!(row[1]|row[2]|row[3]|row[4]|row[5]|row[6]|row[7])) {
- row[0]=row[1]=row[2]=row[3]=row[4]=row[5]=row[6]=row[7]= row[0] << 3;
- return;
- }
- }
-#else
- if(sizeof(DCTELEM)==2){
- if (!(((uint32_t*)row)[1] |
- ((uint32_t*)row)[2] |
- ((uint32_t*)row)[3] |
- row[1])) {
- temp = (row[0] << 3) & 0xffff;
- temp += temp << 16;
- ((uint32_t*)row)[0]=((uint32_t*)row)[1] =
- ((uint32_t*)row)[2]=((uint32_t*)row)[3] = temp;
- return;
- }
- }else{
- if (!(row[1]|row[2]|row[3]|row[4]|row[5]|row[6]|row[7])) {
- row[0]=row[1]=row[2]=row[3]=row[4]=row[5]=row[6]=row[7]= row[0] << 3;
- return;
- }
- }
-#endif
-
- a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1));
- a1 = a0;
- a2 = a0;
- a3 = a0;
-
- /* no need to optimize : gcc does it */
- a0 += W2 * row[2];
- a1 += W6 * row[2];
- a2 -= W6 * row[2];
- a3 -= W2 * row[2];
-
- b0 = MUL16(W1, row[1]);
- MAC16(b0, W3, row[3]);
- b1 = MUL16(W3, row[1]);
- MAC16(b1, -W7, row[3]);
- b2 = MUL16(W5, row[1]);
- MAC16(b2, -W1, row[3]);
- b3 = MUL16(W7, row[1]);
- MAC16(b3, -W5, row[3]);
-
-#if HAVE_FAST_64BIT
- temp = ((uint64_t*)row)[1];
-#else
- temp = ((uint32_t*)row)[2] | ((uint32_t*)row)[3];
-#endif
- if (temp != 0) {
- a0 += W4*row[4] + W6*row[6];
- a1 += - W4*row[4] - W2*row[6];
- a2 += - W4*row[4] + W2*row[6];
- a3 += W4*row[4] - W6*row[6];
-
- MAC16(b0, W5, row[5]);
- MAC16(b0, W7, row[7]);
-
- MAC16(b1, -W1, row[5]);
- MAC16(b1, -W5, row[7]);
-
- MAC16(b2, W7, row[5]);
- MAC16(b2, W3, row[7]);
-
- MAC16(b3, W3, row[5]);
- MAC16(b3, -W1, row[7]);
- }
-
- row[0] = (a0 + b0) >> ROW_SHIFT;
- row[7] = (a0 - b0) >> ROW_SHIFT;
- row[1] = (a1 + b1) >> ROW_SHIFT;
- row[6] = (a1 - b1) >> ROW_SHIFT;
- row[2] = (a2 + b2) >> ROW_SHIFT;
- row[5] = (a2 - b2) >> ROW_SHIFT;
- row[3] = (a3 + b3) >> ROW_SHIFT;
- row[4] = (a3 - b3) >> ROW_SHIFT;
-}
-
-static inline void idctSparseColPut (uint8_t *dest, int line_size,
- DCTELEM * col)
-{
- int a0, a1, a2, a3, b0, b1, b2, b3;
- uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
-
- /* XXX: I did that only to give same values as previous code */
- a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
- a1 = a0;
- a2 = a0;
- a3 = a0;
-
- a0 += + W2*col[8*2];
- a1 += + W6*col[8*2];
- a2 += - W6*col[8*2];
- a3 += - W2*col[8*2];
-
- b0 = MUL16(W1, col[8*1]);
- b1 = MUL16(W3, col[8*1]);
- b2 = MUL16(W5, col[8*1]);
- b3 = MUL16(W7, col[8*1]);
-
- MAC16(b0, + W3, col[8*3]);
- MAC16(b1, - W7, col[8*3]);
- MAC16(b2, - W1, col[8*3]);
- MAC16(b3, - W5, col[8*3]);
-
- if(col[8*4]){
- a0 += + W4*col[8*4];
- a1 += - W4*col[8*4];
- a2 += - W4*col[8*4];
- a3 += + W4*col[8*4];
- }
-
- if (col[8*5]) {
- MAC16(b0, + W5, col[8*5]);
- MAC16(b1, - W1, col[8*5]);
- MAC16(b2, + W7, col[8*5]);
- MAC16(b3, + W3, col[8*5]);
- }
-
- if(col[8*6]){
- a0 += + W6*col[8*6];
- a1 += - W2*col[8*6];
- a2 += + W2*col[8*6];
- a3 += - W6*col[8*6];
- }
-
- if (col[8*7]) {
- MAC16(b0, + W7, col[8*7]);
- MAC16(b1, - W5, col[8*7]);
- MAC16(b2, + W3, col[8*7]);
- MAC16(b3, - W1, col[8*7]);
- }
-
- dest[0] = cm[(a0 + b0) >> COL_SHIFT];
- dest += line_size;
- dest[0] = cm[(a1 + b1) >> COL_SHIFT];
- dest += line_size;
- dest[0] = cm[(a2 + b2) >> COL_SHIFT];
- dest += line_size;
- dest[0] = cm[(a3 + b3) >> COL_SHIFT];
- dest += line_size;
- dest[0] = cm[(a3 - b3) >> COL_SHIFT];
- dest += line_size;
- dest[0] = cm[(a2 - b2) >> COL_SHIFT];
- dest += line_size;
- dest[0] = cm[(a1 - b1) >> COL_SHIFT];
- dest += line_size;
- dest[0] = cm[(a0 - b0) >> COL_SHIFT];
-}
-
-static inline void idctSparseColAdd (uint8_t *dest, int line_size,
- DCTELEM * col)
-{
- int a0, a1, a2, a3, b0, b1, b2, b3;
- uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
-
- /* XXX: I did that only to give same values as previous code */
- a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
- a1 = a0;
- a2 = a0;
- a3 = a0;
-
- a0 += + W2*col[8*2];
- a1 += + W6*col[8*2];
- a2 += - W6*col[8*2];
- a3 += - W2*col[8*2];
-
- b0 = MUL16(W1, col[8*1]);
- b1 = MUL16(W3, col[8*1]);
- b2 = MUL16(W5, col[8*1]);
- b3 = MUL16(W7, col[8*1]);
-
- MAC16(b0, + W3, col[8*3]);
- MAC16(b1, - W7, col[8*3]);
- MAC16(b2, - W1, col[8*3]);
- MAC16(b3, - W5, col[8*3]);
-
- if(col[8*4]){
- a0 += + W4*col[8*4];
- a1 += - W4*col[8*4];
- a2 += - W4*col[8*4];
- a3 += + W4*col[8*4];
- }
-
- if (col[8*5]) {
- MAC16(b0, + W5, col[8*5]);
- MAC16(b1, - W1, col[8*5]);
- MAC16(b2, + W7, col[8*5]);
- MAC16(b3, + W3, col[8*5]);
- }
-
- if(col[8*6]){
- a0 += + W6*col[8*6];
- a1 += - W2*col[8*6];
- a2 += + W2*col[8*6];
- a3 += - W6*col[8*6];
- }
+#define BIT_DEPTH 8
+#include "simple_idct_template.c"
+#undef BIT_DEPTH
- if (col[8*7]) {
- MAC16(b0, + W7, col[8*7]);
- MAC16(b1, - W5, col[8*7]);
- MAC16(b2, + W3, col[8*7]);
- MAC16(b3, - W1, col[8*7]);
- }
-
- dest[0] = cm[dest[0] + ((a0 + b0) >> COL_SHIFT)];
- dest += line_size;
- dest[0] = cm[dest[0] + ((a1 + b1) >> COL_SHIFT)];
- dest += line_size;
- dest[0] = cm[dest[0] + ((a2 + b2) >> COL_SHIFT)];
- dest += line_size;
- dest[0] = cm[dest[0] + ((a3 + b3) >> COL_SHIFT)];
- dest += line_size;
- dest[0] = cm[dest[0] + ((a3 - b3) >> COL_SHIFT)];
- dest += line_size;
- dest[0] = cm[dest[0] + ((a2 - b2) >> COL_SHIFT)];
- dest += line_size;
- dest[0] = cm[dest[0] + ((a1 - b1) >> COL_SHIFT)];
- dest += line_size;
- dest[0] = cm[dest[0] + ((a0 - b0) >> COL_SHIFT)];
-}
-
-static inline void idctSparseCol (DCTELEM * col)
-{
- int a0, a1, a2, a3, b0, b1, b2, b3;
-
- /* XXX: I did that only to give same values as previous code */
- a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
- a1 = a0;
- a2 = a0;
- a3 = a0;
-
- a0 += + W2*col[8*2];
- a1 += + W6*col[8*2];
- a2 += - W6*col[8*2];
- a3 += - W2*col[8*2];
-
- b0 = MUL16(W1, col[8*1]);
- b1 = MUL16(W3, col[8*1]);
- b2 = MUL16(W5, col[8*1]);
- b3 = MUL16(W7, col[8*1]);
-
- MAC16(b0, + W3, col[8*3]);
- MAC16(b1, - W7, col[8*3]);
- MAC16(b2, - W1, col[8*3]);
- MAC16(b3, - W5, col[8*3]);
-
- if(col[8*4]){
- a0 += + W4*col[8*4];
- a1 += - W4*col[8*4];
- a2 += - W4*col[8*4];
- a3 += + W4*col[8*4];
- }
-
- if (col[8*5]) {
- MAC16(b0, + W5, col[8*5]);
- MAC16(b1, - W1, col[8*5]);
- MAC16(b2, + W7, col[8*5]);
- MAC16(b3, + W3, col[8*5]);
- }
-
- if(col[8*6]){
- a0 += + W6*col[8*6];
- a1 += - W2*col[8*6];
- a2 += + W2*col[8*6];
- a3 += - W6*col[8*6];
- }
-
- if (col[8*7]) {
- MAC16(b0, + W7, col[8*7]);
- MAC16(b1, - W5, col[8*7]);
- MAC16(b2, + W3, col[8*7]);
- MAC16(b3, - W1, col[8*7]);
- }
-
- col[0 ] = ((a0 + b0) >> COL_SHIFT);
- col[8 ] = ((a1 + b1) >> COL_SHIFT);
- col[16] = ((a2 + b2) >> COL_SHIFT);
- col[24] = ((a3 + b3) >> COL_SHIFT);
- col[32] = ((a3 - b3) >> COL_SHIFT);
- col[40] = ((a2 - b2) >> COL_SHIFT);
- col[48] = ((a1 - b1) >> COL_SHIFT);
- col[56] = ((a0 - b0) >> COL_SHIFT);
-}
-
-void ff_simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block)
-{
- int i;
- for(i=0; i<8; i++)
- idctRowCondDC(block + i*8);
-
- for(i=0; i<8; i++)
- idctSparseColPut(dest + i, line_size, block + i);
-}
-
-void ff_simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block)
-{
- int i;
- for(i=0; i<8; i++)
- idctRowCondDC(block + i*8);
-
- for(i=0; i<8; i++)
- idctSparseColAdd(dest + i, line_size, block + i);
-}
-
-void ff_simple_idct(DCTELEM *block)
-{
- int i;
- for(i=0; i<8; i++)
- idctRowCondDC(block + i*8);
-
- for(i=0; i<8; i++)
- idctSparseCol(block + i);
-}
+#define BIT_DEPTH 10
+#include "simple_idct_template.c"
+#undef BIT_DEPTH
/* 2x4x8 idct */
@@ -467,7 +108,7 @@ void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block)
/* IDCT8 on each line */
for(i=0; i<8; i++) {
- idctRowCondDC(block + i*8);
+ idctRowCondDC_8(block + i*8, 0);
}
/* IDCT4 and store */
@@ -542,7 +183,7 @@ void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block)
/* IDCT8 on each line */
for(i=0; i<4; i++) {
- idctRowCondDC(block + i*8);
+ idctRowCondDC_8(block + i*8, 0);
}
/* IDCT4 and store */
@@ -562,7 +203,7 @@ void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block)
/* IDCT8 and store */
for(i=0; i<4; i++){
- idctSparseColAdd(dest + i, line_size, block + i);
+ idctSparseColAdd_8(dest + i, line_size, block + i);
}
}
@@ -580,3 +221,17 @@ void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block)
idct4col_add(dest + i, line_size, block + i);
}
}
+
+void ff_prores_idct(DCTELEM *block, const int16_t *qmat)
+{
+ int i;
+
+ for (i = 0; i < 64; i++)
+ block[i] *= qmat[i];
+
+ for (i = 0; i < 8; i++)
+ idctRowCondDC_10(block + i*8, 2);
+
+ for (i = 0; i < 8; i++)
+ idctSparseCol_10(block + i);
+}
diff --git a/libavcodec/simple_idct.h b/libavcodec/simple_idct.h
index 23bae9c..6e22158 100644
--- a/libavcodec/simple_idct.h
+++ b/libavcodec/simple_idct.h
@@ -31,12 +31,23 @@
#include <stdint.h>
#include "dsputil.h"
-void ff_simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_simple_idct_put_8(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_simple_idct_add_8(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_simple_idct_8(DCTELEM *block);
+
+void ff_simple_idct_put_10(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_simple_idct_add_10(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_simple_idct_10(DCTELEM *block);
+/**
+ * Special version of ff_simple_idct_10() which does dequantization
+ * and scales by a factor of 2 more between the two IDCTs to account
+ * for larger scale of input coefficients.
+ */
+void ff_prores_idct(DCTELEM *block, const int16_t *qmat);
+
void ff_simple_idct_mmx(int16_t *block);
void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block);
void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block);
-void ff_simple_idct(DCTELEM *block);
void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block);
diff --git a/libavcodec/simple_idct_template.c b/libavcodec/simple_idct_template.c
new file mode 100644
index 0000000..fdec3aa
--- /dev/null
+++ b/libavcodec/simple_idct_template.c
@@ -0,0 +1,326 @@
+/*
+ * Simple IDCT
+ *
+ * Copyright (c) 2001 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * simpleidct in C.
+ */
+
+/*
+ based upon some outcommented c code from mpeg2dec (idct_mmx.c
+ written by Aaron Holtzman <aholtzma at ess.engr.uvic.ca>)
+ */
+
+#include "bit_depth_template.c"
+
+#undef W1
+#undef W2
+#undef W3
+#undef W4
+#undef W5
+#undef W6
+#undef W7
+#undef ROW_SHIFT
+#undef COL_SHIFT
+#undef DC_SHIFT
+#undef MUL
+#undef MAC
+
+#if BIT_DEPTH == 8
+
+#define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+#define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
+
+#define ROW_SHIFT 11
+#define COL_SHIFT 20
+#define DC_SHIFT 3
+
+#define MUL(a, b) MUL16(a, b)
+#define MAC(a, b, c) MAC16(a, b, c)
+
+#elif BIT_DEPTH == 10
+
+#define W1 90901
+#define W2 85627
+#define W3 77062
+#define W4 65535
+#define W5 51491
+#define W6 35468
+#define W7 18081
+
+#define ROW_SHIFT 15
+#define COL_SHIFT 20
+#define DC_SHIFT 1
+
+#define MUL(a, b) ((a) * (b))
+#define MAC(a, b, c) ((a) += (b) * (c))
+
+#else
+
+#error "Unsupported bitdepth"
+
+#endif
+
+static inline void FUNC(idctRowCondDC)(DCTELEM *row, int extra_shift)
+{
+ int a0, a1, a2, a3, b0, b1, b2, b3;
+
+#if HAVE_FAST_64BIT
+#define ROW0_MASK (0xffffLL << 48 * HAVE_BIGENDIAN)
+ if (((((uint64_t *)row)[0] & ~ROW0_MASK) | ((uint64_t *)row)[1]) == 0) {
+ uint64_t temp;
+ if (DC_SHIFT - extra_shift > 0) {
+ temp = (row[0] << (DC_SHIFT - extra_shift)) & 0xffff;
+ } else {
+ temp = (row[0] >> (extra_shift - DC_SHIFT)) & 0xffff;
+ }
+ temp += temp << 16;
+ temp += temp << 32;
+ ((uint64_t *)row)[0] = temp;
+ ((uint64_t *)row)[1] = temp;
+ return;
+ }
+#else
+ if (!(((uint32_t*)row)[1] |
+ ((uint32_t*)row)[2] |
+ ((uint32_t*)row)[3] |
+ row[1])) {
+ uint32_t temp;
+ if (DC_SHIFT - extra_shift > 0) {
+ temp = (row[0] << (DC_SHIFT - extra_shift)) & 0xffff;
+ } else {
+ temp = (row[0] >> (extra_shift - DC_SHIFT)) & 0xffff;
+ }
+ temp += temp << 16;
+ ((uint32_t*)row)[0]=((uint32_t*)row)[1] =
+ ((uint32_t*)row)[2]=((uint32_t*)row)[3] = temp;
+ return;
+ }
+#endif
+
+ a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1));
+ a1 = a0;
+ a2 = a0;
+ a3 = a0;
+
+ a0 += W2 * row[2];
+ a1 += W6 * row[2];
+ a2 -= W6 * row[2];
+ a3 -= W2 * row[2];
+
+ b0 = MUL(W1, row[1]);
+ MAC(b0, W3, row[3]);
+ b1 = MUL(W3, row[1]);
+ MAC(b1, -W7, row[3]);
+ b2 = MUL(W5, row[1]);
+ MAC(b2, -W1, row[3]);
+ b3 = MUL(W7, row[1]);
+ MAC(b3, -W5, row[3]);
+
+ if (AV_RN64A(row + 4)) {
+ a0 += W4*row[4] + W6*row[6];
+ a1 += - W4*row[4] - W2*row[6];
+ a2 += - W4*row[4] + W2*row[6];
+ a3 += W4*row[4] - W6*row[6];
+
+ MAC(b0, W5, row[5]);
+ MAC(b0, W7, row[7]);
+
+ MAC(b1, -W1, row[5]);
+ MAC(b1, -W5, row[7]);
+
+ MAC(b2, W7, row[5]);
+ MAC(b2, W3, row[7]);
+
+ MAC(b3, W3, row[5]);
+ MAC(b3, -W1, row[7]);
+ }
+
+ row[0] = (a0 + b0) >> (ROW_SHIFT + extra_shift);
+ row[7] = (a0 - b0) >> (ROW_SHIFT + extra_shift);
+ row[1] = (a1 + b1) >> (ROW_SHIFT + extra_shift);
+ row[6] = (a1 - b1) >> (ROW_SHIFT + extra_shift);
+ row[2] = (a2 + b2) >> (ROW_SHIFT + extra_shift);
+ row[5] = (a2 - b2) >> (ROW_SHIFT + extra_shift);
+ row[3] = (a3 + b3) >> (ROW_SHIFT + extra_shift);
+ row[4] = (a3 - b3) >> (ROW_SHIFT + extra_shift);
+}
+
+#define IDCT_COLS do { \
+ a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4)); \
+ a1 = a0; \
+ a2 = a0; \
+ a3 = a0; \
+ \
+ a0 += W2*col[8*2]; \
+ a1 += W6*col[8*2]; \
+ a2 += -W6*col[8*2]; \
+ a3 += -W2*col[8*2]; \
+ \
+ b0 = MUL(W1, col[8*1]); \
+ b1 = MUL(W3, col[8*1]); \
+ b2 = MUL(W5, col[8*1]); \
+ b3 = MUL(W7, col[8*1]); \
+ \
+ MAC(b0, W3, col[8*3]); \
+ MAC(b1, -W7, col[8*3]); \
+ MAC(b2, -W1, col[8*3]); \
+ MAC(b3, -W5, col[8*3]); \
+ \
+ if (col[8*4]) { \
+ a0 += W4*col[8*4]; \
+ a1 += -W4*col[8*4]; \
+ a2 += -W4*col[8*4]; \
+ a3 += W4*col[8*4]; \
+ } \
+ \
+ if (col[8*5]) { \
+ MAC(b0, W5, col[8*5]); \
+ MAC(b1, -W1, col[8*5]); \
+ MAC(b2, W7, col[8*5]); \
+ MAC(b3, W3, col[8*5]); \
+ } \
+ \
+ if (col[8*6]) { \
+ a0 += W6*col[8*6]; \
+ a1 += -W2*col[8*6]; \
+ a2 += W2*col[8*6]; \
+ a3 += -W6*col[8*6]; \
+ } \
+ \
+ if (col[8*7]) { \
+ MAC(b0, W7, col[8*7]); \
+ MAC(b1, -W5, col[8*7]); \
+ MAC(b2, W3, col[8*7]); \
+ MAC(b3, -W1, col[8*7]); \
+ } \
+ } while (0)
+
+static inline void FUNC(idctSparseColPut)(pixel *dest, int line_size,
+ DCTELEM *col)
+{
+ int a0, a1, a2, a3, b0, b1, b2, b3;
+ INIT_CLIP;
+
+ IDCT_COLS;
+
+ dest[0] = CLIP((a0 + b0) >> COL_SHIFT);
+ dest += line_size;
+ dest[0] = CLIP((a1 + b1) >> COL_SHIFT);
+ dest += line_size;
+ dest[0] = CLIP((a2 + b2) >> COL_SHIFT);
+ dest += line_size;
+ dest[0] = CLIP((a3 + b3) >> COL_SHIFT);
+ dest += line_size;
+ dest[0] = CLIP((a3 - b3) >> COL_SHIFT);
+ dest += line_size;
+ dest[0] = CLIP((a2 - b2) >> COL_SHIFT);
+ dest += line_size;
+ dest[0] = CLIP((a1 - b1) >> COL_SHIFT);
+ dest += line_size;
+ dest[0] = CLIP((a0 - b0) >> COL_SHIFT);
+}
+
+static inline void FUNC(idctSparseColAdd)(pixel *dest, int line_size,
+ DCTELEM *col)
+{
+ int a0, a1, a2, a3, b0, b1, b2, b3;
+ INIT_CLIP;
+
+ IDCT_COLS;
+
+ dest[0] = CLIP(dest[0] + ((a0 + b0) >> COL_SHIFT));
+ dest += line_size;
+ dest[0] = CLIP(dest[0] + ((a1 + b1) >> COL_SHIFT));
+ dest += line_size;
+ dest[0] = CLIP(dest[0] + ((a2 + b2) >> COL_SHIFT));
+ dest += line_size;
+ dest[0] = CLIP(dest[0] + ((a3 + b3) >> COL_SHIFT));
+ dest += line_size;
+ dest[0] = CLIP(dest[0] + ((a3 - b3) >> COL_SHIFT));
+ dest += line_size;
+ dest[0] = CLIP(dest[0] + ((a2 - b2) >> COL_SHIFT));
+ dest += line_size;
+ dest[0] = CLIP(dest[0] + ((a1 - b1) >> COL_SHIFT));
+ dest += line_size;
+ dest[0] = CLIP(dest[0] + ((a0 - b0) >> COL_SHIFT));
+}
+
+static inline void FUNC(idctSparseCol)(DCTELEM *col)
+{
+ int a0, a1, a2, a3, b0, b1, b2, b3;
+
+ IDCT_COLS;
+
+ col[0 ] = ((a0 + b0) >> COL_SHIFT);
+ col[8 ] = ((a1 + b1) >> COL_SHIFT);
+ col[16] = ((a2 + b2) >> COL_SHIFT);
+ col[24] = ((a3 + b3) >> COL_SHIFT);
+ col[32] = ((a3 - b3) >> COL_SHIFT);
+ col[40] = ((a2 - b2) >> COL_SHIFT);
+ col[48] = ((a1 - b1) >> COL_SHIFT);
+ col[56] = ((a0 - b0) >> COL_SHIFT);
+}
+
+void FUNC(ff_simple_idct_put)(uint8_t *dest_, int line_size, DCTELEM *block)
+{
+ pixel *dest = (pixel *)dest_;
+ int i;
+
+ line_size /= sizeof(pixel);
+
+ for (i = 0; i < 8; i++)
+ FUNC(idctRowCondDC)(block + i*8, 0);
+
+ for (i = 0; i < 8; i++)
+ FUNC(idctSparseColPut)(dest + i, line_size, block + i);
+}
+
+void FUNC(ff_simple_idct_add)(uint8_t *dest_, int line_size, DCTELEM *block)
+{
+ pixel *dest = (pixel *)dest_;
+ int i;
+
+ line_size /= sizeof(pixel);
+
+ for (i = 0; i < 8; i++)
+ FUNC(idctRowCondDC)(block + i*8, 0);
+
+ for (i = 0; i < 8; i++)
+ FUNC(idctSparseColAdd)(dest + i, line_size, block + i);
+}
+
+void FUNC(ff_simple_idct)(DCTELEM *block)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ FUNC(idctRowCondDC)(block + i*8, 0);
+
+ for (i = 0; i < 8; i++)
+ FUNC(idctSparseCol)(block + i);
+}
diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c
index 2e86861..4502fa5 100644
--- a/libavcodec/sipr.c
+++ b/libavcodec/sipr.c
@@ -27,7 +27,7 @@
#include "libavutil/mathematics.h"
#include "avcodec.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
#include "dsputil.h"
@@ -194,14 +194,16 @@ static void decode_parameters(SiprParameters* parms, GetBitContext *pgb,
{
int i, j;
- parms->ma_pred_switch = get_bits(pgb, p->ma_predictor_bits);
+ if (p->ma_predictor_bits)
+ parms->ma_pred_switch = get_bits(pgb, p->ma_predictor_bits);
for (i = 0; i < 5; i++)
parms->vq_indexes[i] = get_bits(pgb, p->vq_indexes_bits[i]);
for (i = 0; i < p->subframe_count; i++) {
parms->pitch_delay[i] = get_bits(pgb, p->pitch_delay_bits[i]);
- parms->gp_index[i] = get_bits(pgb, p->gp_index_bits);
+ if (p->gp_index_bits)
+ parms->gp_index[i] = get_bits(pgb, p->gp_index_bits);
for (j = 0; j < p->number_of_fc_indexes; j++)
parms->fc_indexes[i][j] = get_bits(pgb, p->fc_index_bits[j]);
@@ -478,15 +480,24 @@ static av_cold int sipr_decoder_init(AVCodecContext * avctx)
SiprContext *ctx = avctx->priv_data;
int i;
- if (avctx->bit_rate > 12200) ctx->mode = MODE_16k;
- else if (avctx->bit_rate > 7500 ) ctx->mode = MODE_8k5;
- else if (avctx->bit_rate > 5750 ) ctx->mode = MODE_6k5;
- else ctx->mode = MODE_5k0;
+ switch (avctx->block_align) {
+ case 20: ctx->mode = MODE_16k; break;
+ case 19: ctx->mode = MODE_8k5; break;
+ case 29: ctx->mode = MODE_6k5; break;
+ case 37: ctx->mode = MODE_5k0; break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Invalid block_align: %d\n", avctx->block_align);
+ return AVERROR(EINVAL);
+ }
av_log(avctx, AV_LOG_DEBUG, "Mode: %s\n", modes[ctx->mode].mode_name);
- if (ctx->mode == MODE_16k)
+ if (ctx->mode == MODE_16k) {
ff_sipr_init_16k(ctx);
+ ctx->decode_frame = ff_sipr_decode_frame_16k;
+ } else {
+ ctx->decode_frame = decode_frame;
+ }
for (i = 0; i < LP_FILTER_ORDER; i++)
ctx->lsp_history[i] = cos((i+1) * M_PI / (LP_FILTER_ORDER + 1));
@@ -496,66 +507,64 @@ static av_cold int sipr_decoder_init(AVCodecContext * avctx)
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ avcodec_get_frame_defaults(&ctx->frame);
+ avctx->coded_frame = &ctx->frame;
+
return 0;
}
-static int sipr_decode_frame(AVCodecContext *avctx, void *datap,
- int *data_size, AVPacket *avpkt)
+static int sipr_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
SiprContext *ctx = avctx->priv_data;
const uint8_t *buf=avpkt->data;
SiprParameters parm;
const SiprModeParam *mode_par = &modes[ctx->mode];
GetBitContext gb;
- float *data = datap;
+ float *samples;
int subframe_size = ctx->mode == MODE_16k ? L_SUBFR_16k : SUBFR_SIZE;
- int i;
+ int i, ret;
ctx->avctx = avctx;
if (avpkt->size < (mode_par->bits_per_frame >> 3)) {
av_log(avctx, AV_LOG_ERROR,
"Error processing packet: packet size (%d) too small\n",
avpkt->size);
-
- *data_size = 0;
return -1;
}
- if (*data_size < subframe_size * mode_par->subframe_count * sizeof(float)) {
- av_log(avctx, AV_LOG_ERROR,
- "Error processing packet: output buffer (%d) too small\n",
- *data_size);
- *data_size = 0;
- return -1;
+ /* get output buffer */
+ ctx->frame.nb_samples = mode_par->frames_per_packet * subframe_size *
+ mode_par->subframe_count;
+ if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
+ samples = (float *)ctx->frame.data[0];
init_get_bits(&gb, buf, mode_par->bits_per_frame);
for (i = 0; i < mode_par->frames_per_packet; i++) {
decode_parameters(&parm, &gb, mode_par);
- if (ctx->mode == MODE_16k)
- ff_sipr_decode_frame_16k(ctx, &parm, data);
- else
- decode_frame(ctx, &parm, data);
+ ctx->decode_frame(ctx, &parm, samples);
- data += subframe_size * mode_par->subframe_count;
+ samples += subframe_size * mode_par->subframe_count;
}
- *data_size = mode_par->frames_per_packet * subframe_size *
- mode_par->subframe_count * sizeof(float);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = ctx->frame;
return mode_par->bits_per_frame >> 3;
}
AVCodec ff_sipr_decoder = {
- "sipr",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_SIPR,
- sizeof(SiprContext),
- sipr_decoder_init,
- NULL,
- NULL,
- sipr_decode_frame,
+ .name = "sipr",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_SIPR,
+ .priv_data_size = sizeof(SiprContext),
+ .init = sipr_decoder_init,
+ .decode = sipr_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("RealAudio SIPR / ACELP.NET"),
};
diff --git a/libavcodec/sipr.h b/libavcodec/sipr.h
index 5b2198e..9515321 100644
--- a/libavcodec/sipr.h
+++ b/libavcodec/sipr.h
@@ -53,8 +53,18 @@ typedef enum {
MODE_COUNT
} SiprMode;
-typedef struct {
+typedef struct SiprParameters {
+ int ma_pred_switch; ///< switched moving average predictor
+ int vq_indexes[5];
+ int pitch_delay[5]; ///< pitch delay
+ int gp_index[5]; ///< adaptive-codebook gain indexes
+ int16_t fc_indexes[5][10]; ///< fixed-codebook indexes
+ int gc_index[5]; ///< fixed-codebook gain indexes
+} SiprParameters;
+
+typedef struct SiprContext {
AVCodecContext *avctx;
+ AVFrame frame;
SiprMode mode;
@@ -85,16 +95,10 @@ typedef struct {
float mem_preemph[LP_FILTER_ORDER_16k];
float synth[LP_FILTER_ORDER_16k];
double lsp_history_16k[16];
-} SiprContext;
-typedef struct {
- int ma_pred_switch; ///< switched moving average predictor
- int vq_indexes[5];
- int pitch_delay[5]; ///< pitch delay
- int gp_index[5]; ///< adaptive-codebook gain indexes
- int16_t fc_indexes[5][10]; ///< fixed-codebook indexes
- int gc_index[5]; ///< fixed-codebook gain indexes
-} SiprParameters;
+ void (*decode_frame)(struct SiprContext *ctx, SiprParameters *params,
+ float *out_data);
+} SiprContext;
extern const float ff_pow_0_5[16];
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index 1fa40de..0c7c405 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -33,8 +33,9 @@
#include "avcodec.h"
#include "libavutil/audioconvert.h"
+#include "mathops.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
#include "bytestream.h"
@@ -557,46 +558,80 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
+typedef struct SmackerAudioContext {
+ AVFrame frame;
+} SmackerAudioContext;
+
static av_cold int smka_decode_init(AVCodecContext *avctx)
{
+ SmackerAudioContext *s = avctx->priv_data;
+
+ if (avctx->channels < 1 || avctx->channels > 2) {
+ av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
+ return AVERROR(EINVAL);
+ }
avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
avctx->sample_fmt = avctx->bits_per_coded_sample == 8 ? AV_SAMPLE_FMT_U8 : AV_SAMPLE_FMT_S16;
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
/**
* Decode Smacker audio data
*/
-static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+static int smka_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
+ SmackerAudioContext *s = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
GetBitContext gb;
HuffContext h[4];
VLC vlc[4];
- int16_t *samples = data;
- int8_t *samples8 = data;
+ int16_t *samples;
+ uint8_t *samples8;
int val;
- int i, res;
+ int i, res, ret;
int unp_size;
int bits, stereo;
int pred[2] = {0, 0};
+ if (buf_size <= 4) {
+ av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
+ return AVERROR(EINVAL);
+ }
+
unp_size = AV_RL32(buf);
init_get_bits(&gb, buf + 4, (buf_size - 4) * 8);
if(!get_bits1(&gb)){
av_log(avctx, AV_LOG_INFO, "Sound: no data\n");
- *data_size = 0;
+ *got_frame_ptr = 0;
return 1;
}
stereo = get_bits1(&gb);
bits = get_bits1(&gb);
- if (unp_size & 0xC0000000 || unp_size > *data_size) {
- av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n");
- return -1;
+ if (stereo ^ (avctx->channels != 1)) {
+ av_log(avctx, AV_LOG_ERROR, "channels mismatch\n");
+ return AVERROR(EINVAL);
+ }
+ if (bits && avctx->sample_fmt == AV_SAMPLE_FMT_U8) {
+ av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n");
+ return AVERROR(EINVAL);
+ }
+
+ /* get output buffer */
+ s->frame.nb_samples = unp_size / (avctx->channels * (bits + 1));
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
+ samples = (int16_t *)s->frame.data[0];
+ samples8 = s->frame.data[0];
memset(vlc, 0, sizeof(VLC) * 4);
memset(h, 0, sizeof(HuffContext) * 4);
@@ -638,8 +673,8 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
else
res = 0;
val |= h[3].values[res] << 8;
- pred[1] += (int16_t)val;
- *samples++ = pred[1];
+ pred[1] += sign_extend(val, 16);
+ *samples++ = av_clip_int16(pred[1]);
} else {
if(vlc[0].table)
res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);
@@ -651,8 +686,8 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
else
res = 0;
val |= h[1].values[res] << 8;
- pred[0] += val;
- *samples++ = pred[0];
+ pred[0] += sign_extend(val, 16);
+ *samples++ = av_clip_int16(pred[0]);
}
}
} else { //8-bit data
@@ -666,15 +701,15 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3);
else
res = 0;
- pred[1] += (int8_t)h[1].values[res];
- *samples8++ = pred[1];
+ pred[1] += sign_extend(h[1].values[res], 8);
+ *samples8++ = av_clip_uint8(pred[1]);
} else {
if(vlc[0].table)
res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);
else
res = 0;
- pred[0] += (int8_t)h[0].values[res];
- *samples8++ = pred[0];
+ pred[0] += sign_extend(h[0].values[res], 8);
+ *samples8++ = av_clip_uint8(pred[0]);
}
}
}
@@ -687,32 +722,32 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
av_free(h[i].values);
}
- *data_size = unp_size;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return buf_size;
}
AVCodec ff_smacker_decoder = {
- "smackvid",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SMACKVIDEO,
- sizeof(SmackVContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "smackvid",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SMACKVIDEO,
+ .priv_data_size = sizeof(SmackVContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Smacker video"),
};
AVCodec ff_smackaud_decoder = {
- "smackaud",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_SMACKAUDIO,
- 0,
- smka_decode_init,
- NULL,
- NULL,
- smka_decode_frame,
+ .name = "smackaud",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_SMACKAUDIO,
+ .priv_data_size = sizeof(SmackerAudioContext),
+ .init = smka_decode_init,
+ .decode = smka_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Smacker audio"),
};
diff --git a/libavcodec/smc.c b/libavcodec/smc.c
index e75203d..f4a0b6a 100644
--- a/libavcodec/smc.c
+++ b/libavcodec/smc.c
@@ -475,14 +475,13 @@ static av_cold int smc_decode_end(AVCodecContext *avctx)
}
AVCodec ff_smc_decoder = {
- "smc",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SMC,
- sizeof(SmcContext),
- smc_decode_init,
- NULL,
- smc_decode_end,
- smc_decode_frame,
- CODEC_CAP_DR1,
+ .name = "smc",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SMC,
+ .priv_data_size = sizeof(SmcContext),
+ .init = smc_decode_init,
+ .close = smc_decode_end,
+ .decode = smc_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("QuickTime Graphics (SMC)"),
};
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index 28f04f1..447289a 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -19,751 +19,56 @@
*/
#include "libavutil/intmath.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
#include "avcodec.h"
#include "dsputil.h"
#include "dwt.h"
#include "snow.h"
+#include "snowdata.h"
#include "rangecoder.h"
#include "mathops.h"
-
-#include "mpegvideo.h"
#include "h263.h"
#undef NDEBUG
#include <assert.h>
-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,
- 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,
- 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,
- 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,
--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,
--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,
--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,
--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, 0,
-};
-static const int8_t quant3b[256]={
- 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, 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, 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, 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, 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,-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,-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,-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,-1,
-};
-static const int8_t quant3bA[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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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 int8_t quant5[256]={
- 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,
-};
-static const int8_t quant7[256]={
- 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,
-};
-static const int8_t quant9[256]={
- 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1,
-};
-static const int8_t quant11[256]={
- 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1,
-};
-static const int8_t quant13[256]={
- 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1,
-};
-
-#if 0 //64*cubic
-static const uint8_t obmc32[1024]={
- 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, 0, 0,
- 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
- 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0,
- 0, 0, 4, 4, 8, 8, 12, 16, 16, 20, 24, 24, 28, 28, 32, 32, 32, 32, 28, 28, 24, 24, 20, 16, 16, 12, 8, 8, 4, 4, 0, 0,
- 0, 0, 4, 8, 8, 12, 16, 24, 28, 32, 36, 40, 44, 48, 48, 48, 48, 48, 48, 44, 40, 36, 32, 28, 24, 16, 12, 8, 8, 4, 0, 0,
- 0, 4, 4, 8, 12, 20, 24, 32, 40, 44, 52, 56, 60, 64, 68, 72, 72, 68, 64, 60, 56, 52, 44, 40, 32, 24, 20, 12, 8, 4, 4, 0,
- 0, 4, 4, 12, 16, 24, 32, 40, 52, 60, 68, 76, 80, 88, 88, 92, 92, 88, 88, 80, 76, 68, 60, 52, 40, 32, 24, 16, 12, 4, 4, 0,
- 0, 4, 8, 16, 24, 32, 40, 52, 64, 76, 84, 92,100,108,112,116,116,112,108,100, 92, 84, 76, 64, 52, 40, 32, 24, 16, 8, 4, 0,
- 0, 4, 8, 16, 28, 40, 52, 64, 76, 88,100,112,124,132,136,140,140,136,132,124,112,100, 88, 76, 64, 52, 40, 28, 16, 8, 4, 0,
- 0, 4, 12, 20, 32, 44, 60, 76, 88,104,120,132,144,152,160,164,164,160,152,144,132,120,104, 88, 76, 60, 44, 32, 20, 12, 4, 0,
- 0, 4, 12, 24, 36, 48, 68, 84,100,120,136,152,164,176,180,184,184,180,176,164,152,136,120,100, 84, 68, 48, 36, 24, 12, 4, 0,
- 0, 4, 12, 24, 40, 56, 76, 92,112,132,152,168,180,192,204,208,208,204,192,180,168,152,132,112, 92, 76, 56, 40, 24, 12, 4, 0,
- 0, 4, 16, 28, 44, 60, 80,100,124,144,164,180,196,208,220,224,224,220,208,196,180,164,144,124,100, 80, 60, 44, 28, 16, 4, 0,
- 0, 8, 16, 28, 48, 64, 88,108,132,152,176,192,208,224,232,240,240,232,224,208,192,176,152,132,108, 88, 64, 48, 28, 16, 8, 0,
- 0, 4, 16, 32, 48, 68, 88,112,136,160,180,204,220,232,244,248,248,244,232,220,204,180,160,136,112, 88, 68, 48, 32, 16, 4, 0,
- 1, 8, 16, 32, 48, 72, 92,116,140,164,184,208,224,240,248,255,255,248,240,224,208,184,164,140,116, 92, 72, 48, 32, 16, 8, 1,
- 1, 8, 16, 32, 48, 72, 92,116,140,164,184,208,224,240,248,255,255,248,240,224,208,184,164,140,116, 92, 72, 48, 32, 16, 8, 1,
- 0, 4, 16, 32, 48, 68, 88,112,136,160,180,204,220,232,244,248,248,244,232,220,204,180,160,136,112, 88, 68, 48, 32, 16, 4, 0,
- 0, 8, 16, 28, 48, 64, 88,108,132,152,176,192,208,224,232,240,240,232,224,208,192,176,152,132,108, 88, 64, 48, 28, 16, 8, 0,
- 0, 4, 16, 28, 44, 60, 80,100,124,144,164,180,196,208,220,224,224,220,208,196,180,164,144,124,100, 80, 60, 44, 28, 16, 4, 0,
- 0, 4, 12, 24, 40, 56, 76, 92,112,132,152,168,180,192,204,208,208,204,192,180,168,152,132,112, 92, 76, 56, 40, 24, 12, 4, 0,
- 0, 4, 12, 24, 36, 48, 68, 84,100,120,136,152,164,176,180,184,184,180,176,164,152,136,120,100, 84, 68, 48, 36, 24, 12, 4, 0,
- 0, 4, 12, 20, 32, 44, 60, 76, 88,104,120,132,144,152,160,164,164,160,152,144,132,120,104, 88, 76, 60, 44, 32, 20, 12, 4, 0,
- 0, 4, 8, 16, 28, 40, 52, 64, 76, 88,100,112,124,132,136,140,140,136,132,124,112,100, 88, 76, 64, 52, 40, 28, 16, 8, 4, 0,
- 0, 4, 8, 16, 24, 32, 40, 52, 64, 76, 84, 92,100,108,112,116,116,112,108,100, 92, 84, 76, 64, 52, 40, 32, 24, 16, 8, 4, 0,
- 0, 4, 4, 12, 16, 24, 32, 40, 52, 60, 68, 76, 80, 88, 88, 92, 92, 88, 88, 80, 76, 68, 60, 52, 40, 32, 24, 16, 12, 4, 4, 0,
- 0, 4, 4, 8, 12, 20, 24, 32, 40, 44, 52, 56, 60, 64, 68, 72, 72, 68, 64, 60, 56, 52, 44, 40, 32, 24, 20, 12, 8, 4, 4, 0,
- 0, 0, 4, 8, 8, 12, 16, 24, 28, 32, 36, 40, 44, 48, 48, 48, 48, 48, 48, 44, 40, 36, 32, 28, 24, 16, 12, 8, 8, 4, 0, 0,
- 0, 0, 4, 4, 8, 8, 12, 16, 16, 20, 24, 24, 28, 28, 32, 32, 32, 32, 28, 28, 24, 24, 20, 16, 16, 12, 8, 8, 4, 4, 0, 0,
- 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0,
- 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 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, 0, 0, 0, 0, 0, 0, 0,
-//error:0.000022
-};
-static const uint8_t obmc16[256]={
- 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0,
- 0, 4, 4, 8, 16, 20, 20, 24, 24, 20, 20, 16, 8, 4, 4, 0,
- 0, 4, 16, 24, 36, 44, 52, 60, 60, 52, 44, 36, 24, 16, 4, 0,
- 0, 8, 24, 44, 60, 80, 96,104,104, 96, 80, 60, 44, 24, 8, 0,
- 0, 16, 36, 60, 92,116,136,152,152,136,116, 92, 60, 36, 16, 0,
- 0, 20, 44, 80,116,152,180,196,196,180,152,116, 80, 44, 20, 0,
- 4, 20, 52, 96,136,180,212,228,228,212,180,136, 96, 52, 20, 4,
- 4, 24, 60,104,152,196,228,248,248,228,196,152,104, 60, 24, 4,
- 4, 24, 60,104,152,196,228,248,248,228,196,152,104, 60, 24, 4,
- 4, 20, 52, 96,136,180,212,228,228,212,180,136, 96, 52, 20, 4,
- 0, 20, 44, 80,116,152,180,196,196,180,152,116, 80, 44, 20, 0,
- 0, 16, 36, 60, 92,116,136,152,152,136,116, 92, 60, 36, 16, 0,
- 0, 8, 24, 44, 60, 80, 96,104,104, 96, 80, 60, 44, 24, 8, 0,
- 0, 4, 16, 24, 36, 44, 52, 60, 60, 52, 44, 36, 24, 16, 4, 0,
- 0, 4, 4, 8, 16, 20, 20, 24, 24, 20, 20, 16, 8, 4, 4, 0,
- 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0,
-//error:0.000033
-};
-#elif 1 // 64*linear
-static const uint8_t obmc32[1024]={
- 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
- 0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
- 0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
- 0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
- 4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
- 4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
- 4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
- 4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
- 4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
- 4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
- 4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
- 4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
- 8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
- 8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
- 8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
- 8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
- 8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
- 8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
- 8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
- 8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
- 4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
- 4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
- 4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
- 4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
- 4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
- 4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
- 4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
- 4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
- 0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
- 0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
- 0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
- 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
- //error:0.000020
-};
-static const uint8_t obmc16[256]={
- 0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
- 4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
- 4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
- 8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
- 8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
- 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
- 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
- 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
- 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
- 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
- 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
- 8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
- 8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
- 4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
- 4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
- 0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
-//error:0.000015
-};
-#else //64*cos
-static const uint8_t obmc32[1024]={
- 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, 0, 0,
- 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 12, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0,
- 0, 0, 4, 4, 4, 8, 8, 12, 16, 20, 20, 24, 28, 28, 28, 28, 28, 28, 28, 28, 24, 20, 20, 16, 12, 8, 8, 4, 4, 4, 0, 0,
- 0, 0, 4, 4, 8, 12, 16, 20, 24, 28, 36, 40, 44, 44, 48, 48, 48, 48, 44, 44, 40, 36, 28, 24, 20, 16, 12, 8, 4, 4, 0, 0,
- 0, 0, 4, 8, 12, 20, 24, 32, 36, 44, 48, 56, 60, 64, 68, 68, 68, 68, 64, 60, 56, 48, 44, 36, 32, 24, 20, 12, 8, 4, 0, 0,
- 0, 4, 4, 8, 16, 24, 32, 40, 48, 60, 68, 76, 80, 84, 88, 92, 92, 88, 84, 80, 76, 68, 60, 48, 40, 32, 24, 16, 8, 4, 4, 0,
- 0, 4, 8, 12, 20, 32, 40, 52, 64, 76, 84, 96,104,108,112,116,116,112,108,104, 96, 84, 76, 64, 52, 40, 32, 20, 12, 8, 4, 0,
- 0, 4, 8, 16, 24, 36, 48, 64, 76, 92,104,116,124,132,136,140,140,136,132,124,116,104, 92, 76, 64, 48, 36, 24, 16, 8, 4, 0,
- 0, 4, 12, 20, 28, 44, 60, 76, 92,104,120,136,148,156,160,164,164,160,156,148,136,120,104, 92, 76, 60, 44, 28, 20, 12, 4, 0,
- 0, 4, 12, 20, 36, 48, 68, 84,104,120,140,152,168,176,184,188,188,184,176,168,152,140,120,104, 84, 68, 48, 36, 20, 12, 4, 0,
- 0, 4, 12, 24, 36, 56, 76, 96,116,136,152,172,184,196,204,208,208,204,196,184,172,152,136,116, 96, 76, 56, 36, 24, 12, 4, 0,
- 0, 4, 12, 24, 44, 60, 80,104,124,148,168,184,200,212,224,228,228,224,212,200,184,168,148,124,104, 80, 60, 44, 24, 12, 4, 0,
- 0, 4, 12, 28, 44, 64, 84,108,132,156,176,196,212,228,236,240,240,236,228,212,196,176,156,132,108, 84, 64, 44, 28, 12, 4, 0,
- 0, 4, 16, 28, 48, 68, 88,112,136,160,184,204,224,236,244,252,252,244,236,224,204,184,160,136,112, 88, 68, 48, 28, 16, 4, 0,
- 1, 4, 16, 28, 48, 68, 92,116,140,164,188,208,228,240,252,255,255,252,240,228,208,188,164,140,116, 92, 68, 48, 28, 16, 4, 1,
- 1, 4, 16, 28, 48, 68, 92,116,140,164,188,208,228,240,252,255,255,252,240,228,208,188,164,140,116, 92, 68, 48, 28, 16, 4, 1,
- 0, 4, 16, 28, 48, 68, 88,112,136,160,184,204,224,236,244,252,252,244,236,224,204,184,160,136,112, 88, 68, 48, 28, 16, 4, 0,
- 0, 4, 12, 28, 44, 64, 84,108,132,156,176,196,212,228,236,240,240,236,228,212,196,176,156,132,108, 84, 64, 44, 28, 12, 4, 0,
- 0, 4, 12, 24, 44, 60, 80,104,124,148,168,184,200,212,224,228,228,224,212,200,184,168,148,124,104, 80, 60, 44, 24, 12, 4, 0,
- 0, 4, 12, 24, 36, 56, 76, 96,116,136,152,172,184,196,204,208,208,204,196,184,172,152,136,116, 96, 76, 56, 36, 24, 12, 4, 0,
- 0, 4, 12, 20, 36, 48, 68, 84,104,120,140,152,168,176,184,188,188,184,176,168,152,140,120,104, 84, 68, 48, 36, 20, 12, 4, 0,
- 0, 4, 12, 20, 28, 44, 60, 76, 92,104,120,136,148,156,160,164,164,160,156,148,136,120,104, 92, 76, 60, 44, 28, 20, 12, 4, 0,
- 0, 4, 8, 16, 24, 36, 48, 64, 76, 92,104,116,124,132,136,140,140,136,132,124,116,104, 92, 76, 64, 48, 36, 24, 16, 8, 4, 0,
- 0, 4, 8, 12, 20, 32, 40, 52, 64, 76, 84, 96,104,108,112,116,116,112,108,104, 96, 84, 76, 64, 52, 40, 32, 20, 12, 8, 4, 0,
- 0, 4, 4, 8, 16, 24, 32, 40, 48, 60, 68, 76, 80, 84, 88, 92, 92, 88, 84, 80, 76, 68, 60, 48, 40, 32, 24, 16, 8, 4, 4, 0,
- 0, 0, 4, 8, 12, 20, 24, 32, 36, 44, 48, 56, 60, 64, 68, 68, 68, 68, 64, 60, 56, 48, 44, 36, 32, 24, 20, 12, 8, 4, 0, 0,
- 0, 0, 4, 4, 8, 12, 16, 20, 24, 28, 36, 40, 44, 44, 48, 48, 48, 48, 44, 44, 40, 36, 28, 24, 20, 16, 12, 8, 4, 4, 0, 0,
- 0, 0, 4, 4, 4, 8, 8, 12, 16, 20, 20, 24, 28, 28, 28, 28, 28, 28, 28, 28, 24, 20, 20, 16, 12, 8, 8, 4, 4, 4, 0, 0,
- 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 12, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0,
-//error:0.000022
-};
-static const uint8_t obmc16[256]={
- 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
- 0, 0, 4, 8, 12, 16, 20, 20, 20, 20, 16, 12, 8, 4, 0, 0,
- 0, 4, 12, 24, 32, 44, 52, 56, 56, 52, 44, 32, 24, 12, 4, 0,
- 0, 8, 24, 40, 60, 80, 96,104,104, 96, 80, 60, 40, 24, 8, 0,
- 0, 12, 32, 64, 92,120,140,152,152,140,120, 92, 64, 32, 12, 0,
- 4, 16, 44, 80,120,156,184,196,196,184,156,120, 80, 44, 16, 4,
- 4, 20, 52, 96,140,184,216,232,232,216,184,140, 96, 52, 20, 4,
- 0, 20, 56,104,152,196,232,252,252,232,196,152,104, 56, 20, 0,
- 0, 20, 56,104,152,196,232,252,252,232,196,152,104, 56, 20, 0,
- 4, 20, 52, 96,140,184,216,232,232,216,184,140, 96, 52, 20, 4,
- 4, 16, 44, 80,120,156,184,196,196,184,156,120, 80, 44, 16, 4,
- 0, 12, 32, 64, 92,120,140,152,152,140,120, 92, 64, 32, 12, 0,
- 0, 8, 24, 40, 60, 80, 96,104,104, 96, 80, 60, 40, 24, 8, 0,
- 0, 4, 12, 24, 32, 44, 52, 56, 56, 52, 44, 32, 24, 12, 4, 0,
- 0, 0, 4, 8, 12, 16, 20, 20, 20, 20, 16, 12, 8, 4, 0, 0,
- 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
-//error:0.000022
-};
-#endif /* 0 */
-
-//linear *64
-static const uint8_t obmc8[64]={
- 4, 12, 20, 28, 28, 20, 12, 4,
- 12, 36, 60, 84, 84, 60, 36, 12,
- 20, 60,100,140,140,100, 60, 20,
- 28, 84,140,196,196,140, 84, 28,
- 28, 84,140,196,196,140, 84, 28,
- 20, 60,100,140,140,100, 60, 20,
- 12, 36, 60, 84, 84, 60, 36, 12,
- 4, 12, 20, 28, 28, 20, 12, 4,
-//error:0.000000
-};
-
-//linear *64
-static const uint8_t obmc4[16]={
- 16, 48, 48, 16,
- 48,144,144, 48,
- 48,144,144, 48,
- 16, 48, 48, 16,
-//error:0.000000
-};
-
-static const uint8_t * const obmc_tab[4]={
- obmc32, obmc16, obmc8, obmc4
-};
-
-static int scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
-
-typedef struct BlockNode{
- int16_t mx;
- int16_t my;
- uint8_t ref;
- uint8_t color[3];
- uint8_t type;
-//#define TYPE_SPLIT 1
-#define BLOCK_INTRA 1
-#define BLOCK_OPT 2
-//#define TYPE_NOCOLOR 4
- uint8_t level; //FIXME merge into type?
-}BlockNode;
-
-static const BlockNode null_block= { //FIXME add border maybe
- .color= {128,128,128},
- .mx= 0,
- .my= 0,
- .ref= 0,
- .type= 0,
- .level= 0,
-};
-
-#define LOG2_MB_SIZE 4
-#define MB_SIZE (1<<LOG2_MB_SIZE)
-#define ENCODER_EXTRA_BITS 4
-#define HTAPS_MAX 8
-
-typedef struct x_and_coeff{
- int16_t x;
- uint16_t coeff;
-} x_and_coeff;
-
-typedef struct SubBand{
- int level;
- int stride;
- int width;
- int height;
- int qlog; ///< log(qscale)/log[2^(1/6)]
- DWTELEM *buf;
- IDWTELEM *ibuf;
- int buf_x_offset;
- int buf_y_offset;
- int stride_line; ///< Stride measured in lines, not pixels.
- x_and_coeff * x_coeff;
- struct SubBand *parent;
- uint8_t state[/*7*2*/ 7 + 512][32];
-}SubBand;
-
-typedef struct Plane{
- int width;
- int height;
- SubBand band[MAX_DECOMPOSITIONS][4];
-
- int htaps;
- int8_t hcoeff[HTAPS_MAX/2];
- int diag_mc;
- int fast_mc;
-
- int last_htaps;
- int8_t last_hcoeff[HTAPS_MAX/2];
- int last_diag_mc;
-}Plane;
-
-typedef struct SnowContext{
-
- AVCodecContext *avctx;
- RangeCoder c;
- DSPContext dsp;
- DWTContext dwt;
- AVFrame new_picture;
- AVFrame input_picture; ///< new_picture with the internal linesizes
- AVFrame current_picture;
- AVFrame last_picture[MAX_REF_FRAMES];
- uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4];
- AVFrame mconly_picture;
-// uint8_t q_context[16];
- uint8_t header_state[32];
- uint8_t block_state[128 + 32*128];
- int keyframe;
- int always_reset;
- int version;
- int spatial_decomposition_type;
- int last_spatial_decomposition_type;
- int temporal_decomposition_type;
- int spatial_decomposition_count;
- int last_spatial_decomposition_count;
- int temporal_decomposition_count;
- int max_ref_frames;
- int ref_frames;
- int16_t (*ref_mvs[MAX_REF_FRAMES])[2];
- uint32_t *ref_scores[MAX_REF_FRAMES];
- DWTELEM *spatial_dwt_buffer;
- IDWTELEM *spatial_idwt_buffer;
- int colorspace_type;
- int chroma_h_shift;
- int chroma_v_shift;
- int spatial_scalability;
- int qlog;
- int last_qlog;
- int lambda;
- int lambda2;
- int pass1_rc;
- int mv_scale;
- int last_mv_scale;
- int qbias;
- int last_qbias;
-#define QBIAS_SHIFT 3
- int b_width;
- int b_height;
- int block_max_depth;
- int last_block_max_depth;
- Plane plane[MAX_PLANES];
- BlockNode *block;
-#define ME_CACHE_SIZE 1024
- int me_cache[ME_CACHE_SIZE];
- int me_cache_generation;
- slice_buffer sb;
-
- MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
-
- uint8_t *scratchbuf;
-}SnowContext;
-
-#ifdef __sgi
-// Avoid a name clash on SGI IRIX
-#undef qexp
-#endif
-#define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0
-static uint8_t qexp[QROOT];
-
-static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
- int i;
-
- if(v){
- const int a= FFABS(v);
- const int e= av_log2(a);
-#if 1
- const int el= FFMIN(e, 10);
- put_rac(c, state+0, 0);
-
- for(i=0; i<el; i++){
- put_rac(c, state+1+i, 1); //1..10
- }
- for(; i<e; i++){
- put_rac(c, state+1+9, 1); //1..10
- }
- put_rac(c, state+1+FFMIN(i,9), 0);
-
- for(i=e-1; i>=el; i--){
- put_rac(c, state+22+9, (a>>i)&1); //22..31
- }
- for(; i>=0; i--){
- put_rac(c, state+22+i, (a>>i)&1); //22..31
- }
-
- if(is_signed)
- put_rac(c, state+11 + el, v < 0); //11..21
-#else
-
- put_rac(c, state+0, 0);
- if(e<=9){
- for(i=0; i<e; i++){
- put_rac(c, state+1+i, 1); //1..10
- }
- put_rac(c, state+1+i, 0);
-
- for(i=e-1; i>=0; i--){
- put_rac(c, state+22+i, (a>>i)&1); //22..31
- }
-
- if(is_signed)
- put_rac(c, state+11 + e, v < 0); //11..21
- }else{
- for(i=0; i<e; i++){
- put_rac(c, state+1+FFMIN(i,9), 1); //1..10
- }
- put_rac(c, state+1+9, 0);
-
- for(i=e-1; i>=0; i--){
- put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31
- }
-
- if(is_signed)
- put_rac(c, state+11 + 10, v < 0); //11..21
- }
-#endif /* 1 */
- }else{
- put_rac(c, state+0, 1);
- }
-}
-
-static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
- if(get_rac(c, state+0))
- return 0;
- else{
- int i, e, a;
- e= 0;
- while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10
- e++;
- }
-
- a= 1;
- for(i=e-1; i>=0; i--){
- a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31
- }
-
- e= -(is_signed && get_rac(c, state+11 + FFMIN(e,10))); //11..21
- return (a^e)-e;
- }
-}
-
-static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){
- int i;
- int r= log2>=0 ? 1<<log2 : 1;
-
- assert(v>=0);
- assert(log2>=-4);
-
- while(v >= r){
- put_rac(c, state+4+log2, 1);
- v -= r;
- log2++;
- if(log2>0) r+=r;
- }
- put_rac(c, state+4+log2, 0);
-
- for(i=log2-1; i>=0; i--){
- put_rac(c, state+31-i, (v>>i)&1);
- }
-}
-
-static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){
- int i;
- int r= log2>=0 ? 1<<log2 : 1;
- int v=0;
-
- assert(log2>=-4);
-
- while(get_rac(c, state+4+log2)){
- v+= r;
- log2++;
- if(log2>0) r+=r;
- }
-
- for(i=log2-1; i>=0; i--){
- v+= get_rac(c, state+31-i)<<i;
- }
-
- return v;
-}
-
-static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, int orientation){
- const int w= b->width;
- const int h= b->height;
- int x,y;
-
- int run, runs;
- x_and_coeff *xc= b->x_coeff;
- x_and_coeff *prev_xc= NULL;
- x_and_coeff *prev2_xc= xc;
- x_and_coeff *parent_xc= parent ? parent->x_coeff : NULL;
- x_and_coeff *prev_parent_xc= parent_xc;
-
- runs= get_symbol2(&s->c, b->state[30], 0);
- if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
- else run= INT_MAX;
-
- for(y=0; y<h; y++){
- int v=0;
- int lt=0, t=0, rt=0;
-
- if(y && prev_xc->x == 0){
- rt= prev_xc->coeff;
- }
- for(x=0; x<w; x++){
- int p=0;
- const int l= v;
-
- lt= t; t= rt;
-
- if(y){
- if(prev_xc->x <= x)
- prev_xc++;
- if(prev_xc->x == x + 1)
- rt= prev_xc->coeff;
- else
- rt=0;
- }
- if(parent_xc){
- if(x>>1 > parent_xc->x){
- parent_xc++;
- }
- if(x>>1 == parent_xc->x){
- p= parent_xc->coeff;
- }
- }
- if(/*ll|*/l|lt|t|rt|p){
- int context= av_log2(/*FFABS(ll) + */3*(l>>1) + (lt>>1) + (t&~1) + (rt>>1) + (p>>1));
- v=get_rac(&s->c, &b->state[0][context]);
- if(v){
- v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1);
- v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3bA[l&0xFF] + 3*quant3bA[t&0xFF]]);
-
- xc->x=x;
- (xc++)->coeff= v;
- }
- }else{
- if(!run){
- if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
- else run= INT_MAX;
- v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1);
- v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]);
-
- xc->x=x;
- (xc++)->coeff= v;
- }else{
- int max_run;
- run--;
- v=0;
+void ff_snow_inner_add_yblock(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){
+ int y, x;
+ IDWTELEM * dst;
+ for(y=0; y<b_h; y++){
+ //FIXME ugly misuse of obmc_stride
+ const uint8_t *obmc1= obmc + y*obmc_stride;
+ const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
+ const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
+ const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
+ dst = slice_buffer_get_line(sb, src_y + y);
+ for(x=0; x<b_w; x++){
+ int v= obmc1[x] * block[3][x + y*src_stride]
+ +obmc2[x] * block[2][x + y*src_stride]
+ +obmc3[x] * block[1][x + y*src_stride]
+ +obmc4[x] * block[0][x + y*src_stride];
- if(y) max_run= FFMIN(run, prev_xc->x - x - 2);
- else max_run= FFMIN(run, w-x-1);
- if(parent_xc)
- max_run= FFMIN(max_run, 2*parent_xc->x - x - 1);
- x+= max_run;
- run-= max_run;
- }
+ v <<= 8 - LOG2_OBMC_MAX;
+ if(FRAC_BITS != 8){
+ v >>= 8 - FRAC_BITS;
}
- }
- (xc++)->x= w+1; //end marker
- prev_xc= prev2_xc;
- prev2_xc= xc;
-
- if(parent_xc){
- if(y&1){
- while(parent_xc->x != parent->width+1)
- parent_xc++;
- parent_xc++;
- prev_parent_xc= parent_xc;
+ if(add){
+ v += dst[x + src_x];
+ v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
+ if(v&(~255)) v= ~(v>>31);
+ dst8[x + y*src_stride] = v;
}else{
- parent_xc= prev_parent_xc;
+ dst[x + src_x] -= v;
}
}
}
-
- (xc++)->x= w+1; //end marker
-}
-
-static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, slice_buffer * sb, int start_y, int h, int save_state[1]){
- const int w= b->width;
- int y;
- const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
- int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
- int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
- int new_index = 0;
-
- if(b->ibuf == s->spatial_idwt_buffer || s->qlog == LOSSLESS_QLOG){
- qadd= 0;
- qmul= 1<<QEXPSHIFT;
- }
-
- /* If we are on the second or later slice, restore our index. */
- if (start_y != 0)
- new_index = save_state[0];
-
-
- for(y=start_y; y<h; y++){
- int x = 0;
- int v;
- IDWTELEM * line = slice_buffer_get_line(sb, y * b->stride_line + b->buf_y_offset) + b->buf_x_offset;
- memset(line, 0, b->width*sizeof(IDWTELEM));
- v = b->x_coeff[new_index].coeff;
- x = b->x_coeff[new_index++].x;
- while(x < w){
- register int t= ( (v>>1)*qmul + qadd)>>QEXPSHIFT;
- register int u= -(v&1);
- line[x] = (t^u) - u;
-
- v = b->x_coeff[new_index].coeff;
- x = b->x_coeff[new_index++].x;
- }
- }
-
- /* Save our variables for the next slice. */
- save_state[0] = new_index;
-
- return;
}
-static void reset_contexts(SnowContext *s){ //FIXME better initial contexts
+void ff_snow_reset_contexts(SnowContext *s){ //FIXME better initial contexts
int plane_index, level, orientation;
for(plane_index=0; plane_index<3; plane_index++){
@@ -777,7 +82,7 @@ static void reset_contexts(SnowContext *s){ //FIXME better initial contexts
memset(s->block_state, MID_STATE, sizeof(s->block_state));
}
-static int alloc_blocks(SnowContext *s){
+int ff_snow_alloc_blocks(SnowContext *s){
int w= -((-s->avctx->width )>>LOG2_MB_SIZE);
int h= -((-s->avctx->height)>>LOG2_MB_SIZE);
@@ -789,137 +94,15 @@ static int alloc_blocks(SnowContext *s){
return 0;
}
-static inline void copy_rac_state(RangeCoder *d, RangeCoder *s){
- uint8_t *bytestream= d->bytestream;
- uint8_t *bytestream_start= d->bytestream_start;
- *d= *s;
- d->bytestream= bytestream;
- d->bytestream_start= bytestream_start;
-}
-
-static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
- const int w= s->b_width << s->block_max_depth;
- const int rem_depth= s->block_max_depth - level;
- const int index= (x + y*w) << rem_depth;
- const int block_w= 1<<rem_depth;
- BlockNode block;
- int i,j;
-
- block.color[0]= l;
- block.color[1]= cb;
- block.color[2]= cr;
- block.mx= mx;
- block.my= my;
- block.ref= ref;
- block.type= type;
- block.level= level;
-
- for(j=0; j<block_w; j++){
- for(i=0; i<block_w; i++){
- s->block[index + i + j*w]= block;
- }
- }
-}
-
-static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){
- const int offset[3]= {
- y*c-> stride + x,
- ((y*c->uvstride + x)>>1),
- ((y*c->uvstride + x)>>1),
- };
+static void init_qexp(void){
int i;
- for(i=0; i<3; i++){
- c->src[0][i]= src [i];
- c->ref[0][i]= ref [i] + offset[i];
- }
- assert(!ref_index);
-}
-
-static inline void pred_mv(SnowContext *s, int *mx, int *my, int ref,
- const BlockNode *left, const BlockNode *top, const BlockNode *tr){
- if(s->ref_frames == 1){
- *mx = mid_pred(left->mx, top->mx, tr->mx);
- *my = mid_pred(left->my, top->my, tr->my);
- }else{
- const int *scale = scale_mv_ref[ref];
- *mx = mid_pred((left->mx * scale[left->ref] + 128) >>8,
- (top ->mx * scale[top ->ref] + 128) >>8,
- (tr ->mx * scale[tr ->ref] + 128) >>8);
- *my = mid_pred((left->my * scale[left->ref] + 128) >>8,
- (top ->my * scale[top ->ref] + 128) >>8,
- (tr ->my * scale[tr ->ref] + 128) >>8);
- }
-}
-
-static av_always_inline int same_block(BlockNode *a, BlockNode *b){
- if((a->type&BLOCK_INTRA) && (b->type&BLOCK_INTRA)){
- return !((a->color[0] - b->color[0]) | (a->color[1] - b->color[1]) | (a->color[2] - b->color[2]));
- }else{
- return !((a->mx - b->mx) | (a->my - b->my) | (a->ref - b->ref) | ((a->type ^ b->type)&BLOCK_INTRA));
- }
-}
-
-static void decode_q_branch(SnowContext *s, int level, int x, int y){
- const int w= s->b_width << s->block_max_depth;
- const int rem_depth= s->block_max_depth - level;
- const int index= (x + y*w) << rem_depth;
- int trx= (x+1)<<rem_depth;
- const BlockNode *left = x ? &s->block[index-1] : &null_block;
- const BlockNode *top = y ? &s->block[index-w] : &null_block;
- const BlockNode *tl = y && x ? &s->block[index-w-1] : left;
- const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
- int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
-
- if(s->keyframe){
- set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA);
- return;
- }
-
- if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){
- int type, mx, my;
- int l = left->color[0];
- int cb= left->color[1];
- int cr= left->color[2];
- int ref = 0;
- int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
- int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx));
- int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my));
-
- type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;
-
- if(type){
- pred_mv(s, &mx, &my, 0, left, top, tr);
- l += get_symbol(&s->c, &s->block_state[32], 1);
- cb+= get_symbol(&s->c, &s->block_state[64], 1);
- cr+= get_symbol(&s->c, &s->block_state[96], 1);
- }else{
- if(s->ref_frames > 1)
- ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);
- pred_mv(s, &mx, &my, ref, left, top, tr);
- mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);
- my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1);
- }
- set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type);
- }else{
- decode_q_branch(s, level+1, 2*x+0, 2*y+0);
- decode_q_branch(s, level+1, 2*x+1, 2*y+0);
- decode_q_branch(s, level+1, 2*x+0, 2*y+1);
- decode_q_branch(s, level+1, 2*x+1, 2*y+1);
- }
-}
-
-static void decode_blocks(SnowContext *s){
- int x, y;
- int w= s->b_width;
- int h= s->b_height;
+ double v=128;
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- decode_q_branch(s, 0, x, y);
- }
+ for(i=0; i<QROOT; i++){
+ qexp[i]= lrintf(v);
+ v *= pow(2, 1.0 / QROOT);
}
}
-
static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int b_w, int b_h, int dx, int dy){
static const uint8_t weight[64]={
8,7,6,5,4,3,2,1,
@@ -1104,26 +287,11 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int
}
}
-#define mca(dx,dy,b_w)\
-static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, int stride, int h){\
- assert(h==b_w);\
- mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, stride, b_w, b_w, dx, dy);\
-}
-
-mca( 0, 0,16)
-mca( 8, 0,16)
-mca( 0, 8,16)
-mca( 8, 8,16)
-mca( 0, 0,8)
-mca( 8, 0,8)
-mca( 0, 8,8)
-mca( 8, 8,8)
-
-static void pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){
+void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){
if(block->type & BLOCK_INTRA){
int x, y;
- const int color = block->color[plane_index];
- const int color4= color*0x01010101;
+ const unsigned color = block->color[plane_index];
+ const unsigned color4 = color*0x01010101;
if(b_w==32){
for(y=0; y < b_h; y++){
*(uint32_t*)&dst[0 + y*stride]= color4;
@@ -1199,497 +367,39 @@ static void pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, i
}
}
-void ff_snow_inner_add_yblock(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){
- int y, x;
- IDWTELEM * dst;
- for(y=0; y<b_h; y++){
- //FIXME ugly misuse of obmc_stride
- const uint8_t *obmc1= obmc + y*obmc_stride;
- const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
- const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
- const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
- dst = slice_buffer_get_line(sb, src_y + y);
- for(x=0; x<b_w; x++){
- int v= obmc1[x] * block[3][x + y*src_stride]
- +obmc2[x] * block[2][x + y*src_stride]
- +obmc3[x] * block[1][x + y*src_stride]
- +obmc4[x] * block[0][x + y*src_stride];
-
- v <<= 8 - LOG2_OBMC_MAX;
- if(FRAC_BITS != 8){
- v >>= 8 - FRAC_BITS;
- }
- if(add){
- v += dst[x + src_x];
- v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
- if(v&(~255)) v= ~(v>>31);
- dst8[x + y*src_stride] = v;
- }else{
- dst[x + src_x] -= v;
- }
- }
- }
+#define mca(dx,dy,b_w)\
+static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, int stride, int h){\
+ assert(h==b_w);\
+ mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, stride, b_w, b_w, dx, dy);\
}
-//FIXME name cleanup (b_w, block_w, b_width stuff)
-static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, IDWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){
- const int b_width = s->b_width << s->block_max_depth;
- const int b_height= s->b_height << s->block_max_depth;
- const int b_stride= b_width;
- BlockNode *lt= &s->block[b_x + b_y*b_stride];
- BlockNode *rt= lt+1;
- BlockNode *lb= lt+b_stride;
- BlockNode *rb= lb+1;
- uint8_t *block[4];
- int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride;
- uint8_t *tmp = s->scratchbuf;
- uint8_t *ptmp;
- int x,y;
-
- if(b_x<0){
- lt= rt;
- lb= rb;
- }else if(b_x + 1 >= b_width){
- rt= lt;
- rb= lb;
- }
- if(b_y<0){
- lt= lb;
- rt= rb;
- }else if(b_y + 1 >= b_height){
- lb= lt;
- rb= rt;
- }
-
- if(src_x<0){ //FIXME merge with prev & always round internal width up to *16
- obmc -= src_x;
- b_w += src_x;
- if(!sliced && !offset_dst)
- dst -= src_x;
- src_x=0;
- }else if(src_x + b_w > w){
- b_w = w - src_x;
- }
- if(src_y<0){
- obmc -= src_y*obmc_stride;
- b_h += src_y;
- if(!sliced && !offset_dst)
- dst -= src_y*dst_stride;
- src_y=0;
- }else if(src_y + b_h> h){
- b_h = h - src_y;
- }
-
- if(b_w<=0 || b_h<=0) return;
-
- assert(src_stride > 2*MB_SIZE + 5);
+mca( 0, 0,16)
+mca( 8, 0,16)
+mca( 0, 8,16)
+mca( 8, 8,16)
+mca( 0, 0,8)
+mca( 8, 0,8)
+mca( 0, 8,8)
+mca( 8, 8,8)
- if(!sliced && offset_dst)
- dst += src_x + src_y*dst_stride;
- dst8+= src_x + src_y*src_stride;
-// src += src_x + src_y*src_stride;
+av_cold int ff_snow_common_init(AVCodecContext *avctx){
+ SnowContext *s = avctx->priv_data;
+ int width, height;
+ int i, j;
- ptmp= tmp + 3*tmp_step;
- block[0]= ptmp;
- ptmp+=tmp_step;
- pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h);
+ s->avctx= avctx;
+ s->max_ref_frames=1; //just make sure its not an invalid value in case of no initial keyframe
- if(same_block(lt, rt)){
- block[1]= block[0];
- }else{
- block[1]= ptmp;
- ptmp+=tmp_step;
- pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h);
- }
+ dsputil_init(&s->dsp, avctx);
+ ff_dwt_init(&s->dwt);
- if(same_block(lt, lb)){
- block[2]= block[0];
- }else if(same_block(rt, lb)){
- block[2]= block[1];
- }else{
- block[2]= ptmp;
- ptmp+=tmp_step;
- pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h);
- }
-
- if(same_block(lt, rb) ){
- block[3]= block[0];
- }else if(same_block(rt, rb)){
- block[3]= block[1];
- }else if(same_block(lb, rb)){
- block[3]= block[2];
- }else{
- block[3]= ptmp;
- pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h);
- }
-#if 0
- for(y=0; y<b_h; y++){
- for(x=0; x<b_w; x++){
- int v= obmc [x + y*obmc_stride] * block[3][x + y*src_stride] * (256/OBMC_MAX);
- if(add) dst[x + y*dst_stride] += v;
- else dst[x + y*dst_stride] -= v;
- }
- }
- for(y=0; y<b_h; y++){
- uint8_t *obmc2= obmc + (obmc_stride>>1);
- for(x=0; x<b_w; x++){
- int v= obmc2[x + y*obmc_stride] * block[2][x + y*src_stride] * (256/OBMC_MAX);
- if(add) dst[x + y*dst_stride] += v;
- else dst[x + y*dst_stride] -= v;
- }
- }
- for(y=0; y<b_h; y++){
- uint8_t *obmc3= obmc + obmc_stride*(obmc_stride>>1);
- for(x=0; x<b_w; x++){
- int v= obmc3[x + y*obmc_stride] * block[1][x + y*src_stride] * (256/OBMC_MAX);
- if(add) dst[x + y*dst_stride] += v;
- else dst[x + y*dst_stride] -= v;
- }
- }
- for(y=0; y<b_h; y++){
- uint8_t *obmc3= obmc + obmc_stride*(obmc_stride>>1);
- uint8_t *obmc4= obmc3+ (obmc_stride>>1);
- for(x=0; x<b_w; x++){
- int v= obmc4[x + y*obmc_stride] * block[0][x + y*src_stride] * (256/OBMC_MAX);
- if(add) dst[x + y*dst_stride] += v;
- else dst[x + y*dst_stride] -= v;
- }
- }
-#else
- if(sliced){
- s->dwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
- }else{
- for(y=0; y<b_h; y++){
- //FIXME ugly misuse of obmc_stride
- const uint8_t *obmc1= obmc + y*obmc_stride;
- const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
- const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
- const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
- for(x=0; x<b_w; x++){
- int v= obmc1[x] * block[3][x + y*src_stride]
- +obmc2[x] * block[2][x + y*src_stride]
- +obmc3[x] * block[1][x + y*src_stride]
- +obmc4[x] * block[0][x + y*src_stride];
-
- v <<= 8 - LOG2_OBMC_MAX;
- if(FRAC_BITS != 8){
- v >>= 8 - FRAC_BITS;
- }
- if(add){
- v += dst[x + y*dst_stride];
- v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
- if(v&(~255)) v= ~(v>>31);
- dst8[x + y*src_stride] = v;
- }else{
- dst[x + y*dst_stride] -= v;
- }
- }
- }
- }
-#endif /* 0 */
-}
-
-static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){
- Plane *p= &s->plane[plane_index];
- const int mb_w= s->b_width << s->block_max_depth;
- const int mb_h= s->b_height << s->block_max_depth;
- int x, y, mb_x;
- int block_size = MB_SIZE >> s->block_max_depth;
- int block_w = plane_index ? block_size/2 : block_size;
- const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
- int obmc_stride= plane_index ? block_size : 2*block_size;
- int ref_stride= s->current_picture.linesize[plane_index];
- uint8_t *dst8= s->current_picture.data[plane_index];
- int w= p->width;
- int h= p->height;
-
- if(s->keyframe || (s->avctx->debug&512)){
- if(mb_y==mb_h)
- return;
-
- if(add){
- for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
-// DWTELEM * line = slice_buffer_get_line(sb, y);
- IDWTELEM * line = sb->line[y];
- for(x=0; x<w; x++){
-// int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
- int v= line[x] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
- v >>= FRAC_BITS;
- if(v&(~255)) v= ~(v>>31);
- dst8[x + y*ref_stride]= v;
- }
- }
- }else{
- for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
-// DWTELEM * line = slice_buffer_get_line(sb, y);
- IDWTELEM * line = sb->line[y];
- for(x=0; x<w; x++){
- line[x] -= 128 << FRAC_BITS;
-// buf[x + y*w]-= 128<<FRAC_BITS;
- }
- }
- }
-
- return;
- }
-
- for(mb_x=0; mb_x<=mb_w; mb_x++){
- add_yblock(s, 1, sb, old_buffer, dst8, obmc,
- block_w*mb_x - block_w/2,
- block_w*mb_y - block_w/2,
- block_w, block_w,
- w, h,
- w, ref_stride, obmc_stride,
- mb_x - 1, mb_y - 1,
- add, 0, plane_index);
- }
-}
-
-static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int plane_index, int add, int mb_y){
- Plane *p= &s->plane[plane_index];
- const int mb_w= s->b_width << s->block_max_depth;
- const int mb_h= s->b_height << s->block_max_depth;
- int x, y, mb_x;
- int block_size = MB_SIZE >> s->block_max_depth;
- int block_w = plane_index ? block_size/2 : block_size;
- const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
- const int obmc_stride= plane_index ? block_size : 2*block_size;
- int ref_stride= s->current_picture.linesize[plane_index];
- uint8_t *dst8= s->current_picture.data[plane_index];
- int w= p->width;
- int h= p->height;
-
- if(s->keyframe || (s->avctx->debug&512)){
- if(mb_y==mb_h)
- return;
-
- if(add){
- for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
- for(x=0; x<w; x++){
- int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
- v >>= FRAC_BITS;
- if(v&(~255)) v= ~(v>>31);
- dst8[x + y*ref_stride]= v;
- }
- }
- }else{
- for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
- for(x=0; x<w; x++){
- buf[x + y*w]-= 128<<FRAC_BITS;
- }
- }
- }
-
- return;
- }
-
- for(mb_x=0; mb_x<=mb_w; mb_x++){
- add_yblock(s, 0, NULL, buf, dst8, obmc,
- block_w*mb_x - block_w/2,
- block_w*mb_y - block_w/2,
- block_w, block_w,
- w, h,
- w, ref_stride, obmc_stride,
- mb_x - 1, mb_y - 1,
- add, 1, plane_index);
- }
-}
-
-static av_always_inline void predict_plane(SnowContext *s, IDWTELEM *buf, int plane_index, int add){
- const int mb_h= s->b_height << s->block_max_depth;
- int mb_y;
- for(mb_y=0; mb_y<=mb_h; mb_y++)
- predict_slice(s, buf, plane_index, add, mb_y);
-}
-
-static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int start_y, int end_y){
- const int w= b->width;
- const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
- const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
- const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
- int x,y;
-
- if(s->qlog == LOSSLESS_QLOG) return;
-
- for(y=start_y; y<end_y; y++){
-// DWTELEM * line = slice_buffer_get_line_from_address(sb, src + (y * stride));
- IDWTELEM * line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
- for(x=0; x<w; x++){
- int i= line[x];
- if(i<0){
- line[x]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
- }else if(i>0){
- line[x]= (( i*qmul + qadd)>>(QEXPSHIFT));
- }
- }
- }
-}
-
-static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){
- const int w= b->width;
- int x,y;
-
- IDWTELEM * line=0; // silence silly "could be used without having been initialized" warning
- IDWTELEM * prev;
-
- if (start_y != 0)
- line = slice_buffer_get_line(sb, ((start_y - 1) * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
-
- for(y=start_y; y<end_y; y++){
- prev = line;
-// line = slice_buffer_get_line_from_address(sb, src + (y * stride));
- line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
- for(x=0; x<w; x++){
- if(x){
- if(use_median){
- if(y && x+1<w) line[x] += mid_pred(line[x - 1], prev[x], prev[x + 1]);
- else line[x] += line[x - 1];
- }else{
- if(y) line[x] += mid_pred(line[x - 1], prev[x], line[x - 1] + prev[x] - prev[x - 1]);
- else line[x] += line[x - 1];
- }
- }else{
- if(y) line[x] += prev[x];
- }
- }
- }
-}
-
-static void decode_qlogs(SnowContext *s){
- int plane_index, level, orientation;
-
- for(plane_index=0; plane_index<3; plane_index++){
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1:0; orientation<4; orientation++){
- int q;
- if (plane_index==2) q= s->plane[1].band[level][orientation].qlog;
- else if(orientation==2) q= s->plane[plane_index].band[level][1].qlog;
- else q= get_symbol(&s->c, s->header_state, 1);
- s->plane[plane_index].band[level][orientation].qlog= q;
- }
- }
- }
-}
-
-#define GET_S(dst, check) \
- tmp= get_symbol(&s->c, s->header_state, 0);\
- if(!(check)){\
- av_log(s->avctx, AV_LOG_ERROR, "Error " #dst " is %d\n", tmp);\
- return -1;\
- }\
- dst= tmp;
-
-static int decode_header(SnowContext *s){
- int plane_index, tmp;
- uint8_t kstate[32];
-
- memset(kstate, MID_STATE, sizeof(kstate));
-
- s->keyframe= get_rac(&s->c, kstate);
- if(s->keyframe || s->always_reset){
- reset_contexts(s);
- s->spatial_decomposition_type=
- s->qlog=
- s->qbias=
- s->mv_scale=
- s->block_max_depth= 0;
- }
- if(s->keyframe){
- GET_S(s->version, tmp <= 0U)
- s->always_reset= get_rac(&s->c, s->header_state);
- s->temporal_decomposition_type= get_symbol(&s->c, s->header_state, 0);
- s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0);
- GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
- s->colorspace_type= get_symbol(&s->c, s->header_state, 0);
- s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0);
- s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0);
- s->spatial_scalability= get_rac(&s->c, s->header_state);
-// s->rate_scalability= get_rac(&s->c, s->header_state);
- GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES)
- s->max_ref_frames++;
-
- decode_qlogs(s);
- }
-
- if(!s->keyframe){
- if(get_rac(&s->c, s->header_state)){
- for(plane_index=0; plane_index<2; plane_index++){
- int htaps, i, sum=0;
- Plane *p= &s->plane[plane_index];
- p->diag_mc= get_rac(&s->c, s->header_state);
- htaps= get_symbol(&s->c, s->header_state, 0)*2 + 2;
- if((unsigned)htaps > HTAPS_MAX || htaps==0)
- return -1;
- p->htaps= htaps;
- for(i= htaps/2; i; i--){
- p->hcoeff[i]= get_symbol(&s->c, s->header_state, 0) * (1-2*(i&1));
- sum += p->hcoeff[i];
- }
- p->hcoeff[0]= 32-sum;
- }
- s->plane[2].diag_mc= s->plane[1].diag_mc;
- s->plane[2].htaps = s->plane[1].htaps;
- memcpy(s->plane[2].hcoeff, s->plane[1].hcoeff, sizeof(s->plane[1].hcoeff));
- }
- if(get_rac(&s->c, s->header_state)){
- GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
- decode_qlogs(s);
- }
- }
-
- s->spatial_decomposition_type+= get_symbol(&s->c, s->header_state, 1);
- if(s->spatial_decomposition_type > 1U){
- av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported", s->spatial_decomposition_type);
- return -1;
- }
- if(FFMIN(s->avctx-> width>>s->chroma_h_shift,
- s->avctx->height>>s->chroma_v_shift) >> (s->spatial_decomposition_count-1) <= 0){
- av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_count %d too large for size", s->spatial_decomposition_count);
- return -1;
- }
-
- s->qlog += get_symbol(&s->c, s->header_state, 1);
- s->mv_scale += get_symbol(&s->c, s->header_state, 1);
- s->qbias += get_symbol(&s->c, s->header_state, 1);
- s->block_max_depth+= get_symbol(&s->c, s->header_state, 1);
- if(s->block_max_depth > 1 || s->block_max_depth < 0){
- av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large", s->block_max_depth);
- s->block_max_depth= 0;
- return -1;
- }
-
- return 0;
-}
-
-static void init_qexp(void){
- int i;
- double v=128;
-
- for(i=0; i<QROOT; i++){
- qexp[i]= lrintf(v);
- v *= pow(2, 1.0 / QROOT);
- }
-}
-
-static av_cold int common_init(AVCodecContext *avctx){
- SnowContext *s = avctx->priv_data;
- int width, height;
- int i, j;
-
- s->avctx= avctx;
- s->max_ref_frames=1; //just make sure its not an invalid value in case of no initial keyframe
-
- dsputil_init(&s->dsp, avctx);
- ff_dwt_init(&s->dwt);
-
-#define mcf(dx,dy)\
- s->dsp.put_qpel_pixels_tab [0][dy+dx/4]=\
- s->dsp.put_no_rnd_qpel_pixels_tab[0][dy+dx/4]=\
- s->dsp.put_h264_qpel_pixels_tab[0][dy+dx/4];\
- s->dsp.put_qpel_pixels_tab [1][dy+dx/4]=\
- s->dsp.put_no_rnd_qpel_pixels_tab[1][dy+dx/4]=\
- s->dsp.put_h264_qpel_pixels_tab[1][dy+dx/4];
+#define mcf(dx,dy)\
+ s->dsp.put_qpel_pixels_tab [0][dy+dx/4]=\
+ s->dsp.put_no_rnd_qpel_pixels_tab[0][dy+dx/4]=\
+ s->dsp.put_h264_qpel_pixels_tab[0][dy+dx/4];\
+ s->dsp.put_qpel_pixels_tab [1][dy+dx/4]=\
+ s->dsp.put_no_rnd_qpel_pixels_tab[1][dy+dx/4]=\
+ s->dsp.put_h264_qpel_pixels_tab[1][dy+dx/4];
mcf( 0, 0)
mcf( 4, 0)
@@ -1721,8 +431,7 @@ static av_cold int common_init(AVCodecContext *avctx){
mcfh(0, 8)
mcfh(8, 8)
- if(!qexp[0])
- init_qexp();
+ init_qexp();
// dec += FFMAX(s->chroma_h_shift, s->chroma_v_shift);
@@ -1742,7 +451,7 @@ static av_cold int common_init(AVCodecContext *avctx){
return 0;
}
-static int common_init_after_header(AVCodecContext *avctx){
+int ff_snow_common_init_after_header(AVCodecContext *avctx) {
SnowContext *s = avctx->priv_data;
int plane_index, level, orientation;
@@ -1795,130 +504,11 @@ static int common_init_after_header(AVCodecContext *avctx){
return 0;
}
-#define QUANTIZE2 0
-
-#if QUANTIZE2==1
-#define Q2_STEP 8
-
-static void find_sse(SnowContext *s, Plane *p, int *score, int score_stride, IDWTELEM *r0, IDWTELEM *r1, int level, int orientation){
- SubBand *b= &p->band[level][orientation];
- int x, y;
- int xo=0;
- int yo=0;
- int step= 1 << (s->spatial_decomposition_count - level);
-
- if(orientation&1)
- xo= step>>1;
- if(orientation&2)
- yo= step>>1;
-
- //FIXME bias for nonzero ?
- //FIXME optimize
- memset(score, 0, sizeof(*score)*score_stride*((p->height + Q2_STEP-1)/Q2_STEP));
- for(y=0; y<p->height; y++){
- for(x=0; x<p->width; x++){
- int sx= (x-xo + step/2) / step / Q2_STEP;
- int sy= (y-yo + step/2) / step / Q2_STEP;
- int v= r0[x + y*p->width] - r1[x + y*p->width];
- assert(sx>=0 && sy>=0 && sx < score_stride);
- v= ((v+8)>>4)<<4;
- score[sx + sy*score_stride] += v*v;
- assert(score[sx + sy*score_stride] >= 0);
- }
- }
-}
-
-static void dequantize_all(SnowContext *s, Plane *p, IDWTELEM *buffer, int width, int height){
- int level, orientation;
-
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &p->band[level][orientation];
- IDWTELEM *dst= buffer + (b->ibuf - s->spatial_idwt_buffer);
-
- dequantize(s, b, dst, b->stride);
- }
- }
-}
-
-static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, int height, int stride, int type){
- int level, orientation, ys, xs, x, y, pass;
- IDWTELEM best_dequant[height * stride];
- IDWTELEM idwt2_buffer[height * stride];
- const int score_stride= (width + 10)/Q2_STEP;
- int best_score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size
- int score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size
- int threshold= (s->m.lambda * s->m.lambda) >> 6;
-
- //FIXME pass the copy cleanly ?
-
-// memcpy(dwt_buffer, buffer, height * stride * sizeof(DWTELEM));
- ff_spatial_dwt(buffer, width, height, stride, type, s->spatial_decomposition_count);
-
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &p->band[level][orientation];
- IDWTELEM *dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer);
- DWTELEM *src= buffer + (b-> buf - s->spatial_dwt_buffer);
- assert(src == b->buf); // code does not depend on this but it is true currently
-
- quantize(s, b, dst, src, b->stride, s->qbias);
- }
- }
- for(pass=0; pass<1; pass++){
- if(s->qbias == 0) //keyframe
- continue;
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &p->band[level][orientation];
- IDWTELEM *dst= idwt2_buffer + (b->ibuf - s->spatial_idwt_buffer);
- IDWTELEM *best_dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer);
-
- for(ys= 0; ys<Q2_STEP; ys++){
- for(xs= 0; xs<Q2_STEP; xs++){
- memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM));
- dequantize_all(s, p, idwt2_buffer, width, height);
- ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count);
- find_sse(s, p, best_score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation);
- memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM));
- for(y=ys; y<b->height; y+= Q2_STEP){
- for(x=xs; x<b->width; x+= Q2_STEP){
- if(dst[x + y*b->stride]<0) dst[x + y*b->stride]++;
- if(dst[x + y*b->stride]>0) dst[x + y*b->stride]--;
- //FIXME try more than just --
- }
- }
- dequantize_all(s, p, idwt2_buffer, width, height);
- ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count);
- find_sse(s, p, score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation);
- for(y=ys; y<b->height; y+= Q2_STEP){
- for(x=xs; x<b->width; x+= Q2_STEP){
- int score_idx= x/Q2_STEP + (y/Q2_STEP)*score_stride;
- if(score[score_idx] <= best_score[score_idx] + threshold){
- best_score[score_idx]= score[score_idx];
- if(best_dst[x + y*b->stride]<0) best_dst[x + y*b->stride]++;
- if(best_dst[x + y*b->stride]>0) best_dst[x + y*b->stride]--;
- //FIXME copy instead
- }
- }
- }
- }
- }
- }
- }
- }
- memcpy(s->spatial_idwt_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); //FIXME work with that directly instead of copy at the end
-}
-
-#endif /* QUANTIZE2==1 */
-
#define USE_HALFPEL_PLANE 0
static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){
int p,x,y;
- assert(!(s->avctx->flags & CODEC_FLAG_EMU_EDGE));
-
for(p=0; p<3; p++){
int is_chroma= !!p;
int w= s->avctx->width >>is_chroma;
@@ -1958,7 +548,8 @@ static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *fr
}
}
-static void release_buffer(AVCodecContext *avctx){
+void ff_snow_release_buffer(AVCodecContext *avctx)
+{
SnowContext *s = avctx->priv_data;
int i;
@@ -1970,12 +561,12 @@ static void release_buffer(AVCodecContext *avctx){
}
}
-static int frame_start(SnowContext *s){
+int ff_snow_frame_start(SnowContext *s){
AVFrame tmp;
int w= s->avctx->width; //FIXME round up to x16 ?
int h= s->avctx->height;
- if(s->current_picture.data[0]){
+ if (s->current_picture.data[0] && !(s->avctx->flags&CODEC_FLAG_EMU_EDGE)) {
s->dsp.draw_edges(s->current_picture.data[0],
s->current_picture.linesize[0], w , h ,
EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM);
@@ -1987,7 +578,7 @@ static int frame_start(SnowContext *s){
EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
}
- release_buffer(s->avctx);
+ ff_snow_release_buffer(s->avctx);
tmp= s->last_picture[s->max_ref_frames-1];
memmove(s->last_picture+1, s->last_picture, (s->max_ref_frames-1)*sizeof(AVFrame));
@@ -2022,7 +613,8 @@ static int frame_start(SnowContext *s){
return 0;
}
-static av_cold void common_end(SnowContext *s){
+av_cold void ff_snow_common_end(SnowContext *s)
+{
int plane_index, level, orientation, i;
av_freep(&s->spatial_dwt_buffer);
@@ -2059,2095 +651,3 @@ static av_cold void common_end(SnowContext *s){
s->avctx->release_buffer(s->avctx, &s->current_picture);
}
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- avctx->pix_fmt= PIX_FMT_YUV420P;
-
- common_init(avctx);
-
- return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt){
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- SnowContext *s = avctx->priv_data;
- RangeCoder * const c= &s->c;
- int bytes_read;
- AVFrame *picture = data;
- int level, orientation, plane_index;
-
- ff_init_range_decoder(c, buf, buf_size);
- ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
-
- s->current_picture.pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P
- if(decode_header(s)<0)
- return -1;
- common_init_after_header(avctx);
-
- // realloc slice buffer for the case that spatial_decomposition_count changed
- ff_slice_buffer_destroy(&s->sb);
- ff_slice_buffer_init(&s->sb, s->plane[0].height, (MB_SIZE >> s->block_max_depth) + s->spatial_decomposition_count * 8 + 1, s->plane[0].width, s->spatial_idwt_buffer);
-
- for(plane_index=0; plane_index<3; plane_index++){
- Plane *p= &s->plane[plane_index];
- p->fast_mc= p->diag_mc && p->htaps==6 && p->hcoeff[0]==40
- && p->hcoeff[1]==-10
- && p->hcoeff[2]==2;
- }
-
- alloc_blocks(s);
-
- if(frame_start(s) < 0)
- return -1;
- //keyframe flag duplication mess FIXME
- if(avctx->debug&FF_DEBUG_PICT_INFO)
- av_log(avctx, AV_LOG_ERROR, "keyframe:%d qlog:%d\n", s->keyframe, s->qlog);
-
- decode_blocks(s);
-
- for(plane_index=0; plane_index<3; plane_index++){
- Plane *p= &s->plane[plane_index];
- int w= p->width;
- int h= p->height;
- int x, y;
- int decode_state[MAX_DECOMPOSITIONS][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */
-
- if(s->avctx->debug&2048){
- memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h);
- predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
-
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- int v= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x];
- s->mconly_picture.data[plane_index][y*s->mconly_picture.linesize[plane_index] + x]= v;
- }
- }
- }
-
- {
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &p->band[level][orientation];
- unpack_coeffs(s, b, b->parent, orientation);
- }
- }
- }
-
- {
- const int mb_h= s->b_height << s->block_max_depth;
- const int block_size = MB_SIZE >> s->block_max_depth;
- const int block_w = plane_index ? block_size/2 : block_size;
- int mb_y;
- DWTCompose cs[MAX_DECOMPOSITIONS];
- int yd=0, yq=0;
- int y;
- int end_y;
-
- ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count);
- for(mb_y=0; mb_y<=mb_h; mb_y++){
-
- int slice_starty = block_w*mb_y;
- int slice_h = block_w*(mb_y+1);
- if (!(s->keyframe || s->avctx->debug&512)){
- slice_starty = FFMAX(0, slice_starty - (block_w >> 1));
- slice_h -= (block_w >> 1);
- }
-
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &p->band[level][orientation];
- int start_y;
- int end_y;
- int our_mb_start = mb_y;
- int our_mb_end = (mb_y + 1);
- const int extra= 3;
- start_y = (mb_y ? ((block_w * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0);
- end_y = (((block_w * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra);
- if (!(s->keyframe || s->avctx->debug&512)){
- start_y = FFMAX(0, start_y - (block_w >> (1+s->spatial_decomposition_count - level)));
- end_y = FFMAX(0, end_y - (block_w >> (1+s->spatial_decomposition_count - level)));
- }
- start_y = FFMIN(b->height, start_y);
- end_y = FFMIN(b->height, end_y);
-
- if (start_y != end_y){
- if (orientation == 0){
- SubBand * correlate_band = &p->band[0][0];
- int correlate_end_y = FFMIN(b->height, end_y + 1);
- int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0));
- decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]);
- correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y);
- dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, start_y, end_y);
- }
- else
- decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]);
- }
- }
- }
-
- for(; yd<slice_h; yd+=4){
- ff_spatial_idwt_buffered_slice(&s->dwt, cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd);
- }
-
- if(s->qlog == LOSSLESS_QLOG){
- for(; yq<slice_h && yq<h; yq++){
- IDWTELEM * line = slice_buffer_get_line(&s->sb, yq);
- for(x=0; x<w; x++){
- line[x] <<= FRAC_BITS;
- }
- }
- }
-
- predict_slice_buffered(s, &s->sb, s->spatial_idwt_buffer, plane_index, 1, mb_y);
-
- y = FFMIN(p->height, slice_starty);
- end_y = FFMIN(p->height, slice_h);
- while(y < end_y)
- ff_slice_buffer_release(&s->sb, y++);
- }
-
- ff_slice_buffer_flush(&s->sb);
- }
-
- }
-
- emms_c();
-
- release_buffer(avctx);
-
- if(!(s->avctx->debug&2048))
- *picture= s->current_picture;
- else
- *picture= s->mconly_picture;
-
- *data_size = sizeof(AVFrame);
-
- bytes_read= c->bytestream - c->bytestream_start;
- if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n"); //FIXME
-
- return bytes_read;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- SnowContext *s = avctx->priv_data;
-
- ff_slice_buffer_destroy(&s->sb);
-
- common_end(s);
-
- return 0;
-}
-
-AVCodec ff_snow_decoder = {
- "snow",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SNOW,
- sizeof(SnowContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
- NULL,
- .long_name = NULL_IF_CONFIG_SMALL("Snow"),
-};
-
-#if CONFIG_SNOW_ENCODER
-static av_cold int encode_init(AVCodecContext *avctx)
-{
- SnowContext *s = avctx->priv_data;
- int plane_index;
-
- if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
- av_log(avctx, AV_LOG_ERROR, "This codec is under development, files encoded with it may not be decodable with future versions!!!\n"
- "Use vstrict=-2 / -strict -2 to use it anyway.\n");
- return -1;
- }
-
- if(avctx->prediction_method == DWT_97
- && (avctx->flags & CODEC_FLAG_QSCALE)
- && avctx->global_quality == 0){
- av_log(avctx, AV_LOG_ERROR, "The 9/7 wavelet is incompatible with lossless mode.\n");
- return -1;
- }
-
- s->spatial_decomposition_type= avctx->prediction_method; //FIXME add decorrelator type r transform_type
-
- s->mv_scale = (avctx->flags & CODEC_FLAG_QPEL) ? 2 : 4;
- s->block_max_depth= (avctx->flags & CODEC_FLAG_4MV ) ? 1 : 0;
-
- for(plane_index=0; plane_index<3; plane_index++){
- s->plane[plane_index].diag_mc= 1;
- s->plane[plane_index].htaps= 6;
- s->plane[plane_index].hcoeff[0]= 40;
- s->plane[plane_index].hcoeff[1]= -10;
- s->plane[plane_index].hcoeff[2]= 2;
- s->plane[plane_index].fast_mc= 1;
- }
-
- common_init(avctx);
- alloc_blocks(s);
-
- s->version=0;
-
- s->m.avctx = avctx;
- s->m.flags = avctx->flags;
- s->m.bit_rate= avctx->bit_rate;
-
- s->m.me.temp =
- s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t));
- s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
- s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
- s->m.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t));
- h263_encode_init(&s->m); //mv_penalty
-
- s->max_ref_frames = FFMAX(FFMIN(avctx->refs, MAX_REF_FRAMES), 1);
-
- if(avctx->flags&CODEC_FLAG_PASS1){
- if(!avctx->stats_out)
- avctx->stats_out = av_mallocz(256);
- }
- if((avctx->flags&CODEC_FLAG_PASS2) || !(avctx->flags&CODEC_FLAG_QSCALE)){
- if(ff_rate_control_init(&s->m) < 0)
- return -1;
- }
- s->pass1_rc= !(avctx->flags & (CODEC_FLAG_QSCALE|CODEC_FLAG_PASS2));
-
- avctx->coded_frame= &s->current_picture;
- switch(avctx->pix_fmt){
-// case PIX_FMT_YUV444P:
-// case PIX_FMT_YUV422P:
- case PIX_FMT_YUV420P:
- case PIX_FMT_GRAY8:
-// case PIX_FMT_YUV411P:
-// case PIX_FMT_YUV410P:
- s->colorspace_type= 0;
- break;
-/* case PIX_FMT_RGB32:
- s->colorspace= 1;
- break;*/
- default:
- av_log(avctx, AV_LOG_ERROR, "pixel format not supported\n");
- return -1;
- }
-// avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
- s->chroma_h_shift= 1;
- s->chroma_v_shift= 1;
-
- ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp);
- ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp);
-
- s->avctx->get_buffer(s->avctx, &s->input_picture);
-
- if(s->avctx->me_method == ME_ITER){
- int i;
- int size= s->b_width * s->b_height << 2*s->block_max_depth;
- for(i=0; i<s->max_ref_frames; i++){
- s->ref_mvs[i]= av_mallocz(size*sizeof(int16_t[2]));
- s->ref_scores[i]= av_mallocz(size*sizeof(uint32_t));
- }
- }
-
- return 0;
-}
-
-//near copy & paste from dsputil, FIXME
-static int pix_sum(uint8_t * pix, int line_size, int w)
-{
- int s, i, j;
-
- s = 0;
- for (i = 0; i < w; i++) {
- for (j = 0; j < w; j++) {
- s += pix[0];
- pix ++;
- }
- pix += line_size - w;
- }
- return s;
-}
-
-//near copy & paste from dsputil, FIXME
-static int pix_norm1(uint8_t * pix, int line_size, int w)
-{
- int s, i, j;
- uint32_t *sq = ff_squareTbl + 256;
-
- s = 0;
- for (i = 0; i < w; i++) {
- for (j = 0; j < w; j ++) {
- s += sq[pix[0]];
- pix ++;
- }
- pix += line_size - w;
- }
- return s;
-}
-
-//FIXME copy&paste
-#define P_LEFT P[1]
-#define P_TOP P[2]
-#define P_TOPRIGHT P[3]
-#define P_MEDIAN P[4]
-#define P_MV1 P[9]
-#define FLAG_QPEL 1 //must be 1
-
-static int encode_q_branch(SnowContext *s, int level, int x, int y){
- uint8_t p_buffer[1024];
- uint8_t i_buffer[1024];
- uint8_t p_state[sizeof(s->block_state)];
- uint8_t i_state[sizeof(s->block_state)];
- RangeCoder pc, ic;
- uint8_t *pbbak= s->c.bytestream;
- uint8_t *pbbak_start= s->c.bytestream_start;
- int score, score2, iscore, i_len, p_len, block_s, sum, base_bits;
- const int w= s->b_width << s->block_max_depth;
- const int h= s->b_height << s->block_max_depth;
- const int rem_depth= s->block_max_depth - level;
- const int index= (x + y*w) << rem_depth;
- const int block_w= 1<<(LOG2_MB_SIZE - level);
- int trx= (x+1)<<rem_depth;
- int try= (y+1)<<rem_depth;
- const BlockNode *left = x ? &s->block[index-1] : &null_block;
- const BlockNode *top = y ? &s->block[index-w] : &null_block;
- const BlockNode *right = trx<w ? &s->block[index+1] : &null_block;
- const BlockNode *bottom= try<h ? &s->block[index+w] : &null_block;
- const BlockNode *tl = y && x ? &s->block[index-w-1] : left;
- const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
- int pl = left->color[0];
- int pcb= left->color[1];
- int pcr= left->color[2];
- int pmx, pmy;
- int mx=0, my=0;
- int l,cr,cb;
- const int stride= s->current_picture.linesize[0];
- const int uvstride= s->current_picture.linesize[1];
- uint8_t *current_data[3]= { s->input_picture.data[0] + (x + y* stride)*block_w,
- s->input_picture.data[1] + (x + y*uvstride)*block_w/2,
- s->input_picture.data[2] + (x + y*uvstride)*block_w/2};
- int P[10][2];
- int16_t last_mv[3][2];
- int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused
- const int shift= 1+qpel;
- MotionEstContext *c= &s->m.me;
- int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
- int mx_context= av_log2(2*FFABS(left->mx - top->mx));
- int my_context= av_log2(2*FFABS(left->my - top->my));
- int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
- int ref, best_ref, ref_score, ref_mx, ref_my;
-
- assert(sizeof(s->block_state) >= 256);
- if(s->keyframe){
- set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
- return 0;
- }
-
-// clip predictors / edge ?
-
- P_LEFT[0]= left->mx;
- P_LEFT[1]= left->my;
- P_TOP [0]= top->mx;
- P_TOP [1]= top->my;
- P_TOPRIGHT[0]= tr->mx;
- P_TOPRIGHT[1]= tr->my;
-
- last_mv[0][0]= s->block[index].mx;
- last_mv[0][1]= s->block[index].my;
- last_mv[1][0]= right->mx;
- last_mv[1][1]= right->my;
- last_mv[2][0]= bottom->mx;
- last_mv[2][1]= bottom->my;
-
- s->m.mb_stride=2;
- s->m.mb_x=
- s->m.mb_y= 0;
- c->skip= 0;
-
- assert(c-> stride == stride);
- assert(c->uvstride == uvstride);
-
- c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
- c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
- c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
- c->current_mv_penalty= c->mv_penalty[s->m.f_code=1] + MAX_MV;
-
- c->xmin = - x*block_w - 16+3;
- c->ymin = - y*block_w - 16+3;
- c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3;
- c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3;
-
- if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift);
- if(P_LEFT[1] > (c->ymax<<shift)) P_LEFT[1] = (c->ymax<<shift);
- if(P_TOP[0] > (c->xmax<<shift)) P_TOP[0] = (c->xmax<<shift);
- if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1] = (c->ymax<<shift);
- if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
- if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift); //due to pmx no clip
- if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
-
- P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
- P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
-
- if (!y) {
- c->pred_x= P_LEFT[0];
- c->pred_y= P_LEFT[1];
- } else {
- c->pred_x = P_MEDIAN[0];
- c->pred_y = P_MEDIAN[1];
- }
-
- score= INT_MAX;
- best_ref= 0;
- for(ref=0; ref<s->ref_frames; ref++){
- init_ref(c, current_data, s->last_picture[ref].data, NULL, block_w*x, block_w*y, 0);
-
- ref_score= ff_epzs_motion_search(&s->m, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv,
- (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w);
-
- assert(ref_mx >= c->xmin);
- assert(ref_mx <= c->xmax);
- assert(ref_my >= c->ymin);
- assert(ref_my <= c->ymax);
-
- ref_score= c->sub_motion_search(&s->m, &ref_mx, &ref_my, ref_score, 0, 0, level-LOG2_MB_SIZE+4, block_w);
- ref_score= ff_get_mb_score(&s->m, ref_mx, ref_my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0);
- ref_score+= 2*av_log2(2*ref)*c->penalty_factor;
- if(s->ref_mvs[ref]){
- s->ref_mvs[ref][index][0]= ref_mx;
- s->ref_mvs[ref][index][1]= ref_my;
- s->ref_scores[ref][index]= ref_score;
- }
- if(score > ref_score){
- score= ref_score;
- best_ref= ref;
- mx= ref_mx;
- my= ref_my;
- }
- }
- //FIXME if mb_cmp != SSE then intra cannot be compared currently and mb_penalty vs. lambda2
-
- // subpel search
- base_bits= get_rac_count(&s->c) - 8*(s->c.bytestream - s->c.bytestream_start);
- pc= s->c;
- pc.bytestream_start=
- pc.bytestream= p_buffer; //FIXME end/start? and at the other stoo
- memcpy(p_state, s->block_state, sizeof(s->block_state));
-
- if(level!=s->block_max_depth)
- put_rac(&pc, &p_state[4 + s_context], 1);
- put_rac(&pc, &p_state[1 + left->type + top->type], 0);
- if(s->ref_frames > 1)
- put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0);
- pred_mv(s, &pmx, &pmy, best_ref, left, top, tr);
- put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1);
- put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1);
- p_len= pc.bytestream - pc.bytestream_start;
- score += (s->lambda2*(get_rac_count(&pc)-base_bits))>>FF_LAMBDA_SHIFT;
-
- block_s= block_w*block_w;
- sum = pix_sum(current_data[0], stride, block_w);
- l= (sum + block_s/2)/block_s;
- iscore = pix_norm1(current_data[0], stride, block_w) - 2*l*sum + l*l*block_s;
-
- block_s= block_w*block_w>>2;
- sum = pix_sum(current_data[1], uvstride, block_w>>1);
- cb= (sum + block_s/2)/block_s;
-// iscore += pix_norm1(¤t_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s;
- sum = pix_sum(current_data[2], uvstride, block_w>>1);
- cr= (sum + block_s/2)/block_s;
-// iscore += pix_norm1(¤t_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s;
-
- ic= s->c;
- ic.bytestream_start=
- ic.bytestream= i_buffer; //FIXME end/start? and at the other stoo
- memcpy(i_state, s->block_state, sizeof(s->block_state));
- if(level!=s->block_max_depth)
- put_rac(&ic, &i_state[4 + s_context], 1);
- put_rac(&ic, &i_state[1 + left->type + top->type], 1);
- put_symbol(&ic, &i_state[32], l-pl , 1);
- put_symbol(&ic, &i_state[64], cb-pcb, 1);
- put_symbol(&ic, &i_state[96], cr-pcr, 1);
- i_len= ic.bytestream - ic.bytestream_start;
- iscore += (s->lambda2*(get_rac_count(&ic)-base_bits))>>FF_LAMBDA_SHIFT;
-
-// assert(score==256*256*256*64-1);
- assert(iscore < 255*255*256 + s->lambda2*10);
- assert(iscore >= 0);
- assert(l>=0 && l<=255);
- assert(pl>=0 && pl<=255);
-
- if(level==0){
- int varc= iscore >> 8;
- int vard= score >> 8;
- if (vard <= 64 || vard < varc)
- c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
- else
- c->scene_change_score+= s->m.qscale;
- }
-
- if(level!=s->block_max_depth){
- put_rac(&s->c, &s->block_state[4 + s_context], 0);
- score2 = encode_q_branch(s, level+1, 2*x+0, 2*y+0);
- score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+0);
- score2+= encode_q_branch(s, level+1, 2*x+0, 2*y+1);
- score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+1);
- score2+= s->lambda2>>FF_LAMBDA_SHIFT; //FIXME exact split overhead
-
- if(score2 < score && score2 < iscore)
- return score2;
- }
-
- if(iscore < score){
- pred_mv(s, &pmx, &pmy, 0, left, top, tr);
- memcpy(pbbak, i_buffer, i_len);
- s->c= ic;
- s->c.bytestream_start= pbbak_start;
- s->c.bytestream= pbbak + i_len;
- set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, 0, BLOCK_INTRA);
- memcpy(s->block_state, i_state, sizeof(s->block_state));
- return iscore;
- }else{
- memcpy(pbbak, p_buffer, p_len);
- s->c= pc;
- s->c.bytestream_start= pbbak_start;
- s->c.bytestream= pbbak + p_len;
- set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, best_ref, 0);
- memcpy(s->block_state, p_state, sizeof(s->block_state));
- return score;
- }
-}
-
-static void encode_q_branch2(SnowContext *s, int level, int x, int y){
- const int w= s->b_width << s->block_max_depth;
- const int rem_depth= s->block_max_depth - level;
- const int index= (x + y*w) << rem_depth;
- int trx= (x+1)<<rem_depth;
- BlockNode *b= &s->block[index];
- const BlockNode *left = x ? &s->block[index-1] : &null_block;
- const BlockNode *top = y ? &s->block[index-w] : &null_block;
- const BlockNode *tl = y && x ? &s->block[index-w-1] : left;
- const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
- int pl = left->color[0];
- int pcb= left->color[1];
- int pcr= left->color[2];
- int pmx, pmy;
- int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
- int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 16*!!b->ref;
- int my_context= av_log2(2*FFABS(left->my - top->my)) + 16*!!b->ref;
- int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
-
- if(s->keyframe){
- set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
- return;
- }
-
- if(level!=s->block_max_depth){
- if(same_block(b,b+1) && same_block(b,b+w) && same_block(b,b+w+1)){
- put_rac(&s->c, &s->block_state[4 + s_context], 1);
- }else{
- put_rac(&s->c, &s->block_state[4 + s_context], 0);
- encode_q_branch2(s, level+1, 2*x+0, 2*y+0);
- encode_q_branch2(s, level+1, 2*x+1, 2*y+0);
- encode_q_branch2(s, level+1, 2*x+0, 2*y+1);
- encode_q_branch2(s, level+1, 2*x+1, 2*y+1);
- return;
- }
- }
- if(b->type & BLOCK_INTRA){
- pred_mv(s, &pmx, &pmy, 0, left, top, tr);
- put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1);
- put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1);
- put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1);
- put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1);
- set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA);
- }else{
- pred_mv(s, &pmx, &pmy, b->ref, left, top, tr);
- put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0);
- if(s->ref_frames > 1)
- put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0);
- put_symbol(&s->c, &s->block_state[128 + 32*mx_context], b->mx - pmx, 1);
- put_symbol(&s->c, &s->block_state[128 + 32*my_context], b->my - pmy, 1);
- set_blocks(s, level, x, y, pl, pcb, pcr, b->mx, b->my, b->ref, 0);
- }
-}
-
-static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){
- int i, x2, y2;
- Plane *p= &s->plane[plane_index];
- const int block_size = MB_SIZE >> s->block_max_depth;
- const int block_w = plane_index ? block_size/2 : block_size;
- const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
- const int obmc_stride= plane_index ? block_size : 2*block_size;
- const int ref_stride= s->current_picture.linesize[plane_index];
- uint8_t *src= s-> input_picture.data[plane_index];
- IDWTELEM *dst= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned
- const int b_stride = s->b_width << s->block_max_depth;
- const int w= p->width;
- const int h= p->height;
- int index= mb_x + mb_y*b_stride;
- BlockNode *b= &s->block[index];
- BlockNode backup= *b;
- int ab=0;
- int aa=0;
-
- b->type|= BLOCK_INTRA;
- b->color[plane_index]= 0;
- memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM));
-
- for(i=0; i<4; i++){
- int mb_x2= mb_x + (i &1) - 1;
- int mb_y2= mb_y + (i>>1) - 1;
- int x= block_w*mb_x2 + block_w/2;
- int y= block_w*mb_y2 + block_w/2;
-
- add_yblock(s, 0, NULL, dst + ((i&1)+(i>>1)*obmc_stride)*block_w, NULL, obmc,
- x, y, block_w, block_w, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index);
-
- for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_w); y2++){
- for(x2= FFMAX(x, 0); x2<FFMIN(w, x+block_w); x2++){
- int index= x2-(block_w*mb_x - block_w/2) + (y2-(block_w*mb_y - block_w/2))*obmc_stride;
- int obmc_v= obmc[index];
- int d;
- if(y<0) obmc_v += obmc[index + block_w*obmc_stride];
- if(x<0) obmc_v += obmc[index + block_w];
- if(y+block_w>h) obmc_v += obmc[index - block_w*obmc_stride];
- if(x+block_w>w) obmc_v += obmc[index - block_w];
- //FIXME precalculate this or simplify it somehow else
-
- d = -dst[index] + (1<<(FRAC_BITS-1));
- dst[index] = d;
- ab += (src[x2 + y2*ref_stride] - (d>>FRAC_BITS)) * obmc_v;
- aa += obmc_v * obmc_v; //FIXME precalculate this
- }
- }
- }
- *b= backup;
-
- return av_clip(((ab<<LOG2_OBMC_MAX) + aa/2)/aa, 0, 255); //FIXME we should not need clipping
-}
-
-static inline int get_block_bits(SnowContext *s, int x, int y, int w){
- const int b_stride = s->b_width << s->block_max_depth;
- const int b_height = s->b_height<< s->block_max_depth;
- int index= x + y*b_stride;
- const BlockNode *b = &s->block[index];
- const BlockNode *left = x ? &s->block[index-1] : &null_block;
- const BlockNode *top = y ? &s->block[index-b_stride] : &null_block;
- const BlockNode *tl = y && x ? &s->block[index-b_stride-1] : left;
- const BlockNode *tr = y && x+w<b_stride ? &s->block[index-b_stride+w] : tl;
- int dmx, dmy;
-// int mx_context= av_log2(2*FFABS(left->mx - top->mx));
-// int my_context= av_log2(2*FFABS(left->my - top->my));
-
- if(x<0 || x>=b_stride || y>=b_height)
- return 0;
-/*
-1 0 0
-01X 1-2 1
-001XX 3-6 2-3
-0001XXX 7-14 4-7
-00001XXXX 15-30 8-15
-*/
-//FIXME try accurate rate
-//FIXME intra and inter predictors if surrounding blocks are not the same type
- if(b->type & BLOCK_INTRA){
- return 3+2*( av_log2(2*FFABS(left->color[0] - b->color[0]))
- + av_log2(2*FFABS(left->color[1] - b->color[1]))
- + av_log2(2*FFABS(left->color[2] - b->color[2])));
- }else{
- pred_mv(s, &dmx, &dmy, b->ref, left, top, tr);
- dmx-= b->mx;
- dmy-= b->my;
- return 2*(1 + av_log2(2*FFABS(dmx)) //FIXME kill the 2* can be merged in lambda
- + av_log2(2*FFABS(dmy))
- + av_log2(2*b->ref));
- }
-}
-
-static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){
- Plane *p= &s->plane[plane_index];
- const int block_size = MB_SIZE >> s->block_max_depth;
- const int block_w = plane_index ? block_size/2 : block_size;
- const int obmc_stride= plane_index ? block_size : 2*block_size;
- const int ref_stride= s->current_picture.linesize[plane_index];
- uint8_t *dst= s->current_picture.data[plane_index];
- uint8_t *src= s-> input_picture.data[plane_index];
- IDWTELEM *pred= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4;
- uint8_t *cur = s->scratchbuf;
- uint8_t tmp[ref_stride*(2*MB_SIZE+HTAPS_MAX-1)];
- const int b_stride = s->b_width << s->block_max_depth;
- const int b_height = s->b_height<< s->block_max_depth;
- const int w= p->width;
- const int h= p->height;
- int distortion;
- int rate= 0;
- const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
- int sx= block_w*mb_x - block_w/2;
- int sy= block_w*mb_y - block_w/2;
- int x0= FFMAX(0,-sx);
- int y0= FFMAX(0,-sy);
- int x1= FFMIN(block_w*2, w-sx);
- int y1= FFMIN(block_w*2, h-sy);
- int i,x,y;
-
- pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_w*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h);
-
- for(y=y0; y<y1; y++){
- const uint8_t *obmc1= obmc_edged + y*obmc_stride;
- const IDWTELEM *pred1 = pred + y*obmc_stride;
- uint8_t *cur1 = cur + y*ref_stride;
- uint8_t *dst1 = dst + sx + (sy+y)*ref_stride;
- for(x=x0; x<x1; x++){
-#if FRAC_BITS >= LOG2_OBMC_MAX
- int v = (cur1[x] * obmc1[x]) << (FRAC_BITS - LOG2_OBMC_MAX);
-#else
- int v = (cur1[x] * obmc1[x] + (1<<(LOG2_OBMC_MAX - FRAC_BITS-1))) >> (LOG2_OBMC_MAX - FRAC_BITS);
-#endif
- v = (v + pred1[x]) >> FRAC_BITS;
- if(v&(~255)) v= ~(v>>31);
- dst1[x] = v;
- }
- }
-
- /* copy the regions where obmc[] = (uint8_t)256 */
- if(LOG2_OBMC_MAX == 8
- && (mb_x == 0 || mb_x == b_stride-1)
- && (mb_y == 0 || mb_y == b_height-1)){
- if(mb_x == 0)
- x1 = block_w;
- else
- x0 = block_w;
- if(mb_y == 0)
- y1 = block_w;
- else
- y0 = block_w;
- for(y=y0; y<y1; y++)
- memcpy(dst + sx+x0 + (sy+y)*ref_stride, cur + x0 + y*ref_stride, x1-x0);
- }
-
- if(block_w==16){
- /* FIXME rearrange dsputil to fit 32x32 cmp functions */
- /* FIXME check alignment of the cmp wavelet vs the encoding wavelet */
- /* FIXME cmps overlap but do not cover the wavelet's whole support.
- * So improving the score of one block is not strictly guaranteed
- * to improve the score of the whole frame, thus iterative motion
- * estimation does not always converge. */
- if(s->avctx->me_cmp == FF_CMP_W97)
- distortion = ff_w97_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
- else if(s->avctx->me_cmp == FF_CMP_W53)
- distortion = ff_w53_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
- else{
- distortion = 0;
- for(i=0; i<4; i++){
- int off = sx+16*(i&1) + (sy+16*(i>>1))*ref_stride;
- distortion += s->dsp.me_cmp[0](&s->m, src + off, dst + off, ref_stride, 16);
- }
- }
- }else{
- assert(block_w==8);
- distortion = s->dsp.me_cmp[0](&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
- }
-
- if(plane_index==0){
- for(i=0; i<4; i++){
-/* ..RRr
- * .RXx.
- * rxx..
- */
- rate += get_block_bits(s, mb_x + (i&1) - (i>>1), mb_y + (i>>1), 1);
- }
- if(mb_x == b_stride-2)
- rate += get_block_bits(s, mb_x + 1, mb_y + 1, 1);
- }
- return distortion + rate*penalty_factor;
-}
-
-static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){
- int i, y2;
- Plane *p= &s->plane[plane_index];
- const int block_size = MB_SIZE >> s->block_max_depth;
- const int block_w = plane_index ? block_size/2 : block_size;
- const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
- const int obmc_stride= plane_index ? block_size : 2*block_size;
- const int ref_stride= s->current_picture.linesize[plane_index];
- uint8_t *dst= s->current_picture.data[plane_index];
- uint8_t *src= s-> input_picture.data[plane_index];
- //FIXME zero_dst is const but add_yblock changes dst if add is 0 (this is never the case for dst=zero_dst
- // const has only been removed from zero_dst to suppress a warning
- static IDWTELEM zero_dst[4096]; //FIXME
- const int b_stride = s->b_width << s->block_max_depth;
- const int w= p->width;
- const int h= p->height;
- int distortion= 0;
- int rate= 0;
- const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
-
- for(i=0; i<9; i++){
- int mb_x2= mb_x + (i%3) - 1;
- int mb_y2= mb_y + (i/3) - 1;
- int x= block_w*mb_x2 + block_w/2;
- int y= block_w*mb_y2 + block_w/2;
-
- add_yblock(s, 0, NULL, zero_dst, dst, obmc,
- x, y, block_w, block_w, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index);
-
- //FIXME find a cleaner/simpler way to skip the outside stuff
- for(y2= y; y2<0; y2++)
- memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
- for(y2= h; y2<y+block_w; y2++)
- memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
- if(x<0){
- for(y2= y; y2<y+block_w; y2++)
- memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, -x);
- }
- if(x+block_w > w){
- for(y2= y; y2<y+block_w; y2++)
- memcpy(dst + w + y2*ref_stride, src + w + y2*ref_stride, x+block_w - w);
- }
-
- assert(block_w== 8 || block_w==16);
- distortion += s->dsp.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_w);
- }
-
- if(plane_index==0){
- BlockNode *b= &s->block[mb_x+mb_y*b_stride];
- int merged= same_block(b,b+1) && same_block(b,b+b_stride) && same_block(b,b+b_stride+1);
-
-/* ..RRRr
- * .RXXx.
- * .RXXx.
- * rxxx.
- */
- if(merged)
- rate = get_block_bits(s, mb_x, mb_y, 2);
- for(i=merged?4:0; i<9; i++){
- static const int dxy[9][2] = {{0,0},{1,0},{0,1},{1,1},{2,0},{2,1},{-1,2},{0,2},{1,2}};
- rate += get_block_bits(s, mb_x + dxy[i][0], mb_y + dxy[i][1], 1);
- }
- }
- return distortion + rate*penalty_factor;
-}
-
-static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){
- const int w= b->width;
- const int h= b->height;
- int x, y;
-
- if(1){
- int run=0;
- int runs[w*h];
- int run_index=0;
- int max_index;
-
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- int v, p=0;
- int /*ll=0, */l=0, lt=0, t=0, rt=0;
- v= src[x + y*stride];
-
- if(y){
- t= src[x + (y-1)*stride];
- if(x){
- lt= src[x - 1 + (y-1)*stride];
- }
- if(x + 1 < w){
- rt= src[x + 1 + (y-1)*stride];
- }
- }
- if(x){
- l= src[x - 1 + y*stride];
- /*if(x > 1){
- if(orientation==1) ll= src[y + (x-2)*stride];
- else ll= src[x - 2 + y*stride];
- }*/
- }
- if(parent){
- int px= x>>1;
- int py= y>>1;
- if(px<b->parent->width && py<b->parent->height)
- p= parent[px + py*2*stride];
- }
- if(!(/*ll|*/l|lt|t|rt|p)){
- if(v){
- runs[run_index++]= run;
- run=0;
- }else{
- run++;
- }
- }
- }
- }
- max_index= run_index;
- runs[run_index++]= run;
- run_index=0;
- run= runs[run_index++];
-
- put_symbol2(&s->c, b->state[30], max_index, 0);
- if(run_index <= max_index)
- put_symbol2(&s->c, b->state[1], run, 3);
-
- for(y=0; y<h; y++){
- if(s->c.bytestream_end - s->c.bytestream < w*40){
- av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
- return -1;
- }
- for(x=0; x<w; x++){
- int v, p=0;
- int /*ll=0, */l=0, lt=0, t=0, rt=0;
- v= src[x + y*stride];
-
- if(y){
- t= src[x + (y-1)*stride];
- if(x){
- lt= src[x - 1 + (y-1)*stride];
- }
- if(x + 1 < w){
- rt= src[x + 1 + (y-1)*stride];
- }
- }
- if(x){
- l= src[x - 1 + y*stride];
- /*if(x > 1){
- if(orientation==1) ll= src[y + (x-2)*stride];
- else ll= src[x - 2 + y*stride];
- }*/
- }
- if(parent){
- int px= x>>1;
- int py= y>>1;
- if(px<b->parent->width && py<b->parent->height)
- p= parent[px + py*2*stride];
- }
- if(/*ll|*/l|lt|t|rt|p){
- int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p));
-
- put_rac(&s->c, &b->state[0][context], !!v);
- }else{
- if(!run){
- run= runs[run_index++];
-
- if(run_index <= max_index)
- put_symbol2(&s->c, b->state[1], run, 3);
- assert(v);
- }else{
- run--;
- assert(!v);
- }
- }
- if(v){
- int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p));
- int l2= 2*FFABS(l) + (l<0);
- int t2= 2*FFABS(t) + (t<0);
-
- put_symbol2(&s->c, b->state[context + 2], FFABS(v)-1, context-4);
- put_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3bA[l2&0xFF] + 3*quant3bA[t2&0xFF]], v<0);
- }
- }
- }
- }
- return 0;
-}
-
-static int encode_subband(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){
-// encode_subband_qtree(s, b, src, parent, stride, orientation);
-// encode_subband_z0run(s, b, src, parent, stride, orientation);
- return encode_subband_c0run(s, b, src, parent, stride, orientation);
-// encode_subband_dzr(s, b, src, parent, stride, orientation);
-}
-
-static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, const uint8_t *obmc_edged, int *best_rd){
- const int b_stride= s->b_width << s->block_max_depth;
- BlockNode *block= &s->block[mb_x + mb_y * b_stride];
- BlockNode backup= *block;
- int rd, index, value;
-
- assert(mb_x>=0 && mb_y>=0);
- assert(mb_x<b_stride);
-
- if(intra){
- block->color[0] = p[0];
- block->color[1] = p[1];
- block->color[2] = p[2];
- block->type |= BLOCK_INTRA;
- }else{
- index= (p[0] + 31*p[1]) & (ME_CACHE_SIZE-1);
- value= s->me_cache_generation + (p[0]>>10) + (p[1]<<6) + (block->ref<<12);
- if(s->me_cache[index] == value)
- return 0;
- s->me_cache[index]= value;
-
- block->mx= p[0];
- block->my= p[1];
- block->type &= ~BLOCK_INTRA;
- }
-
- rd= get_block_rd(s, mb_x, mb_y, 0, obmc_edged);
-
-//FIXME chroma
- if(rd < *best_rd){
- *best_rd= rd;
- return 1;
- }else{
- *block= backup;
- return 0;
- }
-}
-
-/* special case for int[2] args we discard afterwards,
- * fixes compilation problem with gcc 2.95 */
-static av_always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, const uint8_t *obmc_edged, int *best_rd){
- int p[2] = {p0, p1};
- return check_block(s, mb_x, mb_y, p, 0, obmc_edged, best_rd);
-}
-
-static av_always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int ref, int *best_rd){
- const int b_stride= s->b_width << s->block_max_depth;
- BlockNode *block= &s->block[mb_x + mb_y * b_stride];
- BlockNode backup[4]= {block[0], block[1], block[b_stride], block[b_stride+1]};
- int rd, index, value;
-
- assert(mb_x>=0 && mb_y>=0);
- assert(mb_x<b_stride);
- assert(((mb_x|mb_y)&1) == 0);
-
- index= (p0 + 31*p1) & (ME_CACHE_SIZE-1);
- value= s->me_cache_generation + (p0>>10) + (p1<<6) + (block->ref<<12);
- if(s->me_cache[index] == value)
- return 0;
- s->me_cache[index]= value;
-
- block->mx= p0;
- block->my= p1;
- block->ref= ref;
- block->type &= ~BLOCK_INTRA;
- block[1]= block[b_stride]= block[b_stride+1]= *block;
-
- rd= get_4block_rd(s, mb_x, mb_y, 0);
-
-//FIXME chroma
- if(rd < *best_rd){
- *best_rd= rd;
- return 1;
- }else{
- block[0]= backup[0];
- block[1]= backup[1];
- block[b_stride]= backup[2];
- block[b_stride+1]= backup[3];
- return 0;
- }
-}
-
-static void iterative_me(SnowContext *s){
- int pass, mb_x, mb_y;
- const int b_width = s->b_width << s->block_max_depth;
- const int b_height= s->b_height << s->block_max_depth;
- const int b_stride= b_width;
- int color[3];
-
- {
- RangeCoder r = s->c;
- uint8_t state[sizeof(s->block_state)];
- memcpy(state, s->block_state, sizeof(s->block_state));
- for(mb_y= 0; mb_y<s->b_height; mb_y++)
- for(mb_x= 0; mb_x<s->b_width; mb_x++)
- encode_q_branch(s, 0, mb_x, mb_y);
- s->c = r;
- memcpy(s->block_state, state, sizeof(s->block_state));
- }
-
- for(pass=0; pass<25; pass++){
- int change= 0;
-
- for(mb_y= 0; mb_y<b_height; mb_y++){
- for(mb_x= 0; mb_x<b_width; mb_x++){
- int dia_change, i, j, ref;
- int best_rd= INT_MAX, ref_rd;
- BlockNode backup, ref_b;
- const int index= mb_x + mb_y * b_stride;
- BlockNode *block= &s->block[index];
- BlockNode *tb = mb_y ? &s->block[index-b_stride ] : NULL;
- BlockNode *lb = mb_x ? &s->block[index -1] : NULL;
- BlockNode *rb = mb_x+1<b_width ? &s->block[index +1] : NULL;
- BlockNode *bb = mb_y+1<b_height ? &s->block[index+b_stride ] : NULL;
- BlockNode *tlb= mb_x && mb_y ? &s->block[index-b_stride-1] : NULL;
- BlockNode *trb= mb_x+1<b_width && mb_y ? &s->block[index-b_stride+1] : NULL;
- BlockNode *blb= mb_x && mb_y+1<b_height ? &s->block[index+b_stride-1] : NULL;
- BlockNode *brb= mb_x+1<b_width && mb_y+1<b_height ? &s->block[index+b_stride+1] : NULL;
- const int b_w= (MB_SIZE >> s->block_max_depth);
- uint8_t obmc_edged[b_w*2][b_w*2];
-
- if(pass && (block->type & BLOCK_OPT))
- continue;
- block->type |= BLOCK_OPT;
-
- backup= *block;
-
- if(!s->me_cache_generation)
- memset(s->me_cache, 0, sizeof(s->me_cache));
- s->me_cache_generation += 1<<22;
-
- //FIXME precalculate
- {
- int x, y;
- memcpy(obmc_edged, obmc_tab[s->block_max_depth], b_w*b_w*4);
- if(mb_x==0)
- for(y=0; y<b_w*2; y++)
- memset(obmc_edged[y], obmc_edged[y][0] + obmc_edged[y][b_w-1], b_w);
- if(mb_x==b_stride-1)
- for(y=0; y<b_w*2; y++)
- memset(obmc_edged[y]+b_w, obmc_edged[y][b_w] + obmc_edged[y][b_w*2-1], b_w);
- if(mb_y==0){
- for(x=0; x<b_w*2; x++)
- obmc_edged[0][x] += obmc_edged[b_w-1][x];
- for(y=1; y<b_w; y++)
- memcpy(obmc_edged[y], obmc_edged[0], b_w*2);
- }
- if(mb_y==b_height-1){
- for(x=0; x<b_w*2; x++)
- obmc_edged[b_w*2-1][x] += obmc_edged[b_w][x];
- for(y=b_w; y<b_w*2-1; y++)
- memcpy(obmc_edged[y], obmc_edged[b_w*2-1], b_w*2);
- }
- }
-
- //skip stuff outside the picture
- if(mb_x==0 || mb_y==0 || mb_x==b_width-1 || mb_y==b_height-1){
- uint8_t *src= s-> input_picture.data[0];
- uint8_t *dst= s->current_picture.data[0];
- const int stride= s->current_picture.linesize[0];
- const int block_w= MB_SIZE >> s->block_max_depth;
- const int sx= block_w*mb_x - block_w/2;
- const int sy= block_w*mb_y - block_w/2;
- const int w= s->plane[0].width;
- const int h= s->plane[0].height;
- int y;
-
- for(y=sy; y<0; y++)
- memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
- for(y=h; y<sy+block_w*2; y++)
- memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
- if(sx<0){
- for(y=sy; y<sy+block_w*2; y++)
- memcpy(dst + sx + y*stride, src + sx + y*stride, -sx);
- }
- if(sx+block_w*2 > w){
- for(y=sy; y<sy+block_w*2; y++)
- memcpy(dst + w + y*stride, src + w + y*stride, sx+block_w*2 - w);
- }
- }
-
- // intra(black) = neighbors' contribution to the current block
- for(i=0; i<3; i++)
- color[i]= get_dc(s, mb_x, mb_y, i);
-
- // get previous score (cannot be cached due to OBMC)
- if(pass > 0 && (block->type&BLOCK_INTRA)){
- int color0[3]= {block->color[0], block->color[1], block->color[2]};
- check_block(s, mb_x, mb_y, color0, 1, *obmc_edged, &best_rd);
- }else
- check_block_inter(s, mb_x, mb_y, block->mx, block->my, *obmc_edged, &best_rd);
-
- ref_b= *block;
- ref_rd= best_rd;
- for(ref=0; ref < s->ref_frames; ref++){
- int16_t (*mvr)[2]= &s->ref_mvs[ref][index];
- if(s->ref_scores[ref][index] > s->ref_scores[ref_b.ref][index]*3/2) //FIXME tune threshold
- continue;
- block->ref= ref;
- best_rd= INT_MAX;
-
- check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], *obmc_edged, &best_rd);
- check_block_inter(s, mb_x, mb_y, 0, 0, *obmc_edged, &best_rd);
- if(tb)
- check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], *obmc_edged, &best_rd);
- if(lb)
- check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], *obmc_edged, &best_rd);
- if(rb)
- check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], *obmc_edged, &best_rd);
- if(bb)
- check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], *obmc_edged, &best_rd);
-
- /* fullpel ME */
- //FIXME avoid subpel interpolation / round to nearest integer
- do{
- dia_change=0;
- for(i=0; i<FFMAX(s->avctx->dia_size, 1); i++){
- for(j=0; j<i; j++){
- dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my+(4*j), *obmc_edged, &best_rd);
- dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my-(4*j), *obmc_edged, &best_rd);
- dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my-(4*j), *obmc_edged, &best_rd);
- dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my+(4*j), *obmc_edged, &best_rd);
- }
- }
- }while(dia_change);
- /* subpel ME */
- do{
- static const int square[8][2]= {{+1, 0},{-1, 0},{ 0,+1},{ 0,-1},{+1,+1},{-1,-1},{+1,-1},{-1,+1},};
- dia_change=0;
- for(i=0; i<8; i++)
- dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], *obmc_edged, &best_rd);
- }while(dia_change);
- //FIXME or try the standard 2 pass qpel or similar
-
- mvr[0][0]= block->mx;
- mvr[0][1]= block->my;
- if(ref_rd > best_rd){
- ref_rd= best_rd;
- ref_b= *block;
- }
- }
- best_rd= ref_rd;
- *block= ref_b;
- check_block(s, mb_x, mb_y, color, 1, *obmc_edged, &best_rd);
- //FIXME RD style color selection
- if(!same_block(block, &backup)){
- if(tb ) tb ->type &= ~BLOCK_OPT;
- if(lb ) lb ->type &= ~BLOCK_OPT;
- if(rb ) rb ->type &= ~BLOCK_OPT;
- if(bb ) bb ->type &= ~BLOCK_OPT;
- if(tlb) tlb->type &= ~BLOCK_OPT;
- if(trb) trb->type &= ~BLOCK_OPT;
- if(blb) blb->type &= ~BLOCK_OPT;
- if(brb) brb->type &= ~BLOCK_OPT;
- change ++;
- }
- }
- }
- av_log(s->avctx, AV_LOG_ERROR, "pass:%d changed:%d\n", pass, change);
- if(!change)
- break;
- }
-
- if(s->block_max_depth == 1){
- int change= 0;
- for(mb_y= 0; mb_y<b_height; mb_y+=2){
- for(mb_x= 0; mb_x<b_width; mb_x+=2){
- int i;
- int best_rd, init_rd;
- const int index= mb_x + mb_y * b_stride;
- BlockNode *b[4];
-
- b[0]= &s->block[index];
- b[1]= b[0]+1;
- b[2]= b[0]+b_stride;
- b[3]= b[2]+1;
- if(same_block(b[0], b[1]) &&
- same_block(b[0], b[2]) &&
- same_block(b[0], b[3]))
- continue;
-
- if(!s->me_cache_generation)
- memset(s->me_cache, 0, sizeof(s->me_cache));
- s->me_cache_generation += 1<<22;
-
- init_rd= best_rd= get_4block_rd(s, mb_x, mb_y, 0);
-
- //FIXME more multiref search?
- check_4block_inter(s, mb_x, mb_y,
- (b[0]->mx + b[1]->mx + b[2]->mx + b[3]->mx + 2) >> 2,
- (b[0]->my + b[1]->my + b[2]->my + b[3]->my + 2) >> 2, 0, &best_rd);
-
- for(i=0; i<4; i++)
- if(!(b[i]->type&BLOCK_INTRA))
- check_4block_inter(s, mb_x, mb_y, b[i]->mx, b[i]->my, b[i]->ref, &best_rd);
-
- if(init_rd != best_rd)
- change++;
- }
- }
- av_log(s->avctx, AV_LOG_ERROR, "pass:4mv changed:%d\n", change*4);
- }
-}
-
-static void encode_blocks(SnowContext *s, int search){
- int x, y;
- int w= s->b_width;
- int h= s->b_height;
-
- if(s->avctx->me_method == ME_ITER && !s->keyframe && search)
- iterative_me(s);
-
- for(y=0; y<h; y++){
- if(s->c.bytestream_end - s->c.bytestream < w*MB_SIZE*MB_SIZE*3){ //FIXME nicer limit
- av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
- return;
- }
- for(x=0; x<w; x++){
- if(s->avctx->me_method == ME_ITER || !search)
- encode_q_branch2(s, 0, x, y);
- else
- encode_q_branch (s, 0, x, y);
- }
- }
-}
-
-static void quantize(SnowContext *s, SubBand *b, IDWTELEM *dst, DWTELEM *src, int stride, int bias){
- const int w= b->width;
- const int h= b->height;
- const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
- const int qmul= qexp[qlog&(QROOT-1)]<<((qlog>>QSHIFT) + ENCODER_EXTRA_BITS);
- int x,y, thres1, thres2;
-
- if(s->qlog == LOSSLESS_QLOG){
- for(y=0; y<h; y++)
- for(x=0; x<w; x++)
- dst[x + y*stride]= src[x + y*stride];
- return;
- }
-
- bias= bias ? 0 : (3*qmul)>>3;
- thres1= ((qmul - bias)>>QEXPSHIFT) - 1;
- thres2= 2*thres1;
-
- if(!bias){
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- int i= src[x + y*stride];
-
- if((unsigned)(i+thres1) > thres2){
- if(i>=0){
- i<<= QEXPSHIFT;
- i/= qmul; //FIXME optimize
- dst[x + y*stride]= i;
- }else{
- i= -i;
- i<<= QEXPSHIFT;
- i/= qmul; //FIXME optimize
- dst[x + y*stride]= -i;
- }
- }else
- dst[x + y*stride]= 0;
- }
- }
- }else{
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- int i= src[x + y*stride];
-
- if((unsigned)(i+thres1) > thres2){
- if(i>=0){
- i<<= QEXPSHIFT;
- i= (i + bias) / qmul; //FIXME optimize
- dst[x + y*stride]= i;
- }else{
- i= -i;
- i<<= QEXPSHIFT;
- i= (i + bias) / qmul; //FIXME optimize
- dst[x + y*stride]= -i;
- }
- }else
- dst[x + y*stride]= 0;
- }
- }
- }
-}
-
-static void dequantize(SnowContext *s, SubBand *b, IDWTELEM *src, int stride){
- const int w= b->width;
- const int h= b->height;
- const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
- const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
- const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
- int x,y;
-
- if(s->qlog == LOSSLESS_QLOG) return;
-
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- int i= src[x + y*stride];
- if(i<0){
- src[x + y*stride]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
- }else if(i>0){
- src[x + y*stride]= (( i*qmul + qadd)>>(QEXPSHIFT));
- }
- }
- }
-}
-
-static void decorrelate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){
- const int w= b->width;
- const int h= b->height;
- int x,y;
-
- for(y=h-1; y>=0; y--){
- for(x=w-1; x>=0; x--){
- int i= x + y*stride;
-
- if(x){
- if(use_median){
- if(y && x+1<w) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]);
- else src[i] -= src[i - 1];
- }else{
- if(y) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]);
- else src[i] -= src[i - 1];
- }
- }else{
- if(y) src[i] -= src[i - stride];
- }
- }
- }
-}
-
-static void correlate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){
- const int w= b->width;
- const int h= b->height;
- int x,y;
-
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- int i= x + y*stride;
-
- if(x){
- if(use_median){
- if(y && x+1<w) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]);
- else src[i] += src[i - 1];
- }else{
- if(y) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]);
- else src[i] += src[i - 1];
- }
- }else{
- if(y) src[i] += src[i - stride];
- }
- }
- }
-}
-
-static void encode_qlogs(SnowContext *s){
- int plane_index, level, orientation;
-
- for(plane_index=0; plane_index<2; plane_index++){
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1:0; orientation<4; orientation++){
- if(orientation==2) continue;
- put_symbol(&s->c, s->header_state, s->plane[plane_index].band[level][orientation].qlog, 1);
- }
- }
- }
-}
-
-static void encode_header(SnowContext *s){
- int plane_index, i;
- uint8_t kstate[32];
-
- memset(kstate, MID_STATE, sizeof(kstate));
-
- put_rac(&s->c, kstate, s->keyframe);
- if(s->keyframe || s->always_reset){
- reset_contexts(s);
- s->last_spatial_decomposition_type=
- s->last_qlog=
- s->last_qbias=
- s->last_mv_scale=
- s->last_block_max_depth= 0;
- for(plane_index=0; plane_index<2; plane_index++){
- Plane *p= &s->plane[plane_index];
- p->last_htaps=0;
- p->last_diag_mc=0;
- memset(p->last_hcoeff, 0, sizeof(p->last_hcoeff));
- }
- }
- if(s->keyframe){
- put_symbol(&s->c, s->header_state, s->version, 0);
- put_rac(&s->c, s->header_state, s->always_reset);
- put_symbol(&s->c, s->header_state, s->temporal_decomposition_type, 0);
- put_symbol(&s->c, s->header_state, s->temporal_decomposition_count, 0);
- put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
- put_symbol(&s->c, s->header_state, s->colorspace_type, 0);
- put_symbol(&s->c, s->header_state, s->chroma_h_shift, 0);
- put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0);
- put_rac(&s->c, s->header_state, s->spatial_scalability);
-// put_rac(&s->c, s->header_state, s->rate_scalability);
- put_symbol(&s->c, s->header_state, s->max_ref_frames-1, 0);
-
- encode_qlogs(s);
- }
-
- if(!s->keyframe){
- int update_mc=0;
- for(plane_index=0; plane_index<2; plane_index++){
- Plane *p= &s->plane[plane_index];
- update_mc |= p->last_htaps != p->htaps;
- update_mc |= p->last_diag_mc != p->diag_mc;
- update_mc |= !!memcmp(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff));
- }
- put_rac(&s->c, s->header_state, update_mc);
- if(update_mc){
- for(plane_index=0; plane_index<2; plane_index++){
- Plane *p= &s->plane[plane_index];
- put_rac(&s->c, s->header_state, p->diag_mc);
- put_symbol(&s->c, s->header_state, p->htaps/2-1, 0);
- for(i= p->htaps/2; i; i--)
- put_symbol(&s->c, s->header_state, FFABS(p->hcoeff[i]), 0);
- }
- }
- if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){
- put_rac(&s->c, s->header_state, 1);
- put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
- encode_qlogs(s);
- }else
- put_rac(&s->c, s->header_state, 0);
- }
-
- put_symbol(&s->c, s->header_state, s->spatial_decomposition_type - s->last_spatial_decomposition_type, 1);
- put_symbol(&s->c, s->header_state, s->qlog - s->last_qlog , 1);
- put_symbol(&s->c, s->header_state, s->mv_scale - s->last_mv_scale, 1);
- put_symbol(&s->c, s->header_state, s->qbias - s->last_qbias , 1);
- put_symbol(&s->c, s->header_state, s->block_max_depth - s->last_block_max_depth, 1);
-
-}
-
-static void update_last_header_values(SnowContext *s){
- int plane_index;
-
- if(!s->keyframe){
- for(plane_index=0; plane_index<2; plane_index++){
- Plane *p= &s->plane[plane_index];
- p->last_diag_mc= p->diag_mc;
- p->last_htaps = p->htaps;
- memcpy(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff));
- }
- }
-
- s->last_spatial_decomposition_type = s->spatial_decomposition_type;
- s->last_qlog = s->qlog;
- s->last_qbias = s->qbias;
- s->last_mv_scale = s->mv_scale;
- s->last_block_max_depth = s->block_max_depth;
- s->last_spatial_decomposition_count = s->spatial_decomposition_count;
-}
-
-static int qscale2qlog(int qscale){
- return rint(QROOT*log(qscale / (float)FF_QP2LAMBDA)/log(2))
- + 61*QROOT/8; //<64 >60
-}
-
-static int ratecontrol_1pass(SnowContext *s, AVFrame *pict)
-{
- /* Estimate the frame's complexity as a sum of weighted dwt coefficients.
- * FIXME we know exact mv bits at this point,
- * but ratecontrol isn't set up to include them. */
- uint32_t coef_sum= 0;
- int level, orientation, delta_qlog;
-
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &s->plane[0].band[level][orientation];
- IDWTELEM *buf= b->ibuf;
- const int w= b->width;
- const int h= b->height;
- const int stride= b->stride;
- const int qlog= av_clip(2*QROOT + b->qlog, 0, QROOT*16);
- const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
- const int qdiv= (1<<16)/qmul;
- int x, y;
- //FIXME this is ugly
- for(y=0; y<h; y++)
- for(x=0; x<w; x++)
- buf[x+y*stride]= b->buf[x+y*stride];
- if(orientation==0)
- decorrelate(s, b, buf, stride, 1, 0);
- for(y=0; y<h; y++)
- for(x=0; x<w; x++)
- coef_sum+= abs(buf[x+y*stride]) * qdiv >> 16;
- }
- }
-
- /* ugly, ratecontrol just takes a sqrt again */
- coef_sum = (uint64_t)coef_sum * coef_sum >> 16;
- assert(coef_sum < INT_MAX);
-
- if(pict->pict_type == AV_PICTURE_TYPE_I){
- s->m.current_picture.mb_var_sum= coef_sum;
- s->m.current_picture.mc_mb_var_sum= 0;
- }else{
- s->m.current_picture.mc_mb_var_sum= coef_sum;
- s->m.current_picture.mb_var_sum= 0;
- }
-
- pict->quality= ff_rate_estimate_qscale(&s->m, 1);
- if (pict->quality < 0)
- return INT_MIN;
- s->lambda= pict->quality * 3/2;
- delta_qlog= qscale2qlog(pict->quality) - s->qlog;
- s->qlog+= delta_qlog;
- return delta_qlog;
-}
-
-static void calculate_visual_weight(SnowContext *s, Plane *p){
- int width = p->width;
- int height= p->height;
- int level, orientation, x, y;
-
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &p->band[level][orientation];
- IDWTELEM *ibuf= b->ibuf;
- int64_t error=0;
-
- memset(s->spatial_idwt_buffer, 0, sizeof(*s->spatial_idwt_buffer)*width*height);
- ibuf[b->width/2 + b->height/2*b->stride]= 256*16;
- ff_spatial_idwt(s->spatial_idwt_buffer, width, height, width, s->spatial_decomposition_type, s->spatial_decomposition_count);
- for(y=0; y<height; y++){
- for(x=0; x<width; x++){
- int64_t d= s->spatial_idwt_buffer[x + y*width]*16;
- error += d*d;
- }
- }
-
- b->qlog= (int)(log(352256.0/sqrt(error)) / log(pow(2.0, 1.0/QROOT))+0.5);
- }
- }
-}
-
-static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
- SnowContext *s = avctx->priv_data;
- RangeCoder * const c= &s->c;
- AVFrame *pict = data;
- const int width= s->avctx->width;
- const int height= s->avctx->height;
- int level, orientation, plane_index, i, y;
- uint8_t rc_header_bak[sizeof(s->header_state)];
- uint8_t rc_block_bak[sizeof(s->block_state)];
-
- ff_init_range_encoder(c, buf, buf_size);
- ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
-
- for(i=0; i<3; i++){
- int shift= !!i;
- for(y=0; y<(height>>shift); y++)
- memcpy(&s->input_picture.data[i][y * s->input_picture.linesize[i]],
- &pict->data[i][y * pict->linesize[i]],
- width>>shift);
- }
- s->new_picture = *pict;
-
- s->m.picture_number= avctx->frame_number;
- if(avctx->flags&CODEC_FLAG_PASS2){
- s->m.pict_type =
- pict->pict_type= s->m.rc_context.entry[avctx->frame_number].new_pict_type;
- s->keyframe= pict->pict_type==AV_PICTURE_TYPE_I;
- if(!(avctx->flags&CODEC_FLAG_QSCALE)) {
- pict->quality= ff_rate_estimate_qscale(&s->m, 0);
- if (pict->quality < 0)
- return -1;
- }
- }else{
- s->keyframe= avctx->gop_size==0 || avctx->frame_number % avctx->gop_size == 0;
- s->m.pict_type=
- pict->pict_type= s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
- }
-
- if(s->pass1_rc && avctx->frame_number == 0)
- pict->quality= 2*FF_QP2LAMBDA;
- if(pict->quality){
- s->qlog= qscale2qlog(pict->quality);
- s->lambda = pict->quality * 3/2;
- }
- if(s->qlog < 0 || (!pict->quality && (avctx->flags & CODEC_FLAG_QSCALE))){
- s->qlog= LOSSLESS_QLOG;
- s->lambda = 0;
- }//else keep previous frame's qlog until after motion estimation
-
- frame_start(s);
-
- s->m.current_picture_ptr= &s->m.current_picture;
- s->m.last_picture.pts= s->m.current_picture.pts;
- s->m.current_picture.pts= pict->pts;
- if(pict->pict_type == AV_PICTURE_TYPE_P){
- int block_width = (width +15)>>4;
- int block_height= (height+15)>>4;
- int stride= s->current_picture.linesize[0];
-
- assert(s->current_picture.data[0]);
- assert(s->last_picture[0].data[0]);
-
- s->m.avctx= s->avctx;
- s->m.current_picture.data[0]= s->current_picture.data[0];
- s->m. last_picture.data[0]= s->last_picture[0].data[0];
- s->m. new_picture.data[0]= s-> input_picture.data[0];
- s->m. last_picture_ptr= &s->m. last_picture;
- s->m.linesize=
- s->m. last_picture.linesize[0]=
- s->m. new_picture.linesize[0]=
- s->m.current_picture.linesize[0]= stride;
- s->m.uvlinesize= s->current_picture.linesize[1];
- s->m.width = width;
- s->m.height= height;
- s->m.mb_width = block_width;
- s->m.mb_height= block_height;
- s->m.mb_stride= s->m.mb_width+1;
- s->m.b8_stride= 2*s->m.mb_width+1;
- s->m.f_code=1;
- s->m.pict_type= pict->pict_type;
- s->m.me_method= s->avctx->me_method;
- s->m.me.scene_change_score=0;
- s->m.flags= s->avctx->flags;
- s->m.quarter_sample= (s->avctx->flags & CODEC_FLAG_QPEL)!=0;
- s->m.out_format= FMT_H263;
- s->m.unrestricted_mv= 1;
-
- s->m.lambda = s->lambda;
- s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
- s->lambda2= s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
-
- s->m.dsp= s->dsp; //move
- ff_init_me(&s->m);
- s->dsp= s->m.dsp;
- }
-
- if(s->pass1_rc){
- memcpy(rc_header_bak, s->header_state, sizeof(s->header_state));
- memcpy(rc_block_bak, s->block_state, sizeof(s->block_state));
- }
-
-redo_frame:
-
- if(pict->pict_type == AV_PICTURE_TYPE_I)
- s->spatial_decomposition_count= 5;
- else
- s->spatial_decomposition_count= 5;
-
- s->m.pict_type = pict->pict_type;
- s->qbias= pict->pict_type == AV_PICTURE_TYPE_P ? 2 : 0;
-
- common_init_after_header(avctx);
-
- if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){
- for(plane_index=0; plane_index<3; plane_index++){
- calculate_visual_weight(s, &s->plane[plane_index]);
- }
- }
-
- encode_header(s);
- s->m.misc_bits = 8*(s->c.bytestream - s->c.bytestream_start);
- encode_blocks(s, 1);
- s->m.mv_bits = 8*(s->c.bytestream - s->c.bytestream_start) - s->m.misc_bits;
-
- for(plane_index=0; plane_index<3; plane_index++){
- Plane *p= &s->plane[plane_index];
- int w= p->width;
- int h= p->height;
- int x, y;
-// int bits= put_bits_count(&s->c.pb);
-
- if(!(avctx->flags2 & CODEC_FLAG2_MEMC_ONLY)){
- //FIXME optimize
- if(pict->data[plane_index]) //FIXME gray hack
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- s->spatial_idwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<<FRAC_BITS;
- }
- }
- predict_plane(s, s->spatial_idwt_buffer, plane_index, 0);
-
- if( plane_index==0
- && pict->pict_type == AV_PICTURE_TYPE_P
- && !(avctx->flags&CODEC_FLAG_PASS2)
- && s->m.me.scene_change_score > s->avctx->scenechange_threshold){
- ff_init_range_encoder(c, buf, buf_size);
- ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
- pict->pict_type= AV_PICTURE_TYPE_I;
- s->keyframe=1;
- s->current_picture.key_frame=1;
- goto redo_frame;
- }
-
- if(s->qlog == LOSSLESS_QLOG){
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- s->spatial_dwt_buffer[y*w + x]= (s->spatial_idwt_buffer[y*w + x] + (1<<(FRAC_BITS-1))-1)>>FRAC_BITS;
- }
- }
- }else{
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- s->spatial_dwt_buffer[y*w + x]=s->spatial_idwt_buffer[y*w + x]<<ENCODER_EXTRA_BITS;
- }
- }
- }
-
- /* if(QUANTIZE2)
- dwt_quantize(s, p, s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type);
- else*/
- ff_spatial_dwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
-
- if(s->pass1_rc && plane_index==0){
- int delta_qlog = ratecontrol_1pass(s, pict);
- if (delta_qlog <= INT_MIN)
- return -1;
- if(delta_qlog){
- //reordering qlog in the bitstream would eliminate this reset
- ff_init_range_encoder(c, buf, buf_size);
- memcpy(s->header_state, rc_header_bak, sizeof(s->header_state));
- memcpy(s->block_state, rc_block_bak, sizeof(s->block_state));
- encode_header(s);
- encode_blocks(s, 0);
- }
- }
-
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &p->band[level][orientation];
-
- if(!QUANTIZE2)
- quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias);
- if(orientation==0)
- decorrelate(s, b, b->ibuf, b->stride, pict->pict_type == AV_PICTURE_TYPE_P, 0);
- encode_subband(s, b, b->ibuf, b->parent ? b->parent->ibuf : NULL, b->stride, orientation);
- assert(b->parent==NULL || b->parent->stride == b->stride*2);
- if(orientation==0)
- correlate(s, b, b->ibuf, b->stride, 1, 0);
- }
- }
-
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &p->band[level][orientation];
-
- dequantize(s, b, b->ibuf, b->stride);
- }
- }
-
- ff_spatial_idwt(s->spatial_idwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
- if(s->qlog == LOSSLESS_QLOG){
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- s->spatial_idwt_buffer[y*w + x]<<=FRAC_BITS;
- }
- }
- }
- predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
- }else{
- //ME/MC only
- if(pict->pict_type == AV_PICTURE_TYPE_I){
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]=
- pict->data[plane_index][y*pict->linesize[plane_index] + x];
- }
- }
- }else{
- memset(s->spatial_idwt_buffer, 0, sizeof(IDWTELEM)*w*h);
- predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
- }
- }
- if(s->avctx->flags&CODEC_FLAG_PSNR){
- int64_t error= 0;
-
- if(pict->data[plane_index]) //FIXME gray hack
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- int d= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x];
- error += d*d;
- }
- }
- s->avctx->error[plane_index] += error;
- s->current_picture.error[plane_index] = error;
- }
-
- }
-
- update_last_header_values(s);
-
- release_buffer(avctx);
-
- s->current_picture.coded_picture_number = avctx->frame_number;
- s->current_picture.pict_type = pict->pict_type;
- s->current_picture.quality = pict->quality;
- s->m.frame_bits = 8*(s->c.bytestream - s->c.bytestream_start);
- s->m.p_tex_bits = s->m.frame_bits - s->m.misc_bits - s->m.mv_bits;
- s->m.current_picture.display_picture_number =
- s->m.current_picture.coded_picture_number = avctx->frame_number;
- s->m.current_picture.quality = pict->quality;
- s->m.total_bits += 8*(s->c.bytestream - s->c.bytestream_start);
- if(s->pass1_rc)
- if (ff_rate_estimate_qscale(&s->m, 0) < 0)
- return -1;
- if(avctx->flags&CODEC_FLAG_PASS1)
- ff_write_pass1_stats(&s->m);
- s->m.last_pict_type = s->m.pict_type;
- avctx->frame_bits = s->m.frame_bits;
- avctx->mv_bits = s->m.mv_bits;
- avctx->misc_bits = s->m.misc_bits;
- avctx->p_tex_bits = s->m.p_tex_bits;
-
- emms_c();
-
- return ff_rac_terminate(c);
-}
-
-static av_cold int encode_end(AVCodecContext *avctx)
-{
- SnowContext *s = avctx->priv_data;
-
- common_end(s);
- if (s->input_picture.data[0])
- avctx->release_buffer(avctx, &s->input_picture);
- av_free(avctx->stats_out);
-
- return 0;
-}
-
-AVCodec ff_snow_encoder = {
- "snow",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SNOW,
- sizeof(SnowContext),
- encode_init,
- encode_frame,
- encode_end,
- .long_name = NULL_IF_CONFIG_SMALL("Snow"),
-};
-#endif
-
-
-#ifdef TEST
-#undef malloc
-#undef free
-#undef printf
-
-#include "libavutil/lfg.h"
-
-int main(void){
- int width=256;
- int height=256;
- int buffer[2][width*height];
- SnowContext s;
- int i;
- AVLFG prng;
- s.spatial_decomposition_count=6;
- s.spatial_decomposition_type=1;
-
- av_lfg_init(&prng, 1);
-
- printf("testing 5/3 DWT\n");
- for(i=0; i<width*height; i++)
- buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345;
-
- ff_spatial_dwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
- ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
-
- for(i=0; i<width*height; i++)
- if(buffer[0][i]!= buffer[1][i]) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]);
-
- printf("testing 9/7 DWT\n");
- s.spatial_decomposition_type=0;
- for(i=0; i<width*height; i++)
- buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345;
-
- ff_spatial_dwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
- ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
-
- for(i=0; i<width*height; i++)
- if(FFABS(buffer[0][i] - buffer[1][i])>20) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]);
-
-#if 0
- printf("testing AC coder\n");
- memset(s.header_state, 0, sizeof(s.header_state));
- ff_init_range_encoder(&s.c, buffer[0], 256*256);
- ff_init_cabac_states(&s.c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
-
- for(i=-256; i<256; i++){
- put_symbol(&s.c, s.header_state, i*i*i/3*FFABS(i), 1);
- }
- ff_rac_terminate(&s.c);
-
- memset(s.header_state, 0, sizeof(s.header_state));
- ff_init_range_decoder(&s.c, buffer[0], 256*256);
- ff_init_cabac_states(&s.c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
-
- for(i=-256; i<256; i++){
- int j;
- j= get_symbol(&s.c, s.header_state, 1);
- if(j!=i*i*i/3*FFABS(i)) printf("fsck: %d != %d\n", i, j);
- }
-#endif
- {
- int level, orientation, x, y;
- int64_t errors[8][4];
- int64_t g=0;
-
- memset(errors, 0, sizeof(errors));
- s.spatial_decomposition_count=3;
- s.spatial_decomposition_type=0;
- for(level=0; level<s.spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- int w= width >> (s.spatial_decomposition_count-level);
- int h= height >> (s.spatial_decomposition_count-level);
- int stride= width << (s.spatial_decomposition_count-level);
- DWTELEM *buf= buffer[0];
- int64_t error=0;
-
- if(orientation&1) buf+=w;
- if(orientation>1) buf+=stride>>1;
-
- memset(buffer[0], 0, sizeof(int)*width*height);
- buf[w/2 + h/2*stride]= 256*256;
- ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
- for(y=0; y<height; y++){
- for(x=0; x<width; x++){
- int64_t d= buffer[0][x + y*width];
- error += d*d;
- if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9 && level==2) printf("%8"PRId64" ", d);
- }
- if(FFABS(height/2-y)<9 && level==2) printf("\n");
- }
- error= (int)(sqrt(error)+0.5);
- errors[level][orientation]= error;
- if(g) g=av_gcd(g, error);
- else g= error;
- }
- }
- printf("static int const visual_weight[][4]={\n");
- for(level=0; level<s.spatial_decomposition_count; level++){
- printf(" {");
- for(orientation=0; orientation<4; orientation++){
- printf("%8"PRId64",", errors[level][orientation]/g);
- }
- printf("},\n");
- }
- printf("};\n");
- {
- int level=2;
- int w= width >> (s.spatial_decomposition_count-level);
- //int h= height >> (s.spatial_decomposition_count-level);
- int stride= width << (s.spatial_decomposition_count-level);
- DWTELEM *buf= buffer[0];
- int64_t error=0;
-
- buf+=w;
- buf+=stride>>1;
-
- memset(buffer[0], 0, sizeof(int)*width*height);
-#if 1
- for(y=0; y<height; y++){
- for(x=0; x<width; x++){
- int tab[4]={0,2,3,1};
- buffer[0][x+width*y]= 256*256*tab[(x&1) + 2*(y&1)];
- }
- }
- ff_spatial_dwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
-#else
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- buf[x + y*stride ]=169;
- buf[x + y*stride-w]=64;
- }
- }
- ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
-#endif
- for(y=0; y<height; y++){
- for(x=0; x<width; x++){
- int64_t d= buffer[0][x + y*width];
- error += d*d;
- if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9) printf("%8"PRId64" ", d);
- }
- if(FFABS(height/2-y)<9) printf("\n");
- }
- }
-
- }
- return 0;
-}
-#endif /* TEST */
diff --git a/libavcodec/snow.h b/libavcodec/snow.h
index db61b87..bd54994 100644
--- a/libavcodec/snow.h
+++ b/libavcodec/snow.h
@@ -25,6 +25,10 @@
#include "dsputil.h"
#include "dwt.h"
+#include "rangecoder.h"
+#include "mathops.h"
+#include "mpegvideo.h"
+
#define MID_STATE 128
#define MAX_PLANES 4
@@ -36,6 +40,138 @@
#define LOG2_OBMC_MAX 8
#define OBMC_MAX (1<<(LOG2_OBMC_MAX))
+typedef struct BlockNode{
+ int16_t mx;
+ int16_t my;
+ uint8_t ref;
+ uint8_t color[3];
+ uint8_t type;
+//#define TYPE_SPLIT 1
+#define BLOCK_INTRA 1
+#define BLOCK_OPT 2
+//#define TYPE_NOCOLOR 4
+ uint8_t level; //FIXME merge into type?
+}BlockNode;
+
+static const BlockNode null_block= { //FIXME add border maybe
+ .color= {128,128,128},
+ .mx= 0,
+ .my= 0,
+ .ref= 0,
+ .type= 0,
+ .level= 0,
+};
+
+#define LOG2_MB_SIZE 4
+#define MB_SIZE (1<<LOG2_MB_SIZE)
+#define ENCODER_EXTRA_BITS 4
+#define HTAPS_MAX 8
+
+typedef struct x_and_coeff{
+ int16_t x;
+ uint16_t coeff;
+} x_and_coeff;
+
+typedef struct SubBand{
+ int level;
+ int stride;
+ int width;
+ int height;
+ int qlog; ///< log(qscale)/log[2^(1/6)]
+ DWTELEM *buf;
+ IDWTELEM *ibuf;
+ int buf_x_offset;
+ int buf_y_offset;
+ int stride_line; ///< Stride measured in lines, not pixels.
+ x_and_coeff * x_coeff;
+ struct SubBand *parent;
+ uint8_t state[/*7*2*/ 7 + 512][32];
+}SubBand;
+
+typedef struct Plane{
+ int width;
+ int height;
+ SubBand band[MAX_DECOMPOSITIONS][4];
+
+ int htaps;
+ int8_t hcoeff[HTAPS_MAX/2];
+ int diag_mc;
+ int fast_mc;
+
+ int last_htaps;
+ int8_t last_hcoeff[HTAPS_MAX/2];
+ int last_diag_mc;
+}Plane;
+
+typedef struct SnowContext{
+ AVClass *class;
+ AVCodecContext *avctx;
+ RangeCoder c;
+ DSPContext dsp;
+ DWTContext dwt;
+ AVFrame new_picture;
+ AVFrame input_picture; ///< new_picture with the internal linesizes
+ AVFrame current_picture;
+ AVFrame last_picture[MAX_REF_FRAMES];
+ uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4];
+ AVFrame mconly_picture;
+// uint8_t q_context[16];
+ uint8_t header_state[32];
+ uint8_t block_state[128 + 32*128];
+ int keyframe;
+ int always_reset;
+ int version;
+ int spatial_decomposition_type;
+ int last_spatial_decomposition_type;
+ int temporal_decomposition_type;
+ int spatial_decomposition_count;
+ int last_spatial_decomposition_count;
+ int temporal_decomposition_count;
+ int max_ref_frames;
+ int ref_frames;
+ int16_t (*ref_mvs[MAX_REF_FRAMES])[2];
+ uint32_t *ref_scores[MAX_REF_FRAMES];
+ DWTELEM *spatial_dwt_buffer;
+ IDWTELEM *spatial_idwt_buffer;
+ int colorspace_type;
+ int chroma_h_shift;
+ int chroma_v_shift;
+ int spatial_scalability;
+ int qlog;
+ int last_qlog;
+ int lambda;
+ int lambda2;
+ int pass1_rc;
+ int mv_scale;
+ int last_mv_scale;
+ int qbias;
+ int last_qbias;
+#define QBIAS_SHIFT 3
+ int b_width;
+ int b_height;
+ int block_max_depth;
+ int last_block_max_depth;
+ Plane plane[MAX_PLANES];
+ BlockNode *block;
+#define ME_CACHE_SIZE 1024
+ unsigned me_cache[ME_CACHE_SIZE];
+ unsigned me_cache_generation;
+ slice_buffer sb;
+ int memc_only;
+
+ MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
+
+ uint8_t *scratchbuf;
+}SnowContext;
+
+/* Tables */
+extern const uint8_t * const obmc_tab[4];
+#ifdef __sgi
+// Avoid a name clash on SGI IRIX
+#undef qexp
+#endif
+extern uint8_t qexp[QROOT];
+extern int scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
/* C bits used by mmx/sse2/altivec */
@@ -75,4 +211,482 @@ static av_always_inline void snow_horizontal_compose_liftS_lead_out(int i, IDWTE
}
}
+/* common code */
+
+int ff_snow_common_init(AVCodecContext *avctx);
+int ff_snow_common_init_after_header(AVCodecContext *avctx);
+void ff_snow_common_end(SnowContext *s);
+void ff_snow_release_buffer(AVCodecContext *avctx);
+void ff_snow_reset_contexts(SnowContext *s);
+int ff_snow_alloc_blocks(SnowContext *s);
+int ff_snow_frame_start(SnowContext *s);
+void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride,
+ int sx, int sy, int b_w, int b_h, BlockNode *block,
+ int plane_index, int w, int h);
+/* common inline functions */
+//XXX doublecheck all of them should stay inlined
+
+static inline void snow_set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
+ const int w= s->b_width << s->block_max_depth;
+ const int rem_depth= s->block_max_depth - level;
+ const int index= (x + y*w) << rem_depth;
+ const int block_w= 1<<rem_depth;
+ BlockNode block;
+ int i,j;
+
+ block.color[0]= l;
+ block.color[1]= cb;
+ block.color[2]= cr;
+ block.mx= mx;
+ block.my= my;
+ block.ref= ref;
+ block.type= type;
+ block.level= level;
+
+ for(j=0; j<block_w; j++){
+ for(i=0; i<block_w; i++){
+ s->block[index + i + j*w]= block;
+ }
+ }
+}
+
+static inline void pred_mv(SnowContext *s, int *mx, int *my, int ref,
+ const BlockNode *left, const BlockNode *top, const BlockNode *tr){
+ if(s->ref_frames == 1){
+ *mx = mid_pred(left->mx, top->mx, tr->mx);
+ *my = mid_pred(left->my, top->my, tr->my);
+ }else{
+ const int *scale = scale_mv_ref[ref];
+ *mx = mid_pred((left->mx * scale[left->ref] + 128) >>8,
+ (top ->mx * scale[top ->ref] + 128) >>8,
+ (tr ->mx * scale[tr ->ref] + 128) >>8);
+ *my = mid_pred((left->my * scale[left->ref] + 128) >>8,
+ (top ->my * scale[top ->ref] + 128) >>8,
+ (tr ->my * scale[tr ->ref] + 128) >>8);
+ }
+}
+
+static av_always_inline int same_block(BlockNode *a, BlockNode *b){
+ if((a->type&BLOCK_INTRA) && (b->type&BLOCK_INTRA)){
+ return !((a->color[0] - b->color[0]) | (a->color[1] - b->color[1]) | (a->color[2] - b->color[2]));
+ }else{
+ return !((a->mx - b->mx) | (a->my - b->my) | (a->ref - b->ref) | ((a->type ^ b->type)&BLOCK_INTRA));
+ }
+}
+
+//FIXME name cleanup (b_w, block_w, b_width stuff)
+//XXX should we really inline it?
+static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, IDWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){
+ const int b_width = s->b_width << s->block_max_depth;
+ const int b_height= s->b_height << s->block_max_depth;
+ const int b_stride= b_width;
+ BlockNode *lt= &s->block[b_x + b_y*b_stride];
+ BlockNode *rt= lt+1;
+ BlockNode *lb= lt+b_stride;
+ BlockNode *rb= lb+1;
+ uint8_t *block[4];
+ int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride;
+ uint8_t *tmp = s->scratchbuf;
+ uint8_t *ptmp;
+ int x,y;
+
+ if(b_x<0){
+ lt= rt;
+ lb= rb;
+ }else if(b_x + 1 >= b_width){
+ rt= lt;
+ rb= lb;
+ }
+ if(b_y<0){
+ lt= lb;
+ rt= rb;
+ }else if(b_y + 1 >= b_height){
+ lb= lt;
+ rb= rt;
+ }
+
+ if(src_x<0){ //FIXME merge with prev & always round internal width up to *16
+ obmc -= src_x;
+ b_w += src_x;
+ if(!sliced && !offset_dst)
+ dst -= src_x;
+ src_x=0;
+ }else if(src_x + b_w > w){
+ b_w = w - src_x;
+ }
+ if(src_y<0){
+ obmc -= src_y*obmc_stride;
+ b_h += src_y;
+ if(!sliced && !offset_dst)
+ dst -= src_y*dst_stride;
+ src_y=0;
+ }else if(src_y + b_h> h){
+ b_h = h - src_y;
+ }
+
+ if(b_w<=0 || b_h<=0) return;
+
+ assert(src_stride > 2*MB_SIZE + 5);
+
+ if(!sliced && offset_dst)
+ dst += src_x + src_y*dst_stride;
+ dst8+= src_x + src_y*src_stride;
+// src += src_x + src_y*src_stride;
+
+ ptmp= tmp + 3*tmp_step;
+ block[0]= ptmp;
+ ptmp+=tmp_step;
+ ff_snow_pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h);
+
+ if(same_block(lt, rt)){
+ block[1]= block[0];
+ }else{
+ block[1]= ptmp;
+ ptmp+=tmp_step;
+ ff_snow_pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h);
+ }
+
+ if(same_block(lt, lb)){
+ block[2]= block[0];
+ }else if(same_block(rt, lb)){
+ block[2]= block[1];
+ }else{
+ block[2]= ptmp;
+ ptmp+=tmp_step;
+ ff_snow_pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h);
+ }
+
+ if(same_block(lt, rb) ){
+ block[3]= block[0];
+ }else if(same_block(rt, rb)){
+ block[3]= block[1];
+ }else if(same_block(lb, rb)){
+ block[3]= block[2];
+ }else{
+ block[3]= ptmp;
+ ff_snow_pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h);
+ }
+ if(sliced){
+ s->dwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
+ }else{
+ for(y=0; y<b_h; y++){
+ //FIXME ugly misuse of obmc_stride
+ const uint8_t *obmc1= obmc + y*obmc_stride;
+ const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
+ const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
+ const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
+ for(x=0; x<b_w; x++){
+ int v= obmc1[x] * block[3][x + y*src_stride]
+ +obmc2[x] * block[2][x + y*src_stride]
+ +obmc3[x] * block[1][x + y*src_stride]
+ +obmc4[x] * block[0][x + y*src_stride];
+
+ v <<= 8 - LOG2_OBMC_MAX;
+ if(FRAC_BITS != 8){
+ v >>= 8 - FRAC_BITS;
+ }
+ if(add){
+ v += dst[x + y*dst_stride];
+ v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
+ if(v&(~255)) v= ~(v>>31);
+ dst8[x + y*src_stride] = v;
+ }else{
+ dst[x + y*dst_stride] -= v;
+ }
+ }
+ }
+ }
+}
+
+static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int plane_index, int add, int mb_y){
+ Plane *p= &s->plane[plane_index];
+ const int mb_w= s->b_width << s->block_max_depth;
+ const int mb_h= s->b_height << s->block_max_depth;
+ int x, y, mb_x;
+ int block_size = MB_SIZE >> s->block_max_depth;
+ int block_w = plane_index ? block_size/2 : block_size;
+ const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
+ const int obmc_stride= plane_index ? block_size : 2*block_size;
+ int ref_stride= s->current_picture.linesize[plane_index];
+ uint8_t *dst8= s->current_picture.data[plane_index];
+ int w= p->width;
+ int h= p->height;
+
+ if(s->keyframe || (s->avctx->debug&512)){
+ if(mb_y==mb_h)
+ return;
+
+ if(add){
+ for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
+ for(x=0; x<w; x++){
+ int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
+ v >>= FRAC_BITS;
+ if(v&(~255)) v= ~(v>>31);
+ dst8[x + y*ref_stride]= v;
+ }
+ }
+ }else{
+ for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
+ for(x=0; x<w; x++){
+ buf[x + y*w]-= 128<<FRAC_BITS;
+ }
+ }
+ }
+
+ return;
+ }
+
+ for(mb_x=0; mb_x<=mb_w; mb_x++){
+ add_yblock(s, 0, NULL, buf, dst8, obmc,
+ block_w*mb_x - block_w/2,
+ block_w*mb_y - block_w/2,
+ block_w, block_w,
+ w, h,
+ w, ref_stride, obmc_stride,
+ mb_x - 1, mb_y - 1,
+ add, 1, plane_index);
+ }
+}
+
+static av_always_inline void predict_plane(SnowContext *s, IDWTELEM *buf, int plane_index, int add){
+ const int mb_h= s->b_height << s->block_max_depth;
+ int mb_y;
+ for(mb_y=0; mb_y<=mb_h; mb_y++)
+ predict_slice(s, buf, plane_index, add, mb_y);
+}
+
+static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
+ const int w= s->b_width << s->block_max_depth;
+ const int rem_depth= s->block_max_depth - level;
+ const int index= (x + y*w) << rem_depth;
+ const int block_w= 1<<rem_depth;
+ BlockNode block;
+ int i,j;
+
+ block.color[0]= l;
+ block.color[1]= cb;
+ block.color[2]= cr;
+ block.mx= mx;
+ block.my= my;
+ block.ref= ref;
+ block.type= type;
+ block.level= level;
+
+ for(j=0; j<block_w; j++){
+ for(i=0; i<block_w; i++){
+ s->block[index + i + j*w]= block;
+ }
+ }
+}
+
+static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){
+ const int offset[3]= {
+ y*c-> stride + x,
+ ((y*c->uvstride + x)>>1),
+ ((y*c->uvstride + x)>>1),
+ };
+ int i;
+ for(i=0; i<3; i++){
+ c->src[0][i]= src [i];
+ c->ref[0][i]= ref [i] + offset[i];
+ }
+ assert(!ref_index);
+}
+
+
+/* bitstream functions */
+
+extern const int8_t quant3bA[256];
+
+#define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0
+
+static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
+ int i;
+
+ if(v){
+ const int a= FFABS(v);
+ const int e= av_log2(a);
+ const int el= FFMIN(e, 10);
+ put_rac(c, state+0, 0);
+
+ for(i=0; i<el; i++){
+ put_rac(c, state+1+i, 1); //1..10
+ }
+ for(; i<e; i++){
+ put_rac(c, state+1+9, 1); //1..10
+ }
+ put_rac(c, state+1+FFMIN(i,9), 0);
+
+ for(i=e-1; i>=el; i--){
+ put_rac(c, state+22+9, (a>>i)&1); //22..31
+ }
+ for(; i>=0; i--){
+ put_rac(c, state+22+i, (a>>i)&1); //22..31
+ }
+
+ if(is_signed)
+ put_rac(c, state+11 + el, v < 0); //11..21
+ }else{
+ put_rac(c, state+0, 1);
+ }
+}
+
+static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
+ if(get_rac(c, state+0))
+ return 0;
+ else{
+ int i, e, a;
+ e= 0;
+ while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10
+ e++;
+ }
+
+ a= 1;
+ for(i=e-1; i>=0; i--){
+ a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31
+ }
+
+ e= -(is_signed && get_rac(c, state+11 + FFMIN(e,10))); //11..21
+ return (a^e)-e;
+ }
+}
+
+static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){
+ int i;
+ int r= log2>=0 ? 1<<log2 : 1;
+
+ assert(v>=0);
+ assert(log2>=-4);
+
+ while(v >= r){
+ put_rac(c, state+4+log2, 1);
+ v -= r;
+ log2++;
+ if(log2>0) r+=r;
+ }
+ put_rac(c, state+4+log2, 0);
+
+ for(i=log2-1; i>=0; i--){
+ put_rac(c, state+31-i, (v>>i)&1);
+ }
+}
+
+static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){
+ int i;
+ int r= log2>=0 ? 1<<log2 : 1;
+ int v=0;
+
+ assert(log2>=-4);
+
+ while(get_rac(c, state+4+log2)){
+ v+= r;
+ log2++;
+ if(log2>0) r+=r;
+ }
+
+ for(i=log2-1; i>=0; i--){
+ v+= get_rac(c, state+31-i)<<i;
+ }
+
+ return v;
+}
+
+static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, int orientation){
+ const int w= b->width;
+ const int h= b->height;
+ int x,y;
+
+ int run, runs;
+ x_and_coeff *xc= b->x_coeff;
+ x_and_coeff *prev_xc= NULL;
+ x_and_coeff *prev2_xc= xc;
+ x_and_coeff *parent_xc= parent ? parent->x_coeff : NULL;
+ x_and_coeff *prev_parent_xc= parent_xc;
+
+ runs= get_symbol2(&s->c, b->state[30], 0);
+ if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
+ else run= INT_MAX;
+
+ for(y=0; y<h; y++){
+ int v=0;
+ int lt=0, t=0, rt=0;
+
+ if(y && prev_xc->x == 0){
+ rt= prev_xc->coeff;
+ }
+ for(x=0; x<w; x++){
+ int p=0;
+ const int l= v;
+
+ lt= t; t= rt;
+
+ if(y){
+ if(prev_xc->x <= x)
+ prev_xc++;
+ if(prev_xc->x == x + 1)
+ rt= prev_xc->coeff;
+ else
+ rt=0;
+ }
+ if(parent_xc){
+ if(x>>1 > parent_xc->x){
+ parent_xc++;
+ }
+ if(x>>1 == parent_xc->x){
+ p= parent_xc->coeff;
+ }
+ }
+ if(/*ll|*/l|lt|t|rt|p){
+ int context= av_log2(/*FFABS(ll) + */3*(l>>1) + (lt>>1) + (t&~1) + (rt>>1) + (p>>1));
+
+ v=get_rac(&s->c, &b->state[0][context]);
+ if(v){
+ v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1);
+ v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3bA[l&0xFF] + 3*quant3bA[t&0xFF]]);
+
+ xc->x=x;
+ (xc++)->coeff= v;
+ }
+ }else{
+ if(!run){
+ if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
+ else run= INT_MAX;
+ v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1);
+ v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]);
+
+ xc->x=x;
+ (xc++)->coeff= v;
+ }else{
+ int max_run;
+ run--;
+ v=0;
+
+ if(y) max_run= FFMIN(run, prev_xc->x - x - 2);
+ else max_run= FFMIN(run, w-x-1);
+ if(parent_xc)
+ max_run= FFMIN(max_run, 2*parent_xc->x - x - 1);
+ x+= max_run;
+ run-= max_run;
+ }
+ }
+ }
+ (xc++)->x= w+1; //end marker
+ prev_xc= prev2_xc;
+ prev2_xc= xc;
+
+ if(parent_xc){
+ if(y&1){
+ while(parent_xc->x != parent->width+1)
+ parent_xc++;
+ parent_xc++;
+ prev_parent_xc= parent_xc;
+ }else{
+ parent_xc= prev_parent_xc;
+ }
+ }
+ }
+
+ (xc++)->x= w+1; //end marker
+}
+
#endif /* AVCODEC_SNOW_H */
diff --git a/libavcodec/snowdata.h b/libavcodec/snowdata.h
new file mode 100644
index 0000000..ca2468c
--- /dev/null
+++ b/libavcodec/snowdata.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
+ * Copyright (C) 2006 Robert Edele <yartrebo at earthlink.net>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_SNOWDATA_H
+#define AVCODEC_SNOWDATA_H
+
+#include "snow.h"
+
+static const uint8_t obmc32[1024]={
+ 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
+ 0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
+ 0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
+ 0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
+ 4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
+ 4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
+ 4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
+ 4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
+ 4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
+ 4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
+ 4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
+ 4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
+ 8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
+ 8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
+ 8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
+ 8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
+ 8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
+ 8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
+ 8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
+ 8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
+ 4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
+ 4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
+ 4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
+ 4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
+ 4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
+ 4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
+ 4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
+ 4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
+ 0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
+ 0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
+ 0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
+ 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
+ //error:0.000020
+};
+static const uint8_t obmc16[256]={
+ 0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
+ 4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
+ 4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
+ 8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
+ 8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
+ 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
+ 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
+ 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
+ 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
+ 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
+ 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
+ 8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
+ 8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
+ 4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
+ 4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
+ 0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
+//error:0.000015
+};
+
+//linear *64
+static const uint8_t obmc8[64]={
+ 4, 12, 20, 28, 28, 20, 12, 4,
+ 12, 36, 60, 84, 84, 60, 36, 12,
+ 20, 60,100,140,140,100, 60, 20,
+ 28, 84,140,196,196,140, 84, 28,
+ 28, 84,140,196,196,140, 84, 28,
+ 20, 60,100,140,140,100, 60, 20,
+ 12, 36, 60, 84, 84, 60, 36, 12,
+ 4, 12, 20, 28, 28, 20, 12, 4,
+//error:0.000000
+};
+
+//linear *64
+static const uint8_t obmc4[16]={
+ 16, 48, 48, 16,
+ 48,144,144, 48,
+ 48,144,144, 48,
+ 16, 48, 48, 16,
+//error:0.000000
+};
+
+const int8_t quant3bA[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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+};
+
+const uint8_t * const obmc_tab[4]= {
+ obmc32, obmc16, obmc8, obmc4
+};
+
+/* runtime generated tables */
+uint8_t qexp[QROOT];
+int scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
+
+
+#endif /* AVCODEC_SNOW_H */
diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c
new file mode 100644
index 0000000..2b6f6e1
--- /dev/null
+++ b/libavcodec/snowdec.c
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intmath.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "dsputil.h"
+#include "dwt.h"
+#include "snow.h"
+
+#include "rangecoder.h"
+#include "mathops.h"
+
+#include "mpegvideo.h"
+#include "h263.h"
+
+#undef NDEBUG
+#include <assert.h>
+
+static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){
+ Plane *p= &s->plane[plane_index];
+ const int mb_w= s->b_width << s->block_max_depth;
+ const int mb_h= s->b_height << s->block_max_depth;
+ int x, y, mb_x;
+ int block_size = MB_SIZE >> s->block_max_depth;
+ int block_w = plane_index ? block_size/2 : block_size;
+ const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
+ int obmc_stride= plane_index ? block_size : 2*block_size;
+ int ref_stride= s->current_picture.linesize[plane_index];
+ uint8_t *dst8= s->current_picture.data[plane_index];
+ int w= p->width;
+ int h= p->height;
+
+ if(s->keyframe || (s->avctx->debug&512)){
+ if(mb_y==mb_h)
+ return;
+
+ if(add){
+ for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
+// DWTELEM * line = slice_buffer_get_line(sb, y);
+ IDWTELEM * line = sb->line[y];
+ for(x=0; x<w; x++){
+// int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
+ int v= line[x] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
+ v >>= FRAC_BITS;
+ if(v&(~255)) v= ~(v>>31);
+ dst8[x + y*ref_stride]= v;
+ }
+ }
+ }else{
+ for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
+// DWTELEM * line = slice_buffer_get_line(sb, y);
+ IDWTELEM * line = sb->line[y];
+ for(x=0; x<w; x++){
+ line[x] -= 128 << FRAC_BITS;
+// buf[x + y*w]-= 128<<FRAC_BITS;
+ }
+ }
+ }
+
+ return;
+ }
+
+ for(mb_x=0; mb_x<=mb_w; mb_x++){
+ add_yblock(s, 1, sb, old_buffer, dst8, obmc,
+ block_w*mb_x - block_w/2,
+ block_w*mb_y - block_w/2,
+ block_w, block_w,
+ w, h,
+ w, ref_stride, obmc_stride,
+ mb_x - 1, mb_y - 1,
+ add, 0, plane_index);
+ }
+}
+
+static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, slice_buffer * sb, int start_y, int h, int save_state[1]){
+ const int w= b->width;
+ int y;
+ const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
+ int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
+ int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
+ int new_index = 0;
+
+ if(b->ibuf == s->spatial_idwt_buffer || s->qlog == LOSSLESS_QLOG){
+ qadd= 0;
+ qmul= 1<<QEXPSHIFT;
+ }
+
+ /* If we are on the second or later slice, restore our index. */
+ if (start_y != 0)
+ new_index = save_state[0];
+
+
+ for(y=start_y; y<h; y++){
+ int x = 0;
+ int v;
+ IDWTELEM * line = slice_buffer_get_line(sb, y * b->stride_line + b->buf_y_offset) + b->buf_x_offset;
+ memset(line, 0, b->width*sizeof(IDWTELEM));
+ v = b->x_coeff[new_index].coeff;
+ x = b->x_coeff[new_index++].x;
+ while(x < w){
+ register int t= ( (v>>1)*qmul + qadd)>>QEXPSHIFT;
+ register int u= -(v&1);
+ line[x] = (t^u) - u;
+
+ v = b->x_coeff[new_index].coeff;
+ x = b->x_coeff[new_index++].x;
+ }
+ }
+
+ /* Save our variables for the next slice. */
+ save_state[0] = new_index;
+
+ return;
+}
+
+static void decode_q_branch(SnowContext *s, int level, int x, int y){
+ const int w= s->b_width << s->block_max_depth;
+ const int rem_depth= s->block_max_depth - level;
+ const int index= (x + y*w) << rem_depth;
+ int trx= (x+1)<<rem_depth;
+ const BlockNode *left = x ? &s->block[index-1] : &null_block;
+ const BlockNode *top = y ? &s->block[index-w] : &null_block;
+ const BlockNode *tl = y && x ? &s->block[index-w-1] : left;
+ const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
+ int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
+
+ if(s->keyframe){
+ set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA);
+ return;
+ }
+
+ if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){
+ int type, mx, my;
+ int l = left->color[0];
+ int cb= left->color[1];
+ int cr= left->color[2];
+ int ref = 0;
+ int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
+ int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx));
+ int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my));
+
+ type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;
+
+ if(type){
+ pred_mv(s, &mx, &my, 0, left, top, tr);
+ l += get_symbol(&s->c, &s->block_state[32], 1);
+ cb+= get_symbol(&s->c, &s->block_state[64], 1);
+ cr+= get_symbol(&s->c, &s->block_state[96], 1);
+ }else{
+ if(s->ref_frames > 1)
+ ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);
+ pred_mv(s, &mx, &my, ref, left, top, tr);
+ mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);
+ my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1);
+ }
+ set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type);
+ }else{
+ decode_q_branch(s, level+1, 2*x+0, 2*y+0);
+ decode_q_branch(s, level+1, 2*x+1, 2*y+0);
+ decode_q_branch(s, level+1, 2*x+0, 2*y+1);
+ decode_q_branch(s, level+1, 2*x+1, 2*y+1);
+ }
+}
+
+static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int start_y, int end_y){
+ const int w= b->width;
+ const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
+ const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
+ const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
+ int x,y;
+
+ if(s->qlog == LOSSLESS_QLOG) return;
+
+ for(y=start_y; y<end_y; y++){
+// DWTELEM * line = slice_buffer_get_line_from_address(sb, src + (y * stride));
+ IDWTELEM * line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
+ for(x=0; x<w; x++){
+ int i= line[x];
+ if(i<0){
+ line[x]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
+ }else if(i>0){
+ line[x]= (( i*qmul + qadd)>>(QEXPSHIFT));
+ }
+ }
+ }
+}
+
+static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){
+ const int w= b->width;
+ int x,y;
+
+ IDWTELEM * line=0; // silence silly "could be used without having been initialized" warning
+ IDWTELEM * prev;
+
+ if (start_y != 0)
+ line = slice_buffer_get_line(sb, ((start_y - 1) * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
+
+ for(y=start_y; y<end_y; y++){
+ prev = line;
+// line = slice_buffer_get_line_from_address(sb, src + (y * stride));
+ line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
+ for(x=0; x<w; x++){
+ if(x){
+ if(use_median){
+ if(y && x+1<w) line[x] += mid_pred(line[x - 1], prev[x], prev[x + 1]);
+ else line[x] += line[x - 1];
+ }else{
+ if(y) line[x] += mid_pred(line[x - 1], prev[x], line[x - 1] + prev[x] - prev[x - 1]);
+ else line[x] += line[x - 1];
+ }
+ }else{
+ if(y) line[x] += prev[x];
+ }
+ }
+ }
+}
+
+static void decode_qlogs(SnowContext *s){
+ int plane_index, level, orientation;
+
+ for(plane_index=0; plane_index<3; plane_index++){
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1:0; orientation<4; orientation++){
+ int q;
+ if (plane_index==2) q= s->plane[1].band[level][orientation].qlog;
+ else if(orientation==2) q= s->plane[plane_index].band[level][1].qlog;
+ else q= get_symbol(&s->c, s->header_state, 1);
+ s->plane[plane_index].band[level][orientation].qlog= q;
+ }
+ }
+ }
+}
+
+#define GET_S(dst, check) \
+ tmp= get_symbol(&s->c, s->header_state, 0);\
+ if(!(check)){\
+ av_log(s->avctx, AV_LOG_ERROR, "Error " #dst " is %d\n", tmp);\
+ return -1;\
+ }\
+ dst= tmp;
+
+static int decode_header(SnowContext *s){
+ int plane_index, tmp;
+ uint8_t kstate[32];
+
+ memset(kstate, MID_STATE, sizeof(kstate));
+
+ s->keyframe= get_rac(&s->c, kstate);
+ if(s->keyframe || s->always_reset){
+ ff_snow_reset_contexts(s);
+ s->spatial_decomposition_type=
+ s->qlog=
+ s->qbias=
+ s->mv_scale=
+ s->block_max_depth= 0;
+ }
+ if(s->keyframe){
+ GET_S(s->version, tmp <= 0U)
+ s->always_reset= get_rac(&s->c, s->header_state);
+ s->temporal_decomposition_type= get_symbol(&s->c, s->header_state, 0);
+ s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0);
+ GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
+ s->colorspace_type= get_symbol(&s->c, s->header_state, 0);
+ s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0);
+ s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0);
+ s->spatial_scalability= get_rac(&s->c, s->header_state);
+// s->rate_scalability= get_rac(&s->c, s->header_state);
+ GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES)
+ s->max_ref_frames++;
+
+ decode_qlogs(s);
+ }
+
+ if(!s->keyframe){
+ if(get_rac(&s->c, s->header_state)){
+ for(plane_index=0; plane_index<2; plane_index++){
+ int htaps, i, sum=0;
+ Plane *p= &s->plane[plane_index];
+ p->diag_mc= get_rac(&s->c, s->header_state);
+ htaps= get_symbol(&s->c, s->header_state, 0)*2 + 2;
+ if((unsigned)htaps > HTAPS_MAX || htaps==0)
+ return -1;
+ p->htaps= htaps;
+ for(i= htaps/2; i; i--){
+ p->hcoeff[i]= get_symbol(&s->c, s->header_state, 0) * (1-2*(i&1));
+ sum += p->hcoeff[i];
+ }
+ p->hcoeff[0]= 32-sum;
+ }
+ s->plane[2].diag_mc= s->plane[1].diag_mc;
+ s->plane[2].htaps = s->plane[1].htaps;
+ memcpy(s->plane[2].hcoeff, s->plane[1].hcoeff, sizeof(s->plane[1].hcoeff));
+ }
+ if(get_rac(&s->c, s->header_state)){
+ GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
+ decode_qlogs(s);
+ }
+ }
+
+ s->spatial_decomposition_type+= get_symbol(&s->c, s->header_state, 1);
+ if(s->spatial_decomposition_type > 1U){
+ av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported", s->spatial_decomposition_type);
+ return -1;
+ }
+ if(FFMIN(s->avctx-> width>>s->chroma_h_shift,
+ s->avctx->height>>s->chroma_v_shift) >> (s->spatial_decomposition_count-1) <= 0){
+ av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_count %d too large for size", s->spatial_decomposition_count);
+ return -1;
+ }
+
+ s->qlog += get_symbol(&s->c, s->header_state, 1);
+ s->mv_scale += get_symbol(&s->c, s->header_state, 1);
+ s->qbias += get_symbol(&s->c, s->header_state, 1);
+ s->block_max_depth+= get_symbol(&s->c, s->header_state, 1);
+ if(s->block_max_depth > 1 || s->block_max_depth < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large", s->block_max_depth);
+ s->block_max_depth= 0;
+ return -1;
+ }
+
+ return 0;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ avctx->pix_fmt= PIX_FMT_YUV420P;
+
+ ff_snow_common_init(avctx);
+
+ return 0;
+}
+
+static void decode_blocks(SnowContext *s){
+ int x, y;
+ int w= s->b_width;
+ int h= s->b_height;
+
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ decode_q_branch(s, 0, x, y);
+ }
+ }
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt){
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ SnowContext *s = avctx->priv_data;
+ RangeCoder * const c= &s->c;
+ int bytes_read;
+ AVFrame *picture = data;
+ int level, orientation, plane_index;
+
+ ff_init_range_decoder(c, buf, buf_size);
+ ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
+
+ s->current_picture.pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P
+ if(decode_header(s)<0)
+ return -1;
+ ff_snow_common_init_after_header(avctx);
+
+ // realloc slice buffer for the case that spatial_decomposition_count changed
+ ff_slice_buffer_destroy(&s->sb);
+ ff_slice_buffer_init(&s->sb, s->plane[0].height, (MB_SIZE >> s->block_max_depth) + s->spatial_decomposition_count * 8 + 1, s->plane[0].width, s->spatial_idwt_buffer);
+
+ for(plane_index=0; plane_index<3; plane_index++){
+ Plane *p= &s->plane[plane_index];
+ p->fast_mc= p->diag_mc && p->htaps==6 && p->hcoeff[0]==40
+ && p->hcoeff[1]==-10
+ && p->hcoeff[2]==2;
+ }
+
+ ff_snow_alloc_blocks(s);
+
+ if(ff_snow_frame_start(s) < 0)
+ return -1;
+ //keyframe flag duplication mess FIXME
+ if(avctx->debug&FF_DEBUG_PICT_INFO)
+ av_log(avctx, AV_LOG_ERROR, "keyframe:%d qlog:%d\n", s->keyframe, s->qlog);
+
+ decode_blocks(s);
+
+ for(plane_index=0; plane_index<3; plane_index++){
+ Plane *p= &s->plane[plane_index];
+ int w= p->width;
+ int h= p->height;
+ int x, y;
+ int decode_state[MAX_DECOMPOSITIONS][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */
+
+ if(s->avctx->debug&2048){
+ memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h);
+ predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
+
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ int v= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x];
+ s->mconly_picture.data[plane_index][y*s->mconly_picture.linesize[plane_index] + x]= v;
+ }
+ }
+ }
+
+ {
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &p->band[level][orientation];
+ unpack_coeffs(s, b, b->parent, orientation);
+ }
+ }
+ }
+
+ {
+ const int mb_h= s->b_height << s->block_max_depth;
+ const int block_size = MB_SIZE >> s->block_max_depth;
+ const int block_w = plane_index ? block_size/2 : block_size;
+ int mb_y;
+ DWTCompose cs[MAX_DECOMPOSITIONS];
+ int yd=0, yq=0;
+ int y;
+ int end_y;
+
+ ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count);
+ for(mb_y=0; mb_y<=mb_h; mb_y++){
+
+ int slice_starty = block_w*mb_y;
+ int slice_h = block_w*(mb_y+1);
+ if (!(s->keyframe || s->avctx->debug&512)){
+ slice_starty = FFMAX(0, slice_starty - (block_w >> 1));
+ slice_h -= (block_w >> 1);
+ }
+
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &p->band[level][orientation];
+ int start_y;
+ int end_y;
+ int our_mb_start = mb_y;
+ int our_mb_end = (mb_y + 1);
+ const int extra= 3;
+ start_y = (mb_y ? ((block_w * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0);
+ end_y = (((block_w * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra);
+ if (!(s->keyframe || s->avctx->debug&512)){
+ start_y = FFMAX(0, start_y - (block_w >> (1+s->spatial_decomposition_count - level)));
+ end_y = FFMAX(0, end_y - (block_w >> (1+s->spatial_decomposition_count - level)));
+ }
+ start_y = FFMIN(b->height, start_y);
+ end_y = FFMIN(b->height, end_y);
+
+ if (start_y != end_y){
+ if (orientation == 0){
+ SubBand * correlate_band = &p->band[0][0];
+ int correlate_end_y = FFMIN(b->height, end_y + 1);
+ int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0));
+ decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]);
+ correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y);
+ dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, start_y, end_y);
+ }
+ else
+ decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]);
+ }
+ }
+ }
+
+ for(; yd<slice_h; yd+=4){
+ ff_spatial_idwt_buffered_slice(&s->dwt, cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd);
+ }
+
+ if(s->qlog == LOSSLESS_QLOG){
+ for(; yq<slice_h && yq<h; yq++){
+ IDWTELEM * line = slice_buffer_get_line(&s->sb, yq);
+ for(x=0; x<w; x++){
+ line[x] <<= FRAC_BITS;
+ }
+ }
+ }
+
+ predict_slice_buffered(s, &s->sb, s->spatial_idwt_buffer, plane_index, 1, mb_y);
+
+ y = FFMIN(p->height, slice_starty);
+ end_y = FFMIN(p->height, slice_h);
+ while(y < end_y)
+ ff_slice_buffer_release(&s->sb, y++);
+ }
+
+ ff_slice_buffer_flush(&s->sb);
+ }
+
+ }
+
+ emms_c();
+
+ ff_snow_release_buffer(avctx);
+
+ if(!(s->avctx->debug&2048))
+ *picture= s->current_picture;
+ else
+ *picture= s->mconly_picture;
+
+ *data_size = sizeof(AVFrame);
+
+ bytes_read= c->bytestream - c->bytestream_start;
+ if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n"); //FIXME
+
+ return bytes_read;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ SnowContext *s = avctx->priv_data;
+
+ ff_slice_buffer_destroy(&s->sb);
+
+ ff_snow_common_end(s);
+
+ return 0;
+}
+
+AVCodec ff_snow_decoder = {
+ .name = "snow",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SNOW,
+ .priv_data_size = sizeof(SnowContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
+ .long_name = NULL_IF_CONFIG_SMALL("Snow"),
+};
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
new file mode 100644
index 0000000..cd60c3a
--- /dev/null
+++ b/libavcodec/snowenc.c
@@ -0,0 +1,1917 @@
+/*
+ * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intmath.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "dsputil.h"
+#include "dwt.h"
+#include "snow.h"
+
+#include "rangecoder.h"
+#include "mathops.h"
+
+#include "mpegvideo.h"
+#include "h263.h"
+
+#undef NDEBUG
+#include <assert.h>
+
+#define QUANTIZE2 0
+
+#if QUANTIZE2==1
+#define Q2_STEP 8
+
+static void find_sse(SnowContext *s, Plane *p, int *score, int score_stride, IDWTELEM *r0, IDWTELEM *r1, int level, int orientation){
+ SubBand *b= &p->band[level][orientation];
+ int x, y;
+ int xo=0;
+ int yo=0;
+ int step= 1 << (s->spatial_decomposition_count - level);
+
+ if(orientation&1)
+ xo= step>>1;
+ if(orientation&2)
+ yo= step>>1;
+
+ //FIXME bias for nonzero ?
+ //FIXME optimize
+ memset(score, 0, sizeof(*score)*score_stride*((p->height + Q2_STEP-1)/Q2_STEP));
+ for(y=0; y<p->height; y++){
+ for(x=0; x<p->width; x++){
+ int sx= (x-xo + step/2) / step / Q2_STEP;
+ int sy= (y-yo + step/2) / step / Q2_STEP;
+ int v= r0[x + y*p->width] - r1[x + y*p->width];
+ assert(sx>=0 && sy>=0 && sx < score_stride);
+ v= ((v+8)>>4)<<4;
+ score[sx + sy*score_stride] += v*v;
+ assert(score[sx + sy*score_stride] >= 0);
+ }
+ }
+}
+
+static void dequantize_all(SnowContext *s, Plane *p, IDWTELEM *buffer, int width, int height){
+ int level, orientation;
+
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &p->band[level][orientation];
+ IDWTELEM *dst= buffer + (b->ibuf - s->spatial_idwt_buffer);
+
+ dequantize(s, b, dst, b->stride);
+ }
+ }
+}
+
+static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, int height, int stride, int type){
+ int level, orientation, ys, xs, x, y, pass;
+ IDWTELEM best_dequant[height * stride];
+ IDWTELEM idwt2_buffer[height * stride];
+ const int score_stride= (width + 10)/Q2_STEP;
+ int best_score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size
+ int score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size
+ int threshold= (s->m.lambda * s->m.lambda) >> 6;
+
+ //FIXME pass the copy cleanly ?
+
+// memcpy(dwt_buffer, buffer, height * stride * sizeof(DWTELEM));
+ ff_spatial_dwt(buffer, width, height, stride, type, s->spatial_decomposition_count);
+
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &p->band[level][orientation];
+ IDWTELEM *dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer);
+ DWTELEM *src= buffer + (b-> buf - s->spatial_dwt_buffer);
+ assert(src == b->buf); // code does not depend on this but it is true currently
+
+ quantize(s, b, dst, src, b->stride, s->qbias);
+ }
+ }
+ for(pass=0; pass<1; pass++){
+ if(s->qbias == 0) //keyframe
+ continue;
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &p->band[level][orientation];
+ IDWTELEM *dst= idwt2_buffer + (b->ibuf - s->spatial_idwt_buffer);
+ IDWTELEM *best_dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer);
+
+ for(ys= 0; ys<Q2_STEP; ys++){
+ for(xs= 0; xs<Q2_STEP; xs++){
+ memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM));
+ dequantize_all(s, p, idwt2_buffer, width, height);
+ ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count);
+ find_sse(s, p, best_score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation);
+ memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM));
+ for(y=ys; y<b->height; y+= Q2_STEP){
+ for(x=xs; x<b->width; x+= Q2_STEP){
+ if(dst[x + y*b->stride]<0) dst[x + y*b->stride]++;
+ if(dst[x + y*b->stride]>0) dst[x + y*b->stride]--;
+ //FIXME try more than just --
+ }
+ }
+ dequantize_all(s, p, idwt2_buffer, width, height);
+ ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count);
+ find_sse(s, p, score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation);
+ for(y=ys; y<b->height; y+= Q2_STEP){
+ for(x=xs; x<b->width; x+= Q2_STEP){
+ int score_idx= x/Q2_STEP + (y/Q2_STEP)*score_stride;
+ if(score[score_idx] <= best_score[score_idx] + threshold){
+ best_score[score_idx]= score[score_idx];
+ if(best_dst[x + y*b->stride]<0) best_dst[x + y*b->stride]++;
+ if(best_dst[x + y*b->stride]>0) best_dst[x + y*b->stride]--;
+ //FIXME copy instead
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ memcpy(s->spatial_idwt_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); //FIXME work with that directly instead of copy at the end
+}
+
+#endif /* QUANTIZE2==1 */
+
+#if CONFIG_SNOW_ENCODER
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+ SnowContext *s = avctx->priv_data;
+ int plane_index;
+
+ if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
+ av_log(avctx, AV_LOG_ERROR, "This codec is under development, files encoded with it may not be decodable with future versions!!!\n"
+ "Use vstrict=-2 / -strict -2 to use it anyway.\n");
+ return -1;
+ }
+
+ if(avctx->prediction_method == DWT_97
+ && (avctx->flags & CODEC_FLAG_QSCALE)
+ && avctx->global_quality == 0){
+ av_log(avctx, AV_LOG_ERROR, "The 9/7 wavelet is incompatible with lossless mode.\n");
+ return -1;
+ }
+
+ s->spatial_decomposition_type= avctx->prediction_method; //FIXME add decorrelator type r transform_type
+
+ s->mv_scale = (avctx->flags & CODEC_FLAG_QPEL) ? 2 : 4;
+ s->block_max_depth= (avctx->flags & CODEC_FLAG_4MV ) ? 1 : 0;
+
+ for(plane_index=0; plane_index<3; plane_index++){
+ s->plane[plane_index].diag_mc= 1;
+ s->plane[plane_index].htaps= 6;
+ s->plane[plane_index].hcoeff[0]= 40;
+ s->plane[plane_index].hcoeff[1]= -10;
+ s->plane[plane_index].hcoeff[2]= 2;
+ s->plane[plane_index].fast_mc= 1;
+ }
+
+ ff_snow_common_init(avctx);
+ ff_snow_alloc_blocks(s);
+
+ s->version=0;
+
+ s->m.avctx = avctx;
+ s->m.flags = avctx->flags;
+ s->m.bit_rate= avctx->bit_rate;
+
+ s->m.me.temp =
+ s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t));
+ s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
+ s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
+ s->m.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t));
+ h263_encode_init(&s->m); //mv_penalty
+
+ s->max_ref_frames = FFMAX(FFMIN(avctx->refs, MAX_REF_FRAMES), 1);
+
+ if(avctx->flags&CODEC_FLAG_PASS1){
+ if(!avctx->stats_out)
+ avctx->stats_out = av_mallocz(256);
+ }
+ if((avctx->flags&CODEC_FLAG_PASS2) || !(avctx->flags&CODEC_FLAG_QSCALE)){
+ if(ff_rate_control_init(&s->m) < 0)
+ return -1;
+ }
+ s->pass1_rc= !(avctx->flags & (CODEC_FLAG_QSCALE|CODEC_FLAG_PASS2));
+
+ avctx->coded_frame= &s->current_picture;
+ switch(avctx->pix_fmt){
+// case PIX_FMT_YUV444P:
+// case PIX_FMT_YUV422P:
+ case PIX_FMT_YUV420P:
+ case PIX_FMT_GRAY8:
+// case PIX_FMT_YUV411P:
+// case PIX_FMT_YUV410P:
+ s->colorspace_type= 0;
+ break;
+/* case PIX_FMT_RGB32:
+ s->colorspace= 1;
+ break;*/
+ default:
+ av_log(avctx, AV_LOG_ERROR, "pixel format not supported\n");
+ return -1;
+ }
+// avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
+ s->chroma_h_shift= 1;
+ s->chroma_v_shift= 1;
+
+ ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp);
+ ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp);
+
+ s->avctx->get_buffer(s->avctx, &s->input_picture);
+
+ if(s->avctx->me_method == ME_ITER){
+ int i;
+ int size= s->b_width * s->b_height << 2*s->block_max_depth;
+ for(i=0; i<s->max_ref_frames; i++){
+ s->ref_mvs[i]= av_mallocz(size*sizeof(int16_t[2]));
+ s->ref_scores[i]= av_mallocz(size*sizeof(uint32_t));
+ }
+ }
+
+ return 0;
+}
+
+//near copy & paste from dsputil, FIXME
+static int pix_sum(uint8_t * pix, int line_size, int w)
+{
+ int s, i, j;
+
+ s = 0;
+ for (i = 0; i < w; i++) {
+ for (j = 0; j < w; j++) {
+ s += pix[0];
+ pix ++;
+ }
+ pix += line_size - w;
+ }
+ return s;
+}
+
+//near copy & paste from dsputil, FIXME
+static int pix_norm1(uint8_t * pix, int line_size, int w)
+{
+ int s, i, j;
+ uint32_t *sq = ff_squareTbl + 256;
+
+ s = 0;
+ for (i = 0; i < w; i++) {
+ for (j = 0; j < w; j ++) {
+ s += sq[pix[0]];
+ pix ++;
+ }
+ pix += line_size - w;
+ }
+ return s;
+}
+
+//FIXME copy&paste
+#define P_LEFT P[1]
+#define P_TOP P[2]
+#define P_TOPRIGHT P[3]
+#define P_MEDIAN P[4]
+#define P_MV1 P[9]
+#define FLAG_QPEL 1 //must be 1
+
+static int encode_q_branch(SnowContext *s, int level, int x, int y){
+ uint8_t p_buffer[1024];
+ uint8_t i_buffer[1024];
+ uint8_t p_state[sizeof(s->block_state)];
+ uint8_t i_state[sizeof(s->block_state)];
+ RangeCoder pc, ic;
+ uint8_t *pbbak= s->c.bytestream;
+ uint8_t *pbbak_start= s->c.bytestream_start;
+ int score, score2, iscore, i_len, p_len, block_s, sum, base_bits;
+ const int w= s->b_width << s->block_max_depth;
+ const int h= s->b_height << s->block_max_depth;
+ const int rem_depth= s->block_max_depth - level;
+ const int index= (x + y*w) << rem_depth;
+ const int block_w= 1<<(LOG2_MB_SIZE - level);
+ int trx= (x+1)<<rem_depth;
+ int try= (y+1)<<rem_depth;
+ const BlockNode *left = x ? &s->block[index-1] : &null_block;
+ const BlockNode *top = y ? &s->block[index-w] : &null_block;
+ const BlockNode *right = trx<w ? &s->block[index+1] : &null_block;
+ const BlockNode *bottom= try<h ? &s->block[index+w] : &null_block;
+ const BlockNode *tl = y && x ? &s->block[index-w-1] : left;
+ const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
+ int pl = left->color[0];
+ int pcb= left->color[1];
+ int pcr= left->color[2];
+ int pmx, pmy;
+ int mx=0, my=0;
+ int l,cr,cb;
+ const int stride= s->current_picture.linesize[0];
+ const int uvstride= s->current_picture.linesize[1];
+ uint8_t *current_data[3]= { s->input_picture.data[0] + (x + y* stride)*block_w,
+ s->input_picture.data[1] + (x + y*uvstride)*block_w/2,
+ s->input_picture.data[2] + (x + y*uvstride)*block_w/2};
+ int P[10][2];
+ int16_t last_mv[3][2];
+ int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused
+ const int shift= 1+qpel;
+ MotionEstContext *c= &s->m.me;
+ int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
+ int mx_context= av_log2(2*FFABS(left->mx - top->mx));
+ int my_context= av_log2(2*FFABS(left->my - top->my));
+ int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
+ int ref, best_ref, ref_score, ref_mx, ref_my;
+
+ assert(sizeof(s->block_state) >= 256);
+ if(s->keyframe){
+ set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
+ return 0;
+ }
+
+// clip predictors / edge ?
+
+ P_LEFT[0]= left->mx;
+ P_LEFT[1]= left->my;
+ P_TOP [0]= top->mx;
+ P_TOP [1]= top->my;
+ P_TOPRIGHT[0]= tr->mx;
+ P_TOPRIGHT[1]= tr->my;
+
+ last_mv[0][0]= s->block[index].mx;
+ last_mv[0][1]= s->block[index].my;
+ last_mv[1][0]= right->mx;
+ last_mv[1][1]= right->my;
+ last_mv[2][0]= bottom->mx;
+ last_mv[2][1]= bottom->my;
+
+ s->m.mb_stride=2;
+ s->m.mb_x=
+ s->m.mb_y= 0;
+ c->skip= 0;
+
+ assert(c-> stride == stride);
+ assert(c->uvstride == uvstride);
+
+ c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
+ c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
+ c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
+ c->current_mv_penalty= c->mv_penalty[s->m.f_code=1] + MAX_MV;
+
+ c->xmin = - x*block_w - 16+3;
+ c->ymin = - y*block_w - 16+3;
+ c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3;
+ c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3;
+
+ if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift);
+ if(P_LEFT[1] > (c->ymax<<shift)) P_LEFT[1] = (c->ymax<<shift);
+ if(P_TOP[0] > (c->xmax<<shift)) P_TOP[0] = (c->xmax<<shift);
+ if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1] = (c->ymax<<shift);
+ if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
+ if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift); //due to pmx no clip
+ if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
+
+ P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
+ P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
+
+ if (!y) {
+ c->pred_x= P_LEFT[0];
+ c->pred_y= P_LEFT[1];
+ } else {
+ c->pred_x = P_MEDIAN[0];
+ c->pred_y = P_MEDIAN[1];
+ }
+
+ score= INT_MAX;
+ best_ref= 0;
+ for(ref=0; ref<s->ref_frames; ref++){
+ init_ref(c, current_data, s->last_picture[ref].data, NULL, block_w*x, block_w*y, 0);
+
+ ref_score= ff_epzs_motion_search(&s->m, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv,
+ (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w);
+
+ assert(ref_mx >= c->xmin);
+ assert(ref_mx <= c->xmax);
+ assert(ref_my >= c->ymin);
+ assert(ref_my <= c->ymax);
+
+ ref_score= c->sub_motion_search(&s->m, &ref_mx, &ref_my, ref_score, 0, 0, level-LOG2_MB_SIZE+4, block_w);
+ ref_score= ff_get_mb_score(&s->m, ref_mx, ref_my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0);
+ ref_score+= 2*av_log2(2*ref)*c->penalty_factor;
+ if(s->ref_mvs[ref]){
+ s->ref_mvs[ref][index][0]= ref_mx;
+ s->ref_mvs[ref][index][1]= ref_my;
+ s->ref_scores[ref][index]= ref_score;
+ }
+ if(score > ref_score){
+ score= ref_score;
+ best_ref= ref;
+ mx= ref_mx;
+ my= ref_my;
+ }
+ }
+ //FIXME if mb_cmp != SSE then intra cannot be compared currently and mb_penalty vs. lambda2
+
+ // subpel search
+ base_bits= get_rac_count(&s->c) - 8*(s->c.bytestream - s->c.bytestream_start);
+ pc= s->c;
+ pc.bytestream_start=
+ pc.bytestream= p_buffer; //FIXME end/start? and at the other stoo
+ memcpy(p_state, s->block_state, sizeof(s->block_state));
+
+ if(level!=s->block_max_depth)
+ put_rac(&pc, &p_state[4 + s_context], 1);
+ put_rac(&pc, &p_state[1 + left->type + top->type], 0);
+ if(s->ref_frames > 1)
+ put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0);
+ pred_mv(s, &pmx, &pmy, best_ref, left, top, tr);
+ put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1);
+ put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1);
+ p_len= pc.bytestream - pc.bytestream_start;
+ score += (s->lambda2*(get_rac_count(&pc)-base_bits))>>FF_LAMBDA_SHIFT;
+
+ block_s= block_w*block_w;
+ sum = pix_sum(current_data[0], stride, block_w);
+ l= (sum + block_s/2)/block_s;
+ iscore = pix_norm1(current_data[0], stride, block_w) - 2*l*sum + l*l*block_s;
+
+ block_s= block_w*block_w>>2;
+ sum = pix_sum(current_data[1], uvstride, block_w>>1);
+ cb= (sum + block_s/2)/block_s;
+// iscore += pix_norm1(¤t_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s;
+ sum = pix_sum(current_data[2], uvstride, block_w>>1);
+ cr= (sum + block_s/2)/block_s;
+// iscore += pix_norm1(¤t_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s;
+
+ ic= s->c;
+ ic.bytestream_start=
+ ic.bytestream= i_buffer; //FIXME end/start? and at the other stoo
+ memcpy(i_state, s->block_state, sizeof(s->block_state));
+ if(level!=s->block_max_depth)
+ put_rac(&ic, &i_state[4 + s_context], 1);
+ put_rac(&ic, &i_state[1 + left->type + top->type], 1);
+ put_symbol(&ic, &i_state[32], l-pl , 1);
+ put_symbol(&ic, &i_state[64], cb-pcb, 1);
+ put_symbol(&ic, &i_state[96], cr-pcr, 1);
+ i_len= ic.bytestream - ic.bytestream_start;
+ iscore += (s->lambda2*(get_rac_count(&ic)-base_bits))>>FF_LAMBDA_SHIFT;
+
+// assert(score==256*256*256*64-1);
+ assert(iscore < 255*255*256 + s->lambda2*10);
+ assert(iscore >= 0);
+ assert(l>=0 && l<=255);
+ assert(pl>=0 && pl<=255);
+
+ if(level==0){
+ int varc= iscore >> 8;
+ int vard= score >> 8;
+ if (vard <= 64 || vard < varc)
+ c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
+ else
+ c->scene_change_score+= s->m.qscale;
+ }
+
+ if(level!=s->block_max_depth){
+ put_rac(&s->c, &s->block_state[4 + s_context], 0);
+ score2 = encode_q_branch(s, level+1, 2*x+0, 2*y+0);
+ score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+0);
+ score2+= encode_q_branch(s, level+1, 2*x+0, 2*y+1);
+ score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+1);
+ score2+= s->lambda2>>FF_LAMBDA_SHIFT; //FIXME exact split overhead
+
+ if(score2 < score && score2 < iscore)
+ return score2;
+ }
+
+ if(iscore < score){
+ pred_mv(s, &pmx, &pmy, 0, left, top, tr);
+ memcpy(pbbak, i_buffer, i_len);
+ s->c= ic;
+ s->c.bytestream_start= pbbak_start;
+ s->c.bytestream= pbbak + i_len;
+ set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, 0, BLOCK_INTRA);
+ memcpy(s->block_state, i_state, sizeof(s->block_state));
+ return iscore;
+ }else{
+ memcpy(pbbak, p_buffer, p_len);
+ s->c= pc;
+ s->c.bytestream_start= pbbak_start;
+ s->c.bytestream= pbbak + p_len;
+ set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, best_ref, 0);
+ memcpy(s->block_state, p_state, sizeof(s->block_state));
+ return score;
+ }
+}
+
+static void encode_q_branch2(SnowContext *s, int level, int x, int y){
+ const int w= s->b_width << s->block_max_depth;
+ const int rem_depth= s->block_max_depth - level;
+ const int index= (x + y*w) << rem_depth;
+ int trx= (x+1)<<rem_depth;
+ BlockNode *b= &s->block[index];
+ const BlockNode *left = x ? &s->block[index-1] : &null_block;
+ const BlockNode *top = y ? &s->block[index-w] : &null_block;
+ const BlockNode *tl = y && x ? &s->block[index-w-1] : left;
+ const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
+ int pl = left->color[0];
+ int pcb= left->color[1];
+ int pcr= left->color[2];
+ int pmx, pmy;
+ int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
+ int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 16*!!b->ref;
+ int my_context= av_log2(2*FFABS(left->my - top->my)) + 16*!!b->ref;
+ int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
+
+ if(s->keyframe){
+ set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
+ return;
+ }
+
+ if(level!=s->block_max_depth){
+ if(same_block(b,b+1) && same_block(b,b+w) && same_block(b,b+w+1)){
+ put_rac(&s->c, &s->block_state[4 + s_context], 1);
+ }else{
+ put_rac(&s->c, &s->block_state[4 + s_context], 0);
+ encode_q_branch2(s, level+1, 2*x+0, 2*y+0);
+ encode_q_branch2(s, level+1, 2*x+1, 2*y+0);
+ encode_q_branch2(s, level+1, 2*x+0, 2*y+1);
+ encode_q_branch2(s, level+1, 2*x+1, 2*y+1);
+ return;
+ }
+ }
+ if(b->type & BLOCK_INTRA){
+ pred_mv(s, &pmx, &pmy, 0, left, top, tr);
+ put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1);
+ put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1);
+ put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1);
+ put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1);
+ set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA);
+ }else{
+ pred_mv(s, &pmx, &pmy, b->ref, left, top, tr);
+ put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0);
+ if(s->ref_frames > 1)
+ put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0);
+ put_symbol(&s->c, &s->block_state[128 + 32*mx_context], b->mx - pmx, 1);
+ put_symbol(&s->c, &s->block_state[128 + 32*my_context], b->my - pmy, 1);
+ set_blocks(s, level, x, y, pl, pcb, pcr, b->mx, b->my, b->ref, 0);
+ }
+}
+
+static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){
+ int i, x2, y2;
+ Plane *p= &s->plane[plane_index];
+ const int block_size = MB_SIZE >> s->block_max_depth;
+ const int block_w = plane_index ? block_size/2 : block_size;
+ const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
+ const int obmc_stride= plane_index ? block_size : 2*block_size;
+ const int ref_stride= s->current_picture.linesize[plane_index];
+ uint8_t *src= s-> input_picture.data[plane_index];
+ IDWTELEM *dst= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned
+ const int b_stride = s->b_width << s->block_max_depth;
+ const int w= p->width;
+ const int h= p->height;
+ int index= mb_x + mb_y*b_stride;
+ BlockNode *b= &s->block[index];
+ BlockNode backup= *b;
+ int ab=0;
+ int aa=0;
+
+ b->type|= BLOCK_INTRA;
+ b->color[plane_index]= 0;
+ memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM));
+
+ for(i=0; i<4; i++){
+ int mb_x2= mb_x + (i &1) - 1;
+ int mb_y2= mb_y + (i>>1) - 1;
+ int x= block_w*mb_x2 + block_w/2;
+ int y= block_w*mb_y2 + block_w/2;
+
+ add_yblock(s, 0, NULL, dst + ((i&1)+(i>>1)*obmc_stride)*block_w, NULL, obmc,
+ x, y, block_w, block_w, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index);
+
+ for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_w); y2++){
+ for(x2= FFMAX(x, 0); x2<FFMIN(w, x+block_w); x2++){
+ int index= x2-(block_w*mb_x - block_w/2) + (y2-(block_w*mb_y - block_w/2))*obmc_stride;
+ int obmc_v= obmc[index];
+ int d;
+ if(y<0) obmc_v += obmc[index + block_w*obmc_stride];
+ if(x<0) obmc_v += obmc[index + block_w];
+ if(y+block_w>h) obmc_v += obmc[index - block_w*obmc_stride];
+ if(x+block_w>w) obmc_v += obmc[index - block_w];
+ //FIXME precalculate this or simplify it somehow else
+
+ d = -dst[index] + (1<<(FRAC_BITS-1));
+ dst[index] = d;
+ ab += (src[x2 + y2*ref_stride] - (d>>FRAC_BITS)) * obmc_v;
+ aa += obmc_v * obmc_v; //FIXME precalculate this
+ }
+ }
+ }
+ *b= backup;
+
+ return av_clip(((ab<<LOG2_OBMC_MAX) + aa/2)/aa, 0, 255); //FIXME we should not need clipping
+}
+
+static inline int get_block_bits(SnowContext *s, int x, int y, int w){
+ const int b_stride = s->b_width << s->block_max_depth;
+ const int b_height = s->b_height<< s->block_max_depth;
+ int index= x + y*b_stride;
+ const BlockNode *b = &s->block[index];
+ const BlockNode *left = x ? &s->block[index-1] : &null_block;
+ const BlockNode *top = y ? &s->block[index-b_stride] : &null_block;
+ const BlockNode *tl = y && x ? &s->block[index-b_stride-1] : left;
+ const BlockNode *tr = y && x+w<b_stride ? &s->block[index-b_stride+w] : tl;
+ int dmx, dmy;
+// int mx_context= av_log2(2*FFABS(left->mx - top->mx));
+// int my_context= av_log2(2*FFABS(left->my - top->my));
+
+ if(x<0 || x>=b_stride || y>=b_height)
+ return 0;
+/*
+1 0 0
+01X 1-2 1
+001XX 3-6 2-3
+0001XXX 7-14 4-7
+00001XXXX 15-30 8-15
+*/
+//FIXME try accurate rate
+//FIXME intra and inter predictors if surrounding blocks are not the same type
+ if(b->type & BLOCK_INTRA){
+ return 3+2*( av_log2(2*FFABS(left->color[0] - b->color[0]))
+ + av_log2(2*FFABS(left->color[1] - b->color[1]))
+ + av_log2(2*FFABS(left->color[2] - b->color[2])));
+ }else{
+ pred_mv(s, &dmx, &dmy, b->ref, left, top, tr);
+ dmx-= b->mx;
+ dmy-= b->my;
+ return 2*(1 + av_log2(2*FFABS(dmx)) //FIXME kill the 2* can be merged in lambda
+ + av_log2(2*FFABS(dmy))
+ + av_log2(2*b->ref));
+ }
+}
+
+static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){
+ Plane *p= &s->plane[plane_index];
+ const int block_size = MB_SIZE >> s->block_max_depth;
+ const int block_w = plane_index ? block_size/2 : block_size;
+ const int obmc_stride= plane_index ? block_size : 2*block_size;
+ const int ref_stride= s->current_picture.linesize[plane_index];
+ uint8_t *dst= s->current_picture.data[plane_index];
+ uint8_t *src= s-> input_picture.data[plane_index];
+ IDWTELEM *pred= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4;
+ uint8_t *cur = s->scratchbuf;
+ uint8_t tmp[ref_stride*(2*MB_SIZE+HTAPS_MAX-1)];
+ const int b_stride = s->b_width << s->block_max_depth;
+ const int b_height = s->b_height<< s->block_max_depth;
+ const int w= p->width;
+ const int h= p->height;
+ int distortion;
+ int rate= 0;
+ const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
+ int sx= block_w*mb_x - block_w/2;
+ int sy= block_w*mb_y - block_w/2;
+ int x0= FFMAX(0,-sx);
+ int y0= FFMAX(0,-sy);
+ int x1= FFMIN(block_w*2, w-sx);
+ int y1= FFMIN(block_w*2, h-sy);
+ int i,x,y;
+
+ ff_snow_pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_w*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h);
+
+ for(y=y0; y<y1; y++){
+ const uint8_t *obmc1= obmc_edged + y*obmc_stride;
+ const IDWTELEM *pred1 = pred + y*obmc_stride;
+ uint8_t *cur1 = cur + y*ref_stride;
+ uint8_t *dst1 = dst + sx + (sy+y)*ref_stride;
+ for(x=x0; x<x1; x++){
+#if FRAC_BITS >= LOG2_OBMC_MAX
+ int v = (cur1[x] * obmc1[x]) << (FRAC_BITS - LOG2_OBMC_MAX);
+#else
+ int v = (cur1[x] * obmc1[x] + (1<<(LOG2_OBMC_MAX - FRAC_BITS-1))) >> (LOG2_OBMC_MAX - FRAC_BITS);
+#endif
+ v = (v + pred1[x]) >> FRAC_BITS;
+ if(v&(~255)) v= ~(v>>31);
+ dst1[x] = v;
+ }
+ }
+
+ /* copy the regions where obmc[] = (uint8_t)256 */
+ if(LOG2_OBMC_MAX == 8
+ && (mb_x == 0 || mb_x == b_stride-1)
+ && (mb_y == 0 || mb_y == b_height-1)){
+ if(mb_x == 0)
+ x1 = block_w;
+ else
+ x0 = block_w;
+ if(mb_y == 0)
+ y1 = block_w;
+ else
+ y0 = block_w;
+ for(y=y0; y<y1; y++)
+ memcpy(dst + sx+x0 + (sy+y)*ref_stride, cur + x0 + y*ref_stride, x1-x0);
+ }
+
+ if(block_w==16){
+ /* FIXME rearrange dsputil to fit 32x32 cmp functions */
+ /* FIXME check alignment of the cmp wavelet vs the encoding wavelet */
+ /* FIXME cmps overlap but do not cover the wavelet's whole support.
+ * So improving the score of one block is not strictly guaranteed
+ * to improve the score of the whole frame, thus iterative motion
+ * estimation does not always converge. */
+ if(s->avctx->me_cmp == FF_CMP_W97)
+ distortion = ff_w97_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
+ else if(s->avctx->me_cmp == FF_CMP_W53)
+ distortion = ff_w53_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
+ else{
+ distortion = 0;
+ for(i=0; i<4; i++){
+ int off = sx+16*(i&1) + (sy+16*(i>>1))*ref_stride;
+ distortion += s->dsp.me_cmp[0](&s->m, src + off, dst + off, ref_stride, 16);
+ }
+ }
+ }else{
+ assert(block_w==8);
+ distortion = s->dsp.me_cmp[0](&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
+ }
+
+ if(plane_index==0){
+ for(i=0; i<4; i++){
+/* ..RRr
+ * .RXx.
+ * rxx..
+ */
+ rate += get_block_bits(s, mb_x + (i&1) - (i>>1), mb_y + (i>>1), 1);
+ }
+ if(mb_x == b_stride-2)
+ rate += get_block_bits(s, mb_x + 1, mb_y + 1, 1);
+ }
+ return distortion + rate*penalty_factor;
+}
+
+static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){
+ int i, y2;
+ Plane *p= &s->plane[plane_index];
+ const int block_size = MB_SIZE >> s->block_max_depth;
+ const int block_w = plane_index ? block_size/2 : block_size;
+ const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
+ const int obmc_stride= plane_index ? block_size : 2*block_size;
+ const int ref_stride= s->current_picture.linesize[plane_index];
+ uint8_t *dst= s->current_picture.data[plane_index];
+ uint8_t *src= s-> input_picture.data[plane_index];
+ //FIXME zero_dst is const but add_yblock changes dst if add is 0 (this is never the case for dst=zero_dst
+ // const has only been removed from zero_dst to suppress a warning
+ static IDWTELEM zero_dst[4096]; //FIXME
+ const int b_stride = s->b_width << s->block_max_depth;
+ const int w= p->width;
+ const int h= p->height;
+ int distortion= 0;
+ int rate= 0;
+ const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
+
+ for(i=0; i<9; i++){
+ int mb_x2= mb_x + (i%3) - 1;
+ int mb_y2= mb_y + (i/3) - 1;
+ int x= block_w*mb_x2 + block_w/2;
+ int y= block_w*mb_y2 + block_w/2;
+
+ add_yblock(s, 0, NULL, zero_dst, dst, obmc,
+ x, y, block_w, block_w, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index);
+
+ //FIXME find a cleaner/simpler way to skip the outside stuff
+ for(y2= y; y2<0; y2++)
+ memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
+ for(y2= h; y2<y+block_w; y2++)
+ memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
+ if(x<0){
+ for(y2= y; y2<y+block_w; y2++)
+ memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, -x);
+ }
+ if(x+block_w > w){
+ for(y2= y; y2<y+block_w; y2++)
+ memcpy(dst + w + y2*ref_stride, src + w + y2*ref_stride, x+block_w - w);
+ }
+
+ assert(block_w== 8 || block_w==16);
+ distortion += s->dsp.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_w);
+ }
+
+ if(plane_index==0){
+ BlockNode *b= &s->block[mb_x+mb_y*b_stride];
+ int merged= same_block(b,b+1) && same_block(b,b+b_stride) && same_block(b,b+b_stride+1);
+
+/* ..RRRr
+ * .RXXx.
+ * .RXXx.
+ * rxxx.
+ */
+ if(merged)
+ rate = get_block_bits(s, mb_x, mb_y, 2);
+ for(i=merged?4:0; i<9; i++){
+ static const int dxy[9][2] = {{0,0},{1,0},{0,1},{1,1},{2,0},{2,1},{-1,2},{0,2},{1,2}};
+ rate += get_block_bits(s, mb_x + dxy[i][0], mb_y + dxy[i][1], 1);
+ }
+ }
+ return distortion + rate*penalty_factor;
+}
+
+static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){
+ const int w= b->width;
+ const int h= b->height;
+ int x, y;
+
+ if(1){
+ int run=0;
+ int runs[w*h];
+ int run_index=0;
+ int max_index;
+
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ int v, p=0;
+ int /*ll=0, */l=0, lt=0, t=0, rt=0;
+ v= src[x + y*stride];
+
+ if(y){
+ t= src[x + (y-1)*stride];
+ if(x){
+ lt= src[x - 1 + (y-1)*stride];
+ }
+ if(x + 1 < w){
+ rt= src[x + 1 + (y-1)*stride];
+ }
+ }
+ if(x){
+ l= src[x - 1 + y*stride];
+ /*if(x > 1){
+ if(orientation==1) ll= src[y + (x-2)*stride];
+ else ll= src[x - 2 + y*stride];
+ }*/
+ }
+ if(parent){
+ int px= x>>1;
+ int py= y>>1;
+ if(px<b->parent->width && py<b->parent->height)
+ p= parent[px + py*2*stride];
+ }
+ if(!(/*ll|*/l|lt|t|rt|p)){
+ if(v){
+ runs[run_index++]= run;
+ run=0;
+ }else{
+ run++;
+ }
+ }
+ }
+ }
+ max_index= run_index;
+ runs[run_index++]= run;
+ run_index=0;
+ run= runs[run_index++];
+
+ put_symbol2(&s->c, b->state[30], max_index, 0);
+ if(run_index <= max_index)
+ put_symbol2(&s->c, b->state[1], run, 3);
+
+ for(y=0; y<h; y++){
+ if(s->c.bytestream_end - s->c.bytestream < w*40){
+ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+ return -1;
+ }
+ for(x=0; x<w; x++){
+ int v, p=0;
+ int /*ll=0, */l=0, lt=0, t=0, rt=0;
+ v= src[x + y*stride];
+
+ if(y){
+ t= src[x + (y-1)*stride];
+ if(x){
+ lt= src[x - 1 + (y-1)*stride];
+ }
+ if(x + 1 < w){
+ rt= src[x + 1 + (y-1)*stride];
+ }
+ }
+ if(x){
+ l= src[x - 1 + y*stride];
+ /*if(x > 1){
+ if(orientation==1) ll= src[y + (x-2)*stride];
+ else ll= src[x - 2 + y*stride];
+ }*/
+ }
+ if(parent){
+ int px= x>>1;
+ int py= y>>1;
+ if(px<b->parent->width && py<b->parent->height)
+ p= parent[px + py*2*stride];
+ }
+ if(/*ll|*/l|lt|t|rt|p){
+ int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p));
+
+ put_rac(&s->c, &b->state[0][context], !!v);
+ }else{
+ if(!run){
+ run= runs[run_index++];
+
+ if(run_index <= max_index)
+ put_symbol2(&s->c, b->state[1], run, 3);
+ assert(v);
+ }else{
+ run--;
+ assert(!v);
+ }
+ }
+ if(v){
+ int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p));
+ int l2= 2*FFABS(l) + (l<0);
+ int t2= 2*FFABS(t) + (t<0);
+
+ put_symbol2(&s->c, b->state[context + 2], FFABS(v)-1, context-4);
+ put_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3bA[l2&0xFF] + 3*quant3bA[t2&0xFF]], v<0);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static int encode_subband(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){
+// encode_subband_qtree(s, b, src, parent, stride, orientation);
+// encode_subband_z0run(s, b, src, parent, stride, orientation);
+ return encode_subband_c0run(s, b, src, parent, stride, orientation);
+// encode_subband_dzr(s, b, src, parent, stride, orientation);
+}
+
+static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, const uint8_t *obmc_edged, int *best_rd){
+ const int b_stride= s->b_width << s->block_max_depth;
+ BlockNode *block= &s->block[mb_x + mb_y * b_stride];
+ BlockNode backup= *block;
+ unsigned value;
+ int rd, index;
+
+ assert(mb_x>=0 && mb_y>=0);
+ assert(mb_x<b_stride);
+
+ if(intra){
+ block->color[0] = p[0];
+ block->color[1] = p[1];
+ block->color[2] = p[2];
+ block->type |= BLOCK_INTRA;
+ }else{
+ index= (p[0] + 31*p[1]) & (ME_CACHE_SIZE-1);
+ value= s->me_cache_generation + (p[0]>>10) + (p[1]<<6) + (block->ref<<12);
+ if(s->me_cache[index] == value)
+ return 0;
+ s->me_cache[index]= value;
+
+ block->mx= p[0];
+ block->my= p[1];
+ block->type &= ~BLOCK_INTRA;
+ }
+
+ rd= get_block_rd(s, mb_x, mb_y, 0, obmc_edged);
+
+//FIXME chroma
+ if(rd < *best_rd){
+ *best_rd= rd;
+ return 1;
+ }else{
+ *block= backup;
+ return 0;
+ }
+}
+
+/* special case for int[2] args we discard afterwards,
+ * fixes compilation problem with gcc 2.95 */
+static av_always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, const uint8_t *obmc_edged, int *best_rd){
+ int p[2] = {p0, p1};
+ return check_block(s, mb_x, mb_y, p, 0, obmc_edged, best_rd);
+}
+
+static av_always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int ref, int *best_rd){
+ const int b_stride= s->b_width << s->block_max_depth;
+ BlockNode *block= &s->block[mb_x + mb_y * b_stride];
+ BlockNode backup[4]= {block[0], block[1], block[b_stride], block[b_stride+1]};
+ unsigned value;
+ int rd, index;
+
+ assert(mb_x>=0 && mb_y>=0);
+ assert(mb_x<b_stride);
+ assert(((mb_x|mb_y)&1) == 0);
+
+ index= (p0 + 31*p1) & (ME_CACHE_SIZE-1);
+ value= s->me_cache_generation + (p0>>10) + (p1<<6) + (block->ref<<12);
+ if(s->me_cache[index] == value)
+ return 0;
+ s->me_cache[index]= value;
+
+ block->mx= p0;
+ block->my= p1;
+ block->ref= ref;
+ block->type &= ~BLOCK_INTRA;
+ block[1]= block[b_stride]= block[b_stride+1]= *block;
+
+ rd= get_4block_rd(s, mb_x, mb_y, 0);
+
+//FIXME chroma
+ if(rd < *best_rd){
+ *best_rd= rd;
+ return 1;
+ }else{
+ block[0]= backup[0];
+ block[1]= backup[1];
+ block[b_stride]= backup[2];
+ block[b_stride+1]= backup[3];
+ return 0;
+ }
+}
+
+static void iterative_me(SnowContext *s){
+ int pass, mb_x, mb_y;
+ const int b_width = s->b_width << s->block_max_depth;
+ const int b_height= s->b_height << s->block_max_depth;
+ const int b_stride= b_width;
+ int color[3];
+
+ {
+ RangeCoder r = s->c;
+ uint8_t state[sizeof(s->block_state)];
+ memcpy(state, s->block_state, sizeof(s->block_state));
+ for(mb_y= 0; mb_y<s->b_height; mb_y++)
+ for(mb_x= 0; mb_x<s->b_width; mb_x++)
+ encode_q_branch(s, 0, mb_x, mb_y);
+ s->c = r;
+ memcpy(s->block_state, state, sizeof(s->block_state));
+ }
+
+ for(pass=0; pass<25; pass++){
+ int change= 0;
+
+ for(mb_y= 0; mb_y<b_height; mb_y++){
+ for(mb_x= 0; mb_x<b_width; mb_x++){
+ int dia_change, i, j, ref;
+ int best_rd= INT_MAX, ref_rd;
+ BlockNode backup, ref_b;
+ const int index= mb_x + mb_y * b_stride;
+ BlockNode *block= &s->block[index];
+ BlockNode *tb = mb_y ? &s->block[index-b_stride ] : NULL;
+ BlockNode *lb = mb_x ? &s->block[index -1] : NULL;
+ BlockNode *rb = mb_x+1<b_width ? &s->block[index +1] : NULL;
+ BlockNode *bb = mb_y+1<b_height ? &s->block[index+b_stride ] : NULL;
+ BlockNode *tlb= mb_x && mb_y ? &s->block[index-b_stride-1] : NULL;
+ BlockNode *trb= mb_x+1<b_width && mb_y ? &s->block[index-b_stride+1] : NULL;
+ BlockNode *blb= mb_x && mb_y+1<b_height ? &s->block[index+b_stride-1] : NULL;
+ BlockNode *brb= mb_x+1<b_width && mb_y+1<b_height ? &s->block[index+b_stride+1] : NULL;
+ const int b_w= (MB_SIZE >> s->block_max_depth);
+ uint8_t obmc_edged[b_w*2][b_w*2];
+
+ if(pass && (block->type & BLOCK_OPT))
+ continue;
+ block->type |= BLOCK_OPT;
+
+ backup= *block;
+
+ if(!s->me_cache_generation)
+ memset(s->me_cache, 0, sizeof(s->me_cache));
+ s->me_cache_generation += 1<<22;
+
+ //FIXME precalculate
+ {
+ int x, y;
+ memcpy(obmc_edged, obmc_tab[s->block_max_depth], b_w*b_w*4);
+ if(mb_x==0)
+ for(y=0; y<b_w*2; y++)
+ memset(obmc_edged[y], obmc_edged[y][0] + obmc_edged[y][b_w-1], b_w);
+ if(mb_x==b_stride-1)
+ for(y=0; y<b_w*2; y++)
+ memset(obmc_edged[y]+b_w, obmc_edged[y][b_w] + obmc_edged[y][b_w*2-1], b_w);
+ if(mb_y==0){
+ for(x=0; x<b_w*2; x++)
+ obmc_edged[0][x] += obmc_edged[b_w-1][x];
+ for(y=1; y<b_w; y++)
+ memcpy(obmc_edged[y], obmc_edged[0], b_w*2);
+ }
+ if(mb_y==b_height-1){
+ for(x=0; x<b_w*2; x++)
+ obmc_edged[b_w*2-1][x] += obmc_edged[b_w][x];
+ for(y=b_w; y<b_w*2-1; y++)
+ memcpy(obmc_edged[y], obmc_edged[b_w*2-1], b_w*2);
+ }
+ }
+
+ //skip stuff outside the picture
+ if(mb_x==0 || mb_y==0 || mb_x==b_width-1 || mb_y==b_height-1){
+ uint8_t *src= s-> input_picture.data[0];
+ uint8_t *dst= s->current_picture.data[0];
+ const int stride= s->current_picture.linesize[0];
+ const int block_w= MB_SIZE >> s->block_max_depth;
+ const int sx= block_w*mb_x - block_w/2;
+ const int sy= block_w*mb_y - block_w/2;
+ const int w= s->plane[0].width;
+ const int h= s->plane[0].height;
+ int y;
+
+ for(y=sy; y<0; y++)
+ memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
+ for(y=h; y<sy+block_w*2; y++)
+ memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
+ if(sx<0){
+ for(y=sy; y<sy+block_w*2; y++)
+ memcpy(dst + sx + y*stride, src + sx + y*stride, -sx);
+ }
+ if(sx+block_w*2 > w){
+ for(y=sy; y<sy+block_w*2; y++)
+ memcpy(dst + w + y*stride, src + w + y*stride, sx+block_w*2 - w);
+ }
+ }
+
+ // intra(black) = neighbors' contribution to the current block
+ for(i=0; i<3; i++)
+ color[i]= get_dc(s, mb_x, mb_y, i);
+
+ // get previous score (cannot be cached due to OBMC)
+ if(pass > 0 && (block->type&BLOCK_INTRA)){
+ int color0[3]= {block->color[0], block->color[1], block->color[2]};
+ check_block(s, mb_x, mb_y, color0, 1, *obmc_edged, &best_rd);
+ }else
+ check_block_inter(s, mb_x, mb_y, block->mx, block->my, *obmc_edged, &best_rd);
+
+ ref_b= *block;
+ ref_rd= best_rd;
+ for(ref=0; ref < s->ref_frames; ref++){
+ int16_t (*mvr)[2]= &s->ref_mvs[ref][index];
+ if(s->ref_scores[ref][index] > s->ref_scores[ref_b.ref][index]*3/2) //FIXME tune threshold
+ continue;
+ block->ref= ref;
+ best_rd= INT_MAX;
+
+ check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], *obmc_edged, &best_rd);
+ check_block_inter(s, mb_x, mb_y, 0, 0, *obmc_edged, &best_rd);
+ if(tb)
+ check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], *obmc_edged, &best_rd);
+ if(lb)
+ check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], *obmc_edged, &best_rd);
+ if(rb)
+ check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], *obmc_edged, &best_rd);
+ if(bb)
+ check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], *obmc_edged, &best_rd);
+
+ /* fullpel ME */
+ //FIXME avoid subpel interpolation / round to nearest integer
+ do{
+ dia_change=0;
+ for(i=0; i<FFMAX(s->avctx->dia_size, 1); i++){
+ for(j=0; j<i; j++){
+ dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my+(4*j), *obmc_edged, &best_rd);
+ dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my-(4*j), *obmc_edged, &best_rd);
+ dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my-(4*j), *obmc_edged, &best_rd);
+ dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my+(4*j), *obmc_edged, &best_rd);
+ }
+ }
+ }while(dia_change);
+ /* subpel ME */
+ do{
+ static const int square[8][2]= {{+1, 0},{-1, 0},{ 0,+1},{ 0,-1},{+1,+1},{-1,-1},{+1,-1},{-1,+1},};
+ dia_change=0;
+ for(i=0; i<8; i++)
+ dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], *obmc_edged, &best_rd);
+ }while(dia_change);
+ //FIXME or try the standard 2 pass qpel or similar
+
+ mvr[0][0]= block->mx;
+ mvr[0][1]= block->my;
+ if(ref_rd > best_rd){
+ ref_rd= best_rd;
+ ref_b= *block;
+ }
+ }
+ best_rd= ref_rd;
+ *block= ref_b;
+ check_block(s, mb_x, mb_y, color, 1, *obmc_edged, &best_rd);
+ //FIXME RD style color selection
+ if(!same_block(block, &backup)){
+ if(tb ) tb ->type &= ~BLOCK_OPT;
+ if(lb ) lb ->type &= ~BLOCK_OPT;
+ if(rb ) rb ->type &= ~BLOCK_OPT;
+ if(bb ) bb ->type &= ~BLOCK_OPT;
+ if(tlb) tlb->type &= ~BLOCK_OPT;
+ if(trb) trb->type &= ~BLOCK_OPT;
+ if(blb) blb->type &= ~BLOCK_OPT;
+ if(brb) brb->type &= ~BLOCK_OPT;
+ change ++;
+ }
+ }
+ }
+ av_log(s->avctx, AV_LOG_ERROR, "pass:%d changed:%d\n", pass, change);
+ if(!change)
+ break;
+ }
+
+ if(s->block_max_depth == 1){
+ int change= 0;
+ for(mb_y= 0; mb_y<b_height; mb_y+=2){
+ for(mb_x= 0; mb_x<b_width; mb_x+=2){
+ int i;
+ int best_rd, init_rd;
+ const int index= mb_x + mb_y * b_stride;
+ BlockNode *b[4];
+
+ b[0]= &s->block[index];
+ b[1]= b[0]+1;
+ b[2]= b[0]+b_stride;
+ b[3]= b[2]+1;
+ if(same_block(b[0], b[1]) &&
+ same_block(b[0], b[2]) &&
+ same_block(b[0], b[3]))
+ continue;
+
+ if(!s->me_cache_generation)
+ memset(s->me_cache, 0, sizeof(s->me_cache));
+ s->me_cache_generation += 1<<22;
+
+ init_rd= best_rd= get_4block_rd(s, mb_x, mb_y, 0);
+
+ //FIXME more multiref search?
+ check_4block_inter(s, mb_x, mb_y,
+ (b[0]->mx + b[1]->mx + b[2]->mx + b[3]->mx + 2) >> 2,
+ (b[0]->my + b[1]->my + b[2]->my + b[3]->my + 2) >> 2, 0, &best_rd);
+
+ for(i=0; i<4; i++)
+ if(!(b[i]->type&BLOCK_INTRA))
+ check_4block_inter(s, mb_x, mb_y, b[i]->mx, b[i]->my, b[i]->ref, &best_rd);
+
+ if(init_rd != best_rd)
+ change++;
+ }
+ }
+ av_log(s->avctx, AV_LOG_ERROR, "pass:4mv changed:%d\n", change*4);
+ }
+}
+
+static void encode_blocks(SnowContext *s, int search){
+ int x, y;
+ int w= s->b_width;
+ int h= s->b_height;
+
+ if(s->avctx->me_method == ME_ITER && !s->keyframe && search)
+ iterative_me(s);
+
+ for(y=0; y<h; y++){
+ if(s->c.bytestream_end - s->c.bytestream < w*MB_SIZE*MB_SIZE*3){ //FIXME nicer limit
+ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+ return;
+ }
+ for(x=0; x<w; x++){
+ if(s->avctx->me_method == ME_ITER || !search)
+ encode_q_branch2(s, 0, x, y);
+ else
+ encode_q_branch (s, 0, x, y);
+ }
+ }
+}
+
+static void quantize(SnowContext *s, SubBand *b, IDWTELEM *dst, DWTELEM *src, int stride, int bias){
+ const int w= b->width;
+ const int h= b->height;
+ const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
+ const int qmul= qexp[qlog&(QROOT-1)]<<((qlog>>QSHIFT) + ENCODER_EXTRA_BITS);
+ int x,y, thres1, thres2;
+
+ if(s->qlog == LOSSLESS_QLOG){
+ for(y=0; y<h; y++)
+ for(x=0; x<w; x++)
+ dst[x + y*stride]= src[x + y*stride];
+ return;
+ }
+
+ bias= bias ? 0 : (3*qmul)>>3;
+ thres1= ((qmul - bias)>>QEXPSHIFT) - 1;
+ thres2= 2*thres1;
+
+ if(!bias){
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ int i= src[x + y*stride];
+
+ if((unsigned)(i+thres1) > thres2){
+ if(i>=0){
+ i<<= QEXPSHIFT;
+ i/= qmul; //FIXME optimize
+ dst[x + y*stride]= i;
+ }else{
+ i= -i;
+ i<<= QEXPSHIFT;
+ i/= qmul; //FIXME optimize
+ dst[x + y*stride]= -i;
+ }
+ }else
+ dst[x + y*stride]= 0;
+ }
+ }
+ }else{
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ int i= src[x + y*stride];
+
+ if((unsigned)(i+thres1) > thres2){
+ if(i>=0){
+ i<<= QEXPSHIFT;
+ i= (i + bias) / qmul; //FIXME optimize
+ dst[x + y*stride]= i;
+ }else{
+ i= -i;
+ i<<= QEXPSHIFT;
+ i= (i + bias) / qmul; //FIXME optimize
+ dst[x + y*stride]= -i;
+ }
+ }else
+ dst[x + y*stride]= 0;
+ }
+ }
+ }
+}
+
+static void dequantize(SnowContext *s, SubBand *b, IDWTELEM *src, int stride){
+ const int w= b->width;
+ const int h= b->height;
+ const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
+ const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
+ const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
+ int x,y;
+
+ if(s->qlog == LOSSLESS_QLOG) return;
+
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ int i= src[x + y*stride];
+ if(i<0){
+ src[x + y*stride]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
+ }else if(i>0){
+ src[x + y*stride]= (( i*qmul + qadd)>>(QEXPSHIFT));
+ }
+ }
+ }
+}
+
+static void decorrelate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){
+ const int w= b->width;
+ const int h= b->height;
+ int x,y;
+
+ for(y=h-1; y>=0; y--){
+ for(x=w-1; x>=0; x--){
+ int i= x + y*stride;
+
+ if(x){
+ if(use_median){
+ if(y && x+1<w) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]);
+ else src[i] -= src[i - 1];
+ }else{
+ if(y) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]);
+ else src[i] -= src[i - 1];
+ }
+ }else{
+ if(y) src[i] -= src[i - stride];
+ }
+ }
+ }
+}
+
+static void correlate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){
+ const int w= b->width;
+ const int h= b->height;
+ int x,y;
+
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ int i= x + y*stride;
+
+ if(x){
+ if(use_median){
+ if(y && x+1<w) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]);
+ else src[i] += src[i - 1];
+ }else{
+ if(y) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]);
+ else src[i] += src[i - 1];
+ }
+ }else{
+ if(y) src[i] += src[i - stride];
+ }
+ }
+ }
+}
+
+static void encode_qlogs(SnowContext *s){
+ int plane_index, level, orientation;
+
+ for(plane_index=0; plane_index<2; plane_index++){
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1:0; orientation<4; orientation++){
+ if(orientation==2) continue;
+ put_symbol(&s->c, s->header_state, s->plane[plane_index].band[level][orientation].qlog, 1);
+ }
+ }
+ }
+}
+
+static void encode_header(SnowContext *s){
+ int plane_index, i;
+ uint8_t kstate[32];
+
+ memset(kstate, MID_STATE, sizeof(kstate));
+
+ put_rac(&s->c, kstate, s->keyframe);
+ if(s->keyframe || s->always_reset){
+ ff_snow_reset_contexts(s);
+ s->last_spatial_decomposition_type=
+ s->last_qlog=
+ s->last_qbias=
+ s->last_mv_scale=
+ s->last_block_max_depth= 0;
+ for(plane_index=0; plane_index<2; plane_index++){
+ Plane *p= &s->plane[plane_index];
+ p->last_htaps=0;
+ p->last_diag_mc=0;
+ memset(p->last_hcoeff, 0, sizeof(p->last_hcoeff));
+ }
+ }
+ if(s->keyframe){
+ put_symbol(&s->c, s->header_state, s->version, 0);
+ put_rac(&s->c, s->header_state, s->always_reset);
+ put_symbol(&s->c, s->header_state, s->temporal_decomposition_type, 0);
+ put_symbol(&s->c, s->header_state, s->temporal_decomposition_count, 0);
+ put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
+ put_symbol(&s->c, s->header_state, s->colorspace_type, 0);
+ put_symbol(&s->c, s->header_state, s->chroma_h_shift, 0);
+ put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0);
+ put_rac(&s->c, s->header_state, s->spatial_scalability);
+// put_rac(&s->c, s->header_state, s->rate_scalability);
+ put_symbol(&s->c, s->header_state, s->max_ref_frames-1, 0);
+
+ encode_qlogs(s);
+ }
+
+ if(!s->keyframe){
+ int update_mc=0;
+ for(plane_index=0; plane_index<2; plane_index++){
+ Plane *p= &s->plane[plane_index];
+ update_mc |= p->last_htaps != p->htaps;
+ update_mc |= p->last_diag_mc != p->diag_mc;
+ update_mc |= !!memcmp(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff));
+ }
+ put_rac(&s->c, s->header_state, update_mc);
+ if(update_mc){
+ for(plane_index=0; plane_index<2; plane_index++){
+ Plane *p= &s->plane[plane_index];
+ put_rac(&s->c, s->header_state, p->diag_mc);
+ put_symbol(&s->c, s->header_state, p->htaps/2-1, 0);
+ for(i= p->htaps/2; i; i--)
+ put_symbol(&s->c, s->header_state, FFABS(p->hcoeff[i]), 0);
+ }
+ }
+ if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){
+ put_rac(&s->c, s->header_state, 1);
+ put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
+ encode_qlogs(s);
+ }else
+ put_rac(&s->c, s->header_state, 0);
+ }
+
+ put_symbol(&s->c, s->header_state, s->spatial_decomposition_type - s->last_spatial_decomposition_type, 1);
+ put_symbol(&s->c, s->header_state, s->qlog - s->last_qlog , 1);
+ put_symbol(&s->c, s->header_state, s->mv_scale - s->last_mv_scale, 1);
+ put_symbol(&s->c, s->header_state, s->qbias - s->last_qbias , 1);
+ put_symbol(&s->c, s->header_state, s->block_max_depth - s->last_block_max_depth, 1);
+
+}
+
+static void update_last_header_values(SnowContext *s){
+ int plane_index;
+
+ if(!s->keyframe){
+ for(plane_index=0; plane_index<2; plane_index++){
+ Plane *p= &s->plane[plane_index];
+ p->last_diag_mc= p->diag_mc;
+ p->last_htaps = p->htaps;
+ memcpy(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff));
+ }
+ }
+
+ s->last_spatial_decomposition_type = s->spatial_decomposition_type;
+ s->last_qlog = s->qlog;
+ s->last_qbias = s->qbias;
+ s->last_mv_scale = s->mv_scale;
+ s->last_block_max_depth = s->block_max_depth;
+ s->last_spatial_decomposition_count = s->spatial_decomposition_count;
+}
+
+static int qscale2qlog(int qscale){
+ return rint(QROOT*log(qscale / (float)FF_QP2LAMBDA)/log(2))
+ + 61*QROOT/8; ///< 64 > 60
+}
+
+static int ratecontrol_1pass(SnowContext *s, AVFrame *pict)
+{
+ /* Estimate the frame's complexity as a sum of weighted dwt coefficients.
+ * FIXME we know exact mv bits at this point,
+ * but ratecontrol isn't set up to include them. */
+ uint32_t coef_sum= 0;
+ int level, orientation, delta_qlog;
+
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &s->plane[0].band[level][orientation];
+ IDWTELEM *buf= b->ibuf;
+ const int w= b->width;
+ const int h= b->height;
+ const int stride= b->stride;
+ const int qlog= av_clip(2*QROOT + b->qlog, 0, QROOT*16);
+ const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
+ const int qdiv= (1<<16)/qmul;
+ int x, y;
+ //FIXME this is ugly
+ for(y=0; y<h; y++)
+ for(x=0; x<w; x++)
+ buf[x+y*stride]= b->buf[x+y*stride];
+ if(orientation==0)
+ decorrelate(s, b, buf, stride, 1, 0);
+ for(y=0; y<h; y++)
+ for(x=0; x<w; x++)
+ coef_sum+= abs(buf[x+y*stride]) * qdiv >> 16;
+ }
+ }
+
+ /* ugly, ratecontrol just takes a sqrt again */
+ coef_sum = (uint64_t)coef_sum * coef_sum >> 16;
+ assert(coef_sum < INT_MAX);
+
+ if(pict->pict_type == AV_PICTURE_TYPE_I){
+ s->m.current_picture.mb_var_sum= coef_sum;
+ s->m.current_picture.mc_mb_var_sum= 0;
+ }else{
+ s->m.current_picture.mc_mb_var_sum= coef_sum;
+ s->m.current_picture.mb_var_sum= 0;
+ }
+
+ pict->quality= ff_rate_estimate_qscale(&s->m, 1);
+ if (pict->quality < 0)
+ return INT_MIN;
+ s->lambda= pict->quality * 3/2;
+ delta_qlog= qscale2qlog(pict->quality) - s->qlog;
+ s->qlog+= delta_qlog;
+ return delta_qlog;
+}
+
+static void calculate_visual_weight(SnowContext *s, Plane *p){
+ int width = p->width;
+ int height= p->height;
+ int level, orientation, x, y;
+
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &p->band[level][orientation];
+ IDWTELEM *ibuf= b->ibuf;
+ int64_t error=0;
+
+ memset(s->spatial_idwt_buffer, 0, sizeof(*s->spatial_idwt_buffer)*width*height);
+ ibuf[b->width/2 + b->height/2*b->stride]= 256*16;
+ ff_spatial_idwt(s->spatial_idwt_buffer, width, height, width, s->spatial_decomposition_type, s->spatial_decomposition_count);
+ for(y=0; y<height; y++){
+ for(x=0; x<width; x++){
+ int64_t d= s->spatial_idwt_buffer[x + y*width]*16;
+ error += d*d;
+ }
+ }
+
+ b->qlog= (int)(log(352256.0/sqrt(error)) / log(pow(2.0, 1.0/QROOT))+0.5);
+ }
+ }
+}
+
+static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
+ SnowContext *s = avctx->priv_data;
+ RangeCoder * const c= &s->c;
+ AVFrame *pict = data;
+ const int width= s->avctx->width;
+ const int height= s->avctx->height;
+ int level, orientation, plane_index, i, y;
+ uint8_t rc_header_bak[sizeof(s->header_state)];
+ uint8_t rc_block_bak[sizeof(s->block_state)];
+
+ ff_init_range_encoder(c, buf, buf_size);
+ ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
+
+ for(i=0; i<3; i++){
+ int shift= !!i;
+ for(y=0; y<(height>>shift); y++)
+ memcpy(&s->input_picture.data[i][y * s->input_picture.linesize[i]],
+ &pict->data[i][y * pict->linesize[i]],
+ width>>shift);
+ }
+ s->new_picture = *pict;
+
+ s->m.picture_number= avctx->frame_number;
+ if(avctx->flags&CODEC_FLAG_PASS2){
+ s->m.pict_type =
+ pict->pict_type= s->m.rc_context.entry[avctx->frame_number].new_pict_type;
+ s->keyframe= pict->pict_type==AV_PICTURE_TYPE_I;
+ if(!(avctx->flags&CODEC_FLAG_QSCALE)) {
+ pict->quality= ff_rate_estimate_qscale(&s->m, 0);
+ if (pict->quality < 0)
+ return -1;
+ }
+ }else{
+ s->keyframe= avctx->gop_size==0 || avctx->frame_number % avctx->gop_size == 0;
+ s->m.pict_type=
+ pict->pict_type= s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ }
+
+ if(s->pass1_rc && avctx->frame_number == 0)
+ pict->quality= 2*FF_QP2LAMBDA;
+ if(pict->quality){
+ s->qlog= qscale2qlog(pict->quality);
+ s->lambda = pict->quality * 3/2;
+ }
+ if(s->qlog < 0 || (!pict->quality && (avctx->flags & CODEC_FLAG_QSCALE))){
+ s->qlog= LOSSLESS_QLOG;
+ s->lambda = 0;
+ }//else keep previous frame's qlog until after motion estimation
+
+ ff_snow_frame_start(s);
+
+ s->m.current_picture_ptr= &s->m.current_picture;
+ s->m.last_picture.f.pts = s->m.current_picture.f.pts;
+ s->m.current_picture.f.pts = pict->pts;
+ if(pict->pict_type == AV_PICTURE_TYPE_P){
+ int block_width = (width +15)>>4;
+ int block_height= (height+15)>>4;
+ int stride= s->current_picture.linesize[0];
+
+ assert(s->current_picture.data[0]);
+ assert(s->last_picture[0].data[0]);
+
+ s->m.avctx= s->avctx;
+ s->m.current_picture.f.data[0] = s->current_picture.data[0];
+ s->m. last_picture.f.data[0] = s->last_picture[0].data[0];
+ s->m. new_picture.f.data[0] = s-> input_picture.data[0];
+ s->m. last_picture_ptr= &s->m. last_picture;
+ s->m.linesize=
+ s->m. last_picture.f.linesize[0] =
+ s->m. new_picture.f.linesize[0] =
+ s->m.current_picture.f.linesize[0] = stride;
+ s->m.uvlinesize= s->current_picture.linesize[1];
+ s->m.width = width;
+ s->m.height= height;
+ s->m.mb_width = block_width;
+ s->m.mb_height= block_height;
+ s->m.mb_stride= s->m.mb_width+1;
+ s->m.b8_stride= 2*s->m.mb_width+1;
+ s->m.f_code=1;
+ s->m.pict_type= pict->pict_type;
+ s->m.me_method= s->avctx->me_method;
+ s->m.me.scene_change_score=0;
+ s->m.flags= s->avctx->flags;
+ s->m.quarter_sample= (s->avctx->flags & CODEC_FLAG_QPEL)!=0;
+ s->m.out_format= FMT_H263;
+ s->m.unrestricted_mv= 1;
+
+ s->m.lambda = s->lambda;
+ s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
+ s->lambda2= s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
+
+ s->m.dsp= s->dsp; //move
+ ff_init_me(&s->m);
+ s->dsp= s->m.dsp;
+ }
+
+ if(s->pass1_rc){
+ memcpy(rc_header_bak, s->header_state, sizeof(s->header_state));
+ memcpy(rc_block_bak, s->block_state, sizeof(s->block_state));
+ }
+
+redo_frame:
+
+ if(pict->pict_type == AV_PICTURE_TYPE_I)
+ s->spatial_decomposition_count= 5;
+ else
+ s->spatial_decomposition_count= 5;
+
+ s->m.pict_type = pict->pict_type;
+ s->qbias= pict->pict_type == AV_PICTURE_TYPE_P ? 2 : 0;
+
+ ff_snow_common_init_after_header(avctx);
+
+ if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){
+ for(plane_index=0; plane_index<3; plane_index++){
+ calculate_visual_weight(s, &s->plane[plane_index]);
+ }
+ }
+
+ encode_header(s);
+ s->m.misc_bits = 8*(s->c.bytestream - s->c.bytestream_start);
+ encode_blocks(s, 1);
+ s->m.mv_bits = 8*(s->c.bytestream - s->c.bytestream_start) - s->m.misc_bits;
+
+ for(plane_index=0; plane_index<3; plane_index++){
+ Plane *p= &s->plane[plane_index];
+ int w= p->width;
+ int h= p->height;
+ int x, y;
+// int bits= put_bits_count(&s->c.pb);
+
+ if (!s->memc_only) {
+ //FIXME optimize
+ if(pict->data[plane_index]) //FIXME gray hack
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ s->spatial_idwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<<FRAC_BITS;
+ }
+ }
+ predict_plane(s, s->spatial_idwt_buffer, plane_index, 0);
+
+ if( plane_index==0
+ && pict->pict_type == AV_PICTURE_TYPE_P
+ && !(avctx->flags&CODEC_FLAG_PASS2)
+ && s->m.me.scene_change_score > s->avctx->scenechange_threshold){
+ ff_init_range_encoder(c, buf, buf_size);
+ ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
+ pict->pict_type= AV_PICTURE_TYPE_I;
+ s->keyframe=1;
+ s->current_picture.key_frame=1;
+ goto redo_frame;
+ }
+
+ if(s->qlog == LOSSLESS_QLOG){
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ s->spatial_dwt_buffer[y*w + x]= (s->spatial_idwt_buffer[y*w + x] + (1<<(FRAC_BITS-1))-1)>>FRAC_BITS;
+ }
+ }
+ }else{
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ s->spatial_dwt_buffer[y*w + x]=s->spatial_idwt_buffer[y*w + x]<<ENCODER_EXTRA_BITS;
+ }
+ }
+ }
+
+ /* if(QUANTIZE2)
+ dwt_quantize(s, p, s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type);
+ else*/
+ ff_spatial_dwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
+
+ if(s->pass1_rc && plane_index==0){
+ int delta_qlog = ratecontrol_1pass(s, pict);
+ if (delta_qlog <= INT_MIN)
+ return -1;
+ if(delta_qlog){
+ //reordering qlog in the bitstream would eliminate this reset
+ ff_init_range_encoder(c, buf, buf_size);
+ memcpy(s->header_state, rc_header_bak, sizeof(s->header_state));
+ memcpy(s->block_state, rc_block_bak, sizeof(s->block_state));
+ encode_header(s);
+ encode_blocks(s, 0);
+ }
+ }
+
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &p->band[level][orientation];
+
+ if(!QUANTIZE2)
+ quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias);
+ if(orientation==0)
+ decorrelate(s, b, b->ibuf, b->stride, pict->pict_type == AV_PICTURE_TYPE_P, 0);
+ encode_subband(s, b, b->ibuf, b->parent ? b->parent->ibuf : NULL, b->stride, orientation);
+ assert(b->parent==NULL || b->parent->stride == b->stride*2);
+ if(orientation==0)
+ correlate(s, b, b->ibuf, b->stride, 1, 0);
+ }
+ }
+
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &p->band[level][orientation];
+
+ dequantize(s, b, b->ibuf, b->stride);
+ }
+ }
+
+ ff_spatial_idwt(s->spatial_idwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
+ if(s->qlog == LOSSLESS_QLOG){
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ s->spatial_idwt_buffer[y*w + x]<<=FRAC_BITS;
+ }
+ }
+ }
+ predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
+ }else{
+ //ME/MC only
+ if(pict->pict_type == AV_PICTURE_TYPE_I){
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]=
+ pict->data[plane_index][y*pict->linesize[plane_index] + x];
+ }
+ }
+ }else{
+ memset(s->spatial_idwt_buffer, 0, sizeof(IDWTELEM)*w*h);
+ predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
+ }
+ }
+ if(s->avctx->flags&CODEC_FLAG_PSNR){
+ int64_t error= 0;
+
+ if(pict->data[plane_index]) //FIXME gray hack
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ int d= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x];
+ error += d*d;
+ }
+ }
+ s->avctx->error[plane_index] += error;
+ s->current_picture.error[plane_index] = error;
+ }
+
+ }
+
+ update_last_header_values(s);
+
+ ff_snow_release_buffer(avctx);
+
+ s->current_picture.coded_picture_number = avctx->frame_number;
+ s->current_picture.pict_type = pict->pict_type;
+ s->current_picture.quality = pict->quality;
+ s->m.frame_bits = 8*(s->c.bytestream - s->c.bytestream_start);
+ s->m.p_tex_bits = s->m.frame_bits - s->m.misc_bits - s->m.mv_bits;
+ s->m.current_picture.f.display_picture_number =
+ s->m.current_picture.f.coded_picture_number = avctx->frame_number;
+ s->m.current_picture.f.quality = pict->quality;
+ s->m.total_bits += 8*(s->c.bytestream - s->c.bytestream_start);
+ if(s->pass1_rc)
+ if (ff_rate_estimate_qscale(&s->m, 0) < 0)
+ return -1;
+ if(avctx->flags&CODEC_FLAG_PASS1)
+ ff_write_pass1_stats(&s->m);
+ s->m.last_pict_type = s->m.pict_type;
+ avctx->frame_bits = s->m.frame_bits;
+ avctx->mv_bits = s->m.mv_bits;
+ avctx->misc_bits = s->m.misc_bits;
+ avctx->p_tex_bits = s->m.p_tex_bits;
+
+ emms_c();
+
+ return ff_rac_terminate(c);
+}
+
+static av_cold int encode_end(AVCodecContext *avctx)
+{
+ SnowContext *s = avctx->priv_data;
+
+ ff_snow_common_end(s);
+ if (s->input_picture.data[0])
+ avctx->release_buffer(avctx, &s->input_picture);
+ av_free(avctx->stats_out);
+
+ return 0;
+}
+
+#define OFFSET(x) offsetof(SnowContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "memc_only", "Only do ME/MC (I frames -> ref, P frame -> ME+MC).", OFFSET(memc_only), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
+ { NULL },
+};
+
+static const AVClass snowenc_class = {
+ .class_name = "snow encoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_snow_encoder = {
+ .name = "snow",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SNOW,
+ .priv_data_size = sizeof(SnowContext),
+ .init = encode_init,
+ .encode = encode_frame,
+ .close = encode_end,
+ .long_name = NULL_IF_CONFIG_SMALL("Snow"),
+ .priv_class = &snowenc_class,
+};
+#endif
diff --git a/libavcodec/sp5x.h b/libavcodec/sp5x.h
index 23c893b..1577302 100644
--- a/libavcodec/sp5x.h
+++ b/libavcodec/sp5x.h
@@ -235,100 +235,4 @@ static const uint8_t sp5x_quant_table[20][64]=
124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124 }
};
-#if 0
-/* 4NF-M, not ZigZag */
-static const uint8_t sp5x_quant_table_orig[18][64] =
-{
- /* index 0, Q50 */
- { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68,109,103, 77, 24, 35, 55, 64, 81,104,113, 92,
- 49, 64, 78, 87,103,121,120,101, 72, 92, 95, 98,112,100,103, 99 },
- { 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 },
-
- /* index 1, Q70 */
- { 10, 7, 6, 10, 14, 24, 31, 37, 7, 7, 8, 11, 16, 35, 36, 33,
- 8, 8, 10, 14, 24, 34, 41, 34, 8, 10, 13, 17, 31, 52, 48, 37,
- 11, 13, 22, 34, 41, 65, 62, 46, 14, 21, 33, 38, 49, 62, 68, 55,
- 29, 38, 47, 52, 62, 73, 72, 61, 43, 55, 57, 59, 67, 60, 62, 59 },
- { 10, 11, 14, 28, 59, 59, 59, 59, 11, 13, 16, 40, 59, 59, 59, 59,
- 14, 16, 34, 59, 59, 59, 59, 59, 28, 40, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59 },
-
- /* index 2, Q80 */
- { 6, 4, 4, 6, 10, 16, 20, 24, 5, 5, 6, 8, 10, 23, 24, 22,
- 6, 5, 6, 10, 16, 23, 28, 22, 6, 7, 9, 12, 20, 35, 32, 25,
- 7, 9, 15, 22, 27, 44, 41, 31, 10, 14, 22, 26, 32, 42, 45, 37,
- 20, 26, 31, 35, 41, 48, 48, 40, 29, 37, 38, 39, 45, 40, 41, 40 },
- { 7, 7, 10, 19, 40, 40, 40, 40, 7, 8, 10, 26, 40, 40, 40, 40,
- 10, 10, 22, 40, 40, 40, 40, 40, 19, 26, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 },
-
- /* index 3, Q85 */
- { 5, 3, 3, 5, 7, 12, 15, 18, 4, 4, 4, 6, 8, 17, 18, 17,
- 4, 4, 5, 7, 12, 17, 21, 17, 4, 5, 7, 9, 15, 26, 24, 19,
- 5, 7, 11, 17, 20, 33, 31, 23, 7, 11, 17, 19, 24, 31, 34, 28,
- 15, 19, 23, 26, 31, 36, 36, 30, 22, 28, 29, 29, 34, 30, 31, 30 },
- { 5, 5, 7, 14, 30, 30, 30, 30, 5, 6, 8, 20, 30, 30, 30, 30,
- 7, 8, 17, 30, 30, 30, 30, 30, 14, 20, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 },
-
- /* index 4, Q90 */
- { 3, 2, 2, 3, 5, 8, 10, 12, 2, 2, 3, 4, 5, 12, 12, 11,
- 3, 3, 3, 5, 8, 11, 14, 11, 3, 3, 4, 6, 10, 17, 16, 12,
- 4, 4, 7, 11, 14, 22, 21, 15, 5, 7, 11, 13, 16, 21, 23, 18,
- 10, 13, 16, 17, 21, 24, 24, 20, 14, 18, 19, 20, 22, 20, 21, 20 },
- { 3, 4, 5, 9, 20, 20, 20, 20, 4, 4, 5, 13, 20, 20, 20, 20,
- 5, 5, 11, 20, 20, 20, 20, 20, 9, 13, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 },
-
- /* index 5, Q60 */
- { 13, 9, 8, 13, 19, 32, 41, 49, 10, 10, 11, 15, 21, 46, 48, 44,
- 11, 10, 13, 19, 32, 46, 55, 45, 11, 14, 18, 23, 41, 70, 64, 50,
- 14, 18, 30, 45, 54, 87, 82, 62, 19, 28, 44, 51, 65, 83, 90, 74,
- 39, 51, 62, 70, 82, 97, 96, 81, 58, 74, 76, 78, 90, 80, 82, 79 },
- { 14, 14, 19, 38, 79, 79, 79, 79, 14, 17, 21, 53, 79, 79, 79, 79,
- 19, 21, 45, 79, 79, 79, 79, 79, 38, 53, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79 },
-
- /* index 6, Q25 */
- { 32, 22, 20, 32, 48, 80,102,122, 24, 24, 28, 38, 52,116,120,110,
- 28, 26, 32, 48, 80,114,138,112, 28, 34, 44, 58,102,174,160,124,
- 36, 44, 74,112,136,218,206,154, 48, 70,110,128,162,208,226,184,
- 98,128,156,174,206,242,240,202,144,184,190,196,224,200,206,198 },
- { 34, 36, 48, 94,198,198,198,198, 36, 42, 52,132,198,198,198,198,
- 48, 52,112,198,198,198,198,198, 94,132,198,198,198,198,198,198,
- 198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
- 198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198 },
-
- /* index 7, Q95 */
- { 2, 1, 1, 2, 2, 4, 5, 6, 1, 1, 1, 2, 3, 6, 6, 6,
- 1, 1, 2, 2, 4, 6, 7, 6, 1, 2, 2, 3, 5, 9, 8, 6,
- 2, 2, 4, 6, 7, 11, 10, 8, 2, 4, 6, 6, 8, 10, 11, 9,
- 5, 6, 8, 9, 10, 12, 12, 10, 7, 9, 10, 10, 11, 10, 10, 10 },
- { 2, 2, 2, 5, 10, 10, 10, 10, 2, 2, 3, 7, 10, 10, 10, 10,
- 2, 3, 6, 10, 10, 10, 10, 10, 5, 7, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 },
-
- /* index 8, Q93 */
- { 2, 2, 1, 2, 3, 6, 7, 9, 2, 2, 2, 3, 4, 8, 8, 8,
- 2, 2, 2, 3, 6, 8, 10, 8, 2, 2, 3, 4, 7, 12, 11, 9,
- 3, 3, 5, 8, 10, 15, 14, 11, 3, 5, 8, 9, 11, 15, 16, 13,
- 7, 9, 11, 12, 14, 17, 17, 14, 10, 13, 13, 14, 16, 14, 14, 14 },
- { 2, 3, 3, 7, 14, 14, 14, 14, 3, 3, 4, 9, 14, 14, 14, 14,
- 3, 4, 8, 14, 14, 14, 14, 14, 7, 9, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 }
-};
-#endif
-
#endif /* AVCODEC_SP5X_H */
diff --git a/libavcodec/sp5xdec.c b/libavcodec/sp5xdec.c
index ae25733..4c42ab1 100644
--- a/libavcodec/sp5xdec.c
+++ b/libavcodec/sp5xdec.c
@@ -94,29 +94,25 @@ static int sp5x_decode_frame(AVCodecContext *avctx,
}
AVCodec ff_sp5x_decoder = {
- "sp5x",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SP5X,
- sizeof(MJpegDecodeContext),
- ff_mjpeg_decode_init,
- NULL,
- ff_mjpeg_decode_end,
- sp5x_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "sp5x",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SP5X,
+ .priv_data_size = sizeof(MJpegDecodeContext),
+ .init = ff_mjpeg_decode_init,
+ .close = ff_mjpeg_decode_end,
+ .decode = sp5x_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("Sunplus JPEG (SP5X)"),
};
AVCodec ff_amv_decoder = {
- "amv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_AMV,
- sizeof(MJpegDecodeContext),
- ff_mjpeg_decode_init,
- NULL,
- ff_mjpeg_decode_end,
- sp5x_decode_frame,
- 0,
+ .name = "amv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_AMV,
+ .priv_data_size = sizeof(MJpegDecodeContext),
+ .init = ff_mjpeg_decode_init,
+ .close = ff_mjpeg_decode_end,
+ .decode = sp5x_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("AMV Video"),
};
diff --git a/libavcodec/sparc/dsputil_vis.c b/libavcodec/sparc/dsputil_vis.c
index ab9258b..5a9fbc2 100644
--- a/libavcodec/sparc/dsputil_vis.c
+++ b/libavcodec/sparc/dsputil_vis.c
@@ -19,7 +19,7 @@
*/
/* The *no_round* functions have been added by James A. Morrison, 2003,2004.
- The vis code from libmpeg2 was adapted for ffmpeg by James A. Morrison.
+ The vis code from libmpeg2 was adapted for libavcodec by James A. Morrison.
*/
#include "config.h"
@@ -3953,10 +3953,11 @@ void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx)
{
/* VIS-specific optimizations */
int accel = vis_level ();
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
if (accel & ACCEL_SPARC_VIS) {
- if(avctx->idct_algo==FF_IDCT_SIMPLEVIS){
+ if (avctx->bits_per_raw_sample <= 8 &&
+ avctx->idct_algo == FF_IDCT_SIMPLEVIS) {
c->idct_put = ff_simple_idct_put_vis;
c->idct_add = ff_simple_idct_add_vis;
c->idct = ff_simple_idct_vis;
diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c
index cadffdf..455619e 100644
--- a/libavcodec/sunrast.c
+++ b/libavcodec/sunrast.c
@@ -46,6 +46,7 @@ static av_cold int sunrast_init(AVCodecContext *avctx) {
static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
int *data_size, AVPacket *avpkt) {
const uint8_t *buf = avpkt->data;
+ const uint8_t *buf_end = avpkt->data + avpkt->size;
SUNRASTContext * const s = avctx->priv_data;
AVFrame *picture = data;
AVFrame * const p = &s->picture;
@@ -53,6 +54,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
uint8_t *ptr;
const uint8_t *bufstart = buf;
+ if (avpkt->size < 32)
+ return AVERROR_INVALIDDATA;
+
if (AV_RB32(buf) != 0x59a66a95) {
av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n");
return -1;
@@ -64,21 +68,25 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
type = AV_RB32(buf+20);
maptype = AV_RB32(buf+24);
maplength = AV_RB32(buf+28);
+ buf += 32;
if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF) {
av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n");
return -1;
}
- if (type > RT_FORMAT_IFF) {
+ if (type < RT_OLD || type > RT_FORMAT_IFF) {
av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n");
return -1;
}
+ if (av_image_check_size(w, h, 0, avctx)) {
+ av_log(avctx, AV_LOG_ERROR, "invalid image size\n");
+ return -1;
+ }
if (maptype & ~1) {
av_log(avctx, AV_LOG_ERROR, "invalid colormap type\n");
return -1;
}
- buf += 32;
switch (depth) {
case 1:
@@ -98,8 +106,6 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
if (p->data[0])
avctx->release_buffer(avctx, p);
- if (av_image_check_size(w, h, 0, avctx))
- return -1;
if (w != avctx->width || h != avctx->height)
avcodec_set_dimensions(avctx, w, h);
if (avctx->get_buffer(avctx, p) < 0) {
@@ -109,6 +115,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
p->pict_type = AV_PICTURE_TYPE_I;
+ if (buf_end - buf < maplength)
+ return AVERROR_INVALIDDATA;
+
if (depth != 8 && maplength) {
av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n");
@@ -143,8 +152,11 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
uint8_t *end = ptr + h*stride;
x = 0;
- while (ptr != end) {
+ while (ptr != end && buf < buf_end) {
run = 1;
+ if (buf_end - buf < 1)
+ return AVERROR_INVALIDDATA;
+
if ((value = *buf++) == 0x80) {
run = *buf++ + 1;
if (run != 1)
@@ -163,6 +175,8 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
}
} else {
for (y=0; y<h; y++) {
+ if (buf_end - buf < len)
+ break;
memcpy(ptr, buf, len);
ptr += stride;
buf += alen;
@@ -185,15 +199,13 @@ static av_cold int sunrast_end(AVCodecContext *avctx) {
}
AVCodec ff_sunrast_decoder = {
- "sunrast",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SUNRAST,
- sizeof(SUNRASTContext),
- sunrast_init,
- NULL,
- sunrast_end,
- sunrast_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "sunrast",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SUNRAST,
+ .priv_data_size = sizeof(SUNRASTContext),
+ .init = sunrast_init,
+ .close = sunrast_end,
+ .decode = sunrast_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"),
};
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index 325cc12..69dbd1b 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -195,7 +195,8 @@ static const uint8_t string_table[256] = {
#define SVQ1_CALC_CODEBOOK_ENTRIES(cbook)\
codebook = (const uint32_t *) cbook[level];\
- bit_cache = get_bits (bitbuf, 4*stages);\
+ if (stages > 0)\
+ bit_cache = get_bits (bitbuf, 4*stages);\
/* calculate codebook entries for this vector */\
for (j=0; j < stages; j++) {\
entries[j] = (((bit_cache >> (4*(stages - j - 1))) & 0xF) + 16*j) << (level + 1);\
@@ -317,9 +318,9 @@ static int svq1_decode_motion_vector (GetBitContext *bitbuf, svq1_pmv *mv, svq1_
/* add median of motion vector predictors and clip result */
if (i == 1)
- mv->y = ((diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26;
+ mv->y = sign_extend(diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y), 6);
else
- mv->x = ((diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26;
+ mv->x = sign_extend(diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x), 6);
}
return 0;
@@ -690,12 +691,12 @@ static int svq1_decode_frame(AVCodecContext *avctx,
linesize= s->uvlinesize;
}
- current = s->current_picture.data[i];
+ current = s->current_picture.f.data[i];
if(s->pict_type==AV_PICTURE_TYPE_B){
- previous = s->next_picture.data[i];
+ previous = s->next_picture.f.data[i];
}else{
- previous = s->last_picture.data[i];
+ previous = s->last_picture.f.data[i];
}
if (s->pict_type == AV_PICTURE_TYPE_I) {
@@ -809,15 +810,14 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx)
AVCodec ff_svq1_decoder = {
- "svq1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SVQ1,
- sizeof(MpegEncContext),
- svq1_decode_init,
- NULL,
- svq1_decode_end,
- svq1_decode_frame,
- CODEC_CAP_DR1,
+ .name = "svq1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SVQ1,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = svq1_decode_init,
+ .close = svq1_decode_end,
+ .decode = svq1_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.flush= ff_mpeg_flush,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV410P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"),
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index fbeca80..80bae3c 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -113,10 +113,6 @@ static void svq1_write_header(SVQ1Context *s, int frame_type)
#define QUALITY_THRESHOLD 100
#define THRESHOLD_MULTIPLIER 0.6
-#if HAVE_ALTIVEC
-#undef vector
-#endif
-
static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){
int count, y, x, i, j, split, best_mean, best_score, best_count;
int best_vector[6];
@@ -160,7 +156,7 @@ static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *dec
}
best_count=0;
- best_score -= ((block_sum[0]*block_sum[0])>>(level+3));
+ best_score -= (int)(((unsigned)block_sum[0]*block_sum[0])>>(level+3));
best_mean= (block_sum[0] + (size>>1)) >> (level+3);
if(level<4){
@@ -284,11 +280,11 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane
s->m.avctx= s->avctx;
s->m.current_picture_ptr= &s->m.current_picture;
s->m.last_picture_ptr = &s->m.last_picture;
- s->m.last_picture.data[0]= ref_plane;
+ s->m.last_picture.f.data[0] = ref_plane;
s->m.linesize=
- s->m.last_picture.linesize[0]=
- s->m.new_picture.linesize[0]=
- s->m.current_picture.linesize[0]= stride;
+ s->m.last_picture.f.linesize[0] =
+ s->m.new_picture.f.linesize[0] =
+ s->m.current_picture.f.linesize[0] = stride;
s->m.width= width;
s->m.height= height;
s->m.mb_width= block_width;
@@ -318,9 +314,9 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane
s->m.current_picture.mb_mean= (uint8_t *)s->dummy;
s->m.current_picture.mb_var= (uint16_t*)s->dummy;
s->m.current_picture.mc_mb_var= (uint16_t*)s->dummy;
- s->m.current_picture.mb_type= s->dummy;
+ s->m.current_picture.f.mb_type = s->dummy;
- s->m.current_picture.motion_val[0]= s->motion_val8[plane] + 2;
+ s->m.current_picture.f.motion_val[0] = s->motion_val8[plane] + 2;
s->m.p_mv_table= s->motion_val16[plane] + s->m.mb_stride + 1;
s->m.dsp= s->dsp; //move
ff_init_me(&s->m);
@@ -328,7 +324,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane
s->m.me.dia_size= s->avctx->dia_size;
s->m.first_slice_line=1;
for (y = 0; y < block_height; y++) {
- s->m.new_picture.data[0]= src - y*16*stride; //ugly
+ s->m.new_picture.f.data[0] = src - y*16*stride; //ugly
s->m.mb_y= y;
for(i=0; i<16 && i + 16*y<height; i++){
@@ -461,7 +457,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane
s->rd_total += score[best];
for(i=5; i>=0; i--){
- ff_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]);
+ avpriv_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]);
}
if(best==0){
s->dsp.put_pixels_tab[0][0](decoded, temp, stride, 16);
@@ -540,7 +536,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
return -1;
}
-// align_put_bits(&s->pb);
+// avpriv_align_put_bits(&s->pb);
while(put_bits_count(&s->pb) & 31)
put_bits(&s->pb, 1, 0);
@@ -573,13 +569,13 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx)
AVCodec ff_svq1_encoder = {
- "svq1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SVQ1,
- sizeof(SVQ1Context),
- svq1_encode_init,
- svq1_encode_frame,
- svq1_encode_end,
+ .name = "svq1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SVQ1,
+ .priv_data_size = sizeof(SVQ1Context),
+ .init = svq1_encode_init,
+ .encode = svq1_encode_frame,
+ .close = svq1_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV410P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"),
};
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index 23ab209..3cd95ba 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -288,8 +288,8 @@ static inline void svq3_mc_dir_part(MpegEncContext *s,
}
/* form component predictions */
- dest = s->current_picture.data[0] + x + y*s->linesize;
- src = pic->data[0] + mx + my*s->linesize;
+ dest = s->current_picture.f.data[0] + x + y*s->linesize;
+ src = pic->f.data[0] + mx + my*s->linesize;
if (emu) {
s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, (width + 1), (height + 1),
@@ -309,8 +309,8 @@ static inline void svq3_mc_dir_part(MpegEncContext *s,
blocksize++;
for (i = 1; i < 3; i++) {
- dest = s->current_picture.data[i] + (x >> 1) + (y >> 1)*s->uvlinesize;
- src = pic->data[i] + mx + my*s->uvlinesize;
+ dest = s->current_picture.f.data[i] + (x >> 1) + (y >> 1) * s->uvlinesize;
+ src = pic->f.data[i] + mx + my * s->uvlinesize;
if (emu) {
s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->uvlinesize, (width + 1), (height + 1),
@@ -347,8 +347,8 @@ static inline int svq3_mc_dir(H264Context *h, int size, int mode, int dir,
if (mode != PREDICT_MODE) {
pred_motion(h, k, (part_width >> 2), dir, 1, &mx, &my);
} else {
- mx = s->next_picture.motion_val[0][b_xy][0]<<1;
- my = s->next_picture.motion_val[0][b_xy][1]<<1;
+ mx = s->next_picture.f.motion_val[0][b_xy][0] << 1;
+ my = s->next_picture.f.motion_val[0][b_xy][1] << 1;
if (dir == 0) {
mx = ((mx * h->frame_num_offset) / h->prev_frame_num_offset + 1) >> 1;
@@ -425,7 +425,9 @@ static inline int svq3_mc_dir(H264Context *h, int size, int mode, int dir,
}
/* write back motion vectors */
- fill_rectangle(s->current_picture.motion_val[dir][b_xy], part_width>>2, part_height>>2, h->b_stride, pack16to32(mx,my), 4);
+ fill_rectangle(s->current_picture.f.motion_val[dir][b_xy],
+ part_width >> 2, part_height >> 2, h->b_stride,
+ pack16to32(mx, my), 4);
}
}
@@ -448,7 +450,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
h->topright_samples_available = 0xFFFF;
if (mb_type == 0) { /* SKIP */
- if (s->pict_type == AV_PICTURE_TYPE_P || s->next_picture.mb_type[mb_xy] == -1) {
+ if (s->pict_type == AV_PICTURE_TYPE_P || s->next_picture.f.mb_type[mb_xy] == -1) {
svq3_mc_dir_part(s, 16*s->mb_x, 16*s->mb_y, 16, 16, 0, 0, 0, 0, 0, 0);
if (s->pict_type == AV_PICTURE_TYPE_B) {
@@ -457,7 +459,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
mb_type = MB_TYPE_SKIP;
} else {
- mb_type = FFMIN(s->next_picture.mb_type[mb_xy], 6);
+ mb_type = FFMIN(s->next_picture.f.mb_type[mb_xy], 6);
if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 0, 0) < 0)
return -1;
if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 1, 1) < 0)
@@ -486,7 +488,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
for (m = 0; m < 2; m++) {
if (s->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1]+6] != -1) {
for (i = 0; i < 4; i++) {
- *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - 1 + i*h->b_stride];
+ *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = *(uint32_t *) s->current_picture.f.motion_val[m][b_xy - 1 + i*h->b_stride];
}
} else {
for (i = 0; i < 4; i++) {
@@ -494,18 +496,18 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
}
}
if (s->mb_y > 0) {
- memcpy(h->mv_cache[m][scan8[0] - 1*8], s->current_picture.motion_val[m][b_xy - h->b_stride], 4*2*sizeof(int16_t));
+ memcpy(h->mv_cache[m][scan8[0] - 1*8], s->current_picture.f.motion_val[m][b_xy - h->b_stride], 4*2*sizeof(int16_t));
memset(&h->ref_cache[m][scan8[0] - 1*8], (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);
if (s->mb_x < (s->mb_width - 1)) {
- *(uint32_t *) h->mv_cache[m][scan8[0] + 4 - 1*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - h->b_stride + 4];
+ *(uint32_t *) h->mv_cache[m][scan8[0] + 4 - 1*8] = *(uint32_t *) s->current_picture.f.motion_val[m][b_xy - h->b_stride + 4];
h->ref_cache[m][scan8[0] + 4 - 1*8] =
(h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride + 1]+6] == -1 ||
h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride ] ] == -1) ? PART_NOT_AVAILABLE : 1;
}else
h->ref_cache[m][scan8[0] + 4 - 1*8] = PART_NOT_AVAILABLE;
if (s->mb_x > 0) {
- *(uint32_t *) h->mv_cache[m][scan8[0] - 1 - 1*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - h->b_stride - 1];
+ *(uint32_t *) h->mv_cache[m][scan8[0] - 1 - 1*8] = *(uint32_t *) s->current_picture.f.motion_val[m][b_xy - h->b_stride - 1];
h->ref_cache[m][scan8[0] - 1 - 1*8] = (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride - 1]+3] == -1) ? PART_NOT_AVAILABLE : 1;
}else
h->ref_cache[m][scan8[0] - 1 - 1*8] = PART_NOT_AVAILABLE;
@@ -526,7 +528,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
return -1;
} else {
for (i = 0; i < 4; i++) {
- memset(s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t));
+ memset(s->current_picture.f.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t));
}
}
if (mb_type != 1) {
@@ -534,7 +536,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
return -1;
} else {
for (i = 0; i < 4; i++) {
- memset(s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t));
+ memset(s->current_picture.f.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t));
}
}
}
@@ -589,7 +591,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
}
}
- ff_h264_write_back_intra_pred_mode(h);
+ write_back_intra_pred_mode(h);
if (mb_type == 8) {
ff_h264_check_intra4x4_pred_mode(h);
@@ -621,11 +623,11 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
if (!IS_INTER(mb_type) && s->pict_type != AV_PICTURE_TYPE_I) {
for (i = 0; i < 4; i++) {
- memset(s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t));
+ memset(s->current_picture.f.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t));
}
if (s->pict_type == AV_PICTURE_TYPE_B) {
for (i = 0; i < 4; i++) {
- memset(s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t));
+ memset(s->current_picture.f.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t));
}
}
}
@@ -706,7 +708,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
}
h->cbp= cbp;
- s->current_picture.mb_type[mb_xy] = mb_type;
+ s->current_picture.f.mb_type[mb_xy] = mb_type;
if (IS_INTRA(mb_type)) {
h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8);
@@ -922,7 +924,10 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
h->b_stride = 4*s->mb_width;
- ff_h264_alloc_tables(h);
+ if (ff_h264_alloc_tables(h) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n");
+ return AVERROR(ENOMEM);
+ }
}
return 0;
@@ -966,8 +971,8 @@ static int svq3_decode_frame(AVCodecContext *avctx,
}
/* for skipping the frame */
- s->current_picture.pict_type = s->pict_type;
- s->current_picture.key_frame = (s->pict_type == AV_PICTURE_TYPE_I);
+ s->current_picture.f.pict_type = s->pict_type;
+ s->current_picture.f.key_frame = (s->pict_type == AV_PICTURE_TYPE_I);
/* Skip B-frames if we do not have reference frames. */
if (s->last_picture_ptr == NULL && s->pict_type == AV_PICTURE_TYPE_B)
@@ -1051,7 +1056,7 @@ static int svq3_decode_frame(AVCodecContext *avctx,
}
if (s->pict_type != AV_PICTURE_TYPE_B && !s->low_delay) {
- s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
+ s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] =
(s->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
}
}
@@ -1089,15 +1094,14 @@ static int svq3_decode_end(AVCodecContext *avctx)
}
AVCodec ff_svq3_decoder = {
- "svq3",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_SVQ3,
- sizeof(SVQ3Context),
- svq3_decode_init,
- NULL,
- svq3_decode_end,
- svq3_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+ .name = "svq3",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_SVQ3,
+ .priv_data_size = sizeof(SVQ3Context),
+ .init = svq3_decode_init,
+ .close = svq3_decode_end,
+ .decode = svq3_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_DELAY,
.long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"),
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_NONE},
};
diff --git a/libavcodec/tableprint.h b/libavcodec/tableprint.h
index c89f310..81bb9af 100644
--- a/libavcodec/tableprint.h
+++ b/libavcodec/tableprint.h
@@ -57,7 +57,8 @@ void write_##type##_2d_array(const void *arg, int len, int len2)\
/**
* @name Predefined functions for printing tables
- * \{
+ *
+ * @{
*/
void write_int8_t_array (const int8_t *, int);
void write_uint8_t_array (const uint8_t *, int);
@@ -68,7 +69,7 @@ void write_int8_t_2d_array (const void *, int, int);
void write_uint8_t_2d_array (const void *, int, int);
void write_uint32_t_2d_array(const void *, int, int);
void write_float_2d_array (const void *, int, int);
-/** \} */ // end of printfuncs group
+/** @} */ // end of printfuncs group
#define WRITE_ARRAY(prefix, type, name) \
do { \
diff --git a/libavcodec/targa.c b/libavcodec/targa.c
index e57fd8b..b821d74 100644
--- a/libavcodec/targa.c
+++ b/libavcodec/targa.c
@@ -254,15 +254,13 @@ static av_cold int targa_end(AVCodecContext *avctx){
}
AVCodec ff_targa_decoder = {
- "targa",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TARGA,
- sizeof(TargaContext),
- targa_init,
- NULL,
- targa_end,
- decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "targa",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TARGA,
+ .priv_data_size = sizeof(TargaContext),
+ .init = targa_init,
+ .close = targa_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"),
};
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index 401c4d2..7f018fc 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -31,17 +31,20 @@
#include "avcodec.h"
/**
- * Waits for decoding threads to finish and resets internal
- * state. Called by avcodec_flush_buffers().
+ * Wait for decoding threads to finish and reset internal state.
+ * Called by avcodec_flush_buffers().
*
* @param avctx The context.
*/
void ff_thread_flush(AVCodecContext *avctx);
/**
- * Submits a new frame to a decoding thread.
+ * Submit a new frame to a decoding thread.
* Returns the next available frame in picture. *got_picture_ptr
* will be 0 if none is available.
+ * The return value on success is the size of the consumed packet for
+ * compatiblity with avcodec_decode_video2(). This means the decoder
+ * has to consume the full packet.
*
* Parameters are the same as avcodec_decode_video2().
*/
@@ -59,8 +62,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, AVFrame *picture,
void ff_thread_finish_setup(AVCodecContext *avctx);
/**
- * Notifies later decoding threads when part of their reference picture
- * is ready.
+ * Notify later decoding threads when part of their reference picture is ready.
* Call this when some part of the picture is finished decoding.
* Later calls with lower values of progress have no effect.
*
@@ -72,7 +74,7 @@ void ff_thread_finish_setup(AVCodecContext *avctx);
void ff_thread_report_progress(AVFrame *f, int progress, int field);
/**
- * Waits for earlier decoding threads to finish reference pictures
+ * Wait for earlier decoding threads to finish reference pictures.
* Call this before accessing some part of a picture, with a given
* value for progress, and it will return after the responsible decoding
* thread calls ff_thread_report_progress() with the same or
diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c
index 4468f00..12d5bce 100644
--- a/libavcodec/tiertexseqv.c
+++ b/libavcodec/tiertexseqv.c
@@ -25,7 +25,7 @@
*/
#include "avcodec.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
@@ -35,15 +35,19 @@ typedef struct SeqVideoContext {
} SeqVideoContext;
-static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsigned char *dst, int dst_size)
+static const unsigned char *seq_unpack_rle_block(const unsigned char *src,
+ const unsigned char *src_end,
+ unsigned char *dst, int dst_size)
{
int i, len, sz;
GetBitContext gb;
int code_table[64];
- /* get the rle codes (at most 64 bytes) */
- init_get_bits(&gb, src, 64 * 8);
+ /* get the rle codes */
+ init_get_bits(&gb, src, (src_end - src) * 8);
for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) {
+ if (get_bits_left(&gb) < 4)
+ return NULL;
code_table[i] = get_sbits(&gb, 4);
sz += FFABS(code_table[i]);
}
@@ -54,8 +58,12 @@ static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsig
len = code_table[i];
if (len < 0) {
len = -len;
+ if (src_end - src < 1)
+ return NULL;
memset(dst, *src++, FFMIN(len, dst_size));
} else {
+ if (src_end - src < len)
+ return NULL;
memcpy(dst, src, FFMIN(len, dst_size));
src += len;
}
@@ -65,25 +73,30 @@ static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsig
return src;
}
-static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst)
+static const unsigned char *seq_decode_op1(SeqVideoContext *seq,
+ const unsigned char *src,
+ const unsigned char *src_end,
+ unsigned char *dst)
{
const unsigned char *color_table;
int b, i, len, bits;
GetBitContext gb;
unsigned char block[8 * 8];
+ if (src_end - src < 1)
+ return NULL;
len = *src++;
if (len & 0x80) {
switch (len & 3) {
case 1:
- src = seq_unpack_rle_block(src, block, sizeof(block));
+ src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
for (b = 0; b < 8; b++) {
memcpy(dst, &block[b * 8], 8);
dst += seq->frame.linesize[0];
}
break;
case 2:
- src = seq_unpack_rle_block(src, block, sizeof(block));
+ src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
for (i = 0; i < 8; i++) {
for (b = 0; b < 8; b++)
dst[b * seq->frame.linesize[0]] = block[i * 8 + b];
@@ -92,9 +105,13 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned
break;
}
} else {
+ if (len <= 0)
+ return NULL;
+ bits = ff_log2_tab[len - 1] + 1;
+ if (src_end - src < len + 8 * bits)
+ return NULL;
color_table = src;
src += len;
- bits = ff_log2_tab[len - 1] + 1;
init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8;
for (b = 0; b < 8; b++) {
for (i = 0; i < 8; i++)
@@ -106,10 +123,16 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned
return src;
}
-static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst)
+static const unsigned char *seq_decode_op2(SeqVideoContext *seq,
+ const unsigned char *src,
+ const unsigned char *src_end,
+ unsigned char *dst)
{
int i;
+ if (src_end - src < 8 * 8)
+ return NULL;
+
for (i = 0; i < 8; i++) {
memcpy(dst, src, 8);
src += 8;
@@ -119,11 +142,16 @@ static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned
return src;
}
-static const unsigned char *seq_decode_op3(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst)
+static const unsigned char *seq_decode_op3(SeqVideoContext *seq,
+ const unsigned char *src,
+ const unsigned char *src_end,
+ unsigned char *dst)
{
int pos, offset;
do {
+ if (src_end - src < 2)
+ return NULL;
pos = *src++;
offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7);
dst[offset] = *src++;
@@ -132,8 +160,9 @@ static const unsigned char *seq_decode_op3(SeqVideoContext *seq, const unsigned
return src;
}
-static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size)
+static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size)
{
+ const unsigned char *data_end = data + data_size;
GetBitContext gb;
int flags, i, j, x, y, op;
unsigned char c[3];
@@ -144,6 +173,8 @@ static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int
if (flags & 1) {
palette = (uint32_t *)seq->frame.data[1];
+ if (data_end - data < 256 * 3)
+ return AVERROR_INVALIDDATA;
for (i = 0; i < 256; i++) {
for (j = 0; j < 3; j++, data++)
c[j] = (*data << 2) | (*data >> 4);
@@ -153,6 +184,8 @@ static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int
}
if (flags & 2) {
+ if (data_end - data < 128)
+ return AVERROR_INVALIDDATA;
init_get_bits(&gb, data, 128 * 8); data += 128;
for (y = 0; y < 128; y += 8)
for (x = 0; x < 256; x += 8) {
@@ -160,17 +193,20 @@ static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int
op = get_bits(&gb, 2);
switch (op) {
case 1:
- data = seq_decode_op1(seq, data, dst);
+ data = seq_decode_op1(seq, data, data_end, dst);
break;
case 2:
- data = seq_decode_op2(seq, data, dst);
+ data = seq_decode_op2(seq, data, data_end, dst);
break;
case 3:
- data = seq_decode_op3(seq, data, dst);
+ data = seq_decode_op3(seq, data, data_end, dst);
break;
}
+ if (!data)
+ return AVERROR_INVALIDDATA;
}
}
+ return 0;
}
static av_cold int seqvideo_decode_init(AVCodecContext *avctx)
@@ -201,7 +237,8 @@ static int seqvideo_decode_frame(AVCodecContext *avctx,
return -1;
}
- seqvideo_decode(seq, buf, buf_size);
+ if (seqvideo_decode(seq, buf, buf_size))
+ return AVERROR_INVALIDDATA;
*data_size = sizeof(AVFrame);
*(AVFrame *)data = seq->frame;
@@ -220,14 +257,13 @@ static av_cold int seqvideo_decode_end(AVCodecContext *avctx)
}
AVCodec ff_tiertexseqvideo_decoder = {
- "tiertexseqvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TIERTEXSEQVIDEO,
- sizeof(SeqVideoContext),
- seqvideo_decode_init,
- NULL,
- seqvideo_decode_end,
- seqvideo_decode_frame,
- CODEC_CAP_DR1,
+ .name = "tiertexseqvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TIERTEXSEQVIDEO,
+ .priv_data_size = sizeof(SeqVideoContext),
+ .init = seqvideo_decode_init,
+ .close = seqvideo_decode_end,
+ .decode = seqvideo_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"),
};
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 08cd3b0..a88d0f9 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -20,10 +20,11 @@
*/
/**
- * TIFF image decoder
* @file
+ * TIFF image decoder
* @author Konstantin Shishkov
*/
+
#include "avcodec.h"
#if CONFIG_ZLIB
#include <zlib.h>
@@ -172,6 +173,8 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin
}
switch(s->compr){
case TIFF_RAW:
+ if (ssrc + size - src < width)
+ return AVERROR_INVALIDDATA;
if (!s->fill_order) {
memcpy(dst, src, width);
} else {
@@ -279,6 +282,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *
uint32_t *pal;
const uint8_t *rp, *gp, *bp;
+ if (end_buf - buf < 12)
+ return -1;
tag = tget_short(&buf, s->le);
type = tget_short(&buf, s->le);
count = tget_long(&buf, s->le);
@@ -338,7 +343,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *
case TIFF_SHORT:
case TIFF_LONG:
s->bpp = 0;
- for(i = 0; i < count; i++) s->bpp += tget(&buf, type, s->le);
+ for(i = 0; i < count && buf < end_buf; i++) s->bpp += tget(&buf, type, s->le);
break;
default:
s->bpp = -1;
@@ -452,6 +457,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *
case TIFF_PAL:
pal = (uint32_t *) s->palette;
off = type_sizes[type];
+ if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3)
+ return -1;
rp = buf;
gp = buf + count / 3 * off;
bp = buf + count / 3 * off * 2;
@@ -494,12 +501,16 @@ static int decode_frame(AVCodecContext *avctx,
AVFrame *picture = data;
AVFrame * const p= (AVFrame*)&s->picture;
const uint8_t *orig_buf = buf, *end_buf = buf + buf_size;
- int id, le, off, ret;
+ unsigned off;
+ int id, le, ret;
int i, j, entries;
- int stride, soff, ssize;
+ int stride;
+ unsigned soff, ssize;
uint8_t *dst;
//parse image header
+ if (end_buf - buf < 8)
+ return AVERROR_INVALIDDATA;
id = AV_RL16(buf); buf += 2;
if(id == 0x4949) le = 1;
else if(id == 0x4D4D) le = 0;
@@ -519,9 +530,9 @@ static int decode_frame(AVCodecContext *avctx,
}
/* parse image file directory */
off = tget_long(&buf, le);
- if(orig_buf + off + 14 >= end_buf){
+ if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) {
av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
buf = orig_buf + off;
entries = tget_short(&buf, le);
@@ -545,23 +556,23 @@ static int decode_frame(AVCodecContext *avctx,
stride = p->linesize[0];
dst = p->data[0];
for(i = 0; i < s->height; i += s->rps){
- if(s->stripsizes)
+ if(s->stripsizes) {
+ if (s->stripsizes >= end_buf)
+ return AVERROR_INVALIDDATA;
ssize = tget(&s->stripsizes, s->sstype, s->le);
- else
+ } else
ssize = s->stripsize;
- if (ssize > buf_size) {
- av_log(avctx, AV_LOG_ERROR, "Buffer size is smaller than strip size\n");
- return -1;
- }
-
if(s->stripdata){
+ if (s->stripdata >= end_buf)
+ return AVERROR_INVALIDDATA;
soff = tget(&s->stripdata, s->sot, s->le);
}else
soff = s->stripoff;
- if (soff < 0) {
- av_log(avctx, AV_LOG_ERROR, "Invalid stripoff: %d\n", soff);
- return AVERROR(EINVAL);
+
+ if (soff > buf_size || ssize > buf_size - soff) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
+ return -1;
}
if(tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize, FFMIN(s->rps, s->height - i)) < 0)
break;
@@ -620,15 +631,13 @@ static av_cold int tiff_end(AVCodecContext *avctx)
}
AVCodec ff_tiff_decoder = {
- "tiff",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TIFF,
- sizeof(TiffContext),
- tiff_init,
- NULL,
- tiff_end,
- decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "tiff",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TIFF,
+ .priv_data_size = sizeof(TiffContext),
+ .init = tiff_init,
+ .close = tiff_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
};
diff --git a/libavcodec/tiff.h b/libavcodec/tiff.h
index cd7ec83..cf890d6 100644
--- a/libavcodec/tiff.h
+++ b/libavcodec/tiff.h
@@ -20,10 +20,11 @@
*/
/**
- * TIFF tables
* @file
+ * TIFF tables
* @author Konstantin Shishkov
*/
+
#ifndef AVCODEC_TIFF_H
#define AVCODEC_TIFF_H
diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index 5cff13b..3b2b829 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -20,10 +20,14 @@
*/
/**
- * TIFF image encoder
* @file
+ * TIFF image encoder
* @author Bartlomiej Wolowiec
*/
+
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+
#include "avcodec.h"
#if CONFIG_ZLIB
#include <zlib.h>
@@ -42,6 +46,7 @@ static const uint8_t type_sizes2[6] = {
};
typedef struct TiffEncoderContext {
+ AVClass *class; ///< for private options
AVCodecContext *avctx;
AVFrame picture;
@@ -216,6 +221,7 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf,
uint8_t *yuv_line = NULL;
int shift_h, shift_v;
+ s->avctx = avctx;
s->buf_start = buf;
s->buf = &ptr;
s->buf_size = buf_size;
@@ -225,7 +231,11 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf,
p->key_frame = 1;
avctx->coded_frame= &s->picture;
- s->compr = TIFF_PACKBITS;
+#if FF_API_TIFFENC_COMPLEVEL
+ if (avctx->compression_level != FF_COMPRESSION_DEFAULT)
+ av_log(avctx, AV_LOG_WARNING, "Using compression_level to set compression "
+ "algorithm is deprecated. Please use the compression_algo private "
+ "option instead.\n");
if (avctx->compression_level == 0) {
s->compr = TIFF_RAW;
} else if(avctx->compression_level == 2) {
@@ -235,6 +245,7 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf,
s->compr = TIFF_DEFLATE;
#endif
}
+#endif
s->width = avctx->width;
s->height = avctx->height;
@@ -442,17 +453,32 @@ fail:
return ret;
}
+#define OFFSET(x) offsetof(TiffEncoderContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT, {TIFF_PACKBITS}, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
+ { "packbits", NULL, 0, AV_OPT_TYPE_CONST, {TIFF_PACKBITS}, 0, 0, VE, "compression_algo" },
+ { "raw", NULL, 0, AV_OPT_TYPE_CONST, {TIFF_RAW}, 0, 0, VE, "compression_algo" },
+ { "lzw", NULL, 0, AV_OPT_TYPE_CONST, {TIFF_LZW}, 0, 0, VE, "compression_algo" },
+#if CONFIG_ZLIB
+ { "deflate", NULL, 0, AV_OPT_TYPE_CONST, {TIFF_DEFLATE}, 0, 0, VE, "compression_algo" },
+#endif
+ { NULL },
+};
+
+static const AVClass tiffenc_class = {
+ .class_name = "TIFF encoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_tiff_encoder = {
- "tiff",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TIFF,
- sizeof(TiffEncoderContext),
- NULL,
- encode_frame,
- NULL,
- NULL,
- 0,
- NULL,
+ .name = "tiff",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TIFF,
+ .priv_data_size = sizeof(TiffEncoderContext),
+ .encode = encode_frame,
.pix_fmts =
(const enum PixelFormat[]) {PIX_FMT_RGB24, PIX_FMT_PAL8, PIX_FMT_GRAY8,
PIX_FMT_MONOBLACK, PIX_FMT_MONOWHITE,
@@ -461,4 +487,5 @@ AVCodec ff_tiff_encoder = {
PIX_FMT_YUV411P,
PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
+ .priv_class = &tiffenc_class,
};
diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c
index 80f3ac9..be809b3 100644
--- a/libavcodec/tmv.c
+++ b/libavcodec/tmv.c
@@ -20,10 +20,10 @@
*/
/**
- * 8088flex TMV video decoder
* @file
+ * 8088flex TMV video decoder
* @author Daniel Verkamp
- * @sa http://www.oldskool.org/pc/8088_Corruption
+ * @see http://www.oldskool.org/pc/8088_Corruption
*/
#include "avcodec.h"
@@ -82,6 +82,12 @@ static int tmv_decode_frame(AVCodecContext *avctx, void *data,
return avpkt->size;
}
+static av_cold int tmv_decode_init(AVCodecContext *avctx)
+{
+ avctx->pix_fmt = PIX_FMT_PAL8;
+ return 0;
+}
+
static av_cold int tmv_decode_close(AVCodecContext *avctx)
{
TMVContext *tmv = avctx->priv_data;
@@ -97,6 +103,7 @@ AVCodec ff_tmv_decoder = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_TMV,
.priv_data_size = sizeof(TMVContext),
+ .init = tmv_decode_init,
.close = tmv_decode_close,
.decode = tmv_decode_frame,
.capabilities = CODEC_CAP_DR1,
diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c
index 97330d1..fcf6004 100644
--- a/libavcodec/truemotion1.c
+++ b/libavcodec/truemotion1.c
@@ -892,14 +892,13 @@ static av_cold int truemotion1_decode_end(AVCodecContext *avctx)
}
AVCodec ff_truemotion1_decoder = {
- "truemotion1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TRUEMOTION1,
- sizeof(TrueMotion1Context),
- truemotion1_decode_init,
- NULL,
- truemotion1_decode_end,
- truemotion1_decode_frame,
- CODEC_CAP_DR1,
+ .name = "truemotion1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TRUEMOTION1,
+ .priv_data_size = sizeof(TrueMotion1Context),
+ .init = truemotion1_decode_init,
+ .close = truemotion1_decode_end,
+ .decode = truemotion1_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),
};
diff --git a/libavcodec/truemotion1data.h b/libavcodec/truemotion1data.h
index c94e3b5..e950450 100644
--- a/libavcodec/truemotion1data.h
+++ b/libavcodec/truemotion1data.h
@@ -2,9 +2,9 @@
* Duck Truemotion v1 Decoding Tables
*
* Data in this file was originally part of VpVision from On2 which is
- * distributed under the GNU GPL. It is redistributed with ffmpeg under the
- * GNU LGPL using the common understanding that data tables necessary for
- * decoding algorithms are not necessarily licensable.
+ * distributed under the GNU GPL. It is redistributed with libavcodec under
+ * the GNU LGPL using the common understanding that data tables necessary
+ * for decoding algorithms are not necessarily copyrightable.
*
* This file is part of Libav.
*
diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c
index 23abade..8d72bb6 100644
--- a/libavcodec/truemotion2.c
+++ b/libavcodec/truemotion2.c
@@ -864,14 +864,13 @@ static av_cold int decode_end(AVCodecContext *avctx){
}
AVCodec ff_truemotion2_decoder = {
- "truemotion2",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TRUEMOTION2,
- sizeof(TM2Context),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "truemotion2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TRUEMOTION2,
+ .priv_data_size = sizeof(TM2Context),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"),
};
diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c
index df9d918..5ef0a01 100644
--- a/libavcodec/truespeech.c
+++ b/libavcodec/truespeech.c
@@ -21,6 +21,8 @@
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
+#include "dsputil.h"
+#include "get_bits.h"
#include "truespeech_data.h"
/**
@@ -32,14 +34,17 @@
* TrueSpeech decoder context
*/
typedef struct {
+ AVFrame frame;
+ DSPContext dsp;
/* input data */
- int16_t vector[8]; //< input vector: 5/5/4/4/4/3/3/3
- int offset1[2]; //< 8-bit value, used in one copying offset
- int offset2[4]; //< 7-bit value, encodes offsets for copying and for two-point filter
- int pulseoff[4]; //< 4-bit offset of pulse values block
- int pulsepos[4]; //< 27-bit variable, encodes 7 pulse positions
- int pulseval[4]; //< 7x2-bit pulse values
- int flag; //< 1-bit flag, shows how to choose filters
+ uint8_t buffer[32];
+ int16_t vector[8]; ///< input vector: 5/5/4/4/4/3/3/3
+ int offset1[2]; ///< 8-bit value, used in one copying offset
+ int offset2[4]; ///< 7-bit value, encodes offsets for copying and for two-point filter
+ int pulseoff[4]; ///< 4-bit offset of pulse values block
+ int pulsepos[4]; ///< 27-bit variable, encodes 7 pulse positions
+ int pulseval[4]; ///< 7x2-bit pulse values
+ int flag; ///< 1-bit flag, shows how to choose filters
/* temporary data */
int filtbuf[146]; // some big vector used for storing filters
int prevfilt[8]; // filter from previous frame
@@ -54,100 +59,69 @@ typedef struct {
static av_cold int truespeech_decode_init(AVCodecContext * avctx)
{
-// TSContext *c = avctx->priv_data;
+ TSContext *c = avctx->priv_data;
+
+ if (avctx->channels != 1) {
+ av_log_ask_for_sample(avctx, "Unsupported channel count: %d\n", avctx->channels);
+ return AVERROR(EINVAL);
+ }
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ dsputil_init(&c->dsp, avctx);
+
+ avcodec_get_frame_defaults(&c->frame);
+ avctx->coded_frame = &c->frame;
+
return 0;
}
static void truespeech_read_frame(TSContext *dec, const uint8_t *input)
{
- uint32_t t;
-
- /* first dword */
- t = AV_RL32(input);
- input += 4;
-
- dec->flag = t & 1;
-
- dec->vector[0] = ts_codebook[0][(t >> 1) & 0x1F];
- dec->vector[1] = ts_codebook[1][(t >> 6) & 0x1F];
- dec->vector[2] = ts_codebook[2][(t >> 11) & 0xF];
- dec->vector[3] = ts_codebook[3][(t >> 15) & 0xF];
- dec->vector[4] = ts_codebook[4][(t >> 19) & 0xF];
- dec->vector[5] = ts_codebook[5][(t >> 23) & 0x7];
- dec->vector[6] = ts_codebook[6][(t >> 26) & 0x7];
- dec->vector[7] = ts_codebook[7][(t >> 29) & 0x7];
-
- /* second dword */
- t = AV_RL32(input);
- input += 4;
-
- dec->offset2[0] = (t >> 0) & 0x7F;
- dec->offset2[1] = (t >> 7) & 0x7F;
- dec->offset2[2] = (t >> 14) & 0x7F;
- dec->offset2[3] = (t >> 21) & 0x7F;
-
- dec->offset1[0] = ((t >> 28) & 0xF) << 4;
-
- /* third dword */
- t = AV_RL32(input);
- input += 4;
-
- dec->pulseval[0] = (t >> 0) & 0x3FFF;
- dec->pulseval[1] = (t >> 14) & 0x3FFF;
-
- dec->offset1[1] = (t >> 28) & 0x0F;
-
- /* fourth dword */
- t = AV_RL32(input);
- input += 4;
-
- dec->pulseval[2] = (t >> 0) & 0x3FFF;
- dec->pulseval[3] = (t >> 14) & 0x3FFF;
-
- dec->offset1[1] |= ((t >> 28) & 0x0F) << 4;
-
- /* fifth dword */
- t = AV_RL32(input);
- input += 4;
-
- dec->pulsepos[0] = (t >> 4) & 0x7FFFFFF;
-
- dec->pulseoff[0] = (t >> 0) & 0xF;
-
- dec->offset1[0] |= (t >> 31) & 1;
-
- /* sixth dword */
- t = AV_RL32(input);
- input += 4;
-
- dec->pulsepos[1] = (t >> 4) & 0x7FFFFFF;
-
- dec->pulseoff[1] = (t >> 0) & 0xF;
-
- dec->offset1[0] |= ((t >> 31) & 1) << 1;
-
- /* seventh dword */
- t = AV_RL32(input);
- input += 4;
-
- dec->pulsepos[2] = (t >> 4) & 0x7FFFFFF;
-
- dec->pulseoff[2] = (t >> 0) & 0xF;
-
- dec->offset1[0] |= ((t >> 31) & 1) << 2;
-
- /* eighth dword */
- t = AV_RL32(input);
- input += 4;
-
- dec->pulsepos[3] = (t >> 4) & 0x7FFFFFF;
-
- dec->pulseoff[3] = (t >> 0) & 0xF;
-
- dec->offset1[0] |= ((t >> 31) & 1) << 3;
-
+ GetBitContext gb;
+
+ dec->dsp.bswap_buf((uint32_t *)dec->buffer, (const uint32_t *)input, 8);
+ init_get_bits(&gb, dec->buffer, 32 * 8);
+
+ dec->vector[7] = ts_codebook[7][get_bits(&gb, 3)];
+ dec->vector[6] = ts_codebook[6][get_bits(&gb, 3)];
+ dec->vector[5] = ts_codebook[5][get_bits(&gb, 3)];
+ dec->vector[4] = ts_codebook[4][get_bits(&gb, 4)];
+ dec->vector[3] = ts_codebook[3][get_bits(&gb, 4)];
+ dec->vector[2] = ts_codebook[2][get_bits(&gb, 4)];
+ dec->vector[1] = ts_codebook[1][get_bits(&gb, 5)];
+ dec->vector[0] = ts_codebook[0][get_bits(&gb, 5)];
+ dec->flag = get_bits1(&gb);
+
+ dec->offset1[0] = get_bits(&gb, 4) << 4;
+ dec->offset2[3] = get_bits(&gb, 7);
+ dec->offset2[2] = get_bits(&gb, 7);
+ dec->offset2[1] = get_bits(&gb, 7);
+ dec->offset2[0] = get_bits(&gb, 7);
+
+ dec->offset1[1] = get_bits(&gb, 4);
+ dec->pulseval[1] = get_bits(&gb, 14);
+ dec->pulseval[0] = get_bits(&gb, 14);
+
+ dec->offset1[1] |= get_bits(&gb, 4) << 4;
+ dec->pulseval[3] = get_bits(&gb, 14);
+ dec->pulseval[2] = get_bits(&gb, 14);
+
+ dec->offset1[0] |= get_bits1(&gb);
+ dec->pulsepos[0] = get_bits_long(&gb, 27);
+ dec->pulseoff[0] = get_bits(&gb, 4);
+
+ dec->offset1[0] |= get_bits1(&gb) << 1;
+ dec->pulsepos[1] = get_bits_long(&gb, 27);
+ dec->pulseoff[1] = get_bits(&gb, 4);
+
+ dec->offset1[0] |= get_bits1(&gb) << 2;
+ dec->pulsepos[2] = get_bits_long(&gb, 27);
+ dec->pulseoff[2] = get_bits(&gb, 4);
+
+ dec->offset1[0] |= get_bits1(&gb) << 3;
+ dec->pulsepos[3] = get_bits_long(&gb, 27);
+ dec->pulseoff[3] = get_bits(&gb, 4);
}
static void truespeech_correlate_filter(TSContext *dec)
@@ -157,7 +131,7 @@ static void truespeech_correlate_filter(TSContext *dec)
for(i = 0; i < 8; i++){
if(i > 0){
- memcpy(tmp, dec->cvector, i * 2);
+ memcpy(tmp, dec->cvector, i * sizeof(*tmp));
for(j = 0; j < i; j++)
dec->cvector[j] = ((tmp[i - j - 1] * dec->vector[i]) +
(dec->cvector[j] << 15) + 0x4000) >> 15;
@@ -199,12 +173,13 @@ static void truespeech_apply_twopoint_filter(TSContext *dec, int quart)
t = dec->offset2[quart];
if(t == 127){
- memset(dec->newvec, 0, 60 * 2);
+ memset(dec->newvec, 0, 60 * sizeof(*dec->newvec));
return;
}
for(i = 0; i < 146; i++)
tmp[i] = dec->filtbuf[i];
off = (t / 25) + dec->offset1[quart >> 1] + 18;
+ off = av_clip(off, 0, 145);
ptr0 = tmp + 145 - off;
ptr1 = tmp + 146;
filter = (const int16_t*)ts_order2_coeffs + (t % 25) * 2;
@@ -224,7 +199,7 @@ static void truespeech_place_pulses(TSContext *dec, int16_t *out, int quart)
int16_t *ptr2;
int coef;
- memset(out, 0, 60 * 2);
+ memset(out, 0, 60 * sizeof(*out));
for(i = 0; i < 7; i++) {
t = dec->pulseval[quart] & 3;
dec->pulseval[quart] >>= 2;
@@ -263,8 +238,7 @@ static void truespeech_update_filters(TSContext *dec, int16_t *out, int quart)
{
int i;
- for(i = 0; i < 86; i++)
- dec->filtbuf[i] = dec->filtbuf[i + 60];
+ memmove(dec->filtbuf, &dec->filtbuf[60], 86 * sizeof(*dec->filtbuf));
for(i = 0; i < 60; i++){
dec->filtbuf[i + 86] = out[i] + dec->newvec[i] - (dec->newvec[i] >> 3);
out[i] += dec->newvec[i];
@@ -330,65 +304,66 @@ static void truespeech_save_prevvec(TSContext *c)
c->prevfilt[i] = c->cvector[i];
}
-static int truespeech_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int truespeech_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
TSContext *c = avctx->priv_data;
int i, j;
- short *samples = data;
- int consumed = 0;
- int16_t out_buf[240];
- int iterations;
+ int16_t *samples;
+ int iterations, ret;
- if (!buf_size)
- return 0;
+ iterations = buf_size / 32;
- if (buf_size < 32) {
+ if (!iterations) {
av_log(avctx, AV_LOG_ERROR,
"Too small input buffer (%d bytes), need at least 32 bytes\n", buf_size);
return -1;
}
- iterations = FFMIN(buf_size / 32, *data_size / 480);
+
+ /* get output buffer */
+ c->frame.nb_samples = iterations * 240;
+ if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (int16_t *)c->frame.data[0];
+
+ memset(samples, 0, iterations * 240 * sizeof(*samples));
+
for(j = 0; j < iterations; j++) {
- truespeech_read_frame(c, buf + consumed);
- consumed += 32;
+ truespeech_read_frame(c, buf);
+ buf += 32;
truespeech_correlate_filter(c);
truespeech_filters_merge(c);
- memset(out_buf, 0, 240 * 2);
for(i = 0; i < 4; i++) {
truespeech_apply_twopoint_filter(c, i);
- truespeech_place_pulses(c, out_buf + i * 60, i);
- truespeech_update_filters(c, out_buf + i * 60, i);
- truespeech_synth(c, out_buf + i * 60, i);
+ truespeech_place_pulses (c, samples, i);
+ truespeech_update_filters(c, samples, i);
+ truespeech_synth (c, samples, i);
+ samples += 60;
}
truespeech_save_prevvec(c);
-
- /* finally output decoded frame */
- for(i = 0; i < 240; i++)
- *samples++ = out_buf[i];
-
}
- *data_size = consumed * 15;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = c->frame;
- return consumed;
+ return buf_size;
}
AVCodec ff_truespeech_decoder = {
- "truespeech",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_TRUESPEECH,
- sizeof(TSContext),
- truespeech_decode_init,
- NULL,
- NULL,
- truespeech_decode_frame,
+ .name = "truespeech",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_TRUESPEECH,
+ .priv_data_size = sizeof(TSContext),
+ .init = truespeech_decode_init,
+ .decode = truespeech_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("DSP Group TrueSpeech"),
};
diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c
index 772906a..90d203d 100644
--- a/libavcodec/tscc.c
+++ b/libavcodec/tscc.c
@@ -155,7 +155,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
return -1;
}
c->bpp = avctx->bits_per_coded_sample;
- // buffer size for RLE 'best' case when 2-byte code preceeds each pixel and there may be padding after it too
+ // buffer size for RLE 'best' case when 2-byte code precedes each pixel and there may be padding after it too
c->decomp_size = (((avctx->width * c->bpp + 7) >> 3) + 3 * avctx->width + 2) * avctx->height + 2;
/* Allocate decompression buffer */
@@ -199,15 +199,14 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_tscc_decoder = {
- "camtasia",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TSCC,
- sizeof(CamtasiaContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("TechSmith Screen Capture Codec"),
+ .name = "camtasia",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TSCC,
+ .priv_data_size = sizeof(CamtasiaContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("TechSmith Screen Capture Codec"),
};
diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index fd5aa46..7ec5435 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -22,19 +22,19 @@
/**
* @file
* TTA (The Lossless True Audio) decoder
- * (www.true-audio.com or tta.corecodec.org)
+ * @see http://www.true-audio.com/
+ * @see http://tta.corecodec.org/
* @author Alex Beregszaszi
- *
*/
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
//#define DEBUG
#include <limits.h>
#include "avcodec.h"
#include "get_bits.h"
-#define FORMAT_INT 1
-#define FORMAT_FLOAT 3
+#define FORMAT_SIMPLE 1
+#define FORMAT_ENCRYPTED 2
#define MAX_ORDER 16
typedef struct TTAFilter {
@@ -56,9 +56,10 @@ typedef struct TTAChannel {
typedef struct TTAContext {
AVCodecContext *avctx;
+ AVFrame frame;
GetBitContext gb;
- int flags, channels, bps, is_float, data_length;
+ int format, channels, bps, data_length;
int frame_length, last_frame_length, total_frames;
int32_t *decode_buffer;
@@ -66,23 +67,6 @@ typedef struct TTAContext {
TTAChannel *ch_ctx;
} TTAContext;
-#if 0
-static inline int shift_1(int i)
-{
- if (i < 32)
- return 1 << i;
- else
- return 0x80000000; // 16 << 31
-}
-
-static inline int shift_16(int i)
-{
- if (i < 28)
- return 16 << i;
- else
- return 0x80000000; // 16 << 27
-}
-#else
static const uint32_t shift_1[] = {
0x00000001, 0x00000002, 0x00000004, 0x00000008,
0x00000010, 0x00000020, 0x00000040, 0x00000080,
@@ -97,7 +81,6 @@ static const uint32_t shift_1[] = {
};
static const uint32_t * const shift_16 = shift_1 + 4;
-#endif
static const int32_t ttafilter_configs[4][2] = {
{10, 1},
@@ -200,7 +183,7 @@ static int tta_get_unary(GetBitContext *gb)
int ret = 0;
// count ones
- while(get_bits1(gb))
+ while (get_bits_left(gb) > 0 && get_bits1(gb))
ret++;
return ret;
}
@@ -221,56 +204,55 @@ static av_cold int tta_decode_init(AVCodecContext * avctx)
{
/* signature */
skip_bits(&s->gb, 32);
-// if (get_bits_long(&s->gb, 32) != av_bswap32(AV_RL32("TTA1"))) {
-// av_log(s->avctx, AV_LOG_ERROR, "Missing magic\n");
-// return -1;
-// }
-
- s->flags = get_bits(&s->gb, 16);
- if (s->flags != 1 && s->flags != 3)
- {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid flags\n");
+
+ s->format = get_bits(&s->gb, 16);
+ if (s->format > 2) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid format\n");
return -1;
}
- s->is_float = (s->flags == FORMAT_FLOAT);
+ if (s->format == FORMAT_ENCRYPTED) {
+ av_log_missing_feature(s->avctx, "Encrypted TTA", 0);
+ return AVERROR(EINVAL);
+ }
avctx->channels = s->channels = get_bits(&s->gb, 16);
avctx->bits_per_coded_sample = get_bits(&s->gb, 16);
s->bps = (avctx->bits_per_coded_sample + 7) / 8;
avctx->sample_rate = get_bits_long(&s->gb, 32);
- if(avctx->sample_rate > 1000000){ //prevent FRAME_TIME * avctx->sample_rate from overflowing and sanity check
- av_log(avctx, AV_LOG_ERROR, "sample_rate too large\n");
- return -1;
- }
s->data_length = get_bits_long(&s->gb, 32);
skip_bits(&s->gb, 32); // CRC32 of header
- if (s->is_float)
- {
- avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
- av_log_ask_for_sample(s->avctx, "Unsupported sample format.\n");
- return -1;
+ if (s->channels == 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid number of channels\n");
+ return AVERROR_INVALIDDATA;
}
- else switch(s->bps) {
-// case 1: avctx->sample_fmt = AV_SAMPLE_FMT_U8; break;
- case 2: avctx->sample_fmt = AV_SAMPLE_FMT_S16; break;
-// case 3: avctx->sample_fmt = AV_SAMPLE_FMT_S24; break;
- case 4: avctx->sample_fmt = AV_SAMPLE_FMT_S32; break;
- default:
- av_log_ask_for_sample(s->avctx,
- "Invalid/unsupported sample format.\n");
- return -1;
+
+ switch(s->bps) {
+ case 2:
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ avctx->bits_per_raw_sample = 16;
+ break;
+ case 3:
+ avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+ avctx->bits_per_raw_sample = 24;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Invalid/unsupported sample format.\n");
+ return AVERROR_INVALIDDATA;
}
- // FIXME: horribly broken, but directly from reference source
-#define FRAME_TIME 1.04489795918367346939
- s->frame_length = (int)(FRAME_TIME * avctx->sample_rate);
+ // prevent overflow
+ if (avctx->sample_rate > 0x7FFFFF) {
+ av_log(avctx, AV_LOG_ERROR, "sample_rate too large\n");
+ return AVERROR(EINVAL);
+ }
+ s->frame_length = 256 * avctx->sample_rate / 245;
s->last_frame_length = s->data_length % s->frame_length;
s->total_frames = s->data_length / s->frame_length +
(s->last_frame_length ? 1 : 0);
- av_log(s->avctx, AV_LOG_DEBUG, "flags: %x chans: %d bps: %d rate: %d block: %d\n",
- s->flags, avctx->channels, avctx->bits_per_coded_sample, avctx->sample_rate,
+ av_log(s->avctx, AV_LOG_DEBUG, "format: %d chans: %d bps: %d rate: %d block: %d\n",
+ s->format, avctx->channels, avctx->bits_per_coded_sample, avctx->sample_rate,
avctx->block_align);
av_log(s->avctx, AV_LOG_DEBUG, "data_length: %d frame_length: %d last: %d total: %d\n",
s->data_length, s->frame_length, s->last_frame_length, s->total_frames);
@@ -285,165 +267,159 @@ static av_cold int tta_decode_init(AVCodecContext * avctx)
return -1;
}
- s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels);
+ if (s->bps == 2) {
+ s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels);
+ if (!s->decode_buffer)
+ return AVERROR(ENOMEM);
+ }
s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx));
- if (!s->ch_ctx)
+ if (!s->ch_ctx) {
+ av_freep(&s->decode_buffer);
return AVERROR(ENOMEM);
+ }
} else {
av_log(avctx, AV_LOG_ERROR, "Wrong extradata present\n");
return -1;
}
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
-static int tta_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int tta_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
TTAContext *s = avctx->priv_data;
- int i;
+ int i, ret;
+ int cur_chan = 0, framelen = s->frame_length;
+ int32_t *p;
init_get_bits(&s->gb, buf, buf_size*8);
- {
- int cur_chan = 0, framelen = s->frame_length;
- int32_t *p;
- if (*data_size < (framelen * s->channels * 2)) {
- av_log(avctx, AV_LOG_ERROR, "Output buffer size is too small.\n");
- return -1;
- }
- // FIXME: seeking
- s->total_frames--;
- if (!s->total_frames && s->last_frame_length)
- framelen = s->last_frame_length;
-
- // init per channel states
- for (i = 0; i < s->channels; i++) {
- s->ch_ctx[i].predictor = 0;
- ttafilter_init(&s->ch_ctx[i].filter, ttafilter_configs[s->bps-1][0], ttafilter_configs[s->bps-1][1]);
- rice_init(&s->ch_ctx[i].rice, 10, 10);
+ // FIXME: seeking
+ s->total_frames--;
+ if (!s->total_frames && s->last_frame_length)
+ framelen = s->last_frame_length;
+
+ /* get output buffer */
+ s->frame.nb_samples = framelen;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+
+ // decode directly to output buffer for 24-bit sample format
+ if (s->bps == 3)
+ s->decode_buffer = data;
+
+ // init per channel states
+ for (i = 0; i < s->channels; i++) {
+ s->ch_ctx[i].predictor = 0;
+ ttafilter_init(&s->ch_ctx[i].filter, ttafilter_configs[s->bps-1][0], ttafilter_configs[s->bps-1][1]);
+ rice_init(&s->ch_ctx[i].rice, 10, 10);
+ }
+
+ for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) {
+ int32_t *predictor = &s->ch_ctx[cur_chan].predictor;
+ TTAFilter *filter = &s->ch_ctx[cur_chan].filter;
+ TTARice *rice = &s->ch_ctx[cur_chan].rice;
+ uint32_t unary, depth, k;
+ int32_t value;
+
+ unary = tta_get_unary(&s->gb);
+
+ if (unary == 0) {
+ depth = 0;
+ k = rice->k0;
+ } else {
+ depth = 1;
+ k = rice->k1;
+ unary--;
}
- for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) {
- int32_t *predictor = &s->ch_ctx[cur_chan].predictor;
- TTAFilter *filter = &s->ch_ctx[cur_chan].filter;
- TTARice *rice = &s->ch_ctx[cur_chan].rice;
- uint32_t unary, depth, k;
- int32_t value;
-
- unary = tta_get_unary(&s->gb);
-
- if (unary == 0) {
- depth = 0;
- k = rice->k0;
- } else {
- depth = 1;
- k = rice->k1;
- unary--;
- }
+ if (get_bits_left(&s->gb) < k)
+ return -1;
- if (get_bits_left(&s->gb) < k)
+ if (k) {
+ if (k > MIN_CACHE_BITS)
return -1;
+ value = (unary << k) + get_bits(&s->gb, k);
+ } else
+ value = unary;
+
+ // FIXME: copy paste from original
+ switch (depth) {
+ case 1:
+ rice->sum1 += value - (rice->sum1 >> 4);
+ if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1])
+ rice->k1--;
+ else if(rice->sum1 > shift_16[rice->k1 + 1])
+ rice->k1++;
+ value += shift_1[rice->k0];
+ default:
+ rice->sum0 += value - (rice->sum0 >> 4);
+ if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0])
+ rice->k0--;
+ else if(rice->sum0 > shift_16[rice->k0 + 1])
+ rice->k0++;
+ }
- if (k) {
- if (k > MIN_CACHE_BITS)
- return -1;
- value = (unary << k) + get_bits(&s->gb, k);
- } else
- value = unary;
-
- // FIXME: copy paste from original
- switch (depth) {
- case 1:
- rice->sum1 += value - (rice->sum1 >> 4);
- if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1])
- rice->k1--;
- else if(rice->sum1 > shift_16[rice->k1 + 1])
- rice->k1++;
- value += shift_1[rice->k0];
- default:
- rice->sum0 += value - (rice->sum0 >> 4);
- if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0])
- rice->k0--;
- else if(rice->sum0 > shift_16[rice->k0 + 1])
- rice->k0++;
- }
-
- // extract coded value
+ // extract coded value
#define UNFOLD(x) (((x)&1) ? (++(x)>>1) : (-(x)>>1))
- *p = UNFOLD(value);
+ *p = UNFOLD(value);
- // run hybrid filter
- ttafilter_process(filter, p, 0);
+ // run hybrid filter
+ ttafilter_process(filter, p, 0);
- // fixed order prediction
+ // fixed order prediction
#define PRED(x, k) (int32_t)((((uint64_t)x << k) - x) >> k)
- switch (s->bps) {
- case 1: *p += PRED(*predictor, 4); break;
- case 2:
- case 3: *p += PRED(*predictor, 5); break;
- case 4: *p += *predictor; break;
- }
- *predictor = *p;
-
-#if 0
- // extract 32bit float from last two int samples
- if (s->is_float && ((p - data) & 1)) {
- uint32_t neg = *p & 0x80000000;
- uint32_t hi = *(p - 1);
- uint32_t lo = abs(*p) - 1;
-
- hi += (hi || lo) ? 0x3f80 : 0;
- // SWAP16: swap all the 16 bits
- *(p - 1) = (hi << 16) | SWAP16(lo) | neg;
- }
-#endif
-
- /*if ((get_bits_count(&s->gb)+7)/8 > buf_size)
- {
- av_log(NULL, AV_LOG_INFO, "overread!!\n");
- break;
- }*/
-
- // flip channels
- if (cur_chan < (s->channels-1))
- cur_chan++;
- else {
- // decorrelate in case of stereo integer
- if (!s->is_float && (s->channels > 1)) {
- int32_t *r = p - 1;
- for (*p += *r / 2; r > p - s->channels; r--)
- *r = *(r + 1) - *r;
- }
- cur_chan = 0;
+ switch (s->bps) {
+ case 1: *p += PRED(*predictor, 4); break;
+ case 2:
+ case 3: *p += PRED(*predictor, 5); break;
+ case 4: *p += *predictor; break;
+ }
+ *predictor = *p;
+
+ // flip channels
+ if (cur_chan < (s->channels-1))
+ cur_chan++;
+ else {
+ // decorrelate in case of stereo integer
+ if (s->channels > 1) {
+ int32_t *r = p - 1;
+ for (*p += *r / 2; r > p - s->channels; r--)
+ *r = *(r + 1) - *r;
}
+ cur_chan = 0;
}
+ }
- if (get_bits_left(&s->gb) < 32)
- return -1;
- skip_bits(&s->gb, 32); // frame crc
+ if (get_bits_left(&s->gb) < 32)
+ return -1;
+ skip_bits(&s->gb, 32); // frame crc
- // convert to output buffer
- switch(s->bps) {
- case 2: {
- uint16_t *samples = data;
- for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) {
-// *samples++ = (unsigned char)*p;
-// *samples++ = (unsigned char)(*p >> 8);
- *samples++ = *p;
- }
- *data_size = (uint8_t *)samples - (uint8_t *)data;
- break;
- }
- default:
- av_log(s->avctx, AV_LOG_ERROR, "Error, only 16bit samples supported!\n");
- }
+ // convert to output buffer
+ if (s->bps == 2) {
+ int16_t *samples = (int16_t *)s->frame.data[0];
+ for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
+ *samples++ = *p;
+ } else {
+ // shift samples for 24-bit sample format
+ int32_t *samples = (int32_t *)s->frame.data[0];
+ for (i = 0; i < framelen * s->channels; i++)
+ *samples++ <<= 8;
+ // reset decode buffer
+ s->decode_buffer = NULL;
}
-// return get_bits_count(&s->gb)+7)/8;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return buf_size;
}
@@ -457,13 +433,13 @@ static av_cold int tta_decode_close(AVCodecContext *avctx) {
}
AVCodec ff_tta_decoder = {
- "tta",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_TTA,
- sizeof(TTAContext),
- tta_decode_init,
- NULL,
- tta_decode_close,
- tta_decode_frame,
+ .name = "tta",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_TTA,
+ .priv_data_size = sizeof(TTAContext),
+ .init = tta_decode_init,
+ .close = tta_decode_close,
+ .decode = tta_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("True Audio (TTA)"),
};
diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c
index 985f71c..22be07a 100644
--- a/libavcodec/twinvq.c
+++ b/libavcodec/twinvq.c
@@ -174,6 +174,7 @@ static const ModeTab mode_44_48 = {
typedef struct TwinContext {
AVCodecContext *avctx;
+ AVFrame frame;
DSPContext dsp;
FFTContext mdct_ctx[3];
@@ -195,6 +196,7 @@ typedef struct TwinContext {
float *curr_frame; ///< non-interleaved output
float *prev_frame; ///< non-interleaved previous frame
int last_block_pos[2];
+ int discarded_packets;
float *cos_tabs[3];
@@ -411,7 +413,7 @@ static inline float mulawinv(float y, float clip, float mu)
* a*b == 200 and the nearest integer is ill-defined, use a table to emulate
* the following broken float-based implementation used by the binary decoder:
*
- * \code
+ * @code
* static int very_broken_op(int a, int b)
* {
* static float test; // Ugh, force gcc to do the division first...
@@ -419,7 +421,7 @@ static inline float mulawinv(float y, float clip, float mu)
* test = a/400.;
* return b * test + 0.5;
* }
- * \endcode
+ * @endcode
*
* @note if this function is replaced by just ROUNDED_DIV(a*b,400.), the stddev
* between the original file (before encoding with Yamaha encoder) and the
@@ -665,8 +667,9 @@ static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype,
float *out)
{
const ModeTab *mtab = tctx->mtab;
+ int size1, size2;
float *prev_buf = tctx->prev_frame + tctx->last_block_pos[0];
- int i, j;
+ int i;
for (i = 0; i < tctx->avctx->channels; i++) {
imdct_and_window(tctx, ftype, wtype,
@@ -675,27 +678,27 @@ static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype,
i);
}
+ if (!out)
+ return;
+
+ size2 = tctx->last_block_pos[0];
+ size1 = mtab->size - size2;
if (tctx->avctx->channels == 2) {
- for (i = 0; i < mtab->size - tctx->last_block_pos[0]; i++) {
- float f1 = prev_buf[ i];
- float f2 = prev_buf[2*mtab->size + i];
- out[2*i ] = f1 + f2;
- out[2*i + 1] = f1 - f2;
- }
- for (j = 0; i < mtab->size; j++,i++) {
- float f1 = tctx->curr_frame[ j];
- float f2 = tctx->curr_frame[2*mtab->size + j];
- out[2*i ] = f1 + f2;
- out[2*i + 1] = f1 - f2;
- }
+ tctx->dsp.butterflies_float_interleave(out, prev_buf,
+ &prev_buf[2*mtab->size],
+ size1);
+
+ out += 2 * size1;
+
+ tctx->dsp.butterflies_float_interleave(out, tctx->curr_frame,
+ &tctx->curr_frame[2*mtab->size],
+ size2);
} else {
- memcpy(out, prev_buf,
- (mtab->size - tctx->last_block_pos[0]) * sizeof(*out));
+ memcpy(out, prev_buf, size1 * sizeof(*out));
- out += mtab->size - tctx->last_block_pos[0];
+ out += size1;
- memcpy(out, tctx->curr_frame,
- (tctx->last_block_pos[0]) * sizeof(*out));
+ memcpy(out, tctx->curr_frame, size2 * sizeof(*out));
}
}
@@ -813,16 +816,16 @@ static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb,
}
static int twin_decode_frame(AVCodecContext * avctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
TwinContext *tctx = avctx->priv_data;
GetBitContext gb;
const ModeTab *mtab = tctx->mtab;
- float *out = data;
+ float *out = NULL;
enum FrameType ftype;
- int window_type;
+ int window_type, ret;
static const enum FrameType wtype_to_ftype_table[] = {
FT_LONG, FT_LONG, FT_SHORT, FT_LONG,
FT_MEDIUM, FT_LONG, FT_LONG, FT_MEDIUM, FT_MEDIUM
@@ -831,8 +834,17 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data,
if (buf_size*8 < avctx->bit_rate*mtab->size/avctx->sample_rate + 8) {
av_log(avctx, AV_LOG_ERROR,
"Frame too small (%d bytes). Truncated file?\n", buf_size);
- *data_size = 0;
- return buf_size;
+ return AVERROR(EINVAL);
+ }
+
+ /* get output buffer */
+ if (tctx->discarded_packets >= 2) {
+ tctx->frame.nb_samples = mtab->size;
+ if ((ret = avctx->get_buffer(avctx, &tctx->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ out = (float *)tctx->frame.data[0];
}
init_get_bits(&gb, buf, buf_size * 8);
@@ -852,12 +864,14 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data,
FFSWAP(float*, tctx->curr_frame, tctx->prev_frame);
- if (tctx->avctx->frame_number < 2) {
- *data_size=0;
+ if (tctx->discarded_packets < 2) {
+ tctx->discarded_packets++;
+ *got_frame_ptr = 0;
return buf_size;
}
- *data_size = mtab->size*avctx->channels*4;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = tctx->frame;;
return buf_size;
}
@@ -865,9 +879,9 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data,
/**
* Init IMDCT and windowing tables
*/
-static av_cold void init_mdct_win(TwinContext *tctx)
+static av_cold int init_mdct_win(TwinContext *tctx)
{
- int i,j;
+ int i, j, ret;
const ModeTab *mtab = tctx->mtab;
int size_s = mtab->size / mtab->fmode[FT_SHORT].sub;
int size_m = mtab->size / mtab->fmode[FT_MEDIUM].sub;
@@ -876,20 +890,29 @@ static av_cold void init_mdct_win(TwinContext *tctx)
for (i = 0; i < 3; i++) {
int bsize = tctx->mtab->size/tctx->mtab->fmode[i].sub;
- ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1,
- -sqrt(norm/bsize) / (1<<15));
+ if ((ret = ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1,
+ -sqrt(norm/bsize) / (1<<15))))
+ return ret;
}
- tctx->tmp_buf = av_malloc(mtab->size * sizeof(*tctx->tmp_buf));
+ FF_ALLOC_OR_GOTO(tctx->avctx, tctx->tmp_buf,
+ mtab->size * sizeof(*tctx->tmp_buf), alloc_fail);
- tctx->spectrum = av_malloc(2*mtab->size*channels*sizeof(float));
- tctx->curr_frame = av_malloc(2*mtab->size*channels*sizeof(float));
- tctx->prev_frame = av_malloc(2*mtab->size*channels*sizeof(float));
+ FF_ALLOC_OR_GOTO(tctx->avctx, tctx->spectrum,
+ 2 * mtab->size * channels * sizeof(*tctx->spectrum),
+ alloc_fail);
+ FF_ALLOC_OR_GOTO(tctx->avctx, tctx->curr_frame,
+ 2 * mtab->size * channels * sizeof(*tctx->curr_frame),
+ alloc_fail);
+ FF_ALLOC_OR_GOTO(tctx->avctx, tctx->prev_frame,
+ 2 * mtab->size * channels * sizeof(*tctx->prev_frame),
+ alloc_fail);
for (i = 0; i < 3; i++) {
int m = 4*mtab->size/mtab->fmode[i].sub;
double freq = 2*M_PI/m;
- tctx->cos_tabs[i] = av_malloc((m/4)*sizeof(*tctx->cos_tabs));
+ FF_ALLOC_OR_GOTO(tctx->avctx, tctx->cos_tabs[i],
+ (m / 4) * sizeof(*tctx->cos_tabs[i]), alloc_fail);
for (j = 0; j <= m/8; j++)
tctx->cos_tabs[i][j] = cos((2*j + 1)*freq);
@@ -901,6 +924,10 @@ static av_cold void init_mdct_win(TwinContext *tctx)
ff_init_ff_sine_windows(av_log2(size_m));
ff_init_ff_sine_windows(av_log2(size_s/2));
ff_init_ff_sine_windows(av_log2(mtab->size));
+
+ return 0;
+alloc_fail:
+ return AVERROR(ENOMEM);
}
/**
@@ -938,14 +965,14 @@ static void permutate_in_line(int16_t *tab, int num_vect, int num_blocks,
/**
* Interpret the input data as in the following table:
*
- * \verbatim
+ * @verbatim
*
* abcdefgh
* ijklmnop
* qrstuvw
* x123456
*
- * \endverbatim
+ * @endverbatim
*
* and transpose it, giving the output
* aiqxbjr1cks2dlt3emu4fvn5gow6hp
@@ -1062,20 +1089,54 @@ static av_cold void init_bitstream_params(TwinContext *tctx)
construct_perm_table(tctx, frametype);
}
+static av_cold int twin_decode_close(AVCodecContext *avctx)
+{
+ TwinContext *tctx = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ ff_mdct_end(&tctx->mdct_ctx[i]);
+ av_free(tctx->cos_tabs[i]);
+ }
+
+
+ av_free(tctx->curr_frame);
+ av_free(tctx->spectrum);
+ av_free(tctx->prev_frame);
+ av_free(tctx->tmp_buf);
+
+ return 0;
+}
+
static av_cold int twin_decode_init(AVCodecContext *avctx)
{
+ int ret;
TwinContext *tctx = avctx->priv_data;
- int isampf = avctx->sample_rate/1000;
- int ibps = avctx->bit_rate/(1000 * avctx->channels);
+ int isampf, ibps;
tctx->avctx = avctx;
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ if (!avctx->extradata || avctx->extradata_size < 12) {
+ av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n");
+ return AVERROR_INVALIDDATA;
+ }
+ avctx->channels = AV_RB32(avctx->extradata ) + 1;
+ avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000;
+ isampf = AV_RB32(avctx->extradata + 8);
+ switch (isampf) {
+ case 44: avctx->sample_rate = 44100; break;
+ case 22: avctx->sample_rate = 22050; break;
+ case 11: avctx->sample_rate = 11025; break;
+ default: avctx->sample_rate = isampf * 1000; break;
+ }
+
if (avctx->channels > CHANNELS_MAX) {
av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n",
avctx->channels);
return -1;
}
+ ibps = avctx->bit_rate / (1000 * avctx->channels);
switch ((isampf << 8) + ibps) {
case (8 <<8) + 8: tctx->mtab = &mode_08_08; break;
@@ -1093,42 +1154,29 @@ static av_cold int twin_decode_init(AVCodecContext *avctx)
}
dsputil_init(&tctx->dsp, avctx);
- init_mdct_win(tctx);
+ if ((ret = init_mdct_win(tctx))) {
+ av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
+ twin_decode_close(avctx);
+ return ret;
+ }
init_bitstream_params(tctx);
memset_float(tctx->bark_hist[0][0], 0.1, FF_ARRAY_ELEMS(tctx->bark_hist));
- return 0;
-}
-
-static av_cold int twin_decode_close(AVCodecContext *avctx)
-{
- TwinContext *tctx = avctx->priv_data;
- int i;
-
- for (i = 0; i < 3; i++) {
- ff_mdct_end(&tctx->mdct_ctx[i]);
- av_free(tctx->cos_tabs[i]);
- }
-
-
- av_free(tctx->curr_frame);
- av_free(tctx->spectrum);
- av_free(tctx->prev_frame);
- av_free(tctx->tmp_buf);
+ avcodec_get_frame_defaults(&tctx->frame);
+ avctx->coded_frame = &tctx->frame;
return 0;
}
-AVCodec ff_twinvq_decoder =
-{
- "twinvq",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_TWINVQ,
- sizeof(TwinContext),
- twin_decode_init,
- NULL,
- twin_decode_close,
- twin_decode_frame,
- .long_name = NULL_IF_CONFIG_SMALL("VQF TwinVQ"),
+AVCodec ff_twinvq_decoder = {
+ .name = "twinvq",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_TWINVQ,
+ .priv_data_size = sizeof(TwinContext),
+ .init = twin_decode_init,
+ .close = twin_decode_close,
+ .decode = twin_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("VQF TwinVQ"),
};
diff --git a/libavcodec/txd.c b/libavcodec/txd.c
index e91b4fb..734062a 100644
--- a/libavcodec/txd.c
+++ b/libavcodec/txd.c
@@ -108,7 +108,8 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
} else if (depth == 16) {
switch (d3d_format) {
case 0:
- if (!flags&1) goto unsupported;
+ if (!(flags & 1))
+ goto unsupported;
case FF_S3TC_DXT1:
ff_decode_dxt1(cur, ptr, w, h, stride);
break;
@@ -156,15 +157,13 @@ static av_cold int txd_end(AVCodecContext *avctx) {
}
AVCodec ff_txd_decoder = {
- "txd",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TXD,
- sizeof(TXDContext),
- txd_init,
- NULL,
- txd_end,
- txd_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "txd",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TXD,
+ .priv_data_size = sizeof(TXDContext),
+ .init = txd_init,
+ .close = txd_end,
+ .decode = txd_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"),
};
diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c
index 9a73c62..52092b5 100644
--- a/libavcodec/ulti.c
+++ b/libavcodec/ulti.c
@@ -40,6 +40,14 @@ typedef struct UltimotionDecodeContext {
const uint8_t *ulti_codebook;
} UltimotionDecodeContext;
+#define CHECK_OVERREAD_SIZE(size) \
+ do { \
+ if (buf_end - buf < (size)) { \
+ av_log(avctx, AV_LOG_ERROR, "Insufficient data\n"); \
+ return AVERROR_INVALIDDATA; \
+ } \
+ } while(0)
+
static av_cold int ulti_decode_init(AVCodecContext *avctx)
{
UltimotionDecodeContext *s = avctx->priv_data;
@@ -223,6 +231,7 @@ static int ulti_decode_frame(AVCodecContext *avctx,
int i;
int skip;
int tmp;
+ const uint8_t *buf_end = buf + buf_size;
s->frame.reference = 1;
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
@@ -236,10 +245,12 @@ static int ulti_decode_frame(AVCodecContext *avctx,
if(blocks >= s->blocks || y >= s->height)
break;//all blocks decoded
+ CHECK_OVERREAD_SIZE(1);
idx = *buf++;
if((idx & 0xF8) == 0x70) {
switch(idx) {
case 0x70: //change modifier
+ CHECK_OVERREAD_SIZE(1);
modifier = *buf++;
if(modifier>1)
av_log(avctx, AV_LOG_INFO, "warning: modifier must be 0 or 1, got %i\n", modifier);
@@ -254,6 +265,7 @@ static int ulti_decode_frame(AVCodecContext *avctx,
done = 1;
break;
case 0x74: //skip some blocks
+ CHECK_OVERREAD_SIZE(1);
skip = *buf++;
if ((blocks + skip) >= s->blocks)
break;
@@ -280,19 +292,24 @@ static int ulti_decode_frame(AVCodecContext *avctx,
chroma = 0;
} else {
cf = 0;
- if (idx)
+ if (idx) {
+ CHECK_OVERREAD_SIZE(1);
chroma = *buf++;
+ }
}
for (i = 0; i < 4; i++) { // for every subblock
code = (idx >> (6 - i*2)) & 3; //extract 2 bits
if(!code) //skip subblock
continue;
- if(cf)
+ if(cf) {
+ CHECK_OVERREAD_SIZE(1);
chroma = *buf++;
+ }
tx = x + block_coords[i * 2];
ty = y + block_coords[(i * 2) + 1];
switch(code) {
case 1:
+ CHECK_OVERREAD_SIZE(1);
tmp = *buf++;
angle = angle_by_index[(tmp >> 6) & 0x3];
@@ -313,6 +330,7 @@ static int ulti_decode_frame(AVCodecContext *avctx,
case 2:
if (modifier) { // unpack four luma samples
+ CHECK_OVERREAD_SIZE(3);
tmp = bytestream_get_be24(&buf);
Y[0] = (tmp >> 18) & 0x3F;
@@ -321,6 +339,7 @@ static int ulti_decode_frame(AVCodecContext *avctx,
Y[3] = tmp & 0x3F;
angle = 16;
} else { // retrieve luma samples from codebook
+ CHECK_OVERREAD_SIZE(2);
tmp = bytestream_get_be16(&buf);
angle = (tmp >> 12) & 0xF;
@@ -337,6 +356,8 @@ static int ulti_decode_frame(AVCodecContext *avctx,
if (modifier) { // all 16 luma samples
uint8_t Luma[16];
+ CHECK_OVERREAD_SIZE(12);
+
tmp = bytestream_get_be24(&buf);
Luma[0] = (tmp >> 18) & 0x3F;
Luma[1] = (tmp >> 12) & 0x3F;
@@ -363,6 +384,7 @@ static int ulti_decode_frame(AVCodecContext *avctx,
ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma);
} else {
+ CHECK_OVERREAD_SIZE(4);
tmp = *buf++;
if(tmp & 0x80) {
angle = (tmp >> 4) & 0x7;
@@ -402,16 +424,14 @@ static int ulti_decode_frame(AVCodecContext *avctx,
}
AVCodec ff_ulti_decoder = {
- "ultimotion",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ULTI,
- sizeof(UltimotionDecodeContext),
- ulti_decode_init,
- NULL,
- ulti_decode_end,
- ulti_decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "ultimotion",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ULTI,
+ .priv_data_size = sizeof(UltimotionDecodeContext),
+ .init = ulti_decode_init,
+ .close = ulti_decode_end,
+ .decode = ulti_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("IBM UltiMotion"),
};
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 5c19dd7..a88d1a7 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -26,8 +26,8 @@
*/
#include "libavutil/avstring.h"
-#include "libavutil/integer.h"
#include "libavutil/crc.h"
+#include "libavutil/mathematics.h"
#include "libavutil/pixdesc.h"
#include "libavutil/audioconvert.h"
#include "libavutil/imgutils.h"
@@ -40,6 +40,7 @@
#include "thread.h"
#include "audioconvert.h"
#include "internal.h"
+#include "bytestream.h"
#include <stdlib.h>
#include <stdarg.h>
#include <limits.h>
@@ -48,6 +49,7 @@
static int volatile entangled_thread_counter=0;
static int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op);
static void *codec_mutex;
+static void *avformat_mutex;
void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
{
@@ -85,6 +87,20 @@ AVCodec *av_codec_next(AVCodec *c){
else return first_avcodec;
}
+#if !FF_API_AVCODEC_INIT
+static
+#endif
+void avcodec_init(void)
+{
+ static int initialized = 0;
+
+ if (initialized != 0)
+ return;
+ initialized = 1;
+
+ dsputil_static_init();
+}
+
void avcodec_register(AVCodec *codec)
{
AVCodec **p;
@@ -93,6 +109,9 @@ void avcodec_register(AVCodec *codec)
while (*p != NULL) p = &(*p)->next;
*p = codec;
codec->next = NULL;
+
+ if (codec->init_static_data)
+ codec->init_static_data(codec);
}
unsigned avcodec_get_edge_width(void)
@@ -107,18 +126,12 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height){
s->height= -((-height)>>s->lowres);
}
-typedef struct InternalBuffer{
- int last_pic_num;
- uint8_t *base[4];
- uint8_t *data[4];
- int linesize[4];
- int width, height;
- enum PixelFormat pix_fmt;
-}InternalBuffer;
-
#define INTERNAL_BUFFER_SIZE (32+1)
-void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[4]){
+void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
+ int linesize_align[AV_NUM_DATA_POINTERS])
+{
+ int i;
int w_align= 1;
int h_align= 1;
@@ -129,6 +142,7 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int l
case PIX_FMT_YUV422P:
case PIX_FMT_YUV440P:
case PIX_FMT_YUV444P:
+ case PIX_FMT_GBRP:
case PIX_FMT_GRAY8:
case PIX_FMT_GRAY16BE:
case PIX_FMT_GRAY16LE:
@@ -141,16 +155,20 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int l
case PIX_FMT_YUV420P9BE:
case PIX_FMT_YUV420P10LE:
case PIX_FMT_YUV420P10BE:
+ case PIX_FMT_YUV422P9LE:
+ case PIX_FMT_YUV422P9BE:
case PIX_FMT_YUV422P10LE:
case PIX_FMT_YUV422P10BE:
case PIX_FMT_YUV444P9LE:
case PIX_FMT_YUV444P9BE:
case PIX_FMT_YUV444P10LE:
case PIX_FMT_YUV444P10BE:
- w_align= 16; //FIXME check for non mpeg style codecs and use less alignment
- h_align= 16;
- if(s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG || s->codec_id == CODEC_ID_AMV || s->codec_id == CODEC_ID_THP || s->codec_id == CODEC_ID_H264)
- h_align= 32; // interlaced is rounded up to 2 MBs
+ case PIX_FMT_GBRP9LE:
+ case PIX_FMT_GBRP9BE:
+ case PIX_FMT_GBRP10LE:
+ case PIX_FMT_GBRP10BE:
+ w_align = 16; //FIXME assume 16 pixel per macroblock
+ h_align = 16 * 2; // interlaced needs 2 macroblocks height
break;
case PIX_FMT_YUV411P:
case PIX_FMT_UYYVYY411:
@@ -193,10 +211,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int l
*height+=2; // some of the optimized chroma MC reads one line too much
// which is also done in mpeg decoders with lowres > 0
- linesize_align[0] =
- linesize_align[1] =
- linesize_align[2] =
- linesize_align[3] = STRIDE_ALIGN;
+ for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
+ linesize_align[i] = STRIDE_ALIGN;
//STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes
//we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the
//picture size unneccessarily in some cases. The solution here is not
@@ -205,16 +221,15 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int l
if(s->codec_id == CODEC_ID_SVQ1 || s->codec_id == CODEC_ID_VP5 ||
s->codec_id == CODEC_ID_VP6 || s->codec_id == CODEC_ID_VP6F ||
s->codec_id == CODEC_ID_VP6A) {
- linesize_align[0] =
- linesize_align[1] =
- linesize_align[2] = 16;
+ for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
+ linesize_align[i] = 16;
}
#endif
}
void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){
int chroma_shift = av_pix_fmt_descriptors[s->pix_fmt].log2_chroma_w;
- int linesize_align[4];
+ int linesize_align[AV_NUM_DATA_POINTERS];
int align;
avcodec_align_dimensions2(s, width, height, linesize_align);
align = FFMAX(linesize_align[0], linesize_align[3]);
@@ -224,39 +239,132 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){
*width=FFALIGN(*width, align);
}
-int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
+static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+{
+ AVCodecInternal *avci = avctx->internal;
+ InternalBuffer *buf;
+ int buf_size, ret, i, needs_extended_data;
+
+ buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
+ frame->nb_samples, avctx->sample_fmt,
+ 32);
+ if (buf_size < 0)
+ return AVERROR(EINVAL);
+
+ needs_extended_data = av_sample_fmt_is_planar(avctx->sample_fmt) &&
+ avctx->channels > AV_NUM_DATA_POINTERS;
+
+ /* allocate InternalBuffer if needed */
+ if (!avci->buffer) {
+ avci->buffer = av_mallocz(sizeof(InternalBuffer));
+ if (!avci->buffer)
+ return AVERROR(ENOMEM);
+ }
+ buf = avci->buffer;
+
+ /* if there is a previously-used internal buffer, check its size and
+ channel count to see if we can reuse it */
+ if (buf->extended_data) {
+ /* if current buffer is too small, free it */
+ if (buf->extended_data[0] && buf_size > buf->audio_data_size) {
+ av_free(buf->extended_data[0]);
+ if (buf->extended_data != buf->data)
+ av_free(&buf->extended_data);
+ buf->extended_data = NULL;
+ buf->data[0] = NULL;
+ }
+ /* if number of channels has changed, reset and/or free extended data
+ pointers but leave data buffer in buf->data[0] for reuse */
+ if (buf->nb_channels != avctx->channels) {
+ if (buf->extended_data != buf->data)
+ av_free(buf->extended_data);
+ buf->extended_data = NULL;
+ }
+ }
+
+ /* if there is no previous buffer or the previous buffer cannot be used
+ as-is, allocate a new buffer and/or rearrange the channel pointers */
+ if (!buf->extended_data) {
+ /* if the channel pointers will fit, just set extended_data to data,
+ otherwise allocate the extended_data channel pointers */
+ if (needs_extended_data) {
+ buf->extended_data = av_mallocz(avctx->channels *
+ sizeof(*buf->extended_data));
+ if (!buf->extended_data)
+ return AVERROR(ENOMEM);
+ } else {
+ buf->extended_data = buf->data;
+ }
+
+ /* if there is a previous buffer and it is large enough, reuse it and
+ just fill-in new channel pointers and linesize, otherwise allocate
+ a new buffer */
+ if (buf->extended_data[0]) {
+ ret = av_samples_fill_arrays(buf->extended_data, &buf->linesize[0],
+ buf->extended_data[0], avctx->channels,
+ frame->nb_samples, avctx->sample_fmt,
+ 32);
+ } else {
+ ret = av_samples_alloc(buf->extended_data, &buf->linesize[0],
+ avctx->channels, frame->nb_samples,
+ avctx->sample_fmt, 32);
+ }
+ if (ret)
+ return ret;
+
+ /* if data was not used for extended_data, we need to copy as many of
+ the extended_data channel pointers as will fit */
+ if (needs_extended_data) {
+ for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
+ buf->data[i] = buf->extended_data[i];
+ }
+ buf->audio_data_size = buf_size;
+ buf->nb_channels = avctx->channels;
+ }
+
+ /* copy InternalBuffer info to the AVFrame */
+ frame->type = FF_BUFFER_TYPE_INTERNAL;
+ frame->extended_data = buf->extended_data;
+ frame->linesize[0] = buf->linesize[0];
+ memcpy(frame->data, buf->data, sizeof(frame->data));
+
+ if (avctx->pkt) frame->pkt_pts = avctx->pkt->pts;
+ else frame->pkt_pts = AV_NOPTS_VALUE;
+ frame->reordered_opaque = avctx->reordered_opaque;
+
+ if (avctx->debug & FF_DEBUG_BUFFERS)
+ av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, "
+ "internal audio buffer used\n", frame);
+
+ return 0;
+}
+
+static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
+{
int i;
int w= s->width;
int h= s->height;
InternalBuffer *buf;
- int *picture_number;
+ AVCodecInternal *avci = s->internal;
if(pic->data[0]!=NULL) {
av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n");
return -1;
}
- if(s->internal_buffer_count >= INTERNAL_BUFFER_SIZE) {
- av_log(s, AV_LOG_ERROR, "internal_buffer_count overflow (missing release_buffer?)\n");
+ if(avci->buffer_count >= INTERNAL_BUFFER_SIZE) {
+ av_log(s, AV_LOG_ERROR, "buffer_count overflow (missing release_buffer?)\n");
return -1;
}
if(av_image_check_size(w, h, 0, s))
return -1;
- if(s->internal_buffer==NULL){
- s->internal_buffer= av_mallocz((INTERNAL_BUFFER_SIZE+1)*sizeof(InternalBuffer));
+ if (!avci->buffer) {
+ avci->buffer = av_mallocz((INTERNAL_BUFFER_SIZE+1) *
+ sizeof(InternalBuffer));
}
-#if 0
- s->internal_buffer= av_fast_realloc(
- s->internal_buffer,
- &s->internal_buffer_size,
- sizeof(InternalBuffer)*FFMAX(99, s->internal_buffer_count+1)/*FIXME*/
- );
-#endif
- buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];
- picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE]).last_pic_num; //FIXME ugly hack
- (*picture_number)++;
+ buf = &avci->buffer[avci->buffer_count];
if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){
if(s->active_thread_type&FF_THREAD_FRAME) {
@@ -264,22 +372,19 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
return -1;
}
- for(i=0; i<4; i++){
+ for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
av_freep(&buf->base[i]);
buf->data[i]= NULL;
}
}
- if(buf->base[0]){
- pic->age= *picture_number - buf->last_pic_num;
- buf->last_pic_num= *picture_number;
- }else{
+ if (!buf->base[0]) {
int h_chroma_shift, v_chroma_shift;
int size[4] = {0};
int tmpsize;
int unaligned;
AVPicture picture;
- int stride_align[4];
+ int stride_align[AV_NUM_DATA_POINTERS];
const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1;
avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
@@ -312,7 +417,6 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
size[i] = picture.data[i+1] - picture.data[i];
size[i] = tmpsize - (picture.data[i] - picture.data[0]);
- buf->last_pic_num= -256*256*256*64;
memset(buf->base, 0, sizeof(buf->base));
memset(buf->data, 0, sizeof(buf->data));
@@ -332,67 +436,91 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
else
buf->data[i] = buf->base[i] + FFALIGN((buf->linesize[i]*EDGE_WIDTH>>v_shift) + (pixel_size*EDGE_WIDTH>>h_shift), stride_align[i]);
}
+ for (; i < AV_NUM_DATA_POINTERS; i++) {
+ buf->base[i] = buf->data[i] = NULL;
+ buf->linesize[i] = 0;
+ }
if(size[1] && !size[2])
ff_set_systematic_pal2((uint32_t*)buf->data[1], s->pix_fmt);
buf->width = s->width;
buf->height = s->height;
buf->pix_fmt= s->pix_fmt;
- pic->age= 256*256*256*64;
}
pic->type= FF_BUFFER_TYPE_INTERNAL;
- for(i=0; i<4; i++){
+ for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
pic->base[i]= buf->base[i];
pic->data[i]= buf->data[i];
pic->linesize[i]= buf->linesize[i];
}
- s->internal_buffer_count++;
+ pic->extended_data = pic->data;
+ avci->buffer_count++;
if(s->pkt) pic->pkt_pts= s->pkt->pts;
else pic->pkt_pts= AV_NOPTS_VALUE;
pic->reordered_opaque= s->reordered_opaque;
if(s->debug&FF_DEBUG_BUFFERS)
- av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d buffers used\n", pic, s->internal_buffer_count);
+ av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d "
+ "buffers used\n", pic, avci->buffer_count);
return 0;
}
+int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+{
+ switch (avctx->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ return video_get_buffer(avctx, frame);
+ case AVMEDIA_TYPE_AUDIO:
+ return audio_get_buffer(avctx, frame);
+ default:
+ return -1;
+ }
+}
+
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){
int i;
InternalBuffer *buf, *last;
+ AVCodecInternal *avci = s->internal;
- assert(pic->type==FF_BUFFER_TYPE_INTERNAL);
- assert(s->internal_buffer_count);
+ assert(s->codec_type == AVMEDIA_TYPE_VIDEO);
- if(s->internal_buffer){
- buf = NULL; /* avoids warning */
- for(i=0; i<s->internal_buffer_count; i++){ //just 3-5 checks so is not worth to optimize
- buf= &((InternalBuffer*)s->internal_buffer)[i];
- if(buf->data[0] == pic->data[0])
- break;
- }
- assert(i < s->internal_buffer_count);
- s->internal_buffer_count--;
- last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];
+ assert(pic->type==FF_BUFFER_TYPE_INTERNAL);
+ assert(avci->buffer_count);
+
+ if (avci->buffer) {
+ buf = NULL; /* avoids warning */
+ for (i = 0; i < avci->buffer_count; i++) { //just 3-5 checks so is not worth to optimize
+ buf = &avci->buffer[i];
+ if (buf->data[0] == pic->data[0])
+ break;
+ }
+ assert(i < avci->buffer_count);
+ avci->buffer_count--;
+ last = &avci->buffer[avci->buffer_count];
- FFSWAP(InternalBuffer, *buf, *last);
+ if (buf != last)
+ FFSWAP(InternalBuffer, *buf, *last);
}
- for(i=0; i<4; i++){
+ for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
pic->data[i]=NULL;
// pic->base[i]=NULL;
}
//printf("R%X\n", pic->opaque);
if(s->debug&FF_DEBUG_BUFFERS)
- av_log(s, AV_LOG_DEBUG, "default_release_buffer called on pic %p, %d buffers used\n", pic, s->internal_buffer_count);
+ av_log(s, AV_LOG_DEBUG, "default_release_buffer called on pic %p, %d "
+ "buffers used\n", pic, avci->buffer_count);
}
int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){
AVFrame temp_pic;
int i;
+ assert(s->codec_type == AVMEDIA_TYPE_VIDEO);
+
/* If no picture return a new buffer */
if(pic->data[0] == NULL) {
/* We will copy from buffer, so must be readable */
@@ -412,7 +540,7 @@ int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){
* Not internal type and reget_buffer not overridden, emulate cr buffer
*/
temp_pic = *pic;
- for(i = 0; i < 4; i++)
+ for(i = 0; i < AV_NUM_DATA_POINTERS; i++)
pic->data[i] = pic->base[i] = NULL;
pic->opaque = NULL;
/* Allocate new frame */
@@ -456,6 +584,8 @@ void avcodec_get_frame_defaults(AVFrame *pic){
pic->pts= AV_NOPTS_VALUE;
pic->key_frame= 1;
+ pic->sample_aspect_ratio = (AVRational){0, 1};
+ pic->format = -1; /* unknown */
}
AVFrame *avcodec_alloc_frame(void){
@@ -501,6 +631,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD
goto end;
}
+ avctx->internal = av_mallocz(sizeof(AVCodecInternal));
+ if (!avctx->internal) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+
if (codec->priv_data_size > 0) {
if(!avctx->priv_data){
avctx->priv_data = av_mallocz(codec->priv_data_size);
@@ -557,6 +693,16 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD
goto free_and_end;
}
avctx->frame_number = 0;
+#if FF_API_ER
+
+ av_log(avctx, AV_LOG_DEBUG, "err{or,}_recognition separate: %d; %d\n",
+ avctx->error_recognition, avctx->err_recognition);
+ /* FF_ER_CAREFUL (==1) implies AV_EF_CRCCHECK (== 1<<1 - 1),
+ FF_ER_COMPLIANT (==2) implies AV_EF_{CRCCHECK,BITSTREAM} (== 1<<2 - 1), et cetera} */
+ avctx->err_recognition |= (1<<(avctx->error_recognition-(avctx->error_recognition>=FF_ER_VERY_AGGRESSIVE))) - 1;
+ av_log(avctx, AV_LOG_DEBUG, "err{or,}_recognition combined: %d; %d\n",
+ avctx->error_recognition, avctx->err_recognition);
+#endif
if (HAVE_THREADS && !avctx->thread_opaque) {
ret = ff_thread_init(avctx);
@@ -640,6 +786,7 @@ end:
free_and_end:
av_dict_free(&tmp);
av_freep(&avctx->priv_data);
+ av_freep(&avctx->internal);
avctx->codec= NULL;
goto end;
}
@@ -706,13 +853,17 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
avctx->pkt = avpkt;
if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type&FF_THREAD_FRAME)){
- if (HAVE_PTHREADS && avctx->active_thread_type&FF_THREAD_FRAME)
+ if (HAVE_THREADS && avctx->active_thread_type&FF_THREAD_FRAME)
ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr,
avpkt);
else {
ret = avctx->codec->decode(avctx, picture, got_picture_ptr,
avpkt);
picture->pkt_dts= avpkt->dts;
+ picture->sample_aspect_ratio = avctx->sample_aspect_ratio;
+ picture->width = avctx->width;
+ picture->height = avctx->height;
+ picture->format = avctx->pix_fmt;
}
emms_c(); //needed to avoid an emms_c() call before every return;
@@ -725,31 +876,118 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
return ret;
}
+#if FF_API_OLD_DECODE_AUDIO
int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
int *frame_size_ptr,
AVPacket *avpkt)
{
- int ret;
+ AVFrame frame;
+ int ret, got_frame = 0;
- avctx->pkt = avpkt;
+ if (avctx->get_buffer != avcodec_default_get_buffer) {
+ av_log(avctx, AV_LOG_ERROR, "A custom get_buffer() cannot be used with "
+ "avcodec_decode_audio3()\n");
+ return AVERROR(EINVAL);
+ }
- if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size){
- //FIXME remove the check below _after_ ensuring that all audio check that the available space is enough
- if(*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE){
- av_log(avctx, AV_LOG_ERROR, "buffer smaller than AVCODEC_MAX_AUDIO_FRAME_SIZE\n");
- return -1;
+ ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt);
+
+ if (ret >= 0 && got_frame) {
+ int ch, plane_size;
+ int planar = av_sample_fmt_is_planar(avctx->sample_fmt);
+ int data_size = av_samples_get_buffer_size(&plane_size, avctx->channels,
+ frame.nb_samples,
+ avctx->sample_fmt, 1);
+ if (*frame_size_ptr < data_size) {
+ av_log(avctx, AV_LOG_ERROR, "output buffer size is too small for "
+ "the current frame (%d < %d)\n", *frame_size_ptr, data_size);
+ return AVERROR(EINVAL);
}
- if(*frame_size_ptr < FF_MIN_BUFFER_SIZE ||
- *frame_size_ptr < avctx->channels * avctx->frame_size * sizeof(int16_t)){
- av_log(avctx, AV_LOG_ERROR, "buffer %d too small\n", *frame_size_ptr);
- return -1;
+
+ memcpy(samples, frame.extended_data[0], plane_size);
+
+ if (planar && avctx->channels > 1) {
+ uint8_t *out = ((uint8_t *)samples) + plane_size;
+ for (ch = 1; ch < avctx->channels; ch++) {
+ memcpy(out, frame.extended_data[ch], plane_size);
+ out += plane_size;
+ }
}
+ *frame_size_ptr = data_size;
+ } else {
+ *frame_size_ptr = 0;
+ }
+ return ret;
+}
+#endif
- ret = avctx->codec->decode(avctx, samples, frame_size_ptr, avpkt);
- avctx->frame_number++;
- }else{
- ret= 0;
- *frame_size_ptr=0;
+static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt)
+{
+ int size = 0;
+ const uint8_t *data;
+ uint32_t flags;
+
+ if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE))
+ return;
+
+ data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size);
+ if (!data || size < 4)
+ return;
+ flags = bytestream_get_le32(&data);
+ size -= 4;
+ if (size < 4) /* Required for any of the changes */
+ return;
+ if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) {
+ avctx->channels = bytestream_get_le32(&data);
+ size -= 4;
+ }
+ if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) {
+ if (size < 8)
+ return;
+ avctx->channel_layout = bytestream_get_le64(&data);
+ size -= 8;
+ }
+ if (size < 4)
+ return;
+ if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) {
+ avctx->sample_rate = bytestream_get_le32(&data);
+ size -= 4;
+ }
+ if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) {
+ if (size < 8)
+ return;
+ avctx->width = bytestream_get_le32(&data);
+ avctx->height = bytestream_get_le32(&data);
+ size -= 8;
+ }
+}
+
+int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
+ AVFrame *frame,
+ int *got_frame_ptr,
+ AVPacket *avpkt)
+{
+ int ret = 0;
+
+ *got_frame_ptr = 0;
+
+ avctx->pkt = avpkt;
+
+ if (!avpkt->data && avpkt->size) {
+ av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
+ return AVERROR(EINVAL);
+ }
+
+ apply_param_change(avctx, avpkt);
+
+ if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) {
+ ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt);
+ if (ret >= 0 && *got_frame_ptr) {
+ avctx->frame_number++;
+ frame->pkt_dts = avpkt->dts;
+ if (frame->format == AV_SAMPLE_FMT_NONE)
+ frame->format = avctx->sample_fmt;
+ }
}
return ret;
}
@@ -809,6 +1047,7 @@ av_cold int avcodec_close(AVCodecContext *avctx)
avctx->codec->close(avctx);
avcodec_default_free_buffers(avctx);
avctx->coded_frame = NULL;
+ av_freep(&avctx->internal);
if (avctx->codec && avctx->codec->priv_class)
av_opt_free(avctx->priv_data);
av_opt_free(avctx);
@@ -1065,42 +1304,66 @@ const char *avcodec_license(void)
return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
}
-void avcodec_init(void)
-{
- static int initialized = 0;
-
- if (initialized != 0)
- return;
- initialized = 1;
-
- dsputil_static_init();
-}
-
void avcodec_flush_buffers(AVCodecContext *avctx)
{
- if(HAVE_PTHREADS && avctx->active_thread_type&FF_THREAD_FRAME)
+ if(HAVE_THREADS && avctx->active_thread_type&FF_THREAD_FRAME)
ff_thread_flush(avctx);
else if(avctx->codec->flush)
avctx->codec->flush(avctx);
}
-void avcodec_default_free_buffers(AVCodecContext *s){
+static void video_free_buffers(AVCodecContext *s)
+{
+ AVCodecInternal *avci = s->internal;
int i, j;
- if(s->internal_buffer==NULL) return;
+ if (!avci->buffer)
+ return;
- if (s->internal_buffer_count)
- av_log(s, AV_LOG_WARNING, "Found %i unreleased buffers!\n", s->internal_buffer_count);
+ if (avci->buffer_count)
+ av_log(s, AV_LOG_WARNING, "Found %i unreleased buffers!\n",
+ avci->buffer_count);
for(i=0; i<INTERNAL_BUFFER_SIZE; i++){
- InternalBuffer *buf= &((InternalBuffer*)s->internal_buffer)[i];
+ InternalBuffer *buf = &avci->buffer[i];
for(j=0; j<4; j++){
av_freep(&buf->base[j]);
buf->data[j]= NULL;
}
}
- av_freep(&s->internal_buffer);
+ av_freep(&avci->buffer);
- s->internal_buffer_count=0;
+ avci->buffer_count=0;
+}
+
+static void audio_free_buffers(AVCodecContext *avctx)
+{
+ AVCodecInternal *avci = avctx->internal;
+ InternalBuffer *buf;
+
+ if (!avci->buffer)
+ return;
+ buf = avci->buffer;
+
+ if (buf->extended_data) {
+ av_free(buf->extended_data[0]);
+ if (buf->extended_data != buf->data)
+ av_free(buf->extended_data);
+ }
+ av_freep(&avci->buffer);
+}
+
+void avcodec_default_free_buffers(AVCodecContext *avctx)
+{
+ switch (avctx->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ video_free_buffers(avctx);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ audio_free_buffers(avctx);
+ break;
+ default:
+ break;
+ }
}
#if FF_API_OLD_FF_PICT_TYPES
@@ -1118,10 +1381,12 @@ int av_get_bits_per_sample(enum CodecID codec_id){
case CODEC_ID_ADPCM_SBPRO_4:
case CODEC_ID_ADPCM_CT:
case CODEC_ID_ADPCM_IMA_WAV:
+ case CODEC_ID_ADPCM_IMA_QT:
+ case CODEC_ID_ADPCM_SWF:
case CODEC_ID_ADPCM_MS:
case CODEC_ID_ADPCM_YAMAHA:
- return 4;
case CODEC_ID_ADPCM_G722:
+ return 4;
case CODEC_ID_PCM_ALAW:
case CODEC_ID_PCM_MULAW:
case CODEC_ID_PCM_S8:
@@ -1157,7 +1422,7 @@ int av_get_bits_per_sample(enum CodecID codec_id){
#if FF_API_OLD_SAMPLE_FMT
int av_get_bits_per_sample_format(enum AVSampleFormat sample_fmt) {
- return av_get_bits_per_sample_fmt(sample_fmt);
+ return av_get_bytes_per_sample(sample_fmt) << 3;
}
#endif
@@ -1245,6 +1510,8 @@ int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
if (ff_lockmgr_cb) {
if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY))
return -1;
+ if (ff_lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY))
+ return -1;
}
ff_lockmgr_cb = cb;
@@ -1252,11 +1519,31 @@ int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
if (ff_lockmgr_cb) {
if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_CREATE))
return -1;
+ if (ff_lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE))
+ return -1;
}
return 0;
}
-unsigned int ff_toupper4(unsigned int x)
+int avpriv_lock_avformat(void)
+{
+ if (ff_lockmgr_cb) {
+ if ((*ff_lockmgr_cb)(&avformat_mutex, AV_LOCK_OBTAIN))
+ return -1;
+ }
+ return 0;
+}
+
+int avpriv_unlock_avformat(void)
+{
+ if (ff_lockmgr_cb) {
+ if ((*ff_lockmgr_cb)(&avformat_mutex, AV_LOCK_RELEASE))
+ return -1;
+ }
+ return 0;
+}
+
+unsigned int avpriv_toupper4(unsigned int x)
{
return toupper( x &0xFF)
+ (toupper((x>>8 )&0xFF)<<8 )
@@ -1264,7 +1551,7 @@ unsigned int ff_toupper4(unsigned int x)
+ (toupper((x>>24)&0xFF)<<24);
}
-#if !HAVE_PTHREADS
+#if !HAVE_THREADS
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
{
@@ -1298,3 +1585,17 @@ int avcodec_thread_init(AVCodecContext *s, int thread_count)
return ff_thread_init(s);
}
#endif
+
+enum AVMediaType avcodec_get_type(enum CodecID codec_id)
+{
+ if (codec_id <= CODEC_ID_NONE)
+ return AVMEDIA_TYPE_UNKNOWN;
+ else if (codec_id < CODEC_ID_FIRST_AUDIO)
+ return AVMEDIA_TYPE_VIDEO;
+ else if (codec_id < CODEC_ID_FIRST_SUBTITLE)
+ return AVMEDIA_TYPE_AUDIO;
+ else if (codec_id < CODEC_ID_FIRST_UNKNOWN)
+ return AVMEDIA_TYPE_SUBTITLE;
+
+ return AVMEDIA_TYPE_UNKNOWN;
+}
diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c
new file mode 100644
index 0000000..4c3b2a1
--- /dev/null
+++ b/libavcodec/utvideo.c
@@ -0,0 +1,491 @@
+/*
+ * Ut Video decoder
+ * Copyright (c) 2011 Konstantin Shishkov
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Ut Video decoder
+ */
+
+#include <stdlib.h>
+
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "get_bits.h"
+#include "dsputil.h"
+
+enum {
+ PRED_NONE = 0,
+ PRED_LEFT,
+ PRED_GRADIENT,
+ PRED_MEDIAN,
+};
+
+typedef struct UtvideoContext {
+ AVCodecContext *avctx;
+ AVFrame pic;
+ DSPContext dsp;
+
+ uint32_t frame_info_size, flags, frame_info;
+ int planes;
+ int slices;
+ int compression;
+ int interlaced;
+ int frame_pred;
+
+ uint8_t *slice_bits;
+ int slice_bits_size;
+} UtvideoContext;
+
+typedef struct HuffEntry {
+ uint8_t sym;
+ uint8_t len;
+} HuffEntry;
+
+static int huff_cmp(const void *a, const void *b)
+{
+ const HuffEntry *aa = a, *bb = b;
+ return (aa->len - bb->len)*256 + aa->sym - bb->sym;
+}
+
+static int build_huff(const uint8_t *src, VLC *vlc, int *fsym)
+{
+ int i;
+ HuffEntry he[256];
+ int last;
+ uint32_t codes[256];
+ uint8_t bits[256];
+ uint8_t syms[256];
+ uint32_t code;
+
+ *fsym = -1;
+ for (i = 0; i < 256; i++) {
+ he[i].sym = i;
+ he[i].len = *src++;
+ }
+ qsort(he, 256, sizeof(*he), huff_cmp);
+
+ if (!he[0].len) {
+ *fsym = he[0].sym;
+ return 0;
+ }
+ if (he[0].len > 32)
+ return -1;
+
+ last = 255;
+ while (he[last].len == 255 && last)
+ last--;
+
+ code = 1;
+ for (i = last; i >= 0; i--) {
+ codes[i] = code >> (32 - he[i].len);
+ bits[i] = he[i].len;
+ syms[i] = he[i].sym;
+ code += 0x80000000u >> (he[i].len - 1);
+ }
+
+ return init_vlc_sparse(vlc, FFMIN(he[last].len, 9), last + 1,
+ bits, sizeof(*bits), sizeof(*bits),
+ codes, sizeof(*codes), sizeof(*codes),
+ syms, sizeof(*syms), sizeof(*syms), 0);
+}
+
+static int decode_plane(UtvideoContext *c, int plane_no,
+ uint8_t *dst, int step, int stride,
+ int width, int height,
+ const uint8_t *src, int src_size, int use_pred)
+{
+ int i, j, slice, pix;
+ int sstart, send;
+ VLC vlc;
+ GetBitContext gb;
+ int prev, fsym;
+ const int cmask = ~(!plane_no && c->avctx->pix_fmt == PIX_FMT_YUV420P);
+
+ if (build_huff(src, &vlc, &fsym)) {
+ av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (fsym >= 0) { // build_huff reported a symbol to fill slices with
+ send = 0;
+ for (slice = 0; slice < c->slices; slice++) {
+ uint8_t *dest;
+
+ sstart = send;
+ send = (height * (slice + 1) / c->slices) & cmask;
+ dest = dst + sstart * stride;
+
+ prev = 0x80;
+ for (j = sstart; j < send; j++) {
+ for (i = 0; i < width * step; i += step) {
+ pix = fsym;
+ if (use_pred) {
+ prev += pix;
+ pix = prev;
+ }
+ dest[i] = pix;
+ }
+ dest += stride;
+ }
+ }
+ return 0;
+ }
+
+ src += 256;
+ src_size -= 256;
+
+ send = 0;
+ for (slice = 0; slice < c->slices; slice++) {
+ uint8_t *dest;
+ int slice_data_start, slice_data_end, slice_size;
+
+ sstart = send;
+ send = (height * (slice + 1) / c->slices) & cmask;
+ dest = dst + sstart * stride;
+
+ // slice offset and size validation was done earlier
+ slice_data_start = slice ? AV_RL32(src + slice * 4 - 4) : 0;
+ slice_data_end = AV_RL32(src + slice * 4);
+ slice_size = slice_data_end - slice_data_start;
+
+ if (!slice_size) {
+ for (j = sstart; j < send; j++) {
+ for (i = 0; i < width * step; i += step)
+ dest[i] = 0x80;
+ dest += stride;
+ }
+ continue;
+ }
+
+ memcpy(c->slice_bits, src + slice_data_start + c->slices * 4, slice_size);
+ memset(c->slice_bits + slice_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ c->dsp.bswap_buf((uint32_t*)c->slice_bits, (uint32_t*)c->slice_bits,
+ (slice_data_end - slice_data_start + 3) >> 2);
+ init_get_bits(&gb, c->slice_bits, slice_size * 8);
+
+ prev = 0x80;
+ for (j = sstart; j < send; j++) {
+ for (i = 0; i < width * step; i += step) {
+ if (get_bits_left(&gb) <= 0) {
+ av_log(c->avctx, AV_LOG_ERROR, "Slice decoding ran out of bits\n");
+ goto fail;
+ }
+ pix = get_vlc2(&gb, vlc.table, vlc.bits, 4);
+ if (pix < 0) {
+ av_log(c->avctx, AV_LOG_ERROR, "Decoding error\n");
+ goto fail;
+ }
+ if (use_pred) {
+ prev += pix;
+ pix = prev;
+ }
+ dest[i] = pix;
+ }
+ dest += stride;
+ }
+ if (get_bits_left(&gb) > 32)
+ av_log(c->avctx, AV_LOG_WARNING, "%d bits left after decoding slice\n",
+ get_bits_left(&gb));
+ }
+
+ free_vlc(&vlc);
+
+ return 0;
+fail:
+ free_vlc(&vlc);
+ return AVERROR_INVALIDDATA;
+}
+
+static const int rgb_order[4] = { 1, 2, 0, 3 };
+
+static void restore_rgb_planes(uint8_t *src, int step, int stride, int width, int height)
+{
+ int i, j;
+ uint8_t r, g, b;
+
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width * step; i += step) {
+ r = src[i];
+ g = src[i + 1];
+ b = src[i + 2];
+ src[i] = r + g - 0x80;
+ src[i + 2] = b + g - 0x80;
+ }
+ src += stride;
+ }
+}
+
+static void restore_median(uint8_t *src, int step, int stride,
+ int width, int height, int slices, int rmode)
+{
+ int i, j, slice;
+ int A, B, C;
+ uint8_t *bsrc;
+ int slice_start, slice_height;
+ const int cmask = ~rmode;
+
+ for (slice = 0; slice < slices; slice++) {
+ slice_start = ((slice * height) / slices) & cmask;
+ slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start;
+
+ bsrc = src + slice_start * stride;
+
+ // first line - left neighbour prediction
+ bsrc[0] += 0x80;
+ A = bsrc[0];
+ for (i = step; i < width * step; i += step) {
+ bsrc[i] += A;
+ A = bsrc[i];
+ }
+ bsrc += stride;
+ if (slice_height == 1)
+ continue;
+ // second line - first element has top predition, the rest uses median
+ C = bsrc[-stride];
+ bsrc[0] += C;
+ A = bsrc[0];
+ for (i = step; i < width * step; i += step) {
+ B = bsrc[i - stride];
+ bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
+ C = B;
+ A = bsrc[i];
+ }
+ bsrc += stride;
+ // the rest of lines use continuous median prediction
+ for (j = 2; j < slice_height; j++) {
+ for (i = 0; i < width * step; i += step) {
+ B = bsrc[i - stride];
+ bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
+ C = B;
+ A = bsrc[i];
+ }
+ bsrc += stride;
+ }
+ }
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ const uint8_t *buf_end = buf + buf_size;
+ UtvideoContext *c = avctx->priv_data;
+ const uint8_t *ptr;
+ int i, j;
+ const uint8_t *plane_start[5];
+ int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size;
+ int ret;
+
+ if (c->pic.data[0])
+ avctx->release_buffer(avctx, &c->pic);
+
+ c->pic.reference = 1;
+ c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
+ if ((ret = avctx->get_buffer(avctx, &c->pic)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+
+ /* parse plane structure to retrieve frame flags and validate slice offsets */
+ ptr = buf;
+ for (i = 0; i < c->planes; i++) {
+ plane_start[i] = ptr;
+ if (buf_end - ptr < 256 + 4 * c->slices) {
+ av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ptr += 256;
+ slice_start = 0;
+ slice_end = 0;
+ for (j = 0; j < c->slices; j++) {
+ slice_end = bytestream_get_le32(&ptr);
+ slice_size = slice_end - slice_start;
+ if (slice_size < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
+ return AVERROR_INVALIDDATA;
+ }
+ slice_start = slice_end;
+ max_slice_size = FFMAX(max_slice_size, slice_size);
+ }
+ plane_size = slice_end;
+ if (buf_end - ptr < plane_size) {
+ av_log(avctx, AV_LOG_ERROR, "Plane size is bigger than available data\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ptr += plane_size;
+ }
+ plane_start[c->planes] = ptr;
+ if (buf_end - ptr < c->frame_info_size) {
+ av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n");
+ return AVERROR_INVALIDDATA;
+ }
+ c->frame_info = AV_RL32(ptr);
+ av_log(avctx, AV_LOG_DEBUG, "frame information flags %X\n", c->frame_info);
+
+ c->frame_pred = (c->frame_info >> 8) & 3;
+
+ if (c->frame_pred == PRED_GRADIENT) {
+ av_log_ask_for_sample(avctx, "Frame uses gradient prediction\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ av_fast_malloc(&c->slice_bits, &c->slice_bits_size,
+ max_slice_size + FF_INPUT_BUFFER_PADDING_SIZE);
+
+ if (!c->slice_bits) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
+ return AVERROR(ENOMEM);
+ }
+
+ switch (c->avctx->pix_fmt) {
+ case PIX_FMT_RGB24:
+ case PIX_FMT_RGBA:
+ for (i = 0; i < c->planes; i++) {
+ ret = decode_plane(c, i, c->pic.data[0] + rgb_order[i], c->planes,
+ c->pic.linesize[0], avctx->width, avctx->height,
+ plane_start[i], plane_start[i + 1] - plane_start[i],
+ c->frame_pred == PRED_LEFT);
+ if (ret)
+ return ret;
+ if (c->frame_pred == PRED_MEDIAN)
+ restore_median(c->pic.data[0] + rgb_order[i], c->planes,
+ c->pic.linesize[0], avctx->width, avctx->height,
+ c->slices, 0);
+ }
+ restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0],
+ avctx->width, avctx->height);
+ break;
+ case PIX_FMT_YUV420P:
+ for (i = 0; i < 3; i++) {
+ ret = decode_plane(c, i, c->pic.data[i], 1,
+ c->pic.linesize[i], avctx->width >> !!i, avctx->height >> !!i,
+ plane_start[i], plane_start[i + 1] - plane_start[i],
+ c->frame_pred == PRED_LEFT);
+ if (ret)
+ return ret;
+ if (c->frame_pred == PRED_MEDIAN)
+ restore_median(c->pic.data[i], 1, c->pic.linesize[i],
+ avctx->width >> !!i, avctx->height >> !!i,
+ c->slices, !i);
+ }
+ break;
+ case PIX_FMT_YUV422P:
+ for (i = 0; i < 3; i++) {
+ ret = decode_plane(c, i, c->pic.data[i], 1,
+ c->pic.linesize[i], avctx->width >> !!i, avctx->height,
+ plane_start[i], plane_start[i + 1] - plane_start[i],
+ c->frame_pred == PRED_LEFT);
+ if (ret)
+ return ret;
+ if (c->frame_pred == PRED_MEDIAN)
+ restore_median(c->pic.data[i], 1, c->pic.linesize[i],
+ avctx->width >> !!i, avctx->height, c->slices, 0);
+ }
+ break;
+ }
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame*)data = c->pic;
+
+ /* always report that the buffer was completely consumed */
+ return buf_size;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ UtvideoContext * const c = avctx->priv_data;
+
+ c->avctx = avctx;
+
+ dsputil_init(&c->dsp, avctx);
+
+ if (avctx->extradata_size < 16) {
+ av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d, should be at least 16\n",
+ avctx->extradata_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d.%d.%d\n",
+ avctx->extradata[3], avctx->extradata[2],
+ avctx->extradata[1], avctx->extradata[0]);
+ av_log(avctx, AV_LOG_DEBUG, "Original format %X\n", AV_RB32(avctx->extradata + 4));
+ c->frame_info_size = AV_RL32(avctx->extradata + 8);
+ c->flags = AV_RL32(avctx->extradata + 12);
+
+ if (c->frame_info_size != 4)
+ av_log_ask_for_sample(avctx, "Frame info is not 4 bytes\n");
+ av_log(avctx, AV_LOG_DEBUG, "Encoding parameters %08X\n", c->flags);
+ c->slices = (c->flags >> 24) + 1;
+ c->compression = c->flags & 1;
+ c->interlaced = c->flags & 0x800;
+
+ c->slice_bits_size = 0;
+
+ switch (avctx->codec_tag) {
+ case MKTAG('U', 'L', 'R', 'G'):
+ c->planes = 3;
+ avctx->pix_fmt = PIX_FMT_RGB24;
+ break;
+ case MKTAG('U', 'L', 'R', 'A'):
+ c->planes = 4;
+ avctx->pix_fmt = PIX_FMT_RGBA;
+ break;
+ case MKTAG('U', 'L', 'Y', '0'):
+ c->planes = 3;
+ avctx->pix_fmt = PIX_FMT_YUV420P;
+ break;
+ case MKTAG('U', 'L', 'Y', '2'):
+ c->planes = 3;
+ avctx->pix_fmt = PIX_FMT_YUV422P;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unknown Ut Video FOURCC provided (%08X)\n",
+ avctx->codec_tag);
+ return AVERROR_INVALIDDATA;
+ }
+
+ return 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ UtvideoContext * const c = avctx->priv_data;
+
+ if (c->pic.data[0])
+ avctx->release_buffer(avctx, &c->pic);
+
+ av_freep(&c->slice_bits);
+
+ return 0;
+}
+
+AVCodec ff_utvideo_decoder = {
+ .name = "utvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_UTVIDEO,
+ .priv_data_size = sizeof(UtvideoContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("Ut Video"),
+};
+
diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c
index f4ea65c..37b4a3c 100644
--- a/libavcodec/v210dec.c
+++ b/libavcodec/v210dec.c
@@ -30,7 +30,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n");
return -1;
}
- avctx->pix_fmt = PIX_FMT_YUV422P16;
+ avctx->pix_fmt = PIX_FMT_YUV422P10;
avctx->bits_per_raw_sample = 10;
avctx->coded_frame = avcodec_alloc_frame();
@@ -68,10 +68,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
#define READ_PIXELS(a, b, c) \
do { \
- val = av_le2ne32(*src++); \
- *a++ = val << 6; \
- *b++ = (val >> 4) & 0xFFC0; \
- *c++ = (val >> 14) & 0xFFC0; \
+ val = av_le2ne32(*src++); \
+ *a++ = val & 0x3FF; \
+ *b++ = (val >> 10) & 0x3FF; \
+ *c++ = (val >> 20) & 0x3FF; \
} while (0)
for (h = 0; h < avctx->height; h++) {
@@ -87,15 +87,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
READ_PIXELS(u, y, v);
val = av_le2ne32(*src++);
- *y++ = val << 6;
+ *y++ = val & 0x3FF;
}
if (w < avctx->width - 3) {
- *u++ = (val >> 4) & 0xFFC0;
- *y++ = (val >> 14) & 0xFFC0;
+ *u++ = (val >> 10) & 0x3FF;
+ *y++ = (val >> 20) & 0x3FF;
val = av_le2ne32(*src++);
- *v++ = val << 6;
- *y++ = (val >> 4) & 0xFFC0;
+ *v++ = val & 0x3FF;
+ *y++ = (val >> 10) & 0x3FF;
}
psrc += stride;
@@ -121,14 +121,12 @@ static av_cold int decode_close(AVCodecContext *avctx)
}
AVCodec ff_v210_decoder = {
- "v210",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_V210,
- 0,
- decode_init,
- NULL,
- decode_close,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "v210",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_V210,
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
};
diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c
index 8b022fa..5861352 100644
--- a/libavcodec/v210enc.c
+++ b/libavcodec/v210enc.c
@@ -31,8 +31,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
return -1;
}
- if (avctx->pix_fmt != PIX_FMT_YUV422P16) {
- av_log(avctx, AV_LOG_ERROR, "v210 needs YUV422P16\n");
+ if (avctx->pix_fmt != PIX_FMT_YUV422P10) {
+ av_log(avctx, AV_LOG_ERROR, "v210 needs YUV422P10\n");
return -1;
}
@@ -66,11 +66,13 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf,
return -1;
}
+#define CLIP(v) av_clip(v, 4, 1019)
+
#define WRITE_PIXELS(a, b, c) \
do { \
- val = (*a++ >> 6) | \
- ((*b++ & 0xFFC0) << 4); \
- val|= (*c++ & 0xFFC0) << 14; \
+ val = CLIP(*a++); \
+ val |= (CLIP(*b++) << 10) | \
+ (CLIP(*c++) << 20); \
bytestream_put_le32(&p, val); \
} while (0)
@@ -85,17 +87,15 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf,
if (w < avctx->width - 1) {
WRITE_PIXELS(u, y, v);
- val = *y++ >> 6;
+ val = CLIP(*y++);
if (w == avctx->width - 2)
bytestream_put_le32(&p, val);
}
if (w < avctx->width - 3) {
- val |=((*u++ & 0xFFC0) << 4) |
- ((*y++ & 0xFFC0) << 14);
+ val |= (CLIP(*u++) << 10) | (CLIP(*y++) << 20);
bytestream_put_le32(&p, val);
- val = (*v++ >> 6) |
- (*y++ & 0xFFC0) << 4;
+ val = CLIP(*v++) | (CLIP(*y++) << 10);
bytestream_put_le32(&p, val);
}
@@ -118,13 +118,12 @@ static av_cold int encode_close(AVCodecContext *avctx)
}
AVCodec ff_v210_encoder = {
- "v210",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_V210,
- 0,
- encode_init,
- encode_frame,
- encode_close,
- .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P16, PIX_FMT_NONE},
+ .name = "v210",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_V210,
+ .init = encode_init,
+ .encode = encode_frame,
+ .close = encode_close,
+ .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P10, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
};
diff --git a/libavcodec/v210x.c b/libavcodec/v210x.c
index e3b1a3c..959dec5 100644
--- a/libavcodec/v210x.c
+++ b/libavcodec/v210x.c
@@ -133,14 +133,12 @@ static av_cold int decode_close(AVCodecContext *avctx)
}
AVCodec ff_v210x_decoder = {
- "v210x",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_V210X,
- 0,
- decode_init,
- NULL,
- decode_close,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "v210x",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_V210X,
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
};
diff --git a/libavcodec/v410dec.c b/libavcodec/v410dec.c
new file mode 100644
index 0000000..54c9595
--- /dev/null
+++ b/libavcodec/v410dec.c
@@ -0,0 +1,118 @@
+/*
+ * v410 decoder
+ *
+ * Copyright (c) 2011 Derek Buitenhuis
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+
+static av_cold int v410_decode_init(AVCodecContext *avctx)
+{
+ avctx->pix_fmt = PIX_FMT_YUV444P10;
+ avctx->bits_per_raw_sample = 10;
+
+ if (avctx->width & 1) {
+ av_log(avctx, AV_LOG_ERROR, "v410 requires even width.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ avctx->coded_frame = avcodec_alloc_frame();
+
+ if (!avctx->coded_frame) {
+ av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
+static int v410_decode_frame(AVCodecContext *avctx, void *data,
+ int *data_size, AVPacket *avpkt)
+{
+ AVFrame *pic = avctx->coded_frame;
+ uint8_t *src = avpkt->data;
+ uint16_t *y, *u, *v;
+ uint32_t val;
+ int i, j;
+
+ if (pic->data[0])
+ avctx->release_buffer(avctx, pic);
+
+ if (avpkt->size < 4 * avctx->height * avctx->width) {
+ av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+ return AVERROR(EINVAL);
+ }
+
+ pic->reference = 0;
+
+ if (avctx->get_buffer(avctx, pic) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ pic->key_frame = 1;
+ pic->pict_type = FF_I_TYPE;
+
+ y = (uint16_t *)pic->data[0];
+ u = (uint16_t *)pic->data[1];
+ v = (uint16_t *)pic->data[2];
+
+ for (i = 0; i < avctx->height; i++) {
+ for (j = 0; j < avctx->width; j++) {
+ val = AV_RL32(src);
+
+ u[j] = (val >> 2) & 0x3FF;
+ y[j] = (val >> 12) & 0x3FF;
+ v[j] = (val >> 22);
+
+ src += 4;
+ }
+
+ y += pic->linesize[0] >> 1;
+ u += pic->linesize[1] >> 1;
+ v += pic->linesize[2] >> 1;
+ }
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame *)data = *pic;
+
+ return avpkt->size;
+}
+
+static av_cold int v410_decode_close(AVCodecContext *avctx)
+{
+ if (avctx->coded_frame->data[0])
+ avctx->release_buffer(avctx, avctx->coded_frame);
+
+ av_freep(&avctx->coded_frame);
+
+ return 0;
+}
+
+AVCodec ff_v410_decoder = {
+ .name = "v410",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_V410,
+ .init = v410_decode_init,
+ .decode = v410_decode_frame,
+ .close = v410_decode_close,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"),
+};
diff --git a/libavcodec/v410enc.c b/libavcodec/v410enc.c
new file mode 100644
index 0000000..95b36c1
--- /dev/null
+++ b/libavcodec/v410enc.c
@@ -0,0 +1,99 @@
+/*
+ * v410 encoder
+ *
+ * Copyright (c) 2011 Derek Buitenhuis
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+
+static av_cold int v410_encode_init(AVCodecContext *avctx)
+{
+ if (avctx->width & 1) {
+ av_log(avctx, AV_LOG_ERROR, "v410 requires even width.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ avctx->coded_frame = avcodec_alloc_frame();
+
+ if (!avctx->coded_frame) {
+ av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
+static int v410_encode_frame(AVCodecContext *avctx, uint8_t *buf,
+ int buf_size, void *data)
+{
+ AVFrame *pic = data;
+ uint8_t *dst = buf;
+ uint16_t *y, *u, *v;
+ uint32_t val;
+ int i, j;
+ int output_size = 0;
+
+ if (buf_size < avctx->width * avctx->height * 4) {
+ av_log(avctx, AV_LOG_ERROR, "Out buffer is too small.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ avctx->coded_frame->reference = 0;
+ avctx->coded_frame->key_frame = 1;
+ avctx->coded_frame->pict_type = FF_I_TYPE;
+
+ y = (uint16_t *)pic->data[0];
+ u = (uint16_t *)pic->data[1];
+ v = (uint16_t *)pic->data[2];
+
+ for (i = 0; i < avctx->height; i++) {
+ for (j = 0; j < avctx->width; j++) {
+ val = u[j] << 2;
+ val |= y[j] << 12;
+ val |= v[j] << 22;
+ AV_WL32(dst, val);
+ dst += 4;
+ output_size += 4;
+ }
+ y += pic->linesize[0] >> 1;
+ u += pic->linesize[1] >> 1;
+ v += pic->linesize[2] >> 1;
+ }
+
+ return output_size;
+}
+
+static av_cold int v410_encode_close(AVCodecContext *avctx)
+{
+ av_freep(&avctx->coded_frame);
+
+ return 0;
+}
+
+AVCodec ff_v410_encoder = {
+ .name = "v410",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_V410,
+ .init = v410_encode_init,
+ .encode = v410_encode_frame,
+ .close = v410_encode_close,
+ .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_YUV444P10, PIX_FMT_NONE },
+ .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"),
+};
diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c
index cc2fec3..d6b0298 100644
--- a/libavcodec/vaapi.c
+++ b/libavcodec/vaapi.c
@@ -24,7 +24,7 @@
#include "vaapi_internal.h"
/**
- * \addtogroup VAAPI_Decoding
+ * @addtogroup VAAPI_Decoding
*
* @{
*/
diff --git a/libavcodec/vaapi.h b/libavcodec/vaapi.h
index 306e164..36fb386 100644
--- a/libavcodec/vaapi.h
+++ b/libavcodec/vaapi.h
@@ -27,8 +27,8 @@
#include <stdint.h>
/**
- * \defgroup VAAPI_Decoding VA API Decoding
- * \ingroup Decoder
+ * @defgroup VAAPI_Decoding VA API Decoding
+ * @ingroup Decoder
* @{
*/
diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
index 83bf290..820568a 100644
--- a/libavcodec/vaapi_h264.c
+++ b/libavcodec/vaapi_h264.c
@@ -23,9 +23,10 @@
#include "vaapi_internal.h"
#include "h264.h"
-/** @file
- * This file implements the glue code between Libav's and VA API's
- * structures for H.264 decoding.
+/**
+ * @file
+ * This file implements the glue code between Libav's and VA API's
+ * structures for H.264 decoding.
*/
/**
@@ -54,7 +55,7 @@ static void fill_vaapi_pic(VAPictureH264 *va_pic,
int pic_structure)
{
if (pic_structure == 0)
- pic_structure = pic->reference;
+ pic_structure = pic->f.reference;
pic_structure &= PICT_FRAME; /* PICT_TOP_FIELD|PICT_BOTTOM_FIELD */
va_pic->picture_id = ff_vaapi_get_surface_id(pic);
@@ -63,7 +64,7 @@ static void fill_vaapi_pic(VAPictureH264 *va_pic,
va_pic->flags = 0;
if (pic_structure != PICT_FRAME)
va_pic->flags |= (pic_structure & PICT_TOP_FIELD) ? VA_PICTURE_H264_TOP_FIELD : VA_PICTURE_H264_BOTTOM_FIELD;
- if (pic->reference)
+ if (pic->f.reference)
va_pic->flags |= pic->long_ref ? VA_PICTURE_H264_LONG_TERM_REFERENCE : VA_PICTURE_H264_SHORT_TERM_REFERENCE;
va_pic->TopFieldOrderCnt = 0;
@@ -133,13 +134,13 @@ static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param,
for (i = 0; i < h->short_ref_count; i++) {
Picture * const pic = h->short_ref[i];
- if (pic && pic->reference && dpb_add(&dpb, pic) < 0)
+ if (pic && pic->f.reference && dpb_add(&dpb, pic) < 0)
return -1;
}
for (i = 0; i < 16; i++) {
Picture * const pic = h->long_ref[i];
- if (pic && pic->reference && dpb_add(&dpb, pic) < 0)
+ if (pic && pic->f.reference && dpb_add(&dpb, pic) < 0)
return -1;
}
return 0;
@@ -159,7 +160,7 @@ static void fill_vaapi_RefPicList(VAPictureH264 RefPicList[32],
{
unsigned int i, n = 0;
for (i = 0; i < ref_count; i++)
- if (ref_list[i].reference)
+ if (ref_list[i].f.reference)
fill_vaapi_pic(&RefPicList[n++], &ref_list[i], 0);
for (; n < 32; n++)
@@ -340,9 +341,7 @@ AVHWAccel ff_h264_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_H264,
.pix_fmt = PIX_FMT_VAAPI_VLD,
- .capabilities = 0,
.start_frame = start_frame,
.end_frame = end_frame,
.decode_slice = decode_slice,
- .priv_data_size = 0,
};
diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h
index 3a14a2b..c6d5d6e 100644
--- a/libavcodec/vaapi_internal.h
+++ b/libavcodec/vaapi_internal.h
@@ -30,7 +30,7 @@
#include "mpegvideo.h"
/**
- * \addtogroup VAAPI_Decoding
+ * @addtogroup VAAPI_Decoding
*
* @{
*/
@@ -38,7 +38,7 @@
/** Extract VASurfaceID from a Picture */
static inline VASurfaceID ff_vaapi_get_surface_id(Picture *pic)
{
- return (uintptr_t)pic->data[3];
+ return (uintptr_t)pic->f.data[3];
}
/** Common AVHWAccel.end_frame() implementation */
diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c
index 561f4bf..6b08ed2 100644
--- a/libavcodec/vaapi_mpeg2.c
+++ b/libavcodec/vaapi_mpeg2.c
@@ -109,14 +109,14 @@ static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer
MpegEncContext * const s = avctx->priv_data;
VASliceParameterBufferMPEG2 *slice_param;
GetBitContext gb;
- uint32_t start_code, quantiser_scale_code, intra_slice_flag, macroblock_offset;
+ uint32_t quantiser_scale_code, intra_slice_flag, macroblock_offset;
av_dlog(avctx, "vaapi_mpeg2_decode_slice(): buffer %p, size %d\n", buffer, size);
/* Determine macroblock_offset */
init_get_bits(&gb, buffer, 8 * size);
- start_code = get_bits(&gb, 32);
- assert((start_code & 0xffffff00) == 0x00000100);
+ if (get_bits_long(&gb, 32) >> 8 != 1) /* start code */
+ return AVERROR_INVALIDDATA;
quantiser_scale_code = get_bits(&gb, 5);
intra_slice_flag = get_bits1(&gb);
if (intra_slice_flag) {
@@ -143,9 +143,7 @@ AVHWAccel ff_mpeg2_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_MPEG2VIDEO,
.pix_fmt = PIX_FMT_VAAPI_VLD,
- .capabilities = 0,
.start_frame = vaapi_mpeg2_start_frame,
.end_frame = vaapi_mpeg2_end_frame,
.decode_slice = vaapi_mpeg2_decode_slice,
- .priv_data_size = 0,
};
diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c
index fcd4290..41d54c6 100644
--- a/libavcodec/vaapi_mpeg4.c
+++ b/libavcodec/vaapi_mpeg4.c
@@ -79,7 +79,7 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_
pic_param->quant_precision = s->quant_precision;
pic_param->vop_fields.value = 0; /* reset all bits */
pic_param->vop_fields.bits.vop_coding_type = s->pict_type - AV_PICTURE_TYPE_I;
- pic_param->vop_fields.bits.backward_reference_vop_coding_type = s->pict_type == AV_PICTURE_TYPE_B ? s->next_picture.pict_type - AV_PICTURE_TYPE_I : 0;
+ pic_param->vop_fields.bits.backward_reference_vop_coding_type = s->pict_type == AV_PICTURE_TYPE_B ? s->next_picture.f.pict_type - AV_PICTURE_TYPE_I : 0;
pic_param->vop_fields.bits.vop_rounding_type = s->no_rounding;
pic_param->vop_fields.bits.intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(s);
pic_param->vop_fields.bits.top_field_first = s->top_field_first;
@@ -98,7 +98,7 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_
pic_param->forward_reference_picture = ff_vaapi_get_surface_id(&s->last_picture);
/* Fill in VAIQMatrixBufferMPEG4 */
- /* Only the first inverse quantisation method uses the weighthing matrices */
+ /* Only the first inverse quantisation method uses the weighting matrices */
if (pic_param->vol_fields.bits.quant_type) {
iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG4));
if (!iq_matrix)
@@ -155,11 +155,9 @@ AVHWAccel ff_mpeg4_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_MPEG4,
.pix_fmt = PIX_FMT_VAAPI_VLD,
- .capabilities = 0,
.start_frame = vaapi_mpeg4_start_frame,
.end_frame = vaapi_mpeg4_end_frame,
.decode_slice = vaapi_mpeg4_decode_slice,
- .priv_data_size = 0,
};
#endif
@@ -169,10 +167,8 @@ AVHWAccel ff_h263_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_H263,
.pix_fmt = PIX_FMT_VAAPI_VLD,
- .capabilities = 0,
.start_frame = vaapi_mpeg4_start_frame,
.end_frame = vaapi_mpeg4_end_frame,
.decode_slice = vaapi_mpeg4_decode_slice,
- .priv_data_size = 0,
};
#endif
diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c
index 19865dc..d519987 100644
--- a/libavcodec/vaapi_vc1.c
+++ b/libavcodec/vaapi_vc1.c
@@ -116,6 +116,18 @@ static inline VAMvModeVC1 vc1_get_MVMODE2(VC1Context *v)
return 0;
}
+/** Reconstruct bitstream TTFRM (7.1.1.41, Table-53) */
+static inline int vc1_get_TTFRM(VC1Context *v)
+{
+ switch (v->ttfrm) {
+ case TT_8X8: return 0;
+ case TT_8X4: return 1;
+ case TT_4X8: return 2;
+ case TT_4X4: return 3;
+ }
+ return 0;
+}
+
/** Pack Libav bitplanes into a VABitPlaneBuffer element */
static inline void vc1_pack_bitplanes(uint8_t *bitplane, int n, const uint8_t *ff_bp[3], int x, int y, int stride)
{
@@ -239,7 +251,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t
pic_param->transform_fields.value = 0; /* reset all bits */
pic_param->transform_fields.bits.variable_sized_transform_flag = v->vstransform;
pic_param->transform_fields.bits.mb_level_transform_type_flag = v->ttmbf;
- pic_param->transform_fields.bits.frame_level_transform_type = v->ttfrm;
+ pic_param->transform_fields.bits.frame_level_transform_type = vc1_get_TTFRM(v);
pic_param->transform_fields.bits.transform_ac_codingset_idx1 = v->c_ac_table_index;
pic_param->transform_fields.bits.transform_ac_codingset_idx2 = v->y_ac_table_index;
pic_param->transform_fields.bits.intra_transform_dc_table = v->s.dc_table_index;
@@ -334,11 +346,9 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_WMV3,
.pix_fmt = PIX_FMT_VAAPI_VLD,
- .capabilities = 0,
.start_frame = vaapi_vc1_start_frame,
.end_frame = vaapi_vc1_end_frame,
.decode_slice = vaapi_vc1_decode_slice,
- .priv_data_size = 0,
};
#endif
@@ -347,9 +357,7 @@ AVHWAccel ff_vc1_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_VC1,
.pix_fmt = PIX_FMT_VAAPI_VLD,
- .capabilities = 0,
.start_frame = vaapi_vc1_start_frame,
.end_frame = vaapi_vc1_end_frame,
.decode_slice = vaapi_vc1_decode_slice,
- .priv_data_size = 0,
};
diff --git a/libavcodec/vb.c b/libavcodec/vb.c
index fb37283..96387b6 100644
--- a/libavcodec/vb.c
+++ b/libavcodec/vb.c
@@ -288,14 +288,13 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_vb_decoder = {
- "vb",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VB,
- sizeof(VBDecContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
+ .name = "vb",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VB,
+ .priv_data_size = sizeof(VBDecContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Beam Software VB"),
};
diff --git a/libavcodec/vble.c b/libavcodec/vble.c
new file mode 100644
index 0000000..fa205f5
--- /dev/null
+++ b/libavcodec/vble.c
@@ -0,0 +1,229 @@
+/*
+ * VBLE Decoder
+ * Copyright (c) 2011 Derek Buitenhuis
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * VBLE Decoder
+ */
+
+#define BITSTREAM_READER_LE
+
+#include "avcodec.h"
+#include "dsputil.h"
+#include "get_bits.h"
+
+typedef struct {
+ AVCodecContext *avctx;
+ DSPContext dsp;
+
+ int size;
+ uint8_t *val; /* First holds the lengths of vlc symbols and then their values */
+} VBLEContext;
+
+static uint8_t vble_read_reverse_unary(GetBitContext *gb)
+{
+ /* At most we need to read 9 bits total to get indices up to 8 */
+ uint8_t val = show_bits(gb, 8);
+
+ if (val) {
+ val = 7 - av_log2_16bit(av_reverse[val]);
+ skip_bits(gb, val + 1);
+ return val;
+ } else {
+ skip_bits(gb, 8);
+ if (get_bits1(gb))
+ return 8;
+ }
+
+ /* Return something larger than 8 on error */
+ return UINT8_MAX;
+}
+
+static int vble_unpack(VBLEContext *ctx, GetBitContext *gb)
+{
+ int i;
+
+ /* Read all the lengths in first */
+ for (i = 0; i < ctx->size; i++) {
+ ctx->val[i] = vble_read_reverse_unary(gb);
+
+ if (ctx->val[i] == UINT8_MAX)
+ return -1;
+ }
+
+ for (i = 0; i < ctx->size; i++) {
+ /* Check we have enough bits left */
+ if (get_bits_left(gb) < ctx->val[i])
+ return -1;
+
+ /* get_bits can't take a length of 0 */
+ if (ctx->val[i])
+ ctx->val[i] = (1 << ctx->val[i]) + get_bits(gb, ctx->val[i]) - 1;
+ }
+
+ return 0;
+}
+
+static void vble_restore_plane(VBLEContext *ctx, int plane, int offset,
+ int width, int height)
+{
+ AVFrame *pic = ctx->avctx->coded_frame;
+ uint8_t *dst = pic->data[plane];
+ uint8_t *val = ctx->val + offset;
+ int stride = pic->linesize[plane];
+ int i, j, left, left_top;
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++)
+ val[j] = (val[j] >> 1) ^ -(val[j] & 1);
+
+ if (i) {
+ left = 0;
+ left_top = dst[-stride];
+ ctx->dsp.add_hfyu_median_prediction(dst, dst-stride, val,
+ width, &left, &left_top);
+ } else {
+ dst[0] = val[0];
+ for (j = 1; j < width; j++)
+ dst[j] = val[j] + dst[j - 1];
+ }
+ dst += stride;
+ val += width;
+ }
+}
+
+static int vble_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ VBLEContext *ctx = avctx->priv_data;
+ AVFrame *pic = avctx->coded_frame;
+ GetBitContext gb;
+ const uint8_t *src = avpkt->data;
+ int version;
+ int offset = 0;
+ int width_uv = avctx->width / 2, height_uv = avctx->height / 2;
+
+ pic->reference = 0;
+
+ /* Clear buffer if need be */
+ if (pic->data[0])
+ avctx->release_buffer(avctx, pic);
+
+ /* Allocate buffer */
+ if (avctx->get_buffer(avctx, pic) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ /* Set flags */
+ pic->key_frame = 1;
+ pic->pict_type = FF_I_TYPE;
+
+ /* Version should always be 1 */
+ version = AV_RL32(src);
+
+ if (version != 1) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported VBLE Version: %d\n", version);
+ return AVERROR_INVALIDDATA;
+ }
+
+ init_get_bits(&gb, src + 4, (avpkt->size - 4) * 8);
+
+ /* Unpack */
+ if (vble_unpack(ctx, &gb) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid Code\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* Restore planes. Should be almost identical to Huffyuv's. */
+ vble_restore_plane(ctx, 0, offset, avctx->width, avctx->height);
+
+ /* Chroma */
+ if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) {
+ offset += avctx->width * avctx->height;
+ vble_restore_plane(ctx, 1, offset, width_uv, height_uv);
+
+ offset += width_uv * height_uv;
+ vble_restore_plane(ctx, 2, offset, width_uv, height_uv);
+ }
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame *)data = *pic;
+
+ return avpkt->size;
+}
+
+static av_cold int vble_decode_close(AVCodecContext *avctx)
+{
+ VBLEContext *ctx = avctx->priv_data;
+ AVFrame *pic = avctx->coded_frame;
+
+ if (pic->data[0])
+ avctx->release_buffer(avctx, pic);
+
+ av_freep(&avctx->coded_frame);
+ av_freep(&ctx->val);
+
+ return 0;
+}
+
+static av_cold int vble_decode_init(AVCodecContext *avctx)
+{
+ VBLEContext *ctx = avctx->priv_data;
+
+ /* Stash for later use */
+ ctx->avctx = avctx;
+ dsputil_init(&ctx->dsp, avctx);
+
+ avctx->pix_fmt = PIX_FMT_YUV420P;
+ avctx->bits_per_raw_sample = 8;
+ avctx->coded_frame = avcodec_alloc_frame();
+
+ if (!avctx->coded_frame) {
+ av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ ctx->size = avpicture_get_size(avctx->pix_fmt,
+ avctx->width, avctx->height);
+
+ ctx->val = av_malloc(ctx->size * sizeof(*ctx->val));
+
+ if (!ctx->val) {
+ av_log(avctx, AV_LOG_ERROR, "Could not allocate values buffer.\n");
+ vble_decode_close(avctx);
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
+AVCodec ff_vble_decoder = {
+ .name = "vble",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VBLE,
+ .priv_data_size = sizeof(VBLEContext),
+ .init = vble_decode_init,
+ .close = vble_decode_close,
+ .decode = vble_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("VBLE Lossless Codec"),
+};
diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index 5e53680..d728f9b 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -1,5 +1,6 @@
/*
* VC-1 and WMV3 decoder common code
+ * Copyright (c) 2011 Mashiat Sarker Shakkhar
* Copyright (c) 2006-2007 Konstantin Shishkov
* Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
*
@@ -25,6 +26,7 @@
* VC-1 and WMV3 decoder common code
*
*/
+
#include "internal.h"
#include "dsputil.h"
#include "avcodec.h"
@@ -66,14 +68,16 @@ enum Imode {
* @param[in] height Height of this buffer
* @param[in] stride of this buffer
*/
-static void decode_rowskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
+static void decode_rowskip(uint8_t* plane, int width, int height, int stride,
+ GetBitContext *gb)
+{
int x, y;
- for (y=0; y<height; y++){
+ for (y = 0; y < height; y++) {
if (!get_bits1(gb)) //rowskip
memset(plane, 0, width);
else
- for (x=0; x<width; x++)
+ for (x = 0; x < width; x++)
plane[x] = get_bits1(gb);
plane += stride;
}
@@ -86,15 +90,17 @@ static void decode_rowskip(uint8_t* plane, int width, int height, int stride, Ge
* @param[in] stride of this buffer
* @todo FIXME: Optimize
*/
-static void decode_colskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
+static void decode_colskip(uint8_t* plane, int width, int height, int stride,
+ GetBitContext *gb)
+{
int x, y;
- for (x=0; x<width; x++){
+ for (x = 0; x < width; x++) {
if (!get_bits1(gb)) //colskip
- for (y=0; y<height; y++)
+ for (y = 0; y < height; y++)
plane[y*stride] = 0;
else
- for (y=0; y<height; y++)
+ for (y = 0; y < height; y++)
plane[y*stride] = get_bits1(gb);
plane ++;
}
@@ -115,76 +121,76 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v)
uint8_t invert, *planep = data;
int width, height, stride;
- width = v->s.mb_width;
- height = v->s.mb_height;
+ width = v->s.mb_width;
+ height = v->s.mb_height >> v->field_mode;
stride = v->s.mb_stride;
invert = get_bits1(gb);
imode = get_vlc2(gb, ff_vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1);
*raw_flag = 0;
- switch (imode)
- {
+ switch (imode) {
case IMODE_RAW:
//Data is actually read in the MB layer (same for all tests == "raw")
*raw_flag = 1; //invert ignored
return invert;
case IMODE_DIFF2:
case IMODE_NORM2:
- if ((height * width) & 1)
- {
+ if ((height * width) & 1) {
*planep++ = get_bits1(gb);
- offset = 1;
+ offset = 1;
}
- else offset = 0;
+ else
+ offset = 0;
// decode bitplane as one long line
for (y = offset; y < height * width; y += 2) {
code = get_vlc2(gb, ff_vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1);
*planep++ = code & 1;
offset++;
- if(offset == width) {
- offset = 0;
+ if (offset == width) {
+ offset = 0;
planep += stride - width;
}
*planep++ = code >> 1;
offset++;
- if(offset == width) {
- offset = 0;
+ if (offset == width) {
+ offset = 0;
planep += stride - width;
}
}
break;
case IMODE_DIFF6:
case IMODE_NORM6:
- if(!(height % 3) && (width % 3)) { // use 2x3 decoding
- for(y = 0; y < height; y+= 3) {
- for(x = width & 1; x < width; x += 2) {
+ if (!(height % 3) && (width % 3)) { // use 2x3 decoding
+ for (y = 0; y < height; y += 3) {
+ for (x = width & 1; x < width; x += 2) {
code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
- if(code < 0){
+ if (code < 0) {
av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
return -1;
}
- planep[x + 0] = (code >> 0) & 1;
- planep[x + 1] = (code >> 1) & 1;
- planep[x + 0 + stride] = (code >> 2) & 1;
- planep[x + 1 + stride] = (code >> 3) & 1;
+ planep[x + 0] = (code >> 0) & 1;
+ planep[x + 1] = (code >> 1) & 1;
+ planep[x + 0 + stride] = (code >> 2) & 1;
+ planep[x + 1 + stride] = (code >> 3) & 1;
planep[x + 0 + stride * 2] = (code >> 4) & 1;
planep[x + 1 + stride * 2] = (code >> 5) & 1;
}
planep += stride * 3;
}
- if(width & 1) decode_colskip(data, 1, height, stride, &v->s.gb);
+ if (width & 1)
+ decode_colskip(data, 1, height, stride, &v->s.gb);
} else { // 3x2
planep += (height & 1) * stride;
- for(y = height & 1; y < height; y += 2) {
- for(x = width % 3; x < width; x += 3) {
+ for (y = height & 1; y < height; y += 2) {
+ for (x = width % 3; x < width; x += 3) {
code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
- if(code < 0){
+ if (code < 0) {
av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
return -1;
}
- planep[x + 0] = (code >> 0) & 1;
- planep[x + 1] = (code >> 1) & 1;
- planep[x + 2] = (code >> 2) & 1;
+ planep[x + 0] = (code >> 0) & 1;
+ planep[x + 1] = (code >> 1) & 1;
+ planep[x + 2] = (code >> 2) & 1;
planep[x + 0 + stride] = (code >> 3) & 1;
planep[x + 1 + stride] = (code >> 4) & 1;
planep[x + 2 + stride] = (code >> 5) & 1;
@@ -192,8 +198,10 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v)
planep += stride * 2;
}
x = width % 3;
- if(x) decode_colskip(data , x, height , stride, &v->s.gb);
- if(height & 1) decode_rowskip(data+x, width - x, 1, stride, &v->s.gb);
+ if (x)
+ decode_colskip(data, x, height, stride, &v->s.gb);
+ if (height & 1)
+ decode_rowskip(data + x, width - x, 1, stride, &v->s.gb);
}
break;
case IMODE_ROWSKIP:
@@ -202,33 +210,30 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v)
case IMODE_COLSKIP:
decode_colskip(data, width, height, stride, &v->s.gb);
break;
- default: break;
+ default:
+ break;
}
/* Applying diff operator */
- if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)
- {
+ if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6) {
planep = data;
planep[0] ^= invert;
- for (x=1; x<width; x++)
+ for (x = 1; x < width; x++)
planep[x] ^= planep[x-1];
- for (y=1; y<height; y++)
- {
+ for (y = 1; y < height; y++) {
planep += stride;
planep[0] ^= planep[-stride];
- for (x=1; x<width; x++)
- {
+ for (x = 1; x < width; x++) {
if (planep[x-1] != planep[x-stride]) planep[x] ^= invert;
else planep[x] ^= planep[x-1];
}
}
- }
- else if (invert)
- {
+ } else if (invert) {
planep = data;
- for (x=0; x<stride*height; x++) planep[x] = !planep[x]; //FIXME stride
+ for (x = 0; x < stride * height; x++)
+ planep[x] = !planep[x]; //FIXME stride
}
- return (imode<<1) + invert;
+ return (imode << 1) + invert;
}
/** @} */ //Bitplane group
@@ -243,35 +248,34 @@ static int vop_dquant_decoding(VC1Context *v)
int pqdiff;
//variable size
- if (v->dquant == 2)
- {
+ if (v->dquant == 2) {
pqdiff = get_bits(gb, 3);
- if (pqdiff == 7) v->altpq = get_bits(gb, 5);
- else v->altpq = v->pq + pqdiff + 1;
- }
- else
- {
+ if (pqdiff == 7)
+ v->altpq = get_bits(gb, 5);
+ else
+ v->altpq = v->pq + pqdiff + 1;
+ } else {
v->dquantfrm = get_bits1(gb);
- if ( v->dquantfrm )
- {
+ if (v->dquantfrm) {
v->dqprofile = get_bits(gb, 2);
- switch (v->dqprofile)
- {
+ switch (v->dqprofile) {
case DQPROFILE_SINGLE_EDGE:
case DQPROFILE_DOUBLE_EDGES:
v->dqsbedge = get_bits(gb, 2);
break;
case DQPROFILE_ALL_MBS:
v->dqbilevel = get_bits1(gb);
- if(!v->dqbilevel)
+ if (!v->dqbilevel)
v->halfpq = 0;
- default: break; //Forbidden ?
+ default:
+ break; //Forbidden ?
}
- if (v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS)
- {
+ if (v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS) {
pqdiff = get_bits(gb, 3);
- if (pqdiff == 7) v->altpq = get_bits(gb, 5);
- else v->altpq = v->pq + pqdiff + 1;
+ if (pqdiff == 7)
+ v->altpq = get_bits(gb, 5);
+ else
+ v->altpq = v->pq + pqdiff + 1;
}
}
}
@@ -291,80 +295,69 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
{
av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32));
v->profile = get_bits(gb, 2);
- if (v->profile == PROFILE_COMPLEX)
- {
+ if (v->profile == PROFILE_COMPLEX) {
av_log(avctx, AV_LOG_WARNING, "WMV3 Complex Profile is not fully supported\n");
}
- if (v->profile == PROFILE_ADVANCED)
- {
+ if (v->profile == PROFILE_ADVANCED) {
v->zz_8x4 = ff_vc1_adv_progressive_8x4_zz;
v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz;
return decode_sequence_header_adv(v, gb);
- }
- else
- {
+ } else {
v->zz_8x4 = wmv2_scantableA;
v->zz_4x8 = wmv2_scantableB;
v->res_y411 = get_bits1(gb);
v->res_sprite = get_bits1(gb);
- if (v->res_y411)
- {
+ if (v->res_y411) {
av_log(avctx, AV_LOG_ERROR,
"Old interlaced mode is not supported\n");
return -1;
}
- if (v->res_sprite) {
- av_log(avctx, AV_LOG_ERROR, "WMVP is not fully supported\n");
- }
}
// (fps-2)/4 (->30)
v->frmrtq_postproc = get_bits(gb, 3); //common
// (bitrate-32kbps)/64kbps
v->bitrtq_postproc = get_bits(gb, 5); //common
- v->s.loop_filter = get_bits1(gb); //common
- if(v->s.loop_filter == 1 && v->profile == PROFILE_SIMPLE)
- {
+ v->s.loop_filter = get_bits1(gb); //common
+ if (v->s.loop_filter == 1 && v->profile == PROFILE_SIMPLE) {
av_log(avctx, AV_LOG_ERROR,
"LOOPFILTER shall not be enabled in Simple Profile\n");
}
- if(v->s.avctx->skip_loop_filter >= AVDISCARD_ALL)
+ if (v->s.avctx->skip_loop_filter >= AVDISCARD_ALL)
v->s.loop_filter = 0;
- v->res_x8 = get_bits1(gb); //reserved
- v->multires = get_bits1(gb);
- v->res_fasttx = get_bits1(gb);
- if (!v->res_fasttx)
- {
- v->vc1dsp.vc1_inv_trans_8x8 = ff_simple_idct;
- v->vc1dsp.vc1_inv_trans_8x4 = ff_simple_idct84_add;
- v->vc1dsp.vc1_inv_trans_4x8 = ff_simple_idct48_add;
- v->vc1dsp.vc1_inv_trans_4x4 = ff_simple_idct44_add;
- v->vc1dsp.vc1_inv_trans_8x8_dc = ff_simple_idct_add;
+ v->res_x8 = get_bits1(gb); //reserved
+ v->multires = get_bits1(gb);
+ v->res_fasttx = get_bits1(gb);
+ if (!v->res_fasttx) {
+ v->vc1dsp.vc1_inv_trans_8x8 = ff_simple_idct_8;
+ v->vc1dsp.vc1_inv_trans_8x4 = ff_simple_idct84_add;
+ v->vc1dsp.vc1_inv_trans_4x8 = ff_simple_idct48_add;
+ v->vc1dsp.vc1_inv_trans_4x4 = ff_simple_idct44_add;
+ v->vc1dsp.vc1_inv_trans_8x8_dc = ff_simple_idct_add_8;
v->vc1dsp.vc1_inv_trans_8x4_dc = ff_simple_idct84_add;
v->vc1dsp.vc1_inv_trans_4x8_dc = ff_simple_idct48_add;
v->vc1dsp.vc1_inv_trans_4x4_dc = ff_simple_idct44_add;
}
- v->fastuvmc = get_bits1(gb); //common
- if (!v->profile && !v->fastuvmc)
- {
+ v->fastuvmc = get_bits1(gb); //common
+ if (!v->profile && !v->fastuvmc) {
av_log(avctx, AV_LOG_ERROR,
"FASTUVMC unavailable in Simple Profile\n");
return -1;
}
- v->extended_mv = get_bits1(gb); //common
+ v->extended_mv = get_bits1(gb); //common
if (!v->profile && v->extended_mv)
{
av_log(avctx, AV_LOG_ERROR,
"Extended MVs unavailable in Simple Profile\n");
return -1;
}
- v->dquant = get_bits(gb, 2); //common
- v->vstransform = get_bits1(gb); //common
+ v->dquant = get_bits(gb, 2); //common
+ v->vstransform = get_bits1(gb); //common
- v->res_transtab = get_bits1(gb);
+ v->res_transtab = get_bits1(gb);
if (v->res_transtab)
{
av_log(avctx, AV_LOG_ERROR,
@@ -372,12 +365,11 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
return -1;
}
- v->overlap = get_bits1(gb); //common
+ v->overlap = get_bits1(gb); //common
v->s.resync_marker = get_bits1(gb);
- v->rangered = get_bits1(gb);
- if (v->rangered && v->profile == PROFILE_SIMPLE)
- {
+ v->rangered = get_bits1(gb);
+ if (v->rangered && v->profile == PROFILE_SIMPLE) {
av_log(avctx, AV_LOG_INFO,
"RANGERED should be set to 0 in Simple Profile\n");
}
@@ -401,8 +393,7 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
} else {
v->res_rtm_flag = get_bits1(gb); //reserved
}
- if (!v->res_rtm_flag)
- {
+ if (!v->res_rtm_flag) {
// av_log(avctx, AV_LOG_ERROR,
// "0 for reserved RES_RTM_FLAG is forbidden\n");
av_log(avctx, AV_LOG_ERROR,
@@ -410,17 +401,17 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
//return -1;
}
//TODO: figure out what they mean (always 0x402F)
- if(!v->res_fasttx) skip_bits(gb, 16);
+ if (!v->res_fasttx)
+ skip_bits(gb, 16);
av_log(avctx, AV_LOG_DEBUG,
- "Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
- "LoopFilter=%i, MultiRes=%i, FastUVMC=%i, Extended MV=%i\n"
- "Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n"
- "DQuant=%i, Quantizer mode=%i, Max B frames=%i\n",
- v->profile, v->frmrtq_postproc, v->bitrtq_postproc,
- v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv,
- v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
- v->dquant, v->quantizer_mode, avctx->max_b_frames
- );
+ "Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
+ "LoopFilter=%i, MultiRes=%i, FastUVMC=%i, Extended MV=%i\n"
+ "Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n"
+ "DQuant=%i, Quantizer mode=%i, Max B frames=%i\n",
+ v->profile, v->frmrtq_postproc, v->bitrtq_postproc,
+ v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv,
+ v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
+ v->dquant, v->quantizer_mode, avctx->max_b_frames);
return 0;
}
@@ -428,98 +419,104 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
{
v->res_rtm_flag = 1;
v->level = get_bits(gb, 3);
- if(v->level >= 5)
- {
+ if (v->level >= 5) {
av_log(v->s.avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level);
}
v->chromaformat = get_bits(gb, 2);
- if (v->chromaformat != 1)
- {
+ if (v->chromaformat != 1) {
av_log(v->s.avctx, AV_LOG_ERROR,
"Only 4:2:0 chroma format supported\n");
return -1;
}
// (fps-2)/4 (->30)
- v->frmrtq_postproc = get_bits(gb, 3); //common
+ v->frmrtq_postproc = get_bits(gb, 3); //common
// (bitrate-32kbps)/64kbps
- v->bitrtq_postproc = get_bits(gb, 5); //common
- v->postprocflag = get_bits1(gb); //common
+ v->bitrtq_postproc = get_bits(gb, 5); //common
+ v->postprocflag = get_bits1(gb); //common
- v->s.avctx->coded_width = (get_bits(gb, 12) + 1) << 1;
+ v->s.avctx->coded_width = (get_bits(gb, 12) + 1) << 1;
v->s.avctx->coded_height = (get_bits(gb, 12) + 1) << 1;
- v->s.avctx->width = v->s.avctx->coded_width;
- v->s.avctx->height = v->s.avctx->coded_height;
- v->broadcast = get_bits1(gb);
- v->interlace = get_bits1(gb);
- v->tfcntrflag = get_bits1(gb);
- v->finterpflag = get_bits1(gb);
+ v->s.avctx->width = v->s.avctx->coded_width;
+ v->s.avctx->height = v->s.avctx->coded_height;
+ v->broadcast = get_bits1(gb);
+ v->interlace = get_bits1(gb);
+ v->tfcntrflag = get_bits1(gb);
+ v->finterpflag = get_bits1(gb);
skip_bits1(gb); // reserved
- v->s.h_edge_pos = v->s.avctx->coded_width;
- v->s.v_edge_pos = v->s.avctx->coded_height;
-
av_log(v->s.avctx, AV_LOG_DEBUG,
- "Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
- "LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n"
- "TFCTRflag=%i, FINTERPflag=%i\n",
- v->level, v->frmrtq_postproc, v->bitrtq_postproc,
- v->s.loop_filter, v->chromaformat, v->broadcast, v->interlace,
- v->tfcntrflag, v->finterpflag
- );
+ "Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
+ "LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n"
+ "TFCTRflag=%i, FINTERPflag=%i\n",
+ v->level, v->frmrtq_postproc, v->bitrtq_postproc,
+ v->s.loop_filter, v->chromaformat, v->broadcast, v->interlace,
+ v->tfcntrflag, v->finterpflag);
v->psf = get_bits1(gb);
- if(v->psf) { //PsF, 6.1.13
+ if (v->psf) { //PsF, 6.1.13
av_log(v->s.avctx, AV_LOG_ERROR, "Progressive Segmented Frame mode: not supported (yet)\n");
return -1;
}
v->s.max_b_frames = v->s.avctx->max_b_frames = 7;
- if(get_bits1(gb)) { //Display Info - decoding is not affected by it
+ if (get_bits1(gb)) { //Display Info - decoding is not affected by it
int w, h, ar = 0;
av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n");
- v->s.avctx->width = w = get_bits(gb, 14) + 1;
- v->s.avctx->height = h = get_bits(gb, 14) + 1;
+ w = get_bits(gb, 14) + 1;
+ h = get_bits(gb, 14) + 1;
av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h);
- if(get_bits1(gb))
+ if (get_bits1(gb))
ar = get_bits(gb, 4);
- if(ar && ar < 14){
+ if (ar && ar < 14) {
v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar];
- }else if(ar == 15){
+ } else if (ar == 15) {
w = get_bits(gb, 8) + 1;
h = get_bits(gb, 8) + 1;
v->s.avctx->sample_aspect_ratio = (AVRational){w, h};
+ } else {
+ av_reduce(&v->s.avctx->sample_aspect_ratio.num,
+ &v->s.avctx->sample_aspect_ratio.den,
+ v->s.avctx->height * w,
+ v->s.avctx->width * h,
+ 1 << 30);
}
- av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", v->s.avctx->sample_aspect_ratio.num, v->s.avctx->sample_aspect_ratio.den);
+ av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n",
+ v->s.avctx->sample_aspect_ratio.num,
+ v->s.avctx->sample_aspect_ratio.den);
- if(get_bits1(gb)){ //framerate stuff
- if(get_bits1(gb)) {
+ if (get_bits1(gb)) { //framerate stuff
+ if (get_bits1(gb)) {
v->s.avctx->time_base.num = 32;
v->s.avctx->time_base.den = get_bits(gb, 16) + 1;
} else {
int nr, dr;
nr = get_bits(gb, 8);
dr = get_bits(gb, 4);
- if(nr && nr < 8 && dr && dr < 3){
+ if (nr && nr < 8 && dr && dr < 3) {
v->s.avctx->time_base.num = ff_vc1_fps_dr[dr - 1];
v->s.avctx->time_base.den = ff_vc1_fps_nr[nr - 1] * 1000;
}
}
+ if (v->broadcast) { // Pulldown may be present
+ v->s.avctx->time_base.den *= 2;
+ v->s.avctx->ticks_per_frame = 2;
+ }
}
- if(get_bits1(gb)){
- v->color_prim = get_bits(gb, 8);
+ if (get_bits1(gb)) {
+ v->color_prim = get_bits(gb, 8);
v->transfer_char = get_bits(gb, 8);
- v->matrix_coef = get_bits(gb, 8);
+ v->matrix_coef = get_bits(gb, 8);
}
}
v->hrd_param_flag = get_bits1(gb);
- if(v->hrd_param_flag) {
+ if (v->hrd_param_flag) {
int i;
v->hrd_num_leaky_buckets = get_bits(gb, 5);
skip_bits(gb, 4); //bitrate exponent
skip_bits(gb, 4); //buffer size exponent
- for(i = 0; i < v->hrd_num_leaky_buckets; i++) {
+ for (i = 0; i < v->hrd_num_leaky_buckets; i++) {
skip_bits(gb, 16); //hrd_rate[n]
skip_bits(gb, 16); //hrd_buffer[n]
}
@@ -532,45 +529,45 @@ int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext *
int i;
av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32));
- v->broken_link = get_bits1(gb);
- v->closed_entry = get_bits1(gb);
- v->panscanflag = get_bits1(gb);
- v->refdist_flag = get_bits1(gb);
- v->s.loop_filter = get_bits1(gb);
- v->fastuvmc = get_bits1(gb);
- v->extended_mv = get_bits1(gb);
- v->dquant = get_bits(gb, 2);
- v->vstransform = get_bits1(gb);
- v->overlap = get_bits1(gb);
+ v->broken_link = get_bits1(gb);
+ v->closed_entry = get_bits1(gb);
+ v->panscanflag = get_bits1(gb);
+ v->refdist_flag = get_bits1(gb);
+ v->s.loop_filter = get_bits1(gb);
+ v->fastuvmc = get_bits1(gb);
+ v->extended_mv = get_bits1(gb);
+ v->dquant = get_bits(gb, 2);
+ v->vstransform = get_bits1(gb);
+ v->overlap = get_bits1(gb);
v->quantizer_mode = get_bits(gb, 2);
- if(v->hrd_param_flag){
- for(i = 0; i < v->hrd_num_leaky_buckets; i++) {
+ if (v->hrd_param_flag) {
+ for (i = 0; i < v->hrd_num_leaky_buckets; i++) {
skip_bits(gb, 8); //hrd_full[n]
}
}
- if(get_bits1(gb)){
- avctx->coded_width = (get_bits(gb, 12)+1)<<1;
- avctx->coded_height = (get_bits(gb, 12)+1)<<1;
+ if (get_bits1(gb)) {
+ avctx->width = avctx->coded_width = (get_bits(gb, 12) + 1) << 1;
+ avctx->height = avctx->coded_height = (get_bits(gb, 12) + 1) << 1;
}
- if(v->extended_mv)
+ if (v->extended_mv)
v->extended_dmv = get_bits1(gb);
- if((v->range_mapy_flag = get_bits1(gb))) {
+ if ((v->range_mapy_flag = get_bits1(gb))) {
av_log(avctx, AV_LOG_ERROR, "Luma scaling is not supported, expect wrong picture\n");
v->range_mapy = get_bits(gb, 3);
}
- if((v->range_mapuv_flag = get_bits1(gb))) {
+ if ((v->range_mapuv_flag = get_bits1(gb))) {
av_log(avctx, AV_LOG_ERROR, "Chroma scaling is not supported, expect wrong picture\n");
v->range_mapuv = get_bits(gb, 3);
}
av_log(avctx, AV_LOG_DEBUG, "Entry point info:\n"
- "BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n"
- "RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n"
- "DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n",
- v->broken_link, v->closed_entry, v->panscanflag, v->refdist_flag, v->s.loop_filter,
- v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode);
+ "BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n"
+ "RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n"
+ "DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n",
+ v->broken_link, v->closed_entry, v->panscanflag, v->refdist_flag, v->s.loop_filter,
+ v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode);
return 0;
}
@@ -579,41 +576,48 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
{
int pqindex, lowquant, status;
- if(v->finterpflag) v->interpfrm = get_bits1(gb);
+ if (v->finterpflag)
+ v->interpfrm = get_bits1(gb);
skip_bits(gb, 2); //framecnt unused
v->rangeredfrm = 0;
- if (v->rangered) v->rangeredfrm = get_bits1(gb);
+ if (v->rangered)
+ v->rangeredfrm = get_bits1(gb);
v->s.pict_type = get_bits1(gb);
if (v->s.avctx->max_b_frames) {
if (!v->s.pict_type) {
- if (get_bits1(gb)) v->s.pict_type = AV_PICTURE_TYPE_I;
- else v->s.pict_type = AV_PICTURE_TYPE_B;
- } else v->s.pict_type = AV_PICTURE_TYPE_P;
- } else v->s.pict_type = v->s.pict_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
+ if (get_bits1(gb))
+ v->s.pict_type = AV_PICTURE_TYPE_I;
+ else
+ v->s.pict_type = AV_PICTURE_TYPE_B;
+ } else
+ v->s.pict_type = AV_PICTURE_TYPE_P;
+ } else
+ v->s.pict_type = v->s.pict_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
v->bi_type = 0;
- if(v->s.pict_type == AV_PICTURE_TYPE_B) {
+ if (v->s.pict_type == AV_PICTURE_TYPE_B) {
v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
- v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
- if(v->bfraction == 0) {
+ v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
+ if (v->bfraction == 0) {
v->s.pict_type = AV_PICTURE_TYPE_BI;
}
}
- if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
+ if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
skip_bits(gb, 7); // skip buffer fullness
- if(v->parse_only)
+ if (v->parse_only)
return 0;
/* calculate RND */
- if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
+ if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
v->rnd = 1;
- if(v->s.pict_type == AV_PICTURE_TYPE_P)
+ if (v->s.pict_type == AV_PICTURE_TYPE_P)
v->rnd ^= 1;
/* Quantizer stuff */
pqindex = get_bits(gb, 5);
- if(!pqindex) return -1;
+ if (!pqindex)
+ return -1;
if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
v->pq = ff_vc1_pquant_table[0][pqindex];
else
@@ -625,63 +629,69 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
if (v->quantizer_mode == QUANT_NON_UNIFORM)
v->pquantizer = 0;
v->pqindex = pqindex;
- if (pqindex < 9) v->halfpq = get_bits1(gb);
- else v->halfpq = 0;
+ if (pqindex < 9)
+ v->halfpq = get_bits1(gb);
+ else
+ v->halfpq = 0;
if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
v->pquantizer = get_bits1(gb);
v->dquantfrm = 0;
- if (v->extended_mv == 1) v->mvrange = get_unary(gb, 0, 3);
+ if (v->extended_mv == 1)
+ v->mvrange = get_unary(gb, 0, 3);
v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
v->range_x = 1 << (v->k_x - 1);
v->range_y = 1 << (v->k_y - 1);
- if (v->multires && v->s.pict_type != AV_PICTURE_TYPE_B) v->respic = get_bits(gb, 2);
+ if (v->multires && v->s.pict_type != AV_PICTURE_TYPE_B)
+ v->respic = get_bits(gb, 2);
- if(v->res_x8 && (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)){
+ if (v->res_x8 && (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)) {
v->x8_type = get_bits1(gb);
- }else v->x8_type = 0;
+ } else
+ v->x8_type = 0;
//av_log(v->s.avctx, AV_LOG_INFO, "%c Frame: QP=[%i]%i (+%i/2) %i\n",
// (v->s.pict_type == AV_PICTURE_TYPE_P) ? 'P' : ((v->s.pict_type == AV_PICTURE_TYPE_I) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm);
- if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) v->use_ic = 0;
+ if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P)
+ v->use_ic = 0;
- switch(v->s.pict_type) {
+ switch (v->s.pict_type) {
case AV_PICTURE_TYPE_P:
- if (v->pq < 5) v->tt_index = 0;
- else if(v->pq < 13) v->tt_index = 1;
- else v->tt_index = 2;
+ if (v->pq < 5) v->tt_index = 0;
+ else if (v->pq < 13) v->tt_index = 1;
+ else v->tt_index = 2;
lowquant = (v->pq > 12) ? 0 : 1;
v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)];
- if (v->mv_mode == MV_PMODE_INTENSITY_COMP)
- {
+ if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
int scale, shift, i;
v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)];
v->lumscale = get_bits(gb, 6);
v->lumshift = get_bits(gb, 6);
- v->use_ic = 1;
+ v->use_ic = 1;
/* fill lookup tables for intensity compensation */
- if(!v->lumscale) {
+ if (!v->lumscale) {
scale = -64;
shift = (255 - v->lumshift * 2) << 6;
- if(v->lumshift > 31)
+ if (v->lumshift > 31)
shift += 128 << 6;
} else {
scale = v->lumscale + 32;
- if(v->lumshift > 31)
+ if (v->lumshift > 31)
shift = (v->lumshift - 64) << 6;
else
shift = v->lumshift << 6;
}
- for(i = 0; i < 256; i++) {
- v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6);
+ for (i = 0; i < 256; i++) {
+ v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6);
v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
}
}
- if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
+ v->qs_last = v->s.quarter_sample;
+ if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
- else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
- if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)
+ else if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ if (v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
else
v->s.quarter_sample = 1;
@@ -689,12 +699,12 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
v->s.quarter_sample = 1;
v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN));
- if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
- v->mv_mode2 == MV_PMODE_MIXED_MV)
- || v->mv_mode == MV_PMODE_MIXED_MV)
- {
+ if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
+ v->mv_mode2 == MV_PMODE_MIXED_MV) ||
+ v->mv_mode == MV_PMODE_MIXED_MV) {
status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
- if (status < 0) return -1;
+ if (status < 0)
+ return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
} else {
@@ -702,7 +712,8 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
}
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
- if (status < 0) return -1;
+ if (status < 0)
+ return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
@@ -710,18 +721,15 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables
v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
- if (v->dquant)
- {
+ if (v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
vop_dquant_decoding(v);
}
v->ttfrm = 0; //FIXME Is that so ?
- if (v->vstransform)
- {
+ if (v->vstransform) {
v->ttmbf = get_bits1(gb);
- if (v->ttmbf)
- {
+ if (v->ttmbf) {
v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
}
} else {
@@ -730,38 +738,38 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
}
break;
case AV_PICTURE_TYPE_B:
- if (v->pq < 5) v->tt_index = 0;
- else if(v->pq < 13) v->tt_index = 1;
- else v->tt_index = 2;
+ if (v->pq < 5) v->tt_index = 0;
+ else if (v->pq < 13) v->tt_index = 1;
+ else v->tt_index = 2;
- v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
+ v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
+ v->qs_last = v->s.quarter_sample;
v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
- v->s.mspel = v->s.quarter_sample;
+ v->s.mspel = v->s.quarter_sample;
status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
- if (status < 0) return -1;
+ if (status < 0)
+ return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
- if (status < 0) return -1;
+ if (status < 0)
+ return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
v->s.mv_table_index = get_bits(gb, 2);
- v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
+ v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
- if (v->dquant)
- {
+ if (v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
vop_dquant_decoding(v);
}
v->ttfrm = 0;
- if (v->vstransform)
- {
+ if (v->vstransform) {
v->ttmbf = get_bits1(gb);
- if (v->ttmbf)
- {
+ if (v->ttmbf) {
v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
}
} else {
@@ -771,85 +779,154 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
break;
}
- if(!v->x8_type)
- {
+ if (!v->x8_type) {
/* AC Syntax */
v->c_ac_table_index = decode012(gb);
- if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
- {
+ if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) {
v->y_ac_table_index = decode012(gb);
}
/* DC Syntax */
v->s.dc_table_index = get_bits1(gb);
}
- if(v->s.pict_type == AV_PICTURE_TYPE_BI) {
+ if (v->s.pict_type == AV_PICTURE_TYPE_BI) {
v->s.pict_type = AV_PICTURE_TYPE_B;
- v->bi_type = 1;
+ v->bi_type = 1;
}
return 0;
}
+/* fill lookup tables for intensity compensation */
+#define INIT_LUT(lumscale, lumshift, luty, lutuv) \
+ if (!lumscale) { \
+ scale = -64; \
+ shift = (255 - lumshift * 2) << 6; \
+ if (lumshift > 31) \
+ shift += 128 << 6; \
+ } else { \
+ scale = lumscale + 32; \
+ if (lumshift > 31) \
+ shift = (lumshift - 64) << 6; \
+ else \
+ shift = lumshift << 6; \
+ } \
+ for (i = 0; i < 256; i++) { \
+ luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); \
+ lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); \
+ }
+
int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
{
int pqindex, lowquant;
int status;
+ int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */
+ int scale, shift, i; /* for initializing LUT for intensity compensation */
v->p_frame_skipped = 0;
+ if (v->second_field) {
+ v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
+ if (v->fptype & 4)
+ v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
+ v->s.current_picture_ptr->f.pict_type = v->s.pict_type;
+ if (!v->pic_header_flag)
+ goto parse_common_info;
+ }
- if(v->interlace){
+ v->field_mode = 0;
+ if (v->interlace) {
v->fcm = decode012(gb);
- if(v->fcm){
- if(!v->warn_interlaced++)
- av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced frames/fields support is not implemented\n");
- return -1;
+ if (v->fcm) {
+ if (v->fcm == ILACE_FIELD)
+ v->field_mode = 1;
+ if (!v->warn_interlaced++)
+ av_log(v->s.avctx, AV_LOG_ERROR,
+ "Interlaced frames/fields support is incomplete\n");
}
+ } else {
+ v->fcm = PROGRESSIVE;
}
- switch(get_unary(gb, 0, 4)) {
- case 0:
- v->s.pict_type = AV_PICTURE_TYPE_P;
- break;
- case 1:
- v->s.pict_type = AV_PICTURE_TYPE_B;
- break;
- case 2:
- v->s.pict_type = AV_PICTURE_TYPE_I;
- break;
- case 3:
- v->s.pict_type = AV_PICTURE_TYPE_BI;
- break;
- case 4:
- v->s.pict_type = AV_PICTURE_TYPE_P; // skipped pic
- v->p_frame_skipped = 1;
- return 0;
+
+ if (v->field_mode) {
+ v->fptype = get_bits(gb, 3);
+ v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
+ if (v->fptype & 4) // B-picture
+ v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
+ } else {
+ switch (get_unary(gb, 0, 4)) {
+ case 0:
+ v->s.pict_type = AV_PICTURE_TYPE_P;
+ break;
+ case 1:
+ v->s.pict_type = AV_PICTURE_TYPE_B;
+ break;
+ case 2:
+ v->s.pict_type = AV_PICTURE_TYPE_I;
+ break;
+ case 3:
+ v->s.pict_type = AV_PICTURE_TYPE_BI;
+ break;
+ case 4:
+ v->s.pict_type = AV_PICTURE_TYPE_P; // skipped pic
+ v->p_frame_skipped = 1;
+ break;
+ }
}
- if(v->tfcntrflag)
+ if (v->tfcntrflag)
skip_bits(gb, 8);
- if(v->broadcast) {
- if(!v->interlace || v->psf) {
+ if (v->broadcast) {
+ if (!v->interlace || v->psf) {
v->rptfrm = get_bits(gb, 2);
} else {
v->tff = get_bits1(gb);
- v->rptfrm = get_bits1(gb);
+ v->rff = get_bits1(gb);
}
}
- if(v->panscanflag) {
+ if (v->panscanflag) {
av_log_missing_feature(v->s.avctx, "Pan-scan", 0);
//...
}
+ if (v->p_frame_skipped) {
+ return 0;
+ }
v->rnd = get_bits1(gb);
- if(v->interlace)
+ if (v->interlace)
v->uvsamp = get_bits1(gb);
- if(v->finterpflag) v->interpfrm = get_bits1(gb);
- if(v->s.pict_type == AV_PICTURE_TYPE_B) {
+ if (v->field_mode) {
+ if (!v->refdist_flag)
+ v->refdist = 0;
+ else {
+ if ((v->s.pict_type != AV_PICTURE_TYPE_B)
+ && (v->s.pict_type != AV_PICTURE_TYPE_BI)) {
+ v->refdist = get_bits(gb, 2);
+ if (v->refdist == 3)
+ v->refdist += get_unary(gb, 0, 16);
+ } else {
+ v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
+ v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
+ v->frfd = (v->bfraction * v->refdist) >> 8;
+ v->brfd = v->refdist - v->frfd - 1;
+ if (v->brfd < 0)
+ v->brfd = 0;
+ }
+ }
+ goto parse_common_info;
+ }
+ if (v->finterpflag)
+ v->interpfrm = get_bits1(gb);
+ if (v->s.pict_type == AV_PICTURE_TYPE_B) {
v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
- v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
- if(v->bfraction == 0) {
+ v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
+ if (v->bfraction == 0) {
v->s.pict_type = AV_PICTURE_TYPE_BI; /* XXX: should not happen here */
}
}
+
+ parse_common_info:
+ if (v->field_mode)
+ v->cur_field_type = !(v->tff ^ v->second_field);
pqindex = get_bits(gb, 5);
- if(!pqindex) return -1;
+ if (!pqindex)
+ return -1;
v->pqindex = pqindex;
if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
v->pq = ff_vc1_pquant_table[0][pqindex];
@@ -862,118 +939,193 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
if (v->quantizer_mode == QUANT_NON_UNIFORM)
v->pquantizer = 0;
v->pqindex = pqindex;
- if (pqindex < 9) v->halfpq = get_bits1(gb);
- else v->halfpq = 0;
+ if (pqindex < 9)
+ v->halfpq = get_bits1(gb);
+ else
+ v->halfpq = 0;
if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
v->pquantizer = get_bits1(gb);
- if(v->postprocflag)
+ if (v->postprocflag)
v->postproc = get_bits(gb, 2);
- if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) v->use_ic = 0;
+ if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P)
+ v->use_ic = 0;
- if(v->parse_only)
+ if (v->parse_only)
return 0;
- switch(v->s.pict_type) {
+ switch (v->s.pict_type) {
case AV_PICTURE_TYPE_I:
case AV_PICTURE_TYPE_BI:
+ if (v->fcm == ILACE_FRAME) { //interlace frame picture
+ status = bitplane_decoding(v->fieldtx_plane, &v->fieldtx_is_raw, v);
+ if (status < 0)
+ return -1;
+ av_log(v->s.avctx, AV_LOG_DEBUG, "FIELDTX plane encoding: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
+ }
status = bitplane_decoding(v->acpred_plane, &v->acpred_is_raw, v);
- if (status < 0) return -1;
+ if (status < 0)
+ return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "ACPRED plane encoding: "
- "Imode: %i, Invert: %i\n", status>>1, status&1);
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
v->condover = CONDOVER_NONE;
- if(v->overlap && v->pq <= 8) {
+ if (v->overlap && v->pq <= 8) {
v->condover = decode012(gb);
- if(v->condover == CONDOVER_SELECT) {
+ if (v->condover == CONDOVER_SELECT) {
status = bitplane_decoding(v->over_flags_plane, &v->overflg_is_raw, v);
- if (status < 0) return -1;
+ if (status < 0)
+ return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "CONDOVER plane encoding: "
- "Imode: %i, Invert: %i\n", status>>1, status&1);
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
}
}
break;
case AV_PICTURE_TYPE_P:
- if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3);
- else v->mvrange = 0;
+ if (v->field_mode) {
+ v->numref = get_bits1(gb);
+ if (!v->numref) {
+ v->reffield = get_bits1(gb);
+ v->ref_field_type[0] = v->reffield ^ !v->cur_field_type;
+ }
+ }
+ if (v->extended_mv)
+ v->mvrange = get_unary(gb, 0, 3);
+ else
+ v->mvrange = 0;
+ if (v->interlace) {
+ if (v->extended_dmv)
+ v->dmvrange = get_unary(gb, 0, 3);
+ else
+ v->dmvrange = 0;
+ if (v->fcm == ILACE_FRAME) { // interlaced frame picture
+ v->fourmvswitch = get_bits1(gb);
+ v->intcomp = get_bits1(gb);
+ if (v->intcomp) {
+ v->lumscale = get_bits(gb, 6);
+ v->lumshift = get_bits(gb, 6);
+ INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv);
+ }
+ status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
+ av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
+ mbmodetab = get_bits(gb, 2);
+ if (v->fourmvswitch)
+ v->mbmode_vlc = &ff_vc1_intfr_4mv_mbmode_vlc[mbmodetab];
+ else
+ v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab];
+ imvtab = get_bits(gb, 2);
+ v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab];
+ // interlaced p-picture cbpcy range is [1, 63]
+ icbptab = get_bits(gb, 3);
+ v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];
+ twomvbptab = get_bits(gb, 2);
+ v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[twomvbptab];
+ if (v->fourmvswitch) {
+ fourmvbptab = get_bits(gb, 2);
+ v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
+ }
+ }
+ }
v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
v->range_x = 1 << (v->k_x - 1);
v->range_y = 1 << (v->k_y - 1);
- if (v->pq < 5) v->tt_index = 0;
- else if(v->pq < 13) v->tt_index = 1;
- else v->tt_index = 2;
-
- lowquant = (v->pq > 12) ? 0 : 1;
- v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)];
- if (v->mv_mode == MV_PMODE_INTENSITY_COMP)
- {
- int scale, shift, i;
- v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)];
- v->lumscale = get_bits(gb, 6);
- v->lumshift = get_bits(gb, 6);
- /* fill lookup tables for intensity compensation */
- if(!v->lumscale) {
- scale = -64;
- shift = (255 - v->lumshift * 2) << 6;
- if(v->lumshift > 31)
- shift += 128 << 6;
- } else {
- scale = v->lumscale + 32;
- if(v->lumshift > 31)
- shift = (v->lumshift - 64) << 6;
- else
- shift = v->lumshift << 6;
- }
- for(i = 0; i < 256; i++) {
- v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6);
- v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
+ if (v->pq < 5)
+ v->tt_index = 0;
+ else if (v->pq < 13)
+ v->tt_index = 1;
+ else
+ v->tt_index = 2;
+ if (v->fcm != ILACE_FRAME) {
+ int mvmode;
+ mvmode = get_unary(gb, 1, 4);
+ lowquant = (v->pq > 12) ? 0 : 1;
+ v->mv_mode = ff_vc1_mv_pmode_table[lowquant][mvmode];
+ if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ int mvmode2;
+ mvmode2 = get_unary(gb, 1, 3);
+ v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][mvmode2];
+ if (v->field_mode)
+ v->intcompfield = decode210(gb);
+ v->lumscale = get_bits(gb, 6);
+ v->lumshift = get_bits(gb, 6);
+ INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv);
+ if ((v->field_mode) && !v->intcompfield) {
+ v->lumscale2 = get_bits(gb, 6);
+ v->lumshift2 = get_bits(gb, 6);
+ INIT_LUT(v->lumscale2, v->lumshift2, v->luty2, v->lutuv2);
+ }
+ v->use_ic = 1;
}
- v->use_ic = 1;
- }
- if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
- v->s.quarter_sample = 0;
- else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
- if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)
+ v->qs_last = v->s.quarter_sample;
+ if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
- else
+ else if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ if (v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)
+ v->s.quarter_sample = 0;
+ else
+ v->s.quarter_sample = 1;
+ } else
v->s.quarter_sample = 1;
- } else
- v->s.quarter_sample = 1;
- v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN));
-
- if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
+ v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN
+ || (v->mv_mode == MV_PMODE_INTENSITY_COMP
+ && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN));
+ }
+ if (v->fcm == PROGRESSIVE) { // progressive
+ if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
v->mv_mode2 == MV_PMODE_MIXED_MV)
- || v->mv_mode == MV_PMODE_MIXED_MV)
- {
- status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
- if (status < 0) return -1;
- av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
+ || v->mv_mode == MV_PMODE_MIXED_MV) {
+ status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
+ if (status < 0)
+ return -1;
+ av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
+ } else {
+ v->mv_type_is_raw = 0;
+ memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
+ }
+ status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
+ if (status < 0)
+ return -1;
+ av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
- } else {
- v->mv_type_is_raw = 0;
- memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
- }
- status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
- if (status < 0) return -1;
- av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
- "Imode: %i, Invert: %i\n", status>>1, status&1);
- /* Hopefully this is correct for P frames */
- v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables
- v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
- if (v->dquant)
- {
+ /* Hopefully this is correct for P frames */
+ v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables
+ v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
+ } else if (v->fcm == ILACE_FRAME) { // frame interlaced
+ v->qs_last = v->s.quarter_sample;
+ v->s.quarter_sample = 1;
+ v->s.mspel = 1;
+ } else { // field interlaced
+ mbmodetab = get_bits(gb, 3);
+ imvtab = get_bits(gb, 2 + v->numref);
+ if (!v->numref)
+ v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab];
+ else
+ v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab];
+ icbptab = get_bits(gb, 3);
+ v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];
+ if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
+ v->mv_mode2 == MV_PMODE_MIXED_MV) || v->mv_mode == MV_PMODE_MIXED_MV) {
+ fourmvbptab = get_bits(gb, 2);
+ v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
+ v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab];
+ } else {
+ v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab];
+ }
+ }
+ if (v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
vop_dquant_decoding(v);
}
v->ttfrm = 0; //FIXME Is that so ?
- if (v->vstransform)
- {
+ if (v->vstransform) {
v->ttmbf = get_bits1(gb);
- if (v->ttmbf)
- {
+ if (v->ttmbf) {
v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
}
} else {
@@ -982,45 +1134,82 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
}
break;
case AV_PICTURE_TYPE_B:
- if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3);
- else v->mvrange = 0;
- v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
- v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
+ // TODO: implement interlaced frame B picture decoding
+ if (v->fcm == ILACE_FRAME)
+ return -1;
+ if (v->extended_mv)
+ v->mvrange = get_unary(gb, 0, 3);
+ else
+ v->mvrange = 0;
+ v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
+ v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
v->range_x = 1 << (v->k_x - 1);
v->range_y = 1 << (v->k_y - 1);
- if (v->pq < 5) v->tt_index = 0;
- else if(v->pq < 13) v->tt_index = 1;
- else v->tt_index = 2;
-
- v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
- v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
- v->s.mspel = v->s.quarter_sample;
-
- status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
- if (status < 0) return -1;
- av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "
- "Imode: %i, Invert: %i\n", status>>1, status&1);
- status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
- if (status < 0) return -1;
- av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
- "Imode: %i, Invert: %i\n", status>>1, status&1);
-
- v->s.mv_table_index = get_bits(gb, 2);
- v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
+ if (v->pq < 5)
+ v->tt_index = 0;
+ else if (v->pq < 13)
+ v->tt_index = 1;
+ else
+ v->tt_index = 2;
+
+ if (v->field_mode) {
+ int mvmode;
+ if (v->extended_dmv)
+ v->dmvrange = get_unary(gb, 0, 3);
+ mvmode = get_unary(gb, 1, 3);
+ lowquant = (v->pq > 12) ? 0 : 1;
+ v->mv_mode = ff_vc1_mv_pmode_table2[lowquant][mvmode];
+ v->qs_last = v->s.quarter_sample;
+ v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV || v->mv_mode == MV_PMODE_MIXED_MV);
+ v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || v->mv_mode == MV_PMODE_1MV_HPEL);
+ status = bitplane_decoding(v->forward_mb_plane, &v->fmb_is_raw, v);
+ if (status < 0)
+ return -1;
+ av_log(v->s.avctx, AV_LOG_DEBUG, "MB Forward Type plane encoding: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
+ mbmodetab = get_bits(gb, 3);
+ if (v->mv_mode == MV_PMODE_MIXED_MV)
+ v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab];
+ else
+ v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab];
+ imvtab = get_bits(gb, 3);
+ v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab];
+ icbptab = get_bits(gb, 3);
+ v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];
+ if (v->mv_mode == MV_PMODE_MIXED_MV) {
+ fourmvbptab = get_bits(gb, 2);
+ v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
+ }
+ v->numref = 1; // interlaced field B pictures are always 2-ref
+ } else {
+ v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
+ v->qs_last = v->s.quarter_sample;
+ v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
+ v->s.mspel = v->s.quarter_sample;
+ status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
+ if (status < 0)
+ return -1;
+ av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
+ status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
+ if (status < 0)
+ return -1;
+ av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
+ "Imode: %i, Invert: %i\n", status>>1, status&1);
+ v->s.mv_table_index = get_bits(gb, 2);
+ v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
+ }
- if (v->dquant)
- {
+ if (v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
vop_dquant_decoding(v);
}
v->ttfrm = 0;
- if (v->vstransform)
- {
+ if (v->vstransform) {
v->ttmbf = get_bits1(gb);
- if (v->ttmbf)
- {
+ if (v->ttmbf) {
v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
}
} else {
@@ -1032,19 +1221,19 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
/* AC Syntax */
v->c_ac_table_index = decode012(gb);
- if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
- {
+ if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) {
v->y_ac_table_index = decode012(gb);
}
/* DC Syntax */
v->s.dc_table_index = get_bits1(gb);
- if ((v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) && v->dquant) {
+ if ((v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
+ && v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
vop_dquant_decoding(v);
}
v->bi_type = 0;
- if(v->s.pict_type == AV_PICTURE_TYPE_BI) {
+ if (v->s.pict_type == AV_PICTURE_TYPE_BI) {
v->s.pict_type = AV_PICTURE_TYPE_B;
v->bi_type = 1;
}
diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index 96e5744..6096077 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -30,7 +30,7 @@
/** Markers used in VC-1 AP frame data */
//@{
-enum VC1Code{
+enum VC1Code {
VC1_CODE_RES0 = 0x00000100,
VC1_CODE_ENDOFSEQ = 0x0000010A,
VC1_CODE_SLICE,
@@ -105,12 +105,25 @@ enum MVModes {
};
//@}
+/** MBMODE for interlaced frame P-picture */
+//@{
+enum MBModesIntfr {
+ MV_PMODE_INTFR_1MV,
+ MV_PMODE_INTFR_2MV_FIELD,
+ MV_PMODE_INTFR_2MV,
+ MV_PMODE_INTFR_4MV_FIELD,
+ MV_PMODE_INTFR_4MV,
+ MV_PMODE_INTFR_INTRA,
+};
+//@}
+
/** @name MV types for B frames */
//@{
enum BMVTypes {
BMV_TYPE_BACKWARD,
BMV_TYPE_FORWARD,
- BMV_TYPE_INTERPOLATED
+ BMV_TYPE_INTERPOLATED,
+ BMV_TYPE_DIRECT
};
//@}
@@ -120,10 +133,10 @@ enum TransformTypes {
TT_8X8,
TT_8X4_BOTTOM,
TT_8X4_TOP,
- TT_8X4, //Both halves
+ TT_8X4, // both halves
TT_4X8_RIGHT,
TT_4X8_LEFT,
- TT_4X8, //Both halves
+ TT_4X8, // both halves
TT_4X4
};
//@}
@@ -148,6 +161,16 @@ enum COTypes {
};
//@}
+/**
+ * FCM Frame Coding Mode
+ * @note some content might be marked interlaced
+ * but have fcm set to 0 as well (e.g. HD-DVD)
+ */
+enum FrameCodingMode {
+ PROGRESSIVE = 0, ///< in the bitstream is reported as 00b
+ ILACE_FRAME, ///< in the bitstream is reported as 10b
+ ILACE_FIELD ///< in the bitstream is reported as 11b
+};
/** The VC1 Context
* @todo Change size wherever another size is more efficient
@@ -211,16 +234,16 @@ typedef struct VC1Context{
/** Frame decoding info for all profiles */
//@{
- uint8_t mv_mode; ///< MV coding monde
- uint8_t mv_mode2; ///< Secondary MV coding mode (B frames)
- int k_x; ///< Number of bits for MVs (depends on MV range)
- int k_y; ///< Number of bits for MVs (depends on MV range)
- int range_x, range_y; ///< MV range
- uint8_t pq, altpq; ///< Current/alternate frame quantizer scale
- uint8_t zz_8x8[4][64];///< Zigzag table for TT_8x8, permuted for IDCT
+ uint8_t mv_mode; ///< MV coding monde
+ uint8_t mv_mode2; ///< Secondary MV coding mode (B frames)
+ int k_x; ///< Number of bits for MVs (depends on MV range)
+ int k_y; ///< Number of bits for MVs (depends on MV range)
+ int range_x, range_y; ///< MV range
+ uint8_t pq, altpq; ///< Current/alternate frame quantizer scale
+ uint8_t zz_8x8[4][64]; ///< Zigzag table for TT_8x8, permuted for IDCT
int left_blk_sh, top_blk_sh; ///< Either 3 or 0, positions of l/t in blk[]
- const uint8_t* zz_8x4;///< Zigzag scan table for TT_8x4 coding mode
- const uint8_t* zz_4x8;///< Zigzag scan table for TT_4x8 coding mode
+ const uint8_t* zz_8x4; ///< Zigzag scan table for TT_8x4 coding mode
+ const uint8_t* zz_4x8; ///< Zigzag scan table for TT_4x8 coding mode
/** pquant parameters */
//@{
uint8_t dquantfrm;
@@ -232,15 +255,15 @@ typedef struct VC1Context{
* @see 8.1.1.10, p(1)10
*/
//@{
- int c_ac_table_index; ///< Chroma index from ACFRM element
- int y_ac_table_index; ///< Luma index from AC2FRM element
+ int c_ac_table_index; ///< Chroma index from ACFRM element
+ int y_ac_table_index; ///< Luma index from AC2FRM element
//@}
- int ttfrm; ///< Transform type info present at frame level
- uint8_t ttmbf; ///< Transform type flag
+ int ttfrm; ///< Transform type info present at frame level
+ uint8_t ttmbf; ///< Transform type flag
int *ttblk_base, *ttblk; ///< Transform type at the block level
- int codingset; ///< index of current table set from 11.8 to use for luma block decoding
- int codingset2; ///< index of current table set from 11.8 to use for chroma block decoding
- int pqindex; ///< raw pqindex used in coding set selection
+ int codingset; ///< index of current table set from 11.8 to use for luma block decoding
+ int codingset2; ///< index of current table set from 11.8 to use for chroma block decoding
+ int pqindex; ///< raw pqindex used in coding set selection
int a_avail, c_avail;
uint8_t *mb_type_base, *mb_type[3];
@@ -260,28 +283,30 @@ typedef struct VC1Context{
* -# 2 -> [-512, 511.f] x [-128, 127.f]
* -# 3 -> [-1024, 1023.f] x [-256, 255.f]
*/
- uint8_t mvrange;
- uint8_t pquantizer; ///< Uniform (over sequence) quantizer in use
- VLC *cbpcy_vlc; ///< CBPCY VLC table
- int tt_index; ///< Index for Transform Type tables
- uint8_t* mv_type_mb_plane; ///< bitplane for mv_type == (4MV)
- uint8_t* direct_mb_plane; ///< bitplane for "direct" MBs
- int mv_type_is_raw; ///< mv type mb plane is not coded
- int dmb_is_raw; ///< direct mb plane is raw
- int skip_is_raw; ///< skip mb plane is not coded
- uint8_t luty[256], lutuv[256]; // lookup tables used for intensity compensation
- int use_ic; ///< use intensity compensation in B-frames
- int rnd; ///< rounding control
+ uint8_t mvrange; ///< Extended MV range flag
+ uint8_t pquantizer; ///< Uniform (over sequence) quantizer in use
+ VLC *cbpcy_vlc; ///< CBPCY VLC table
+ int tt_index; ///< Index for Transform Type tables (to decode TTMB)
+ uint8_t* mv_type_mb_plane; ///< bitplane for mv_type == (4MV)
+ uint8_t* direct_mb_plane; ///< bitplane for "direct" MBs
+ uint8_t* forward_mb_plane; ///< bitplane for "forward" MBs
+ int mv_type_is_raw; ///< mv type mb plane is not coded
+ int dmb_is_raw; ///< direct mb plane is raw
+ int fmb_is_raw; ///< forward mb plane is raw
+ int skip_is_raw; ///< skip mb plane is not coded
+ uint8_t luty[256], lutuv[256]; ///< lookup tables used for intensity compensation
+ int use_ic; ///< use intensity compensation in B-frames
+ int rnd; ///< rounding control
/** Frame decoding info for S/M profiles only */
//@{
- uint8_t rangeredfrm; ///< out_sample = CLIP((in_sample-128)*2+128)
+ uint8_t rangeredfrm; ///< out_sample = CLIP((in_sample-128)*2+128)
uint8_t interpfrm;
//@}
/** Frame decoding info for Advanced profile */
//@{
- uint8_t fcm; ///< 0->Progressive, 2->Frame-Interlace, 3->Field-Interlace
+ enum FrameCodingMode fcm;
uint8_t numpanscanwin;
uint8_t tfcntr;
uint8_t rptfrm, tff, rff;
@@ -307,10 +332,51 @@ typedef struct VC1Context{
uint8_t range_mapuv;
//@}
+ /** Frame decoding info for interlaced picture */
+ uint8_t dmvrange; ///< Extended differential MV range flag
+ int fourmvswitch;
+ int intcomp;
+ uint8_t lumscale2; ///< for interlaced field P picture
+ uint8_t lumshift2;
+ uint8_t luty2[256], lutuv2[256]; // lookup tables used for intensity compensation
+ VLC* mbmode_vlc;
+ VLC* imv_vlc;
+ VLC* twomvbp_vlc;
+ VLC* fourmvbp_vlc;
+ uint8_t twomvbp;
+ uint8_t fourmvbp;
+ uint8_t* fieldtx_plane;
+ int fieldtx_is_raw;
+ int8_t zzi_8x8[64];
+ uint8_t *blk_mv_type_base, *blk_mv_type; ///< 0: frame MV, 1: field MV (interlaced frame)
+ uint8_t *mv_f_base, *mv_f[2]; ///< 0: MV obtained from same field, 1: opposite field
+ uint8_t *mv_f_last_base, *mv_f_last[2];
+ uint8_t *mv_f_next_base, *mv_f_next[2];
+ int field_mode; ///< 1 for interlaced field pictures
+ int fptype;
+ int second_field;
+ int refdist; ///< distance of the current picture from reference
+ int numref; ///< number of past field pictures used as reference
+ // 0 corresponds to 1 and 1 corresponds to 2 references
+ int reffield; ///< if numref = 0 (1 reference) then reffield decides which
+ // field to use among the two fields from previous frame
+ int intcompfield; ///< which of the two fields to be intensity compensated
+ // 0: both fields, 1: bottom field, 2: top field
+ int cur_field_type; ///< 0: top, 1: bottom
+ int ref_field_type[2]; ///< forward and backward reference field type (top or bottom)
+ int blocks_off, mb_off;
+ int qs_last; ///< if qpel has been used in the previous (tr.) picture
+ int bmvtype;
+ int frfd, brfd; ///< reference frame distance (forward or backward)
+ int pic_header_flag;
+
/** Frame decoding info for sprite modes */
//@{
int new_sprite;
int two_sprites;
+ AVFrame sprite_output_frame;
+ int output_width, output_height, sprite_width, sprite_height;
+ uint8_t* sr_rows[2][2]; ///< Sprite resizer line cache
//@}
int p_frame_skipped;
@@ -322,11 +388,11 @@ typedef struct VC1Context{
uint32_t *cbp_base, *cbp;
uint8_t *is_intra_base, *is_intra;
int16_t (*luma_mv_base)[2], (*luma_mv)[2];
- uint8_t bfraction_lut_index;///< Index for BFRACTION value (see Table 40, reproduced into ff_vc1_bfraction_lut[])
- uint8_t broken_link; ///< Broken link flag (BROKEN_LINK syntax element)
- uint8_t closed_entry; ///< Closed entry point flag (CLOSED_ENTRY syntax element)
+ uint8_t bfraction_lut_index; ///< Index for BFRACTION value (see Table 40, reproduced into ff_vc1_bfraction_lut[])
+ uint8_t broken_link; ///< Broken link flag (BROKEN_LINK syntax element)
+ uint8_t closed_entry; ///< Closed entry point flag (CLOSED_ENTRY syntax element)
- int parse_only; ///< Context is used within parser
+ int parse_only; ///< Context is used within parser
int warn_interlaced;
} VC1Context;
@@ -338,11 +404,12 @@ static av_always_inline const uint8_t* find_next_marker(const uint8_t *src, cons
{
uint32_t mrk = 0xFFFFFFFF;
- if(end-src < 4) return end;
- while(src < end){
+ if (end-src < 4)
+ return end;
+ while (src < end) {
mrk = (mrk << 8) | *src++;
- if(IS_MARKER(mrk))
- return src-4;
+ if (IS_MARKER(mrk))
+ return src - 4;
}
return end;
}
@@ -351,12 +418,13 @@ static av_always_inline int vc1_unescape_buffer(const uint8_t *src, int size, ui
{
int dsize = 0, i;
- if(size < 4){
- for(dsize = 0; dsize < size; dsize++) *dst++ = *src++;
+ if (size < 4) {
+ for (dsize = 0; dsize < size; dsize++)
+ *dst++ = *src++;
return size;
}
- for(i = 0; i < size; i++, src++) {
- if(src[0] == 3 && i >= 2 && !src[-1] && !src[-2] && i < size-1 && src[1] < 4) {
+ for (i = 0; i < size; i++, src++) {
+ if (src[0] == 3 && i >= 2 && !src[-1] && !src[-2] && i < size-1 && src[1] < 4) {
dst[dsize++] = src[1];
src++;
i++;
diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c
index 27ff1bd..e6243d9 100644
--- a/libavcodec/vc1_parser.c
+++ b/libavcodec/vc1_parser.c
@@ -45,6 +45,7 @@ static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx,
vpc->v.s.avctx = avctx;
vpc->v.parse_only = 1;
next = buf;
+ s->repeat_pict = 0;
for(start = buf, end = buf + buf_size; next < end; start = next){
int buf2_size, size;
@@ -73,6 +74,20 @@ static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx,
else
s->pict_type = vpc->v.s.pict_type;
+ if (avctx->ticks_per_frame > 1){
+ // process pulldown flags
+ s->repeat_pict = 1;
+ // Pulldown flags are only valid when 'broadcast' has been set.
+ // So ticks_per_frame will be 2
+ if (vpc->v.rff){
+ // repeat field
+ s->repeat_pict = 2;
+ }else if (vpc->v.rptfrm){
+ // repeat frames
+ s->repeat_pict = vpc->v.rptfrm * 2 + 1;
+ }
+ }
+
break;
}
}
@@ -81,7 +96,7 @@ static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx,
}
/**
- * finds the end of the current frame in the bitstream.
+ * Find the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
static int vc1_find_frame_end(ParseContext *pc, const uint8_t *buf,
@@ -170,10 +185,9 @@ static int vc1_split(AVCodecContext *avctx,
}
AVCodecParser ff_vc1_parser = {
- { CODEC_ID_VC1 },
- sizeof(VC1ParseContext),
- NULL,
- vc1_parse,
- ff_parse1_close,
- vc1_split,
+ .codec_ids = { CODEC_ID_VC1 },
+ .priv_data_size = sizeof(VC1ParseContext),
+ .parser_parse = vc1_parse,
+ .parser_close = ff_parse1_close,
+ .split = vc1_split,
};
diff --git a/libavcodec/vc1data.c b/libavcodec/vc1data.c
index 1cbf93e..69d71ad 100644
--- a/libavcodec/vc1data.c
+++ b/libavcodec/vc1data.c
@@ -1,5 +1,6 @@
/*
* VC-1 and WMV3 decoder
+ * copyright (c) 2011 Mashiat Sarker Shakkhar
* copyright (c) 2006 Konstantin Shishkov
* (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer
*
@@ -31,38 +32,70 @@
/** Table for conversion between TTBLK and TTMB */
const int ff_vc1_ttblk_to_tt[3][8] = {
- { TT_8X4, TT_4X8, TT_8X8, TT_4X4, TT_8X4_TOP, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT },
- { TT_8X8, TT_4X8_RIGHT, TT_4X8_LEFT, TT_4X4, TT_8X4, TT_4X8, TT_8X4_BOTTOM, TT_8X4_TOP },
- { TT_8X8, TT_4X8, TT_4X4, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT, TT_8X4, TT_8X4_TOP }
+ { TT_8X4, TT_4X8, TT_8X8, TT_4X4, TT_8X4_TOP, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT },
+ { TT_8X8, TT_4X8_RIGHT, TT_4X8_LEFT, TT_4X4, TT_8X4, TT_4X8, TT_8X4_BOTTOM, TT_8X4_TOP },
+ { TT_8X8, TT_4X8, TT_4X4, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT, TT_8X4, TT_8X4_TOP }
};
const int ff_vc1_ttfrm_to_tt[4] = { TT_8X8, TT_8X4, TT_4X8, TT_4X4 };
/** MV P mode - the 5th element is only used for mode 1 */
const uint8_t ff_vc1_mv_pmode_table[2][5] = {
- { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_MIXED_MV },
- { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_1MV_HPEL_BILIN }
+ { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_MIXED_MV },
+ { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_1MV_HPEL_BILIN }
};
const uint8_t ff_vc1_mv_pmode_table2[2][4] = {
- { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_MIXED_MV },
- { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN }
+ { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_MIXED_MV },
+ { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN }
+};
+
+/* MBMODE table for interlaced frame P-picture */
+const uint8_t ff_vc1_mbmode_intfrp[2][15][4] = {
+ { /* 1: 4-MV, 0: non-4-MV */
+ /* Type, FIELDTX, 1-MV Differential present, Residuals (CBP) present */
+ /* Table 164 - Table 167 */
+ { MV_PMODE_INTFR_1MV , 0, 1, 1 },
+ { MV_PMODE_INTFR_1MV , 1, 1, 1 },
+ { MV_PMODE_INTFR_1MV , 0, 1, 0 },
+ { MV_PMODE_INTFR_1MV , 0, 0, 1 },
+ { MV_PMODE_INTFR_1MV , 1, 0, 1 },
+ { MV_PMODE_INTFR_2MV_FIELD, 0, 0, 1 },
+ { MV_PMODE_INTFR_2MV_FIELD, 1, 0, 1 },
+ { MV_PMODE_INTFR_2MV_FIELD, 0, 0, 0 },
+ { MV_PMODE_INTFR_INTRA , 0, 0, 0 }
+ },
+ {
+ /* Table 160 - Table 163 */
+ { MV_PMODE_INTFR_1MV , 0, 1, 1 },
+ { MV_PMODE_INTFR_1MV , 1, 1, 1 },
+ { MV_PMODE_INTFR_1MV , 0, 1, 0 },
+ { MV_PMODE_INTFR_1MV , 0, 0, 1 },
+ { MV_PMODE_INTFR_1MV , 1, 0, 1 },
+ { MV_PMODE_INTFR_2MV_FIELD, 0, 0, 1 },
+ { MV_PMODE_INTFR_2MV_FIELD, 1, 0, 1 },
+ { MV_PMODE_INTFR_2MV_FIELD, 0, 0, 0 },
+ { MV_PMODE_INTFR_4MV , 0, 0, 1 },
+ { MV_PMODE_INTFR_4MV , 1, 0, 1 },
+ { MV_PMODE_INTFR_4MV , 0, 0, 0 },
+ { MV_PMODE_INTFR_4MV_FIELD, 0, 0, 1 },
+ { MV_PMODE_INTFR_4MV_FIELD, 1, 0, 1 },
+ { MV_PMODE_INTFR_4MV_FIELD, 0, 0, 0 },
+ { MV_PMODE_INTFR_INTRA , 0, 0, 0 }
+ }
};
const int ff_vc1_fps_nr[5] = { 24, 25, 30, 50, 60 },
- ff_vc1_fps_dr[2] = { 1000, 1001 };
+ ff_vc1_fps_dr[2] = { 1000, 1001 };
const uint8_t ff_vc1_pquant_table[3][32] = {
- { /* Implicit quantizer */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31
- },
- { /* Explicit quantizer, pquantizer uniform */
- 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
- },
- { /* Explicit quantizer, pquantizer non-uniform */
- 0, 1, 1, 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, 29, 31
- }
+ /* Implicit quantizer */
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31 },
+ /* Explicit quantizer, pquantizer uniform */
+ { 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 },
+ /* Explicit quantizer, pquantizer non-uniform */
+ { 0, 1, 1, 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, 29, 31 }
};
/** @name VC-1 VLC tables and defines
@@ -84,38 +117,57 @@ VLC ff_vc1_ttmb_vlc[3];
VLC ff_vc1_mv_diff_vlc[4];
#define VC1_CBPCY_P_VLC_BITS 9 //14
VLC ff_vc1_cbpcy_p_vlc[4];
+#define VC1_ICBPCY_VLC_BITS 9
+VLC ff_vc1_icbpcy_vlc[8];
#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6
VLC ff_vc1_4mv_block_pattern_vlc[4];
+#define VC1_2MV_BLOCK_PATTERN_VLC_BITS 3
+VLC ff_vc1_2mv_block_pattern_vlc[4];
#define VC1_TTBLK_VLC_BITS 5
VLC ff_vc1_ttblk_vlc[3];
#define VC1_SUBBLKPAT_VLC_BITS 6
VLC ff_vc1_subblkpat_vlc[3];
+#define VC1_INTFR_4MV_MBMODE_VLC_BITS 9
+VLC ff_vc1_intfr_4mv_mbmode_vlc[4];
+#define VC1_INTFR_NON4MV_MBMODE_VLC_BITS 6
+VLC ff_vc1_intfr_non4mv_mbmode_vlc[4];
+#define VC1_IF_MMV_MBMODE_VLC_BITS 5
+VLC ff_vc1_if_mmv_mbmode_vlc[8];
+#define VC1_IF_1MV_MBMODE_VLC_BITS 5
+VLC ff_vc1_if_1mv_mbmode_vlc[8];
+#define VC1_1REF_MVDATA_VLC_BITS 9
+VLC ff_vc1_1ref_mvdata_vlc[4];
+#define VC1_2REF_MVDATA_VLC_BITS 9
+VLC ff_vc1_2ref_mvdata_vlc[8];
VLC ff_vc1_ac_coeff_table[8];
+
+#define VC1_IF_MBMODE_VLC_BITS 5 // as a placeholder for VC1_IF_MMV_MBMODE_VLC_BITS
+ // or VC1_IF_1MV_MBMODE_VLC_BITS since they are the same
//@}
-#if B_FRACTION_DEN==840 //original bfraction from vc9data.h, not conforming to standard
+#if B_FRACTION_DEN == 840 // original bfraction from vc9data.h, not conforming to standard
/* bfraction is fractional, we scale to the GCD 3*5*7*8 = 840 */
const int16_t ff_vc1_bfraction_lut[23] = {
- 420 /*1/2*/, 280 /*1/3*/, 560 /*2/3*/, 210 /*1/4*/,
- 630 /*3/4*/, 168 /*1/5*/, 336 /*2/5*/,
- 504 /*3/5*/, 672 /*4/5*/, 140 /*1/6*/, 700 /*5/6*/,
- 120 /*1/7*/, 240 /*2/7*/, 360 /*3/7*/, 480 /*4/7*/,
- 600 /*5/7*/, 720 /*6/7*/, 105 /*1/8*/, 315 /*3/8*/,
- 525 /*5/8*/, 735 /*7/8*/,
- -1 /*inv.*/, 0 /*BI fm*/
+ 420 /*1/2*/, 280 /*1/3*/, 560 /*2/3*/, 210 /*1/4*/,
+ 630 /*3/4*/, 168 /*1/5*/, 336 /*2/5*/,
+ 504 /*3/5*/, 672 /*4/5*/, 140 /*1/6*/, 700 /*5/6*/,
+ 120 /*1/7*/, 240 /*2/7*/, 360 /*3/7*/, 480 /*4/7*/,
+ 600 /*5/7*/, 720 /*6/7*/, 105 /*1/8*/, 315 /*3/8*/,
+ 525 /*5/8*/, 735 /*7/8*/,
+ -1 /*inv.*/, 0 /*BI fm*/
};
#else
/* pre-computed scales for all bfractions and base=256 */
const int16_t ff_vc1_bfraction_lut[23] = {
- 128 /*1/2*/, 85 /*1/3*/, 170 /*2/3*/, 64 /*1/4*/,
- 192 /*3/4*/, 51 /*1/5*/, 102 /*2/5*/,
- 153 /*3/5*/, 204 /*4/5*/, 43 /*1/6*/, 215 /*5/6*/,
- 37 /*1/7*/, 74 /*2/7*/, 111 /*3/7*/, 148 /*4/7*/,
- 185 /*5/7*/, 222 /*6/7*/, 32 /*1/8*/, 96 /*3/8*/,
- 160 /*5/8*/, 224 /*7/8*/,
- -1 /*inv.*/, 0 /*BI fm*/
+ 128 /*1/2*/, 85 /*1/3*/, 170 /*2/3*/, 64 /*1/4*/,
+ 192 /*3/4*/, 51 /*1/5*/, 102 /*2/5*/,
+ 153 /*3/5*/, 204 /*4/5*/, 43 /*1/6*/, 215 /*5/6*/,
+ 37 /*1/7*/, 74 /*2/7*/, 111 /*3/7*/, 148 /*4/7*/,
+ 185 /*5/7*/, 222 /*6/7*/, 32 /*1/8*/, 96 /*3/8*/,
+ 160 /*5/8*/, 224 /*7/8*/,
+ -1 /*inv.*/, 0 /*BI fm*/
};
#endif
@@ -129,154 +181,477 @@ const uint8_t ff_vc1_bfraction_bits[23] = {
7, 7
};
const uint8_t ff_vc1_bfraction_codes[23] = {
- 0, 1, 2, 3,
- 4, 5, 6,
- 112, 113, 114, 115,
- 116, 117, 118, 119,
- 120, 121, 122, 123,
- 124, 125,
- 126, 127
+ 0, 1, 2, 3,
+ 4, 5, 6,
+ 112, 113, 114, 115,
+ 116, 117, 118, 119,
+ 120, 121, 122, 123,
+ 124, 125,
+ 126, 127
};
//Same as H.264
-const AVRational ff_vc1_pixel_aspect[16]={
- {0, 1},
- {1, 1},
- {12, 11},
- {10, 11},
- {16, 11},
- {40, 33},
- {24, 11},
- {20, 11},
- {32, 11},
- {80, 33},
- {18, 11},
- {15, 11},
- {64, 33},
- {160, 99},
- {0, 1},
- {0, 1}
+const AVRational ff_vc1_pixel_aspect[16] = {
+ { 0, 1 },
+ { 1, 1 },
+ { 12, 11 },
+ { 10, 11 },
+ { 16, 11 },
+ { 40, 33 },
+ { 24, 11 },
+ { 20, 11 },
+ { 32, 11 },
+ { 80, 33 },
+ { 18, 11 },
+ { 15, 11 },
+ { 64, 33 },
+ { 160, 99 },
+ { 0, 1 },
+ { 0, 1 }
};
/* BitPlane IMODE - such a small table... */
const uint8_t ff_vc1_imode_codes[7] = {
- 0, 2, 1, 3, 1, 2, 3
+ 0, 2, 1, 3, 1, 2, 3
};
const uint8_t ff_vc1_imode_bits[7] = {
- 4, 2, 3, 2, 4, 3, 3
+ 4, 2, 3, 2, 4, 3, 3
};
/* Normal-2 imode */
const uint8_t ff_vc1_norm2_codes[4] = {
- 0, 4, 5, 3
+ 0, 4, 5, 3
};
const uint8_t ff_vc1_norm2_bits[4] = {
- 1, 3, 3, 2
+ 1, 3, 3, 2
};
const uint16_t ff_vc1_norm6_codes[64] = {
-0x001, 0x002, 0x003, 0x000, 0x004, 0x001, 0x002, 0x047, 0x005, 0x003, 0x004, 0x04B, 0x005, 0x04D, 0x04E, 0x30E,
-0x006, 0x006, 0x007, 0x053, 0x008, 0x055, 0x056, 0x30D, 0x009, 0x059, 0x05A, 0x30C, 0x05C, 0x30B, 0x30A, 0x037,
-0x007, 0x00A, 0x00B, 0x043, 0x00C, 0x045, 0x046, 0x309, 0x00D, 0x049, 0x04A, 0x308, 0x04C, 0x307, 0x306, 0x036,
-0x00E, 0x051, 0x052, 0x305, 0x054, 0x304, 0x303, 0x035, 0x058, 0x302, 0x301, 0x034, 0x300, 0x033, 0x032, 0x007,
+ 0x001, 0x002, 0x003, 0x000, 0x004, 0x001, 0x002, 0x047, 0x005, 0x003, 0x004, 0x04B, 0x005, 0x04D, 0x04E, 0x30E,
+ 0x006, 0x006, 0x007, 0x053, 0x008, 0x055, 0x056, 0x30D, 0x009, 0x059, 0x05A, 0x30C, 0x05C, 0x30B, 0x30A, 0x037,
+ 0x007, 0x00A, 0x00B, 0x043, 0x00C, 0x045, 0x046, 0x309, 0x00D, 0x049, 0x04A, 0x308, 0x04C, 0x307, 0x306, 0x036,
+ 0x00E, 0x051, 0x052, 0x305, 0x054, 0x304, 0x303, 0x035, 0x058, 0x302, 0x301, 0x034, 0x300, 0x033, 0x032, 0x007,
};
const uint8_t ff_vc1_norm6_bits[64] = {
- 1, 4, 4, 8, 4, 8, 8, 10, 4, 8, 8, 10, 8, 10, 10, 13,
- 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9,
- 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9,
- 8, 10, 10, 13, 10, 13, 13, 9, 10, 13, 13, 9, 13, 9, 9, 6,
-};
-#if 0
-/* Normal-6 imode */
-const uint8_t ff_vc1_norm6_spec[64][5] = {
-{ 0, 1, 1 },
-{ 1, 2, 4 },
-{ 2, 3, 4 },
-{ 3, 0, 8 },
-{ 4, 4, 4 },
-{ 5, 1, 8 },
-{ 6, 2, 8 },
-{ 7, 2, 5, 7, 5 },
-{ 8, 5, 4 },
-{ 9, 3, 8 },
-{10, 4, 8 },
-{11, 2, 5, 11, 5 },
-{12, 5, 8 },
-{13, 2, 5, 13, 5 },
-{14, 2, 5, 14, 5 },
-{15, 3, 5, 14, 8 },
-{16, 6, 4 },
-{17, 6, 8 },
-{18, 7, 8 },
-{19, 2, 5, 19, 5 },
-{20, 8, 8 },
-{21, 2, 5, 21, 5 },
-{22, 2, 5, 22, 5 },
-{23, 3, 5, 13, 8 },
-{24, 9, 8 },
-{25, 2, 5, 25, 5 },
-{26, 2, 5, 26, 5 },
-{27, 3, 5, 12, 8 },
-{28, 2, 5, 28, 5 },
-{29, 3, 5, 11, 8 },
-{30, 3, 5, 10, 8 },
-{31, 3, 5, 7, 4 },
-{32, 7, 4 },
-{33, 10, 8 },
-{34, 11, 8 },
-{35, 2, 5, 3, 5 },
-{36, 12, 8 },
-{37, 2, 5, 5, 5 },
-{38, 2, 5, 6, 5 },
-{39, 3, 5, 9, 8 },
-{40, 13, 8 },
-{41, 2, 5, 9, 5 },
-{42, 2, 5, 10, 5 },
-{43, 3, 5, 8, 8 },
-{44, 2, 5, 12, 5 },
-{45, 3, 5, 7, 8 },
-{46, 3, 5, 6, 8 },
-{47, 3, 5, 6, 4 },
-{48, 14, 8 },
-{49, 2, 5, 17, 5 },
-{50, 2, 5, 18, 5 },
-{51, 3, 5, 5, 8 },
-{52, 2, 5, 20, 5 },
-{53, 3, 5, 4, 8 },
-{54, 3, 5, 3, 8 },
-{55, 3, 5, 5, 4 },
-{56, 2, 5, 24, 5 },
-{57, 3, 5, 2, 8 },
-{58, 3, 5, 1, 8 },
-{59, 3, 5, 4, 4 },
-{60, 3, 5, 0, 8 },
-{61, 3, 5, 3, 4 },
-{62, 3, 5, 2, 4 },
-{63, 3, 5, 1, 1 },
+ 1, 4, 4, 8, 4, 8, 8, 10, 4, 8, 8, 10, 8, 10, 10, 13,
+ 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9,
+ 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9,
+ 8, 10, 10, 13, 10, 13, 13, 9, 10, 13, 13, 9, 13, 9, 9, 6,
};
-#endif
/* 4MV Block pattern VLC tables */
const uint8_t ff_vc1_4mv_block_pattern_codes[4][16] = {
- { 14, 58, 59, 25, 12, 26, 15, 15, 13, 24, 27, 0, 28, 1, 2, 2},
- { 8, 18, 19, 4, 20, 5, 30, 11, 21, 31, 6, 12, 7, 13, 14, 0},
- { 15, 6, 7, 2, 8, 3, 28, 9, 10, 29, 4, 11, 5, 12, 13, 0},
- { 0, 11, 12, 4, 13, 5, 30, 16, 14, 31, 6, 17, 7, 18, 19, 10}
+ { 14, 58, 59, 25, 12, 26, 15, 15, 13, 24, 27, 0, 28, 1, 2, 2 },
+ { 8, 18, 19, 4, 20, 5, 30, 11, 21, 31, 6, 12, 7, 13, 14, 0 },
+ { 15, 6, 7, 2, 8, 3, 28, 9, 10, 29, 4, 11, 5, 12, 13, 0 },
+ { 0, 11, 12, 4, 13, 5, 30, 16, 14, 31, 6, 17, 7, 18, 19, 10 }
};
const uint8_t ff_vc1_4mv_block_pattern_bits[4][16] = {
- { 5, 6, 6, 5, 5, 5, 5, 4, 5, 5, 5, 3, 5, 3, 3, 2},
- { 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2},
- { 4, 4, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3},
- { 2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4}
+ { 5, 6, 6, 5, 5, 5, 5, 4, 5, 5, 5, 3, 5, 3, 3, 2 },
+ { 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2 },
+ { 4, 4, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3 },
+ { 2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4 }
+};
+
+/* 2MV Block pattern VLC tables */
+const uint8_t ff_vc1_2mv_block_pattern_codes[4][4] = {
+ { 2, 1, 0, 3 }, { 1, 0, 2, 3 }, { 2, 0, 3, 1 }, { 1, 3, 2, 0 }
+};
+
+const uint8_t ff_vc1_2mv_block_pattern_bits[4][4] = {
+ { 2, 2, 2, 2 }, { 1, 2, 3, 3 }, { 3, 2, 3, 1 }, { 1, 3, 3, 2 }
+};
+
+/* Interlaced frame picture 4MV MBMODE VLC tables (p. 246, p. 360) */
+const uint16_t ff_vc1_intfr_4mv_mbmode_codes[4][15] = {
+ { 22, 17, 0, 47, 32, 10, 1, 3, 67, 133, 132, 92, 19, 93, 18 },
+ { 3, 45, 0, 7, 23, 6, 1, 2, 10, 39, 44, 8, 18, 77, 76 },
+ { 15, 6, 28, 9, 41, 6, 2, 15, 14, 8, 40, 29, 0, 21, 11 },
+ { 7, 198, 1, 2, 193, 13, 25, 0, 97, 1599, 98, 398, 798, 192, 1598 }
+};
+
+const uint8_t ff_vc1_intfr_4mv_mbmode_bits[4][15] = {
+ { 5, 5, 2, 6, 6, 4, 2, 2, 7, 8, 8, 7, 5, 7, 5 },
+ { 3, 6, 3, 3, 5, 3, 3, 3, 4, 6, 6, 4, 5, 7, 7 },
+ { 4, 3, 5, 5, 7, 4, 2, 5, 5, 5, 7, 5, 2, 6, 5 },
+ { 4, 9, 1, 3, 9, 5, 6, 2, 8, 12, 8, 10, 11, 9, 12 }
+};
+
+/* Interlaced frame picture NON-4MV MBMODE VLC tables (p. 363) */
+const uint8_t ff_vc1_intfr_non4mv_mbmode_codes[4][9] = {
+ { 9, 22, 0, 17, 16, 10, 1, 3, 23 },
+ { 7, 0, 5, 2, 1, 1, 6, 3, 4 },
+ { 1, 0, 10, 23, 44, 8, 3, 9, 45 },
+ { 7, 97, 1, 2, 49, 13, 25, 0, 96 }
+};
+
+const uint8_t ff_vc1_intfr_non4mv_mbmode_bits[4][9] = {
+ { 4, 5, 2, 5, 5, 4, 2, 2, 5 },
+ { 3, 4, 6, 2, 3, 2, 3, 5, 6 },
+ { 2, 2, 4, 5, 6, 4, 2, 4, 6 },
+ { 4, 8, 1, 3, 7, 5, 6, 2, 8 }
+};
+
+/* Interlaced field picture MBMODE VLC tables (p. 356 - 11.4.1, 11.4.2) */
+/* mixed-MV */
+const uint8_t ff_vc1_if_mmv_mbmode_codes[8][8] = {
+ { 16, 17, 3, 3, 0, 5, 9, 2 },
+ { 8, 9, 3, 6, 7, 0, 5, 2 },
+ { 16, 17, 5, 3, 0, 3, 9, 2 },
+ { 56, 57, 15, 4, 5, 6, 29, 0 },
+ { 52, 53, 27, 14, 15, 2, 12, 0 },
+ { 56, 57, 29, 5, 6, 0, 15, 4 },
+ { 16, 17, 6, 7, 0, 1, 9, 5 },
+ { 56, 57, 0, 5, 6, 29, 4, 15 }
+};
+const uint8_t ff_vc1_if_mmv_mbmode_bits[8][8] = {
+ { 6, 6, 2, 3, 2, 4, 5, 2 },
+ { 5, 5, 3, 3, 3, 2, 4, 2 },
+ { 6, 6, 4, 3, 2, 2, 5, 2 },
+ { 6, 6, 4, 3, 3, 3, 5, 1 },
+ { 6, 6, 5, 4, 4, 2, 4, 1 },
+ { 6, 6, 5, 3, 3, 1, 4, 3 },
+ { 5, 5, 3, 3, 2, 2, 4, 3 },
+ { 6, 6, 1, 3, 3, 5, 3, 4 }
+};
+/* 1MV */
+const uint8_t ff_vc1_if_1mv_mbmode_codes[8][6] = {
+ { 0, 1, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 1, 1 },
+ { 16, 17, 3, 0, 9, 5 },
+ { 20, 21, 3, 11, 0, 4 },
+ { 4, 5, 2, 3, 3, 0 },
+ { 4, 5, 3, 2, 0, 3 },
+ { 0, 1, 1, 1, 1, 1 },
+ { 16, 17, 9, 5, 3, 0 }
+};
+const uint8_t ff_vc1_if_1mv_mbmode_bits[8][6] = {
+ { 5, 5, 1, 3, 2, 4 },
+ { 5, 5, 1, 2, 3, 4 },
+ { 5, 5, 2, 1, 4, 3 },
+ { 5, 5, 2, 4, 1, 3 },
+ { 4, 4, 2, 3, 2, 2 },
+ { 4, 4, 3, 2, 2, 2 },
+ { 5, 5, 3, 4, 1, 2 },
+ { 5, 5, 4, 3, 2, 1 }
+};
+
+/* Interlaced frame/field picture MVDATA VLC tables */
+
+/* 1-reference tables */
+const uint32_t ff_vc1_1ref_mvdata_codes[4][72] = { /* uint32_t may be too big */
+ {
+ 0x00005, 0x0000C, 0x0001E, 0x00012, 0x0000C, 0x00034, 0x00075, 0x00070,
+ 0x00000, 0x00008, 0x0001B, 0x00008, 0x0001D, 0x0007C, 0x000D6, 0x001DE,
+ 0x001AF, 0x00005, 0x0001B, 0x00026, 0x0001E, 0x00012, 0x00076, 0x0004D,
+ 0x001F6, 0x001F4, 0x00039, 0x0007F, 0x00027, 0x0006A, 0x00071, 0x00035,
+ 0x00071, 0x00068, 0x001DC, 0x00027, 0x00073, 0x000FF, 0x000E8, 0x000E9,
+ 0x0007E, 0x001F9, 0x001F5, 0x001FD, 0x0003E, 0x001CA, 0x003F9, 0x0004C,
+ 0x00069, 0x001FA, 0x001DF, 0x001F7, 0x00070, 0x001DD, 0x00E4D, 0x00727,
+ 0x00392, 0x001C8, 0x001CB, 0x003F8, 0x001AE, 0x001F8, 0x001FB, 0x0E4CE,
+ 0x0E4CF, 0x07260, 0x07261, 0x07262, 0x07263, 0x07264, 0x07265, 0x07266
+ },
+ {
+ 0x00007, 0x00001, 0x00007, 0x00016, 0x00001, 0x00045, 0x00018, 0x002B6,
+ 0x00006, 0x00004, 0x00017, 0x00010, 0x00029, 0x0002C, 0x0015A, 0x00066,
+ 0x0019E, 0x00009, 0x00028, 0x00017, 0x00000, 0x0002A, 0x00004, 0x0005B,
+ 0x000B5, 0x000CE, 0x00006, 0x00044, 0x0000F, 0x00046, 0x0000E, 0x000AC,
+ 0x00032, 0x00037, 0x011EB, 0x0000A, 0x0001A, 0x0011F, 0x00016, 0x00014,
+ 0x0002B, 0x00168, 0x00055, 0x023D5, 0x00057, 0x0002F, 0x00036, 0x0002E,
+ 0x00169, 0x00054, 0x0047B, 0x0019F, 0x02B7D, 0x0008E, 0x00ADE, 0x00479,
+ 0x0056E, 0x008F4, 0x015BF, 0x00478, 0x023D4, 0x0ADF1, 0x056F9, 0xADF0E,
+ 0xADF0F, 0x56F80, 0x56F81, 0x56F82, 0x56F83, 0x56F84, 0x56F85, 0x56F86
+ },
+ {
+ 0x00002, 0x00006, 0x00007, 0x0000D, 0x00007, 0x00030, 0x000FF, 0x001F0,
+ 0x00002, 0x00000, 0x00005, 0x00019, 0x0001E, 0x00007, 0x00063, 0x000FD,
+ 0x00023, 0x0000E, 0x0001B, 0x0001A, 0x00006, 0x00009, 0x00018, 0x000C5,
+ 0x00033, 0x001F1, 0x00002, 0x003FB, 0x001F3, 0x00022, 0x001FC, 0x00042,
+ 0x00623, 0x00083, 0x00620, 0x0007D, 0x00040, 0x00043, 0x003E4, 0x003E5,
+ 0x00191, 0x00FE9, 0x00105, 0x00208, 0x000FC, 0x00624, 0x00622, 0x00190,
+ 0x00626, 0x007F5, 0x00C4B, 0x01FD0, 0x0104D, 0x00065, 0x00C42, 0x000C9,
+ 0x00627, 0x00C43, 0x00C4A, 0x0104E, 0x01FD1, 0x0104F, 0x00412, 0x104CE,
+ 0x104CF, 0x08260, 0x08261, 0x08262, 0x08263, 0x08264, 0x08265, 0x08266
+ },
+ {
+ 0x0000D, 0x00001, 0x00004, 0x00000, 0x00017, 0x00005, 0x0007F, 0x0004D,
+ 0x00003, 0x00011, 0x0003E, 0x0003B, 0x00017, 0x00067, 0x0004A, 0x000C3,
+ 0x000F2, 0x0000A, 0x0002C, 0x00032, 0x0003D, 0x00015, 0x00028, 0x00093,
+ 0x000CC, 0x00096, 0x00003, 0x00075, 0x00020, 0x0002D, 0x00021, 0x00029,
+ 0x00090, 0x001D0, 0x001FB, 0x0001C, 0x0004C, 0x00060, 0x00009, 0x00008,
+ 0x0002D, 0x0009F, 0x001FA, 0x0013D, 0x00031, 0x000FC, 0x00058, 0x00092,
+ 0x000F0, 0x000F1, 0x000CD, 0x00185, 0x00165, 0x0004E, 0x00091, 0x000E9,
+ 0x00184, 0x001D1, 0x001E6, 0x00097, 0x001E7, 0x000B3, 0x0013C, 0x0164E,
+ 0x0164F, 0x00B20, 0x00B21, 0x00B22, 0x00B23, 0x00B24, 0x00B25, 0x00B26
+ }
};
-const uint8_t wmv3_dc_scale_table[32]={
- 0, 2, 4, 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
+const uint8_t ff_vc1_1ref_mvdata_bits[4][72] = {
+ {
+ 3, 4, 5, 5, 5, 6, 7, 7, 2, 4, 5, 5, 6, 7, 8, 9, 9, 4,
+ 6, 6, 6, 6, 7, 8, 9, 9, 6, 8, 7, 7, 7, 7, 8, 8, 9, 6,
+ 8, 8, 8, 8, 8, 9, 9, 9, 7, 10, 10, 8, 8, 9, 9, 9, 8, 9,
+ 13, 12, 11, 10, 10, 10, 9, 9, 9, 17, 17, 16, 16, 16, 16, 16, 16, 16
+ },
+ {
+ 3, 3, 4, 5, 5, 7, 8, 10, 3, 4, 5, 5, 6, 7, 9, 10, 12, 4,
+ 6, 6, 5, 6, 6, 8, 9, 11, 4, 7, 7, 7, 7, 8, 9, 9, 13, 5,
+ 8, 9, 8, 8, 9, 10, 10, 14, 7, 9, 9, 9, 10, 10, 11, 12, 14, 8,
+ 12, 11, 11, 12, 13, 11, 14, 16, 15, 20, 20, 19, 19, 19, 19, 19, 19, 19
+ },
+ {
+ 3, 4, 4, 4, 5, 6, 8, 9, 2, 4, 5, 5, 5, 6, 7, 8, 8, 4,
+ 7, 7, 6, 6, 7, 8, 8, 9, 5, 10, 9, 8, 9, 9, 11, 10, 11, 7,
+ 9, 9, 10, 10, 11, 12, 11, 12, 8, 11, 11, 11, 11, 11, 12, 13, 15, 9,
+ 12, 10, 11, 12, 12, 15, 13, 15, 13, 19, 19, 18, 18, 18, 18, 18, 18, 18
+ },
+ {
+ 4, 4, 4, 4, 5, 5, 7, 7, 3, 5, 6, 6, 6, 7, 7, 8, 8, 4,
+ 6, 6, 6, 6, 7, 8, 8, 8, 4, 7, 6, 6, 6, 7, 8, 9, 9, 5,
+ 7, 7, 6, 6, 7, 8, 9, 9, 6, 8, 8, 8, 8, 8, 8, 9, 10, 7,
+ 8, 8, 9, 9, 9, 8, 9, 9, 9, 14, 14, 13, 13, 13, 13, 13, 13, 13
+ }
+};
+
+/* 2-reference tables */
+const uint32_t ff_vc1_2ref_mvdata_codes[8][126] = { /* table 132 - table 139 */
+ {
+ 0x0000C, 0x0001C, 0x0000B, 0x00000, 0x0000E, 0x0002A, 0x00050, 0x00368,
+ 0x00002, 0x0001A, 0x00004, 0x0003A, 0x0001D, 0x0006C, 0x000EF, 0x001BC,
+ 0x0015F, 0x0000F, 0x00003, 0x0001C, 0x0000D, 0x0000B, 0x0003E, 0x000A7,
+ 0x00146, 0x00199, 0x00006, 0x0001F, 0x00004, 0x0003C, 0x00007, 0x001BE,
+ 0x0008B, 0x0002C, 0x007B3, 0x00005, 0x000DB, 0x00056, 0x000EC, 0x00052,
+ 0x001BD, 0x00078, 0x000CF, 0x00573, 0x00009, 0x00023, 0x000ED, 0x00018,
+ 0x00006, 0x00044, 0x000F5, 0x00079, 0x006D2, 0x0006E, 0x0002B, 0x0015D,
+ 0x00017, 0x0037F, 0x00144, 0x000CE, 0x00028, 0x000AB, 0x00010, 0x001B5,
+ 0x000F7, 0x000A6, 0x0007B, 0x00028, 0x001ED, 0x001E9, 0x006FD, 0x00004,
+ 0x000F5, 0x00029, 0x0028A, 0x0028B, 0x0028F, 0x00DF9, 0x00335, 0x01E85,
+ 0x000EE, 0x002BD, 0x0002B, 0x003D8, 0x003D1, 0x00198, 0x001E9, 0x0051D,
+ 0x000B4, 0x0003F, 0x00455, 0x0022B, 0x00229, 0x00451, 0x00578, 0x007B2,
+ 0x00570, 0x00155, 0x00032, 0x003D0, 0x00054, 0x006D3, 0x00571, 0x00454,
+ 0x00334, 0x01BF1, 0x000B7, 0x00029, 0x01E84, 0x0016C, 0x0019B, 0x01BF0,
+ 0x00579, 0x00F43, 0x000B5, 0x008A1, 0x0002A, 0x0016D, 0x008A0, 0x007A0,
+ 0x003D1, 0x00AE5, 0x00154, 0x00AE4, 0x00A39, 0x00A38
+ },
+ {
+ 0x00003, 0x00009, 0x00016, 0x00010, 0x000D7, 0x00335, 0x00574, 0x00555,
+ 0x00000, 0x0001D, 0x00009, 0x00017, 0x0002C, 0x000AD, 0x00374, 0x006B3,
+ 0x00577, 0x0000F, 0x00018, 0x0000A, 0x0002E, 0x00022, 0x0017C, 0x00E7B,
+ 0x01B89, 0x015D8, 0x00008, 0x00034, 0x0006D, 0x00023, 0x001C2, 0x00376,
+ 0x002D3, 0x01C4A, 0x0330A, 0x00014, 0x0006A, 0x00072, 0x0006C, 0x000E3,
+ 0x0019B, 0x0073F, 0x01CF0, 0x00B41, 0x00032, 0x000E6, 0x000E0, 0x000CF,
+ 0x000AB, 0x0019C, 0x002AB, 0x00E2B, 0x015D9, 0x0006F, 0x001C3, 0x000AF,
+ 0x000BF, 0x000AC, 0x0017D, 0x006E3, 0x00E29, 0x01984, 0x00054, 0x000B5,
+ 0x0017A, 0x001AD, 0x00199, 0x00178, 0x00358, 0x002D2, 0x01C4B, 0x0005B,
+ 0x002A8, 0x00331, 0x00388, 0x0038B, 0x00370, 0x00713, 0x00CC3, 0x01CF1,
+ 0x001B9, 0x005EF, 0x00738, 0x002F2, 0x0033B, 0x002B9, 0x006EB, 0x00570,
+ 0x00E24, 0x0039D, 0x005A2, 0x005A3, 0x00E7D, 0x005EE, 0x00739, 0x00554,
+ 0x00AA5, 0x00AA4, 0x00377, 0x01CF5, 0x00BCE, 0x00E79, 0x00660, 0x00674,
+ 0x006EA, 0x00E7C, 0x00D65, 0x002F6, 0x015DA, 0x01B88, 0x005A1, 0x01CF4,
+ 0x005E6, 0x00E28, 0x00575, 0x00D64, 0x00334, 0x0330B, 0x015DB, 0x00B40,
+ 0x00BCF, 0x00DC5, 0x00E2A, 0x00675, 0x00571, 0x00553
+ },
+ {
+ 0x00004, 0x00002, 0x00010, 0x00003, 0x00017, 0x00045, 0x0003E, 0x0007E,
+ 0x00003, 0x00002, 0x00028, 0x0001E, 0x00015, 0x00047, 0x00002, 0x0014D,
+ 0x00060, 0x0000B, 0x00026, 0x00024, 0x00014, 0x00032, 0x0006F, 0x000C3,
+ 0x00531, 0x006E5, 0x00015, 0x0003F, 0x0002D, 0x00001, 0x0013E, 0x000DD,
+ 0x000F6, 0x00305, 0x00331, 0x0000E, 0x00003, 0x00034, 0x00033, 0x0001A,
+ 0x0014A, 0x000C5, 0x000F4, 0x006E4, 0x00001, 0x0003C, 0x0007D, 0x0008D,
+ 0x0009D, 0x00031, 0x0006E, 0x00296, 0x000CD, 0x00025, 0x00149, 0x00032,
+ 0x00089, 0x00036, 0x00088, 0x0006F, 0x00003, 0x0031D, 0x0000E, 0x001AA,
+ 0x0027E, 0x00061, 0x0014E, 0x0014F, 0x00067, 0x000FF, 0x00183, 0x00036,
+ 0x00357, 0x000F5, 0x000C6, 0x000C2, 0x00299, 0x00119, 0x00231, 0x00350,
+ 0x0002C, 0x0018F, 0x00530, 0x00297, 0x00004, 0x001B8, 0x000C0, 0x0027A,
+ 0x00311, 0x0009C, 0x00621, 0x00199, 0x0031C, 0x000F7, 0x003E3, 0x00356,
+ 0x00189, 0x00005, 0x0006B, 0x008C2, 0x00330, 0x004FF, 0x004F0, 0x00351,
+ 0x004F2, 0x001F2, 0x00373, 0x00000, 0x00C41, 0x008C3, 0x009EC, 0x003E2,
+ 0x00304, 0x004F7, 0x004F1, 0x001F0, 0x00148, 0x00C40, 0x009ED, 0x008C0,
+ 0x008C1, 0x004F3, 0x004FE, 0x000FE, 0x001F3, 0x001A9
+ },
+ {
+ 0x00000, 0x00004, 0x0002F, 0x00052, 0x00010, 0x000AD, 0x0050B, 0x00190,
+ 0x00003, 0x00016, 0x00007, 0x0000D, 0x000BB, 0x00173, 0x000C9, 0x0050F,
+ 0x0172C, 0x00003, 0x00011, 0x00005, 0x00043, 0x00023, 0x0004B, 0x0032E,
+ 0x02E5B, 0x00482, 0x00009, 0x0002A, 0x00014, 0x0002A, 0x00108, 0x005CA,
+ 0x0065A, 0x02136, 0x02132, 0x0000B, 0x00013, 0x00041, 0x000B8, 0x00174,
+ 0x00100, 0x014DA, 0x0404E, 0x01437, 0x0002B, 0x00085, 0x000A7, 0x000A0,
+ 0x0014C, 0x0029A, 0x0032C, 0x02133, 0x0142A, 0x00051, 0x00284, 0x000AC,
+ 0x00102, 0x00045, 0x00044, 0x0081B, 0x0065E, 0x00CB7, 0x00018, 0x0050C,
+ 0x00212, 0x002E4, 0x00203, 0x00094, 0x00122, 0x0081A, 0x00655, 0x00033,
+ 0x002BA, 0x00246, 0x00242, 0x00A6E, 0x0040C, 0x00808, 0x02134, 0x0404F,
+ 0x00175, 0x00405, 0x00247, 0x0012A, 0x00A14, 0x002BB, 0x00191, 0x0084F,
+ 0x01438, 0x000AF, 0x00B97, 0x00483, 0x0143B, 0x0032B, 0x00243, 0x0142B,
+ 0x00958, 0x029BF, 0x00049, 0x00A6C, 0x014DB, 0x004AD, 0x014DE, 0x0084E,
+ 0x01434, 0x00257, 0x02E5A, 0x00207, 0x01435, 0x01439, 0x00CB6, 0x0143A,
+ 0x00194, 0x00654, 0x02135, 0x0537C, 0x0015C, 0x00240, 0x01012, 0x0537D,
+ 0x00959, 0x01098, 0x01436, 0x0065F, 0x02026, 0x02137
+ },
+ {
+ 0x00005, 0x00019, 0x00016, 0x00011, 0x0003E, 0x0005E, 0x000EF, 0x000E2,
+ 0x00000, 0x00039, 0x0002B, 0x00026, 0x00028, 0x00012, 0x000C2, 0x000ED,
+ 0x0011D, 0x0000D, 0x00031, 0x0002A, 0x00025, 0x00020, 0x0005C, 0x001ED,
+ 0x0024D, 0x00770, 0x00006, 0x0007A, 0x00060, 0x0004F, 0x00048, 0x00039,
+ 0x00186, 0x00213, 0x00EC6, 0x0000F, 0x00026, 0x0005F, 0x00075, 0x00070,
+ 0x00027, 0x001DB, 0x003C6, 0x0078F, 0x0003F, 0x000A6, 0x000F0, 0x0003A,
+ 0x00052, 0x0004E, 0x000E3, 0x001D9, 0x0030F, 0x00010, 0x001DD, 0x000A7,
+ 0x000F7, 0x00022, 0x00092, 0x003C4, 0x002EF, 0x00762, 0x00079, 0x0008F,
+ 0x001DA, 0x00087, 0x000E8, 0x000BA, 0x00176, 0x000EE, 0x003B0, 0x00085,
+ 0x00119, 0x0030E, 0x00108, 0x001D2, 0x0010C, 0x00773, 0x00424, 0x00434,
+ 0x00071, 0x005DD, 0x001C1, 0x003A7, 0x00127, 0x0008D, 0x0021B, 0x007B2,
+ 0x001DF, 0x003D8, 0x00764, 0x00EE4, 0x003B3, 0x0074D, 0x001D8, 0x005DC,
+ 0x0084A, 0x00499, 0x003C5, 0x01D8E, 0x00765, 0x00435, 0x00771, 0x001C2,
+ 0x00118, 0x003BC, 0x00381, 0x00387, 0x07B33, 0x01097, 0x01096, 0x01ECD,
+ 0x00E99, 0x00F1C, 0x00F1D, 0x00EE5, 0x0011C, 0x07B32, 0x03D98, 0x01D8F,
+ 0x00E98, 0x00F67, 0x003BD, 0x00380, 0x00498, 0x00386
+ },
+ {
+ 0x0000D, 0x00010, 0x0002E, 0x00039, 0x0000D, 0x00074, 0x000ED, 0x000B6,
+ 0x00001, 0x00002, 0x00000, 0x00030, 0x00029, 0x00070, 0x000F3, 0x0008C,
+ 0x00166, 0x00009, 0x00033, 0x00078, 0x00006, 0x000C4, 0x0000B, 0x00163,
+ 0x000CC, 0x005BE, 0x0001F, 0x0002F, 0x00064, 0x00018, 0x000C6, 0x0000A,
+ 0x00162, 0x002C0, 0x00EF3, 0x00007, 0x0000F, 0x000E3, 0x000CA, 0x000B2,
+ 0x0018F, 0x003AE, 0x0075F, 0x00C51, 0x00015, 0x00047, 0x000EE, 0x000E2,
+ 0x000EA, 0x00009, 0x0016A, 0x002C3, 0x0059D, 0x0003D, 0x00008, 0x001D9,
+ 0x00032, 0x0000E, 0x0016E, 0x0032C, 0x0065B, 0x0196B, 0x00002, 0x0000F,
+ 0x001D8, 0x0008D, 0x000B4, 0x001E4, 0x00067, 0x00317, 0x00794, 0x00022,
+ 0x003BE, 0x00315, 0x00034, 0x00037, 0x002DE, 0x0006C, 0x00EFE, 0x0066C,
+ 0x00028, 0x003CB, 0x003AC, 0x00035, 0x0016B, 0x003BD, 0x002C1, 0x0062C,
+ 0x01DFE, 0x0000E, 0x0059E, 0x005BF, 0x000DA, 0x00629, 0x00584, 0x00EB7,
+ 0x00B0A, 0x0066D, 0x0000C, 0x0077E, 0x0059C, 0x00778, 0x0075E, 0x0075A,
+ 0x0062D, 0x00337, 0x00334, 0x00197, 0x01E57, 0x01DE4, 0x0196A, 0x01E56,
+ 0x00C50, 0x00B3F, 0x01E54, 0x00B0B, 0x0018E, 0x001B6, 0x01E55, 0x00CB4,
+ 0x00B3E, 0x00EB6, 0x01DE5, 0x01DFF, 0x00335, 0x001B7
+ },
+ {
+ 0x00001, 0x0000B, 0x00019, 0x0006F, 0x0002A, 0x00075, 0x007EB, 0x00163,
+ 0x00001, 0x0000E, 0x0001A, 0x0003E, 0x0001C, 0x0002D, 0x00164, 0x007EC,
+ 0x00165, 0x00004, 0x00006, 0x00036, 0x0007F, 0x000AE, 0x00158, 0x0015C,
+ 0x0056D, 0xFD510, 0x00000, 0x00004, 0x0007B, 0x000F3, 0x0003B, 0x007ED,
+ 0x002B3, 0x002CC, 0x0056E, 0x00018, 0x0003E, 0x00017, 0x0001E, 0x000AF,
+ 0x003F7, 0x0056F, 0x002CD, 0xFD511, 0x00014, 0x000AD, 0x000AA, 0x00014,
+ 0x000A8, 0x00153, 0x000E8, 0x001FE, 0x00DCF, 0x00078, 0x001B8, 0x00152,
+ 0x000FE, 0x002B1, 0x0015D, 0x00160, 0xFD512, 0xFD513, 0x0007A, 0x002B0,
+ 0x001E5, 0x000E9, 0x000FC, 0x006E6, 0x00DC8, 0x00584, 0xFD514, 0x000AB,
+ 0x00DDE, 0x00159, 0x003F4, 0x00DC9, 0x00DCA, 0x001FA, 0xFD515, 0xFD516,
+ 0x000FC, 0x001FF, 0x001E4, 0x000AF, 0x0015A, 0x00167, 0x00DCB, 0x00585,
+ 0xFD517, 0x003F7, 0x03F55, 0xFD518, 0x00DDC, 0x00586, 0x03F56, 0xFD519,
+ 0x03F57, 0xFD51A, 0x001BA, 0x00587, 0x00588, 0x00DDF, 0x002B2, 0xFD51B,
+ 0x00DCE, 0x003F6, 0xFD51C, 0x00FD4, 0xFD51D, 0xFD51E, 0xFD51F, 0x7EA80,
+ 0x7EA81, 0x0056C, 0x7EA82, 0x7EA83, 0x00376, 0x00589, 0x0058A, 0x7EA84,
+ 0x7EA85, 0x00DDD, 0x7EA86, 0x7EA87, 0x0058B, 0x07EA9
+ },
+ {
+ 0x00003, 0x0000E, 0x0000F, 0x0007E, 0x00062, 0x000C6, 0x00CD9, 0x0063E,
+ 0x00002, 0x00002, 0x00000, 0x00018, 0x0000C, 0x00069, 0x00039, 0x00707,
+ 0x00C7E, 0x00002, 0x0000D, 0x0001B, 0x0000F, 0x0019A, 0x00647, 0x01A37,
+ 0x346C4, 0x0346D, 0x00001, 0x0001E, 0x0007F, 0x0000A, 0x000E1, 0x00661,
+ 0x00CE4, 0x346C5, 0x346C6, 0x0001D, 0x00030, 0x0000D, 0x000CB, 0x00199,
+ 0x00320, 0x0008E, 0x0652E, 0x346C7, 0x0003E, 0x00039, 0x00035, 0x00033,
+ 0x0019F, 0x001C0, 0x00CDA, 0x346C8, 0x346C9, 0x0000B, 0x000D0, 0x0019E,
+ 0x00022, 0x00038, 0x0018E, 0x0031E, 0x03294, 0x0023C, 0x00032, 0x00012,
+ 0x00013, 0x00071, 0x0019D, 0x00020, 0x00C87, 0x00CC0, 0x346CA, 0x00338,
+ 0x00653, 0x001A2, 0x0032A, 0x00322, 0x00CE7, 0x00084, 0x0011F, 0x346CB,
+ 0x00325, 0x00649, 0x0032B, 0x00077, 0x00648, 0x00642, 0x00C86, 0x00C8C,
+ 0x346CC, 0x0003A, 0x019B7, 0x00043, 0x00327, 0x0008C, 0x0008D, 0x00C8D,
+ 0x346CD, 0x346CE, 0x00337, 0x00CE5, 0x00085, 0x00326, 0x00347, 0x00CA4,
+ 0x00C7F, 0x00D1A, 0x346CF, 0x00328, 0x1A360, 0x1A361, 0x00CD8, 0x0068C,
+ 0x03295, 0x03296, 0x0652F, 0x066D8, 0x00331, 0x00706, 0x0023D, 0x00076,
+ 0x00CC1, 0x00382, 0x00CE6, 0x066D9, 0x066DA, 0x066DB
+ }
+};
+
+const uint8_t ff_vc1_2ref_mvdata_bits[8][126] = {
+ {
+ 4, 5, 5, 5, 6, 7, 8, 10, 2, 5, 5, 6, 6, 7, 8, 9,
+ 10, 4, 5, 6, 6, 7, 8, 9, 10, 11, 4, 6, 6, 7, 7, 9,
+ 9, 10, 12, 5, 8, 8, 8, 8, 9, 9, 10, 12, 5, 7, 8, 7,
+ 7, 8, 9, 9, 11, 7, 9, 10, 9, 10, 10, 10, 10, 12, 6, 9,
+ 9, 9, 9, 9, 10, 10, 11, 7, 10, 10, 11, 11, 11, 12, 12, 14,
+ 8, 11, 10, 11, 11, 11, 11, 12, 12, 8, 12, 11, 11, 12, 12, 12,
+ 12, 13, 8, 12, 11, 11, 12, 12, 12, 13, 12, 9, 14, 13, 11, 13,
+ 12, 13, 12, 13, 9, 13, 13, 12, 12, 13, 13, 13, 13, 13
+ },
+ {
+ 3, 4, 5, 6, 8, 10, 11, 11, 2, 5, 5, 6, 7, 8, 10, 11,
+ 11, 4, 5, 5, 6, 7, 9, 12, 13, 13, 4, 6, 7, 7, 9, 10,
+ 11, 13, 14, 5, 7, 7, 7, 8, 9, 11, 13, 13, 6, 8, 8, 8,
+ 8, 9, 10, 12, 13, 7, 9, 8, 8, 8, 9, 11, 12, 13, 7, 9,
+ 9, 9, 9, 9, 10, 11, 13, 8, 10, 10, 10, 10, 10, 11, 12, 13,
+ 9, 11, 11, 10, 10, 10, 11, 11, 12, 10, 12, 12, 12, 11, 11, 11,
+ 12, 12, 10, 13, 12, 12, 11, 11, 11, 12, 12, 10, 13, 13, 12, 13,
+ 11, 12, 11, 12, 10, 14, 13, 13, 12, 12, 12, 11, 11, 11
+ },
+ {
+ 4, 4, 5, 5, 6, 7, 8, 9, 2, 5, 6, 6, 6, 7, 7, 9,
+ 9, 4, 6, 6, 6, 7, 8, 9, 11, 12, 5, 7, 7, 7, 9, 9,
+ 10, 11, 12, 5, 7, 7, 7, 7, 9, 9, 10, 12, 5, 8, 8, 8,
+ 8, 8, 9, 10, 10, 6, 9, 8, 8, 8, 8, 9, 9, 11, 6, 10,
+ 10, 9, 9, 9, 9, 10, 10, 7, 11, 10, 9, 9, 10, 9, 10, 11,
+ 7, 10, 11, 10, 10, 10, 9, 10, 11, 8, 12, 11, 11, 10, 11, 11,
+ 10, 10, 8, 12, 12, 11, 11, 11, 11, 10, 11, 8, 13, 12, 12, 11,
+ 11, 11, 11, 10, 9, 13, 12, 12, 12, 11, 11, 10, 10, 10
+ },
+ {
+ 3, 4, 6, 7, 7, 9, 11, 11, 2, 5, 5, 6, 8, 9, 10, 11,
+ 13, 3, 5, 5, 7, 8, 9, 12, 14, 13, 4, 6, 6, 7, 9, 11,
+ 13, 14, 14, 5, 7, 7, 8, 9, 9, 13, 15, 13, 6, 8, 8, 8,
+ 9, 10, 12, 14, 13, 7, 10, 9, 9, 9, 9, 12, 13, 14, 7, 11,
+ 10, 10, 10, 10, 11, 12, 13, 8, 11, 12, 12, 12, 11, 12, 14, 15,
+ 9, 11, 12, 11, 12, 11, 11, 12, 13, 9, 12, 13, 13, 12, 12, 13,
+ 14, 14, 9, 12, 13, 13, 13, 12, 13, 12, 14, 10, 13, 13, 14, 13,
+ 11, 13, 14, 15, 10, 12, 13, 15, 14, 13, 13, 13, 14, 14
+ },
+ {
+ 4, 5, 5, 5, 6, 7, 8, 8, 2, 6, 6, 6, 6, 6, 8, 9,
+ 10, 4, 6, 6, 6, 6, 7, 9, 10, 11, 4, 7, 7, 7, 7, 7,
+ 9, 10, 12, 5, 7, 7, 7, 7, 7, 9, 10, 11, 6, 8, 8, 7,
+ 7, 7, 8, 9, 10, 6, 9, 8, 8, 7, 8, 10, 10, 11, 7, 9,
+ 9, 8, 8, 8, 9, 9, 10, 8, 10, 10, 9, 9, 9, 11, 11, 11,
+ 8, 11, 10, 10, 9, 9, 10, 11, 10, 10, 12, 12, 11, 11, 10, 11,
+ 12, 11, 10, 13, 12, 11, 11, 10, 10, 11, 11, 11, 15, 13, 13, 13,
+ 12, 12, 12, 12, 10, 15, 14, 13, 12, 12, 11, 11, 11, 11
+ },
+ {
+ 4, 5, 6, 6, 6, 7, 8, 8, 2, 4, 5, 6, 6, 7, 8, 8,
+ 9, 4, 6, 7, 7, 8, 8, 9, 10, 11, 5, 6, 7, 7, 8, 8,
+ 9, 10, 12, 5, 7, 8, 8, 8, 9, 10, 11, 12, 5, 7, 8, 8,
+ 8, 8, 9, 10, 11, 6, 8, 9, 8, 8, 9, 10, 11, 13, 5, 8,
+ 9, 8, 8, 9, 9, 10, 11, 6, 10, 10, 9, 9, 10, 10, 12, 13,
+ 6, 10, 10, 9, 9, 10, 10, 11, 13, 7, 11, 11, 11, 11, 11, 12,
+ 12, 13, 7, 11, 11, 11, 11, 11, 11, 12, 12, 9, 13, 13, 13, 13,
+ 12, 12, 13, 12, 9, 12, 13, 12, 12, 12, 13, 13, 12, 12
+ },
+ {
+ 3, 5, 6, 8, 9, 10, 12, 12, 1, 5, 6, 7, 8, 9, 12, 12,
+ 12, 4, 6, 7, 8, 9, 12, 12, 14, 21, 4, 6, 8, 9, 9, 12,
+ 13, 13, 14, 6, 9, 8, 8, 9, 13, 14, 13, 21, 6, 9, 9, 8,
+ 9, 10, 11, 12, 13, 8, 10, 10, 11, 11, 12, 12, 21, 21, 8, 11,
+ 10, 11, 11, 12, 13, 14, 21, 9, 13, 10, 11, 13, 13, 12, 21, 21,
+ 9, 12, 10, 11, 12, 12, 13, 14, 21, 11, 15, 21, 13, 14, 15, 21,
+ 15, 21, 10, 14, 14, 13, 13, 21, 13, 13, 21, 13, 21, 21, 21, 20,
+ 20, 14, 20, 20, 11, 14, 14, 20, 20, 13, 20, 20, 14, 16
+ },
+ {
+ 2, 5, 6, 8, 9, 10, 13, 13, 2, 4, 5, 6, 8, 9, 10, 13,
+ 14, 3, 5, 7, 8, 10, 12, 15, 20, 16, 4, 6, 8, 8, 10, 12,
+ 13, 20, 20, 7, 8, 8, 9, 10, 11, 12, 16, 20, 7, 8, 8, 8,
+ 10, 11, 13, 20, 20, 8, 10, 10, 10, 10, 11, 12, 15, 14, 8, 9,
+ 9, 9, 10, 10, 13, 13, 20, 11, 12, 11, 11, 11, 13, 12, 13, 20,
+ 11, 12, 11, 11, 12, 12, 13, 13, 20, 10, 14, 11, 11, 12, 12, 13,
+ 20, 20, 11, 13, 12, 11, 12, 13, 14, 14, 20, 11, 19, 19, 13, 13,
+ 15, 15, 16, 16, 11, 13, 14, 11, 13, 12, 13, 16, 16, 16
+ }
+};
+
+const uint8_t wmv3_dc_scale_table[32] = {
+ 0, 2, 4, 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
};
/* P-Picture CBPCY VLC tables */
-#if 1 // Looks like original tables are not conforming to standard at all. Are they used for old WMV?
+// Looks like original tables are not conforming to standard at all. Are they used for old WMV?
const uint16_t ff_vc1_cbpcy_p_codes[4][64] = {
{
0, 6, 15, 13, 13, 11, 3, 13, 5, 8, 49, 10, 12, 114, 102, 119,
@@ -330,60 +705,141 @@ const uint8_t ff_vc1_cbpcy_p_bits[4][64] = {
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8
}
};
-#else
-const uint16_t ff_vc1_cbpcy_p_codes[4][64] = {
+
+/* Interlaced CBPCY VLC tables (Table 124 - Table 131) */
+const uint16_t ff_vc1_icbpcy_p_codes[8][63] = {
{
- 0, 1, 1, 4, 5, 1, 12, 4, 13, 14, 10, 11, 12, 7, 13, 2,
- 15, 1, 96, 1, 49, 97, 2, 100, 3, 4, 5, 101, 102, 52, 53, 4,
- 6, 7, 54, 103, 8, 9, 10, 110, 11, 12, 111, 56, 114, 58, 115, 5,
- 13, 7, 8, 9, 10, 11, 12, 30, 13, 14, 15, 118, 119, 62, 63, 3
+ 0x2F1A, 0x2F1B, 0x178C, 0x0090, 0x02A8, 0x02A9, 0x0BC7, 0x0091,
+ 0x02AA, 0x02AB, 0x05E0, 0x004A, 0x0096, 0x0097, 0x00BD, 0x0092,
+ 0x02AC, 0x02AD, 0x05E1, 0x0098, 0x0132, 0x0133, 0x0179, 0x0134,
+ 0x026A, 0x026B, 0x02FC, 0x004E, 0x0040, 0x0041, 0x002B, 0x0093,
+ 0x02AE, 0x02AF, 0x05E2, 0x0136, 0x026E, 0x026F, 0x02FD, 0x009E,
+ 0x013E, 0x013F, 0x017F, 0x0050, 0x0042, 0x0043, 0x002C, 0x0051,
+ 0x00A4, 0x00A5, 0x00BE, 0x0053, 0x0044, 0x0045, 0x002D, 0x0054,
+ 0x0046, 0x0047, 0x002E, 0x0003, 0x0000, 0x0001, 0x0001
},
{
- 0, 1, 2, 1, 3, 1, 16, 17, 5, 18, 12, 19, 13, 1, 28, 58,
- 1, 1, 1, 2, 3, 2, 3, 236, 237, 4, 5, 238, 6, 7, 239, 8,
- 9, 240, 10, 11, 121, 122, 12, 13, 14, 15, 241, 246, 16, 17, 124, 63,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 247, 125
+ 0x0041, 0x0042, 0x0100, 0x0043, 0x0088, 0x0089, 0x0101, 0x0045,
+ 0x008C, 0x008D, 0x0102, 0x0010, 0x0022, 0x0023, 0x0024, 0x0047,
+ 0x0010, 0x0011, 0x0103, 0x0025, 0x0058, 0x0059, 0x005A, 0x005B,
+ 0x005A, 0x005B, 0x005C, 0x000C, 0x0030, 0x0031, 0x0019, 0x0009,
+ 0x0014, 0x0015, 0x002C, 0x005C, 0x005D, 0x005E, 0x005F, 0x0026,
+ 0x005D, 0x005E, 0x005F, 0x000D, 0x0034, 0x0035, 0x001B, 0x0014,
+ 0x0027, 0x002A, 0x002B, 0x000E, 0x0038, 0x0039, 0x001D, 0x000F,
+ 0x003C, 0x003D, 0x001F, 0x0005, 0x0009, 0x0000, 0x0003
},
{
- 0, 1, 2, 3, 2, 3, 1, 4, 5, 24, 7, 13, 16, 17, 9, 5,
- 25, 1, 1, 1, 2, 3, 96, 194, 1, 2, 98, 99, 195, 200, 101, 26,
- 201, 102, 412, 413, 414, 54, 220, 111, 221, 3, 224, 113, 225, 114, 230, 29,
- 231, 415, 240, 4, 241, 484, 5, 243, 3, 244, 245, 485, 492, 493, 247, 31
+ 0x0032, 0x0033, 0x001A, 0x0026, 0x00E4, 0x00E5, 0x01E6, 0x0027,
+ 0x00E6, 0x00E7, 0x01E7, 0x000E, 0x0063, 0x006C, 0x0077, 0x0028,
+ 0x00E8, 0x00E9, 0x01E8, 0x007B, 0x00DA, 0x00DB, 0x00EC, 0x00F5,
+ 0x01B8, 0x01B9, 0x01DA, 0x0021, 0x004B, 0x0054, 0x002B, 0x0029,
+ 0x00EA, 0x00EB, 0x01E9, 0x004A, 0x01BA, 0x01BB, 0x01DB, 0x0020,
+ 0x00DE, 0x00DF, 0x00F2, 0x0022, 0x0055, 0x0058, 0x002D, 0x000F,
+ 0x0070, 0x0071, 0x0078, 0x0023, 0x0059, 0x005C, 0x002F, 0x0024,
+ 0x005D, 0x0062, 0x0030, 0x0002, 0x001F, 0x0006, 0x0000
},
{
- 0, 1, 1, 1, 2, 2, 3, 4, 3, 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 28, 29, 30, 31
- }
+ 0x0028, 0x0029, 0x009D, 0x0000, 0x01EA, 0x01EB, 0x01EC, 0x0001,
+ 0x01ED, 0x01EE, 0x01EF, 0x0005, 0x00F0, 0x00F1, 0x003B, 0x0002,
+ 0x01F0, 0x01F1, 0x01F2, 0x003F, 0x015C, 0x015D, 0x0099, 0x0010,
+ 0x03D0, 0x03D1, 0x0130, 0x000F, 0x009E, 0x009F, 0x00FB, 0x0003,
+ 0x01F3, 0x01F4, 0x01F5, 0x0011, 0x03D2, 0x03D3, 0x0131, 0x0009,
+ 0x015E, 0x015F, 0x009C, 0x0010, 0x00A8, 0x00A9, 0x0038, 0x0006,
+ 0x00F2, 0x00F3, 0x004D, 0x0011, 0x00AA, 0x00AB, 0x0039, 0x0012,
+ 0x00AC, 0x00AD, 0x003A, 0x0006, 0x0016, 0x0017, 0x000E
+ },
+ {
+ 0x003C, 0x003D, 0x001F, 0x000A, 0x0061, 0x0062, 0x0002, 0x000B,
+ 0x0063, 0x0064, 0x0003, 0x0007, 0x0003, 0x0004, 0x000B, 0x000C,
+ 0x0065, 0x0066, 0x0004, 0x0012, 0x000A, 0x000B, 0x0014, 0x001B,
+ 0x0018, 0x0019, 0x0034, 0x002C, 0x0067, 0x0068, 0x0035, 0x000D,
+ 0x0069, 0x006C, 0x0005, 0x0060, 0x001A, 0x001B, 0x0035, 0x0013,
+ 0x000E, 0x000F, 0x0015, 0x002D, 0x006D, 0x006E, 0x0038, 0x0008,
+ 0x0008, 0x0009, 0x000C, 0x002E, 0x006F, 0x0072, 0x003A, 0x002F,
+ 0x0073, 0x0000, 0x003B, 0x0007, 0x0014, 0x0015, 0x0004
+ },
+ {
+ 0x0038, 0x0039, 0x009D, 0x000A, 0x0091, 0x0092, 0x0093, 0x000B,
+ 0x0094, 0x0095, 0x0096, 0x0003, 0x00EE, 0x00EF, 0x0036, 0x000C,
+ 0x0097, 0x0098, 0x0099, 0x0008, 0x01E4, 0x01E5, 0x006A, 0x0018,
+ 0x03CC, 0x03CD, 0x00D6, 0x000E, 0x009E, 0x009F, 0x00F5, 0x000D,
+ 0x009A, 0x009B, 0x009C, 0x0019, 0x03CE, 0x03CF, 0x00D7, 0x0009,
+ 0x01E8, 0x01E9, 0x0090, 0x000F, 0x00E8, 0x00E9, 0x00F6, 0x0005,
+ 0x00F0, 0x00F1, 0x0037, 0x0010, 0x00EA, 0x00EB, 0x00F7, 0x0011,
+ 0x00EC, 0x00ED, 0x0034, 0x0000, 0x003E, 0x003F, 0x0002
+ },
+ {
+ 0x003C, 0x003D, 0x01CF, 0x0000, 0x00BF, 0x00E0, 0x01FC, 0x0001,
+ 0x00E1, 0x00E2, 0x01FD, 0x0009, 0x01F1, 0x01F2, 0x01F3, 0x0002,
+ 0x00E3, 0x00E4, 0x01FE, 0x0011, 0x03EE, 0x03EF, 0x03F0, 0x0021,
+ 0x07E2, 0x07E3, 0x07E4, 0x0018, 0x03F7, 0x03FE, 0x03FF, 0x0003,
+ 0x00E5, 0x00E6, 0x0080, 0x002E, 0x07E5, 0x07E6, 0x07E7, 0x0016,
+ 0x03F4, 0x03F5, 0x03F6, 0x0019, 0x0102, 0x0103, 0x0104, 0x000A,
+ 0x01F4, 0x01F5, 0x01F6, 0x001A, 0x0105, 0x0106, 0x0107, 0x001B,
+ 0x0178, 0x0179, 0x01CE, 0x001D, 0x00BD, 0x00BE, 0x01F0
+ },
+ {
+ 0x0003, 0x0004, 0x01B6, 0x0004, 0x002E, 0x002F, 0x000E, 0x0005,
+ 0x0030, 0x0031, 0x000F, 0x0003, 0x000A, 0x000B, 0x0014, 0x0006,
+ 0x0032, 0x0033, 0x0010, 0x0005, 0x0030, 0x0031, 0x0032, 0x0009,
+ 0x0066, 0x0067, 0x0068, 0x001D, 0x01B7, 0x01B8, 0x01B9, 0x0007,
+ 0x0034, 0x0035, 0x0011, 0x0016, 0x0069, 0x006A, 0x006B, 0x000A,
+ 0x0036, 0x0037, 0x00D8, 0x001E, 0x01BA, 0x01BB, 0x01BC, 0x0004,
+ 0x0015, 0x0016, 0x0017, 0x001F, 0x01BD, 0x01BE, 0x01BF, 0x0000,
+ 0x0010, 0x0011, 0x0012, 0x001C, 0x00D9, 0x00DA, 0x0013
+ }
};
-const uint8_t ff_vc1_cbpcy_p_bits[4][64] = {
+
+const uint8_t ff_vc1_icbpcy_p_bits[8][63] = {
+ {
+ 15, 15, 14, 9, 11, 11, 13, 9, 11, 11, 12, 8, 9, 9, 9, 9,
+ 11, 11, 12, 9, 10, 10, 10, 10, 11, 11, 11, 8, 8, 8, 7, 9,
+ 11, 11, 12, 10, 11, 11, 11, 9, 10, 10, 10, 8, 8, 8, 7, 8,
+ 9, 9, 9, 8, 8, 8, 7, 8, 8, 8, 7, 3, 3, 3, 1
+ },
+ {
+ 7, 7, 9, 7, 8, 8, 9, 7, 8, 8, 9, 6, 7, 7, 7, 7,
+ 7, 7, 9, 7, 8, 8, 8, 8, 9, 9, 9, 6, 7, 7, 6, 6,
+ 7, 7, 8, 8, 9, 9, 9, 7, 8, 8, 8, 6, 7, 7, 6, 6,
+ 7, 7, 7, 6, 7, 7, 6, 6, 7, 7, 6, 3, 4, 3, 2
+ },
{
- 13, 6, 5, 6, 6, 7, 7, 5, 7, 7, 6, 6, 6, 5, 6, 3,
- 7, 8, 8, 13, 7, 8, 13, 8, 13, 13, 13, 8, 8, 7, 7, 3,
- 13, 13, 7, 8, 13, 13, 13, 8, 13, 13, 8, 7, 8, 7, 8, 3,
- 13, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 8, 8, 7, 7, 2
+ 6, 6, 5, 6, 8, 8, 9, 6, 8, 8, 9, 5, 7, 7, 7, 6,
+ 8, 8, 9, 7, 8, 8, 8, 8, 9, 9, 9, 6, 7, 7, 6, 6,
+ 8, 8, 9, 7, 9, 9, 9, 6, 8, 8, 8, 6, 7, 7, 6, 5,
+ 7, 7, 7, 6, 7, 7, 6, 6, 7, 7, 6, 3, 5, 4, 2
},
{
- 14, 3, 3, 5, 3, 4, 5, 5, 3, 5, 4, 5, 4, 6, 5, 6,
- 8, 14, 13, 8, 8, 13, 13, 8, 8, 13, 13, 8, 13, 13, 8, 13,
- 13, 8, 13, 13, 7, 7, 13, 13, 13, 13, 8, 8, 13, 13, 7, 6,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 7
+ 6, 6, 8, 4, 9, 9, 9, 4, 9, 9, 9, 4, 8, 8, 7, 4,
+ 9, 9, 9, 6, 9, 9, 8, 6, 10, 10, 9, 5, 8, 8, 8, 4,
+ 9, 9, 9, 6, 10, 10, 9, 5, 9, 9, 8, 5, 8, 8, 7, 4,
+ 8, 8, 7, 5, 8, 8, 7, 5, 8, 8, 7, 3, 5, 5, 4
},
{
- 13, 5, 5, 5, 4, 4, 6, 4, 4, 6, 4, 5, 5, 5, 4, 3,
- 6, 8, 10, 9, 8, 8, 7, 8, 13, 13, 7, 7, 8, 8, 7, 5,
- 8, 7, 9, 9, 9, 6, 8, 7, 8, 13, 8, 7, 8, 7, 8, 5,
- 8, 9, 8, 13, 8, 9, 13, 8, 12, 8, 8, 9, 9, 9, 8, 5
+ 6, 6, 5, 5, 7, 7, 7, 5, 7, 7, 7, 5, 6, 6, 6, 5,
+ 7, 7, 7, 6, 7, 7, 7, 7, 8, 8, 8, 6, 7, 7, 6, 5,
+ 7, 7, 7, 7, 8, 8, 8, 6, 7, 7, 7, 6, 7, 7, 6, 5,
+ 6, 6, 6, 6, 7, 7, 6, 6, 7, 6, 6, 4, 5, 5, 3
},
{
- 9, 2, 3, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8
+ 6, 6, 8, 4, 8, 8, 8, 4, 8, 8, 8, 4, 8, 8, 7, 4,
+ 8, 8, 8, 5, 9, 9, 8, 6, 10, 10, 9, 5, 8, 8, 8, 4,
+ 8, 8, 8, 6, 10, 10, 9, 5, 9, 9, 8, 5, 8, 8, 8, 4,
+ 8, 8, 7, 5, 8, 8, 8, 5, 8, 8, 7, 3, 6, 6, 4
+ },
+ {
+ 6, 6, 9, 3, 8, 8, 9, 3, 8, 8, 9, 4, 9, 9, 9, 3,
+ 8, 8, 9, 5, 10, 10, 10, 6, 11, 11, 11, 5, 10, 10, 10, 3,
+ 8, 8, 8, 6, 11, 11, 11, 5, 10, 10, 10, 5, 9, 9, 9, 4,
+ 9, 9, 9, 5, 9, 9, 9, 5, 9, 9, 9, 5, 8, 8, 9
+ },
+ {
+ 6, 6, 10, 3, 7, 7, 7, 3, 7, 7, 7, 4, 8, 8, 8, 3,
+ 7, 7, 7, 5, 9, 9, 9, 6, 10, 10, 10, 6, 10, 10, 10, 3,
+ 7, 7, 7, 6, 10, 10, 10, 5, 9, 9, 9, 6, 10, 10, 10, 4,
+ 8, 8, 8, 6, 10, 10, 10, 5, 9, 9, 9, 6, 9, 9, 9
}
};
-#endif
/* MacroBlock Transform Type: 7.1.3.11, p89
* 8x8:B
@@ -455,26 +911,26 @@ const uint8_t ff_vc1_ttmb_bits[3][16] = {
/* TTBLK (Transform Type per Block) tables */
const uint8_t ff_vc1_ttblk_codes[3][8] = {
- { 0, 1, 3, 5, 16, 17, 18, 19},
- { 3, 0, 1, 2, 3, 5, 8, 9},
- { 1, 0, 1, 4, 6, 7, 10, 11}
+ { 0, 1, 3, 5, 16, 17, 18, 19 },
+ { 3, 0, 1, 2, 3, 5, 8, 9 },
+ { 1, 0, 1, 4, 6, 7, 10, 11 }
};
const uint8_t ff_vc1_ttblk_bits[3][8] = {
- { 2, 2, 2, 3, 5, 5, 5, 5},
- { 2, 3, 3, 3, 3, 3, 4, 4},
- { 2, 3, 3, 3, 3, 3, 4, 4}
+ { 2, 2, 2, 3, 5, 5, 5, 5 },
+ { 2, 3, 3, 3, 3, 3, 4, 4 },
+ { 2, 3, 3, 3, 3, 3, 4, 4 }
};
/* SUBBLKPAT tables, p93-94, reordered */
const uint8_t ff_vc1_subblkpat_codes[3][15] = {
- { 14, 12, 7, 11, 9, 26, 2, 10, 27, 8, 0, 6, 1, 15, 1},
- { 14, 0, 8, 15, 10, 4, 23, 13, 5, 9, 25, 3, 24, 22, 1},
- { 5, 6, 2, 2, 8, 0, 28, 3, 1, 3, 29, 1, 19, 18, 15}
+ { 14, 12, 7, 11, 9, 26, 2, 10, 27, 8, 0, 6, 1, 15, 1 },
+ { 14, 0, 8, 15, 10, 4, 23, 13, 5, 9, 25, 3, 24, 22, 1 },
+ { 5, 6, 2, 2, 8, 0, 28, 3, 1, 3, 29, 1, 19, 18, 15 }
};
const uint8_t ff_vc1_subblkpat_bits[3][15] = {
- { 5, 5, 5, 5, 5, 6, 4, 5, 6, 5, 4, 5, 4, 5, 1},
- { 4, 3, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 2},
- { 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4}
+ { 5, 5, 5, 5, 5, 6, 4, 5, 6, 5, 4, 5, 4, 5, 1},
+ { 4, 3, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 2},
+ { 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4}
};
/* MV differential tables, p265 */
@@ -563,83 +1019,113 @@ const uint8_t ff_vc1_mv_diff_bits[4][73] = {
/* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */
/* Table 232 */
-const int8_t ff_vc1_simple_progressive_4x4_zz [16] =
-{
- 0, 8, 16, 1,
- 9, 24, 17, 2,
- 10, 18, 25, 3,
- 11, 26, 19, 27
-};
-
-const int8_t ff_vc1_adv_progressive_8x4_zz [32] = /* Table 233 */
-{
- 0, 8, 1, 16, 2, 9, 10, 3,
- 24, 17, 4, 11, 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_adv_progressive_4x8_zz [32] = /* Table 234 */
-{
- 0, 1, 8, 2,
- 9, 16, 17, 24,
- 10, 32, 25, 18,
- 40, 3, 33, 26,
- 48, 11, 56, 41,
- 34, 49, 57, 42,
- 19, 50, 27, 58,
- 35, 43, 51, 59
-};
-
-const int8_t ff_vc1_adv_interlaced_8x8_zz [64] = /* Table 235 */
-{
- 0, 8, 1, 16, 24, 9, 2, 32,
- 40, 48, 56, 17, 10, 3, 25, 18,
- 11, 4, 33, 41, 49, 57, 26, 34,
- 42, 50, 58, 19, 12, 5, 27, 20,
- 13, 6, 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_adv_interlaced_8x4_zz [32] = /* Table 236 */
-{
- 0, 8, 16, 24, 1, 9, 2, 17,
- 25, 10, 3, 18, 26, 4, 11, 19,
- 12, 5, 13, 20, 27, 6, 21, 28,
- 14, 22, 29, 7, 30, 15, 23, 31
-};
-
-const int8_t ff_vc1_adv_interlaced_4x8_zz [32] = /* Table 237 */
-{
- 0, 1, 2, 8,
- 16, 9, 24, 17,
- 10, 3, 32, 40,
- 48, 56, 25, 18,
- 33, 26, 41, 34,
- 49, 57, 11, 42,
- 19, 50, 27, 58,
- 35, 43, 51, 59
-};
-
-const int8_t ff_vc1_adv_interlaced_4x4_zz [16] = /* Table 238 */
-{
- 0, 8, 16, 24,
- 1, 9, 17, 2,
- 25, 10, 18, 3,
- 26, 11, 19, 27
+const int8_t ff_vc1_simple_progressive_4x4_zz [16] = {
+ 0, 8, 16, 1,
+ 9, 24, 17, 2,
+ 10, 18, 25, 3,
+ 11, 26, 19, 27
+};
+
+const int8_t ff_vc1_adv_progressive_8x4_zz [32] = { /* Table 233 */
+ 0, 8, 1, 16, 2, 9, 10, 3,
+ 24, 17, 4, 11, 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_adv_progressive_4x8_zz [32] = { /* Table 234 */
+ 0, 1, 8, 2,
+ 9, 16, 17, 24,
+ 10, 32, 25, 18,
+ 40, 3, 33, 26,
+ 48, 11, 56, 41,
+ 34, 49, 57, 42,
+ 19, 50, 27, 58,
+ 35, 43, 51, 59
+};
+
+const int8_t ff_vc1_adv_interlaced_8x8_zz [64] = { /* Table 235 */
+ 0, 8, 1, 16, 24, 9, 2, 32,
+ 40, 48, 56, 17, 10, 3, 25, 18,
+ 11, 4, 33, 41, 49, 57, 26, 34,
+ 42, 50, 58, 19, 12, 5, 27, 20,
+ 13, 6, 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_adv_interlaced_8x4_zz [32] = { /* Table 236 */
+ 0, 8, 16, 24, 1, 9, 2, 17,
+ 25, 10, 3, 18, 26, 4, 11, 19,
+ 12, 5, 13, 20, 27, 6, 21, 28,
+ 14, 22, 29, 7, 30, 15, 23, 31
+};
+
+const int8_t ff_vc1_adv_interlaced_4x8_zz [32] = { /* Table 237 */
+ 0, 1, 2, 8,
+ 16, 9, 24, 17,
+ 10, 3, 32, 40,
+ 48, 56, 25, 18,
+ 33, 26, 41, 34,
+ 49, 57, 11, 42,
+ 19, 50, 27, 58,
+ 35, 43, 51, 59
+};
+
+const int8_t ff_vc1_adv_interlaced_4x4_zz [16] = { /* Table 238 */
+ 0, 8, 16, 24,
+ 1, 9, 17, 2,
+ 25, 10, 18, 3,
+ 26, 11, 19, 27
};
/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */
const int32_t ff_vc1_dqscale[63] = {
-0x40000, 0x20000, 0x15555, 0x10000, 0xCCCD, 0xAAAB, 0x9249, 0x8000,
- 0x71C7, 0x6666, 0x5D17, 0x5555, 0x4EC5, 0x4925, 0x4444, 0x4000,
- 0x3C3C, 0x38E4, 0x35E5, 0x3333, 0x30C3, 0x2E8C, 0x2C86, 0x2AAB,
- 0x28F6, 0x2762, 0x25ED, 0x2492, 0x234F, 0x2222, 0x2108, 0x2000,
- 0x1F08, 0x1E1E, 0x1D42, 0x1C72, 0x1BAD, 0x1AF3, 0x1A42, 0x199A,
- 0x18FA, 0x1862, 0x17D0, 0x1746, 0x16C1, 0x1643, 0x15CA, 0x1555,
- 0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249,
- 0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1000
+ 0x40000, 0x20000, 0x15555, 0x10000, 0xCCCD, 0xAAAB, 0x9249, 0x8000,
+ 0x71C7, 0x6666, 0x5D17, 0x5555, 0x4EC5, 0x4925, 0x4444, 0x4000,
+ 0x3C3C, 0x38E4, 0x35E5, 0x3333, 0x30C3, 0x2E8C, 0x2C86, 0x2AAB,
+ 0x28F6, 0x2762, 0x25ED, 0x2492, 0x234F, 0x2222, 0x2108, 0x2000,
+ 0x1F08, 0x1E1E, 0x1D42, 0x1C72, 0x1BAD, 0x1AF3, 0x1A42, 0x199A,
+ 0x18FA, 0x1862, 0x17D0, 0x1746, 0x16C1, 0x1643, 0x15CA, 0x1555,
+ 0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249,
+ 0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1000
+};
+
+/* P Interlaced field picture MV predictor scaling values (Table 114) */
+const uint16_t vc1_field_mvpred_scales[2][7][4] = {
+// Refdist:
+// 0 1 2 3 or greater
+ { // current field is first
+ { 128, 192, 213, 224 }, // SCALEOPP
+ { 512, 341, 307, 293 }, // SCALESAME1
+ { 219, 236, 242, 245 }, // SCALESAME2
+ { 32, 48, 53, 56 }, // SCALEZONE1_X
+ { 8, 12, 13, 14 }, // SCALEZONE1_Y
+ { 37, 20, 14, 11 }, // ZONE1OFFSET_X
+ { 10, 5, 4, 3 } // ZONE1OFFSET_Y
+ },
+ { // current field is second
+ { 128, 64, 43, 32 }, // SCALEOPP
+ { 512, 1024, 1536, 2048 }, // SCALESAME1
+ { 219, 204, 200, 198 }, // SCALESAME2
+ { 32, 16, 11, 8 }, // SCALEZONE1_X
+ { 8, 4, 3, 2 }, // SCALEZONE1_Y
+ { 37, 52, 56, 58 }, // ZONE1OFFSET_X
+ { 10, 13, 14, 15 } // ZONE1OFFSET_Y
+ }
+};
+
+/* B Interlaced field picture backward MV predictor scaling values for first field (Table 115) */
+const uint16_t vc1_b_field_mvpred_scales[7][4] = {
+ // BRFD:
+ // 0 1 2 3 or greater
+ { 171, 205, 219, 228 }, // SCALESAME
+ { 384, 320, 299, 288 }, // SCALEOPP1
+ { 230, 239, 244, 246 }, // SCALEOPP2
+ { 43, 51, 55, 57 }, // SCALEZONE1_X
+ { 11, 13, 14, 14 }, // SCALEZONE1_Y
+ { 26, 17, 12, 10 }, // ZONE1OFFSET_X
+ { 7, 4, 3, 3 } // ZONE1OFFSET_Y
};
diff --git a/libavcodec/vc1data.h b/libavcodec/vc1data.h
index 1ccc9bb..da8f0a1 100644
--- a/libavcodec/vc1data.h
+++ b/libavcodec/vc1data.h
@@ -44,6 +44,9 @@ extern const uint8_t ff_vc1_mv_pmode_table2[2][4];
extern const int ff_vc1_fps_nr[5], ff_vc1_fps_dr[2];
extern const uint8_t ff_vc1_pquant_table[3][32];
+/* MBMODE table for interlaced frame P-picture */
+extern const uint8_t ff_vc1_mbmode_intfrp[2][15][4];
+
/** @name VC-1 VLC tables and defines
* @todo TODO move this into the context
*/
@@ -63,31 +66,40 @@ extern VLC ff_vc1_ttmb_vlc[3];
extern VLC ff_vc1_mv_diff_vlc[4];
#define VC1_CBPCY_P_VLC_BITS 9 //14
extern VLC ff_vc1_cbpcy_p_vlc[4];
+#define VC1_ICBPCY_VLC_BITS 9
+extern VLC ff_vc1_icbpcy_vlc[8];
#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6
extern VLC ff_vc1_4mv_block_pattern_vlc[4];
+#define VC1_2MV_BLOCK_PATTERN_VLC_BITS 3
+extern VLC ff_vc1_2mv_block_pattern_vlc[4];
#define VC1_TTBLK_VLC_BITS 5
extern VLC ff_vc1_ttblk_vlc[3];
#define VC1_SUBBLKPAT_VLC_BITS 6
extern VLC ff_vc1_subblkpat_vlc[3];
+#define VC1_INTFR_4MV_MBMODE_VLC_BITS 9
+extern VLC ff_vc1_intfr_4mv_mbmode_vlc[4];
+#define VC1_INTFR_NON4MV_MBMODE_VLC_BITS 6
+extern VLC ff_vc1_intfr_non4mv_mbmode_vlc[4];
+#define VC1_IF_MMV_MBMODE_VLC_BITS 5
+extern VLC ff_vc1_if_mmv_mbmode_vlc[8];
+#define VC1_IF_1MV_MBMODE_VLC_BITS 5
+extern VLC ff_vc1_if_1mv_mbmode_vlc[8];
+#define VC1_1REF_MVDATA_VLC_BITS 9
+extern VLC ff_vc1_1ref_mvdata_vlc[4];
+#define VC1_2REF_MVDATA_VLC_BITS 9
+extern VLC ff_vc1_2ref_mvdata_vlc[8];
extern VLC ff_vc1_ac_coeff_table[8];
+
+#define VC1_IF_MBMODE_VLC_BITS 5
//@}
-#if 0 //original bfraction from vc9data.h, not conforming to standard
-/* Denominator used for ff_vc1_bfraction_lut */
-#define B_FRACTION_DEN 840
-
-/* bfraction is fractional, we scale to the GCD 3*5*7*8 = 840 */
-extern const int16_t ff_vc1_bfraction_lut[23];
-#else
/* Denominator used for ff_vc1_bfraction_lut */
#define B_FRACTION_DEN 256
/* pre-computed scales for all bfractions and base=256 */
extern const int16_t ff_vc1_bfraction_lut[23];
-#endif
-
extern const uint8_t ff_vc1_bfraction_bits[23];
extern const uint8_t ff_vc1_bfraction_codes[23];
@@ -110,12 +122,20 @@ extern const uint8_t ff_vc1_norm6_spec[64][5];
extern const uint8_t ff_vc1_4mv_block_pattern_codes[4][16];
extern const uint8_t ff_vc1_4mv_block_pattern_bits[4][16];
+/* 2MV Block pattern VLC tables */
+extern const uint8_t ff_vc1_2mv_block_pattern_codes[4][4];
+extern const uint8_t ff_vc1_2mv_block_pattern_bits[4][4];
+
extern const uint8_t wmv3_dc_scale_table[32];
/* P-Picture CBPCY VLC tables */
extern const uint16_t ff_vc1_cbpcy_p_codes[4][64];
extern const uint8_t ff_vc1_cbpcy_p_bits[4][64];
+/* Interlaced CBPCY VLC tables (Table 124 - Table 131) */
+extern const uint16_t ff_vc1_icbpcy_p_codes[8][63];
+extern const uint8_t ff_vc1_icbpcy_p_bits[8][63];
+
/* MacroBlock Transform Type: 7.1.3.11, p89
* 8x8:B
* 8x4:B:btm 8x4:B:top 8x4:B:both,
@@ -140,6 +160,26 @@ extern const uint8_t ff_vc1_subblkpat_bits[3][15];
extern const uint16_t ff_vc1_mv_diff_codes[4][73];
extern const uint8_t ff_vc1_mv_diff_bits[4][73];
+/* Interlaced frame picture MBMODE VLC tables (p. 246, p. 360) */
+extern const uint16_t ff_vc1_intfr_4mv_mbmode_codes[4][15];
+extern const uint8_t ff_vc1_intfr_4mv_mbmode_bits[4][15];
+extern const uint8_t ff_vc1_intfr_non4mv_mbmode_codes[4][9];
+extern const uint8_t ff_vc1_intfr_non4mv_mbmode_bits[4][9];
+
+/* Interlaced field picture MBMODE VLC tables (p. 356 - 11.4.1, 11.4.2) */
+extern const uint8_t ff_vc1_if_mmv_mbmode_codes[8][8];
+extern const uint8_t ff_vc1_if_mmv_mbmode_bits[8][8];
+extern const uint8_t ff_vc1_if_1mv_mbmode_codes[8][6];
+extern const uint8_t ff_vc1_if_1mv_mbmode_bits[8][6];
+
+/* Interlaced frame/field picture MVDATA VLC tables */
+/* 1-reference tables */
+extern const uint32_t ff_vc1_1ref_mvdata_codes[4][72];
+extern const uint8_t ff_vc1_1ref_mvdata_bits[4][72];
+/* 2-reference tables */
+extern const uint32_t ff_vc1_2ref_mvdata_codes[8][126];
+extern const uint8_t ff_vc1_2ref_mvdata_bits[8][126];
+
/* 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) */
@@ -150,8 +190,14 @@ extern const int8_t ff_vc1_adv_interlaced_8x8_zz [64];
extern const int8_t ff_vc1_adv_interlaced_8x4_zz [32];
extern const int8_t ff_vc1_adv_interlaced_4x8_zz [32];
extern const int8_t ff_vc1_adv_interlaced_4x4_zz [16];
+extern const int8_t ff_vc1_intra_horz_8x8_zz [64];
+extern const int8_t ff_vc1_intra_vert_8x8_zz [64];
/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */
extern const int32_t ff_vc1_dqscale[63];
+/* P Interlaced field picture MV predictor scaling values (Table 114) */
+extern const uint16_t vc1_field_mvpred_scales[2][7][4];
+/* B Interlaced field picture backward MV predictor scaling values for first field (Table 115) */
+extern const uint16_t vc1_b_field_mvpred_scales[7][4];
#endif /* AVCODEC_VC1DATA_H */
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index c87558b..3cb7661 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -1,5 +1,6 @@
/*
* VC-1 and WMV3 decoder
+ * Copyright (c) 2011 Mashiat Sarker Shakkhar
* Copyright (c) 2006-2007 Konstantin Shishkov
* Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
*
@@ -23,8 +24,8 @@
/**
* @file
* VC-1 and WMV3 decoder
- *
*/
+
#include "internal.h"
#include "dsputil.h"
#include "avcodec.h"
@@ -45,15 +46,22 @@
#define MB_INTRA_VLC_BITS 9
#define DC_VLC_BITS 9
#define AC_VLC_BITS 9
-static const uint16_t table_mb_intra[64][2];
static const uint16_t vlc_offs[] = {
- 0, 520, 552, 616, 1128, 1160, 1224, 1740, 1772, 1836, 1900, 2436,
- 2986, 3050, 3610, 4154, 4218, 4746, 5326, 5390, 5902, 6554, 7658, 8620,
- 9262, 10202, 10756, 11310, 12228, 15078
+ 0, 520, 552, 616, 1128, 1160, 1224, 1740, 1772, 1836, 1900, 2436,
+ 2986, 3050, 3610, 4154, 4218, 4746, 5326, 5390, 5902, 6554, 7658, 8342,
+ 9304, 9988, 10630, 11234, 12174, 13006, 13560, 14232, 14786, 15432, 16350, 17522,
+ 20372, 21818, 22330, 22394, 23166, 23678, 23742, 24820, 25332, 25396, 26460, 26980,
+ 27048, 27592, 27600, 27608, 27616, 27624, 28224, 28258, 28290, 28802, 28834, 28866,
+ 29378, 29412, 29444, 29960, 29994, 30026, 30538, 30572, 30604, 31120, 31154, 31186,
+ 31714, 31746, 31778, 32306, 32340, 32372
};
+// offset tables for interlaced picture MVDATA decoding
+static const int offset_table1[9] = { 0, 1, 2, 4, 8, 16, 32, 64, 128 };
+static const int offset_table2[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
+
/**
* Init VC-1 specific tables and VC1Context members
* @param v The VC1Context to initialize
@@ -63,73 +71,123 @@ static int vc1_init_common(VC1Context *v)
{
static int done = 0;
int i = 0;
- static VLC_TYPE vlc_table[15078][2];
+ static VLC_TYPE vlc_table[32372][2];
v->hrd_rate = v->hrd_buffer = NULL;
/* VLC tables */
- if(!done)
- {
+ if (!done) {
INIT_VLC_STATIC(&ff_vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23,
- ff_vc1_bfraction_bits, 1, 1,
- ff_vc1_bfraction_codes, 1, 1, 1 << VC1_BFRACTION_VLC_BITS);
+ ff_vc1_bfraction_bits, 1, 1,
+ ff_vc1_bfraction_codes, 1, 1, 1 << VC1_BFRACTION_VLC_BITS);
INIT_VLC_STATIC(&ff_vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4,
- ff_vc1_norm2_bits, 1, 1,
- ff_vc1_norm2_codes, 1, 1, 1 << VC1_NORM2_VLC_BITS);
+ ff_vc1_norm2_bits, 1, 1,
+ ff_vc1_norm2_codes, 1, 1, 1 << VC1_NORM2_VLC_BITS);
INIT_VLC_STATIC(&ff_vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64,
- ff_vc1_norm6_bits, 1, 1,
- ff_vc1_norm6_codes, 2, 2, 556);
+ ff_vc1_norm6_bits, 1, 1,
+ ff_vc1_norm6_codes, 2, 2, 556);
INIT_VLC_STATIC(&ff_vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7,
- ff_vc1_imode_bits, 1, 1,
- ff_vc1_imode_codes, 1, 1, 1 << VC1_IMODE_VLC_BITS);
- for (i=0; i<3; i++)
- {
- ff_vc1_ttmb_vlc[i].table = &vlc_table[vlc_offs[i*3+0]];
- ff_vc1_ttmb_vlc[i].table_allocated = vlc_offs[i*3+1] - vlc_offs[i*3+0];
+ ff_vc1_imode_bits, 1, 1,
+ ff_vc1_imode_codes, 1, 1, 1 << VC1_IMODE_VLC_BITS);
+ for (i = 0; i < 3; i++) {
+ ff_vc1_ttmb_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 0]];
+ ff_vc1_ttmb_vlc[i].table_allocated = vlc_offs[i * 3 + 1] - vlc_offs[i * 3 + 0];
init_vlc(&ff_vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16,
ff_vc1_ttmb_bits[i], 1, 1,
ff_vc1_ttmb_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
- ff_vc1_ttblk_vlc[i].table = &vlc_table[vlc_offs[i*3+1]];
- ff_vc1_ttblk_vlc[i].table_allocated = vlc_offs[i*3+2] - vlc_offs[i*3+1];
+ ff_vc1_ttblk_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 1]];
+ ff_vc1_ttblk_vlc[i].table_allocated = vlc_offs[i * 3 + 2] - vlc_offs[i * 3 + 1];
init_vlc(&ff_vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8,
ff_vc1_ttblk_bits[i], 1, 1,
ff_vc1_ttblk_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
- ff_vc1_subblkpat_vlc[i].table = &vlc_table[vlc_offs[i*3+2]];
- ff_vc1_subblkpat_vlc[i].table_allocated = vlc_offs[i*3+3] - vlc_offs[i*3+2];
+ ff_vc1_subblkpat_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 2]];
+ ff_vc1_subblkpat_vlc[i].table_allocated = vlc_offs[i * 3 + 3] - vlc_offs[i * 3 + 2];
init_vlc(&ff_vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15,
ff_vc1_subblkpat_bits[i], 1, 1,
ff_vc1_subblkpat_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
}
- for(i=0; i<4; i++)
- {
- ff_vc1_4mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i*3+9]];
- ff_vc1_4mv_block_pattern_vlc[i].table_allocated = vlc_offs[i*3+10] - vlc_offs[i*3+9];
+ for (i = 0; i < 4; i++) {
+ ff_vc1_4mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 9]];
+ ff_vc1_4mv_block_pattern_vlc[i].table_allocated = vlc_offs[i * 3 + 10] - vlc_offs[i * 3 + 9];
init_vlc(&ff_vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16,
ff_vc1_4mv_block_pattern_bits[i], 1, 1,
ff_vc1_4mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
- ff_vc1_cbpcy_p_vlc[i].table = &vlc_table[vlc_offs[i*3+10]];
- ff_vc1_cbpcy_p_vlc[i].table_allocated = vlc_offs[i*3+11] - vlc_offs[i*3+10];
+ ff_vc1_cbpcy_p_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 10]];
+ ff_vc1_cbpcy_p_vlc[i].table_allocated = vlc_offs[i * 3 + 11] - vlc_offs[i * 3 + 10];
init_vlc(&ff_vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64,
ff_vc1_cbpcy_p_bits[i], 1, 1,
ff_vc1_cbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
- ff_vc1_mv_diff_vlc[i].table = &vlc_table[vlc_offs[i*3+11]];
- ff_vc1_mv_diff_vlc[i].table_allocated = vlc_offs[i*3+12] - vlc_offs[i*3+11];
+ ff_vc1_mv_diff_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 11]];
+ ff_vc1_mv_diff_vlc[i].table_allocated = vlc_offs[i * 3 + 12] - vlc_offs[i * 3 + 11];
init_vlc(&ff_vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73,
ff_vc1_mv_diff_bits[i], 1, 1,
ff_vc1_mv_diff_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
}
- for(i=0; i<8; i++){
- ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i+21]];
- ff_vc1_ac_coeff_table[i].table_allocated = vlc_offs[i+22] - vlc_offs[i+21];
+ for (i = 0; i < 8; i++) {
+ ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i * 2 + 21]];
+ ff_vc1_ac_coeff_table[i].table_allocated = vlc_offs[i * 2 + 22] - vlc_offs[i * 2 + 21];
init_vlc(&ff_vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i],
&vc1_ac_tables[i][0][1], 8, 4,
&vc1_ac_tables[i][0][0], 8, 4, INIT_VLC_USE_NEW_STATIC);
+ /* initialize interlaced MVDATA tables (2-Ref) */
+ ff_vc1_2ref_mvdata_vlc[i].table = &vlc_table[vlc_offs[i * 2 + 22]];
+ ff_vc1_2ref_mvdata_vlc[i].table_allocated = vlc_offs[i * 2 + 23] - vlc_offs[i * 2 + 22];
+ init_vlc(&ff_vc1_2ref_mvdata_vlc[i], VC1_2REF_MVDATA_VLC_BITS, 126,
+ ff_vc1_2ref_mvdata_bits[i], 1, 1,
+ ff_vc1_2ref_mvdata_codes[i], 4, 4, INIT_VLC_USE_NEW_STATIC);
+ }
+ for (i = 0; i < 4; i++) {
+ /* initialize 4MV MBMODE VLC tables for interlaced frame P picture */
+ ff_vc1_intfr_4mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 37]];
+ ff_vc1_intfr_4mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 38] - vlc_offs[i * 3 + 37];
+ init_vlc(&ff_vc1_intfr_4mv_mbmode_vlc[i], VC1_INTFR_4MV_MBMODE_VLC_BITS, 15,
+ ff_vc1_intfr_4mv_mbmode_bits[i], 1, 1,
+ ff_vc1_intfr_4mv_mbmode_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
+ /* initialize NON-4MV MBMODE VLC tables for the same */
+ ff_vc1_intfr_non4mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 38]];
+ ff_vc1_intfr_non4mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 39] - vlc_offs[i * 3 + 38];
+ init_vlc(&ff_vc1_intfr_non4mv_mbmode_vlc[i], VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 9,
+ ff_vc1_intfr_non4mv_mbmode_bits[i], 1, 1,
+ ff_vc1_intfr_non4mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
+ /* initialize interlaced MVDATA tables (1-Ref) */
+ ff_vc1_1ref_mvdata_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 39]];
+ ff_vc1_1ref_mvdata_vlc[i].table_allocated = vlc_offs[i * 3 + 40] - vlc_offs[i * 3 + 39];
+ init_vlc(&ff_vc1_1ref_mvdata_vlc[i], VC1_1REF_MVDATA_VLC_BITS, 72,
+ ff_vc1_1ref_mvdata_bits[i], 1, 1,
+ ff_vc1_1ref_mvdata_codes[i], 4, 4, INIT_VLC_USE_NEW_STATIC);
+ }
+ for (i = 0; i < 4; i++) {
+ /* Initialize 2MV Block pattern VLC tables */
+ ff_vc1_2mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i + 49]];
+ ff_vc1_2mv_block_pattern_vlc[i].table_allocated = vlc_offs[i + 50] - vlc_offs[i + 49];
+ init_vlc(&ff_vc1_2mv_block_pattern_vlc[i], VC1_2MV_BLOCK_PATTERN_VLC_BITS, 4,
+ ff_vc1_2mv_block_pattern_bits[i], 1, 1,
+ ff_vc1_2mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
+ }
+ for (i = 0; i < 8; i++) {
+ /* Initialize interlaced CBPCY VLC tables (Table 124 - Table 131) */
+ ff_vc1_icbpcy_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 53]];
+ ff_vc1_icbpcy_vlc[i].table_allocated = vlc_offs[i * 3 + 54] - vlc_offs[i * 3 + 53];
+ init_vlc(&ff_vc1_icbpcy_vlc[i], VC1_ICBPCY_VLC_BITS, 63,
+ ff_vc1_icbpcy_p_bits[i], 1, 1,
+ ff_vc1_icbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
+ /* Initialize interlaced field picture MBMODE VLC tables */
+ ff_vc1_if_mmv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 54]];
+ ff_vc1_if_mmv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 55] - vlc_offs[i * 3 + 54];
+ init_vlc(&ff_vc1_if_mmv_mbmode_vlc[i], VC1_IF_MMV_MBMODE_VLC_BITS, 8,
+ ff_vc1_if_mmv_mbmode_bits[i], 1, 1,
+ ff_vc1_if_mmv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
+ ff_vc1_if_1mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 55]];
+ ff_vc1_if_1mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 56] - vlc_offs[i * 3 + 55];
+ init_vlc(&ff_vc1_if_1mv_mbmode_vlc[i], VC1_IF_1MV_MBMODE_VLC_BITS, 6,
+ ff_vc1_if_1mv_mbmode_bits[i], 1, 1,
+ ff_vc1_if_1mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
}
done = 1;
}
/* Other defaults */
- v->pq = -1;
+ v->pq = -1;
v->mvrange = 0; /* 7.1.1.18, p80 */
return 0;
@@ -163,6 +221,9 @@ enum Imode {
static void vc1_put_signed_blocks_clamped(VC1Context *v)
{
MpegEncContext *s = &v->s;
+ int topleft_mb_pos, top_mb_pos;
+ int stride_y, fieldtx;
+ int v_dist;
/* The put pixels loop is always one MB row behind the decoding loop,
* because we can only put pixels when overlap filtering is done, and
@@ -173,18 +234,22 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v)
* of the right MB edge, we need the next MB present. */
if (!s->first_slice_line) {
if (s->mb_x) {
+ topleft_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x - 1;
+ fieldtx = v->fieldtx_plane[topleft_mb_pos];
+ stride_y = s->linesize << fieldtx;
+ v_dist = (16 - fieldtx) >> (fieldtx == 0);
s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][0],
s->dest[0] - 16 * s->linesize - 16,
- s->linesize);
+ stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][1],
s->dest[0] - 16 * s->linesize - 8,
- s->linesize);
+ stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][2],
- s->dest[0] - 8 * s->linesize - 16,
- s->linesize);
+ s->dest[0] - v_dist * s->linesize - 16,
+ stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][3],
- s->dest[0] - 8 * s->linesize - 8,
- s->linesize);
+ s->dest[0] - v_dist * s->linesize - 8,
+ stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][4],
s->dest[1] - 8 * s->uvlinesize - 8,
s->uvlinesize);
@@ -193,18 +258,22 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v)
s->uvlinesize);
}
if (s->mb_x == s->mb_width - 1) {
+ top_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x;
+ fieldtx = v->fieldtx_plane[top_mb_pos];
+ stride_y = s->linesize << fieldtx;
+ v_dist = fieldtx ? 15 : 8;
s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][0],
s->dest[0] - 16 * s->linesize,
- s->linesize);
+ stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][1],
s->dest[0] - 16 * s->linesize + 8,
- s->linesize);
+ stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][2],
- s->dest[0] - 8 * s->linesize,
- s->linesize);
+ s->dest[0] - v_dist * s->linesize,
+ stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][3],
- s->dest[0] - 8 * s->linesize + 8,
- s->linesize);
+ s->dest[0] - v_dist * s->linesize + 8,
+ stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][4],
s->dest[1] - 8 * s->uvlinesize,
s->uvlinesize);
@@ -233,17 +302,17 @@ static void vc1_loop_filter_iblk(VC1Context *v, int pq)
if (!s->first_slice_line) {
v->vc1dsp.vc1_v_loop_filter16(s->dest[0], s->linesize, pq);
if (s->mb_x)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16*s->linesize, s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16*s->linesize+8, s->linesize, pq);
- for(j = 0; j < 2; j++){
- v->vc1dsp.vc1_v_loop_filter8(s->dest[j+1], s->uvlinesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1], s->uvlinesize, pq);
if (s->mb_x)
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j+1]-8*s->uvlinesize, s->uvlinesize, pq);
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
}
}
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] + 8*s->linesize, s->linesize, pq);
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] + 8 * s->linesize, s->linesize, pq);
- if (s->mb_y == s->end_mb_y-1) {
+ if (s->mb_y == s->end_mb_y - 1) {
if (s->mb_x) {
v->vc1dsp.vc1_h_loop_filter16(s->dest[0], s->linesize, pq);
v->vc1dsp.vc1_h_loop_filter8(s->dest[1], s->uvlinesize, pq);
@@ -268,10 +337,10 @@ static void vc1_loop_filter_iblk_delayed(VC1Context *v, int pq)
if (s->mb_x >= 2)
v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 16, s->linesize, pq);
v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 8, s->linesize, pq);
- for(j = 0; j < 2; j++) {
- v->vc1dsp.vc1_v_loop_filter8(s->dest[j+1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
if (s->mb_x >= 2) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j+1] - 16 * s->uvlinesize - 8, s->uvlinesize, pq);
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize - 8, s->uvlinesize, pq);
}
}
}
@@ -285,10 +354,10 @@ static void vc1_loop_filter_iblk_delayed(VC1Context *v, int pq)
if (s->mb_x)
v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize, s->linesize, pq);
v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize + 8, s->linesize, pq);
- for(j = 0; j < 2; j++) {
- v->vc1dsp.vc1_v_loop_filter8(s->dest[j+1] - 8 * s->uvlinesize, s->uvlinesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
if (s->mb_x >= 2) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j+1] - 16 * s->uvlinesize, s->uvlinesize, pq);
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize, s->uvlinesize, pq);
}
}
}
@@ -301,8 +370,8 @@ static void vc1_loop_filter_iblk_delayed(VC1Context *v, int pq)
v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq);
v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 8, s->linesize, pq);
if (s->mb_x >= 2) {
- for(j = 0; j < 2; j++) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j+1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
}
}
}
@@ -312,8 +381,8 @@ static void vc1_loop_filter_iblk_delayed(VC1Context *v, int pq)
v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq);
if (s->mb_x) {
- for(j = 0; j < 2; j++) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j+1] - 8 * s->uvlinesize, s->uvlinesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
}
}
}
@@ -338,14 +407,14 @@ static void vc1_smooth_overlap_filter_iblk(VC1Context *v)
* running the V overlap. Therefore, the V overlap makes us trail by one
* MB col and the H overlap filter makes us trail by one MB row. This
* is reflected in the time at which we run the put_pixels loop. */
- if(v->condover == CONDOVER_ALL || v->pq >= 9 || v->over_flags_plane[mb_pos]) {
- if(s->mb_x && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
- v->over_flags_plane[mb_pos - 1])) {
+ if (v->condover == CONDOVER_ALL || v->pq >= 9 || v->over_flags_plane[mb_pos]) {
+ if (s->mb_x && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
+ v->over_flags_plane[mb_pos - 1])) {
v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][1],
v->block[v->cur_blk_idx][0]);
v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][3],
v->block[v->cur_blk_idx][2]);
- if(!(s->flags & CODEC_FLAG_GRAY)) {
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][4],
v->block[v->cur_blk_idx][4]);
v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][5],
@@ -358,13 +427,13 @@ static void vc1_smooth_overlap_filter_iblk(VC1Context *v)
v->block[v->cur_blk_idx][3]);
if (s->mb_x == s->mb_width - 1) {
- if(!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
- v->over_flags_plane[mb_pos - s->mb_stride])) {
+ if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
+ v->over_flags_plane[mb_pos - s->mb_stride])) {
v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][2],
v->block[v->cur_blk_idx][0]);
v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][3],
v->block[v->cur_blk_idx][1]);
- if(!(s->flags & CODEC_FLAG_GRAY)) {
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][4],
v->block[v->cur_blk_idx][4]);
v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][5],
@@ -378,13 +447,13 @@ static void vc1_smooth_overlap_filter_iblk(VC1Context *v)
}
}
if (s->mb_x && (v->condover == CONDOVER_ALL || v->over_flags_plane[mb_pos - 1])) {
- if(!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
- v->over_flags_plane[mb_pos - s->mb_stride - 1])) {
+ if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
+ v->over_flags_plane[mb_pos - s->mb_stride - 1])) {
v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][2],
v->block[v->left_blk_idx][0]);
v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][3],
v->block[v->left_blk_idx][1]);
- if(!(s->flags & CODEC_FLAG_GRAY)) {
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][4],
v->block[v->left_blk_idx][4]);
v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][5],
@@ -404,371 +473,670 @@ static void vc1_smooth_overlap_filter_iblk(VC1Context *v)
static void vc1_mc_1mv(VC1Context *v, int dir)
{
MpegEncContext *s = &v->s;
- DSPContext *dsp = &v->s.dsp;
+ DSPContext *dsp = &v->s.dsp;
uint8_t *srcY, *srcU, *srcV;
int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
-
- if(!v->s.last_picture.data[0])return;
+ int off, off_uv;
+ int v_edge_pos = s->v_edge_pos >> v->field_mode;
+ if (!v->field_mode && !v->s.last_picture.f.data[0])
+ return;
mx = s->mv[dir][0][0];
my = s->mv[dir][0][1];
// store motion vectors for further use in B frames
- if(s->pict_type == AV_PICTURE_TYPE_P) {
- s->current_picture.motion_val[1][s->block_index[0]][0] = mx;
- s->current_picture.motion_val[1][s->block_index[0]][1] = my;
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = mx;
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = my;
}
+
uvmx = (mx + ((mx & 3) == 3)) >> 1;
uvmy = (my + ((my & 3) == 3)) >> 1;
v->luma_mv[s->mb_x][0] = uvmx;
v->luma_mv[s->mb_x][1] = uvmy;
- if(v->fastuvmc) {
- uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1));
- uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1));
- }
- if(!dir) {
- srcY = s->last_picture.data[0];
- srcU = s->last_picture.data[1];
- srcV = s->last_picture.data[2];
+
+ if (v->field_mode &&
+ v->cur_field_type != v->ref_field_type[dir]) {
+ my = my - 2 + 4 * v->cur_field_type;
+ uvmy = uvmy - 2 + 4 * v->cur_field_type;
+ }
+
+ // fastuvmc shall be ignored for interlaced frame picture
+ if (v->fastuvmc && (v->fcm != ILACE_FRAME)) {
+ uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
+ uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
+ }
+ if (v->field_mode) { // interlaced field picture
+ if (!dir) {
+ if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) {
+ srcY = s->current_picture.f.data[0];
+ srcU = s->current_picture.f.data[1];
+ srcV = s->current_picture.f.data[2];
+ } else {
+ srcY = s->last_picture.f.data[0];
+ srcU = s->last_picture.f.data[1];
+ srcV = s->last_picture.f.data[2];
+ }
+ } else {
+ srcY = s->next_picture.f.data[0];
+ srcU = s->next_picture.f.data[1];
+ srcV = s->next_picture.f.data[2];
+ }
} else {
- srcY = s->next_picture.data[0];
- srcU = s->next_picture.data[1];
- srcV = s->next_picture.data[2];
+ if (!dir) {
+ srcY = s->last_picture.f.data[0];
+ srcU = s->last_picture.f.data[1];
+ srcV = s->last_picture.f.data[2];
+ } else {
+ srcY = s->next_picture.f.data[0];
+ srcU = s->next_picture.f.data[1];
+ srcV = s->next_picture.f.data[2];
+ }
}
- src_x = s->mb_x * 16 + (mx >> 2);
- src_y = s->mb_y * 16 + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
- uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
+ src_x = s->mb_x * 16 + (mx >> 2);
+ src_y = s->mb_y * 16 + (my >> 2);
+ uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
+ uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
- if(v->profile != PROFILE_ADVANCED){
+ if (v->profile != PROFILE_ADVANCED) {
src_x = av_clip( src_x, -16, s->mb_width * 16);
src_y = av_clip( src_y, -16, s->mb_height * 16);
uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
- }else{
+ } else {
src_x = av_clip( src_x, -17, s->avctx->coded_width);
src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
}
- srcY += src_y * s->linesize + src_x;
+ srcY += src_y * s->linesize + src_x;
srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
+ if (v->field_mode && v->ref_field_type[dir]) {
+ srcY += s->current_picture_ptr->f.linesize[0];
+ srcU += s->current_picture_ptr->f.linesize[1];
+ srcV += s->current_picture_ptr->f.linesize[2];
+ }
+
/* for grayscale we should not try to read from unknown area */
- if(s->flags & CODEC_FLAG_GRAY) {
+ if (s->flags & CODEC_FLAG_GRAY) {
srcU = s->edge_emu_buffer + 18 * s->linesize;
srcV = s->edge_emu_buffer + 18 * s->linesize;
}
- if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
- || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel*3
- || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 16 - s->mspel*3){
- uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize;
+ if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
+ || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
+ || (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel * 3) {
+ uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
srcY -= s->mspel * (1 + s->linesize);
- s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17+s->mspel*2, 17+s->mspel*2,
- src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos);
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+ 17 + s->mspel * 2, 17 + s->mspel * 2,
+ src_x - s->mspel, src_y - s->mspel,
+ s->h_edge_pos, v_edge_pos);
srcY = s->edge_emu_buffer;
- s->dsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ s->dsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
+ s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
srcU = uvbuf;
srcV = uvbuf + 16;
/* if we deal with range reduction we need to scale source blocks */
- if(v->rangeredfrm) {
+ if (v->rangeredfrm) {
int i, j;
uint8_t *src, *src2;
src = srcY;
- for(j = 0; j < 17 + s->mspel*2; j++) {
- for(i = 0; i < 17 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128;
+ for (j = 0; j < 17 + s->mspel * 2; j++) {
+ for (i = 0; i < 17 + s->mspel * 2; i++)
+ src[i] = ((src[i] - 128) >> 1) + 128;
src += s->linesize;
}
- src = srcU; src2 = srcV;
- for(j = 0; j < 9; j++) {
- for(i = 0; i < 9; i++) {
- src[i] = ((src[i] - 128) >> 1) + 128;
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ for (i = 0; i < 9; i++) {
+ src[i] = ((src[i] - 128) >> 1) + 128;
src2[i] = ((src2[i] - 128) >> 1) + 128;
}
- src += s->uvlinesize;
+ src += s->uvlinesize;
src2 += s->uvlinesize;
}
}
/* if we deal with intensity compensation we need to scale source blocks */
- if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
int i, j;
uint8_t *src, *src2;
src = srcY;
- for(j = 0; j < 17 + s->mspel*2; j++) {
- for(i = 0; i < 17 + s->mspel*2; i++) src[i] = v->luty[src[i]];
+ for (j = 0; j < 17 + s->mspel * 2; j++) {
+ for (i = 0; i < 17 + s->mspel * 2; i++)
+ src[i] = v->luty[src[i]];
src += s->linesize;
}
- src = srcU; src2 = srcV;
- for(j = 0; j < 9; j++) {
- for(i = 0; i < 9; i++) {
- src[i] = v->lutuv[src[i]];
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ for (i = 0; i < 9; i++) {
+ src[i] = v->lutuv[src[i]];
src2[i] = v->lutuv[src2[i]];
}
- src += s->uvlinesize;
+ src += s->uvlinesize;
src2 += s->uvlinesize;
}
}
srcY += s->mspel * (1 + s->linesize);
}
- if(s->mspel) {
+ if (v->field_mode && v->cur_field_type) {
+ off = s->current_picture_ptr->f.linesize[0];
+ off_uv = s->current_picture_ptr->f.linesize[1];
+ } else {
+ off = 0;
+ off_uv = 0;
+ }
+ if (s->mspel) {
dxy = ((my & 3) << 2) | (mx & 3);
- v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] , srcY , s->linesize, v->rnd);
- v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd);
+ v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off , srcY , s->linesize, v->rnd);
+ v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd);
srcY += s->linesize * 8;
- v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize , srcY , s->linesize, v->rnd);
- v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
+ v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize , srcY , s->linesize, v->rnd);
+ v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
} else { // hpel mc - always used for luma
dxy = (my & 2) | ((mx & 2) >> 1);
-
- if(!v->rnd)
- dsp->put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
+ if (!v->rnd)
+ dsp->put_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
else
- dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
+ dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
}
- if(s->flags & CODEC_FLAG_GRAY) return;
+ if (s->flags & CODEC_FLAG_GRAY) return;
/* Chroma MC always uses qpel bilinear */
- uvmx = (uvmx&3)<<1;
- uvmy = (uvmy&3)<<1;
- if(!v->rnd){
- dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
- }else{
- v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
+ uvmx = (uvmx & 3) << 1;
+ uvmy = (uvmy & 3) << 1;
+ if (!v->rnd) {
+ dsp->put_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
+ dsp->put_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+ } else {
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+ }
+}
+
+static inline int median4(int a, int b, int c, int d)
+{
+ if (a < b) {
+ if (c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
+ else return (FFMIN(b, c) + FFMAX(a, d)) / 2;
+ } else {
+ if (c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
+ else return (FFMIN(a, c) + FFMAX(b, d)) / 2;
}
}
/** Do motion compensation for 4-MV macroblock - luminance block
*/
-static void vc1_mc_4mv_luma(VC1Context *v, int n)
+static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
{
MpegEncContext *s = &v->s;
DSPContext *dsp = &v->s.dsp;
uint8_t *srcY;
int dxy, mx, my, src_x, src_y;
int off;
+ int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
+ int v_edge_pos = s->v_edge_pos >> v->field_mode;
- if(!v->s.last_picture.data[0])return;
- mx = s->mv[0][n][0];
- my = s->mv[0][n][1];
- srcY = s->last_picture.data[0];
+ if (!v->field_mode && !v->s.last_picture.f.data[0])
+ return;
- off = s->linesize * 4 * (n&2) + (n&1) * 8;
+ mx = s->mv[dir][n][0];
+ my = s->mv[dir][n][1];
- src_x = s->mb_x * 16 + (n&1) * 8 + (mx >> 2);
- src_y = s->mb_y * 16 + (n&2) * 4 + (my >> 2);
+ if (!dir) {
+ if (v->field_mode) {
+ if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type)
+ srcY = s->current_picture.f.data[0];
+ else
+ srcY = s->last_picture.f.data[0];
+ } else
+ srcY = s->last_picture.f.data[0];
+ } else
+ srcY = s->next_picture.f.data[0];
+
+ if (v->field_mode) {
+ if (v->cur_field_type != v->ref_field_type[dir])
+ my = my - 2 + 4 * v->cur_field_type;
+ }
+
+ if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {
+ int same_count = 0, opp_count = 0, k;
+ int chosen_mv[2][4][2], f;
+ int tx, ty;
+ for (k = 0; k < 4; k++) {
+ f = v->mv_f[0][s->block_index[k] + v->blocks_off];
+ chosen_mv[f][f ? opp_count : same_count][0] = s->mv[0][k][0];
+ chosen_mv[f][f ? opp_count : same_count][1] = s->mv[0][k][1];
+ opp_count += f;
+ same_count += 1 - f;
+ }
+ f = opp_count > same_count;
+ switch (f ? opp_count : same_count) {
+ case 4:
+ tx = median4(chosen_mv[f][0][0], chosen_mv[f][1][0],
+ chosen_mv[f][2][0], chosen_mv[f][3][0]);
+ ty = median4(chosen_mv[f][0][1], chosen_mv[f][1][1],
+ chosen_mv[f][2][1], chosen_mv[f][3][1]);
+ break;
+ case 3:
+ tx = mid_pred(chosen_mv[f][0][0], chosen_mv[f][1][0], chosen_mv[f][2][0]);
+ ty = mid_pred(chosen_mv[f][0][1], chosen_mv[f][1][1], chosen_mv[f][2][1]);
+ break;
+ case 2:
+ tx = (chosen_mv[f][0][0] + chosen_mv[f][1][0]) / 2;
+ ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2;
+ break;
+ }
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
+ for (k = 0; k < 4; k++)
+ v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
+ }
+
+ if (v->fcm == ILACE_FRAME) { // not sure if needed for other types of picture
+ int qx, qy;
+ int width = s->avctx->coded_width;
+ int height = s->avctx->coded_height >> 1;
+ qx = (s->mb_x * 16) + (mx >> 2);
+ qy = (s->mb_y * 8) + (my >> 3);
+
+ if (qx < -17)
+ mx -= 4 * (qx + 17);
+ else if (qx > width)
+ mx -= 4 * (qx - width);
+ if (qy < -18)
+ my -= 8 * (qy + 18);
+ else if (qy > height + 1)
+ my -= 8 * (qy - height - 1);
+ }
+
+ if ((v->fcm == ILACE_FRAME) && fieldmv)
+ off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
+ else
+ off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
+ if (v->field_mode && v->cur_field_type)
+ off += s->current_picture_ptr->f.linesize[0];
- if(v->profile != PROFILE_ADVANCED){
- src_x = av_clip( src_x, -16, s->mb_width * 16);
- src_y = av_clip( src_y, -16, s->mb_height * 16);
- }else{
- src_x = av_clip( src_x, -17, s->avctx->coded_width);
- src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
+ src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
+ if (!fieldmv)
+ src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2);
+ else
+ src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);
+
+ if (v->profile != PROFILE_ADVANCED) {
+ src_x = av_clip(src_x, -16, s->mb_width * 16);
+ src_y = av_clip(src_y, -16, s->mb_height * 16);
+ } else {
+ src_x = av_clip(src_x, -17, s->avctx->coded_width);
+ if (v->fcm == ILACE_FRAME) {
+ if (src_y & 1)
+ src_y = av_clip(src_y, -17, s->avctx->coded_height + 1);
+ else
+ src_y = av_clip(src_y, -18, s->avctx->coded_height);
+ } else {
+ src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
+ }
}
srcY += src_y * s->linesize + src_x;
-
- if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
- || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 8 - s->mspel*2
- || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 8 - s->mspel*2){
- srcY -= s->mspel * (1 + s->linesize);
- s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 9+s->mspel*2, 9+s->mspel*2,
- src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos);
+ if (v->field_mode && v->ref_field_type[dir])
+ srcY += s->current_picture_ptr->f.linesize[0];
+
+ if (fieldmv && !(src_y & 1))
+ v_edge_pos--;
+ if (fieldmv && (src_y & 1) && src_y < 4)
+ src_y--;
+ if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
+ || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
+ || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
+ srcY -= s->mspel * (1 + (s->linesize << fieldmv));
+ /* check emulate edge stride and offset */
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+ 9 + s->mspel * 2, (9 + s->mspel * 2) << fieldmv,
+ src_x - s->mspel, src_y - (s->mspel << fieldmv),
+ s->h_edge_pos, v_edge_pos);
srcY = s->edge_emu_buffer;
/* if we deal with range reduction we need to scale source blocks */
- if(v->rangeredfrm) {
+ if (v->rangeredfrm) {
int i, j;
uint8_t *src;
src = srcY;
- for(j = 0; j < 9 + s->mspel*2; j++) {
- for(i = 0; i < 9 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128;
- src += s->linesize;
+ for (j = 0; j < 9 + s->mspel * 2; j++) {
+ for (i = 0; i < 9 + s->mspel * 2; i++)
+ src[i] = ((src[i] - 128) >> 1) + 128;
+ src += s->linesize << fieldmv;
}
}
/* if we deal with intensity compensation we need to scale source blocks */
- if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
int i, j;
uint8_t *src;
src = srcY;
- for(j = 0; j < 9 + s->mspel*2; j++) {
- for(i = 0; i < 9 + s->mspel*2; i++) src[i] = v->luty[src[i]];
- src += s->linesize;
+ for (j = 0; j < 9 + s->mspel * 2; j++) {
+ for (i = 0; i < 9 + s->mspel * 2; i++)
+ src[i] = v->luty[src[i]];
+ src += s->linesize << fieldmv;
}
}
- srcY += s->mspel * (1 + s->linesize);
+ srcY += s->mspel * (1 + (s->linesize << fieldmv));
}
- if(s->mspel) {
+ if (s->mspel) {
dxy = ((my & 3) << 2) | (mx & 3);
- v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, v->rnd);
+ v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
} else { // hpel mc - always used for luma
dxy = (my & 2) | ((mx & 2) >> 1);
- if(!v->rnd)
+ if (!v->rnd)
dsp->put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
else
dsp->put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
}
}
-static inline int median4(int a, int b, int c, int d)
+static av_always_inline int get_chroma_mv(int *mvx, int *mvy, int *a, int flag, int *tx, int *ty)
{
- if(a < b) {
- if(c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
- else return (FFMIN(b, c) + FFMAX(a, d)) / 2;
+ int idx, i;
+ static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+
+ idx = ((a[3] != flag) << 3)
+ | ((a[2] != flag) << 2)
+ | ((a[1] != flag) << 1)
+ | (a[0] != flag);
+ if (!idx) {
+ *tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]);
+ *ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]);
+ return 4;
+ } else if (count[idx] == 1) {
+ switch (idx) {
+ case 0x1:
+ *tx = mid_pred(mvx[1], mvx[2], mvx[3]);
+ *ty = mid_pred(mvy[1], mvy[2], mvy[3]);
+ return 3;
+ case 0x2:
+ *tx = mid_pred(mvx[0], mvx[2], mvx[3]);
+ *ty = mid_pred(mvy[0], mvy[2], mvy[3]);
+ return 3;
+ case 0x4:
+ *tx = mid_pred(mvx[0], mvx[1], mvx[3]);
+ *ty = mid_pred(mvy[0], mvy[1], mvy[3]);
+ return 3;
+ case 0x8:
+ *tx = mid_pred(mvx[0], mvx[1], mvx[2]);
+ *ty = mid_pred(mvy[0], mvy[1], mvy[2]);
+ return 3;
+ }
+ } else if (count[idx] == 2) {
+ int t1 = 0, t2 = 0;
+ for (i = 0; i < 3; i++)
+ if (!a[i]) {
+ t1 = i;
+ break;
+ }
+ for (i = t1 + 1; i < 4; i++)
+ if (!a[i]) {
+ t2 = i;
+ break;
+ }
+ *tx = (mvx[t1] + mvx[t2]) / 2;
+ *ty = (mvy[t1] + mvy[t2]) / 2;
+ return 2;
} else {
- if(c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
- else return (FFMIN(a, c) + FFMAX(b, d)) / 2;
+ return 0;
}
+ return -1;
}
-
/** Do motion compensation for 4-MV macroblock - both chroma blocks
*/
-static void vc1_mc_4mv_chroma(VC1Context *v)
+static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
{
MpegEncContext *s = &v->s;
- DSPContext *dsp = &v->s.dsp;
+ DSPContext *dsp = &v->s.dsp;
uint8_t *srcU, *srcV;
int uvmx, uvmy, uvsrc_x, uvsrc_y;
- int i, idx, tx = 0, ty = 0;
- int mvx[4], mvy[4], intra[4];
- static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+ int k, tx = 0, ty = 0;
+ int mvx[4], mvy[4], intra[4], mv_f[4];
+ int valid_count;
+ int chroma_ref_type = v->cur_field_type, off = 0;
+ int v_edge_pos = s->v_edge_pos >> v->field_mode;
- if(!v->s.last_picture.data[0])return;
- if(s->flags & CODEC_FLAG_GRAY) return;
+ if (!v->field_mode && !v->s.last_picture.f.data[0])
+ return;
+ if (s->flags & CODEC_FLAG_GRAY)
+ return;
- for(i = 0; i < 4; i++) {
- mvx[i] = s->mv[0][i][0];
- mvy[i] = s->mv[0][i][1];
- intra[i] = v->mb_type[0][s->block_index[i]];
+ for (k = 0; k < 4; k++) {
+ mvx[k] = s->mv[dir][k][0];
+ mvy[k] = s->mv[dir][k][1];
+ intra[k] = v->mb_type[0][s->block_index[k]];
+ if (v->field_mode)
+ mv_f[k] = v->mv_f[dir][s->block_index[k] + v->blocks_off];
}
/* calculate chroma MV vector from four luma MVs */
- idx = (intra[3] << 3) | (intra[2] << 2) | (intra[1] << 1) | intra[0];
- if(!idx) { // all blocks are inter
- tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]);
- ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]);
- } else if(count[idx] == 1) { // 3 inter blocks
- switch(idx) {
- case 0x1:
- tx = mid_pred(mvx[1], mvx[2], mvx[3]);
- ty = mid_pred(mvy[1], mvy[2], mvy[3]);
- break;
- case 0x2:
- tx = mid_pred(mvx[0], mvx[2], mvx[3]);
- ty = mid_pred(mvy[0], mvy[2], mvy[3]);
- break;
- case 0x4:
- tx = mid_pred(mvx[0], mvx[1], mvx[3]);
- ty = mid_pred(mvy[0], mvy[1], mvy[3]);
- break;
- case 0x8:
- tx = mid_pred(mvx[0], mvx[1], mvx[2]);
- ty = mid_pred(mvy[0], mvy[1], mvy[2]);
- break;
+ if (!v->field_mode || (v->field_mode && !v->numref)) {
+ valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty);
+ if (!valid_count) {
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+ v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
+ return; //no need to do MC for intra blocks
}
- } else if(count[idx] == 2) {
- int t1 = 0, t2 = 0;
- for(i=0; i<3;i++) if(!intra[i]) {t1 = i; break;}
- for(i= t1+1; i<4; i++)if(!intra[i]) {t2 = i; break;}
- tx = (mvx[t1] + mvx[t2]) / 2;
- ty = (mvy[t1] + mvy[t2]) / 2;
} else {
- s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
- s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
- v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
- return; //no need to do MC for inter blocks
- }
+ int dominant = 0;
+ if (mv_f[0] + mv_f[1] + mv_f[2] + mv_f[3] > 2)
+ dominant = 1;
+ valid_count = get_chroma_mv(mvx, mvy, mv_f, dominant, &tx, &ty);
+ if (dominant)
+ chroma_ref_type = !v->cur_field_type;
+ }
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
+ uvmx = (tx + ((tx & 3) == 3)) >> 1;
+ uvmy = (ty + ((ty & 3) == 3)) >> 1;
- s->current_picture.motion_val[1][s->block_index[0]][0] = tx;
- s->current_picture.motion_val[1][s->block_index[0]][1] = ty;
- uvmx = (tx + ((tx&3) == 3)) >> 1;
- uvmy = (ty + ((ty&3) == 3)) >> 1;
v->luma_mv[s->mb_x][0] = uvmx;
v->luma_mv[s->mb_x][1] = uvmy;
- if(v->fastuvmc) {
- uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1));
- uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1));
+
+ if (v->fastuvmc) {
+ uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
+ uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
}
+ // Field conversion bias
+ if (v->cur_field_type != chroma_ref_type)
+ uvmy += 2 - 4 * chroma_ref_type;
uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
- if(v->profile != PROFILE_ADVANCED){
- uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
- uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
- }else{
- uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
- uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+ if (v->profile != PROFILE_ADVANCED) {
+ uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
+ } else {
+ uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
}
- srcU = s->last_picture.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV = s->last_picture.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
- if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
- || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
- || (unsigned)uvsrc_y > (s->v_edge_pos >> 1) - 9){
- s->dsp.emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- s->dsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ if (!dir) {
+ if (v->field_mode) {
+ if ((v->cur_field_type != chroma_ref_type) && v->cur_field_type) {
+ srcU = s->current_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV = s->current_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ } else {
+ srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ }
+ } else {
+ srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ }
+ } else {
+ srcU = s->next_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV = s->next_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ }
+
+ if (v->field_mode) {
+ if (chroma_ref_type) {
+ srcU += s->current_picture_ptr->f.linesize[1];
+ srcV += s->current_picture_ptr->f.linesize[2];
+ }
+ off = v->cur_field_type ? s->current_picture_ptr->f.linesize[1] : 0;
+ }
+
+ if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
+ || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
+ || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) {
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize,
+ 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, v_edge_pos >> 1);
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize,
+ 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, v_edge_pos >> 1);
srcU = s->edge_emu_buffer;
srcV = s->edge_emu_buffer + 16;
/* if we deal with range reduction we need to scale source blocks */
- if(v->rangeredfrm) {
+ if (v->rangeredfrm) {
int i, j;
uint8_t *src, *src2;
- src = srcU; src2 = srcV;
- for(j = 0; j < 9; j++) {
- for(i = 0; i < 9; i++) {
- src[i] = ((src[i] - 128) >> 1) + 128;
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ for (i = 0; i < 9; i++) {
+ src[i] = ((src[i] - 128) >> 1) + 128;
src2[i] = ((src2[i] - 128) >> 1) + 128;
}
- src += s->uvlinesize;
+ src += s->uvlinesize;
src2 += s->uvlinesize;
}
}
/* if we deal with intensity compensation we need to scale source blocks */
- if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
int i, j;
uint8_t *src, *src2;
- src = srcU; src2 = srcV;
- for(j = 0; j < 9; j++) {
- for(i = 0; i < 9; i++) {
- src[i] = v->lutuv[src[i]];
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ for (i = 0; i < 9; i++) {
+ src[i] = v->lutuv[src[i]];
src2[i] = v->lutuv[src2[i]];
}
- src += s->uvlinesize;
+ src += s->uvlinesize;
src2 += s->uvlinesize;
}
}
}
/* Chroma MC always uses qpel bilinear */
- uvmx = (uvmx&3)<<1;
- uvmy = (uvmy&3)<<1;
- if(!v->rnd){
- dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
- }else{
- v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
+ uvmx = (uvmx & 3) << 1;
+ uvmy = (uvmy & 3) << 1;
+ if (!v->rnd) {
+ dsp->put_h264_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy);
+ dsp->put_h264_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy);
+ } else {
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy);
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy);
+ }
+}
+
+/** Do motion compensation for 4-MV field chroma macroblock (both U and V)
+ */
+static void vc1_mc_4mv_chroma4(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ DSPContext *dsp = &v->s.dsp;
+ uint8_t *srcU, *srcV;
+ int uvsrc_x, uvsrc_y;
+ int uvmx_field[4], uvmy_field[4];
+ int i, off, tx, ty;
+ int fieldmv = v->blk_mv_type[s->block_index[0]];
+ static const int s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
+ int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
+ int v_edge_pos = s->v_edge_pos >> 1;
+
+ if (!v->s.last_picture.f.data[0])
+ return;
+ if (s->flags & CODEC_FLAG_GRAY)
+ return;
+
+ for (i = 0; i < 4; i++) {
+ tx = s->mv[0][i][0];
+ uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
+ ty = s->mv[0][i][1];
+ if (fieldmv)
+ uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
+ else
+ uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1;
+ }
+
+ for (i = 0; i < 4; i++) {
+ off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0);
+ uvsrc_x = s->mb_x * 8 + (i & 1) * 4 + (uvmx_field[i] >> 2);
+ uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2);
+ // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
+ uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+ srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+ uvmx_field[i] = (uvmx_field[i] & 3) << 1;
+ uvmy_field[i] = (uvmy_field[i] & 3) << 1;
+
+ if (fieldmv && !(uvsrc_y & 1))
+ v_edge_pos--;
+ if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
+ uvsrc_y--;
+ if ((v->mv_mode == MV_PMODE_INTENSITY_COMP)
+ || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
+ || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize,
+ 5, (5 << fieldmv), uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, v_edge_pos);
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize,
+ 5, (5 << fieldmv), uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, v_edge_pos);
+ srcU = s->edge_emu_buffer;
+ srcV = s->edge_emu_buffer + 16;
+
+ /* if we deal with intensity compensation we need to scale source blocks */
+ if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ int i, j;
+ uint8_t *src, *src2;
+
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 5; j++) {
+ for (i = 0; i < 5; i++) {
+ src[i] = v->lutuv[src[i]];
+ src2[i] = v->lutuv[src2[i]];
+ }
+ src += s->uvlinesize << 1;
+ src2 += s->uvlinesize << 1;
+ }
+ }
+ }
+ if (!v->rnd) {
+ dsp->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ dsp->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ } else {
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ }
}
}
@@ -784,37 +1152,34 @@ static void vc1_mc_4mv_chroma(VC1Context *v)
* @brief Get macroblock-level quantizer scale
*/
#define GET_MQUANT() \
- if (v->dquantfrm) \
- { \
- int edges = 0; \
- if (v->dqprofile == DQPROFILE_ALL_MBS) \
- { \
- if (v->dqbilevel) \
- { \
- mquant = (get_bits1(gb)) ? v->altpq : v->pq; \
- } \
- else \
- { \
- mqdiff = get_bits(gb, 3); \
- if (mqdiff != 7) mquant = v->pq + mqdiff; \
- else mquant = get_bits(gb, 5); \
- } \
- } \
- if(v->dqprofile == DQPROFILE_SINGLE_EDGE) \
- edges = 1 << v->dqsbedge; \
- else if(v->dqprofile == DQPROFILE_DOUBLE_EDGES) \
- edges = (3 << v->dqsbedge) % 15; \
- else if(v->dqprofile == DQPROFILE_FOUR_EDGES) \
- edges = 15; \
- if((edges&1) && !s->mb_x) \
- mquant = v->altpq; \
- if((edges&2) && s->first_slice_line) \
- mquant = v->altpq; \
- if((edges&4) && s->mb_x == (s->mb_width - 1)) \
- mquant = v->altpq; \
- if((edges&8) && s->mb_y == (s->mb_height - 1)) \
- mquant = v->altpq; \
- }
+ if (v->dquantfrm) { \
+ int edges = 0; \
+ if (v->dqprofile == DQPROFILE_ALL_MBS) { \
+ if (v->dqbilevel) { \
+ mquant = (get_bits1(gb)) ? v->altpq : v->pq; \
+ } else { \
+ mqdiff = get_bits(gb, 3); \
+ if (mqdiff != 7) \
+ mquant = v->pq + mqdiff; \
+ else \
+ mquant = get_bits(gb, 5); \
+ } \
+ } \
+ if (v->dqprofile == DQPROFILE_SINGLE_EDGE) \
+ edges = 1 << v->dqsbedge; \
+ else if (v->dqprofile == DQPROFILE_DOUBLE_EDGES) \
+ edges = (3 << v->dqsbedge) % 15; \
+ else if (v->dqprofile == DQPROFILE_FOUR_EDGES) \
+ edges = 15; \
+ if ((edges&1) && !s->mb_x) \
+ mquant = v->altpq; \
+ if ((edges&2) && s->first_slice_line) \
+ mquant = v->altpq; \
+ if ((edges&4) && s->mb_x == (s->mb_width - 1)) \
+ mquant = v->altpq; \
+ if ((edges&8) && s->mb_y == (s->mb_height - 1)) \
+ mquant = v->altpq; \
+ }
/**
* @def GET_MVDATA(_dmv_x, _dmv_y)
@@ -823,96 +1188,346 @@ static void vc1_mc_4mv_chroma(VC1Context *v)
* @param _dmv_x Horizontal differential for decoded MV
* @param _dmv_y Vertical differential for decoded MV
*/
-#define GET_MVDATA(_dmv_x, _dmv_y) \
- index = 1 + get_vlc2(gb, ff_vc1_mv_diff_vlc[s->mv_table_index].table,\
- VC1_MV_DIFF_VLC_BITS, 2); \
- if (index > 36) \
- { \
- mb_has_coeffs = 1; \
- index -= 37; \
- } \
- else mb_has_coeffs = 0; \
- s->mb_intra = 0; \
- if (!index) { _dmv_x = _dmv_y = 0; } \
- else if (index == 35) \
- { \
- _dmv_x = get_bits(gb, v->k_x - 1 + s->quarter_sample); \
- _dmv_y = get_bits(gb, v->k_y - 1 + s->quarter_sample); \
- } \
- else if (index == 36) \
- { \
- _dmv_x = 0; \
- _dmv_y = 0; \
- s->mb_intra = 1; \
- } \
- else \
- { \
- index1 = index%6; \
- if (!s->quarter_sample && index1 == 5) val = 1; \
- else val = 0; \
- if(size_table[index1] - val > 0) \
- val = get_bits(gb, size_table[index1] - val); \
- else val = 0; \
- sign = 0 - (val&1); \
- _dmv_x = (sign ^ ((val>>1) + offset_table[index1])) - sign; \
- \
- index1 = index/6; \
- if (!s->quarter_sample && index1 == 5) val = 1; \
- else val = 0; \
- if(size_table[index1] - val > 0) \
- val = get_bits(gb, size_table[index1] - val); \
- else val = 0; \
- sign = 0 - (val&1); \
- _dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign; \
- }
+#define GET_MVDATA(_dmv_x, _dmv_y) \
+ index = 1 + get_vlc2(gb, ff_vc1_mv_diff_vlc[s->mv_table_index].table, \
+ VC1_MV_DIFF_VLC_BITS, 2); \
+ if (index > 36) { \
+ mb_has_coeffs = 1; \
+ index -= 37; \
+ } else \
+ mb_has_coeffs = 0; \
+ s->mb_intra = 0; \
+ if (!index) { \
+ _dmv_x = _dmv_y = 0; \
+ } else if (index == 35) { \
+ _dmv_x = get_bits(gb, v->k_x - 1 + s->quarter_sample); \
+ _dmv_y = get_bits(gb, v->k_y - 1 + s->quarter_sample); \
+ } else if (index == 36) { \
+ _dmv_x = 0; \
+ _dmv_y = 0; \
+ s->mb_intra = 1; \
+ } else { \
+ index1 = index % 6; \
+ if (!s->quarter_sample && index1 == 5) val = 1; \
+ else val = 0; \
+ if (size_table[index1] - val > 0) \
+ val = get_bits(gb, size_table[index1] - val); \
+ else val = 0; \
+ sign = 0 - (val&1); \
+ _dmv_x = (sign ^ ((val>>1) + offset_table[index1])) - sign; \
+ \
+ index1 = index / 6; \
+ if (!s->quarter_sample && index1 == 5) val = 1; \
+ else val = 0; \
+ if (size_table[index1] - val > 0) \
+ val = get_bits(gb, size_table[index1] - val); \
+ else val = 0; \
+ sign = 0 - (val & 1); \
+ _dmv_y = (sign ^ ((val >> 1) + offset_table[index1])) - sign; \
+ }
+
+static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x,
+ int *dmv_y, int *pred_flag)
+{
+ int index, index1;
+ int extend_x = 0, extend_y = 0;
+ GetBitContext *gb = &v->s.gb;
+ int bits, esc;
+ int val, sign;
+ const int* offs_tab;
+
+ if (v->numref) {
+ bits = VC1_2REF_MVDATA_VLC_BITS;
+ esc = 125;
+ } else {
+ bits = VC1_1REF_MVDATA_VLC_BITS;
+ esc = 71;
+ }
+ switch (v->dmvrange) {
+ case 1:
+ extend_x = 1;
+ break;
+ case 2:
+ extend_y = 1;
+ break;
+ case 3:
+ extend_x = extend_y = 1;
+ break;
+ }
+ index = get_vlc2(gb, v->imv_vlc->table, bits, 3);
+ if (index == esc) {
+ *dmv_x = get_bits(gb, v->k_x);
+ *dmv_y = get_bits(gb, v->k_y);
+ if (v->numref) {
+ *pred_flag = *dmv_y & 1;
+ *dmv_y = (*dmv_y + *pred_flag) >> 1;
+ }
+ }
+ else {
+ if (extend_x)
+ offs_tab = offset_table2;
+ else
+ offs_tab = offset_table1;
+ index1 = (index + 1) % 9;
+ if (index1 != 0) {
+ val = get_bits(gb, index1 + extend_x);
+ sign = 0 -(val & 1);
+ *dmv_x = (sign ^ ((val >> 1) + offs_tab[index1])) - sign;
+ } else
+ *dmv_x = 0;
+ if (extend_y)
+ offs_tab = offset_table2;
+ else
+ offs_tab = offset_table1;
+ index1 = (index + 1) / 9;
+ if (index1 > v->numref) {
+ val = get_bits(gb, (index1 + (extend_y << v->numref)) >> v->numref);
+ sign = 0 - (val & 1);
+ *dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign;
+ } else
+ *dmv_y = 0;
+ if (v->numref)
+ *pred_flag = index1 & 1;
+ }
+}
+
+static av_always_inline int scaleforsame_x(VC1Context *v, int n /* MV */, int dir)
+{
+ int scaledvalue, refdist;
+ int scalesame1, scalesame2;
+ int scalezone1_x, zone1offset_x;
+ int table_index = dir ^ v->second_field;
+
+ if (v->s.pict_type != AV_PICTURE_TYPE_B)
+ refdist = v->refdist;
+ else
+ refdist = dir ? v->brfd : v->frfd;
+ if (refdist > 3)
+ refdist = 3;
+ scalesame1 = vc1_field_mvpred_scales[table_index][1][refdist];
+ scalesame2 = vc1_field_mvpred_scales[table_index][2][refdist];
+ scalezone1_x = vc1_field_mvpred_scales[table_index][3][refdist];
+ zone1offset_x = vc1_field_mvpred_scales[table_index][5][refdist];
+
+ if (FFABS(n) > 255)
+ scaledvalue = n;
+ else {
+ if (FFABS(n) < scalezone1_x)
+ scaledvalue = (n * scalesame1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scalesame2) >> 8) - zone1offset_x;
+ else
+ scaledvalue = ((n * scalesame2) >> 8) + zone1offset_x;
+ }
+ }
+ return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
+}
+
+static av_always_inline int scaleforsame_y(VC1Context *v, int i, int n /* MV */, int dir)
+{
+ int scaledvalue, refdist;
+ int scalesame1, scalesame2;
+ int scalezone1_y, zone1offset_y;
+ int table_index = dir ^ v->second_field;
+
+ if (v->s.pict_type != AV_PICTURE_TYPE_B)
+ refdist = v->refdist;
+ else
+ refdist = dir ? v->brfd : v->frfd;
+ if (refdist > 3)
+ refdist = 3;
+ scalesame1 = vc1_field_mvpred_scales[table_index][1][refdist];
+ scalesame2 = vc1_field_mvpred_scales[table_index][2][refdist];
+ scalezone1_y = vc1_field_mvpred_scales[table_index][4][refdist];
+ zone1offset_y = vc1_field_mvpred_scales[table_index][6][refdist];
+
+ if (FFABS(n) > 63)
+ scaledvalue = n;
+ else {
+ if (FFABS(n) < scalezone1_y)
+ scaledvalue = (n * scalesame1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scalesame2) >> 8) - zone1offset_y;
+ else
+ scaledvalue = ((n * scalesame2) >> 8) + zone1offset_y;
+ }
+ }
+
+ if (v->cur_field_type && !v->ref_field_type[dir])
+ return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
+ else
+ return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
+}
+
+static av_always_inline int scaleforopp_x(VC1Context *v, int n /* MV */)
+{
+ int scalezone1_x, zone1offset_x;
+ int scaleopp1, scaleopp2, brfd;
+ int scaledvalue;
+
+ brfd = FFMIN(v->brfd, 3);
+ scalezone1_x = vc1_b_field_mvpred_scales[3][brfd];
+ zone1offset_x = vc1_b_field_mvpred_scales[5][brfd];
+ scaleopp1 = vc1_b_field_mvpred_scales[1][brfd];
+ scaleopp2 = vc1_b_field_mvpred_scales[2][brfd];
+
+ if (FFABS(n) > 255)
+ scaledvalue = n;
+ else {
+ if (FFABS(n) < scalezone1_x)
+ scaledvalue = (n * scaleopp1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_x;
+ else
+ scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_x;
+ }
+ }
+ return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
+}
+
+static av_always_inline int scaleforopp_y(VC1Context *v, int n /* MV */, int dir)
+{
+ int scalezone1_y, zone1offset_y;
+ int scaleopp1, scaleopp2, brfd;
+ int scaledvalue;
+
+ brfd = FFMIN(v->brfd, 3);
+ scalezone1_y = vc1_b_field_mvpred_scales[4][brfd];
+ zone1offset_y = vc1_b_field_mvpred_scales[6][brfd];
+ scaleopp1 = vc1_b_field_mvpred_scales[1][brfd];
+ scaleopp2 = vc1_b_field_mvpred_scales[2][brfd];
+
+ if (FFABS(n) > 63)
+ scaledvalue = n;
+ else {
+ if (FFABS(n) < scalezone1_y)
+ scaledvalue = (n * scaleopp1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_y;
+ else
+ scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_y;
+ }
+ }
+ if (v->cur_field_type && !v->ref_field_type[dir]) {
+ return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
+ } else {
+ return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
+ }
+}
+
+static av_always_inline int scaleforsame(VC1Context *v, int i, int n /* MV */,
+ int dim, int dir)
+{
+ int brfd, scalesame;
+ int hpel = 1 - v->s.quarter_sample;
+
+ n >>= hpel;
+ if (v->s.pict_type != AV_PICTURE_TYPE_B || v->second_field || !dir) {
+ if (dim)
+ n = scaleforsame_y(v, i, n, dir) << hpel;
+ else
+ n = scaleforsame_x(v, n, dir) << hpel;
+ return n;
+ }
+ brfd = FFMIN(v->brfd, 3);
+ scalesame = vc1_b_field_mvpred_scales[0][brfd];
+
+ n = (n * scalesame >> 8) << hpel;
+ return n;
+}
+
+static av_always_inline int scaleforopp(VC1Context *v, int n /* MV */,
+ int dim, int dir)
+{
+ int refdist, scaleopp;
+ int hpel = 1 - v->s.quarter_sample;
+
+ n >>= hpel;
+ if (v->s.pict_type == AV_PICTURE_TYPE_B && !v->second_field && dir == 1) {
+ if (dim)
+ n = scaleforopp_y(v, n, dir) << hpel;
+ else
+ n = scaleforopp_x(v, n) << hpel;
+ return n;
+ }
+ if (v->s.pict_type != AV_PICTURE_TYPE_B)
+ refdist = FFMIN(v->refdist, 3);
+ else
+ refdist = dir ? v->brfd : v->frfd;
+ scaleopp = vc1_field_mvpred_scales[dir ^ v->second_field][0][refdist];
+
+ n = (n * scaleopp >> 8) << hpel;
+ return n;
+}
/** Predict and set motion vector
*/
-static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8_t* is_intra)
+static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
+ int mv1, int r_x, int r_y, uint8_t* is_intra,
+ int pred_flag, int dir)
{
MpegEncContext *s = &v->s;
int xy, wrap, off = 0;
int16_t *A, *B, *C;
int px, py;
int sum;
-
+ int mixedmv_pic, num_samefield = 0, num_oppfield = 0;
+ int opposit, a_f, b_f, c_f;
+ int16_t field_predA[2];
+ int16_t field_predB[2];
+ int16_t field_predC[2];
+ int a_valid, b_valid, c_valid;
+ int hybridmv_thresh, y_bias = 0;
+
+ if (v->mv_mode == MV_PMODE_MIXED_MV ||
+ ((v->mv_mode == MV_PMODE_INTENSITY_COMP) && (v->mv_mode2 == MV_PMODE_MIXED_MV)))
+ mixedmv_pic = 1;
+ else
+ mixedmv_pic = 0;
/* scale MV difference to be quad-pel */
dmv_x <<= 1 - s->quarter_sample;
dmv_y <<= 1 - s->quarter_sample;
wrap = s->b8_stride;
- xy = s->block_index[n];
-
- if(s->mb_intra){
- s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0;
- s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0;
- s->current_picture.motion_val[1][xy][0] = 0;
- s->current_picture.motion_val[1][xy][1] = 0;
- if(mv1) { /* duplicate motion data for 1-MV block */
- s->current_picture.motion_val[0][xy + 1][0] = 0;
- s->current_picture.motion_val[0][xy + 1][1] = 0;
- s->current_picture.motion_val[0][xy + wrap][0] = 0;
- s->current_picture.motion_val[0][xy + wrap][1] = 0;
- s->current_picture.motion_val[0][xy + wrap + 1][0] = 0;
- s->current_picture.motion_val[0][xy + wrap + 1][1] = 0;
+ xy = s->block_index[n];
+
+ if (s->mb_intra) {
+ s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = 0;
+ s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = 0;
+ s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = 0;
+ s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0;
+ if (mv1) { /* duplicate motion data for 1-MV block */
+ s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][0] = 0;
+ s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][1] = 0;
+ s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][0] = 0;
+ s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][1] = 0;
+ s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
+ s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
- s->current_picture.motion_val[1][xy + 1][0] = 0;
- s->current_picture.motion_val[1][xy + 1][1] = 0;
- s->current_picture.motion_val[1][xy + wrap][0] = 0;
- s->current_picture.motion_val[1][xy + wrap][1] = 0;
- s->current_picture.motion_val[1][xy + wrap + 1][0] = 0;
- s->current_picture.motion_val[1][xy + wrap + 1][1] = 0;
+ s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][0] = 0;
+ s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][1] = 0;
+ s->current_picture.f.motion_val[1][xy + wrap][0] = 0;
+ s->current_picture.f.motion_val[1][xy + wrap + v->blocks_off][1] = 0;
+ s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
+ s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
}
return;
}
- C = s->current_picture.motion_val[0][xy - 1];
- A = s->current_picture.motion_val[0][xy - wrap];
- if(mv1)
- off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
- else {
+ C = s->current_picture.f.motion_val[dir][xy - 1 + v->blocks_off];
+ A = s->current_picture.f.motion_val[dir][xy - wrap + v->blocks_off];
+ if (mv1) {
+ if (v->field_mode && mixedmv_pic)
+ off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
+ else
+ off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
+ } else {
//in 4-MV mode different blocks have different B predictor position
- switch(n){
+ switch (n) {
case 0:
off = (s->mb_x > 0) ? -1 : 1;
break;
@@ -926,79 +1541,404 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int m
off = -1;
}
}
- B = s->current_picture.motion_val[0][xy - wrap + off];
+ B = s->current_picture.f.motion_val[dir][xy - wrap + off + v->blocks_off];
- if(!s->first_slice_line || (n==2 || n==3)) { // predictor A is not out of bounds
- if(s->mb_width == 1) {
- px = A[0];
- py = A[1];
- } else {
- px = mid_pred(A[0], B[0], C[0]);
- py = mid_pred(A[1], B[1], C[1]);
+ a_valid = !s->first_slice_line || (n == 2 || n == 3);
+ b_valid = a_valid && (s->mb_width > 1);
+ c_valid = s->mb_x || (n == 1 || n == 3);
+ if (v->field_mode) {
+ a_valid = a_valid && !is_intra[xy - wrap];
+ b_valid = b_valid && !is_intra[xy - wrap + off];
+ c_valid = c_valid && !is_intra[xy - 1];
+ }
+
+ if (a_valid) {
+ a_f = v->mv_f[dir][xy - wrap + v->blocks_off];
+ num_oppfield += a_f;
+ num_samefield += 1 - a_f;
+ field_predA[0] = A[0];
+ field_predA[1] = A[1];
+ } else {
+ field_predA[0] = field_predA[1] = 0;
+ a_f = 0;
+ }
+ if (b_valid) {
+ b_f = v->mv_f[dir][xy - wrap + off + v->blocks_off];
+ num_oppfield += b_f;
+ num_samefield += 1 - b_f;
+ field_predB[0] = B[0];
+ field_predB[1] = B[1];
+ } else {
+ field_predB[0] = field_predB[1] = 0;
+ b_f = 0;
+ }
+ if (c_valid) {
+ c_f = v->mv_f[dir][xy - 1 + v->blocks_off];
+ num_oppfield += c_f;
+ num_samefield += 1 - c_f;
+ field_predC[0] = C[0];
+ field_predC[1] = C[1];
+ } else {
+ field_predC[0] = field_predC[1] = 0;
+ c_f = 0;
+ }
+
+ if (v->field_mode) {
+ if (num_samefield <= num_oppfield)
+ opposit = 1 - pred_flag;
+ else
+ opposit = pred_flag;
+ } else
+ opposit = 0;
+ if (opposit) {
+ if (a_valid && !a_f) {
+ field_predA[0] = scaleforopp(v, field_predA[0], 0, dir);
+ field_predA[1] = scaleforopp(v, field_predA[1], 1, dir);
+ }
+ if (b_valid && !b_f) {
+ field_predB[0] = scaleforopp(v, field_predB[0], 0, dir);
+ field_predB[1] = scaleforopp(v, field_predB[1], 1, dir);
+ }
+ if (c_valid && !c_f) {
+ field_predC[0] = scaleforopp(v, field_predC[0], 0, dir);
+ field_predC[1] = scaleforopp(v, field_predC[1], 1, dir);
}
- } else if(s->mb_x || (n==1 || n==3)) { // predictor C is not out of bounds
- px = C[0];
- py = C[1];
+ v->mv_f[dir][xy + v->blocks_off] = 1;
+ v->ref_field_type[dir] = !v->cur_field_type;
} else {
- px = py = 0;
+ if (a_valid && a_f) {
+ field_predA[0] = scaleforsame(v, n, field_predA[0], 0, dir);
+ field_predA[1] = scaleforsame(v, n, field_predA[1], 1, dir);
+ }
+ if (b_valid && b_f) {
+ field_predB[0] = scaleforsame(v, n, field_predB[0], 0, dir);
+ field_predB[1] = scaleforsame(v, n, field_predB[1], 1, dir);
+ }
+ if (c_valid && c_f) {
+ field_predC[0] = scaleforsame(v, n, field_predC[0], 0, dir);
+ field_predC[1] = scaleforsame(v, n, field_predC[1], 1, dir);
+ }
+ v->mv_f[dir][xy + v->blocks_off] = 0;
+ v->ref_field_type[dir] = v->cur_field_type;
+ }
+
+ if (a_valid) {
+ px = field_predA[0];
+ py = field_predA[1];
+ } else if (c_valid) {
+ px = field_predC[0];
+ py = field_predC[1];
+ } else if (b_valid) {
+ px = field_predB[0];
+ py = field_predB[1];
+ } else {
+ px = 0;
+ py = 0;
+ }
+
+ if (num_samefield + num_oppfield > 1) {
+ px = mid_pred(field_predA[0], field_predB[0], field_predC[0]);
+ py = mid_pred(field_predA[1], field_predB[1], field_predC[1]);
}
+
/* Pullback MV as specified in 8.3.5.3.4 */
- {
+ if (!v->field_mode) {
int qx, qy, X, Y;
- qx = (s->mb_x << 6) + ((n==1 || n==3) ? 32 : 0);
- qy = (s->mb_y << 6) + ((n==2 || n==3) ? 32 : 0);
- X = (s->mb_width << 6) - 4;
- Y = (s->mb_height << 6) - 4;
- if(mv1) {
- if(qx + px < -60) px = -60 - qx;
- if(qy + py < -60) py = -60 - qy;
+ qx = (s->mb_x << 6) + ((n == 1 || n == 3) ? 32 : 0);
+ qy = (s->mb_y << 6) + ((n == 2 || n == 3) ? 32 : 0);
+ X = (s->mb_width << 6) - 4;
+ Y = (s->mb_height << 6) - 4;
+ if (mv1) {
+ if (qx + px < -60) px = -60 - qx;
+ if (qy + py < -60) py = -60 - qy;
} else {
- if(qx + px < -28) px = -28 - qx;
- if(qy + py < -28) py = -28 - qy;
+ if (qx + px < -28) px = -28 - qx;
+ if (qy + py < -28) py = -28 - qy;
}
- if(qx + px > X) px = X - qx;
- if(qy + py > Y) py = Y - qy;
+ if (qx + px > X) px = X - qx;
+ if (qy + py > Y) py = Y - qy;
}
- /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
- if((!s->first_slice_line || (n==2 || n==3)) && (s->mb_x || (n==1 || n==3))) {
- if(is_intra[xy - wrap])
- sum = FFABS(px) + FFABS(py);
- else
- sum = FFABS(px - A[0]) + FFABS(py - A[1]);
- if(sum > 32) {
- if(get_bits1(&s->gb)) {
- px = A[0];
- py = A[1];
+
+ if (!v->field_mode || s->pict_type != AV_PICTURE_TYPE_B) {
+ /* Calculate hybrid prediction as specified in 8.3.5.3.5 (also 10.3.5.4.3.5) */
+ hybridmv_thresh = 32;
+ if (a_valid && c_valid) {
+ if (is_intra[xy - wrap])
+ sum = FFABS(px) + FFABS(py);
+ else
+ sum = FFABS(px - field_predA[0]) + FFABS(py - field_predA[1]);
+ if (sum > hybridmv_thresh) {
+ if (get_bits1(&s->gb)) { // read HYBRIDPRED bit
+ px = field_predA[0];
+ py = field_predA[1];
+ } else {
+ px = field_predC[0];
+ py = field_predC[1];
+ }
} else {
- px = C[0];
- py = C[1];
+ if (is_intra[xy - 1])
+ sum = FFABS(px) + FFABS(py);
+ else
+ sum = FFABS(px - field_predC[0]) + FFABS(py - field_predC[1]);
+ if (sum > hybridmv_thresh) {
+ if (get_bits1(&s->gb)) {
+ px = field_predA[0];
+ py = field_predA[1];
+ } else {
+ px = field_predC[0];
+ py = field_predC[1];
+ }
+ }
+ }
+ }
+ }
+
+ if (v->field_mode && !s->quarter_sample) {
+ r_x <<= 1;
+ r_y <<= 1;
+ }
+ if (v->field_mode && v->numref)
+ r_y >>= 1;
+ if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0)
+ y_bias = 1;
+ /* store MV using signed modulus of MV range defined in 4.11 */
+ s->mv[dir][n][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[dir][n][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
+ if (mv1) { /* duplicate motion data for 1-MV block */
+ s->current_picture.f.motion_val[dir][xy + 1 + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
+ s->current_picture.f.motion_val[dir][xy + 1 + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
+ s->current_picture.f.motion_val[dir][xy + wrap + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
+ s->current_picture.f.motion_val[dir][xy + wrap + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
+ s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
+ s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
+ v->mv_f[dir][xy + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
+ v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
+ }
+}
+
+/** Predict and set motion vector for interlaced frame picture MBs
+ */
+static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
+ int mvn, int r_x, int r_y, uint8_t* is_intra)
+{
+ MpegEncContext *s = &v->s;
+ int xy, wrap, off = 0;
+ int A[2], B[2], C[2];
+ int px, py;
+ int a_valid = 0, b_valid = 0, c_valid = 0;
+ int field_a, field_b, field_c; // 0: same, 1: opposit
+ int total_valid, num_samefield, num_oppfield;
+ int pos_c, pos_b, n_adj;
+
+ wrap = s->b8_stride;
+ xy = s->block_index[n];
+
+ if (s->mb_intra) {
+ s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = 0;
+ s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = 0;
+ s->current_picture.f.motion_val[1][xy][0] = 0;
+ s->current_picture.f.motion_val[1][xy][1] = 0;
+ if (mvn == 1) { /* duplicate motion data for 1-MV block */
+ s->current_picture.f.motion_val[0][xy + 1][0] = 0;
+ s->current_picture.f.motion_val[0][xy + 1][1] = 0;
+ s->current_picture.f.motion_val[0][xy + wrap][0] = 0;
+ s->current_picture.f.motion_val[0][xy + wrap][1] = 0;
+ s->current_picture.f.motion_val[0][xy + wrap + 1][0] = 0;
+ s->current_picture.f.motion_val[0][xy + wrap + 1][1] = 0;
+ v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
+ s->current_picture.f.motion_val[1][xy + 1][0] = 0;
+ s->current_picture.f.motion_val[1][xy + 1][1] = 0;
+ s->current_picture.f.motion_val[1][xy + wrap][0] = 0;
+ s->current_picture.f.motion_val[1][xy + wrap][1] = 0;
+ s->current_picture.f.motion_val[1][xy + wrap + 1][0] = 0;
+ s->current_picture.f.motion_val[1][xy + wrap + 1][1] = 0;
+ }
+ return;
+ }
+
+ off = ((n == 0) || (n == 1)) ? 1 : -1;
+ /* predict A */
+ if (s->mb_x || (n == 1) || (n == 3)) {
+ if ((v->blk_mv_type[xy]) // current block (MB) has a field MV
+ || (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV
+ A[0] = s->current_picture.f.motion_val[0][xy - 1][0];
+ A[1] = s->current_picture.f.motion_val[0][xy - 1][1];
+ a_valid = 1;
+ } else { // current block has frame mv and cand. has field MV (so average)
+ A[0] = (s->current_picture.f.motion_val[0][xy - 1][0]
+ + s->current_picture.f.motion_val[0][xy - 1 + off * wrap][0] + 1) >> 1;
+ A[1] = (s->current_picture.f.motion_val[0][xy - 1][1]
+ + s->current_picture.f.motion_val[0][xy - 1 + off * wrap][1] + 1) >> 1;
+ a_valid = 1;
+ }
+ if (!(n & 1) && v->is_intra[s->mb_x - 1]) {
+ a_valid = 0;
+ A[0] = A[1] = 0;
+ }
+ } else
+ A[0] = A[1] = 0;
+ /* Predict B and C */
+ B[0] = B[1] = C[0] = C[1] = 0;
+ if (n == 0 || n == 1 || v->blk_mv_type[xy]) {
+ if (!s->first_slice_line) {
+ if (!v->is_intra[s->mb_x - s->mb_stride]) {
+ b_valid = 1;
+ n_adj = n | 2;
+ pos_b = s->block_index[n_adj] - 2 * wrap;
+ if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) {
+ n_adj = (n & 2) | (n & 1);
+ }
+ B[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][0];
+ B[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][1];
+ if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) {
+ B[0] = (B[0] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
+ B[1] = (B[1] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
+ }
}
+ if (s->mb_width > 1) {
+ if (!v->is_intra[s->mb_x - s->mb_stride + 1]) {
+ c_valid = 1;
+ n_adj = 2;
+ pos_c = s->block_index[2] - 2 * wrap + 2;
+ if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
+ n_adj = n & 2;
+ }
+ C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][0];
+ C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][1];
+ if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
+ C[0] = (1 + C[0] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
+ C[1] = (1 + C[1] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (!v->is_intra[s->mb_x - s->mb_stride - 1]) {
+ c_valid = 1;
+ n_adj = 3;
+ pos_c = s->block_index[3] - 2 * wrap - 2;
+ if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
+ n_adj = n | 1;
+ }
+ C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][0];
+ C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][1];
+ if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
+ C[0] = (1 + C[0] + s->current_picture.f.motion_val[0][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
+ C[1] = (1 + C[1] + s->current_picture.f.motion_val[0][s->block_index[1] - 2 * wrap - 2][1]) >> 1;
+ }
+ } else
+ c_valid = 0;
+ }
+ }
+ }
+ }
+ } else {
+ pos_b = s->block_index[1];
+ b_valid = 1;
+ B[0] = s->current_picture.f.motion_val[0][pos_b][0];
+ B[1] = s->current_picture.f.motion_val[0][pos_b][1];
+ pos_c = s->block_index[0];
+ c_valid = 1;
+ C[0] = s->current_picture.f.motion_val[0][pos_c][0];
+ C[1] = s->current_picture.f.motion_val[0][pos_c][1];
+ }
+
+ total_valid = a_valid + b_valid + c_valid;
+ // check if predictor A is out of bounds
+ if (!s->mb_x && !(n == 1 || n == 3)) {
+ A[0] = A[1] = 0;
+ }
+ // check if predictor B is out of bounds
+ if ((s->first_slice_line && v->blk_mv_type[xy]) || (s->first_slice_line && !(n & 2))) {
+ B[0] = B[1] = C[0] = C[1] = 0;
+ }
+ if (!v->blk_mv_type[xy]) {
+ if (s->mb_width == 1) {
+ px = B[0];
+ py = B[1];
} else {
- if(is_intra[xy - 1])
- sum = FFABS(px) + FFABS(py);
- else
- sum = FFABS(px - C[0]) + FFABS(py - C[1]);
- if(sum > 32) {
- if(get_bits1(&s->gb)) {
+ if (total_valid >= 2) {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ } else if (total_valid) {
+ if (a_valid) { px = A[0]; py = A[1]; }
+ if (b_valid) { px = B[0]; py = B[1]; }
+ if (c_valid) { px = C[0]; py = C[1]; }
+ } else
+ px = py = 0;
+ }
+ } else {
+ if (a_valid)
+ field_a = (A[1] & 4) ? 1 : 0;
+ else
+ field_a = 0;
+ if (b_valid)
+ field_b = (B[1] & 4) ? 1 : 0;
+ else
+ field_b = 0;
+ if (c_valid)
+ field_c = (C[1] & 4) ? 1 : 0;
+ else
+ field_c = 0;
+
+ num_oppfield = field_a + field_b + field_c;
+ num_samefield = total_valid - num_oppfield;
+ if (total_valid == 3) {
+ if ((num_samefield == 3) || (num_oppfield == 3)) {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ } else if (num_samefield >= num_oppfield) {
+ /* take one MV from same field set depending on priority
+ the check for B may not be necessary */
+ px = !field_a ? A[0] : B[0];
+ py = !field_a ? A[1] : B[1];
+ } else {
+ px = field_a ? A[0] : B[0];
+ py = field_a ? A[1] : B[1];
+ }
+ } else if (total_valid == 2) {
+ if (num_samefield >= num_oppfield) {
+ if (!field_a && a_valid) {
px = A[0];
py = A[1];
- } else {
+ } else if (!field_b && b_valid) {
+ px = B[0];
+ py = B[1];
+ } else if (c_valid) {
+ px = C[0];
+ py = C[1];
+ } else px = py = 0;
+ } else {
+ if (field_a && a_valid) {
+ px = A[0];
+ py = A[1];
+ } else if (field_b && b_valid) {
+ px = B[0];
+ py = B[1];
+ } else if (c_valid) {
px = C[0];
py = C[1];
}
}
- }
+ } else if (total_valid == 1) {
+ px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]);
+ py = (a_valid) ? A[1] : ((b_valid) ? B[1] : C[1]);
+ } else
+ px = py = 0;
}
+
/* store MV using signed modulus of MV range defined in 4.11 */
- s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
- s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
- if(mv1) { /* duplicate motion data for 1-MV block */
- s->current_picture.motion_val[0][xy + 1][0] = s->current_picture.motion_val[0][xy][0];
- s->current_picture.motion_val[0][xy + 1][1] = s->current_picture.motion_val[0][xy][1];
- s->current_picture.motion_val[0][xy + wrap][0] = s->current_picture.motion_val[0][xy][0];
- s->current_picture.motion_val[0][xy + wrap][1] = s->current_picture.motion_val[0][xy][1];
- s->current_picture.motion_val[0][xy + wrap + 1][0] = s->current_picture.motion_val[0][xy][0];
- s->current_picture.motion_val[0][xy + wrap + 1][1] = s->current_picture.motion_val[0][xy][1];
+ s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
+ if (mvn == 1) { /* duplicate motion data for 1-MV block */
+ s->current_picture.f.motion_val[0][xy + 1 ][0] = s->current_picture.f.motion_val[0][xy][0];
+ s->current_picture.f.motion_val[0][xy + 1 ][1] = s->current_picture.f.motion_val[0][xy][1];
+ s->current_picture.f.motion_val[0][xy + wrap ][0] = s->current_picture.f.motion_val[0][xy][0];
+ s->current_picture.f.motion_val[0][xy + wrap ][1] = s->current_picture.f.motion_val[0][xy][1];
+ s->current_picture.f.motion_val[0][xy + wrap + 1][0] = s->current_picture.f.motion_val[0][xy][0];
+ s->current_picture.f.motion_val[0][xy + wrap + 1][1] = s->current_picture.f.motion_val[0][xy][1];
+ } else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */
+ s->current_picture.f.motion_val[0][xy + 1][0] = s->current_picture.f.motion_val[0][xy][0];
+ s->current_picture.f.motion_val[0][xy + 1][1] = s->current_picture.f.motion_val[0][xy][1];
+ s->mv[0][n + 1][0] = s->mv[0][n][0];
+ s->mv[0][n + 1][1] = s->mv[0][n][1];
}
}
@@ -1010,112 +1950,138 @@ static void vc1_interp_mc(VC1Context *v)
DSPContext *dsp = &v->s.dsp;
uint8_t *srcY, *srcU, *srcV;
int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
+ int off, off_uv;
+ int v_edge_pos = s->v_edge_pos >> v->field_mode;
- if(!v->s.next_picture.data[0])return;
+ if (!v->field_mode && !v->s.next_picture.f.data[0])
+ return;
- mx = s->mv[1][0][0];
- my = s->mv[1][0][1];
+ mx = s->mv[1][0][0];
+ my = s->mv[1][0][1];
uvmx = (mx + ((mx & 3) == 3)) >> 1;
uvmy = (my + ((my & 3) == 3)) >> 1;
- if(v->fastuvmc) {
- uvmx = uvmx + ((uvmx<0)?-(uvmx&1):(uvmx&1));
- uvmy = uvmy + ((uvmy<0)?-(uvmy&1):(uvmy&1));
+ if (v->field_mode) {
+ if (v->cur_field_type != v->ref_field_type[1])
+ my = my - 2 + 4 * v->cur_field_type;
+ uvmy = uvmy - 2 + 4 * v->cur_field_type;
}
- srcY = s->next_picture.data[0];
- srcU = s->next_picture.data[1];
- srcV = s->next_picture.data[2];
+ if (v->fastuvmc) {
+ uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1));
+ uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1));
+ }
+ srcY = s->next_picture.f.data[0];
+ srcU = s->next_picture.f.data[1];
+ srcV = s->next_picture.f.data[2];
- src_x = s->mb_x * 16 + (mx >> 2);
- src_y = s->mb_y * 16 + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
- uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
+ src_x = s->mb_x * 16 + (mx >> 2);
+ src_y = s->mb_y * 16 + (my >> 2);
+ uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
+ uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
- if(v->profile != PROFILE_ADVANCED){
+ if (v->profile != PROFILE_ADVANCED) {
src_x = av_clip( src_x, -16, s->mb_width * 16);
src_y = av_clip( src_y, -16, s->mb_height * 16);
uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
- }else{
+ } else {
src_x = av_clip( src_x, -17, s->avctx->coded_width);
src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
}
- srcY += src_y * s->linesize + src_x;
+ srcY += src_y * s->linesize + src_x;
srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
+ if (v->field_mode && v->ref_field_type[1]) {
+ srcY += s->current_picture_ptr->f.linesize[0];
+ srcU += s->current_picture_ptr->f.linesize[1];
+ srcV += s->current_picture_ptr->f.linesize[2];
+ }
+
/* for grayscale we should not try to read from unknown area */
- if(s->flags & CODEC_FLAG_GRAY) {
+ if (s->flags & CODEC_FLAG_GRAY) {
srcU = s->edge_emu_buffer + 18 * s->linesize;
srcV = s->edge_emu_buffer + 18 * s->linesize;
}
- if(v->rangeredfrm
- || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel*3
- || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 16 - s->mspel*3){
- uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize;
+ if (v->rangeredfrm
+ || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 16 - s->mspel * 3
+ || (unsigned)(src_y - s->mspel) > v_edge_pos - (my & 3) - 16 - s->mspel * 3) {
+ uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
srcY -= s->mspel * (1 + s->linesize);
- s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17+s->mspel*2, 17+s->mspel*2,
- src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos);
+ s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+ 17 + s->mspel * 2, 17 + s->mspel * 2,
+ src_x - s->mspel, src_y - s->mspel,
+ s->h_edge_pos, v_edge_pos);
srcY = s->edge_emu_buffer;
- s->dsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ s->dsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
+ s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
srcU = uvbuf;
srcV = uvbuf + 16;
/* if we deal with range reduction we need to scale source blocks */
- if(v->rangeredfrm) {
+ if (v->rangeredfrm) {
int i, j;
uint8_t *src, *src2;
src = srcY;
- for(j = 0; j < 17 + s->mspel*2; j++) {
- for(i = 0; i < 17 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128;
+ for (j = 0; j < 17 + s->mspel * 2; j++) {
+ for (i = 0; i < 17 + s->mspel * 2; i++)
+ src[i] = ((src[i] - 128) >> 1) + 128;
src += s->linesize;
}
- src = srcU; src2 = srcV;
- for(j = 0; j < 9; j++) {
- for(i = 0; i < 9; i++) {
- src[i] = ((src[i] - 128) >> 1) + 128;
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ for (i = 0; i < 9; i++) {
+ src[i] = ((src[i] - 128) >> 1) + 128;
src2[i] = ((src2[i] - 128) >> 1) + 128;
}
- src += s->uvlinesize;
+ src += s->uvlinesize;
src2 += s->uvlinesize;
}
}
srcY += s->mspel * (1 + s->linesize);
}
- if(s->mspel) {
+ if (v->field_mode && v->cur_field_type) {
+ off = s->current_picture_ptr->f.linesize[0];
+ off_uv = s->current_picture_ptr->f.linesize[1];
+ } else {
+ off = 0;
+ off_uv = 0;
+ }
+
+ if (s->mspel) {
dxy = ((my & 3) << 2) | (mx & 3);
- v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] , srcY , s->linesize, v->rnd);
- v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd);
+ v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off , srcY , s->linesize, v->rnd);
+ v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd);
srcY += s->linesize * 8;
- v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize , srcY , s->linesize, v->rnd);
- v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
+ v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize , srcY , s->linesize, v->rnd);
+ v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
} else { // hpel mc
dxy = (my & 2) | ((mx & 2) >> 1);
- if(!v->rnd)
- dsp->avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
+ if (!v->rnd)
+ dsp->avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
else
- dsp->avg_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
+ dsp->avg_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
}
- if(s->flags & CODEC_FLAG_GRAY) return;
+ if (s->flags & CODEC_FLAG_GRAY) return;
/* Chroma MC always uses qpel blilinear */
- uvmx = (uvmx&3)<<1;
- uvmy = (uvmy&3)<<1;
- if(!v->rnd){
- dsp->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- dsp->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
- }else{
- v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
+ uvmx = (uvmx & 3) << 1;
+ uvmy = (uvmy & 3) << 1;
+ if (!v->rnd) {
+ dsp->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
+ dsp->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+ } else {
+ v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
+ v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
}
}
@@ -1124,47 +2090,67 @@ static av_always_inline int scale_mv(int value, int bfrac, int inv, int qs)
int n = bfrac;
#if B_FRACTION_DEN==256
- if(inv)
+ if (inv)
n -= 256;
- if(!qs)
+ if (!qs)
return 2 * ((value * n + 255) >> 9);
return (value * n + 128) >> 8;
#else
- if(inv)
+ if (inv)
n -= B_FRACTION_DEN;
- if(!qs)
+ if (!qs)
return 2 * ((value * n + B_FRACTION_DEN - 1) / (2 * B_FRACTION_DEN));
return (value * n + B_FRACTION_DEN/2) / B_FRACTION_DEN;
#endif
}
+static av_always_inline int scale_mv_intfi(int value, int bfrac, int inv,
+ int qs, int qs_last)
+{
+ int n = bfrac;
+
+ if (inv)
+ n -= 256;
+ n <<= !qs_last;
+ if (!qs)
+ return (value * n + 255) >> 9;
+ else
+ return (value * n + 128) >> 8;
+}
+
/** Reconstruct motion vector for B-frame and do motion compensation
*/
-static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mode)
+static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2],
+ int direct, int mode)
{
- if(v->use_ic) {
+ if (v->use_ic) {
v->mv_mode2 = v->mv_mode;
- v->mv_mode = MV_PMODE_INTENSITY_COMP;
+ v->mv_mode = MV_PMODE_INTENSITY_COMP;
}
- if(direct) {
+ if (direct) {
vc1_mc_1mv(v, 0);
vc1_interp_mc(v);
- if(v->use_ic) v->mv_mode = v->mv_mode2;
+ if (v->use_ic)
+ v->mv_mode = v->mv_mode2;
return;
}
- if(mode == BMV_TYPE_INTERPOLATED) {
+ if (mode == BMV_TYPE_INTERPOLATED) {
vc1_mc_1mv(v, 0);
vc1_interp_mc(v);
- if(v->use_ic) v->mv_mode = v->mv_mode2;
+ if (v->use_ic)
+ v->mv_mode = v->mv_mode2;
return;
}
- if(v->use_ic && (mode == BMV_TYPE_BACKWARD)) v->mv_mode = v->mv_mode2;
+ if (v->use_ic && (mode == BMV_TYPE_BACKWARD))
+ v->mv_mode = v->mv_mode2;
vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD));
- if(v->use_ic) v->mv_mode = v->mv_mode2;
+ if (v->use_ic)
+ v->mv_mode = v->mv_mode2;
}
-static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mvtype)
+static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
+ int direct, int mvtype)
{
MpegEncContext *s = &v->s;
int xy, wrap, off = 0;
@@ -1185,47 +2171,49 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int
wrap = s->b8_stride;
xy = s->block_index[0];
- if(s->mb_intra) {
- s->current_picture.motion_val[0][xy][0] =
- s->current_picture.motion_val[0][xy][1] =
- s->current_picture.motion_val[1][xy][0] =
- s->current_picture.motion_val[1][xy][1] = 0;
+ if (s->mb_intra) {
+ s->current_picture.f.motion_val[0][xy + v->blocks_off][0] =
+ s->current_picture.f.motion_val[0][xy + v->blocks_off][1] =
+ s->current_picture.f.motion_val[1][xy + v->blocks_off][0] =
+ s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0;
return;
}
- s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
- s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
- s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
- s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
-
- /* Pullback predicted motion vectors as specified in 8.4.5.4 */
- s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
- s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
- s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
- s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
- if(direct) {
- s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
- s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
- s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
- s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
+ if (!v->field_mode) {
+ s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
+ s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
+ s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
+ s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
+
+ /* Pullback predicted motion vectors as specified in 8.4.5.4 */
+ s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
+ s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
+ s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
+ s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
+ }
+ if (direct) {
+ s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0];
+ s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1];
+ s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0];
+ s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1];
return;
}
- if((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
- C = s->current_picture.motion_val[0][xy - 2];
- A = s->current_picture.motion_val[0][xy - wrap*2];
+ if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
+ C = s->current_picture.f.motion_val[0][xy - 2];
+ A = s->current_picture.f.motion_val[0][xy - wrap * 2];
off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
- B = s->current_picture.motion_val[0][xy - wrap*2 + off];
+ B = s->current_picture.f.motion_val[0][xy - wrap * 2 + off];
- if(!s->mb_x) C[0] = C[1] = 0;
- if(!s->first_slice_line) { // predictor A is not out of bounds
- if(s->mb_width == 1) {
+ if (!s->mb_x) C[0] = C[1] = 0;
+ if (!s->first_slice_line) { // predictor A is not out of bounds
+ if (s->mb_width == 1) {
px = A[0];
py = A[1];
} else {
px = mid_pred(A[0], B[0], C[0]);
py = mid_pred(A[1], B[1], C[1]);
}
- } else if(s->mb_x) { // predictor C is not out of bounds
+ } else if (s->mb_x) { // predictor C is not out of bounds
px = C[0];
py = C[1];
} else {
@@ -1234,34 +2222,34 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int
/* Pullback MV as specified in 8.3.5.3.4 */
{
int qx, qy, X, Y;
- if(v->profile < PROFILE_ADVANCED) {
+ if (v->profile < PROFILE_ADVANCED) {
qx = (s->mb_x << 5);
qy = (s->mb_y << 5);
- X = (s->mb_width << 5) - 4;
- Y = (s->mb_height << 5) - 4;
- if(qx + px < -28) px = -28 - qx;
- if(qy + py < -28) py = -28 - qy;
- if(qx + px > X) px = X - qx;
- if(qy + py > Y) py = Y - qy;
+ X = (s->mb_width << 5) - 4;
+ Y = (s->mb_height << 5) - 4;
+ if (qx + px < -28) px = -28 - qx;
+ if (qy + py < -28) py = -28 - qy;
+ if (qx + px > X) px = X - qx;
+ if (qy + py > Y) py = Y - qy;
} else {
qx = (s->mb_x << 6);
qy = (s->mb_y << 6);
- X = (s->mb_width << 6) - 4;
- Y = (s->mb_height << 6) - 4;
- if(qx + px < -60) px = -60 - qx;
- if(qy + py < -60) py = -60 - qy;
- if(qx + px > X) px = X - qx;
- if(qy + py > Y) py = Y - qy;
+ X = (s->mb_width << 6) - 4;
+ Y = (s->mb_height << 6) - 4;
+ if (qx + px < -60) px = -60 - qx;
+ if (qy + py < -60) py = -60 - qy;
+ if (qx + px > X) px = X - qx;
+ if (qy + py > Y) py = Y - qy;
}
}
/* Calculate hybrid prediction as specified in 8.3.5.3.5 */
- if(0 && !s->first_slice_line && s->mb_x) {
- if(is_intra[xy - wrap])
+ if (0 && !s->first_slice_line && s->mb_x) {
+ if (is_intra[xy - wrap])
sum = FFABS(px) + FFABS(py);
else
sum = FFABS(px - A[0]) + FFABS(py - A[1]);
- if(sum > 32) {
- if(get_bits1(&s->gb)) {
+ if (sum > 32) {
+ if (get_bits1(&s->gb)) {
px = A[0];
py = A[1];
} else {
@@ -1269,12 +2257,12 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int
py = C[1];
}
} else {
- if(is_intra[xy - 2])
+ if (is_intra[xy - 2])
sum = FFABS(px) + FFABS(py);
else
sum = FFABS(px - C[0]) + FFABS(py - C[1]);
- if(sum > 32) {
- if(get_bits1(&s->gb)) {
+ if (sum > 32) {
+ if (get_bits1(&s->gb)) {
px = A[0];
py = A[1];
} else {
@@ -1288,22 +2276,23 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int
s->mv[0][0][0] = ((px + dmv_x[0] + r_x) & ((r_x << 1) - 1)) - r_x;
s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
}
- if((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
- C = s->current_picture.motion_val[1][xy - 2];
- A = s->current_picture.motion_val[1][xy - wrap*2];
+ if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
+ C = s->current_picture.f.motion_val[1][xy - 2];
+ A = s->current_picture.f.motion_val[1][xy - wrap * 2];
off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
- B = s->current_picture.motion_val[1][xy - wrap*2 + off];
+ B = s->current_picture.f.motion_val[1][xy - wrap * 2 + off];
- if(!s->mb_x) C[0] = C[1] = 0;
- if(!s->first_slice_line) { // predictor A is not out of bounds
- if(s->mb_width == 1) {
+ if (!s->mb_x)
+ C[0] = C[1] = 0;
+ if (!s->first_slice_line) { // predictor A is not out of bounds
+ if (s->mb_width == 1) {
px = A[0];
py = A[1];
} else {
px = mid_pred(A[0], B[0], C[0]);
py = mid_pred(A[1], B[1], C[1]);
}
- } else if(s->mb_x) { // predictor C is not out of bounds
+ } else if (s->mb_x) { // predictor C is not out of bounds
px = C[0];
py = C[1];
} else {
@@ -1312,34 +2301,34 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int
/* Pullback MV as specified in 8.3.5.3.4 */
{
int qx, qy, X, Y;
- if(v->profile < PROFILE_ADVANCED) {
+ if (v->profile < PROFILE_ADVANCED) {
qx = (s->mb_x << 5);
qy = (s->mb_y << 5);
- X = (s->mb_width << 5) - 4;
- Y = (s->mb_height << 5) - 4;
- if(qx + px < -28) px = -28 - qx;
- if(qy + py < -28) py = -28 - qy;
- if(qx + px > X) px = X - qx;
- if(qy + py > Y) py = Y - qy;
+ X = (s->mb_width << 5) - 4;
+ Y = (s->mb_height << 5) - 4;
+ if (qx + px < -28) px = -28 - qx;
+ if (qy + py < -28) py = -28 - qy;
+ if (qx + px > X) px = X - qx;
+ if (qy + py > Y) py = Y - qy;
} else {
qx = (s->mb_x << 6);
qy = (s->mb_y << 6);
- X = (s->mb_width << 6) - 4;
- Y = (s->mb_height << 6) - 4;
- if(qx + px < -60) px = -60 - qx;
- if(qy + py < -60) py = -60 - qy;
- if(qx + px > X) px = X - qx;
- if(qy + py > Y) py = Y - qy;
+ X = (s->mb_width << 6) - 4;
+ Y = (s->mb_height << 6) - 4;
+ if (qx + px < -60) px = -60 - qx;
+ if (qy + py < -60) py = -60 - qy;
+ if (qx + px > X) px = X - qx;
+ if (qy + py > Y) py = Y - qy;
}
}
/* Calculate hybrid prediction as specified in 8.3.5.3.5 */
- if(0 && !s->first_slice_line && s->mb_x) {
- if(is_intra[xy - wrap])
+ if (0 && !s->first_slice_line && s->mb_x) {
+ if (is_intra[xy - wrap])
sum = FFABS(px) + FFABS(py);
else
sum = FFABS(px - A[0]) + FFABS(py - A[1]);
- if(sum > 32) {
- if(get_bits1(&s->gb)) {
+ if (sum > 32) {
+ if (get_bits1(&s->gb)) {
px = A[0];
py = A[1];
} else {
@@ -1347,12 +2336,12 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int
py = C[1];
}
} else {
- if(is_intra[xy - 2])
+ if (is_intra[xy - 2])
sum = FFABS(px) + FFABS(py);
else
sum = FFABS(px - C[0]) + FFABS(py - C[1]);
- if(sum > 32) {
- if(get_bits1(&s->gb)) {
+ if (sum > 32) {
+ if (get_bits1(&s->gb)) {
px = A[0];
py = A[1];
} else {
@@ -1367,10 +2356,67 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int
s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x;
s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y;
}
- s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
- s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
- s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
- s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
+ s->current_picture.f.motion_val[0][xy][0] = s->mv[0][0][0];
+ s->current_picture.f.motion_val[0][xy][1] = s->mv[0][0][1];
+ s->current_picture.f.motion_val[1][xy][0] = s->mv[1][0][0];
+ s->current_picture.f.motion_val[1][xy][1] = s->mv[1][0][1];
+}
+
+static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y, int mv1, int *pred_flag)
+{
+ int dir = (v->bmvtype == BMV_TYPE_BACKWARD) ? 1 : 0;
+ MpegEncContext *s = &v->s;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+
+ if (v->bmvtype == BMV_TYPE_DIRECT) {
+ int total_opp, k, f;
+ if (s->next_picture.f.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
+ s->mv[0][0][0] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0],
+ v->bfraction, 0, s->quarter_sample, v->qs_last);
+ s->mv[0][0][1] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1],
+ v->bfraction, 0, s->quarter_sample, v->qs_last);
+ s->mv[1][0][0] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0],
+ v->bfraction, 1, s->quarter_sample, v->qs_last);
+ s->mv[1][0][1] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1],
+ v->bfraction, 1, s->quarter_sample, v->qs_last);
+
+ total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off]
+ + v->mv_f_next[0][s->block_index[1] + v->blocks_off]
+ + v->mv_f_next[0][s->block_index[2] + v->blocks_off]
+ + v->mv_f_next[0][s->block_index[3] + v->blocks_off];
+ f = (total_opp > 2) ? 1 : 0;
+ } else {
+ s->mv[0][0][0] = s->mv[0][0][1] = 0;
+ s->mv[1][0][0] = s->mv[1][0][1] = 0;
+ f = 0;
+ }
+ v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f;
+ for (k = 0; k < 4; k++) {
+ s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
+ s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
+ s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
+ s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
+ v->mv_f[0][s->block_index[k] + v->blocks_off] = f;
+ v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
+ }
+ return;
+ }
+ if (v->bmvtype == BMV_TYPE_INTERPOLATED) {
+ vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
+ vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
+ return;
+ }
+ if (dir) { // backward
+ vc1_pred_mv(v, n, dmv_x[1], dmv_y[1], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
+ if (n == 3 || mv1) {
+ vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
+ }
+ } else { // forward
+ vc1_pred_mv(v, n, dmv_x[0], dmv_y[0], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
+ if (n == 3 || mv1) {
+ vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type[0], 0, 1);
+ }
+ }
}
/** Get predicted DC value for I-frames only
@@ -1383,23 +2429,23 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int
* @param dir_ptr Prediction direction for use in AC prediction
*/
static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
- int16_t **dc_val_ptr, int *dir_ptr)
+ int16_t **dc_val_ptr, int *dir_ptr)
{
int a, b, c, wrap, pred, scale;
int16_t *dc_val;
static const uint16_t dcpred[32] = {
- -1, 1024, 512, 341, 256, 205, 171, 146, 128,
- 114, 102, 93, 85, 79, 73, 68, 64,
- 60, 57, 54, 51, 49, 47, 45, 43,
- 41, 39, 38, 37, 35, 34, 33
+ -1, 1024, 512, 341, 256, 205, 171, 146, 128,
+ 114, 102, 93, 85, 79, 73, 68, 64,
+ 60, 57, 54, 51, 49, 47, 45, 43,
+ 41, 39, 38, 37, 35, 34, 33
};
/* find prediction - wmv3_dc_scale always used here in fact */
- if (n < 4) scale = s->y_dc_scale;
- else scale = s->c_dc_scale;
+ if (n < 4) scale = s->y_dc_scale;
+ else scale = s->c_dc_scale;
- wrap = s->block_wrap[n];
- dc_val= s->dc_val[0] + s->block_index[n];
+ wrap = s->block_wrap[n];
+ dc_val = s->dc_val[0] + s->block_index[n];
/* B A
* C X
@@ -1408,25 +2454,26 @@ static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
b = dc_val[ - 1 - wrap];
a = dc_val[ - wrap];
- if (pq < 9 || !overlap)
- {
+ if (pq < 9 || !overlap) {
/* Set outer values */
- if (s->first_slice_line && (n!=2 && n!=3)) b=a=dcpred[scale];
- if (s->mb_x == 0 && (n!=1 && n!=3)) b=c=dcpred[scale];
- }
- else
- {
+ if (s->first_slice_line && (n != 2 && n != 3))
+ b = a = dcpred[scale];
+ if (s->mb_x == 0 && (n != 1 && n != 3))
+ b = c = dcpred[scale];
+ } else {
/* Set outer values */
- if (s->first_slice_line && (n!=2 && n!=3)) b=a=0;
- if (s->mb_x == 0 && (n!=1 && n!=3)) b=c=0;
+ if (s->first_slice_line && (n != 2 && n != 3))
+ b = a = 0;
+ if (s->mb_x == 0 && (n != 1 && n != 3))
+ b = c = 0;
}
if (abs(a - b) <= abs(b - c)) {
- pred = c;
- *dir_ptr = 1;//left
+ pred = c;
+ *dir_ptr = 1; // left
} else {
- pred = a;
- *dir_ptr = 0;//top
+ pred = a;
+ *dir_ptr = 0; // top
}
/* update predictor */
@@ -1456,7 +2503,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
int q1, q2 = 0;
wrap = s->block_wrap[n];
- dc_val= s->dc_val[0] + s->block_index[n];
+ dc_val = s->dc_val[0] + s->block_index[n];
/* B A
* C X
@@ -1465,43 +2512,45 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
b = dc_val[ - 1 - wrap];
a = dc_val[ - wrap];
/* scale predictors if needed */
- q1 = s->current_picture.qscale_table[mb_pos];
- if(c_avail && (n!= 1 && n!=3)) {
- q2 = s->current_picture.qscale_table[mb_pos - 1];
- if(q2 && q2 != q1)
+ q1 = s->current_picture.f.qscale_table[mb_pos];
+ if (c_avail && (n != 1 && n != 3)) {
+ q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+ if (q2 && q2 != q1)
c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18;
}
- if(a_avail && (n!= 2 && n!=3)) {
- q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
- if(q2 && q2 != q1)
+ if (a_avail && (n != 2 && n != 3)) {
+ q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+ if (q2 && q2 != q1)
a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18;
}
- if(a_avail && c_avail && (n!=3)) {
+ if (a_avail && c_avail && (n != 3)) {
int off = mb_pos;
- if(n != 1) off--;
- if(n != 2) off -= s->mb_stride;
- q2 = s->current_picture.qscale_table[off];
- if(q2 && q2 != q1)
+ if (n != 1)
+ off--;
+ if (n != 2)
+ off -= s->mb_stride;
+ q2 = s->current_picture.f.qscale_table[off];
+ if (q2 && q2 != q1)
b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18;
}
- if(a_avail && c_avail) {
- if(abs(a - b) <= abs(b - c)) {
- pred = c;
- *dir_ptr = 1;//left
+ if (a_avail && c_avail) {
+ if (abs(a - b) <= abs(b - c)) {
+ pred = c;
+ *dir_ptr = 1; // left
} else {
- pred = a;
- *dir_ptr = 0;//top
+ pred = a;
+ *dir_ptr = 0; // top
}
- } else if(a_avail) {
- pred = a;
- *dir_ptr = 0;//top
- } else if(c_avail) {
- pred = c;
- *dir_ptr = 1;//left
+ } else if (a_avail) {
+ pred = a;
+ *dir_ptr = 0; // top
+ } else if (c_avail) {
+ pred = c;
+ *dir_ptr = 1; // left
} else {
- pred = 0;
- *dir_ptr = 1;//left
+ pred = 0;
+ *dir_ptr = 1; // left
}
/* update predictor */
@@ -1517,11 +2566,12 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
* @{
*/
-static inline int vc1_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
+static inline int vc1_coded_block_pred(MpegEncContext * s, int n,
+ uint8_t **coded_block_ptr)
{
int xy, wrap, pred, a, b, c;
- xy = s->block_index[n];
+ xy = s->block_index[n];
wrap = s->b8_stride;
/* B C
@@ -1552,61 +2602,62 @@ static inline int vc1_coded_block_pred(MpegEncContext * s, int n, uint8_t **code
* @param codingset set of VLC to decode data
* @see 8.1.3.4
*/
-static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int *value, int codingset)
+static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip,
+ int *value, int codingset)
{
GetBitContext *gb = &v->s.gb;
int index, escape, run = 0, level = 0, lst = 0;
index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
if (index != vc1_ac_sizes[codingset] - 1) {
- run = vc1_index_decode_table[codingset][index][0];
+ run = vc1_index_decode_table[codingset][index][0];
level = vc1_index_decode_table[codingset][index][1];
- lst = index >= vc1_last_decode_table[codingset] || get_bits_left(gb) < 0;
- if(get_bits1(gb))
+ lst = index >= vc1_last_decode_table[codingset] || get_bits_left(gb) < 0;
+ if (get_bits1(gb))
level = -level;
} else {
escape = decode210(gb);
if (escape != 2) {
index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
- run = vc1_index_decode_table[codingset][index][0];
+ run = vc1_index_decode_table[codingset][index][0];
level = vc1_index_decode_table[codingset][index][1];
- lst = index >= vc1_last_decode_table[codingset];
- if(escape == 0) {
- if(lst)
+ lst = index >= vc1_last_decode_table[codingset];
+ if (escape == 0) {
+ if (lst)
level += vc1_last_delta_level_table[codingset][run];
else
level += vc1_delta_level_table[codingset][run];
} else {
- if(lst)
+ if (lst)
run += vc1_last_delta_run_table[codingset][level] + 1;
else
run += vc1_delta_run_table[codingset][level] + 1;
}
- if(get_bits1(gb))
+ if (get_bits1(gb))
level = -level;
} else {
int sign;
lst = get_bits1(gb);
- if(v->s.esc3_level_length == 0) {
- if(v->pq < 8 || v->dquantfrm) { // table 59
+ if (v->s.esc3_level_length == 0) {
+ if (v->pq < 8 || v->dquantfrm) { // table 59
v->s.esc3_level_length = get_bits(gb, 3);
- if(!v->s.esc3_level_length)
+ if (!v->s.esc3_level_length)
v->s.esc3_level_length = get_bits(gb, 2) + 8;
- } else { //table 60
+ } else { // table 60
v->s.esc3_level_length = get_unary(gb, 1, 6) + 2;
}
v->s.esc3_run_length = 3 + get_bits(gb, 2);
}
- run = get_bits(gb, v->s.esc3_run_length);
- sign = get_bits1(gb);
+ run = get_bits(gb, v->s.esc3_run_length);
+ sign = get_bits1(gb);
level = get_bits(gb, v->s.esc3_level_length);
- if(sign)
+ if (sign)
level = -level;
}
}
- *last = lst;
- *skip = run;
+ *last = lst;
+ *skip = run;
*value = level;
}
@@ -1617,7 +2668,8 @@ static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int *value,
* @param coded are AC coeffs present or not
* @param codingset set of VLC to decode data
*/
-static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded, int codingset)
+static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n,
+ int coded, int codingset)
{
GetBitContext *gb = &v->s.gb;
MpegEncContext *s = &v->s;
@@ -1633,25 +2685,21 @@ static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded
} else {
dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
}
- if (dcdiff < 0){
+ if (dcdiff < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
return -1;
}
- if (dcdiff)
- {
- if (dcdiff == 119 /* ESC index value */)
- {
+ if (dcdiff) {
+ if (dcdiff == 119 /* ESC index value */) {
/* TODO: Optimize */
- if (v->pq == 1) dcdiff = get_bits(gb, 10);
+ if (v->pq == 1) dcdiff = get_bits(gb, 10);
else if (v->pq == 2) dcdiff = get_bits(gb, 9);
- else dcdiff = get_bits(gb, 8);
- }
- else
- {
+ else dcdiff = get_bits(gb, 8);
+ } else {
if (v->pq == 1)
- dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
+ dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
else if (v->pq == 2)
- dcdiff = (dcdiff<<1) + get_bits1(gb) - 1;
+ dcdiff = (dcdiff << 1) + get_bits1(gb) - 1;
}
if (get_bits1(gb))
dcdiff = -dcdiff;
@@ -1672,7 +2720,7 @@ static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded
goto not_coded;
}
- //AC Decoding
+ // AC Decoding
i = 1;
{
@@ -1683,87 +2731,87 @@ static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded
scale = v->pq * 2 + v->halfpq;
- if(v->s.ac_pred) {
- if(!dc_pred_dir)
+ if (v->s.ac_pred) {
+ if (!dc_pred_dir)
zz_table = v->zz_8x8[2];
else
zz_table = v->zz_8x8[3];
} else
zz_table = v->zz_8x8[1];
- ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
ac_val2 = ac_val;
- if(dc_pred_dir) //left
+ if (dc_pred_dir) // left
ac_val -= 16;
- else //top
+ else // top
ac_val -= 16 * s->block_wrap[n];
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
i += skip;
- if(i > 63)
+ if (i > 63)
break;
block[zz_table[i++]] = value;
}
/* apply AC prediction if needed */
- if(s->ac_pred) {
- if(dc_pred_dir) { //left
- for(k = 1; k < 8; k++)
+ if (s->ac_pred) {
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++)
block[k << v->left_blk_sh] += ac_val[k];
- } else { //top
- for(k = 1; k < 8; k++)
+ } else { // top
+ for (k = 1; k < 8; k++)
block[k << v->top_blk_sh] += ac_val[k + 8];
}
}
/* save AC coeffs for further prediction */
- for(k = 1; k < 8; k++) {
+ for (k = 1; k < 8; k++) {
ac_val2[k] = block[k << v->left_blk_sh];
ac_val2[k + 8] = block[k << v->top_blk_sh];
}
/* scale AC coeffs */
- for(k = 1; k < 64; k++)
- if(block[k]) {
+ for (k = 1; k < 64; k++)
+ if (block[k]) {
block[k] *= scale;
- if(!v->pquantizer)
+ if (!v->pquantizer)
block[k] += (block[k] < 0) ? -v->pq : v->pq;
}
- if(s->ac_pred) i = 63;
+ if (s->ac_pred) i = 63;
}
not_coded:
- if(!coded) {
+ if (!coded) {
int k, scale;
- ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
ac_val2 = ac_val;
i = 0;
scale = v->pq * 2 + v->halfpq;
memset(ac_val2, 0, 16 * 2);
- if(dc_pred_dir) {//left
+ if (dc_pred_dir) { // left
ac_val -= 16;
- if(s->ac_pred)
+ if (s->ac_pred)
memcpy(ac_val2, ac_val, 8 * 2);
- } else {//top
+ } else { // top
ac_val -= 16 * s->block_wrap[n];
- if(s->ac_pred)
+ if (s->ac_pred)
memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
}
/* apply AC prediction if needed */
- if(s->ac_pred) {
- if(dc_pred_dir) { //left
- for(k = 1; k < 8; k++) {
+ if (s->ac_pred) {
+ if (dc_pred_dir) { //left
+ for (k = 1; k < 8; k++) {
block[k << v->left_blk_sh] = ac_val[k] * scale;
- if(!v->pquantizer && block[k << v->left_blk_sh])
+ if (!v->pquantizer && block[k << v->left_blk_sh])
block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -v->pq : v->pq;
}
- } else { //top
- for(k = 1; k < 8; k++) {
+ } else { // top
+ for (k = 1; k < 8; k++) {
block[k << v->top_blk_sh] = ac_val[k + 8] * scale;
- if(!v->pquantizer && block[k << v->top_blk_sh])
+ if (!v->pquantizer && block[k << v->top_blk_sh])
block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -v->pq : v->pq;
}
}
@@ -1783,7 +2831,8 @@ not_coded:
* @param codingset set of VLC to decode data
* @param mquant quantizer value for this macroblock
*/
-static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int coded, int codingset, int mquant)
+static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n,
+ int coded, int codingset, int mquant)
{
GetBitContext *gb = &v->s.gb;
MpegEncContext *s = &v->s;
@@ -1804,25 +2853,21 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c
} else {
dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
}
- if (dcdiff < 0){
+ if (dcdiff < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
return -1;
}
- if (dcdiff)
- {
- if (dcdiff == 119 /* ESC index value */)
- {
+ if (dcdiff) {
+ if (dcdiff == 119 /* ESC index value */) {
/* TODO: Optimize */
- if (mquant == 1) dcdiff = get_bits(gb, 10);
+ if (mquant == 1) dcdiff = get_bits(gb, 10);
else if (mquant == 2) dcdiff = get_bits(gb, 9);
- else dcdiff = get_bits(gb, 8);
- }
- else
- {
+ else dcdiff = get_bits(gb, 8);
+ } else {
if (mquant == 1)
- dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
+ dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
else if (mquant == 2)
- dcdiff = (dcdiff<<1) + get_bits1(gb) - 1;
+ dcdiff = (dcdiff << 1) + get_bits1(gb) - 1;
}
if (get_bits1(gb))
dcdiff = -dcdiff;
@@ -1843,122 +2888,136 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c
i = 1;
/* check if AC is needed at all */
- if(!a_avail && !c_avail) use_pred = 0;
- ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ if (!a_avail && !c_avail)
+ use_pred = 0;
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
ac_val2 = ac_val;
scale = mquant * 2 + ((mquant == v->pq) ? v->halfpq : 0);
- if(dc_pred_dir) //left
+ if (dc_pred_dir) // left
ac_val -= 16;
- else //top
+ else // top
ac_val -= 16 * s->block_wrap[n];
- q1 = s->current_picture.qscale_table[mb_pos];
- if(dc_pred_dir && c_avail && mb_pos) q2 = s->current_picture.qscale_table[mb_pos - 1];
- if(!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
- if(dc_pred_dir && n==1) q2 = q1;
- if(!dc_pred_dir && n==2) q2 = q1;
- if(n==3) q2 = q1;
-
- if(coded) {
+ q1 = s->current_picture.f.qscale_table[mb_pos];
+ if ( dc_pred_dir && c_avail && mb_pos)
+ q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+ if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
+ q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+ if ( dc_pred_dir && n == 1)
+ q2 = q1;
+ if (!dc_pred_dir && n == 2)
+ q2 = q1;
+ if (n == 3)
+ q2 = q1;
+
+ if (coded) {
int last = 0, skip, value;
const uint8_t *zz_table;
int k;
- if(v->s.ac_pred) {
- if(!dc_pred_dir)
- zz_table = v->zz_8x8[2];
+ if (v->s.ac_pred) {
+ if (!use_pred && v->fcm == ILACE_FRAME) {
+ zz_table = v->zzi_8x8;
+ } else {
+ if (!dc_pred_dir) // top
+ zz_table = v->zz_8x8[2];
+ else // left
+ zz_table = v->zz_8x8[3];
+ }
+ } else {
+ if (v->fcm != ILACE_FRAME)
+ zz_table = v->zz_8x8[1];
else
- zz_table = v->zz_8x8[3];
- } else
- zz_table = v->zz_8x8[1];
+ zz_table = v->zzi_8x8;
+ }
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
i += skip;
- if(i > 63)
+ if (i > 63)
break;
block[zz_table[i++]] = value;
}
/* apply AC prediction if needed */
- if(use_pred) {
+ if (use_pred) {
/* scale predictors if needed*/
- if(q2 && q1!=q2) {
+ if (q2 && q1 != q2) {
q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
- if(dc_pred_dir) { //left
- for(k = 1; k < 8; k++)
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++)
block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
- } else { //top
- for(k = 1; k < 8; k++)
+ } else { // top
+ for (k = 1; k < 8; k++)
block[k << v->top_blk_sh] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
}
} else {
- if(dc_pred_dir) { //left
- for(k = 1; k < 8; k++)
+ if (dc_pred_dir) { //left
+ for (k = 1; k < 8; k++)
block[k << v->left_blk_sh] += ac_val[k];
} else { //top
- for(k = 1; k < 8; k++)
+ for (k = 1; k < 8; k++)
block[k << v->top_blk_sh] += ac_val[k + 8];
}
}
}
/* save AC coeffs for further prediction */
- for(k = 1; k < 8; k++) {
+ for (k = 1; k < 8; k++) {
ac_val2[k ] = block[k << v->left_blk_sh];
ac_val2[k + 8] = block[k << v->top_blk_sh];
}
/* scale AC coeffs */
- for(k = 1; k < 64; k++)
- if(block[k]) {
+ for (k = 1; k < 64; k++)
+ if (block[k]) {
block[k] *= scale;
- if(!v->pquantizer)
+ if (!v->pquantizer)
block[k] += (block[k] < 0) ? -mquant : mquant;
}
- if(use_pred) i = 63;
+ if (use_pred) i = 63;
} else { // no AC coeffs
int k;
memset(ac_val2, 0, 16 * 2);
- if(dc_pred_dir) {//left
- if(use_pred) {
+ if (dc_pred_dir) { // left
+ if (use_pred) {
memcpy(ac_val2, ac_val, 8 * 2);
- if(q2 && q1!=q2) {
+ if (q2 && q1 != q2) {
q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
- for(k = 1; k < 8; k++)
+ for (k = 1; k < 8; k++)
ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
}
}
- } else {//top
- if(use_pred) {
+ } else { // top
+ if (use_pred) {
memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
- if(q2 && q1!=q2) {
+ if (q2 && q1 != q2) {
q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
- for(k = 1; k < 8; k++)
+ for (k = 1; k < 8; k++)
ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
}
}
}
/* apply AC prediction if needed */
- if(use_pred) {
- if(dc_pred_dir) { //left
- for(k = 1; k < 8; k++) {
+ if (use_pred) {
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++) {
block[k << v->left_blk_sh] = ac_val2[k] * scale;
- if(!v->pquantizer && block[k << v->left_blk_sh])
+ if (!v->pquantizer && block[k << v->left_blk_sh])
block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -mquant : mquant;
}
- } else { //top
- for(k = 1; k < 8; k++) {
+ } else { // top
+ for (k = 1; k < 8; k++) {
block[k << v->top_blk_sh] = ac_val2[k + 8] * scale;
- if(!v->pquantizer && block[k << v->top_blk_sh])
+ if (!v->pquantizer && block[k << v->top_blk_sh])
block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -mquant : mquant;
}
}
@@ -1978,7 +3037,8 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c
* @param mquant block quantizer
* @param codingset set of VLC to decode data
*/
-static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int coded, int mquant, int codingset)
+static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n,
+ int coded, int mquant, int codingset)
{
GetBitContext *gb = &v->s.gb;
MpegEncContext *s = &v->s;
@@ -1996,7 +3056,7 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c
s->dsp.clear_block(block);
/* XXX: Guard against dumb values of mquant */
- mquant = (mquant < 1) ? 0 : ( (mquant>31) ? 31 : mquant );
+ mquant = (mquant < 1) ? 0 : ((mquant > 31) ? 31 : mquant);
/* Set DC scale - y and c use the same */
s->y_dc_scale = s->y_dc_scale_table[mquant];
@@ -2008,25 +3068,21 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c
} else {
dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
}
- if (dcdiff < 0){
+ if (dcdiff < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
return -1;
}
- if (dcdiff)
- {
- if (dcdiff == 119 /* ESC index value */)
- {
+ if (dcdiff) {
+ if (dcdiff == 119 /* ESC index value */) {
/* TODO: Optimize */
- if (mquant == 1) dcdiff = get_bits(gb, 10);
+ if (mquant == 1) dcdiff = get_bits(gb, 10);
else if (mquant == 2) dcdiff = get_bits(gb, 9);
- else dcdiff = get_bits(gb, 8);
- }
- else
- {
+ else dcdiff = get_bits(gb, 8);
+ } else {
if (mquant == 1)
- dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
+ dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
else if (mquant == 2)
- dcdiff = (dcdiff<<1) + get_bits1(gb) - 1;
+ dcdiff = (dcdiff << 1) + get_bits1(gb) - 1;
}
if (get_bits1(gb))
dcdiff = -dcdiff;
@@ -2048,115 +3104,130 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c
i = 1;
/* check if AC is needed at all and adjust direction if needed */
- if(!a_avail) dc_pred_dir = 1;
- if(!c_avail) dc_pred_dir = 0;
- if(!a_avail && !c_avail) use_pred = 0;
+ if (!a_avail) dc_pred_dir = 1;
+ if (!c_avail) dc_pred_dir = 0;
+ if (!a_avail && !c_avail) use_pred = 0;
ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
ac_val2 = ac_val;
scale = mquant * 2 + v->halfpq;
- if(dc_pred_dir) //left
+ if (dc_pred_dir) //left
ac_val -= 16;
else //top
ac_val -= 16 * s->block_wrap[n];
- q1 = s->current_picture.qscale_table[mb_pos];
- if(dc_pred_dir && c_avail && mb_pos) q2 = s->current_picture.qscale_table[mb_pos - 1];
- if(!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
- if(dc_pred_dir && n==1) q2 = q1;
- if(!dc_pred_dir && n==2) q2 = q1;
- if(n==3) q2 = q1;
-
- if(coded) {
+ q1 = s->current_picture.f.qscale_table[mb_pos];
+ if (dc_pred_dir && c_avail && mb_pos)
+ q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+ if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
+ q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+ if ( dc_pred_dir && n == 1)
+ q2 = q1;
+ if (!dc_pred_dir && n == 2)
+ q2 = q1;
+ if (n == 3) q2 = q1;
+
+ if (coded) {
int last = 0, skip, value;
int k;
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
i += skip;
- if(i > 63)
+ if (i > 63)
break;
- block[v->zz_8x8[0][i++]] = value;
+ if (v->fcm == PROGRESSIVE)
+ block[v->zz_8x8[0][i++]] = value;
+ else {
+ if (use_pred && (v->fcm == ILACE_FRAME)) {
+ if (!dc_pred_dir) // top
+ block[v->zz_8x8[2][i++]] = value;
+ else // left
+ block[v->zz_8x8[3][i++]] = value;
+ } else {
+ block[v->zzi_8x8[i++]] = value;
+ }
+ }
}
/* apply AC prediction if needed */
- if(use_pred) {
+ if (use_pred) {
/* scale predictors if needed*/
- if(q2 && q1!=q2) {
+ if (q2 && q1 != q2) {
q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
- if(dc_pred_dir) { //left
- for(k = 1; k < 8; k++)
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++)
block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
} else { //top
- for(k = 1; k < 8; k++)
+ for (k = 1; k < 8; k++)
block[k << v->top_blk_sh] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
}
} else {
- if(dc_pred_dir) { //left
- for(k = 1; k < 8; k++)
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++)
block[k << v->left_blk_sh] += ac_val[k];
- } else { //top
- for(k = 1; k < 8; k++)
+ } else { // top
+ for (k = 1; k < 8; k++)
block[k << v->top_blk_sh] += ac_val[k + 8];
}
}
}
/* save AC coeffs for further prediction */
- for(k = 1; k < 8; k++) {
+ for (k = 1; k < 8; k++) {
ac_val2[k ] = block[k << v->left_blk_sh];
ac_val2[k + 8] = block[k << v->top_blk_sh];
}
/* scale AC coeffs */
- for(k = 1; k < 64; k++)
- if(block[k]) {
+ for (k = 1; k < 64; k++)
+ if (block[k]) {
block[k] *= scale;
- if(!v->pquantizer)
+ if (!v->pquantizer)
block[k] += (block[k] < 0) ? -mquant : mquant;
}
- if(use_pred) i = 63;
+ if (use_pred) i = 63;
} else { // no AC coeffs
int k;
memset(ac_val2, 0, 16 * 2);
- if(dc_pred_dir) {//left
- if(use_pred) {
+ if (dc_pred_dir) { // left
+ if (use_pred) {
memcpy(ac_val2, ac_val, 8 * 2);
- if(q2 && q1!=q2) {
+ if (q2 && q1 != q2) {
q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
- for(k = 1; k < 8; k++)
+ for (k = 1; k < 8; k++)
ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
}
}
- } else {//top
- if(use_pred) {
+ } else { // top
+ if (use_pred) {
memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
- if(q2 && q1!=q2) {
+ if (q2 && q1 != q2) {
q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
- for(k = 1; k < 8; k++)
+ for (k = 1; k < 8; k++)
ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
}
}
}
/* apply AC prediction if needed */
- if(use_pred) {
- if(dc_pred_dir) { //left
- for(k = 1; k < 8; k++) {
+ if (use_pred) {
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++) {
block[k << v->left_blk_sh] = ac_val2[k] * scale;
- if(!v->pquantizer && block[k << v->left_blk_sh])
+ if (!v->pquantizer && block[k << v->left_blk_sh])
block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -mquant : mquant;
}
- } else { //top
- for(k = 1; k < 8; k++) {
+ } else { // top
+ for (k = 1; k < 8; k++) {
block[k << v->top_blk_sh] = ac_val2[k + 8] * scale;
- if(!v->pquantizer && block[k << v->top_blk_sh])
+ if (!v->pquantizer && block[k << v->top_blk_sh])
block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -mquant : mquant;
}
}
@@ -2170,8 +3241,10 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c
/** Decode P block
*/
-static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquant, int ttmb, int first_block,
- uint8_t *dst, int linesize, int skip_block, int *ttmb_out)
+static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n,
+ int mquant, int ttmb, int first_block,
+ uint8_t *dst, int linesize, int skip_block,
+ int *ttmb_out)
{
MpegEncContext *s = &v->s;
GetBitContext *gb = &s->gb;
@@ -2183,50 +3256,56 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan
s->dsp.clear_block(block);
- if(ttmb == -1) {
+ if (ttmb == -1) {
ttblk = ff_vc1_ttblk_to_tt[v->tt_index][get_vlc2(gb, ff_vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];
}
- if(ttblk == TT_4X4) {
+ if (ttblk == TT_4X4) {
subblkpat = ~(get_vlc2(gb, ff_vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1);
}
- if((ttblk != TT_8X8 && ttblk != TT_4X4)
+ if ((ttblk != TT_8X8 && ttblk != TT_4X4)
&& ((v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))
|| (!v->res_rtm_flag && !first_block))) {
subblkpat = decode012(gb);
- if(subblkpat) subblkpat ^= 3; //swap decoded pattern bits
- if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) ttblk = TT_8X4;
- if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) ttblk = TT_4X8;
+ if (subblkpat)
+ subblkpat ^= 3; // swap decoded pattern bits
+ if (ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM)
+ ttblk = TT_8X4;
+ if (ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT)
+ ttblk = TT_4X8;
}
scale = 2 * mquant + ((v->pq == mquant) ? v->halfpq : 0);
// convert transforms like 8X4_TOP to generic TT and SUBBLKPAT
- if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) {
+ if (ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) {
subblkpat = 2 - (ttblk == TT_8X4_TOP);
- ttblk = TT_8X4;
+ ttblk = TT_8X4;
}
- if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) {
+ if (ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) {
subblkpat = 2 - (ttblk == TT_4X8_LEFT);
- ttblk = TT_4X8;
+ ttblk = TT_4X8;
}
- switch(ttblk) {
+ switch (ttblk) {
case TT_8X8:
- pat = 0xF;
- i = 0;
+ pat = 0xF;
+ i = 0;
last = 0;
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
i += skip;
- if(i > 63)
+ if (i > 63)
break;
- idx = v->zz_8x8[0][i++];
+ if (!v->fcm)
+ idx = v->zz_8x8[0][i++];
+ else
+ idx = v->zzi_8x8[i++];
block[idx] = value * scale;
- if(!v->pquantizer)
+ if (!v->pquantizer)
block[idx] += (block[idx] < 0) ? -mquant : mquant;
}
- if(!skip_block){
- if(i==1)
+ if (!skip_block) {
+ if (i == 1)
v->vc1dsp.vc1_inv_trans_8x8_dc(dst, linesize, block);
- else{
+ else {
v->vc1dsp.vc1_inv_trans_8x8(block);
s->dsp.add_pixels_clamped(block, dst, linesize);
}
@@ -2234,71 +3313,80 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan
break;
case TT_4X4:
pat = ~subblkpat & 0xF;
- for(j = 0; j < 4; j++) {
+ for (j = 0; j < 4; j++) {
last = subblkpat & (1 << (3 - j));
- i = 0;
- off = (j & 1) * 4 + (j & 2) * 16;
+ i = 0;
+ off = (j & 1) * 4 + (j & 2) * 16;
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
i += skip;
- if(i > 15)
+ if (i > 15)
break;
- idx = ff_vc1_simple_progressive_4x4_zz[i++];
+ if (!v->fcm)
+ idx = ff_vc1_simple_progressive_4x4_zz[i++];
+ else
+ idx = ff_vc1_adv_interlaced_4x4_zz[i++];
block[idx + off] = value * scale;
- if(!v->pquantizer)
+ if (!v->pquantizer)
block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
}
- if(!(subblkpat & (1 << (3 - j))) && !skip_block){
- if(i==1)
- v->vc1dsp.vc1_inv_trans_4x4_dc(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off);
+ if (!(subblkpat & (1 << (3 - j))) && !skip_block) {
+ if (i == 1)
+ v->vc1dsp.vc1_inv_trans_4x4_dc(dst + (j & 1) * 4 + (j & 2) * 2 * linesize, linesize, block + off);
else
- v->vc1dsp.vc1_inv_trans_4x4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off);
+ v->vc1dsp.vc1_inv_trans_4x4(dst + (j & 1) * 4 + (j & 2) * 2 * linesize, linesize, block + off);
}
}
break;
case TT_8X4:
- pat = ~((subblkpat & 2)*6 + (subblkpat & 1)*3) & 0xF;
- for(j = 0; j < 2; j++) {
+ pat = ~((subblkpat & 2) * 6 + (subblkpat & 1) * 3) & 0xF;
+ for (j = 0; j < 2; j++) {
last = subblkpat & (1 << (1 - j));
- i = 0;
- off = j * 32;
+ i = 0;
+ off = j * 32;
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
i += skip;
- if(i > 31)
+ if (i > 31)
break;
- idx = v->zz_8x4[i++]+off;
+ if (!v->fcm)
+ idx = v->zz_8x4[i++] + off;
+ else
+ idx = ff_vc1_adv_interlaced_8x4_zz[i++] + off;
block[idx] = value * scale;
- if(!v->pquantizer)
+ if (!v->pquantizer)
block[idx] += (block[idx] < 0) ? -mquant : mquant;
}
- if(!(subblkpat & (1 << (1 - j))) && !skip_block){
- if(i==1)
- v->vc1dsp.vc1_inv_trans_8x4_dc(dst + j*4*linesize, linesize, block + off);
+ if (!(subblkpat & (1 << (1 - j))) && !skip_block) {
+ if (i == 1)
+ v->vc1dsp.vc1_inv_trans_8x4_dc(dst + j * 4 * linesize, linesize, block + off);
else
- v->vc1dsp.vc1_inv_trans_8x4(dst + j*4*linesize, linesize, block + off);
+ v->vc1dsp.vc1_inv_trans_8x4(dst + j * 4 * linesize, linesize, block + off);
}
}
break;
case TT_4X8:
- pat = ~(subblkpat*5) & 0xF;
- for(j = 0; j < 2; j++) {
+ pat = ~(subblkpat * 5) & 0xF;
+ for (j = 0; j < 2; j++) {
last = subblkpat & (1 << (1 - j));
- i = 0;
- off = j * 4;
+ i = 0;
+ off = j * 4;
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
i += skip;
- if(i > 31)
+ if (i > 31)
break;
- idx = v->zz_4x8[i++]+off;
+ if (!v->fcm)
+ idx = v->zz_4x8[i++] + off;
+ else
+ idx = ff_vc1_adv_interlaced_4x8_zz[i++] + off;
block[idx] = value * scale;
- if(!v->pquantizer)
+ if (!v->pquantizer)
block[idx] += (block[idx] < 0) ? -mquant : mquant;
}
- if(!(subblkpat & (1 << (1 - j))) && !skip_block){
- if(i==1)
- v->vc1dsp.vc1_inv_trans_4x8_dc(dst + j*4, linesize, block + off);
+ if (!(subblkpat & (1 << (1 - j))) && !skip_block) {
+ if (i == 1)
+ v->vc1dsp.vc1_inv_trans_4x8_dc(dst + j * 4, linesize, block + off);
else
v->vc1dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off);
}
@@ -2317,15 +3405,15 @@ static const int offset_table[6] = { 0, 1, 3, 7, 15, 31 };
static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_num)
{
- MpegEncContext *s = &v->s;
+ MpegEncContext *s = &v->s;
int mb_cbp = v->cbp[s->mb_x - s->mb_stride],
block_cbp = mb_cbp >> (block_num * 4), bottom_cbp,
mb_is_intra = v->is_intra[s->mb_x - s->mb_stride],
block_is_intra = mb_is_intra >> (block_num * 4), bottom_is_intra;
- int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
+ int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
uint8_t *dst;
- if(block_num > 3) {
+ if (block_num > 3) {
dst = s->dest[block_num - 3];
} else {
dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 8) * linesize;
@@ -2334,18 +3422,18 @@ static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_
int16_t (*mv)[2];
int mv_stride;
- if(block_num > 3) {
+ if (block_num > 3) {
bottom_cbp = v->cbp[s->mb_x] >> (block_num * 4);
bottom_is_intra = v->is_intra[s->mb_x] >> (block_num * 4);
mv = &v->luma_mv[s->mb_x - s->mb_stride];
mv_stride = s->mb_stride;
} else {
- bottom_cbp = (block_num < 2) ? (mb_cbp >> ((block_num + 2) * 4)) :
- (v->cbp[s->mb_x] >> ((block_num - 2) * 4));
- bottom_is_intra = (block_num < 2) ? (mb_is_intra >> ((block_num + 2) * 4)) :
- (v->is_intra[s->mb_x] >> ((block_num - 2) * 4));
+ bottom_cbp = (block_num < 2) ? (mb_cbp >> ((block_num + 2) * 4))
+ : (v->cbp[s->mb_x] >> ((block_num - 2) * 4));
+ bottom_is_intra = (block_num < 2) ? (mb_is_intra >> ((block_num + 2) * 4))
+ : (v->is_intra[s->mb_x] >> ((block_num - 2) * 4));
mv_stride = s->b8_stride;
- mv = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
+ mv = &s->current_picture.f.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
}
if (bottom_is_intra & 1 || block_is_intra & 1 ||
@@ -2353,7 +3441,7 @@ static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_
v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
} else {
idx = ((bottom_cbp >> 2) | block_cbp) & 3;
- if(idx == 3) {
+ if (idx == 3) {
v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
} else if (idx) {
if (idx == 1)
@@ -2365,7 +3453,7 @@ static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_
}
dst -= 4 * linesize;
- ttblk = (v->ttblk[s->mb_x - s->mb_stride] >> (block_num * 4)) & 0xf;
+ ttblk = (v->ttblk[s->mb_x - s->mb_stride] >> (block_num * 4)) & 0xF;
if (ttblk == TT_4X4 || ttblk == TT_8X4) {
idx = (block_cbp | (block_cbp >> 2)) & 3;
if (idx == 3) {
@@ -2381,12 +3469,12 @@ static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_
static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_num)
{
- MpegEncContext *s = &v->s;
+ MpegEncContext *s = &v->s;
int mb_cbp = v->cbp[s->mb_x - 1 - s->mb_stride],
block_cbp = mb_cbp >> (block_num * 4), right_cbp,
mb_is_intra = v->is_intra[s->mb_x - 1 - s->mb_stride],
block_is_intra = mb_is_intra >> (block_num * 4), right_is_intra;
- int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
+ int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
uint8_t *dst;
if (block_num > 3) {
@@ -2398,16 +3486,16 @@ static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_
if (s->mb_x != s->mb_width || !(block_num & 5)) {
int16_t (*mv)[2];
- if(block_num > 3) {
+ if (block_num > 3) {
right_cbp = v->cbp[s->mb_x - s->mb_stride] >> (block_num * 4);
right_is_intra = v->is_intra[s->mb_x - s->mb_stride] >> (block_num * 4);
mv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
- }else{
- right_cbp = (block_num & 1) ? (v->cbp[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4)) :
- (mb_cbp >> ((block_num + 1) * 4));
- right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4)) :
- (mb_is_intra >> ((block_num + 1) * 4));
- mv = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
+ } else {
+ right_cbp = (block_num & 1) ? (v->cbp[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4))
+ : (mb_cbp >> ((block_num + 1) * 4));
+ right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4))
+ : (mb_is_intra >> ((block_num + 1) * 4));
+ mv = &s->current_picture.f.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
}
if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) {
v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
@@ -2417,9 +3505,9 @@ static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_
v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
} else if (idx) {
if (idx == 1)
- v->vc1dsp.vc1_h_loop_filter4(dst+4*linesize, linesize, v->pq);
+ v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize, linesize, v->pq);
else
- v->vc1dsp.vc1_h_loop_filter4(dst, linesize, v->pq);
+ v->vc1dsp.vc1_h_loop_filter4(dst, linesize, v->pq);
}
}
}
@@ -2432,9 +3520,9 @@ static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_
v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
} else if (idx) {
if (idx == 1)
- v->vc1dsp.vc1_h_loop_filter4(dst + linesize*4, linesize, v->pq);
+ v->vc1dsp.vc1_h_loop_filter4(dst + linesize * 4, linesize, v->pq);
else
- v->vc1dsp.vc1_h_loop_filter4(dst, linesize, v->pq);
+ v->vc1dsp.vc1_h_loop_filter4(dst, linesize, v->pq);
}
}
}
@@ -2448,7 +3536,7 @@ static void vc1_apply_p_loop_filter(VC1Context *v)
vc1_apply_p_v_loop_filter(v, i);
}
- /* V always preceedes H, therefore we run H one MB before V;
+ /* V always precedes H, therefore we run H one MB before V;
* at the end of a row, we catch up to complete the row */
if (s->mb_x) {
for (i = 0; i < 6; i++) {
@@ -2464,7 +3552,7 @@ static void vc1_apply_p_loop_filter(VC1Context *v)
}
}
-/** Decode one P-frame MB (in Simple/Main profile)
+/** Decode one P-frame MB
*/
static int vc1_decode_p_mb(VC1Context *v)
{
@@ -2485,7 +3573,7 @@ static int vc1_decode_p_mb(VC1Context *v)
int skipped, fourmv;
int block_cbp = 0, pat, block_tt = 0, block_intra = 0;
- mquant = v->pq; /* Loosy initialization */
+ mquant = v->pq; /* lossy initialization */
if (v->mv_type_is_raw)
fourmv = get_bits1(gb);
@@ -2496,208 +3584,543 @@ static int vc1_decode_p_mb(VC1Context *v)
else
skipped = v->s.mbskip_table[mb_pos];
- if (!fourmv) /* 1MV mode */
- {
- if (!skipped)
- {
+ if (!fourmv) { /* 1MV mode */
+ if (!skipped) {
GET_MVDATA(dmv_x, dmv_y);
if (s->mb_intra) {
- s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
- s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
+ s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
}
- s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
- vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]);
+ s->current_picture.f.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
+ vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
/* FIXME Set DC val for inter block ? */
- if (s->mb_intra && !mb_has_coeffs)
- {
+ if (s->mb_intra && !mb_has_coeffs) {
GET_MQUANT();
s->ac_pred = get_bits1(gb);
- cbp = 0;
- }
- else if (mb_has_coeffs)
- {
- if (s->mb_intra) s->ac_pred = get_bits1(gb);
+ cbp = 0;
+ } else if (mb_has_coeffs) {
+ if (s->mb_intra)
+ s->ac_pred = get_bits1(gb);
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
GET_MQUANT();
- }
- else
- {
+ } else {
mquant = v->pq;
- cbp = 0;
+ cbp = 0;
}
- s->current_picture.qscale_table[mb_pos] = mquant;
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table,
VC1_TTMB_VLC_BITS, 2);
- if(!s->mb_intra) vc1_mc_1mv(v, 0);
+ if (!s->mb_intra) vc1_mc_1mv(v, 0);
dst_idx = 0;
- for (i=0; i<6; i++)
- {
+ for (i = 0; i < 6; i++) {
s->dc_val[0][s->block_index[i]] = 0;
dst_idx += i >> 2;
val = ((cbp >> (5 - i)) & 1);
off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
v->mb_type[0][s->block_index[i]] = s->mb_intra;
- if(s->mb_intra) {
+ if (s->mb_intra) {
/* check if prediction blocks A and C are available */
v->a_avail = v->c_avail = 0;
- if(i == 2 || i == 3 || !s->first_slice_line)
+ if (i == 2 || i == 3 || !s->first_slice_line)
v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
- if(i == 1 || i == 3 || s->mb_x)
+ if (i == 1 || i == 3 || s->mb_x)
v->c_avail = v->mb_type[0][s->block_index[i] - 1];
- vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
- if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
+ continue;
v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
- if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[i][j] <<= 1;
s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
- if(v->pq >= 9 && v->overlap) {
- if(v->c_avail)
+ if (v->pq >= 9 && v->overlap) {
+ if (v->c_avail)
v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
- if(v->a_avail)
+ if (v->a_avail)
v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
}
- block_cbp |= 0xF << (i << 2);
+ block_cbp |= 0xF << (i << 2);
block_intra |= 1 << i;
- } else if(val) {
- pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
+ } else if (val) {
+ pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block,
+ s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize,
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
block_cbp |= pat << (i << 2);
- if(!v->ttmbf && ttmb < 8) ttmb = -1;
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
first_block = 0;
}
}
- }
- else //Skipped
- {
+ } else { // skipped
s->mb_intra = 0;
- for(i = 0; i < 6; i++) {
+ for (i = 0; i < 6; i++) {
v->mb_type[0][s->block_index[i]] = 0;
- s->dc_val[0][s->block_index[i]] = 0;
+ s->dc_val[0][s->block_index[i]] = 0;
}
- s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
- s->current_picture.qscale_table[mb_pos] = 0;
- vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]);
+ s->current_picture.f.mb_type[mb_pos] = MB_TYPE_SKIP;
+ s->current_picture.f.qscale_table[mb_pos] = 0;
+ vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
vc1_mc_1mv(v, 0);
}
- } //1MV mode
- else //4MV mode
- {
- if (!skipped /* unskipped MB */)
- {
+ } else { // 4MV mode
+ if (!skipped /* unskipped MB */) {
int intra_count = 0, coded_inter = 0;
int is_intra[6], is_coded[6];
/* Get CBPCY */
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- for (i=0; i<6; i++)
- {
+ for (i = 0; i < 6; i++) {
val = ((cbp >> (5 - i)) & 1);
s->dc_val[0][s->block_index[i]] = 0;
- s->mb_intra = 0;
- if(i < 4) {
+ s->mb_intra = 0;
+ if (i < 4) {
dmv_x = dmv_y = 0;
- s->mb_intra = 0;
+ s->mb_intra = 0;
mb_has_coeffs = 0;
- if(val) {
+ if (val) {
GET_MVDATA(dmv_x, dmv_y);
}
- vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]);
- if(!s->mb_intra) vc1_mc_4mv_luma(v, i);
+ vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
+ if (!s->mb_intra)
+ vc1_mc_4mv_luma(v, i, 0);
intra_count += s->mb_intra;
- is_intra[i] = s->mb_intra;
- is_coded[i] = mb_has_coeffs;
+ is_intra[i] = s->mb_intra;
+ is_coded[i] = mb_has_coeffs;
}
- if(i&4){
+ if (i & 4) {
is_intra[i] = (intra_count >= 3);
is_coded[i] = val;
}
- if(i == 4) vc1_mc_4mv_chroma(v);
+ if (i == 4)
+ vc1_mc_4mv_chroma(v, 0);
v->mb_type[0][s->block_index[i]] = is_intra[i];
- if(!coded_inter) coded_inter = !is_intra[i] & is_coded[i];
+ if (!coded_inter)
+ coded_inter = !is_intra[i] & is_coded[i];
}
// if there are no coded blocks then don't do anything more
dst_idx = 0;
- if(!intra_count && !coded_inter)
+ if (!intra_count && !coded_inter)
goto end;
GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
/* test if block is intra and has pred */
{
int intrapred = 0;
- for(i=0; i<6; i++)
- if(is_intra[i]) {
- if(((!s->first_slice_line || (i==2 || i==3)) && v->mb_type[0][s->block_index[i] - s->block_wrap[i]])
- || ((s->mb_x || (i==1 || i==3)) && v->mb_type[0][s->block_index[i] - 1])) {
+ for (i = 0; i < 6; i++)
+ if (is_intra[i]) {
+ if (((!s->first_slice_line || (i == 2 || i == 3)) && v->mb_type[0][s->block_index[i] - s->block_wrap[i]])
+ || ((s->mb_x || (i == 1 || i == 3)) && v->mb_type[0][s->block_index[i] - 1])) {
intrapred = 1;
break;
}
}
- if(intrapred)s->ac_pred = get_bits1(gb);
- else s->ac_pred = 0;
+ if (intrapred)
+ s->ac_pred = get_bits1(gb);
+ else
+ s->ac_pred = 0;
}
if (!v->ttmbf && coded_inter)
ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
- for (i=0; i<6; i++)
- {
- dst_idx += i >> 2;
- off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ for (i = 0; i < 6; i++) {
+ dst_idx += i >> 2;
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
s->mb_intra = is_intra[i];
if (is_intra[i]) {
/* check if prediction blocks A and C are available */
v->a_avail = v->c_avail = 0;
- if(i == 2 || i == 3 || !s->first_slice_line)
+ if (i == 2 || i == 3 || !s->first_slice_line)
v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
- if(i == 1 || i == 3 || s->mb_x)
+ if (i == 1 || i == 3 || s->mb_x)
v->c_avail = v->mb_type[0][s->block_index[i] - 1];
- vc1_decode_intra_block(v, s->block[i], i, is_coded[i], mquant, (i&4)?v->codingset2:v->codingset);
- if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
+ vc1_decode_intra_block(v, s->block[i], i, is_coded[i], mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
+ continue;
v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
- if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
- s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
- if(v->pq >= 9 && v->overlap) {
- if(v->c_avail)
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[i][j] <<= 1;
+ s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : s->linesize);
+ if (v->pq >= 9 && v->overlap) {
+ if (v->c_avail)
v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
- if(v->a_avail)
+ if (v->a_avail)
v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
}
- block_cbp |= 0xF << (i << 2);
+ block_cbp |= 0xF << (i << 2);
block_intra |= 1 << i;
- } else if(is_coded[i]) {
- pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
+ } else if (is_coded[i]) {
+ pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : s->linesize,
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY),
+ &block_tt);
block_cbp |= pat << (i << 2);
- if(!v->ttmbf && ttmb < 8) ttmb = -1;
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
first_block = 0;
}
}
- }
- else //Skipped MB
- {
- s->mb_intra = 0;
- s->current_picture.qscale_table[mb_pos] = 0;
- for (i=0; i<6; i++) {
+ } else { // skipped MB
+ s->mb_intra = 0;
+ s->current_picture.f.qscale_table[mb_pos] = 0;
+ for (i = 0; i < 6; i++) {
v->mb_type[0][s->block_index[i]] = 0;
- s->dc_val[0][s->block_index[i]] = 0;
+ s->dc_val[0][s->block_index[i]] = 0;
}
- for (i=0; i<4; i++)
- {
- vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0]);
- vc1_mc_4mv_luma(v, i);
+ for (i = 0; i < 4; i++) {
+ vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
+ vc1_mc_4mv_luma(v, i, 0);
}
- vc1_mc_4mv_chroma(v);
- s->current_picture.qscale_table[mb_pos] = 0;
+ vc1_mc_4mv_chroma(v, 0);
+ s->current_picture.f.qscale_table[mb_pos] = 0;
}
}
end:
- v->cbp[s->mb_x] = block_cbp;
- v->ttblk[s->mb_x] = block_tt;
+ v->cbp[s->mb_x] = block_cbp;
+ v->ttblk[s->mb_x] = block_tt;
v->is_intra[s->mb_x] = block_intra;
return 0;
}
+/* Decode one macroblock in an interlaced frame p picture */
+
+static int vc1_decode_p_mb_intfr(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int cbp = 0; /* cbp decoding stuff */
+ int mqdiff, mquant; /* MB quantization */
+ int ttmb = v->ttfrm; /* MB Transform type */
+
+ int mb_has_coeffs = 1; /* last_flag */
+ int dmv_x, dmv_y; /* Differential MV components */
+ int val; /* temp value */
+ int first_block = 1;
+ int dst_idx, off;
+ int skipped, fourmv = 0, twomv = 0;
+ int block_cbp = 0, pat, block_tt = 0;
+ int idx_mbmode = 0, mvbp;
+ int stride_y, fieldtx;
+
+ mquant = v->pq; /* Loosy initialization */
+
+ if (v->skip_is_raw)
+ skipped = get_bits1(gb);
+ else
+ skipped = v->s.mbskip_table[mb_pos];
+ if (!skipped) {
+ if (v->fourmvswitch)
+ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_4MV_MBMODE_VLC_BITS, 2); // try getting this done
+ else
+ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2); // in a single line
+ switch (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0]) {
+ /* store the motion vector type in a flag (useful later) */
+ case MV_PMODE_INTFR_4MV:
+ fourmv = 1;
+ v->blk_mv_type[s->block_index[0]] = 0;
+ v->blk_mv_type[s->block_index[1]] = 0;
+ v->blk_mv_type[s->block_index[2]] = 0;
+ v->blk_mv_type[s->block_index[3]] = 0;
+ break;
+ case MV_PMODE_INTFR_4MV_FIELD:
+ fourmv = 1;
+ v->blk_mv_type[s->block_index[0]] = 1;
+ v->blk_mv_type[s->block_index[1]] = 1;
+ v->blk_mv_type[s->block_index[2]] = 1;
+ v->blk_mv_type[s->block_index[3]] = 1;
+ break;
+ case MV_PMODE_INTFR_2MV_FIELD:
+ twomv = 1;
+ v->blk_mv_type[s->block_index[0]] = 1;
+ v->blk_mv_type[s->block_index[1]] = 1;
+ v->blk_mv_type[s->block_index[2]] = 1;
+ v->blk_mv_type[s->block_index[3]] = 1;
+ break;
+ case MV_PMODE_INTFR_1MV:
+ v->blk_mv_type[s->block_index[0]] = 0;
+ v->blk_mv_type[s->block_index[1]] = 0;
+ v->blk_mv_type[s->block_index[2]] = 0;
+ v->blk_mv_type[s->block_index[3]] = 0;
+ break;
+ }
+ if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
+ s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
+ s->current_picture.f.mb_type[mb_pos] = MB_TYPE_INTRA;
+ s->mb_intra = v->is_intra[s->mb_x] = 1;
+ for (i = 0; i < 6; i++)
+ v->mb_type[0][s->block_index[i]] = 1;
+ fieldtx = v->fieldtx_plane[mb_pos] = get_bits1(gb);
+ mb_has_coeffs = get_bits1(gb);
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
+ GET_MQUANT();
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
+ /* Set DC scale - y and c use the same (not sure if necessary here) */
+ s->y_dc_scale = s->y_dc_scale_table[mquant];
+ s->c_dc_scale = s->c_dc_scale_table[mquant];
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ v->mb_type[0][s->block_index[i]] = s->mb_intra;
+ v->a_avail = v->c_avail = 0;
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ if (i < 4) {
+ stride_y = s->linesize << fieldtx;
+ off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
+ } else {
+ stride_y = s->uvlinesize;
+ off = 0;
+ }
+ s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, stride_y);
+ //TODO: loop filter
+ }
+
+ } else { // inter MB
+ mb_has_coeffs = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][3];
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
+ v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
+ } else {
+ if ((ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV)
+ || (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV_FIELD)) {
+ v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
+ }
+ }
+ s->mb_intra = v->is_intra[s->mb_x] = 0;
+ for (i = 0; i < 6; i++)
+ v->mb_type[0][s->block_index[i]] = 0;
+ fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][1];
+ /* for all motion vector read MVDATA and motion compensate each block */
+ dst_idx = 0;
+ if (fourmv) {
+ mvbp = v->fourmvbp;
+ for (i = 0; i < 6; i++) {
+ if (i < 4) {
+ dmv_x = dmv_y = 0;
+ val = ((mvbp >> (3 - i)) & 1);
+ if (val) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ }
+ vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]);
+ vc1_mc_4mv_luma(v, i, 0);
+ } else if (i == 4) {
+ vc1_mc_4mv_chroma4(v);
+ }
+ }
+ } else if (twomv) {
+ mvbp = v->twomvbp;
+ dmv_x = dmv_y = 0;
+ if (mvbp & 2) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ }
+ vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0]);
+ vc1_mc_4mv_luma(v, 0, 0);
+ vc1_mc_4mv_luma(v, 1, 0);
+ dmv_x = dmv_y = 0;
+ if (mvbp & 1) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ }
+ vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0]);
+ vc1_mc_4mv_luma(v, 2, 0);
+ vc1_mc_4mv_luma(v, 3, 0);
+ vc1_mc_4mv_chroma4(v);
+ } else {
+ mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2];
+ if (mvbp) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ }
+ vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]);
+ vc1_mc_1mv(v, 0);
+ }
+ if (cbp)
+ GET_MQUANT(); // p. 227
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf && cbp)
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ if (!fieldtx)
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ else
+ off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize));
+ if (val) {
+ pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : (s->linesize << fieldtx),
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
+ block_cbp |= pat << (i << 2);
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
+ first_block = 0;
+ }
+ }
+ }
+ } else { // skipped
+ s->mb_intra = v->is_intra[s->mb_x] = 0;
+ for (i = 0; i < 6; i++) {
+ v->mb_type[0][s->block_index[i]] = 0;
+ s->dc_val[0][s->block_index[i]] = 0;
+ }
+ s->current_picture.f.mb_type[mb_pos] = MB_TYPE_SKIP;
+ s->current_picture.f.qscale_table[mb_pos] = 0;
+ v->blk_mv_type[s->block_index[0]] = 0;
+ v->blk_mv_type[s->block_index[1]] = 0;
+ v->blk_mv_type[s->block_index[2]] = 0;
+ v->blk_mv_type[s->block_index[3]] = 0;
+ vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]);
+ vc1_mc_1mv(v, 0);
+ }
+ if (s->mb_x == s->mb_width - 1)
+ memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride);
+ return 0;
+}
+
+static int vc1_decode_p_mb_intfi(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int cbp = 0; /* cbp decoding stuff */
+ int mqdiff, mquant; /* MB quantization */
+ int ttmb = v->ttfrm; /* MB Transform type */
+
+ int mb_has_coeffs = 1; /* last_flag */
+ int dmv_x, dmv_y; /* Differential MV components */
+ int val; /* temp values */
+ int first_block = 1;
+ int dst_idx, off;
+ int pred_flag;
+ int block_cbp = 0, pat, block_tt = 0;
+ int idx_mbmode = 0;
+
+ mquant = v->pq; /* Loosy initialization */
+
+ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
+ if (idx_mbmode <= 1) { // intra MB
+ s->mb_intra = v->is_intra[s->mb_x] = 1;
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+ s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
+ GET_MQUANT();
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
+ /* Set DC scale - y and c use the same (not sure if necessary here) */
+ s->y_dc_scale = s->y_dc_scale_table[mquant];
+ s->c_dc_scale = s->c_dc_scale_table[mquant];
+ v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
+ mb_has_coeffs = idx_mbmode & 1;
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2);
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ v->mb_type[0][s->block_index[i]] = 1;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ v->a_avail = v->c_avail = 0;
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
+ s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
+ // TODO: loop filter
+ }
+ } else {
+ s->mb_intra = v->is_intra[s->mb_x] = 0;
+ s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
+ for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
+ if (idx_mbmode <= 5) { // 1-MV
+ dmv_x = dmv_y = 0;
+ if (idx_mbmode & 1) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
+ }
+ vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
+ vc1_mc_1mv(v, 0);
+ mb_has_coeffs = !(idx_mbmode & 2);
+ } else { // 4-MV
+ v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
+ for (i = 0; i < 6; i++) {
+ if (i < 4) {
+ dmv_x = dmv_y = pred_flag = 0;
+ val = ((v->fourmvbp >> (3 - i)) & 1);
+ if (val) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
+ }
+ vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
+ vc1_mc_4mv_luma(v, i, 0);
+ } else if (i == 4)
+ vc1_mc_4mv_chroma(v, 0);
+ }
+ mb_has_coeffs = idx_mbmode & 1;
+ }
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ if (cbp) {
+ GET_MQUANT();
+ }
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf && cbp) {
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ }
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
+ if (v->cur_field_type)
+ off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0];
+ if (val) {
+ pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : s->linesize,
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY),
+ &block_tt);
+ block_cbp |= pat << (i << 2);
+ if (!v->ttmbf && ttmb < 8) ttmb = -1;
+ first_block = 0;
+ }
+ }
+ }
+ if (s->mb_x == s->mb_width - 1)
+ memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
+ return 0;
+}
+
/** Decode one B-frame MB (in Main profile)
*/
static void vc1_decode_b_mb(VC1Context *v)
@@ -2718,7 +4141,7 @@ static void vc1_decode_b_mb(VC1Context *v)
int dmv_x[2], dmv_y[2];
int bmvtype = BMV_TYPE_BACKWARD;
- mquant = v->pq; /* Loosy initialization */
+ mquant = v->pq; /* lossy initialization */
s->mb_intra = 0;
if (v->dmb_is_raw)
@@ -2731,11 +4154,11 @@ static void vc1_decode_b_mb(VC1Context *v)
skipped = v->s.mbskip_table[mb_pos];
dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
- for(i = 0; i < 6; i++) {
+ for (i = 0; i < 6; i++) {
v->mb_type[0][s->block_index[i]] = 0;
- s->dc_val[0][s->block_index[i]] = 0;
+ s->dc_val[0][s->block_index[i]] = 0;
}
- s->current_picture.qscale_table[mb_pos] = 0;
+ s->current_picture.f.qscale_table[mb_pos] = 0;
if (!direct) {
if (!skipped) {
@@ -2743,9 +4166,9 @@ static void vc1_decode_b_mb(VC1Context *v)
dmv_x[1] = dmv_x[0];
dmv_y[1] = dmv_y[0];
}
- if(skipped || !s->mb_intra) {
+ if (skipped || !s->mb_intra) {
bmvtype = decode012(gb);
- switch(bmvtype) {
+ switch (bmvtype) {
case 0:
bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;
break;
@@ -2753,16 +4176,17 @@ static void vc1_decode_b_mb(VC1Context *v)
bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;
break;
case 2:
- bmvtype = BMV_TYPE_INTERPOLATED;
+ bmvtype = BMV_TYPE_INTERPOLATED;
dmv_x[0] = dmv_y[0] = 0;
}
}
}
- for(i = 0; i < 6; i++)
+ for (i = 0; i < 6; i++)
v->mb_type[0][s->block_index[i]] = s->mb_intra;
if (skipped) {
- if(direct) bmvtype = BMV_TYPE_INTERPOLATED;
+ if (direct)
+ bmvtype = BMV_TYPE_INTERPOLATED;
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
return;
@@ -2771,73 +4195,236 @@ static void vc1_decode_b_mb(VC1Context *v)
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
GET_MQUANT();
s->mb_intra = 0;
- s->current_picture.qscale_table[mb_pos] = mquant;
- if(!v->ttmbf)
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf)
ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0;
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
} else {
- if(!mb_has_coeffs && !s->mb_intra) {
+ if (!mb_has_coeffs && !s->mb_intra) {
/* no coded blocks - effectively skipped */
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
return;
}
- if(s->mb_intra && !mb_has_coeffs) {
+ if (s->mb_intra && !mb_has_coeffs) {
GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
s->ac_pred = get_bits1(gb);
cbp = 0;
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
} else {
- if(bmvtype == BMV_TYPE_INTERPOLATED) {
+ if (bmvtype == BMV_TYPE_INTERPOLATED) {
GET_MVDATA(dmv_x[0], dmv_y[0]);
- if(!mb_has_coeffs) {
+ if (!mb_has_coeffs) {
/* interpolated skipped block */
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
return;
}
}
- vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
- if(!s->mb_intra) {
- vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
+ vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
+ if (!s->mb_intra) {
+ vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
+ }
+ if (s->mb_intra)
+ s->ac_pred = get_bits1(gb);
+ cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ GET_MQUANT();
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ }
+ }
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ v->mb_type[0][s->block_index[i]] = s->mb_intra;
+ if (s->mb_intra) {
+ /* check if prediction blocks A and C are available */
+ v->a_avail = v->c_avail = 0;
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[i][j] <<= 1;
+ s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
+ } else if (val) {
+ vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : s->linesize,
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY), NULL);
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
+ first_block = 0;
+ }
+ }
+}
+
+/** Decode one B-frame MB (in interlaced field B picture)
+ */
+static void vc1_decode_b_mb_intfi(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i, j;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int cbp = 0; /* cbp decoding stuff */
+ int mqdiff, mquant; /* MB quantization */
+ int ttmb = v->ttfrm; /* MB Transform type */
+ int mb_has_coeffs = 0; /* last_flag */
+ int val; /* temp value */
+ int first_block = 1;
+ int dst_idx, off;
+ int fwd;
+ int dmv_x[2], dmv_y[2], pred_flag[2];
+ int bmvtype = BMV_TYPE_BACKWARD;
+ int idx_mbmode, interpmvp;
+
+ mquant = v->pq; /* Loosy initialization */
+ s->mb_intra = 0;
+
+ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
+ if (idx_mbmode <= 1) { // intra MB
+ s->mb_intra = v->is_intra[s->mb_x] = 1;
+ s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
+ s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
+ GET_MQUANT();
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
+ /* Set DC scale - y and c use the same (not sure if necessary here) */
+ s->y_dc_scale = s->y_dc_scale_table[mquant];
+ s->c_dc_scale = s->c_dc_scale_table[mquant];
+ v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
+ mb_has_coeffs = idx_mbmode & 1;
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2);
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ v->mb_type[0][s->block_index[i]] = s->mb_intra;
+ v->a_avail = v->c_avail = 0;
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[i][j] <<= 1;
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
+ s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
+ // TODO: yet to perform loop filter
+ }
+ } else {
+ s->mb_intra = v->is_intra[s->mb_x] = 0;
+ s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
+ for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
+ if (v->fmb_is_raw)
+ fwd = v->forward_mb_plane[mb_pos] = get_bits1(gb);
+ else
+ fwd = v->forward_mb_plane[mb_pos];
+ if (idx_mbmode <= 5) { // 1-MV
+ dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
+ pred_flag[0] = pred_flag[1] = 0;
+ if (fwd)
+ bmvtype = BMV_TYPE_FORWARD;
+ else {
+ bmvtype = decode012(gb);
+ switch (bmvtype) {
+ case 0:
+ bmvtype = BMV_TYPE_BACKWARD;
+ break;
+ case 1:
+ bmvtype = BMV_TYPE_DIRECT;
+ break;
+ case 2:
+ bmvtype = BMV_TYPE_INTERPOLATED;
+ interpmvp = get_bits1(gb);
+ }
+ }
+ v->bmvtype = bmvtype;
+ if (bmvtype != BMV_TYPE_DIRECT && idx_mbmode & 1) {
+ get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD], &dmv_y[bmvtype == BMV_TYPE_BACKWARD], &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
}
- if(s->mb_intra)
- s->ac_pred = get_bits1(gb);
- cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ if (bmvtype == BMV_TYPE_INTERPOLATED && interpmvp) {
+ get_mvdata_interlaced(v, &dmv_x[1], &dmv_y[1], &pred_flag[1]);
+ }
+ if (bmvtype == BMV_TYPE_DIRECT) {
+ dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
+ dmv_x[1] = dmv_y[1] = pred_flag[0] = 0;
+ }
+ vc1_pred_b_mv_intfi(v, 0, dmv_x, dmv_y, 1, pred_flag);
+ vc1_b_mc(v, dmv_x, dmv_y, (bmvtype == BMV_TYPE_DIRECT), bmvtype);
+ mb_has_coeffs = !(idx_mbmode & 2);
+ } else { // 4-MV
+ if (fwd)
+ bmvtype = BMV_TYPE_FORWARD;
+ v->bmvtype = bmvtype;
+ v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
+ for (i = 0; i < 6; i++) {
+ if (i < 4) {
+ dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
+ dmv_x[1] = dmv_y[1] = pred_flag[1] = 0;
+ val = ((v->fourmvbp >> (3 - i)) & 1);
+ if (val) {
+ get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD],
+ &dmv_y[bmvtype == BMV_TYPE_BACKWARD],
+ &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
+ }
+ vc1_pred_b_mv_intfi(v, i, dmv_x, dmv_y, 0, pred_flag);
+ vc1_mc_4mv_luma(v, i, bmvtype == BMV_TYPE_BACKWARD);
+ } else if (i == 4)
+ vc1_mc_4mv_chroma(v, bmvtype == BMV_TYPE_BACKWARD);
+ }
+ mb_has_coeffs = idx_mbmode & 1;
+ }
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ if (cbp) {
GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
- if(!v->ttmbf && !s->mb_intra && mb_has_coeffs)
- ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
}
- }
- dst_idx = 0;
- for (i=0; i<6; i++)
- {
- s->dc_val[0][s->block_index[i]] = 0;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
- v->mb_type[0][s->block_index[i]] = s->mb_intra;
- if(s->mb_intra) {
- /* check if prediction blocks A and C are available */
- v->a_avail = v->c_avail = 0;
- if(i == 2 || i == 3 || !s->first_slice_line)
- v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
- if(i == 1 || i == 3 || s->mb_x)
- v->c_avail = v->mb_type[0][s->block_index[i] - 1];
-
- vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
- if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
- v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
- if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
- s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
- } else if(val) {
- vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), NULL);
- if(!v->ttmbf && ttmb < 8) ttmb = -1;
- first_block = 0;
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf && cbp) {
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ }
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
+ if (v->cur_field_type)
+ off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0];
+ if (val) {
+ vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : s->linesize,
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY), NULL);
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
+ first_block = 0;
+ }
}
}
}
@@ -2853,7 +4440,7 @@ static void vc1_decode_i_blocks(VC1Context *v)
int mb_pos;
/* select codingmode used for VLC tables selection */
- switch(v->y_ac_table_index){
+ switch (v->y_ac_table_index) {
case 0:
v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
break;
@@ -2865,7 +4452,7 @@ static void vc1_decode_i_blocks(VC1Context *v)
break;
}
- switch(v->c_ac_table_index){
+ switch (v->c_ac_table_index) {
case 0:
v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
break;
@@ -2883,12 +4470,12 @@ static void vc1_decode_i_blocks(VC1Context *v)
//do frame decode
s->mb_x = s->mb_y = 0;
- s->mb_intra = 1;
+ s->mb_intra = 1;
s->first_slice_line = 1;
- for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
+ for (s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
s->mb_x = 0;
ff_init_block_index(s);
- for(; s->mb_x < s->mb_width; s->mb_x++) {
+ for (; s->mb_x < s->mb_width; s->mb_x++) {
uint8_t *dst[6];
ff_update_block_index(s);
dst[0] = s->dest[0];
@@ -2899,53 +4486,58 @@ static void vc1_decode_i_blocks(VC1Context *v)
dst[5] = s->dest[2];
s->dsp.clear_blocks(s->block[0]);
mb_pos = s->mb_x + s->mb_y * s->mb_width;
- s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
- s->current_picture.qscale_table[mb_pos] = v->pq;
- s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
- s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
+ s->current_picture.f.mb_type[mb_pos] = MB_TYPE_INTRA;
+ s->current_picture.f.qscale_table[mb_pos] = v->pq;
+ s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
// do actual MB decoding and displaying
cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
v->s.ac_pred = get_bits1(&v->s.gb);
- for(k = 0; k < 6; k++) {
+ for (k = 0; k < 6; k++) {
val = ((cbp >> (5 - k)) & 1);
if (k < 4) {
- int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
- val = val ^ pred;
+ int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
+ val = val ^ pred;
*coded_val = val;
}
cbp |= val << (5 - k);
- vc1_decode_i_block(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2);
+ vc1_decode_i_block(v, s->block[k], k, val, (k < 4) ? v->codingset : v->codingset2);
- if (k > 3 && (s->flags & CODEC_FLAG_GRAY)) continue;
+ if (k > 3 && (s->flags & CODEC_FLAG_GRAY))
+ continue;
v->vc1dsp.vc1_inv_trans_8x8(s->block[k]);
- if(v->pq >= 9 && v->overlap) {
- if (v->rangeredfrm) for(j = 0; j < 64; j++) s->block[k][j] <<= 1;
+ if (v->pq >= 9 && v->overlap) {
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[k][j] <<= 1;
s->dsp.put_signed_pixels_clamped(s->block[k], dst[k], k & 4 ? s->uvlinesize : s->linesize);
} else {
- if (v->rangeredfrm) for(j = 0; j < 64; j++) s->block[k][j] = (s->block[k][j] - 64) << 1;
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[k][j] = (s->block[k][j] - 64) << 1;
s->dsp.put_pixels_clamped(s->block[k], dst[k], k & 4 ? s->uvlinesize : s->linesize);
}
}
- if(v->pq >= 9 && v->overlap) {
- if(s->mb_x) {
+ if (v->pq >= 9 && v->overlap) {
+ if (s->mb_x) {
v->vc1dsp.vc1_h_overlap(s->dest[0], s->linesize);
v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
- if(!(s->flags & CODEC_FLAG_GRAY)) {
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
v->vc1dsp.vc1_h_overlap(s->dest[1], s->uvlinesize);
v->vc1dsp.vc1_h_overlap(s->dest[2], s->uvlinesize);
}
}
v->vc1dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize);
v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
- if(!s->first_slice_line) {
+ if (!s->first_slice_line) {
v->vc1dsp.vc1_v_overlap(s->dest[0], s->linesize);
v->vc1dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize);
- if(!(s->flags & CODEC_FLAG_GRAY)) {
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
v->vc1dsp.vc1_v_overlap(s->dest[1], s->uvlinesize);
v->vc1dsp.vc1_v_overlap(s->dest[2], s->uvlinesize);
}
@@ -2953,24 +4545,25 @@ static void vc1_decode_i_blocks(VC1Context *v)
v->vc1dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
v->vc1dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
}
- if(v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
+ if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
- if(get_bits_count(&s->gb) > v->bits) {
- ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END));
- av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits);
+ if (get_bits_count(&s->gb) > v->bits) {
+ ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR);
+ av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
+ get_bits_count(&s->gb), v->bits);
return;
}
}
if (!v->s.loop_filter)
ff_draw_horiz_band(s, s->mb_y * 16, 16);
else if (s->mb_y)
- ff_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
+ ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
s->first_slice_line = 0;
}
if (v->s.loop_filter)
- ff_draw_horiz_band(s, (s->mb_height-1)*16, 16);
- ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
+ ff_draw_horiz_band(s, (s->mb_height - 1) * 16, 16);
+ ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END);
}
/** Decode blocks of I-frame for advanced profile
@@ -2987,7 +4580,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
GetBitContext *gb = &s->gb;
/* select codingmode used for VLC tables selection */
- switch(v->y_ac_table_index){
+ switch (v->y_ac_table_index) {
case 0:
v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
break;
@@ -2999,7 +4592,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
break;
}
- switch(v->c_ac_table_index){
+ switch (v->c_ac_table_index) {
case 0:
v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
break;
@@ -3011,32 +4604,34 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
break;
}
- //do frame decode
- s->mb_x = s->mb_y = 0;
- s->mb_intra = 1;
+ // do frame decode
+ s->mb_x = s->mb_y = 0;
+ s->mb_intra = 1;
s->first_slice_line = 1;
- s->mb_y = s->start_mb_y;
+ s->mb_y = s->start_mb_y;
if (s->start_mb_y) {
s->mb_x = 0;
ff_init_block_index(s);
- memset(&s->coded_block[s->block_index[0]-s->b8_stride], 0,
+ memset(&s->coded_block[s->block_index[0] - s->b8_stride], 0,
(1 + s->b8_stride) * sizeof(*s->coded_block));
}
- for(; s->mb_y < s->end_mb_y; s->mb_y++) {
+ for (; s->mb_y < s->end_mb_y; s->mb_y++) {
s->mb_x = 0;
ff_init_block_index(s);
- for(;s->mb_x < s->mb_width; s->mb_x++) {
+ for (;s->mb_x < s->mb_width; s->mb_x++) {
DCTELEM (*block)[64] = v->block[v->cur_blk_idx];
ff_update_block_index(s);
s->dsp.clear_blocks(block[0]);
mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
- s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
- s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
+ s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+ s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
// do actual MB decoding and displaying
+ if (v->fieldtx_is_raw)
+ v->fieldtx_plane[mb_pos] = get_bits1(&v->s.gb);
cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
- if(v->acpred_is_raw)
+ if ( v->acpred_is_raw)
v->s.ac_pred = get_bits1(&v->s.gb);
else
v->s.ac_pred = v->acpred_plane[mb_pos];
@@ -3046,37 +4641,41 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
+ s->current_picture.f.qscale_table[mb_pos] = mquant;
/* Set DC scale - y and c use the same */
s->y_dc_scale = s->y_dc_scale_table[mquant];
s->c_dc_scale = s->c_dc_scale_table[mquant];
- for(k = 0; k < 6; k++) {
+ for (k = 0; k < 6; k++) {
val = ((cbp >> (5 - k)) & 1);
if (k < 4) {
- int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
- val = val ^ pred;
+ int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
+ val = val ^ pred;
*coded_val = val;
}
cbp |= val << (5 - k);
- v->a_avail = !s->first_slice_line || (k==2 || k==3);
- v->c_avail = !!s->mb_x || (k==1 || k==3);
+ v->a_avail = !s->first_slice_line || (k == 2 || k == 3);
+ v->c_avail = !!s->mb_x || (k == 1 || k == 3);
- vc1_decode_i_block_adv(v, block[k], k, val, (k<4)? v->codingset : v->codingset2, mquant);
+ vc1_decode_i_block_adv(v, block[k], k, val,
+ (k < 4) ? v->codingset : v->codingset2, mquant);
- if (k > 3 && (s->flags & CODEC_FLAG_GRAY)) continue;
+ if (k > 3 && (s->flags & CODEC_FLAG_GRAY))
+ continue;
v->vc1dsp.vc1_inv_trans_8x8(block[k]);
}
vc1_smooth_overlap_filter_iblk(v);
vc1_put_signed_blocks_clamped(v);
- if(v->s.loop_filter) vc1_loop_filter_iblk_delayed(v, v->pq);
+ if (v->s.loop_filter) vc1_loop_filter_iblk_delayed(v, v->pq);
- if(get_bits_count(&s->gb) > v->bits) {
- ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END));
- av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits);
+ if (get_bits_count(&s->gb) > v->bits) {
+ // TODO: may need modification to handle slice coding
+ ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+ av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
+ get_bits_count(&s->gb), v->bits);
return;
}
}
@@ -3090,14 +4689,16 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
/* raw bottom MB row */
s->mb_x = 0;
ff_init_block_index(s);
- for(;s->mb_x < s->mb_width; s->mb_x++) {
+ for (;s->mb_x < s->mb_width; s->mb_x++) {
ff_update_block_index(s);
vc1_put_signed_blocks_clamped(v);
- if(v->s.loop_filter) vc1_loop_filter_iblk_delayed(v, v->pq);
+ if (v->s.loop_filter)
+ vc1_loop_filter_iblk_delayed(v, v->pq);
}
if (v->s.loop_filter)
ff_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
- ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END));
+ ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+ (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
}
static void vc1_decode_p_blocks(VC1Context *v)
@@ -3106,7 +4707,7 @@ static void vc1_decode_p_blocks(VC1Context *v)
int apply_loop_filter;
/* select codingmode used for VLC tables selection */
- switch(v->c_ac_table_index){
+ switch (v->c_ac_table_index) {
case 0:
v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
break;
@@ -3118,7 +4719,7 @@ static void vc1_decode_p_blocks(VC1Context *v)
break;
}
- switch(v->c_ac_table_index){
+ switch (v->c_ac_table_index) {
case 0:
v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
break;
@@ -3130,29 +4731,35 @@ static void vc1_decode_p_blocks(VC1Context *v)
break;
}
- apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY);
+ apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY);
s->first_slice_line = 1;
memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride);
- for(s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
+ for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
s->mb_x = 0;
ff_init_block_index(s);
- for(; s->mb_x < s->mb_width; s->mb_x++) {
+ for (; s->mb_x < s->mb_width; s->mb_x++) {
ff_update_block_index(s);
- vc1_decode_p_mb(v);
- if (s->mb_y != s->start_mb_y && apply_loop_filter)
+ if (v->fcm == ILACE_FIELD)
+ vc1_decode_p_mb_intfi(v);
+ else if (v->fcm == ILACE_FRAME)
+ vc1_decode_p_mb_intfr(v);
+ else vc1_decode_p_mb(v);
+ if (s->mb_y != s->start_mb_y && apply_loop_filter && v->fcm == PROGRESSIVE)
vc1_apply_p_loop_filter(v);
- if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
- ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END));
- av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y);
+ if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
+ // TODO: may need modification to handle slice coding
+ ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+ av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
+ get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
return;
}
}
- memmove(v->cbp_base, v->cbp, sizeof(v->cbp_base[0])*s->mb_stride);
- memmove(v->ttblk_base, v->ttblk, sizeof(v->ttblk_base[0])*s->mb_stride);
- memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride);
- memmove(v->luma_mv_base, v->luma_mv, sizeof(v->luma_mv_base[0])*s->mb_stride);
- if (s->mb_y != s->start_mb_y) ff_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
+ memmove(v->cbp_base, v->cbp, sizeof(v->cbp_base[0]) * s->mb_stride);
+ memmove(v->ttblk_base, v->ttblk, sizeof(v->ttblk_base[0]) * s->mb_stride);
+ memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
+ memmove(v->luma_mv_base, v->luma_mv, sizeof(v->luma_mv_base[0]) * s->mb_stride);
+ if (s->mb_y != s->start_mb_y) ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
s->first_slice_line = 0;
}
if (apply_loop_filter) {
@@ -3164,8 +4771,9 @@ static void vc1_decode_p_blocks(VC1Context *v)
}
}
if (s->end_mb_y >= s->start_mb_y)
- ff_draw_horiz_band(s, (s->end_mb_y-1) * 16, 16);
- ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END));
+ ff_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+ ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+ (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
}
static void vc1_decode_b_blocks(VC1Context *v)
@@ -3173,7 +4781,7 @@ static void vc1_decode_b_blocks(VC1Context *v)
MpegEncContext *s = &v->s;
/* select codingmode used for VLC tables selection */
- switch(v->c_ac_table_index){
+ switch (v->c_ac_table_index) {
case 0:
v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
break;
@@ -3185,7 +4793,7 @@ static void vc1_decode_b_blocks(VC1Context *v)
break;
}
- switch(v->c_ac_table_index){
+ switch (v->c_ac_table_index) {
case 0:
v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
break;
@@ -3198,44 +4806,50 @@ static void vc1_decode_b_blocks(VC1Context *v)
}
s->first_slice_line = 1;
- for(s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
+ for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
s->mb_x = 0;
ff_init_block_index(s);
- for(; s->mb_x < s->mb_width; s->mb_x++) {
+ for (; s->mb_x < s->mb_width; s->mb_x++) {
ff_update_block_index(s);
- vc1_decode_b_mb(v);
- if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
- ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END));
- av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y);
+ if (v->fcm == ILACE_FIELD)
+ vc1_decode_b_mb_intfi(v);
+ else
+ vc1_decode_b_mb(v);
+ if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
+ // TODO: may need modification to handle slice coding
+ ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+ av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
+ get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
return;
}
- if(v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
+ if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
}
if (!v->s.loop_filter)
ff_draw_horiz_band(s, s->mb_y * 16, 16);
else if (s->mb_y)
- ff_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
+ ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
s->first_slice_line = 0;
}
if (v->s.loop_filter)
- ff_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
- ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END));
+ ff_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+ ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+ (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
}
static void vc1_decode_skip_blocks(VC1Context *v)
{
MpegEncContext *s = &v->s;
- ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END));
+ ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END);
s->first_slice_line = 1;
- for(s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
+ for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
s->mb_x = 0;
ff_init_block_index(s);
ff_update_block_index(s);
- memcpy(s->dest[0], s->last_picture.data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16);
- memcpy(s->dest[1], s->last_picture.data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
- memcpy(s->dest[2], s->last_picture.data[2] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
+ memcpy(s->dest[0], s->last_picture.f.data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16);
+ memcpy(s->dest[1], s->last_picture.f.data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
+ memcpy(s->dest[2], s->last_picture.f.data[2] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
ff_draw_horiz_band(s, s->mb_y * 16, 16);
s->first_slice_line = 0;
}
@@ -3246,147 +4860,376 @@ static void vc1_decode_blocks(VC1Context *v)
{
v->s.esc3_level_length = 0;
- if(v->x8_type){
- ff_intrax8_decode_picture(&v->x8, 2*v->pq+v->halfpq, v->pq*(!v->pquantizer) );
- }else{
- v->cur_blk_idx = 0;
- v->left_blk_idx = -1;
- v->topleft_blk_idx = 1;
- v->top_blk_idx = 2;
- switch(v->s.pict_type) {
+ if (v->x8_type) {
+ ff_intrax8_decode_picture(&v->x8, 2*v->pq + v->halfpq, v->pq * !v->pquantizer);
+ } else {
+ v->cur_blk_idx = 0;
+ v->left_blk_idx = -1;
+ v->topleft_blk_idx = 1;
+ v->top_blk_idx = 2;
+ switch (v->s.pict_type) {
case AV_PICTURE_TYPE_I:
- if(v->profile == PROFILE_ADVANCED)
+ if (v->profile == PROFILE_ADVANCED)
vc1_decode_i_blocks_adv(v);
else
vc1_decode_i_blocks(v);
break;
case AV_PICTURE_TYPE_P:
- if(v->p_frame_skipped)
+ if (v->p_frame_skipped)
vc1_decode_skip_blocks(v);
else
vc1_decode_p_blocks(v);
break;
case AV_PICTURE_TYPE_B:
- if(v->bi_type){
- if(v->profile == PROFILE_ADVANCED)
+ if (v->bi_type) {
+ if (v->profile == PROFILE_ADVANCED)
vc1_decode_i_blocks_adv(v);
else
vc1_decode_i_blocks(v);
- }else
+ } else
vc1_decode_b_blocks(v);
break;
}
}
}
-static inline float get_float_val(GetBitContext* gb)
+#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
+
+typedef struct {
+ /**
+ * Transform coefficients for both sprites in 16.16 fixed point format,
+ * in the order they appear in the bitstream:
+ * x scale
+ * rotation 1 (unused)
+ * x offset
+ * rotation 2 (unused)
+ * y scale
+ * y offset
+ * alpha
+ */
+ int coefs[2][7];
+
+ int effect_type, effect_flag;
+ int effect_pcount1, effect_pcount2; ///< amount of effect parameters stored in effect_params
+ int effect_params1[15], effect_params2[10]; ///< effect parameters in 16.16 fixed point format
+} SpriteData;
+
+static inline int get_fp_val(GetBitContext* gb)
{
- return (float)get_bits_long(gb, 30) / (1<<15) - (1<<14);
+ return (get_bits_long(gb, 30) - (1 << 29)) << 1;
}
-static void vc1_sprite_parse_transform(VC1Context *v, GetBitContext* gb, float c[7])
+static void vc1_sprite_parse_transform(GetBitContext* gb, int c[7])
{
- c[1] = c[3] = 0.0f;
+ c[1] = c[3] = 0;
switch (get_bits(gb, 2)) {
case 0:
- c[0] = 1.0f;
- c[2] = get_float_val(gb);
- c[4] = 1.0f;
+ c[0] = 1 << 16;
+ c[2] = get_fp_val(gb);
+ c[4] = 1 << 16;
break;
case 1:
- c[0] = c[4] = get_float_val(gb);
- c[2] = get_float_val(gb);
+ c[0] = c[4] = get_fp_val(gb);
+ c[2] = get_fp_val(gb);
break;
case 2:
- c[0] = get_float_val(gb);
- c[2] = get_float_val(gb);
- c[4] = get_float_val(gb);
+ c[0] = get_fp_val(gb);
+ c[2] = get_fp_val(gb);
+ c[4] = get_fp_val(gb);
break;
case 3:
- av_log_ask_for_sample(v->s.avctx, NULL);
- c[0] = get_float_val(gb);
- c[1] = get_float_val(gb);
- c[2] = get_float_val(gb);
- c[3] = get_float_val(gb);
- c[4] = get_float_val(gb);
+ c[0] = get_fp_val(gb);
+ c[1] = get_fp_val(gb);
+ c[2] = get_fp_val(gb);
+ c[3] = get_fp_val(gb);
+ c[4] = get_fp_val(gb);
break;
}
- c[5] = get_float_val(gb);
+ c[5] = get_fp_val(gb);
if (get_bits1(gb))
- c[6] = get_float_val(gb);
+ c[6] = get_fp_val(gb);
else
- c[6] = 1.0f;
+ c[6] = 1 << 16;
}
-static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb)
+static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd)
{
- int effect_type, effect_flag, effect_pcount1, effect_pcount2, i;
- float effect_params1[14], effect_params2[10];
-
- float coefs[2][7];
- vc1_sprite_parse_transform(v, gb, coefs[0]);
- av_log(v->s.avctx, AV_LOG_DEBUG, "S1:");
- for (i = 0; i < 7; i++)
- av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", coefs[0][i]);
- av_log(v->s.avctx, AV_LOG_DEBUG, "\n");
-
- if (v->two_sprites) {
- vc1_sprite_parse_transform(v, gb, coefs[1]);
- av_log(v->s.avctx, AV_LOG_DEBUG, "S2:");
+ AVCodecContext *avctx = v->s.avctx;
+ int sprite, i;
+
+ for (sprite = 0; sprite <= v->two_sprites; sprite++) {
+ vc1_sprite_parse_transform(gb, sd->coefs[sprite]);
+ if (sd->coefs[sprite][1] || sd->coefs[sprite][3])
+ av_log_ask_for_sample(avctx, "Rotation coefficients are not zero");
+ av_log(avctx, AV_LOG_DEBUG, sprite ? "S2:" : "S1:");
for (i = 0; i < 7; i++)
- av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", coefs[1][i]);
- av_log(v->s.avctx, AV_LOG_DEBUG, "\n");
+ av_log(avctx, AV_LOG_DEBUG, " %d.%.3d",
+ sd->coefs[sprite][i] / (1<<16),
+ (abs(sd->coefs[sprite][i]) & 0xFFFF) * 1000 / (1 << 16));
+ av_log(avctx, AV_LOG_DEBUG, "\n");
}
+
skip_bits(gb, 2);
- if (effect_type = get_bits_long(gb, 30)){
- switch (effect_pcount1 = get_bits(gb, 4)) {
- case 2:
- effect_params1[0] = get_float_val(gb);
- effect_params1[1] = get_float_val(gb);
- break;
+ if (sd->effect_type = get_bits_long(gb, 30)) {
+ switch (sd->effect_pcount1 = get_bits(gb, 4)) {
case 7:
- vc1_sprite_parse_transform(v, gb, effect_params1);
+ vc1_sprite_parse_transform(gb, sd->effect_params1);
break;
case 14:
- vc1_sprite_parse_transform(v, gb, effect_params1);
- vc1_sprite_parse_transform(v, gb, &effect_params1[7]);
+ vc1_sprite_parse_transform(gb, sd->effect_params1);
+ vc1_sprite_parse_transform(gb, sd->effect_params1 + 7);
break;
default:
- av_log_ask_for_sample(v->s.avctx, NULL);
- return;
+ for (i = 0; i < sd->effect_pcount1; i++)
+ sd->effect_params1[i] = get_fp_val(gb);
}
- if (effect_type != 13 || effect_params1[0] != coefs[0][6]) {
+ if (sd->effect_type != 13 || sd->effect_params1[0] != sd->coefs[0][6]) {
// effect 13 is simple alpha blending and matches the opacity above
- av_log(v->s.avctx, AV_LOG_DEBUG, "Effect: %d; params: ", effect_type);
- for (i = 0; i < effect_pcount1; i++)
- av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", effect_params1[i]);
- av_log(v->s.avctx, AV_LOG_DEBUG, "\n");
+ av_log(avctx, AV_LOG_DEBUG, "Effect: %d; params: ", sd->effect_type);
+ for (i = 0; i < sd->effect_pcount1; i++)
+ av_log(avctx, AV_LOG_DEBUG, " %d.%.2d",
+ sd->effect_params1[i] / (1 << 16),
+ (abs(sd->effect_params1[i]) & 0xFFFF) * 1000 / (1 << 16));
+ av_log(avctx, AV_LOG_DEBUG, "\n");
}
- effect_pcount2 = get_bits(gb, 16);
- if (effect_pcount2 > 10) {
- av_log(v->s.avctx, AV_LOG_ERROR, "Too many effect parameters\n");
+ sd->effect_pcount2 = get_bits(gb, 16);
+ if (sd->effect_pcount2 > 10) {
+ av_log(avctx, AV_LOG_ERROR, "Too many effect parameters\n");
return;
- } else if (effect_pcount2) {
- i = 0;
- av_log(v->s.avctx, AV_LOG_DEBUG, "Effect params 2: ");
- while (i < effect_pcount2){
- effect_params2[i] = get_float_val(gb);
- av_log(v->s.avctx, AV_LOG_DEBUG, " %.3f", effect_params2[i]);
- i++;
+ } else if (sd->effect_pcount2) {
+ i = -1;
+ av_log(avctx, AV_LOG_DEBUG, "Effect params 2: ");
+ while (++i < sd->effect_pcount2) {
+ sd->effect_params2[i] = get_fp_val(gb);
+ av_log(avctx, AV_LOG_DEBUG, " %d.%.2d",
+ sd->effect_params2[i] / (1 << 16),
+ (abs(sd->effect_params2[i]) & 0xFFFF) * 1000 / (1 << 16));
}
- av_log(v->s.avctx, AV_LOG_DEBUG, "\n");
+ av_log(avctx, AV_LOG_DEBUG, "\n");
}
}
- if (effect_flag = get_bits1(gb))
- av_log(v->s.avctx, AV_LOG_DEBUG, "Effect flag set\n");
+ if (sd->effect_flag = get_bits1(gb))
+ av_log(avctx, AV_LOG_DEBUG, "Effect flag set\n");
if (get_bits_count(gb) >= gb->size_in_bits +
- (v->s.avctx->codec_id == CODEC_ID_WMV3 ? 64 : 0))
- av_log(v->s.avctx, AV_LOG_ERROR, "Buffer overrun\n");
+ (avctx->codec_id == CODEC_ID_WMV3IMAGE ? 64 : 0))
+ av_log(avctx, AV_LOG_ERROR, "Buffer overrun\n");
if (get_bits_count(gb) < gb->size_in_bits - 8)
- av_log(v->s.avctx, AV_LOG_WARNING, "Buffer not fully read\n");
+ av_log(avctx, AV_LOG_WARNING, "Buffer not fully read\n");
+}
+
+static void vc1_draw_sprites(VC1Context *v, SpriteData* sd)
+{
+ int i, plane, row, sprite;
+ int sr_cache[2][2] = { { -1, -1 }, { -1, -1 } };
+ uint8_t* src_h[2][2];
+ int xoff[2], xadv[2], yoff[2], yadv[2], alpha;
+ int ysub[2];
+ MpegEncContext *s = &v->s;
+
+ for (i = 0; i < 2; i++) {
+ xoff[i] = av_clip(sd->coefs[i][2], 0, v->sprite_width-1 << 16);
+ xadv[i] = sd->coefs[i][0];
+ if (xadv[i] != 1<<16 || (v->sprite_width << 16) - (v->output_width << 16) - xoff[i])
+ xadv[i] = av_clip(xadv[i], 0, ((v->sprite_width<<16) - xoff[i] - 1) / v->output_width);
+
+ yoff[i] = av_clip(sd->coefs[i][5], 0, v->sprite_height-1 << 16);
+ yadv[i] = av_clip(sd->coefs[i][4], 0, ((v->sprite_height << 16) - yoff[i]) / v->output_height);
+ }
+ alpha = av_clip(sd->coefs[1][6], 0, (1<<16) - 1);
+
+ for (plane = 0; plane < (s->flags&CODEC_FLAG_GRAY ? 1 : 3); plane++) {
+ int width = v->output_width>>!!plane;
+
+ for (row = 0; row < v->output_height>>!!plane; row++) {
+ uint8_t *dst = v->sprite_output_frame.data[plane] +
+ v->sprite_output_frame.linesize[plane] * row;
+
+ for (sprite = 0; sprite <= v->two_sprites; sprite++) {
+ uint8_t *iplane = s->current_picture.f.data[plane];
+ int iline = s->current_picture.f.linesize[plane];
+ int ycoord = yoff[sprite] + yadv[sprite] * row;
+ int yline = ycoord >> 16;
+ ysub[sprite] = ycoord & 0xFFFF;
+ if (sprite) {
+ iplane = s->last_picture.f.data[plane];
+ iline = s->last_picture.f.linesize[plane];
+ }
+ if (!(xoff[sprite] & 0xFFFF) && xadv[sprite] == 1 << 16) {
+ src_h[sprite][0] = iplane + (xoff[sprite] >> 16) + yline * iline;
+ if (ysub[sprite])
+ src_h[sprite][1] = iplane + (xoff[sprite] >> 16) + (yline + 1) * iline;
+ } else {
+ if (sr_cache[sprite][0] != yline) {
+ if (sr_cache[sprite][1] == yline) {
+ FFSWAP(uint8_t*, v->sr_rows[sprite][0], v->sr_rows[sprite][1]);
+ FFSWAP(int, sr_cache[sprite][0], sr_cache[sprite][1]);
+ } else {
+ v->vc1dsp.sprite_h(v->sr_rows[sprite][0], iplane + yline * iline, xoff[sprite], xadv[sprite], width);
+ sr_cache[sprite][0] = yline;
+ }
+ }
+ if (ysub[sprite] && sr_cache[sprite][1] != yline + 1) {
+ v->vc1dsp.sprite_h(v->sr_rows[sprite][1], iplane + (yline + 1) * iline, xoff[sprite], xadv[sprite], width);
+ sr_cache[sprite][1] = yline + 1;
+ }
+ src_h[sprite][0] = v->sr_rows[sprite][0];
+ src_h[sprite][1] = v->sr_rows[sprite][1];
+ }
+ }
+
+ if (!v->two_sprites) {
+ if (ysub[0]) {
+ v->vc1dsp.sprite_v_single(dst, src_h[0][0], src_h[0][1], ysub[0], width);
+ } else {
+ memcpy(dst, src_h[0][0], width);
+ }
+ } else {
+ if (ysub[0] && ysub[1]) {
+ v->vc1dsp.sprite_v_double_twoscale(dst, src_h[0][0], src_h[0][1], ysub[0],
+ src_h[1][0], src_h[1][1], ysub[1], alpha, width);
+ } else if (ysub[0]) {
+ v->vc1dsp.sprite_v_double_onescale(dst, src_h[0][0], src_h[0][1], ysub[0],
+ src_h[1][0], alpha, width);
+ } else if (ysub[1]) {
+ v->vc1dsp.sprite_v_double_onescale(dst, src_h[1][0], src_h[1][1], ysub[1],
+ src_h[0][0], (1<<16)-1-alpha, width);
+ } else {
+ v->vc1dsp.sprite_v_double_noscale(dst, src_h[0][0], src_h[1][0], alpha, width);
+ }
+ }
+ }
+
+ if (!plane) {
+ for (i = 0; i < 2; i++) {
+ xoff[i] >>= 1;
+ yoff[i] >>= 1;
+ }
+ }
+
+ }
+}
+
+
+static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb)
+{
+ MpegEncContext *s = &v->s;
+ AVCodecContext *avctx = s->avctx;
+ SpriteData sd;
+
+ vc1_parse_sprites(v, gb, &sd);
+
+ if (!s->current_picture.f.data[0]) {
+ av_log(avctx, AV_LOG_ERROR, "Got no sprites\n");
+ return -1;
+ }
+
+ if (v->two_sprites && (!s->last_picture_ptr || !s->last_picture.f.data[0])) {
+ av_log(avctx, AV_LOG_WARNING, "Need two sprites, only got one\n");
+ v->two_sprites = 0;
+ }
+
+ if (v->sprite_output_frame.data[0])
+ avctx->release_buffer(avctx, &v->sprite_output_frame);
+
+ v->sprite_output_frame.buffer_hints = FF_BUFFER_HINTS_VALID;
+ v->sprite_output_frame.reference = 0;
+ if (avctx->get_buffer(avctx, &v->sprite_output_frame) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return -1;
+ }
+
+ vc1_draw_sprites(v, &sd);
+
+ return 0;
+}
+
+static void vc1_sprite_flush(AVCodecContext *avctx)
+{
+ VC1Context *v = avctx->priv_data;
+ MpegEncContext *s = &v->s;
+ AVFrame *f = &s->current_picture.f;
+ int plane, i;
+
+ /* Windows Media Image codecs have a convergence interval of two keyframes.
+ Since we can't enforce it, clear to black the missing sprite. This is
+ wrong but it looks better than doing nothing. */
+
+ if (f->data[0])
+ for (plane = 0; plane < (s->flags&CODEC_FLAG_GRAY ? 1 : 3); plane++)
+ for (i = 0; i < v->sprite_height>>!!plane; i++)
+ memset(f->data[plane] + i * f->linesize[plane],
+ plane ? 128 : 0, f->linesize[plane]);
+}
+
+#endif
+
+static av_cold int vc1_decode_init_alloc_tables(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ int i;
+
+ /* Allocate mb bitplanes */
+ v->mv_type_mb_plane = av_malloc (s->mb_stride * s->mb_height);
+ v->direct_mb_plane = av_malloc (s->mb_stride * s->mb_height);
+ v->forward_mb_plane = av_malloc (s->mb_stride * s->mb_height);
+ v->fieldtx_plane = av_mallocz(s->mb_stride * s->mb_height);
+ v->acpred_plane = av_malloc (s->mb_stride * s->mb_height);
+ v->over_flags_plane = av_malloc (s->mb_stride * s->mb_height);
+
+ v->n_allocated_blks = s->mb_width + 2;
+ v->block = av_malloc(sizeof(*v->block) * v->n_allocated_blks);
+ v->cbp_base = av_malloc(sizeof(v->cbp_base[0]) * 2 * s->mb_stride);
+ v->cbp = v->cbp_base + s->mb_stride;
+ v->ttblk_base = av_malloc(sizeof(v->ttblk_base[0]) * 2 * s->mb_stride);
+ v->ttblk = v->ttblk_base + s->mb_stride;
+ v->is_intra_base = av_mallocz(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride);
+ v->is_intra = v->is_intra_base + s->mb_stride;
+ v->luma_mv_base = av_malloc(sizeof(v->luma_mv_base[0]) * 2 * s->mb_stride);
+ v->luma_mv = v->luma_mv_base + s->mb_stride;
+
+ /* allocate block type info in that way so it could be used with s->block_index[] */
+ v->mb_type_base = av_malloc(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
+ v->mb_type[0] = v->mb_type_base + s->b8_stride + 1;
+ v->mb_type[1] = v->mb_type_base + s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride + 1;
+ v->mb_type[2] = v->mb_type[1] + s->mb_stride * (s->mb_height + 1);
+
+ /* allocate memory to store block level MV info */
+ v->blk_mv_type_base = av_mallocz( s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
+ v->blk_mv_type = v->blk_mv_type_base + s->b8_stride + 1;
+ v->mv_f_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
+ v->mv_f[0] = v->mv_f_base + s->b8_stride + 1;
+ v->mv_f[1] = v->mv_f[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
+ v->mv_f_last_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
+ v->mv_f_last[0] = v->mv_f_last_base + s->b8_stride + 1;
+ v->mv_f_last[1] = v->mv_f_last[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
+ v->mv_f_next_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
+ v->mv_f_next[0] = v->mv_f_next_base + s->b8_stride + 1;
+ v->mv_f_next[1] = v->mv_f_next[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
+
+ /* Init coded blocks info */
+ if (v->profile == PROFILE_ADVANCED) {
+// if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0)
+// return -1;
+// if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0)
+// return -1;
+ }
+
+ ff_intrax8_common_init(&v->x8,s);
+
+ if (s->avctx->codec_id == CODEC_ID_WMV3IMAGE || s->avctx->codec_id == CODEC_ID_VC1IMAGE) {
+ for (i = 0; i < 4; i++)
+ if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width))) return -1;
+ }
+
+ if (!v->mv_type_mb_plane || !v->direct_mb_plane || !v->acpred_plane || !v->over_flags_plane ||
+ !v->block || !v->cbp_base || !v->ttblk_base || !v->is_intra_base || !v->luma_mv_base ||
+ !v->mb_type_base)
+ return -1;
+
+ return 0;
}
/** Initialize a VC1/WMV3 decoder
@@ -3398,9 +5241,14 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
VC1Context *v = avctx->priv_data;
MpegEncContext *s = &v->s;
GetBitContext gb;
- int i, cur_width, cur_height;
+ int i;
+
+ /* save the container output size for WMImage */
+ v->output_width = avctx->width;
+ v->output_height = avctx->height;
- if (!avctx->extradata_size || !avctx->extradata) return -1;
+ if (!avctx->extradata_size || !avctx->extradata)
+ return -1;
if (!(avctx->flags & CODEC_FLAG_GRAY))
avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
else
@@ -3408,21 +5256,17 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
v->s.avctx = avctx;
avctx->flags |= CODEC_FLAG_EMU_EDGE;
- v->s.flags |= CODEC_FLAG_EMU_EDGE;
+ v->s.flags |= CODEC_FLAG_EMU_EDGE;
- if(avctx->idct_algo==FF_IDCT_AUTO){
- avctx->idct_algo=FF_IDCT_WMV2;
+ if (avctx->idct_algo == FF_IDCT_AUTO) {
+ avctx->idct_algo = FF_IDCT_WMV2;
}
- if(ff_msmpeg4_decode_init(avctx) < 0)
+ if (vc1_init_common(v) < 0)
return -1;
- if (vc1_init_common(v) < 0) return -1;
ff_vc1dsp_init(&v->vc1dsp);
- cur_width = avctx->coded_width = avctx->width;
- cur_height = avctx->coded_height = avctx->height;
- if (avctx->codec_id == CODEC_ID_WMV3)
- {
+ if (avctx->codec_id == CODEC_ID_WMV3 || avctx->codec_id == CODEC_ID_WMV3IMAGE) {
int count = 0;
// looks like WMV3 has a sequence header stored in the extradata
@@ -3436,13 +5280,10 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
return -1;
count = avctx->extradata_size*8 - get_bits_count(&gb);
- if (count>0)
- {
+ if (count > 0) {
av_log(avctx, AV_LOG_INFO, "Extra data: %i bits left, value: %X\n",
count, get_bits(&gb, count));
- }
- else if (count < 0)
- {
+ } else if (count < 0) {
av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count);
}
} else { // VC1/WVC1/WVP2
@@ -3453,30 +5294,31 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
uint8_t *buf2 = NULL;
int seq_initialized = 0, ep_initialized = 0;
- if(avctx->extradata_size < 16) {
+ if (avctx->extradata_size < 16) {
av_log(avctx, AV_LOG_ERROR, "Extradata size too small: %i\n", avctx->extradata_size);
return -1;
}
- buf2 = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ buf2 = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
start = find_next_marker(start, end); // in WVC1 extradata first byte is its size, but can be 0 in mkv
- next = start;
- for(; next < end; start = next){
+ next = start;
+ for (; next < end; start = next) {
next = find_next_marker(start + 4, end);
size = next - start - 4;
- if(size <= 0) continue;
+ if (size <= 0)
+ continue;
buf2_size = vc1_unescape_buffer(start + 4, size, buf2);
init_get_bits(&gb, buf2, buf2_size * 8);
- switch(AV_RB32(start)){
+ switch (AV_RB32(start)) {
case VC1_CODE_SEQHDR:
- if(vc1_decode_sequence_header(avctx, v, &gb) < 0){
+ if (vc1_decode_sequence_header(avctx, v, &gb) < 0) {
av_free(buf2);
return -1;
}
seq_initialized = 1;
break;
case VC1_CODE_ENTRYPOINT:
- if(vc1_decode_entry_point(avctx, v, &gb) < 0){
+ if (vc1_decode_entry_point(avctx, v, &gb) < 0) {
av_free(buf2);
return -1;
}
@@ -3485,42 +5327,30 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
}
}
av_free(buf2);
- if(!seq_initialized || !ep_initialized){
+ if (!seq_initialized || !ep_initialized) {
av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n");
return -1;
}
v->res_sprite = (avctx->codec_tag == MKTAG('W','V','P','2'));
}
- // Sequence header information may not have been parsed
- // yet when ff_msmpeg4_decode_init was called the fist time
- // above. If sequence information changes, we need to call
- // it again.
- if (cur_width != avctx->width ||
- cur_height != avctx->height) {
- MPV_common_end(s);
- if(ff_msmpeg4_decode_init(avctx) < 0)
- return -1;
- avctx->coded_width = avctx->width;
- avctx->coded_height = avctx->height;
- }
avctx->profile = v->profile;
if (v->profile == PROFILE_ADVANCED)
avctx->level = v->level;
- avctx->has_b_frames= !!(avctx->max_b_frames);
- s->low_delay = !avctx->has_b_frames;
+ avctx->has_b_frames = !!(avctx->max_b_frames);
- s->mb_width = (avctx->coded_width+15)>>4;
- s->mb_height = (avctx->coded_height+15)>>4;
+ s->mb_width = (avctx->coded_width + 15) >> 4;
+ s->mb_height = (avctx->coded_height + 15) >> 4;
if (v->profile == PROFILE_ADVANCED || v->res_fasttx) {
- for (i = 0; i < 64; i++) {
-#define transpose(x) ((x>>3) | ((x&7)<<3))
+ for (i = 0; i < 64; i++) {
+#define transpose(x) ((x >> 3) | ((x & 7) << 3))
v->zz_8x8[0][i] = transpose(wmv1_scantable[0][i]);
v->zz_8x8[1][i] = transpose(wmv1_scantable[1][i]);
v->zz_8x8[2][i] = transpose(wmv1_scantable[2][i]);
v->zz_8x8[3][i] = transpose(wmv1_scantable[3][i]);
+ v->zzi_8x8[i] = transpose(ff_vc1_adv_interlaced_8x8_zz[i]);
}
v->left_blk_sh = 0;
v->top_blk_sh = 3;
@@ -3530,39 +5360,55 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
v->top_blk_sh = 0;
}
- /* Allocate mb bitplanes */
- v->mv_type_mb_plane = av_malloc(s->mb_stride * s->mb_height);
- v->direct_mb_plane = av_malloc(s->mb_stride * s->mb_height);
- v->acpred_plane = av_malloc(s->mb_stride * s->mb_height);
- v->over_flags_plane = av_malloc(s->mb_stride * s->mb_height);
-
- v->n_allocated_blks = s->mb_width + 2;
- v->block = av_malloc(sizeof(*v->block) * v->n_allocated_blks);
- v->cbp_base = av_malloc(sizeof(v->cbp_base[0]) * 2 * s->mb_stride);
- v->cbp = v->cbp_base + s->mb_stride;
- v->ttblk_base = av_malloc(sizeof(v->ttblk_base[0]) * 2 * s->mb_stride);
- v->ttblk = v->ttblk_base + s->mb_stride;
- v->is_intra_base = av_malloc(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride);
- v->is_intra = v->is_intra_base + s->mb_stride;
- v->luma_mv_base = av_malloc(sizeof(v->luma_mv_base[0]) * 2 * s->mb_stride);
- v->luma_mv = v->luma_mv_base + s->mb_stride;
+ if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
+ v->sprite_width = avctx->coded_width;
+ v->sprite_height = avctx->coded_height;
- /* allocate block type info in that way so it could be used with s->block_index[] */
- v->mb_type_base = av_malloc(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
- v->mb_type[0] = v->mb_type_base + s->b8_stride + 1;
- v->mb_type[1] = v->mb_type_base + s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride + 1;
- v->mb_type[2] = v->mb_type[1] + s->mb_stride * (s->mb_height + 1);
+ avctx->coded_width = avctx->width = v->output_width;
+ avctx->coded_height = avctx->height = v->output_height;
- /* Init coded blocks info */
- if (v->profile == PROFILE_ADVANCED)
- {
-// if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0)
-// return -1;
-// if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0)
-// return -1;
+ // prevent 16.16 overflows
+ if (v->sprite_width > 1 << 14 ||
+ v->sprite_height > 1 << 14 ||
+ v->output_width > 1 << 14 ||
+ v->output_height > 1 << 14) return -1;
}
+ return 0;
+}
- ff_intrax8_common_init(&v->x8,s);
+/** Close a VC1/WMV3 decoder
+ * @warning Initial try at using MpegEncContext stuff
+ */
+static av_cold int vc1_decode_end(AVCodecContext *avctx)
+{
+ VC1Context *v = avctx->priv_data;
+ int i;
+
+ if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE)
+ && v->sprite_output_frame.data[0])
+ avctx->release_buffer(avctx, &v->sprite_output_frame);
+ for (i = 0; i < 4; i++)
+ av_freep(&v->sr_rows[i >> 1][i & 1]);
+ av_freep(&v->hrd_rate);
+ av_freep(&v->hrd_buffer);
+ MPV_common_end(&v->s);
+ av_freep(&v->mv_type_mb_plane);
+ av_freep(&v->direct_mb_plane);
+ av_freep(&v->forward_mb_plane);
+ av_freep(&v->fieldtx_plane);
+ av_freep(&v->acpred_plane);
+ av_freep(&v->over_flags_plane);
+ av_freep(&v->mb_type_base);
+ av_freep(&v->blk_mv_type_base);
+ av_freep(&v->mv_f_base);
+ av_freep(&v->mv_f_last_base);
+ av_freep(&v->mv_f_next_base);
+ av_freep(&v->block);
+ av_freep(&v->cbp_base);
+ av_freep(&v->ttblk_base);
+ av_freep(&v->is_intra_base); // FIXME use v->mb_type[]
+ av_freep(&v->luma_mv_base);
+ ff_intrax8_common_end(&v->x8);
return 0;
}
@@ -3570,9 +5416,8 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
/** Decode a VC1/WMV3 frame
* @todo TODO: Handle VC-1 IDUs (Transport level?)
*/
-static int vc1_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int vc1_decode_frame(AVCodecContext *avctx, void *data,
+ int *data_size, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size, n_slices = 0, i;
@@ -3581,18 +5426,19 @@ static int vc1_decode_frame(AVCodecContext *avctx,
AVFrame *pict = data;
uint8_t *buf2 = NULL;
const uint8_t *buf_start = buf;
+ int mb_height, n_slices1;
struct {
uint8_t *buf;
GetBitContext gb;
int mby_start;
- } *slices = NULL;
+ } *slices = NULL, *tmp;
/* no supplementary picture */
if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) {
/* special case for last picture */
- if (s->low_delay==0 && s->next_picture_ptr) {
- *pict= *(AVFrame*)s->next_picture_ptr;
- s->next_picture_ptr= NULL;
+ if (s->low_delay == 0 && s->next_picture_ptr) {
+ *pict = *(AVFrame*)s->next_picture_ptr;
+ s->next_picture_ptr = NULL;
*data_size = sizeof(AVFrame);
}
@@ -3600,14 +5446,7 @@ static int vc1_decode_frame(AVCodecContext *avctx,
return 0;
}
- /* We need to set current_picture_ptr before reading the header,
- * otherwise we cannot store anything in there. */
- if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){
- int i= ff_find_unused_picture(s, 0);
- s->current_picture_ptr= &s->picture[i];
- }
-
- if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){
+ if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
if (v->profile < PROFILE_ADVANCED)
avctx->pix_fmt = PIX_FMT_VDPAU_WMV3;
else
@@ -3615,37 +5454,58 @@ static int vc1_decode_frame(AVCodecContext *avctx,
}
//for advanced profile we may need to parse and unescape data
- if (avctx->codec_id == CODEC_ID_VC1) {
+ if (avctx->codec_id == CODEC_ID_VC1 || avctx->codec_id == CODEC_ID_VC1IMAGE) {
int buf_size2 = 0;
buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
- if(IS_MARKER(AV_RB32(buf))){ /* frame starts with marker and needs to be parsed */
+ if (IS_MARKER(AV_RB32(buf))) { /* frame starts with marker and needs to be parsed */
const uint8_t *start, *end, *next;
int size;
next = buf;
- for(start = buf, end = buf + buf_size; next < end; start = next){
+ for (start = buf, end = buf + buf_size; next < end; start = next) {
next = find_next_marker(start + 4, end);
size = next - start - 4;
- if(size <= 0) continue;
- switch(AV_RB32(start)){
+ if (size <= 0) continue;
+ switch (AV_RB32(start)) {
case VC1_CODE_FRAME:
if (avctx->hwaccel ||
s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
buf_start = start;
buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
break;
+ case VC1_CODE_FIELD: {
+ int buf_size3;
+ slices = av_realloc(slices, sizeof(*slices) * (n_slices+1));
+ if (!slices)
+ goto err;
+ slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!slices[n_slices].buf)
+ goto err;
+ buf_size3 = vc1_unescape_buffer(start + 4, size,
+ slices[n_slices].buf);
+ init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
+ buf_size3 << 3);
+ /* assuming that the field marker is at the exact middle,
+ hope it's correct */
+ slices[n_slices].mby_start = s->mb_height >> 1;
+ n_slices1 = n_slices - 1; // index of the last slice of the first field
+ n_slices++;
+ break;
+ }
case VC1_CODE_ENTRYPOINT: /* it should be before frame data */
buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
- init_get_bits(&s->gb, buf2, buf_size2*8);
+ init_get_bits(&s->gb, buf2, buf_size2 * 8);
vc1_decode_entry_point(avctx, v, &s->gb);
break;
case VC1_CODE_SLICE: {
int buf_size3;
slices = av_realloc(slices, sizeof(*slices) * (n_slices+1));
- if (!slices) goto err;
+ if (!slices)
+ goto err;
slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!slices[n_slices].buf) goto err;
+ if (!slices[n_slices].buf)
+ goto err;
buf_size3 = vc1_unescape_buffer(start + 4, size,
slices[n_slices].buf);
init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
@@ -3656,21 +5516,31 @@ static int vc1_decode_frame(AVCodecContext *avctx,
}
}
}
- }else if(v->interlace && ((buf[0] & 0xC0) == 0xC0)){ /* WVC1 interlaced stores both fields divided by marker */
+ } else if (v->interlace && ((buf[0] & 0xC0) == 0xC0)) { /* WVC1 interlaced stores both fields divided by marker */
const uint8_t *divider;
+ int buf_size3;
divider = find_next_marker(buf, buf + buf_size);
- if((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD){
+ if ((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD) {
av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n");
goto err;
+ } else { // found field marker, unescape second field
+ tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));
+ if (!tmp)
+ goto err;
+ slices = tmp;
+ slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!slices[n_slices].buf)
+ goto err;
+ buf_size3 = vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, slices[n_slices].buf);
+ init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
+ buf_size3 << 3);
+ slices[n_slices].mby_start = s->mb_height >> 1;
+ n_slices1 = n_slices - 1;
+ n_slices++;
}
-
buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2);
- // TODO
- if(!v->warn_interlaced++)
- av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced WVC1 support is not implemented\n");
- goto err;
- }else{
+ } else {
buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2);
}
init_get_bits(&s->gb, buf2, buf_size2*8);
@@ -3678,54 +5548,107 @@ static int vc1_decode_frame(AVCodecContext *avctx,
init_get_bits(&s->gb, buf, buf_size*8);
if (v->res_sprite) {
- v->new_sprite = !get_bits1(&s->gb);
- v->two_sprites = get_bits1(&s->gb);
- if (!v->new_sprite)
- goto end;
+ v->new_sprite = !get_bits1(&s->gb);
+ v->two_sprites = get_bits1(&s->gb);
+ /* res_sprite means a Windows Media Image stream, CODEC_ID_*IMAGE means
+ we're using the sprite compositor. These are intentionally kept separate
+ so you can get the raw sprites by using the wmv3 decoder for WMVP or
+ the vc1 one for WVP2 */
+ if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
+ if (v->new_sprite) {
+ // switch AVCodecContext parameters to those of the sprites
+ avctx->width = avctx->coded_width = v->sprite_width;
+ avctx->height = avctx->coded_height = v->sprite_height;
+ } else {
+ goto image;
+ }
+ }
+ }
+
+ if (s->context_initialized &&
+ (s->width != avctx->coded_width ||
+ s->height != avctx->coded_height)) {
+ vc1_decode_end(avctx);
+ }
+
+ if (!s->context_initialized) {
+ if (ff_msmpeg4_decode_init(avctx) < 0 || vc1_decode_init_alloc_tables(v) < 0)
+ return -1;
+
+ s->low_delay = !avctx->has_b_frames || v->res_sprite;
+
+ if (v->profile == PROFILE_ADVANCED) {
+ s->h_edge_pos = avctx->coded_width;
+ s->v_edge_pos = avctx->coded_height;
+ }
+ }
+
+ /* We need to set current_picture_ptr before reading the header,
+ * otherwise we cannot store anything in there. */
+ if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) {
+ int i = ff_find_unused_picture(s, 0);
+ if (i < 0)
+ goto err;
+ s->current_picture_ptr = &s->picture[i];
}
// do parse frame header
- if(v->profile < PROFILE_ADVANCED) {
- if(vc1_parse_frame_header(v, &s->gb) == -1) {
+ v->pic_header_flag = 0;
+ if (v->profile < PROFILE_ADVANCED) {
+ if (vc1_parse_frame_header(v, &s->gb) == -1) {
goto err;
}
} else {
- if(vc1_parse_frame_header_adv(v, &s->gb) == -1) {
+ if (vc1_parse_frame_header_adv(v, &s->gb) == -1) {
goto err;
}
}
- if (v->res_sprite && s->pict_type!=AV_PICTURE_TYPE_I) {
- av_log(v->s.avctx, AV_LOG_WARNING, "Sprite decoder: expected I-frame\n");
+ if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE)
+ && s->pict_type != AV_PICTURE_TYPE_I) {
+ av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected I-frame\n");
+ goto err;
+ }
+
+ // process pulldown flags
+ s->current_picture_ptr->f.repeat_pict = 0;
+ // Pulldown flags are only valid when 'broadcast' has been set.
+ // So ticks_per_frame will be 2
+ if (v->rff) {
+ // repeat field
+ s->current_picture_ptr->f.repeat_pict = 1;
+ } else if (v->rptfrm) {
+ // repeat frames
+ s->current_picture_ptr->f.repeat_pict = v->rptfrm * 2;
}
// for skipping the frame
- s->current_picture.pict_type= s->pict_type;
- s->current_picture.key_frame= s->pict_type == AV_PICTURE_TYPE_I;
+ s->current_picture.f.pict_type = s->pict_type;
+ s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
/* skip B-frames if we don't have reference frames */
- if(s->last_picture_ptr==NULL && (s->pict_type==AV_PICTURE_TYPE_B || s->dropable)){
+ if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->dropable)) {
goto err;
}
- if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B)
- || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I)
- || avctx->skip_frame >= AVDISCARD_ALL) {
+ if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) ||
+ (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) ||
+ avctx->skip_frame >= AVDISCARD_ALL) {
goto end;
}
- if(s->next_p_frame_damaged){
- if(s->pict_type==AV_PICTURE_TYPE_B)
+ if (s->next_p_frame_damaged) {
+ if (s->pict_type == AV_PICTURE_TYPE_B)
goto end;
else
- s->next_p_frame_damaged=0;
+ s->next_p_frame_damaged = 0;
}
- if(MPV_frame_start(s, avctx) < 0) {
+ if (MPV_frame_start(s, avctx) < 0) {
goto err;
}
- s->me.qpel_put= s->dsp.put_qpel_pixels_tab;
- s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
+ s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
+ s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
if ((CONFIG_VC1_VDPAU_DECODER)
&&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
@@ -3741,38 +5664,96 @@ static int vc1_decode_frame(AVCodecContext *avctx,
ff_er_frame_start(s);
v->bits = buf_size * 8;
+ if (v->field_mode) {
+ uint8_t *tmp[2];
+ s->current_picture.f.linesize[0] <<= 1;
+ s->current_picture.f.linesize[1] <<= 1;
+ s->current_picture.f.linesize[2] <<= 1;
+ s->linesize <<= 1;
+ s->uvlinesize <<= 1;
+ tmp[0] = v->mv_f_last[0];
+ tmp[1] = v->mv_f_last[1];
+ v->mv_f_last[0] = v->mv_f_next[0];
+ v->mv_f_last[1] = v->mv_f_next[1];
+ v->mv_f_next[0] = v->mv_f[0];
+ v->mv_f_next[1] = v->mv_f[1];
+ v->mv_f[0] = tmp[0];
+ v->mv_f[1] = tmp[1];
+ }
+ mb_height = s->mb_height >> v->field_mode;
for (i = 0; i <= n_slices; i++) {
- if (i && get_bits1(&s->gb))
- vc1_parse_frame_header_adv(v, &s->gb);
- s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start);
- s->end_mb_y = (i == n_slices) ? s->mb_height : FFMIN(s->mb_height, slices[i].mby_start);
+ if (i > 0 && slices[i - 1].mby_start >= mb_height) {
+ v->second_field = 1;
+ v->blocks_off = s->mb_width * s->mb_height << 1;
+ v->mb_off = s->mb_stride * s->mb_height >> 1;
+ } else {
+ v->second_field = 0;
+ v->blocks_off = 0;
+ v->mb_off = 0;
+ }
+ if (i) {
+ v->pic_header_flag = 0;
+ if (v->field_mode && i == n_slices1 + 2)
+ vc1_parse_frame_header_adv(v, &s->gb);
+ else if (get_bits1(&s->gb)) {
+ v->pic_header_flag = 1;
+ vc1_parse_frame_header_adv(v, &s->gb);
+ }
+ }
+ s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start % mb_height);
+ if (!v->field_mode || v->second_field)
+ s->end_mb_y = (i == n_slices ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
+ else
+ s->end_mb_y = (i == n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
vc1_decode_blocks(v);
- if (i != n_slices) s->gb = slices[i].gb;
+ if (i != n_slices)
+ s->gb = slices[i].gb;
+ }
+ if (v->field_mode) {
+ v->second_field = 0;
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
+ memcpy(v->mv_f_base, v->mv_f_next_base,
+ 2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
+ }
+ s->current_picture.f.linesize[0] >>= 1;
+ s->current_picture.f.linesize[1] >>= 1;
+ s->current_picture.f.linesize[2] >>= 1;
+ s->linesize >>= 1;
+ s->uvlinesize >>= 1;
}
//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), s->gb.size_in_bits);
-// if(get_bits_count(&s->gb) > buf_size * 8)
+// if (get_bits_count(&s->gb) > buf_size * 8)
// return -1;
ff_er_frame_end(s);
}
MPV_frame_end(s);
-assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);
-assert(s->current_picture.pict_type == s->pict_type);
- if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
- *pict= *(AVFrame*)s->current_picture_ptr;
- } else if (s->last_picture_ptr != NULL) {
- *pict= *(AVFrame*)s->last_picture_ptr;
- }
-
- if(s->last_picture_ptr || s->low_delay){
+ if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
+image:
+ avctx->width = avctx->coded_width = v->output_width;
+ avctx->height = avctx->coded_height = v->output_height;
+ if (avctx->skip_frame >= AVDISCARD_NONREF)
+ goto end;
+#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
+ if (vc1_decode_sprites(v, &s->gb))
+ goto err;
+#endif
+ *pict = v->sprite_output_frame;
*data_size = sizeof(AVFrame);
- ff_print_debug_info(s, pict);
+ } else {
+ if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
+ *pict = *(AVFrame*)s->current_picture_ptr;
+ } else if (s->last_picture_ptr != NULL) {
+ *pict = *(AVFrame*)s->last_picture_ptr;
+ }
+ if (s->last_picture_ptr || s->low_delay) {
+ *data_size = sizeof(AVFrame);
+ ff_print_debug_info(s, pict);
+ }
}
end:
- if (v->res_sprite)
- vc1_parse_sprites(v, &s->gb);
av_free(buf2);
for (i = 0; i < n_slices; i++)
av_free(slices[i].buf);
@@ -3788,30 +5769,6 @@ err:
}
-/** Close a VC1/WMV3 decoder
- * @warning Initial try at using MpegEncContext stuff
- */
-static av_cold int vc1_decode_end(AVCodecContext *avctx)
-{
- VC1Context *v = avctx->priv_data;
-
- av_freep(&v->hrd_rate);
- av_freep(&v->hrd_buffer);
- MPV_common_end(&v->s);
- av_freep(&v->mv_type_mb_plane);
- av_freep(&v->direct_mb_plane);
- av_freep(&v->acpred_plane);
- av_freep(&v->over_flags_plane);
- av_freep(&v->mb_type_base);
- av_freep(&v->block);
- av_freep(&v->cbp_base);
- av_freep(&v->ttblk_base);
- av_freep(&v->is_intra_base); // FIXME use v->mb_type[]
- av_freep(&v->luma_mv_base);
- ff_intrax8_common_end(&v->x8);
- return 0;
-}
-
static const AVProfile profiles[] = {
{ FF_PROFILE_VC1_SIMPLE, "Simple" },
{ FF_PROFILE_VC1_MAIN, "Main" },
@@ -3821,71 +5778,95 @@ static const AVProfile profiles[] = {
};
AVCodec ff_vc1_decoder = {
- "vc1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VC1,
- sizeof(VC1Context),
- vc1_decode_init,
- NULL,
- vc1_decode_end,
- vc1_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY,
- NULL,
- .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"),
- .pix_fmts = ff_hwaccel_pixfmt_list_420,
- .profiles = NULL_IF_CONFIG_SMALL(profiles)
+ .name = "vc1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VC1,
+ .priv_data_size = sizeof(VC1Context),
+ .init = vc1_decode_init,
+ .close = vc1_decode_end,
+ .decode = vc1_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+ .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"),
+ .pix_fmts = ff_hwaccel_pixfmt_list_420,
+ .profiles = NULL_IF_CONFIG_SMALL(profiles)
};
#if CONFIG_WMV3_DECODER
AVCodec ff_wmv3_decoder = {
- "wmv3",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_WMV3,
- sizeof(VC1Context),
- vc1_decode_init,
- NULL,
- vc1_decode_end,
- vc1_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY,
- NULL,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"),
- .pix_fmts = ff_hwaccel_pixfmt_list_420,
- .profiles = NULL_IF_CONFIG_SMALL(profiles)
+ .name = "wmv3",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_WMV3,
+ .priv_data_size = sizeof(VC1Context),
+ .init = vc1_decode_init,
+ .close = vc1_decode_end,
+ .decode = vc1_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"),
+ .pix_fmts = ff_hwaccel_pixfmt_list_420,
+ .profiles = NULL_IF_CONFIG_SMALL(profiles)
};
#endif
#if CONFIG_WMV3_VDPAU_DECODER
AVCodec ff_wmv3_vdpau_decoder = {
- "wmv3_vdpau",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_WMV3,
- sizeof(VC1Context),
- vc1_decode_init,
- NULL,
- vc1_decode_end,
- vc1_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
- NULL,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"),
- .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_WMV3, PIX_FMT_NONE},
- .profiles = NULL_IF_CONFIG_SMALL(profiles)
+ .name = "wmv3_vdpau",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_WMV3,
+ .priv_data_size = sizeof(VC1Context),
+ .init = vc1_decode_init,
+ .close = vc1_decode_end,
+ .decode = vc1_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"),
+ .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_WMV3, PIX_FMT_NONE},
+ .profiles = NULL_IF_CONFIG_SMALL(profiles)
};
#endif
#if CONFIG_VC1_VDPAU_DECODER
AVCodec ff_vc1_vdpau_decoder = {
- "vc1_vdpau",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VC1,
- sizeof(VC1Context),
- vc1_decode_init,
- NULL,
- vc1_decode_end,
- vc1_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
- NULL,
- .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"),
- .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_VC1, PIX_FMT_NONE},
- .profiles = NULL_IF_CONFIG_SMALL(profiles)
+ .name = "vc1_vdpau",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VC1,
+ .priv_data_size = sizeof(VC1Context),
+ .init = vc1_decode_init,
+ .close = vc1_decode_end,
+ .decode = vc1_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
+ .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"),
+ .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_VC1, PIX_FMT_NONE},
+ .profiles = NULL_IF_CONFIG_SMALL(profiles)
+};
+#endif
+
+#if CONFIG_WMV3IMAGE_DECODER
+AVCodec ff_wmv3image_decoder = {
+ .name = "wmv3image",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_WMV3IMAGE,
+ .priv_data_size = sizeof(VC1Context),
+ .init = vc1_decode_init,
+ .close = vc1_decode_end,
+ .decode = vc1_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .flush = vc1_sprite_flush,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"),
+ .pix_fmts = ff_pixfmt_list_420
+};
+#endif
+
+#if CONFIG_VC1IMAGE_DECODER
+AVCodec ff_vc1image_decoder = {
+ .name = "vc1image",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VC1IMAGE,
+ .priv_data_size = sizeof(VC1Context),
+ .init = vc1_decode_init,
+ .close = vc1_decode_end,
+ .decode = vc1_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .flush = vc1_sprite_flush,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"),
+ .pix_fmts = ff_pixfmt_list_420
};
#endif
diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c
index 7d0e406..9bd107c 100644
--- a/libavcodec/vc1dsp.c
+++ b/libavcodec/vc1dsp.c
@@ -550,8 +550,8 @@ static av_always_inline int vc1_mspel_ ## DIR ## _filter_16bits(const TYPE *src,
return 0; /* should not occur */ \
}
-VC1_MSPEL_FILTER_16B(ver, uint8_t);
-VC1_MSPEL_FILTER_16B(hor, int16_t);
+VC1_MSPEL_FILTER_16B(ver, uint8_t)
+VC1_MSPEL_FILTER_16B(hor, int16_t)
/** Filter used to interpolate fractional pel values
@@ -688,6 +688,26 @@ static void put_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a
}
}
+static void put_no_rnd_vc1_chroma_mc4_c(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y){
+ const int A=(8-x)*(8-y);
+ const int B=( x)*(8-y);
+ const int C=(8-x)*( y);
+ const int D=( x)*( y);
+ int i;
+
+ assert(x<8 && y<8 && x>=0 && y>=0);
+
+ for(i=0; i<h; i++)
+ {
+ dst[0] = (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + 32 - 4) >> 6;
+ dst[1] = (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6;
+ dst[2] = (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6;
+ dst[3] = (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6;
+ dst+= stride;
+ src+= stride;
+ }
+}
+
#define avg2(a,b) ((a+b+1)>>1)
static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){
const int A=(8-x)*(8-y);
@@ -713,6 +733,66 @@ static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a
}
}
+#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
+
+static void sprite_h_c(uint8_t *dst, const uint8_t *src, int offset, int advance, int count)
+{
+ while (count--) {
+ int a = src[(offset >> 16) ];
+ int b = src[(offset >> 16) + 1];
+ *dst++ = a + ((b - a) * (offset&0xFFFF) >> 16);
+ offset += advance;
+ }
+}
+
+static av_always_inline void sprite_v_template(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
+ int two_sprites, const uint8_t *src2a, const uint8_t *src2b, int offset2,
+ int alpha, int scaled, int width)
+{
+ int a1, b1, a2, b2;
+ while (width--) {
+ a1 = *src1a++;
+ if (scaled) {
+ b1 = *src1b++;
+ a1 = a1 + ((b1 - a1) * offset1 >> 16);
+ }
+ if (two_sprites) {
+ a2 = *src2a++;
+ if (scaled > 1) {
+ b2 = *src2b++;
+ a2 = a2 + ((b2 - a2) * offset2 >> 16);
+ }
+ a1 = a1 + ((a2 - a1) * alpha >> 16);
+ }
+ *dst++ = a1;
+ }
+}
+
+static void sprite_v_single_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset, int width)
+{
+ sprite_v_template(dst, src1a, src1b, offset, 0, NULL, NULL, 0, 0, 1, width);
+}
+
+static void sprite_v_double_noscale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src2a, int alpha, int width)
+{
+ sprite_v_template(dst, src1a, NULL, 0, 1, src2a, NULL, 0, alpha, 0, width);
+}
+
+static void sprite_v_double_onescale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
+ const uint8_t *src2a, int alpha, int width)
+{
+ sprite_v_template(dst, src1a, src1b, offset1, 1, src2a, NULL, 0, alpha, 1, width);
+}
+
+static void sprite_v_double_twoscale_c(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
+ const uint8_t *src2a, const uint8_t *src2b, int offset2,
+ int alpha, int width)
+{
+ sprite_v_template(dst, src1a, src1b, offset1, 1, src2a, src2b, offset2, alpha, 2, width);
+}
+
+#endif
+
av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c;
dsp->vc1_inv_trans_4x8 = vc1_inv_trans_4x8_c;
@@ -769,6 +849,15 @@ av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c;
dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c;
+ dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = put_no_rnd_vc1_chroma_mc4_c;
+
+#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
+ dsp->sprite_h = sprite_h_c;
+ dsp->sprite_v_single = sprite_v_single_c;
+ dsp->sprite_v_double_noscale = sprite_v_double_noscale_c;
+ dsp->sprite_v_double_onescale = sprite_v_double_onescale_c;
+ dsp->sprite_v_double_twoscale = sprite_v_double_twoscale_c;
+#endif
if (HAVE_ALTIVEC)
ff_vc1dsp_init_altivec(dsp);
diff --git a/libavcodec/vc1dsp.h b/libavcodec/vc1dsp.h
index e1b6ba0..3e0a88e 100644
--- a/libavcodec/vc1dsp.h
+++ b/libavcodec/vc1dsp.h
@@ -60,6 +60,16 @@ typedef struct VC1DSPContext {
/* This is really one func used in VC-1 decoding */
h264_chroma_mc_func put_no_rnd_vc1_chroma_pixels_tab[3];
h264_chroma_mc_func avg_no_rnd_vc1_chroma_pixels_tab[3];
+
+ /* Windows Media Image functions */
+ void (*sprite_h)(uint8_t *dst, const uint8_t *src, int offset, int advance, int count);
+ void (*sprite_v_single)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset, int width);
+ void (*sprite_v_double_noscale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src2a, int alpha, int width);
+ void (*sprite_v_double_onescale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
+ const uint8_t *src2a, int alpha, int width);
+ void (*sprite_v_double_twoscale)(uint8_t *dst, const uint8_t *src1a, const uint8_t *src1b, int offset1,
+ const uint8_t *src2a, const uint8_t *src2b, int offset2,
+ int alpha, int width);
} VC1DSPContext;
void ff_vc1dsp_init(VC1DSPContext* c);
diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c
index aaf8eae..e50e092 100644
--- a/libavcodec/vcr1.c
+++ b/libavcodec/vcr1.c
@@ -114,8 +114,6 @@ static int decode_frame(AVCodecContext *avctx,
*picture= *(AVFrame*)&a->picture;
*data_size = sizeof(AVPicture);
- emms_c();
-
return buf_size;
}
@@ -130,9 +128,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
p->pict_type= AV_PICTURE_TYPE_I;
p->key_frame= 1;
- emms_c();
-
- align_put_bits(&a->pb);
+ avpriv_align_put_bits(&a->pb);
while(get_bit_count(&a->pb)&31)
put_bits(&a->pb, 8, 0);
@@ -177,27 +173,25 @@ static av_cold int encode_init(AVCodecContext *avctx){
#endif
AVCodec ff_vcr1_decoder = {
- "vcr1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VCR1,
- sizeof(VCR1Context),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "vcr1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VCR1,
+ .priv_data_size = sizeof(VCR1Context),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
};
#if CONFIG_VCR1_ENCODER
AVCodec ff_vcr1_encoder = {
- "vcr1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VCR1,
- sizeof(VCR1Context),
- encode_init,
- encode_frame,
- //encode_end,
+ .name = "vcr1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VCR1,
+ .priv_data_size = sizeof(VCR1Context),
+ .init = encode_init,
+ .encode = encode_frame,
.long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
};
#endif
diff --git a/libavcodec/vda.c b/libavcodec/vda.c
new file mode 100644
index 0000000..34739f8
--- /dev/null
+++ b/libavcodec/vda.c
@@ -0,0 +1,259 @@
+/*
+ * VDA hardware acceleration
+ *
+ * copyright (c) 2011 Sebastien Zwickert
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <pthread.h>
+#include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFData.h>
+#include <CoreFoundation/CFString.h>
+
+#include "libavutil/avutil.h"
+#include "vda_internal.h"
+
+/* helper to create a dictionary according to the given pts */
+static CFDictionaryRef vda_dictionary_with_pts(int64_t i_pts)
+{
+ CFStringRef key = CFSTR("FF_VDA_DECODER_PTS_KEY");
+ CFNumberRef value = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberSInt64Type, &i_pts);
+ CFDictionaryRef user_info = CFDictionaryCreate(kCFAllocatorDefault,
+ (const void **)&key,
+ (const void **)&value,
+ 1,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFRelease(value);
+ return user_info;
+}
+
+/* helper to retrieve the pts from the given dictionary */
+static int64_t vda_pts_from_dictionary(CFDictionaryRef user_info)
+{
+ CFNumberRef pts;
+ int64_t outValue = 0;
+
+ if (!user_info)
+ return 0;
+
+ pts = CFDictionaryGetValue(user_info, CFSTR("FF_VDA_DECODER_PTS_KEY"));
+
+ if (pts)
+ CFNumberGetValue(pts, kCFNumberSInt64Type, &outValue);
+
+ return outValue;
+}
+
+/* Remove and release all frames from the queue. */
+static void vda_clear_queue(struct vda_context *vda_ctx)
+{
+ vda_frame *top_frame;
+
+ pthread_mutex_lock(&vda_ctx->queue_mutex);
+
+ while (vda_ctx->queue) {
+ top_frame = vda_ctx->queue;
+ vda_ctx->queue = top_frame->next_frame;
+ ff_vda_release_vda_frame(top_frame);
+ }
+
+ pthread_mutex_unlock(&vda_ctx->queue_mutex);
+}
+
+/* Decoder callback that adds the VDA frame to the queue in display order. */
+static void vda_decoder_callback(void *vda_hw_ctx,
+ CFDictionaryRef user_info,
+ OSStatus status,
+ uint32_t infoFlags,
+ CVImageBufferRef image_buffer)
+{
+ struct vda_context *vda_ctx = vda_hw_ctx;
+ vda_frame *new_frame;
+ vda_frame *queue_walker;
+
+ if (!image_buffer)
+ return;
+
+ if (vda_ctx->cv_pix_fmt_type != CVPixelBufferGetPixelFormatType(image_buffer))
+ return;
+
+ if (!(new_frame = av_mallocz(sizeof(vda_frame))))
+ return;
+ new_frame->next_frame = NULL;
+ new_frame->cv_buffer = CVPixelBufferRetain(image_buffer);
+ new_frame->pts = vda_pts_from_dictionary(user_info);
+
+ pthread_mutex_lock(&vda_ctx->queue_mutex);
+
+ queue_walker = vda_ctx->queue;
+
+ if (!queue_walker || new_frame->pts < queue_walker->pts) {
+ /* we have an empty queue, or this frame earlier than the current queue head */
+ new_frame->next_frame = queue_walker;
+ vda_ctx->queue = new_frame;
+ } else {
+ /* walk the queue and insert this frame where it belongs in display order */
+ vda_frame *next_frame;
+ while (1) {
+ next_frame = queue_walker->next_frame;
+ if (!next_frame || new_frame->pts < next_frame->pts) {
+ new_frame->next_frame = next_frame;
+ queue_walker->next_frame = new_frame;
+ break;
+ }
+ queue_walker = next_frame;
+ }
+ }
+
+ pthread_mutex_unlock(&vda_ctx->queue_mutex);
+}
+
+int ff_vda_create_decoder(struct vda_context *vda_ctx,
+ uint8_t *extradata,
+ int extradata_size)
+{
+ OSStatus status = kVDADecoderNoErr;
+ CFNumberRef height;
+ CFNumberRef width;
+ CFNumberRef format;
+ CFDataRef avc_data;
+ CFMutableDictionaryRef config_info;
+ CFMutableDictionaryRef buffer_attributes;
+ CFMutableDictionaryRef io_surface_properties;
+ CFNumberRef cv_pix_fmt;
+
+ pthread_mutex_init(&vda_ctx->queue_mutex, NULL);
+
+ config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 4,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->height);
+ width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->width);
+ format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->format);
+ avc_data = CFDataCreate(kCFAllocatorDefault, extradata, extradata_size);
+
+ CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height, height);
+ CFDictionarySetValue(config_info, kVDADecoderConfiguration_Width, width);
+ CFDictionarySetValue(config_info, kVDADecoderConfiguration_SourceFormat, format);
+ CFDictionarySetValue(config_info, kVDADecoderConfiguration_avcCData, avc_data);
+
+ buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 2,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberSInt32Type,
+ &vda_ctx->cv_pix_fmt_type);
+ CFDictionarySetValue(buffer_attributes,
+ kCVPixelBufferPixelFormatTypeKey,
+ cv_pix_fmt);
+ CFDictionarySetValue(buffer_attributes,
+ kCVPixelBufferIOSurfacePropertiesKey,
+ io_surface_properties);
+
+ status = VDADecoderCreate(config_info,
+ buffer_attributes,
+ vda_decoder_callback,
+ vda_ctx,
+ &vda_ctx->decoder);
+
+ CFRelease(height);
+ CFRelease(width);
+ CFRelease(format);
+ CFRelease(avc_data);
+ CFRelease(config_info);
+ CFRelease(io_surface_properties);
+ CFRelease(cv_pix_fmt);
+ CFRelease(buffer_attributes);
+
+ if (kVDADecoderNoErr != status)
+ return status;
+
+ return 0;
+}
+
+int ff_vda_destroy_decoder(struct vda_context *vda_ctx)
+{
+ OSStatus status = kVDADecoderNoErr;
+
+ if (vda_ctx->decoder)
+ status = VDADecoderDestroy(vda_ctx->decoder);
+
+ vda_clear_queue(vda_ctx);
+
+ pthread_mutex_destroy(&vda_ctx->queue_mutex);
+
+ if (kVDADecoderNoErr != status)
+ return status;
+
+ return 0;
+}
+
+vda_frame *ff_vda_queue_pop(struct vda_context *vda_ctx)
+{
+ vda_frame *top_frame;
+
+ if (!vda_ctx->queue)
+ return NULL;
+
+ pthread_mutex_lock(&vda_ctx->queue_mutex);
+ top_frame = vda_ctx->queue;
+ vda_ctx->queue = top_frame->next_frame;
+ pthread_mutex_unlock(&vda_ctx->queue_mutex);
+
+ return top_frame;
+}
+
+void ff_vda_release_vda_frame(vda_frame *frame)
+{
+ if (frame) {
+ CVPixelBufferRelease(frame->cv_buffer);
+ av_freep(&frame);
+ }
+}
+
+int ff_vda_decoder_decode(struct vda_context *vda_ctx,
+ uint8_t *bitstream,
+ int bitstream_size,
+ int64_t frame_pts)
+{
+ OSStatus status = kVDADecoderNoErr;
+ CFDictionaryRef user_info;
+ CFDataRef coded_frame;
+
+ coded_frame = CFDataCreate(kCFAllocatorDefault, bitstream, bitstream_size);
+ user_info = vda_dictionary_with_pts(frame_pts);
+ status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, user_info);
+
+ CFRelease(user_info);
+ CFRelease(coded_frame);
+
+ if (kVDADecoderNoErr != status)
+ return status;
+
+ return 0;
+}
diff --git a/libavcodec/vda.h b/libavcodec/vda.h
new file mode 100644
index 0000000..2cb51c5
--- /dev/null
+++ b/libavcodec/vda.h
@@ -0,0 +1,144 @@
+/*
+ * VDA HW acceleration
+ *
+ * copyright (c) 2011 Sebastien Zwickert
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_VDA_H
+#define AVCODEC_VDA_H
+
+#include <pthread.h>
+#include <stdint.h>
+
+// emmintrin.h is unable to compile with -std=c99 -Werror=missing-prototypes
+// http://openradar.appspot.com/8026390
+#undef __GNUC_STDC_INLINE__
+
+#define Picture QuickdrawPicture
+#include <VideoDecodeAcceleration/VDADecoder.h>
+#undef Picture
+
+/**
+ * This structure is used to store a decoded frame information and data.
+ */
+typedef struct vda_frame {
+ /**
+ * The PTS of the frame.
+ *
+ * - encoding: unused
+ * - decoding: Set/Unset by libavcodec.
+ */
+ int64_t pts;
+
+ /**
+ * The CoreVideo buffer that contains the decoded data.
+ *
+ * - encoding: unused
+ * - decoding: Set/Unset by libavcodec.
+ */
+ CVPixelBufferRef cv_buffer;
+
+ /**
+ * A pointer to the next frame.
+ *
+ * - encoding: unused
+ * - decoding: Set/Unset by libavcodec.
+ */
+ struct vda_frame *next_frame;
+} vda_frame;
+
+/**
+ * This structure is used to provide the necessary configurations and data
+ * to the VDA Libav HWAccel implementation.
+ *
+ * The application must make it available as AVCodecContext.hwaccel_context.
+ */
+struct vda_context {
+ /**
+ * VDA decoder object.
+ *
+ * - encoding: unused
+ * - decoding: Set/Unset by libavcodec.
+ */
+ VDADecoder decoder;
+
+ /**
+ * VDA frames queue ordered by presentation timestamp.
+ *
+ * - encoding: unused
+ * - decoding: Set/Unset by libavcodec.
+ */
+ vda_frame *queue;
+
+ /**
+ * Mutex for locking queue operations.
+ *
+ * - encoding: unused
+ * - decoding: Set/Unset by libavcodec.
+ */
+ pthread_mutex_t queue_mutex;
+
+ /**
+ * The frame width.
+ *
+ * - encoding: unused
+ * - decoding: Set/Unset by user.
+ */
+ int width;
+
+ /**
+ * The frame height.
+ *
+ * - encoding: unused
+ * - decoding: Set/Unset by user.
+ */
+ int height;
+
+ /**
+ * The frame format.
+ *
+ * - encoding: unused
+ * - decoding: Set/Unset by user.
+ */
+ int format;
+
+ /**
+ * The pixel format for output image buffers.
+ *
+ * - encoding: unused
+ * - decoding: Set/Unset by user.
+ */
+ OSType cv_pix_fmt_type;
+};
+
+/** Create the video decoder. */
+int ff_vda_create_decoder(struct vda_context *vda_ctx,
+ uint8_t *extradata,
+ int extradata_size);
+
+/** Destroy the video decoder. */
+int ff_vda_destroy_decoder(struct vda_context *vda_ctx);
+
+/** Return the top frame of the queue. */
+vda_frame *ff_vda_queue_pop(struct vda_context *vda_ctx);
+
+/** Release the given frame. */
+void ff_vda_release_vda_frame(vda_frame *frame);
+
+#endif /* AVCODEC_VDA_H */
diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c
new file mode 100644
index 0000000..b50a4c9
--- /dev/null
+++ b/libavcodec/vda_h264.c
@@ -0,0 +1,109 @@
+/*
+ * VDA H.264 hardware acceleration
+ *
+ * copyright (c) 2011 Sebastien Zwickert
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "h264.h"
+#include "h264data.h"
+
+#include "vda_internal.h"
+
+/* This structure is used to store the bitstream of the current frame. */
+struct vda_picture_context {
+ uint8_t *bitstream;
+ int bitstream_size;
+};
+
+static int start_frame(AVCodecContext *avctx,
+ av_unused const uint8_t *buffer,
+ av_unused uint32_t size)
+{
+ const H264Context *h = avctx->priv_data;
+ struct vda_context *vda_ctx = avctx->hwaccel_context;
+ struct vda_picture_context *pic_ctx = h->s.current_picture_ptr->f.hwaccel_picture_private;
+
+ if (!vda_ctx->decoder)
+ return -1;
+
+ pic_ctx->bitstream = NULL;
+ pic_ctx->bitstream_size = 0;
+
+ return 0;
+}
+
+static int decode_slice(AVCodecContext *avctx,
+ const uint8_t *buffer,
+ uint32_t size)
+{
+ H264Context *h = avctx->priv_data;
+ struct vda_context *vda_ctx = avctx->hwaccel_context;
+ struct vda_picture_context *pic_ctx = h->s.current_picture_ptr->f.hwaccel_picture_private;
+ void *tmp;
+
+ if (!vda_ctx->decoder)
+ return -1;
+
+ tmp = av_realloc(pic_ctx->bitstream, pic_ctx->bitstream_size+size+4);
+ if (!tmp)
+ return AVERROR(ENOMEM);
+
+ pic_ctx->bitstream = tmp;
+
+ AV_WB32(pic_ctx->bitstream + pic_ctx->bitstream_size, size);
+ memcpy(pic_ctx->bitstream + pic_ctx->bitstream_size + 4, buffer, size);
+
+ pic_ctx->bitstream_size += size + 4;
+
+ return 0;
+}
+
+static int end_frame(AVCodecContext *avctx)
+{
+ H264Context *h = avctx->priv_data;
+ struct vda_context *vda_ctx = avctx->hwaccel_context;
+ struct vda_picture_context *pic_ctx = h->s.current_picture_ptr->f.hwaccel_picture_private;
+ AVFrame *frame = &h->s.current_picture_ptr->f;
+ int status;
+
+ if (!vda_ctx->decoder || !pic_ctx->bitstream)
+ return -1;
+
+ status = ff_vda_decoder_decode(vda_ctx, pic_ctx->bitstream,
+ pic_ctx->bitstream_size,
+ frame->reordered_opaque);
+
+ if (status)
+ av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
+
+ av_freep(&pic_ctx->bitstream);
+
+ return status;
+}
+
+AVHWAccel ff_h264_vda_hwaccel = {
+ .name = "h264_vda",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_H264,
+ .pix_fmt = PIX_FMT_VDA_VLD,
+ .start_frame = start_frame,
+ .decode_slice = decode_slice,
+ .end_frame = end_frame,
+ .priv_data_size = sizeof(struct vda_picture_context),
+};
diff --git a/libavcodec/vda_internal.h b/libavcodec/vda_internal.h
new file mode 100644
index 0000000..364ebfb
--- /dev/null
+++ b/libavcodec/vda_internal.h
@@ -0,0 +1,42 @@
+/*
+ * VDA hardware acceleration
+ *
+ * copyright (c) 2011 Sebastien Zwickert
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_VDA_INTERNAL_H
+#define AVCODEC_VDA_INTERNAL_H
+
+#include "vda.h"
+
+/**
+ * @addtogroup VDA_Decoding
+ *
+ * @{
+ */
+
+/** Send frame data to the hardware decoder. */
+int ff_vda_decoder_decode(struct vda_context *vda_ctx,
+ uint8_t *bitstream,
+ int bitstream_size,
+ int64_t frame_pts);
+
+/* @} */
+
+#endif /* AVCODEC_VDA_INTERNAL_H */
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index 5312b4b..df04ca0 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -33,7 +33,7 @@
#include "vdpau_internal.h"
/**
- * \addtogroup VDPAU_Decoding
+ * @addtogroup VDPAU_Decoding
*
* @{
*/
@@ -46,7 +46,7 @@ void ff_vdpau_h264_set_reference_frames(MpegEncContext *s)
Picture *pic;
int i, list, pic_frame_idx;
- render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+ render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
assert(render);
rf = &render->info.h264.referenceFrames[0];
@@ -58,11 +58,11 @@ void ff_vdpau_h264_set_reference_frames(MpegEncContext *s)
for (i = 0; i < ls; ++i) {
pic = lp[i];
- if (!pic || !pic->reference)
+ if (!pic || !pic->f.reference)
continue;
pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
- render_ref = (struct vdpau_render_state *)pic->data[0];
+ render_ref = (struct vdpau_render_state *)pic->f.data[0];
assert(render_ref);
rf2 = &render->info.h264.referenceFrames[0];
@@ -76,8 +76,8 @@ void ff_vdpau_h264_set_reference_frames(MpegEncContext *s)
++rf2;
}
if (rf2 != rf) {
- rf2->top_is_reference |= (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE;
- rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
+ rf2->top_is_reference |= (pic->f.reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE;
+ rf2->bottom_is_reference |= (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
continue;
}
@@ -86,8 +86,8 @@ void ff_vdpau_h264_set_reference_frames(MpegEncContext *s)
rf->surface = render_ref->surface;
rf->is_long_term = pic->long_ref;
- rf->top_is_reference = (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE;
- rf->bottom_is_reference = (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
+ rf->top_is_reference = (pic->f.reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE;
+ rf->bottom_is_reference = (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
rf->field_order_cnt[0] = pic->field_poc[0];
rf->field_order_cnt[1] = pic->field_poc[1];
rf->frame_idx = pic_frame_idx;
@@ -112,7 +112,7 @@ void ff_vdpau_add_data_chunk(MpegEncContext *s,
{
struct vdpau_render_state *render;
- render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+ render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
assert(render);
render->bitstream_buffers= av_fast_realloc(
@@ -133,7 +133,7 @@ void ff_vdpau_h264_picture_start(MpegEncContext *s)
struct vdpau_render_state *render;
int i;
- render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+ render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
assert(render);
for (i = 0; i < 2; ++i) {
@@ -151,14 +151,14 @@ void ff_vdpau_h264_picture_complete(MpegEncContext *s)
H264Context *h = s->avctx->priv_data;
struct vdpau_render_state *render;
- render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+ render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
assert(render);
render->info.h264.slice_count = h->slice_num;
if (render->info.h264.slice_count < 1)
return;
- render->info.h264.is_reference = (s->current_picture_ptr->reference & 3) ? VDP_TRUE : VDP_FALSE;
+ render->info.h264.is_reference = (s->current_picture_ptr->f.reference & 3) ? VDP_TRUE : VDP_FALSE;
render->info.h264.field_pic_flag = s->picture_structure != PICT_FRAME;
render->info.h264.bottom_field_flag = s->picture_structure == PICT_BOTTOM_FIELD;
render->info.h264.num_ref_frames = h->sps.ref_frame_count;
@@ -198,7 +198,7 @@ void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf,
if (!s->current_picture_ptr) return;
- render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+ render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
assert(render);
/* fill VdpPictureInfoMPEG1Or2 struct */
@@ -227,12 +227,12 @@ void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf,
switch(s->pict_type){
case AV_PICTURE_TYPE_B:
- next = (struct vdpau_render_state *)s->next_picture.data[0];
+ next = (struct vdpau_render_state *)s->next_picture.f.data[0];
assert(next);
render->info.mpeg.backward_reference = next->surface;
// no return here, going to set forward prediction
case AV_PICTURE_TYPE_P:
- last = (struct vdpau_render_state *)s->last_picture.data[0];
+ last = (struct vdpau_render_state *)s->last_picture.f.data[0];
if (!last) // FIXME: Does this test make sense?
last = render; // predict second field from the first
render->info.mpeg.forward_reference = last->surface;
@@ -253,7 +253,7 @@ void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf,
VC1Context *v = s->avctx->priv_data;
struct vdpau_render_state *render, *last, *next;
- render = (struct vdpau_render_state *)s->current_picture.data[0];
+ render = (struct vdpau_render_state *)s->current_picture.f.data[0];
assert(render);
/* fill LvPictureInfoVC1 struct */
@@ -297,12 +297,12 @@ void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf,
switch(s->pict_type){
case AV_PICTURE_TYPE_B:
- next = (struct vdpau_render_state *)s->next_picture.data[0];
+ next = (struct vdpau_render_state *)s->next_picture.f.data[0];
assert(next);
render->info.vc1.backward_reference = next->surface;
// no break here, going to set forward prediction
case AV_PICTURE_TYPE_P:
- last = (struct vdpau_render_state *)s->last_picture.data[0];
+ last = (struct vdpau_render_state *)s->last_picture.f.data[0];
if (!last) // FIXME: Does this test make sense?
last = render; // predict second field from the first
render->info.vc1.forward_reference = last->surface;
@@ -324,7 +324,7 @@ void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf,
if (!s->current_picture_ptr) return;
- render = (struct vdpau_render_state *)s->current_picture_ptr->data[0];
+ render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
assert(render);
/* fill VdpPictureInfoMPEG4Part2 struct */
@@ -353,13 +353,13 @@ void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf,
switch (s->pict_type) {
case AV_PICTURE_TYPE_B:
- next = (struct vdpau_render_state *)s->next_picture.data[0];
+ next = (struct vdpau_render_state *)s->next_picture.f.data[0];
assert(next);
render->info.mpeg4.backward_reference = next->surface;
render->info.mpeg4.vop_coding_type = 2;
// no break here, going to set forward prediction
case AV_PICTURE_TYPE_P:
- last = (struct vdpau_render_state *)s->last_picture.data[0];
+ last = (struct vdpau_render_state *)s->last_picture.f.data[0];
assert(last);
render->info.mpeg4.forward_reference = last->surface;
}
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index d06ba63..6f13860 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -25,7 +25,7 @@
#define AVCODEC_VDPAU_H
/**
- * \defgroup Decoder VDPAU Decoder and Renderer
+ * @defgroup Decoder VDPAU Decoder and Renderer
*
* VDPAU hardware acceleration has two modules
* - VDPAU decoding
@@ -38,25 +38,25 @@
* and rendering (API calls) are done as part of the VDPAU
* presentation (vo_vdpau.c) module.
*
- * \defgroup VDPAU_Decoding VDPAU Decoding
- * \ingroup Decoder
+ * @defgroup VDPAU_Decoding VDPAU Decoding
+ * @ingroup Decoder
* @{
*/
#include <vdpau/vdpau.h>
#include <vdpau/vdpau_x11.h>
-/** \brief The videoSurface is used for rendering. */
+/** @brief The videoSurface is used for rendering. */
#define FF_VDPAU_STATE_USED_FOR_RENDER 1
/**
- * \brief The videoSurface is needed for reference/prediction.
+ * @brief The videoSurface is needed for reference/prediction.
* The codec manipulates this.
*/
#define FF_VDPAU_STATE_USED_FOR_REFERENCE 2
/**
- * \brief This structure is used as a callback between the Libav
+ * @brief This structure is used as a callback between the Libav
* decoder (vd_) and presentation (vo_) module.
* This is used for defining a video frame containing surface,
* picture parameter, bitstream information etc which are passed
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 44c9198..9b4f6d7 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -21,7 +21,7 @@
#define AVCODEC_VERSION_H
#define LIBAVCODEC_VERSION_MAJOR 53
-#define LIBAVCODEC_VERSION_MINOR 6
+#define LIBAVCODEC_VERSION_MINOR 32
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@@ -68,8 +68,56 @@
#ifndef FF_API_GET_PIX_FMT_NAME
#define FF_API_GET_PIX_FMT_NAME (LIBAVCODEC_VERSION_MAJOR < 54)
#endif
+#ifndef FF_API_ALLOC_CONTEXT
+#define FF_API_ALLOC_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
#ifndef FF_API_AVCODEC_OPEN
#define FF_API_AVCODEC_OPEN (LIBAVCODEC_VERSION_MAJOR < 54)
#endif
+#ifndef FF_API_DRC_SCALE
+#define FF_API_DRC_SCALE (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_ER
+#define FF_API_ER (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_AVCODEC_INIT
+#define FF_API_AVCODEC_INIT (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_X264_GLOBAL_OPTS
+#define FF_API_X264_GLOBAL_OPTS (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_MPEGVIDEO_GLOBAL_OPTS
+#define FF_API_MPEGVIDEO_GLOBAL_OPTS (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_LAME_GLOBAL_OPTS
+#define FF_API_LAME_GLOBAL_OPTS (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_SNOW_GLOBAL_OPTS
+#define FF_API_SNOW_GLOBAL_OPTS (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_MJPEG_GLOBAL_OPTS
+#define FF_API_MJPEG_GLOBAL_OPTS (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_GET_ALPHA_INFO
+#define FF_API_GET_ALPHA_INFO (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_PARSE_FRAME
+#define FF_API_PARSE_FRAME (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_INTERNAL_CONTEXT
+#define FF_API_INTERNAL_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_TIFFENC_COMPLEVEL
+#define FF_API_TIFFENC_COMPLEVEL (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_DATA_POINTERS
+#define FF_API_DATA_POINTERS (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_OLD_DECODE_AUDIO
+#define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_AVFRAME_AGE
+#define FF_API_AVFRAME_AGE (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
#endif /* AVCODEC_VERSION_H */
diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c
index 500adcb..89b5c2b 100644
--- a/libavcodec/vmdav.c
+++ b/libavcodec/vmdav.c
@@ -473,9 +473,9 @@ static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
#define BLOCK_TYPE_SILENCE 3
typedef struct VmdAudioContext {
- AVCodecContext *avctx;
+ AVFrame frame;
int out_bps;
- int predictors[2];
+ int chunk_size;
} VmdAudioContext;
static const uint16_t vmdaudio_table[128] = {
@@ -498,12 +498,25 @@ static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
{
VmdAudioContext *s = avctx->priv_data;
- s->avctx = avctx;
+ if (avctx->channels < 1 || avctx->channels > 2) {
+ av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
+ return AVERROR(EINVAL);
+ }
+ if (avctx->block_align < 1) {
+ av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
+ return AVERROR(EINVAL);
+ }
+
if (avctx->bits_per_coded_sample == 16)
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
else
avctx->sample_fmt = AV_SAMPLE_FMT_U8;
- s->out_bps = av_get_bits_per_sample_fmt(avctx->sample_fmt) >> 3;
+ s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
+
+ s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
"block align = %d, sample rate = %d\n",
@@ -513,56 +526,50 @@ static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
return 0;
}
-static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
- const uint8_t *buf, int buf_size, int stereo)
+static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
+ int channels)
{
- int i;
- int chan = 0;
- int16_t *out = (int16_t*)data;
-
- for(i = 0; i < buf_size; i++) {
- if(buf[i] & 0x80)
- s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
- else
- s->predictors[chan] += vmdaudio_table[buf[i]];
- s->predictors[chan] = av_clip_int16(s->predictors[chan]);
- out[i] = s->predictors[chan];
- chan ^= stereo;
+ int ch;
+ const uint8_t *buf_end = buf + buf_size;
+ int predictor[2];
+ int st = channels - 1;
+
+ /* decode initial raw sample */
+ for (ch = 0; ch < channels; ch++) {
+ predictor[ch] = (int16_t)AV_RL16(buf);
+ buf += 2;
+ *out++ = predictor[ch];
}
-}
-
-static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
- const uint8_t *buf, int silent_chunks, int data_size)
-{
- int silent_size = s->avctx->block_align * silent_chunks * s->out_bps;
- if (silent_chunks) {
- memset(data, s->out_bps == 2 ? 0x00 : 0x80, silent_size);
- data += silent_size;
- }
- if (s->avctx->bits_per_coded_sample == 16)
- vmdaudio_decode_audio(s, data, buf, data_size, s->avctx->channels == 2);
- else {
- /* just copy the data */
- memcpy(data, buf, data_size);
+ /* decode DPCM samples */
+ ch = 0;
+ while (buf < buf_end) {
+ uint8_t b = *buf++;
+ if (b & 0x80)
+ predictor[ch] -= vmdaudio_table[b & 0x7F];
+ else
+ predictor[ch] += vmdaudio_table[b];
+ predictor[ch] = av_clip_int16(predictor[ch]);
+ *out++ = predictor[ch];
+ ch ^= st;
}
-
- return silent_size + data_size * s->out_bps;
}
-static int vmdaudio_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
+ const uint8_t *buf_end;
int buf_size = avpkt->size;
VmdAudioContext *s = avctx->priv_data;
- int block_type, silent_chunks;
- unsigned char *output_samples = (unsigned char *)data;
+ int block_type, silent_chunks, audio_chunks;
+ int ret;
+ uint8_t *output_samples_u8;
+ int16_t *output_samples_s16;
if (buf_size < 16) {
av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
- *data_size = 0;
+ *got_frame_ptr = 0;
return buf_size;
}
@@ -574,10 +581,16 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx,
buf += 16;
buf_size -= 16;
+ /* get number of silent chunks */
silent_chunks = 0;
if (block_type == BLOCK_TYPE_INITIAL) {
- uint32_t flags = AV_RB32(buf);
- silent_chunks = av_popcount(flags);
+ uint32_t flags;
+ if (buf_size < 4) {
+ av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
+ return AVERROR(EINVAL);
+ }
+ flags = AV_RB32(buf);
+ silent_chunks = av_popcount(flags);
buf += 4;
buf_size -= 4;
} else if (block_type == BLOCK_TYPE_SILENCE) {
@@ -586,10 +599,47 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx,
}
/* ensure output buffer is large enough */
- if (*data_size < (avctx->block_align*silent_chunks + buf_size) * s->out_bps)
- return -1;
+ audio_chunks = buf_size / s->chunk_size;
+
+ /* get output buffer */
+ s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ output_samples_u8 = s->frame.data[0];
+ output_samples_s16 = (int16_t *)s->frame.data[0];
+
+ /* decode silent chunks */
+ if (silent_chunks > 0) {
+ int silent_size = avctx->block_align * silent_chunks;
+ if (s->out_bps == 2) {
+ memset(output_samples_s16, 0x00, silent_size * 2);
+ output_samples_s16 += silent_size;
+ } else {
+ memset(output_samples_u8, 0x80, silent_size);
+ output_samples_u8 += silent_size;
+ }
+ }
+
+ /* decode audio chunks */
+ if (audio_chunks > 0) {
+ buf_end = buf + buf_size;
+ while (buf < buf_end) {
+ if (s->out_bps == 2) {
+ decode_audio_s16(output_samples_s16, buf, s->chunk_size,
+ avctx->channels);
+ output_samples_s16 += avctx->block_align;
+ } else {
+ memcpy(output_samples_u8, buf, s->chunk_size);
+ output_samples_u8 += avctx->block_align;
+ }
+ buf += s->chunk_size;
+ }
+ }
- *data_size = vmdaudio_loadsound(s, output_samples, buf, silent_chunks, buf_size);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
return avpkt->size;
}
@@ -600,26 +650,24 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx,
*/
AVCodec ff_vmdvideo_decoder = {
- "vmdvideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VMDVIDEO,
- sizeof(VmdVideoContext),
- vmdvideo_decode_init,
- NULL,
- vmdvideo_decode_end,
- vmdvideo_decode_frame,
- CODEC_CAP_DR1,
+ .name = "vmdvideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VMDVIDEO,
+ .priv_data_size = sizeof(VmdVideoContext),
+ .init = vmdvideo_decode_init,
+ .close = vmdvideo_decode_end,
+ .decode = vmdvideo_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
};
AVCodec ff_vmdaudio_decoder = {
- "vmdaudio",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_VMDAUDIO,
- sizeof(VmdAudioContext),
- vmdaudio_decode_init,
- NULL,
- NULL,
- vmdaudio_decode_frame,
+ .name = "vmdaudio",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_VMDAUDIO,
+ .priv_data_size = sizeof(VmdAudioContext),
+ .init = vmdaudio_decode_init,
+ .decode = vmdaudio_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
};
diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c
index f95bef7..a72c507 100644
--- a/libavcodec/vmnc.c
+++ b/libavcodec/vmnc.c
@@ -509,15 +509,14 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_vmnc_decoder = {
- "vmnc",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VMNC,
- sizeof(VmncContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "vmnc",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VMNC,
+ .priv_data_size = sizeof(VmncContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("VMware Screen Codec / VMware Video"),
};
diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c
index f413170..86df288 100644
--- a/libavcodec/vorbis.c
+++ b/libavcodec/vorbis.c
@@ -1,8 +1,4 @@
-/**
- * @file
- * Common code for Vorbis I encoder and decoder
- * @author Denes Balatoni ( dbalatoni programozo hu )
- *
+/*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
@@ -20,7 +16,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define ALT_BITSTREAM_READER_LE
+/**
+ * @file
+ * Common code for Vorbis I encoder and decoder
+ * @author Denes Balatoni ( dbalatoni programozo hu )
+ */
+
+#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "get_bits.h"
diff --git a/libavcodec/vorbis.h b/libavcodec/vorbis.h
index 8501e0a..a55523f 100644
--- a/libavcodec/vorbis.h
+++ b/libavcodec/vorbis.h
@@ -27,7 +27,7 @@ extern const float ff_vorbis_floor1_inverse_db_table[256];
extern const float * const ff_vorbis_vwin[8];
extern const uint8_t ff_vorbis_channel_layout_offsets[8][8];
extern const uint8_t ff_vorbis_encoding_channel_layout_offsets[8][8];
-extern const int64_t ff_vorbis_channel_layouts[9];
+extern const uint64_t ff_vorbis_channel_layouts[9];
typedef struct {
uint16_t x;
diff --git a/libavcodec/vorbis_data.c b/libavcodec/vorbis_data.c
index 4e1fe00..bd27b82 100644
--- a/libavcodec/vorbis_data.c
+++ b/libavcodec/vorbis_data.c
@@ -44,7 +44,7 @@ const uint8_t ff_vorbis_encoding_channel_layout_offsets[8][8] = {
{ 0, 2, 1, 6, 7, 4, 5, 3 },
};
-const int64_t ff_vorbis_channel_layouts[9] = {
+const uint64_t ff_vorbis_channel_layouts[9] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_SURROUND,
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index 017102e..70690dd 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -1,8 +1,4 @@
-/**
- * @file
- * Vorbis I decoder
- * @author Denes Balatoni ( dbalatoni programozo hu )
- *
+/*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
@@ -20,10 +16,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * Vorbis I decoder
+ * @author Denes Balatoni ( dbalatoni programozo hu )
+ */
+
#include <inttypes.h>
#include <math.h>
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
@@ -119,6 +121,7 @@ typedef struct {
typedef struct vorbis_context_s {
AVCodecContext *avccontext;
+ AVFrame frame;
GetBitContext gb;
DSPContext dsp;
FmtConvertContext fmt_conv;
@@ -162,7 +165,7 @@ static const char idx_err_str[] = "Index value %d out of range (0 - %d) for %s a
av_log(vc->avccontext, AV_LOG_ERROR,\
idx_err_str,\
(int)(idx), (int)(limit - 1), #idx, __FILE__, __LINE__);\
- return -1;\
+ return AVERROR_INVALIDDATA;\
}
#define GET_VALIDATED_INDEX(idx, bits, limit) \
{\
@@ -235,6 +238,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
uint32_t *tmp_vlc_codes;
GetBitContext *gb = &vc->gb;
uint16_t *codebook_multiplicands;
+ int ret = 0;
vc->codebook_count = get_bits(gb, 8) + 1;
@@ -254,6 +258,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
if (get_bits(gb, 24) != 0x564342) {
av_log(vc->avccontext, AV_LOG_ERROR,
" %u. Codebook setup data corrupt.\n", cb);
+ ret = AVERROR_INVALIDDATA;
goto error;
}
@@ -262,6 +267,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
av_log(vc->avccontext, AV_LOG_ERROR,
" %u. Codebook's dimension is invalid (%d).\n",
cb, codebook_setup->dimensions);
+ ret = AVERROR_INVALIDDATA;
goto error;
}
entries = get_bits(gb, 24);
@@ -269,6 +275,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
av_log(vc->avccontext, AV_LOG_ERROR,
" %u. Codebook has too many entries (%u).\n",
cb, entries);
+ ret = AVERROR_INVALIDDATA;
goto error;
}
@@ -326,6 +333,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
}
if (current_entry>used_entries) {
av_log(vc->avccontext, AV_LOG_ERROR, " More codelengths than codes in codebook. \n");
+ ret = AVERROR_INVALIDDATA;
goto error;
}
}
@@ -393,17 +401,20 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
}
if (j != used_entries) {
av_log(vc->avccontext, AV_LOG_ERROR, "Bug in codevector vector building code. \n");
+ ret = AVERROR_INVALIDDATA;
goto error;
}
entries = used_entries;
} else if (codebook_setup->lookup_type >= 2) {
av_log(vc->avccontext, AV_LOG_ERROR, "Codebook lookup type not supported. \n");
+ ret = AVERROR_INVALIDDATA;
goto error;
}
// Initialize VLC table
if (ff_vorbis_len2vlc(tmp_vlc_bits, tmp_vlc_codes, entries)) {
av_log(vc->avccontext, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n");
+ ret = AVERROR_INVALIDDATA;
goto error;
}
codebook_setup->maxdepth = 0;
@@ -418,7 +429,11 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
codebook_setup->maxdepth = (codebook_setup->maxdepth+codebook_setup->nb_bits - 1) / codebook_setup->nb_bits;
- if (init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits, entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits), sizeof(*tmp_vlc_bits), tmp_vlc_codes, sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes), INIT_VLC_LE)) {
+ if ((ret = init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits,
+ entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits),
+ sizeof(*tmp_vlc_bits), tmp_vlc_codes,
+ sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes),
+ INIT_VLC_LE))) {
av_log(vc->avccontext, AV_LOG_ERROR, " Error generating vlc tables. \n");
goto error;
}
@@ -434,7 +449,7 @@ error:
av_free(tmp_vlc_bits);
av_free(tmp_vlc_codes);
av_free(codebook_multiplicands);
- return -1;
+ return ret;
}
// Process time domain transforms part (unused in Vorbis I)
@@ -452,7 +467,7 @@ static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc)
if (vorbis_tdtransform) {
av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
return 0;
@@ -544,7 +559,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
av_log(vc->avccontext, AV_LOG_ERROR,
"Floor value is too large for blocksize: %u (%"PRIu32")\n",
rangemax, vc->blocksize[1] / 2);
- return -1;
+ return AVERROR_INVALIDDATA;
}
floor_setup->data.t1.list[0].x = 0;
floor_setup->data.t1.list[1].x = rangemax;
@@ -574,7 +589,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
if (floor_setup->data.t0.amplitude_bits == 0) {
av_log(vc->avccontext, AV_LOG_ERROR,
"Floor 0 amplitude bits is 0.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
floor_setup->data.t0.amplitude_offset = get_bits(gb, 8);
floor_setup->data.t0.num_books = get_bits(gb, 4) + 1;
@@ -583,7 +598,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
floor_setup->data.t0.book_list =
av_malloc(floor_setup->data.t0.num_books);
if (!floor_setup->data.t0.book_list)
- return -1;
+ return AVERROR(ENOMEM);
/* read book indexes */
{
int idx;
@@ -604,7 +619,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
av_malloc((floor_setup->data.t0.order + 1 + max_codebook_dim)
* sizeof(*floor_setup->data.t0.lsp));
if (!floor_setup->data.t0.lsp)
- return -1;
+ return AVERROR(ENOMEM);
/* debug output parsed headers */
av_dlog(NULL, "floor0 order: %u\n", floor_setup->data.t0.order);
@@ -628,7 +643,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
}
} else {
av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
return 0;
@@ -666,7 +681,7 @@ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc)
"partition out of bounds: type, begin, end, size, blocksize: %"PRIu16", %"PRIu32", %"PRIu32", %u, %"PRIu32"\n",
res_setup->type, res_setup->begin, res_setup->end,
res_setup->partition_size, vc->blocksize[1] / 2);
- return -1;
+ return AVERROR_INVALIDDATA;
}
res_setup->classifications = get_bits(gb, 6) + 1;
@@ -731,7 +746,7 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc)
if (get_bits(gb, 16)) {
av_log(vc->avccontext, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (get_bits1(gb)) {
mapping_setup->submaps = get_bits(gb, 4) + 1;
@@ -758,7 +773,7 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc)
if (get_bits(gb, 2)) {
av_log(vc->avccontext, AV_LOG_ERROR, "%u. mapping setup data invalid.\n", i);
- return -1; // following spec.
+ return AVERROR_INVALIDDATA; // following spec.
}
if (mapping_setup->submaps>1) {
@@ -845,41 +860,42 @@ static int vorbis_parse_setup_hdr_modes(vorbis_context *vc)
static int vorbis_parse_setup_hdr(vorbis_context *vc)
{
GetBitContext *gb = &vc->gb;
+ int ret;
if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') ||
(get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') ||
(get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
- if (vorbis_parse_setup_hdr_codebooks(vc)) {
+ if ((ret = vorbis_parse_setup_hdr_codebooks(vc))) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n");
- return -2;
+ return ret;
}
- if (vorbis_parse_setup_hdr_tdtransforms(vc)) {
+ if ((ret = vorbis_parse_setup_hdr_tdtransforms(vc))) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n");
- return -3;
+ return ret;
}
- if (vorbis_parse_setup_hdr_floors(vc)) {
+ if ((ret = vorbis_parse_setup_hdr_floors(vc))) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n");
- return -4;
+ return ret;
}
- if (vorbis_parse_setup_hdr_residues(vc)) {
+ if ((ret = vorbis_parse_setup_hdr_residues(vc))) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n");
- return -5;
+ return ret;
}
- if (vorbis_parse_setup_hdr_mappings(vc)) {
+ if ((ret = vorbis_parse_setup_hdr_mappings(vc))) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n");
- return -6;
+ return ret;
}
- if (vorbis_parse_setup_hdr_modes(vc)) {
+ if ((ret = vorbis_parse_setup_hdr_modes(vc))) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n");
- return -7;
+ return ret;
}
if (!get_bits1(gb)) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n");
- return -8; // framing flag bit unset error
+ return AVERROR_INVALIDDATA; // framing flag bit unset error
}
return 0;
@@ -896,19 +912,19 @@ static int vorbis_parse_id_hdr(vorbis_context *vc)
(get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') ||
(get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
vc->version = get_bits_long(gb, 32); //FIXME check 0
vc->audio_channels = get_bits(gb, 8);
if (vc->audio_channels <= 0) {
av_log(vc->avccontext, AV_LOG_ERROR, "Invalid number of channels\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
vc->audio_samplerate = get_bits_long(gb, 32);
if (vc->audio_samplerate <= 0) {
av_log(vc->avccontext, AV_LOG_ERROR, "Invalid samplerate\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
vc->bitrate_maximum = get_bits_long(gb, 32);
vc->bitrate_nominal = get_bits_long(gb, 32);
@@ -919,20 +935,14 @@ static int vorbis_parse_id_hdr(vorbis_context *vc)
vc->blocksize[1] = (1 << bl1);
if (bl0 > 13 || bl0 < 6 || bl1 > 13 || bl1 < 6 || bl1 < bl0) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n");
- return -3;
- }
- // output format int16
- if (vc->blocksize[1] / 2 * vc->audio_channels * 2 > AVCODEC_MAX_AUDIO_FRAME_SIZE) {
- av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis channel count makes "
- "output packets too large.\n");
- return -4;
+ return AVERROR_INVALIDDATA;
}
vc->win[0] = ff_vorbis_vwin[bl0 - 6];
vc->win[1] = ff_vorbis_vwin[bl1 - 6];
if ((get_bits1(gb)) == 0) {
av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n");
- return -2;
+ return AVERROR_INVALIDDATA;
}
vc->channel_residues = av_malloc((vc->blocksize[1] / 2) * vc->audio_channels * sizeof(*vc->channel_residues));
@@ -960,13 +970,13 @@ static int vorbis_parse_id_hdr(vorbis_context *vc)
static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
{
- vorbis_context *vc = avccontext->priv_data ;
+ vorbis_context *vc = avccontext->priv_data;
uint8_t *headers = avccontext->extradata;
int headers_len = avccontext->extradata_size;
uint8_t *header_start[3];
int header_len[3];
GetBitContext *gb = &(vc->gb);
- int hdr_type;
+ int hdr_type, ret;
vc->avccontext = avccontext;
dsputil_init(&vc->dsp, avccontext);
@@ -982,24 +992,24 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
if (!headers_len) {
av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
- if (ff_split_xiph_headers(headers, headers_len, 30, header_start, header_len) < 0) {
+ if ((ret = avpriv_split_xiph_headers(headers, headers_len, 30, header_start, header_len)) < 0) {
av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");
- return -1;
+ return ret;
}
init_get_bits(gb, header_start[0], header_len[0]*8);
hdr_type = get_bits(gb, 8);
if (hdr_type != 1) {
av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
- if (vorbis_parse_id_hdr(vc)) {
+ if ((ret = vorbis_parse_id_hdr(vc))) {
av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n");
vorbis_free(vc);
- return -1;
+ return ret;
}
init_get_bits(gb, header_start[2], header_len[2]*8);
@@ -1007,12 +1017,12 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
if (hdr_type != 5) {
av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n");
vorbis_free(vc);
- return -1;
+ return AVERROR_INVALIDDATA;
}
- if (vorbis_parse_setup_hdr(vc)) {
+ if ((ret = vorbis_parse_setup_hdr(vc))) {
av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n");
vorbis_free(vc);
- return -1;
+ return ret;
}
if (vc->audio_channels > 8)
@@ -1024,7 +1034,10 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
avccontext->sample_rate = vc->audio_samplerate;
avccontext->frame_size = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2;
- return 0 ;
+ avcodec_get_frame_defaults(&vc->frame);
+ avccontext->coded_frame = &vc->frame;
+
+ return 0;
}
// Decode audiopackets -------------------------------------------------
@@ -1055,7 +1068,7 @@ static int vorbis_floor0_decode(vorbis_context *vc,
codebook = vc->codebooks[vf->book_list[book_idx]];
/* Invalid codebook! */
if (!codebook.codevectors)
- return -1;
+ return AVERROR_INVALIDDATA;
while (lsp_len<vf->order) {
int vec_off;
@@ -1421,7 +1434,7 @@ static inline int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr,
return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 0);
else {
av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
@@ -1469,7 +1482,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc)
if (get_bits1(gb)) {
av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n");
- return -1; // packet type not audio
+ return AVERROR_INVALIDDATA; // packet type not audio
}
if (vc->mode_count == 1) {
@@ -1506,7 +1519,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc)
if (ret < 0) {
av_log(vc->avccontext, AV_LOG_ERROR, "Invalid codebook in vorbis_floor_decode.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
no_residue[i] = ret;
ch_floor_ptr += blocksize / 2;
@@ -1596,40 +1609,39 @@ static int vorbis_parse_audio_packet(vorbis_context *vc)
// Return the decoded audio packet through the standard api
-static int vorbis_decode_frame(AVCodecContext *avccontext,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int vorbis_decode_frame(AVCodecContext *avccontext, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- vorbis_context *vc = avccontext->priv_data ;
+ vorbis_context *vc = avccontext->priv_data;
GetBitContext *gb = &(vc->gb);
const float *channel_ptrs[255];
- int i, len;
-
- if (!buf_size)
- return 0;
+ int i, len, ret;
av_dlog(NULL, "packet length %d \n", buf_size);
init_get_bits(gb, buf, buf_size*8);
- len = vorbis_parse_audio_packet(vc);
-
- if (len <= 0) {
- *data_size = 0;
- return buf_size;
- }
+ if ((len = vorbis_parse_audio_packet(vc)) <= 0)
+ return len;
if (!vc->first_frame) {
vc->first_frame = 1;
- *data_size = 0;
- return buf_size ;
+ *got_frame_ptr = 0;
+ return buf_size;
}
av_dlog(NULL, "parsed %d bytes %d bits, returned %d samples (*ch*bits) \n",
get_bits_count(gb) / 8, get_bits_count(gb) % 8, len);
+ /* get output buffer */
+ vc->frame.nb_samples = len;
+ if ((ret = avccontext->get_buffer(avccontext, &vc->frame)) < 0) {
+ av_log(avccontext, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+
if (vc->audio_channels > 8) {
for (i = 0; i < vc->audio_channels; i++)
channel_ptrs[i] = vc->channel_floors + i * len;
@@ -1640,15 +1652,17 @@ static int vorbis_decode_frame(AVCodecContext *avccontext,
}
if (avccontext->sample_fmt == AV_SAMPLE_FMT_FLT)
- vc->fmt_conv.float_interleave(data, channel_ptrs, len, vc->audio_channels);
+ vc->fmt_conv.float_interleave((float *)vc->frame.data[0], channel_ptrs,
+ len, vc->audio_channels);
else
- vc->fmt_conv.float_to_int16_interleave(data, channel_ptrs, len,
+ vc->fmt_conv.float_to_int16_interleave((int16_t *)vc->frame.data[0],
+ channel_ptrs, len,
vc->audio_channels);
- *data_size = len * vc->audio_channels *
- (av_get_bits_per_sample_fmt(avccontext->sample_fmt) / 8);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = vc->frame;
- return buf_size ;
+ return buf_size;
}
// Close decoder
@@ -1659,18 +1673,18 @@ static av_cold int vorbis_decode_close(AVCodecContext *avccontext)
vorbis_free(vc);
- return 0 ;
+ return 0;
}
AVCodec ff_vorbis_decoder = {
- "vorbis",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_VORBIS,
- sizeof(vorbis_context),
- vorbis_decode_init,
- NULL,
- vorbis_decode_close,
- vorbis_decode_frame,
+ .name = "vorbis",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_VORBIS,
+ .priv_data_size = sizeof(vorbis_context),
+ .init = vorbis_decode_init,
+ .close = vorbis_decode_close,
+ .decode = vorbis_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
.channel_layouts = ff_vorbis_channel_layouts,
.sample_fmts = (const enum AVSampleFormat[]) {
diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c
index 67d094b..00fe402 100644
--- a/libavcodec/vorbisenc.c
+++ b/libavcodec/vorbisenc.c
@@ -1103,13 +1103,13 @@ static av_cold int vorbis_encode_close(AVCodecContext *avccontext)
}
AVCodec ff_vorbis_encoder = {
- "vorbis",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_VORBIS,
- sizeof(vorbis_enc_context),
- vorbis_encode_init,
- vorbis_encode_frame,
- vorbis_encode_close,
+ .name = "vorbis",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_VORBIS,
+ .priv_data_size = sizeof(vorbis_enc_context),
+ .init = vorbis_encode_init,
+ .encode = vorbis_encode_frame,
+ .close = vorbis_encode_close,
.capabilities= CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 890db5c..f44d084 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -35,6 +35,7 @@
#include "libavutil/imgutils.h"
#include "avcodec.h"
+#include "internal.h"
#include "dsputil.h"
#include "get_bits.h"
@@ -44,8 +45,6 @@
#define FRAGMENT_PIXELS 8
-static av_cold int vp3_decode_end(AVCodecContext *avctx);
-
//FIXME split things out into their own arrays
typedef struct Vp3Fragment {
int16_t dc;
@@ -225,7 +224,7 @@ typedef struct Vp3DecodeContext {
/* these arrays need to be on 16-byte boundaries since SSE2 operations
* index into them */
- DECLARE_ALIGNED(16, int16_t, qmat)[3][2][3][64]; //<qmat[qpi][is_inter][plane]
+ DECLARE_ALIGNED(16, int16_t, qmat)[3][2][3][64]; ///< qmat[qpi][is_inter][plane]
/* This table contains superblock_count * 16 entries. Each set of 16
* numbers corresponds to the fragment indexes 0..15 of the superblock.
@@ -254,6 +253,63 @@ typedef struct Vp3DecodeContext {
* VP3 specific functions
************************************************************************/
+static void vp3_decode_flush(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+
+ if (s->golden_frame.data[0]) {
+ if (s->golden_frame.data[0] == s->last_frame.data[0])
+ memset(&s->last_frame, 0, sizeof(AVFrame));
+ if (s->current_frame.data[0] == s->golden_frame.data[0])
+ memset(&s->current_frame, 0, sizeof(AVFrame));
+ ff_thread_release_buffer(avctx, &s->golden_frame);
+ }
+ if (s->last_frame.data[0]) {
+ if (s->current_frame.data[0] == s->last_frame.data[0])
+ memset(&s->current_frame, 0, sizeof(AVFrame));
+ ff_thread_release_buffer(avctx, &s->last_frame);
+ }
+ if (s->current_frame.data[0])
+ ff_thread_release_buffer(avctx, &s->current_frame);
+}
+
+static av_cold int vp3_decode_end(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+ int i;
+
+ av_free(s->superblock_coding);
+ av_free(s->all_fragments);
+ av_free(s->coded_fragment_list[0]);
+ av_free(s->dct_tokens_base);
+ av_free(s->superblock_fragments);
+ av_free(s->macroblock_coding);
+ av_free(s->motion_val[0]);
+ av_free(s->motion_val[1]);
+ av_free(s->edge_emu_buffer);
+
+ if (avctx->internal->is_copy)
+ return 0;
+
+ for (i = 0; i < 16; i++) {
+ free_vlc(&s->dc_vlc[i]);
+ free_vlc(&s->ac_vlc_1[i]);
+ free_vlc(&s->ac_vlc_2[i]);
+ free_vlc(&s->ac_vlc_3[i]);
+ free_vlc(&s->ac_vlc_4[i]);
+ }
+
+ free_vlc(&s->superblock_run_length_vlc);
+ free_vlc(&s->fragment_run_length_vlc);
+ free_vlc(&s->mode_code_vlc);
+ free_vlc(&s->motion_vector_vlc);
+
+ /* release all frames */
+ vp3_decode_flush(avctx);
+
+ return 0;
+}
+
/*
* This function sets up all of the various blocks mappings:
* superblocks <-> fragments, macroblocks <-> fragments,
@@ -890,7 +946,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
/* decode a VLC into a token */
token = get_vlc2(gb, vlc_table, 11, 3);
/* use the token to get a zero run, a coefficient, and an eob run */
- if (token <= 6) {
+ if ((unsigned) token <= 6U) {
eob_run = eob_run_base[token];
if (eob_run_get_bits[token])
eob_run += get_bits(gb, eob_run_get_bits[token]);
@@ -908,7 +964,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
coeff_i += eob_run;
eob_run = 0;
}
- } else {
+ } else if (token >= 0) {
bits_to_get = coeff_get_bits[token];
if (bits_to_get)
bits_to_get = get_bits(gb, bits_to_get);
@@ -942,6 +998,10 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
for (i = coeff_index+1; i <= coeff_index+zero_run; i++)
s->num_coded_frags[plane][i]--;
coeff_i++;
+ } else {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid token %d\n", token);
+ return -1;
}
}
@@ -991,6 +1051,8 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
/* unpack the Y plane DC coefficients */
residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_y_table], 0,
0, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
/* reverse prediction of the Y-plane DC coefficients */
reverse_dc_prediction(s, 0, s->fragment_width[0], s->fragment_height[0]);
@@ -998,8 +1060,12 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
/* unpack the C plane DC coefficients */
residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0,
1, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0,
2, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
/* reverse prediction of the C-plane DC coefficients */
if (!(s->avctx->flags & CODEC_FLAG_GRAY))
@@ -1036,11 +1102,17 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
for (i = 1; i <= 63; i++) {
residual_eob_run = unpack_vlcs(s, gb, y_tables[i], i,
0, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i,
1, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i,
2, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
}
return 0;
@@ -1317,10 +1389,10 @@ end:
*/
static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
{
- int h, cy;
- int offset[4];
+ int h, cy, i;
+ int offset[AV_NUM_DATA_POINTERS];
- if (HAVE_PTHREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) {
+ if (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) {
int y_flipped = s->flipped_image ? s->avctx->height-y : y;
// At the end of the frame, report INT_MAX instead of the height of the frame.
@@ -1344,7 +1416,8 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
offset[0] = s->current_frame.linesize[0]*y;
offset[1] = s->current_frame.linesize[1]*cy;
offset[2] = s->current_frame.linesize[2]*cy;
- offset[3] = 0;
+ for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
+ offset[i] = 0;
emms_c();
s->avctx->draw_horiz_band(s->avctx, &s->current_frame, offset, y, 3, h);
@@ -1404,7 +1477,7 @@ static void render_slice(Vp3DecodeContext *s, int slice)
int fragment_width = s->fragment_width[!!plane];
int fragment_height = s->fragment_height[!!plane];
int fragment_start = s->fragment_start[plane];
- int do_await = !plane && HAVE_PTHREADS && (s->avctx->active_thread_type&FF_THREAD_FRAME);
+ int do_await = !plane && HAVE_THREADS && (s->avctx->active_thread_type&FF_THREAD_FRAME);
if (!s->flipped_image) stride = -stride;
if (CONFIG_GRAY && plane && (s->avctx->flags & CODEC_FLAG_GRAY))
@@ -1581,9 +1654,6 @@ static av_cold int allocate_tables(AVCodecContext *avctx)
return 0;
}
-/*
- * This is the ffmpeg/libavcodec API init function.
- */
static av_cold int vp3_decode_init(AVCodecContext *avctx)
{
Vp3DecodeContext *s = avctx->priv_data;
@@ -1787,10 +1857,15 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *
Vp3DecodeContext *s = dst->priv_data, *s1 = src->priv_data;
int qps_changed = 0, i, err;
+#define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field)
+
if (!s1->current_frame.data[0]
||s->width != s1->width
- ||s->height!= s1->height)
+ ||s->height!= s1->height) {
+ if (s != s1)
+ copy_fields(s, s1, golden_frame, current_frame);
return -1;
+ }
if (s != s1) {
// init tables if the first frame hasn't been decoded
@@ -1806,8 +1881,6 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *
memcpy(s->motion_val[1], s1->motion_val[1], c_fragment_count * sizeof(*s->motion_val[1]));
}
-#define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field)
-
// copy previous frame data
copy_fields(s, s1, golden_frame, dsp);
@@ -1832,9 +1905,6 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *
return 0;
}
-/*
- * This is the ffmpeg/libavcodec API frame decode function.
- */
static int vp3_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
AVPacket *avpkt)
@@ -1975,7 +2045,7 @@ static int vp3_decode_frame(AVCodecContext *avctx,
*data_size=sizeof(AVFrame);
*(AVFrame*)data= s->current_frame;
- if (!HAVE_PTHREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME))
+ if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME))
update_frames(avctx);
return buf_size;
@@ -1983,59 +2053,12 @@ static int vp3_decode_frame(AVCodecContext *avctx,
error:
ff_thread_report_progress(&s->current_frame, INT_MAX, 0);
- if (!HAVE_PTHREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME))
+ if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME))
avctx->release_buffer(avctx, &s->current_frame);
return -1;
}
-/*
- * This is the ffmpeg/libavcodec API module cleanup function.
- */
-static av_cold int vp3_decode_end(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
- int i;
-
- if (avctx->is_copy && !s->current_frame.data[0])
- return 0;
-
- av_free(s->superblock_coding);
- av_free(s->all_fragments);
- av_free(s->coded_fragment_list[0]);
- av_free(s->dct_tokens_base);
- av_free(s->superblock_fragments);
- av_free(s->macroblock_coding);
- av_free(s->motion_val[0]);
- av_free(s->motion_val[1]);
- av_free(s->edge_emu_buffer);
-
- if (avctx->is_copy) return 0;
-
- for (i = 0; i < 16; i++) {
- free_vlc(&s->dc_vlc[i]);
- free_vlc(&s->ac_vlc_1[i]);
- free_vlc(&s->ac_vlc_2[i]);
- free_vlc(&s->ac_vlc_3[i]);
- free_vlc(&s->ac_vlc_4[i]);
- }
-
- free_vlc(&s->superblock_run_length_vlc);
- free_vlc(&s->fragment_run_length_vlc);
- free_vlc(&s->mode_code_vlc);
- free_vlc(&s->motion_vector_vlc);
-
- /* release all frames */
- if (s->golden_frame.data[0])
- ff_thread_release_buffer(avctx, &s->golden_frame);
- if (s->last_frame.data[0] && s->last_frame.type != FF_BUFFER_TYPE_COPY)
- ff_thread_release_buffer(avctx, &s->last_frame);
- /* no need to release the current_frame since it will always be pointing
- * to the same frame as either the golden or last frame */
-
- return 0;
-}
-
static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb)
{
Vp3DecodeContext *s = avctx->priv_data;
@@ -2070,6 +2093,23 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb)
return 0;
}
+static int vp3_init_thread_copy(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+
+ s->superblock_coding = NULL;
+ s->all_fragments = NULL;
+ s->coded_fragment_list[0] = NULL;
+ s->dct_tokens_base = NULL;
+ s->superblock_fragments = NULL;
+ s->macroblock_coding = NULL;
+ s->motion_val[0] = NULL;
+ s->motion_val[1] = NULL;
+ s->edge_emu_buffer = NULL;
+
+ return 0;
+}
+
#if CONFIG_THEORA_DECODER
static const enum PixelFormat theora_pix_fmts[4] = {
PIX_FMT_YUV420P, PIX_FMT_NONE, PIX_FMT_YUV422P, PIX_FMT_YUV444P
@@ -2285,7 +2325,7 @@ static av_cold int theora_decode_init(AVCodecContext *avctx)
return -1;
}
- if (ff_split_xiph_headers(avctx->extradata, avctx->extradata_size,
+ if (avpriv_split_xiph_headers(avctx->extradata, avctx->extradata_size,
42, header_start, header_len) < 0) {
av_log(avctx, AV_LOG_ERROR, "Corrupt extradata\n");
return -1;
@@ -2331,55 +2371,33 @@ static av_cold int theora_decode_init(AVCodecContext *avctx)
return vp3_decode_init(avctx);
}
-static void vp3_decode_flush(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
-
- if (s->golden_frame.data[0]) {
- if (s->golden_frame.data[0] == s->last_frame.data[0])
- memset(&s->last_frame, 0, sizeof(AVFrame));
- if (s->current_frame.data[0] == s->golden_frame.data[0])
- memset(&s->current_frame, 0, sizeof(AVFrame));
- ff_thread_release_buffer(avctx, &s->golden_frame);
- }
- if (s->last_frame.data[0]) {
- if (s->current_frame.data[0] == s->last_frame.data[0])
- memset(&s->current_frame, 0, sizeof(AVFrame));
- ff_thread_release_buffer(avctx, &s->last_frame);
- }
- if (s->current_frame.data[0])
- ff_thread_release_buffer(avctx, &s->current_frame);
-}
-
AVCodec ff_theora_decoder = {
- "theora",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_THEORA,
- sizeof(Vp3DecodeContext),
- theora_decode_init,
- NULL,
- vp3_decode_end,
- vp3_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS,
- NULL,
+ .name = "theora",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_THEORA,
+ .priv_data_size = sizeof(Vp3DecodeContext),
+ .init = theora_decode_init,
+ .close = vp3_decode_end,
+ .decode = vp3_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS,
.flush = vp3_decode_flush,
.long_name = NULL_IF_CONFIG_SMALL("Theora"),
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
.update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context)
};
#endif
AVCodec ff_vp3_decoder = {
- "vp3",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VP3,
- sizeof(Vp3DecodeContext),
- vp3_decode_init,
- NULL,
- vp3_decode_end,
- vp3_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS,
- NULL,
+ .name = "vp3",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VP3,
+ .priv_data_size = sizeof(Vp3DecodeContext),
+ .init = vp3_decode_init,
+ .close = vp3_decode_end,
+ .decode = vp3_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS,
.flush = vp3_decode_flush,
.long_name = NULL_IF_CONFIG_SMALL("On2 VP3"),
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
.update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context)
};
diff --git a/libavcodec/vp3_parser.c b/libavcodec/vp3_parser.c
index cfe6b3f..1d70408 100644
--- a/libavcodec/vp3_parser.c
+++ b/libavcodec/vp3_parser.c
@@ -36,9 +36,7 @@ static int parse(AVCodecParserContext *s,
}
AVCodecParser ff_vp3_parser = {
- { CODEC_ID_THEORA, CODEC_ID_VP3,
- CODEC_ID_VP6, CODEC_ID_VP6F, CODEC_ID_VP6A },
- 0,
- NULL,
- parse,
+ .codec_ids = { CODEC_ID_THEORA, CODEC_ID_VP3, CODEC_ID_VP6,
+ CODEC_ID_VP6F, CODEC_ID_VP6A },
+ .parser_parse = parse,
};
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c
index d61163e..56f667c 100644
--- a/libavcodec/vp5.c
+++ b/libavcodec/vp5.c
@@ -1,7 +1,4 @@
-/**
- * @file
- * VP5 compatible video decoder
- *
+/*
* Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of Libav.
@@ -21,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP5 compatible video decoder
+ */
+
#include <stdlib.h>
#include <string.h>
@@ -183,7 +185,8 @@ static void vp5_parse_coeff(VP56Context *s)
model1 = model->coeff_dccv[pt];
model2 = model->coeff_dcct[pt][ctx];
- for (coeff_idx=0; coeff_idx<64; ) {
+ coeff_idx = 0;
+ for (;;) {
if (vp56_rac_get_prob(c, model2[0])) {
if (vp56_rac_get_prob(c, model2[2])) {
if (vp56_rac_get_prob(c, model2[3])) {
@@ -220,8 +223,11 @@ static void vp5_parse_coeff(VP56Context *s)
ct = 0;
s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 0;
}
+ coeff_idx++;
+ if (coeff_idx >= 64)
+ break;
- cg = vp5_coeff_groups[++coeff_idx];
+ cg = vp5_coeff_groups[coeff_idx];
ctx = s->coeff_ctx[vp56_b6to4[b]][coeff_idx];
model1 = model->coeff_ract[pt][ct][cg];
model2 = cg > 2 ? model1 : model->coeff_acct[pt][ct][cg][ctx];
@@ -268,14 +274,13 @@ static av_cold int vp5_decode_init(AVCodecContext *avctx)
}
AVCodec ff_vp5_decoder = {
- "vp5",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VP5,
- sizeof(VP56Context),
- vp5_decode_init,
- NULL,
- ff_vp56_free,
- ff_vp56_decode_frame,
- CODEC_CAP_DR1,
+ .name = "vp5",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VP5,
+ .priv_data_size = sizeof(VP56Context),
+ .init = vp5_decode_init,
+ .close = ff_vp56_free,
+ .decode = ff_vp56_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("On2 VP5"),
};
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index a6b2014..3b2ac95 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -1,7 +1,4 @@
-/**
- * @file
- * VP5 and VP6 compatible video decoder (common features)
- *
+/*
* Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of Libav.
@@ -21,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP5 and VP6 compatible video decoder (common features)
+ */
+
#include "avcodec.h"
#include "bytestream.h"
@@ -399,6 +401,8 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
frame_current = s->framep[VP56_FRAME_CURRENT];
frame_ref = s->framep[ref_frame];
+ if (mb_type != VP56_MB_INTRA && !frame_ref->data[0])
+ return;
ab = 6*is_alpha;
b_max = 6 - 2*is_alpha;
@@ -463,6 +467,7 @@ static int vp56_size_changed(AVCodecContext *avctx)
s->mb_height = (avctx->coded_height+15) / 16;
if (s->mb_width > 1000 || s->mb_height > 1000) {
+ avcodec_set_dimensions(avctx, 0, 0);
av_log(avctx, AV_LOG_ERROR, "picture too big\n");
return -1;
}
@@ -511,6 +516,18 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
if (!res)
return -1;
+ if (res == 2) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ if (s->frames[i].data[0])
+ avctx->release_buffer(avctx, &s->frames[i]);
+ }
+ if (is_alpha) {
+ avcodec_set_dimensions(avctx, 0, 0);
+ return -1;
+ }
+ }
+
if (!is_alpha) {
p->reference = 1;
if (avctx->get_buffer(avctx, p) < 0) {
diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h
index 0c34438..ceb516d 100644
--- a/libavcodec/vp56.h
+++ b/libavcodec/vp56.h
@@ -1,7 +1,4 @@
-/**
- * @file
- * VP5 and VP6 compatible video decoder (common features)
- *
+/*
* Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of Libav.
@@ -21,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP5 and VP6 compatible video decoder (common features)
+ */
+
#ifndef AVCODEC_VP56_H
#define AVCODEC_VP56_H
diff --git a/libavcodec/vp56data.c b/libavcodec/vp56data.c
index 7a41876..aa1dcef 100644
--- a/libavcodec/vp56data.c
+++ b/libavcodec/vp56data.c
@@ -1,7 +1,4 @@
-/**
- * @file
- * VP5 and VP6 compatible video decoder (common data)
- *
+/*
* Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of Libav.
@@ -21,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP5 and VP6 compatible video decoder (common data)
+ */
+
#include "vp56data.h"
const uint8_t vp56_b2p[] = { 0, 0, 0, 0, 1, 2, 3, 3, 3, 3 };
diff --git a/libavcodec/vp56data.h b/libavcodec/vp56data.h
index 7be5921..b1f2710 100644
--- a/libavcodec/vp56data.h
+++ b/libavcodec/vp56data.h
@@ -1,7 +1,4 @@
-/**
- * @file
- * VP5 and VP6 compatible video decoder (common data)
- *
+/*
* Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of Libav.
@@ -21,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP5 and VP6 compatible video decoder (common data)
+ */
+
#ifndef AVCODEC_VP56DATA_H
#define AVCODEC_VP56DATA_H
diff --git a/libavcodec/vp5data.h b/libavcodec/vp5data.h
index 11144a3..b11b99d 100644
--- a/libavcodec/vp5data.h
+++ b/libavcodec/vp5data.h
@@ -1,7 +1,4 @@
-/**
- * @file
- * VP5 compatible video decoder
- *
+/*
* Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of Libav.
@@ -21,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP5 compatible video decoder
+ */
+
#ifndef AVCODEC_VP5DATA_H
#define AVCODEC_VP5DATA_H
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index 02fe70b..9433983 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -1,13 +1,6 @@
-/**
- * @file
- * VP6 compatible video decoder
- *
+/*
* Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.org>
*
- * The VP6F decoder accepts an optional 1 byte extradata. It is composed of:
- * - upper 4bits: difference between encoded width and visible width
- * - lower 4bits: difference between encoded height and visible height
- *
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
@@ -25,6 +18,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP6 compatible video decoder
+ *
+ * The VP6F decoder accepts an optional 1 byte extradata. It is composed of:
+ * - upper 4 bits: difference between encoded width and visible width
+ * - lower 4 bits: difference between encoded height and visible height
+ */
+
#include <stdlib.h>
#include "avcodec.h"
@@ -619,42 +621,39 @@ static av_cold int vp6_decode_free(AVCodecContext *avctx)
}
AVCodec ff_vp6_decoder = {
- "vp6",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VP6,
- sizeof(VP56Context),
- vp6_decode_init,
- NULL,
- vp6_decode_free,
- ff_vp56_decode_frame,
- CODEC_CAP_DR1,
+ .name = "vp6",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VP6,
+ .priv_data_size = sizeof(VP56Context),
+ .init = vp6_decode_init,
+ .close = vp6_decode_free,
+ .decode = ff_vp56_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("On2 VP6"),
};
/* flash version, not flipped upside-down */
AVCodec ff_vp6f_decoder = {
- "vp6f",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VP6F,
- sizeof(VP56Context),
- vp6_decode_init,
- NULL,
- vp6_decode_free,
- ff_vp56_decode_frame,
- CODEC_CAP_DR1,
+ .name = "vp6f",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VP6F,
+ .priv_data_size = sizeof(VP56Context),
+ .init = vp6_decode_init,
+ .close = vp6_decode_free,
+ .decode = ff_vp56_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"),
};
/* flash version, not flipped upside-down, with alpha channel */
AVCodec ff_vp6a_decoder = {
- "vp6a",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VP6A,
- sizeof(VP56Context),
- vp6_decode_init,
- NULL,
- vp6_decode_free,
- ff_vp56_decode_frame,
- CODEC_CAP_DR1,
+ .name = "vp6a",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VP6A,
+ .priv_data_size = sizeof(VP56Context),
+ .init = vp6_decode_init,
+ .close = vp6_decode_free,
+ .decode = ff_vp56_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"),
};
diff --git a/libavcodec/vp6data.h b/libavcodec/vp6data.h
index 2ba3ef3..9a11f89 100644
--- a/libavcodec/vp6data.h
+++ b/libavcodec/vp6data.h
@@ -1,7 +1,4 @@
-/**
- * @file
- * VP6 compatible video decoder
- *
+/*
* Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of Libav.
@@ -21,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP6 compatible video decoder
+ */
+
#ifndef AVCODEC_VP6DATA_H
#define AVCODEC_VP6DATA_H
diff --git a/libavcodec/vp6dsp.c b/libavcodec/vp6dsp.c
index 64282a5..54a96ed 100644
--- a/libavcodec/vp6dsp.c
+++ b/libavcodec/vp6dsp.c
@@ -1,7 +1,4 @@
-/**
- * @file
- * VP6 DSP-oriented functions
- *
+/*
* Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.org>
*
* This file is part of Libav.
@@ -21,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP6 DSP-oriented functions
+ */
+
#include "libavutil/common.h"
#include "vp56dsp.h"
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 5e331c9..8338198 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -24,6 +24,7 @@
#include "libavutil/imgutils.h"
#include "avcodec.h"
+#include "internal.h"
#include "vp8.h"
#include "vp8data.h"
#include "rectangle.h"
@@ -33,27 +34,76 @@
# include "arm/vp8.h"
#endif
-static void vp8_decode_flush(AVCodecContext *avctx)
+static void free_buffers(VP8Context *s)
+{
+ av_freep(&s->macroblocks_base);
+ av_freep(&s->filter_strength);
+ av_freep(&s->intra4x4_pred_mode_top);
+ av_freep(&s->top_nnz);
+ av_freep(&s->edge_emu_buffer);
+ av_freep(&s->top_border);
+
+ s->macroblocks = NULL;
+}
+
+static int vp8_alloc_frame(VP8Context *s, AVFrame *f)
+{
+ int ret;
+ if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0)
+ return ret;
+ if (s->num_maps_to_be_freed && !s->maps_are_invalid) {
+ f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed];
+ } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) {
+ ff_thread_release_buffer(s->avctx, f);
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
+static void vp8_release_frame(VP8Context *s, AVFrame *f, int prefer_delayed_free, int can_direct_free)
+{
+ if (f->ref_index[0]) {
+ if (prefer_delayed_free) {
+ /* Upon a size change, we want to free the maps but other threads may still
+ * be using them, so queue them. Upon a seek, all threads are inactive so
+ * we want to cache one to prevent re-allocation in the next decoding
+ * iteration, but the rest we can free directly. */
+ int max_queued_maps = can_direct_free ? 1 : FF_ARRAY_ELEMS(s->segmentation_maps);
+ if (s->num_maps_to_be_freed < max_queued_maps) {
+ s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0];
+ } else if (can_direct_free) /* vp8_decode_flush(), but our queue is full */ {
+ av_free(f->ref_index[0]);
+ } /* else: MEMLEAK (should never happen, but better that than crash) */
+ f->ref_index[0] = NULL;
+ } else /* vp8_decode_free() */ {
+ av_free(f->ref_index[0]);
+ }
+ }
+ ff_thread_release_buffer(s->avctx, f);
+}
+
+static void vp8_decode_flush_impl(AVCodecContext *avctx,
+ int prefer_delayed_free, int can_direct_free, int free_mem)
{
VP8Context *s = avctx->priv_data;
int i;
- if (!avctx->is_copy) {
+ if (!avctx->internal->is_copy) {
for (i = 0; i < 5; i++)
if (s->frames[i].data[0])
- ff_thread_release_buffer(avctx, &s->frames[i]);
+ vp8_release_frame(s, &s->frames[i], prefer_delayed_free, can_direct_free);
}
memset(s->framep, 0, sizeof(s->framep));
- av_freep(&s->macroblocks_base);
- av_freep(&s->filter_strength);
- av_freep(&s->intra4x4_pred_mode_top);
- av_freep(&s->top_nnz);
- av_freep(&s->edge_emu_buffer);
- av_freep(&s->top_border);
- av_freep(&s->segmentation_map);
+ if (free_mem) {
+ free_buffers(s);
+ s->maps_are_invalid = 1;
+ }
+}
- s->macroblocks = NULL;
+static void vp8_decode_flush(AVCodecContext *avctx)
+{
+ vp8_decode_flush_impl(avctx, 1, 1, 0);
}
static int update_dimensions(VP8Context *s, int width, int height)
@@ -63,7 +113,7 @@ static int update_dimensions(VP8Context *s, int width, int height)
if (av_image_check_size(width, height, 0, s->avctx))
return AVERROR_INVALIDDATA;
- vp8_decode_flush(s->avctx);
+ vp8_decode_flush_impl(s->avctx, 1, 0, 1);
avcodec_set_dimensions(s->avctx, width, height);
}
@@ -76,10 +126,9 @@ static int update_dimensions(VP8Context *s, int width, int height)
s->intra4x4_pred_mode_top = av_mallocz(s->mb_width*4);
s->top_nnz = av_mallocz(s->mb_width*sizeof(*s->top_nnz));
s->top_border = av_mallocz((s->mb_width+1)*sizeof(*s->top_border));
- s->segmentation_map = av_mallocz(s->mb_width*s->mb_height);
if (!s->macroblocks_base || !s->filter_strength || !s->intra4x4_pred_mode_top ||
- !s->top_nnz || !s->top_border || !s->segmentation_map)
+ !s->top_nnz || !s->top_border)
return AVERROR(ENOMEM);
s->macroblocks = s->macroblocks_base + 1;
@@ -273,7 +322,7 @@ static int decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
if (!s->macroblocks_base || /* first frame */
width != s->avctx->width || height != s->avctx->height) {
- if ((ret = update_dimensions(s, width, height) < 0))
+ if ((ret = update_dimensions(s, width, height)) < 0)
return ret;
}
@@ -487,6 +536,7 @@ void decode_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y)
AV_ZERO32(&near_mv[0]);
AV_ZERO32(&near_mv[1]);
+ AV_ZERO32(&near_mv[2]);
/* Process MB on top, left and top-left */
#define MV_EDGE_CHECK(n)\
@@ -919,7 +969,8 @@ void intra_predict(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb,
int mb_x, int mb_y)
{
AVCodecContext *avctx = s->avctx;
- int x, y, mode, nnz, tr;
+ int x, y, mode, nnz;
+ uint32_t tr;
// for the first row, we need to run xchg_mb_border to init the top edge to 127
// otherwise, skip it if we aren't going to deblock
@@ -948,7 +999,7 @@ void intra_predict(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb,
// from the top macroblock
if (!(!mb_y && avctx->flags & CODEC_FLAG_EMU_EDGE) &&
mb_x == s->mb_width-1) {
- tr = tr_right[-1]*0x01010101;
+ tr = tr_right[-1]*0x01010101u;
tr_right = (uint8_t *)&tr;
}
@@ -1047,7 +1098,7 @@ static const uint8_t subpel_idx[3][8] = {
*
* @param s VP8 decoding context
* @param dst target buffer for block data at block position
- * @param src reference picture buffer at origin (0, 0)
+ * @param ref reference picture buffer at origin (0, 0)
* @param mv motion vector (relative to block position) to get pixel data from
* @param x_off horizontal position of block from origin (0, 0)
* @param y_off vertical position of block from origin (0, 0)
@@ -1501,17 +1552,29 @@ static void filter_mb_row_simple(VP8Context *s, AVFrame *curframe, int mb_y)
}
}
+static void release_queued_segmaps(VP8Context *s, int is_close)
+{
+ int leave_behind = is_close ? 0 : !s->maps_are_invalid;
+ while (s->num_maps_to_be_freed > leave_behind)
+ av_freep(&s->segmentation_maps[--s->num_maps_to_be_freed]);
+ s->maps_are_invalid = 0;
+}
+
static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
AVPacket *avpkt)
{
VP8Context *s = avctx->priv_data;
int ret, mb_x, mb_y, i, y, referenced;
enum AVDiscard skip_thresh;
- AVFrame *av_uninit(curframe), *prev_frame = s->framep[VP56_FRAME_CURRENT];
+ AVFrame *av_uninit(curframe), *prev_frame;
+
+ release_queued_segmaps(s, 0);
if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0)
return ret;
+ prev_frame = s->framep[VP56_FRAME_CURRENT];
+
referenced = s->update_last || s->update_golden == VP56_FRAME_CURRENT
|| s->update_altref == VP56_FRAME_CURRENT;
@@ -1531,7 +1594,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
&s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
&s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
&s->frames[i] != s->framep[VP56_FRAME_GOLDEN2])
- ff_thread_release_buffer(avctx, &s->frames[i]);
+ vp8_release_frame(s, &s->frames[i], 1, 0);
// find a free buffer
for (i = 0; i < 5; i++)
@@ -1547,13 +1610,12 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
abort();
}
if (curframe->data[0])
- ff_thread_release_buffer(avctx, curframe);
+ vp8_release_frame(s, curframe, 1, 0);
curframe->key_frame = s->keyframe;
curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
curframe->reference = referenced ? 3 : 0;
- curframe->ref_index[0] = s->segmentation_map;
- if ((ret = ff_thread_get_buffer(avctx, curframe))) {
+ if ((ret = vp8_alloc_frame(s, curframe))) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n");
return ret;
}
@@ -1645,8 +1707,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
s->dsp.prefetch(dst[0] + (mb_x&3)*4*s->linesize + 64, s->linesize, 4);
s->dsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1], 2);
- decode_mb_mode(s, mb, mb_x, mb_y, s->segmentation_map + mb_xy,
- prev_frame ? prev_frame->ref_index[0] + mb_xy : NULL);
+ decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy,
+ prev_frame && prev_frame->ref_index[0] ? prev_frame->ref_index[0] + mb_xy : NULL);
prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS);
@@ -1721,7 +1783,7 @@ static av_cold int vp8_decode_init(AVCodecContext *avctx)
avctx->pix_fmt = PIX_FMT_YUV420P;
dsputil_init(&s->dsp, avctx);
- ff_h264_pred_init(&s->hpc, CODEC_ID_VP8, 8);
+ ff_h264_pred_init(&s->hpc, CODEC_ID_VP8, 8, 1);
ff_vp8dsp_init(&s->vp8dsp);
return 0;
@@ -1729,7 +1791,8 @@ static av_cold int vp8_decode_init(AVCodecContext *avctx)
static av_cold int vp8_decode_free(AVCodecContext *avctx)
{
- vp8_decode_flush(avctx);
+ vp8_decode_flush_impl(avctx, 0, 1, 1);
+ release_queued_segmaps(avctx->priv_data, 1);
return 0;
}
@@ -1749,6 +1812,12 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
{
VP8Context *s = dst->priv_data, *s_src = src->priv_data;
+ if (s->macroblocks_base &&
+ (s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) {
+ free_buffers(s);
+ s->maps_are_invalid = 1;
+ }
+
s->prob[0] = s_src->prob[!s_src->update_probabilities];
s->segmentation = s_src->segmentation;
s->lf_delta = s_src->lf_delta;
@@ -1764,15 +1833,14 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
}
AVCodec ff_vp8_decoder = {
- "vp8",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VP8,
- sizeof(VP8Context),
- vp8_decode_init,
- NULL,
- vp8_decode_free,
- vp8_decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+ .name = "vp8",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VP8,
+ .priv_data_size = sizeof(VP8Context),
+ .init = vp8_decode_init,
+ .close = vp8_decode_free,
+ .decode = vp8_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
.flush = vp8_decode_flush,
.long_name = NULL_IF_CONFIG_SMALL("On2 VP8"),
.init_thread_copy = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy),
diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h
index 5a96cd4..6cbdca2 100644
--- a/libavcodec/vp8.h
+++ b/libavcodec/vp8.h
@@ -130,7 +130,6 @@ typedef struct {
uint8_t *intra4x4_pred_mode_top;
uint8_t intra4x4_pred_mode_left[4];
- uint8_t *segmentation_map;
/**
* Macroblocks can have one of 4 different quants in a frame when
@@ -237,6 +236,16 @@ typedef struct {
H264PredContext hpc;
vp8_mc_func put_pixels_tab[3][3][3];
AVFrame frames[5];
+
+ /**
+ * A list of segmentation_map buffers that are to be free()'ed in
+ * the next decoding iteration. We can't free() them right away
+ * because the map may still be used by subsequent decoding threads.
+ * Unused if frame threading is off.
+ */
+ uint8_t *segmentation_maps[5];
+ int num_maps_to_be_freed;
+ int maps_are_invalid;
} VP8Context;
#endif /* AVCODEC_VP8_H */
diff --git a/libavcodec/vp8_parser.c b/libavcodec/vp8_parser.c
index fbdd0ee..e6d4151 100644
--- a/libavcodec/vp8_parser.c
+++ b/libavcodec/vp8_parser.c
@@ -33,8 +33,6 @@ static int parse(AVCodecParserContext *s,
}
AVCodecParser ff_vp8_parser = {
- { CODEC_ID_VP8 },
- 0,
- NULL,
- parse,
+ .codec_ids = { CODEC_ID_VP8 },
+ .parser_parse = parse,
};
diff --git a/libavcodec/vp8data.h b/libavcodec/vp8data.h
index 4ea4581..a48b0f6 100644
--- a/libavcodec/vp8data.h
+++ b/libavcodec/vp8data.h
@@ -1,6 +1,4 @@
-/**
- * VP8 compatible video decoder
- *
+/*
* Copyright (C) 2010 David Conrad
* Copyright (C) 2010 Ronald S. Bultje
*
@@ -21,6 +19,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP8 compatible video decoder
+ */
+
#ifndef AVCODEC_VP8DATA_H
#define AVCODEC_VP8DATA_H
diff --git a/libavcodec/vp8dsp.c b/libavcodec/vp8dsp.c
index 159c070..89c3453 100644
--- a/libavcodec/vp8dsp.c
+++ b/libavcodec/vp8dsp.c
@@ -1,6 +1,4 @@
-/**
- * VP8 compatible video decoder
- *
+/*
* Copyright (C) 2010 David Conrad
* Copyright (C) 2010 Ronald S. Bultje
*
@@ -21,6 +19,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP8 compatible video decoder
+ */
+
#include "dsputil.h"
#include "vp8dsp.h"
diff --git a/libavcodec/vp8dsp.h b/libavcodec/vp8dsp.h
index e2fb8e7..5429e98 100644
--- a/libavcodec/vp8dsp.h
+++ b/libavcodec/vp8dsp.h
@@ -1,6 +1,4 @@
-/**
- * VP8 compatible video decoder
- *
+/*
* Copyright (C) 2010 David Conrad
* Copyright (C) 2010 Ronald S. Bultje
*
@@ -21,6 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * VP8 compatible video decoder
+ */
#ifndef AVCODEC_VP8DSP_H
#define AVCODEC_VP8DSP_H
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index caffddb..7a6308a 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -21,9 +21,9 @@
/**
* @file
- * VQA Video Decoder by Mike Melanson (melanson at pcisys.net)
- * For more information about the VQA format, visit:
- * http://wiki.multimedia.cx/index.php?title=VQA
+ * VQA Video Decoder
+ * @author Mike Melanson (melanson at pcisys.net)
+ * @see http://wiki.multimedia.cx/index.php?title=VQA
*
* The VQA video decoder outputs PAL8 or RGB555 colorspace data, depending
* on the type of data in the file.
@@ -600,14 +600,13 @@ static av_cold int vqa_decode_end(AVCodecContext *avctx)
}
AVCodec ff_vqa_decoder = {
- "vqavideo",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_WS_VQA,
- sizeof(VqaContext),
- vqa_decode_init,
- NULL,
- vqa_decode_end,
- vqa_decode_frame,
- CODEC_CAP_DR1,
+ .name = "vqavideo",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_WS_VQA,
+ .priv_data_size = sizeof(VqaContext),
+ .init = vqa_decode_init,
+ .close = vqa_decode_end,
+ .decode = vqa_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA (Vector Quantized Animation) video"),
};
diff --git a/libavcodec/w32pthreads.h b/libavcodec/w32pthreads.h
new file mode 100644
index 0000000..70b84cf
--- /dev/null
+++ b/libavcodec/w32pthreads.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2010-2011 x264 project
+ *
+ * Authors: Steven Walters <kemuri9 at gmail.com>
+ * Pegasys Inc. <http://www.pegasys-inc.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * w32threads to pthreads wrapper
+ */
+
+#ifndef AVCODEC_W32PTHREADS_H
+#define AVCODEC_W32PTHREADS_H
+
+/* Build up a pthread-like API using underlying Windows API. Have only static
+ * methods so as to not conflict with a potentially linked in pthread-win32
+ * library.
+ * As most functions here are used without checking return values,
+ * only implement return values as necessary. */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <process.h>
+
+typedef struct {
+ void *handle;
+ void *(*func)(void* arg);
+ void *arg;
+ void *ret;
+} pthread_t;
+
+/* the conditional variable api for windows 6.0+ uses critical sections and
+ * not mutexes */
+typedef CRITICAL_SECTION pthread_mutex_t;
+
+/* This is the CONDITIONAL_VARIABLE typedef for using Window's native
+ * conditional variables on kernels 6.0+.
+ * MinGW does not currently have this typedef. */
+typedef struct {
+ void *ptr;
+} pthread_cond_t;
+
+/* function pointers to conditional variable API on windows 6.0+ kernels */
+static void (WINAPI *cond_broadcast)(pthread_cond_t *cond);
+static void (WINAPI *cond_init)(pthread_cond_t *cond);
+static void (WINAPI *cond_signal)(pthread_cond_t *cond);
+static BOOL (WINAPI *cond_wait)(pthread_cond_t *cond, pthread_mutex_t *mutex,
+ DWORD milliseconds);
+
+static unsigned __stdcall attribute_align_arg win32thread_worker(void *arg)
+{
+ pthread_t *h = arg;
+ h->ret = h->func(h->arg);
+ return 0;
+}
+
+static int pthread_create(pthread_t *thread, const void *unused_attr,
+ void *(*start_routine)(void*), void *arg)
+{
+ thread->func = start_routine;
+ thread->arg = arg;
+ thread->handle = (void*)_beginthreadex(NULL, 0, win32thread_worker, thread,
+ 0, NULL);
+ return !thread->handle;
+}
+
+static void pthread_join(pthread_t thread, void **value_ptr)
+{
+ DWORD ret = WaitForSingleObject(thread.handle, INFINITE);
+ if (ret != WAIT_OBJECT_0)
+ return;
+ if (value_ptr)
+ *value_ptr = thread.ret;
+ CloseHandle(thread.handle);
+}
+
+static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
+{
+ InitializeCriticalSection(m);
+ return 0;
+}
+static inline int pthread_mutex_destroy(pthread_mutex_t *m)
+{
+ DeleteCriticalSection(m);
+ return 0;
+}
+static inline int pthread_mutex_lock(pthread_mutex_t *m)
+{
+ EnterCriticalSection(m);
+ return 0;
+}
+static inline int pthread_mutex_unlock(pthread_mutex_t *m)
+{
+ LeaveCriticalSection(m);
+ return 0;
+}
+
+/* for pre-Windows 6.0 platforms we need to define and use our own condition
+ * variable and api */
+typedef struct {
+ pthread_mutex_t mtx_broadcast;
+ pthread_mutex_t mtx_waiter_count;
+ volatile int waiter_count;
+ HANDLE semaphore;
+ HANDLE waiters_done;
+ volatile int is_broadcast;
+} win32_cond_t;
+
+static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
+{
+ win32_cond_t *win32_cond = NULL;
+ if (cond_init) {
+ cond_init(cond);
+ return;
+ }
+
+ /* non native condition variables */
+ win32_cond = av_mallocz(sizeof(win32_cond_t));
+ if (!win32_cond)
+ return;
+ cond->ptr = win32_cond;
+ win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
+ if (!win32_cond->semaphore)
+ return;
+ win32_cond->waiters_done = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (!win32_cond->waiters_done)
+ return;
+
+ pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL);
+ pthread_mutex_init(&win32_cond->mtx_broadcast, NULL);
+}
+
+static void pthread_cond_destroy(pthread_cond_t *cond)
+{
+ win32_cond_t *win32_cond = cond->ptr;
+ /* native condition variables do not destroy */
+ if (cond_init)
+ return;
+
+ /* non native condition variables */
+ CloseHandle(win32_cond->semaphore);
+ CloseHandle(win32_cond->waiters_done);
+ pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
+ pthread_mutex_destroy(&win32_cond->mtx_broadcast);
+ av_freep(&win32_cond);
+ cond->ptr = NULL;
+}
+
+static void pthread_cond_broadcast(pthread_cond_t *cond)
+{
+ win32_cond_t *win32_cond = cond->ptr;
+ int have_waiter;
+
+ if (cond_broadcast) {
+ cond_broadcast(cond);
+ return;
+ }
+
+ /* non native condition variables */
+ pthread_mutex_lock(&win32_cond->mtx_broadcast);
+ pthread_mutex_lock(&win32_cond->mtx_waiter_count);
+ have_waiter = 0;
+
+ if (win32_cond->waiter_count) {
+ win32_cond->is_broadcast = 1;
+ have_waiter = 1;
+ }
+
+ if (have_waiter) {
+ ReleaseSemaphore(win32_cond->semaphore, win32_cond->waiter_count, NULL);
+ pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+ WaitForSingleObject(win32_cond->waiters_done, INFINITE);
+ ResetEvent(win32_cond->waiters_done);
+ win32_cond->is_broadcast = 0;
+ } else
+ pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+ pthread_mutex_unlock(&win32_cond->mtx_broadcast);
+}
+
+static void pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ win32_cond_t *win32_cond = cond->ptr;
+ int last_waiter;
+ if (cond_wait) {
+ cond_wait(cond, mutex, INFINITE);
+ return;
+ }
+
+ /* non native condition variables */
+ pthread_mutex_lock(&win32_cond->mtx_broadcast);
+ pthread_mutex_lock(&win32_cond->mtx_waiter_count);
+ win32_cond->waiter_count++;
+ pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+ pthread_mutex_unlock(&win32_cond->mtx_broadcast);
+
+ // unlock the external mutex
+ pthread_mutex_unlock(mutex);
+ WaitForSingleObject(win32_cond->semaphore, INFINITE);
+
+ pthread_mutex_lock(&win32_cond->mtx_waiter_count);
+ win32_cond->waiter_count--;
+ last_waiter = !win32_cond->waiter_count || !win32_cond->is_broadcast;
+ pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+
+ if (last_waiter)
+ SetEvent(win32_cond->waiters_done);
+
+ // lock the external mutex
+ return pthread_mutex_lock(mutex);
+}
+
+static void pthread_cond_signal(pthread_cond_t *cond)
+{
+ win32_cond_t *win32_cond = cond->ptr;
+ int have_waiter;
+ if (cond_signal) {
+ cond_signal(cond);
+ return;
+ }
+
+ pthread_mutex_lock(&win32_cond->mtx_broadcast);
+
+ /* non-native condition variables */
+ pthread_mutex_lock(&win32_cond->mtx_waiter_count);
+ have_waiter = win32_cond->waiter_count;
+ pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+
+ if (have_waiter) {
+ ReleaseSemaphore(win32_cond->semaphore, 1, NULL);
+ WaitForSingleObject(win32_cond->waiters_done, INFINITE);
+ ResetEvent(win32_cond->waiters_done);
+ }
+
+ pthread_mutex_unlock(&win32_cond->mtx_broadcast);
+}
+
+static void w32thread_init(void)
+{
+ HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll"));
+ /* if one is available, then they should all be available */
+ cond_init =
+ (void*)GetProcAddress(kernel_dll, "InitializeConditionVariable");
+ cond_broadcast =
+ (void*)GetProcAddress(kernel_dll, "WakeAllConditionVariable");
+ cond_signal =
+ (void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
+ cond_wait =
+ (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
+}
+
+#endif /* AVCODEC_W32PTHREADS_H */
diff --git a/libavcodec/w32thread.c b/libavcodec/w32thread.c
deleted file mode 100644
index 023be0e..0000000
--- a/libavcodec/w32thread.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (c) 2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-//#define DEBUG
-
-#include "avcodec.h"
-#include "thread.h"
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <process.h>
-
-typedef struct ThreadContext{
- AVCodecContext *avctx;
- HANDLE thread;
- HANDLE work_sem;
- HANDLE job_sem;
- HANDLE done_sem;
- int (*func)(AVCodecContext *c, void *arg);
- int (*func2)(AVCodecContext *c, void *arg, int, int);
- void *arg;
- int argsize;
- int *jobnr;
- int *ret;
- int threadnr;
-}ThreadContext;
-
-
-static unsigned WINAPI attribute_align_arg thread_func(void *v){
- ThreadContext *c= v;
-
- for(;;){
- int ret, jobnr;
-//printf("thread_func %X enter wait\n", (int)v); fflush(stdout);
- WaitForSingleObject(c->work_sem, INFINITE);
- // avoid trying to access jobnr if we should quit
- if (!c->func && !c->func2)
- break;
- WaitForSingleObject(c->job_sem, INFINITE);
- jobnr = (*c->jobnr)++;
- ReleaseSemaphore(c->job_sem, 1, 0);
-//printf("thread_func %X after wait (func=%X)\n", (int)v, (int)c->func); fflush(stdout);
- if(c->func)
- ret= c->func(c->avctx, (uint8_t *)c->arg + jobnr*c->argsize);
- else
- ret= c->func2(c->avctx, c->arg, jobnr, c->threadnr);
- if (c->ret)
- c->ret[jobnr] = ret;
-//printf("thread_func %X signal complete\n", (int)v); fflush(stdout);
- ReleaseSemaphore(c->done_sem, 1, 0);
- }
-
- return 0;
-}
-
-/**
- * Free what has been allocated by ff_thread_init().
- * Must be called after decoding has finished, especially do not call while avcodec_thread_execute() is running.
- */
-void ff_thread_free(AVCodecContext *s){
- ThreadContext *c= s->thread_opaque;
- int i;
-
- for(i=0; i<s->thread_count; i++){
-
- c[i].func= NULL;
- c[i].func2= NULL;
- }
- ReleaseSemaphore(c[0].work_sem, s->thread_count, 0);
- for(i=0; i<s->thread_count; i++){
- WaitForSingleObject(c[i].thread, INFINITE);
- if(c[i].thread) CloseHandle(c[i].thread);
- }
- if(c[0].work_sem) CloseHandle(c[0].work_sem);
- if(c[0].job_sem) CloseHandle(c[0].job_sem);
- if(c[0].done_sem) CloseHandle(c[0].done_sem);
-
- av_freep(&s->thread_opaque);
-}
-
-static int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size){
- ThreadContext *c= s->thread_opaque;
- int i;
- int jobnr = 0;
-
- assert(s == c->avctx);
-
- /* note, we can be certain that this is not called with the same AVCodecContext by different threads at the same time */
-
- for(i=0; i<s->thread_count; i++){
- c[i].arg= arg;
- c[i].argsize= size;
- c[i].func= func;
- c[i].ret= ret;
- c[i].jobnr = &jobnr;
- }
- ReleaseSemaphore(c[0].work_sem, count, 0);
- for(i=0; i<count; i++)
- WaitForSingleObject(c[0].done_sem, INFINITE);
-
- return 0;
-}
-
-static int avcodec_thread_execute2(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count){
- ThreadContext *c= s->thread_opaque;
- int i;
- for(i=0; i<s->thread_count; i++)
- c[i].func2 = func;
- avcodec_thread_execute(s, NULL, arg, ret, count, 0);
-}
-
-int ff_thread_init(AVCodecContext *s){
- int i;
- ThreadContext *c;
- uint32_t threadid;
-
- if(!(s->thread_type & FF_THREAD_SLICE)){
- av_log(s, AV_LOG_WARNING, "The requested thread algorithm is not supported with this thread library.\n");
- return 0;
- }
-
- s->active_thread_type= FF_THREAD_SLICE;
-
- if (s->thread_count <= 1)
- return 0;
-
- assert(!s->thread_opaque);
- c= av_mallocz(sizeof(ThreadContext)*s->thread_count);
- s->thread_opaque= c;
- if(!(c[0].work_sem = CreateSemaphore(NULL, 0, INT_MAX, NULL)))
- goto fail;
- if(!(c[0].job_sem = CreateSemaphore(NULL, 1, 1, NULL)))
- goto fail;
- if(!(c[0].done_sem = CreateSemaphore(NULL, 0, INT_MAX, NULL)))
- goto fail;
-
- for(i=0; i<s->thread_count; i++){
-//printf("init semaphors %d\n", i); fflush(stdout);
- c[i].avctx= s;
- c[i].work_sem = c[0].work_sem;
- c[i].job_sem = c[0].job_sem;
- c[i].done_sem = c[0].done_sem;
- c[i].threadnr = i;
-
-//printf("create thread %d\n", i); fflush(stdout);
- c[i].thread = (HANDLE)_beginthreadex(NULL, 0, thread_func, &c[i], 0, &threadid );
- if( !c[i].thread ) goto fail;
- }
-//printf("init done\n"); fflush(stdout);
-
- s->execute= avcodec_thread_execute;
- s->execute2= avcodec_thread_execute2;
-
- return 0;
-fail:
- ff_thread_free(s);
- return -1;
-}
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 155633f..7d16a9b 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -18,7 +18,7 @@
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "get_bits.h"
#include "unary.h"
@@ -110,13 +110,11 @@ typedef struct WavpackFrameContext {
int extra_bits;
int and, or, shift;
int post_shift;
- int hybrid, hybrid_bitrate;
+ int hybrid, hybrid_bitrate, hybrid_maxclip;
int float_flag;
int float_shift;
int float_max_exp;
WvChannel ch[2];
- int samples_left;
- int max_samples;
int pos;
SavedContext sc, extra_sc;
} WavpackFrameContext;
@@ -125,6 +123,7 @@ typedef struct WavpackFrameContext {
typedef struct WavpackContext {
AVCodecContext *avctx;
+ AVFrame frame;
WavpackFrameContext *fdec[WV_MAX_FRAME_DECODERS];
int fdec_num;
@@ -133,7 +132,6 @@ typedef struct WavpackContext {
int mkv_mode;
int block;
int samples;
- int samples_left;
int ch_offset;
} WavpackContext;
@@ -405,8 +403,14 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, in
*crc = *crc * 9 + (S&0xffff) * 3 + ((unsigned)S>>16);
}
}
+
bit = (S & s->and) | s->or;
- return (((S + bit) << s->shift) - bit) << s->post_shift;
+ bit = (((S + bit) << s->shift) - bit) << s->post_shift;
+
+ if(s->hybrid)
+ bit = av_clip(bit, -s->hybrid_maxclip - 1, s->hybrid_maxclip);
+
+ return bit;
}
static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S)
@@ -501,8 +505,7 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, vo
float *dstfl = dst;
const int channel_pad = s->avctx->channels - 2;
- if(s->samples_left == s->samples)
- s->one = s->zero = s->zeroes = 0;
+ s->one = s->zero = s->zeroes = 0;
do{
L = wv_get_value(s, gb, 0, &last);
if(last) break;
@@ -593,13 +596,9 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, vo
dst16 += channel_pad;
}
count++;
- }while(!last && count < s->max_samples);
+ } while (!last && count < s->samples);
- if (last)
- s->samples_left = 0;
- else
- s->samples_left -= count;
- if(!s->samples_left){
+ wv_reset_saved_context(s);
if(crc != s->CRC){
av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
return -1;
@@ -608,16 +607,7 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, vo
av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");
return -1;
}
- wv_reset_saved_context(s);
- }else{
- s->pos = pos;
- s->sc.crc = crc;
- s->sc.bits_used = get_bits_count(&s->gb);
- if(s->got_extra_bits){
- s->extra_sc.crc = crc_extra_bits;
- s->extra_sc.bits_used = get_bits_count(&s->gb_extra_bits);
- }
- }
+
return count * 2;
}
@@ -634,8 +624,7 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void
float *dstfl = dst;
const int channel_stride = s->avctx->channels;
- if(s->samples_left == s->samples)
- s->one = s->zero = s->zeroes = 0;
+ s->one = s->zero = s->zeroes = 0;
do{
T = wv_get_value(s, gb, 0, &last);
S = 0;
@@ -674,13 +663,9 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void
dst16 += channel_stride;
}
count++;
- }while(!last && count < s->max_samples);
+ } while (!last && count < s->samples);
- if (last)
- s->samples_left = 0;
- else
- s->samples_left -= count;
- if(!s->samples_left){
+ wv_reset_saved_context(s);
if(crc != s->CRC){
av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
return -1;
@@ -689,16 +674,7 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void
av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");
return -1;
}
- wv_reset_saved_context(s);
- }else{
- s->pos = pos;
- s->sc.crc = crc;
- s->sc.bits_used = get_bits_count(&s->gb);
- if(s->got_extra_bits){
- s->extra_sc.crc = crc_extra_bits;
- s->extra_sc.bits_used = get_bits_count(&s->gb_extra_bits);
- }
- }
+
return count;
}
@@ -742,6 +718,9 @@ static av_cold int wavpack_decode_init(AVCodecContext *avctx)
s->fdec_num = 0;
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
@@ -758,7 +737,7 @@ static av_cold int wavpack_decode_end(AVCodecContext *avctx)
}
static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
- void *data, int *data_size,
+ void *data, int *got_frame_ptr,
const uint8_t *buf, int buf_size)
{
WavpackContext *wc = avctx->priv_data;
@@ -773,7 +752,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
int bpp, chan, chmask;
if (buf_size == 0){
- *data_size = 0;
+ *got_frame_ptr = 0;
return 0;
}
@@ -788,34 +767,30 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
return -1;
}
- if(!s->samples_left){
memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
memset(s->ch, 0, sizeof(s->ch));
s->extra_bits = 0;
s->and = s->or = s->shift = 0;
s->got_extra_bits = 0;
- }
if(!wc->mkv_mode){
s->samples = AV_RL32(buf); buf += 4;
if(!s->samples){
- *data_size = 0;
- return buf_size;
+ *got_frame_ptr = 0;
+ return 0;
}
}else{
s->samples = wc->samples;
}
s->frame_flags = AV_RL32(buf); buf += 4;
if(s->frame_flags&0x80){
- bpp = sizeof(float);
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
} else if((s->frame_flags&0x03) <= 1){
- bpp = 2;
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
} else {
- bpp = 4;
avctx->sample_fmt = AV_SAMPLE_FMT_S32;
}
+ bpp = av_get_bytes_per_sample(avctx->sample_fmt);
samples = (uint8_t*)samples + bpp * wc->ch_offset;
s->stereo = !(s->frame_flags & WV_MONO);
@@ -823,6 +798,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
s->joint = s->frame_flags & WV_JOINT_STEREO;
s->hybrid = s->frame_flags & WV_HYBRID_MODE;
s->hybrid_bitrate = s->frame_flags & WV_HYBRID_BITRATE;
+ s->hybrid_maxclip = (1LL << ((((s->frame_flags & 0x03) + 1) << 3) - 1)) - 1;
s->post_shift = 8 * (bpp-1-(s->frame_flags&0x03)) + ((s->frame_flags >> 13) & 0x1f);
s->CRC = AV_RL32(buf); buf += 4;
if(wc->mkv_mode)
@@ -830,13 +806,6 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
wc->ch_offset += 1 + s->stereo;
- s->max_samples = *data_size / (bpp * avctx->channels);
- s->max_samples = FFMIN(s->max_samples, s->samples);
- if(s->samples_left > 0){
- s->max_samples = FFMIN(s->max_samples, s->samples_left);
- buf = buf_end;
- }
-
// parse metadata blocks
while(buf < buf_end){
id = *buf++;
@@ -1065,7 +1034,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
}
if(id & WP_IDF_ODD) buf++;
}
- if(!s->samples_left){
+
if(!got_terms){
av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n");
return -1;
@@ -1102,16 +1071,6 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
s->got_extra_bits = 0;
}
}
- s->samples_left = s->samples;
- }else{
- init_get_bits(&s->gb, orig_buf + s->sc.offset, s->sc.size);
- skip_bits_long(&s->gb, s->sc.bits_used);
- if(s->got_extra_bits){
- init_get_bits(&s->gb_extra_bits, orig_buf + s->extra_sc.offset,
- s->extra_sc.size);
- skip_bits_long(&s->gb_extra_bits, s->extra_sc.bits_used);
- }
- }
if(s->stereo_in){
if(avctx->sample_fmt == AV_SAMPLE_FMT_S16)
@@ -1168,28 +1127,54 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
}
}
- wc->samples_left = s->samples_left;
+ *got_frame_ptr = 1;
return samplecount * bpp;
}
-static int wavpack_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static void wavpack_decode_flush(AVCodecContext *avctx)
+{
+ WavpackContext *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < s->fdec_num; i++)
+ wv_reset_saved_context(s->fdec[i]);
+}
+
+static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
WavpackContext *s = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- int frame_size;
+ int frame_size, ret;
int samplecount = 0;
s->block = 0;
- s->samples_left = 0;
s->ch_offset = 0;
+ /* determine number of samples */
if(s->mkv_mode){
s->samples = AV_RL32(buf); buf += 4;
+ } else {
+ if (s->multichannel)
+ s->samples = AV_RL32(buf + 4);
+ else
+ s->samples = AV_RL32(buf);
}
+ if (s->samples <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n",
+ s->samples);
+ return AVERROR(EINVAL);
+ }
+
+ /* get output buffer */
+ s->frame.nb_samples = s->samples;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+
while(buf_size > 0){
if(!s->multichannel){
frame_size = buf_size;
@@ -1205,28 +1190,33 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
if(frame_size < 0 || frame_size > buf_size){
av_log(avctx, AV_LOG_ERROR, "Block %d has invalid size (size %d vs. %d bytes left)\n",
s->block, frame_size, buf_size);
+ wavpack_decode_flush(avctx);
return -1;
}
- if((samplecount = wavpack_decode_block(avctx, s->block, data,
- data_size, buf, frame_size)) < 0)
+ if((samplecount = wavpack_decode_block(avctx, s->block, s->frame.data[0],
+ got_frame_ptr, buf, frame_size)) < 0) {
+ wavpack_decode_flush(avctx);
return -1;
+ }
s->block++;
buf += frame_size; buf_size -= frame_size;
}
- *data_size = samplecount * avctx->channels;
- return s->samples_left > 0 ? 0 : avpkt->size;
+ if (*got_frame_ptr)
+ *(AVFrame *)data = s->frame;
+
+ return avpkt->size;
}
AVCodec ff_wavpack_decoder = {
- "wavpack",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_WAVPACK,
- sizeof(WavpackContext),
- wavpack_decode_init,
- NULL,
- wavpack_decode_end,
- wavpack_decode_frame,
- .capabilities = CODEC_CAP_SUBFRAMES,
+ .name = "wavpack",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_WAVPACK,
+ .priv_data_size = sizeof(WavpackContext),
+ .init = wavpack_decode_init,
+ .close = wavpack_decode_end,
+ .decode = wavpack_decode_frame,
+ .flush = wavpack_decode_flush,
+ .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("WavPack"),
};
diff --git a/libavcodec/wma.h b/libavcodec/wma.h
index f11d550..4acbf04 100644
--- a/libavcodec/wma.h
+++ b/libavcodec/wma.h
@@ -65,6 +65,7 @@ typedef struct CoefVLCTable {
typedef struct WMACodecContext {
AVCodecContext* avctx;
+ AVFrame frame;
GetBitContext gb;
PutBitContext pb;
int sample_rate;
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index 479b34c..5600f9b 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -124,6 +124,10 @@ static int wma_decode_init(AVCodecContext * avctx)
}
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
@@ -797,14 +801,13 @@ static int wma_decode_frame(WMACodecContext *s, int16_t *samples)
return 0;
}
-static int wma_decode_superframe(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int wma_decode_superframe(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
WMACodecContext *s = avctx->priv_data;
- int nb_frames, bit_offset, i, pos, len;
+ int nb_frames, bit_offset, i, pos, len, ret;
uint8_t *q;
int16_t *samples;
@@ -818,20 +821,25 @@ static int wma_decode_superframe(AVCodecContext *avctx,
return 0;
buf_size = s->block_align;
- samples = data;
-
init_get_bits(&s->gb, buf, buf_size*8);
if (s->use_bit_reservoir) {
/* read super frame header */
skip_bits(&s->gb, 4); /* super frame index */
- nb_frames = get_bits(&s->gb, 4) - 1;
+ nb_frames = get_bits(&s->gb, 4) - (s->last_superframe_len <= 0);
+ } else {
+ nb_frames = 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;
- }
+ /* get output buffer */
+ s->frame.nb_samples = nb_frames * s->frame_len;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = (int16_t *)s->frame.data[0];
+ if (s->use_bit_reservoir) {
bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3);
if (s->last_superframe_len > 0) {
@@ -860,6 +868,7 @@ static int wma_decode_superframe(AVCodecContext *avctx,
if (wma_decode_frame(s, samples) < 0)
goto fail;
samples += s->nb_channels * s->frame_len;
+ nb_frames--;
}
/* read each frame starting from bit_offset */
@@ -888,10 +897,6 @@ 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;
@@ -900,7 +905,9 @@ static int wma_decode_superframe(AVCodecContext *avctx,
//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d outbytes:%d eaten:%d\n", s->frame_len_bits, s->block_len_bits, s->frame_len, s->block_len, (int8_t *)samples - (int8_t *)data, s->block_align);
- *data_size = (int8_t *)samples - (int8_t *)data;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return s->block_align;
fail:
/* when error, we reset the bit reservoir */
@@ -916,30 +923,28 @@ static av_cold void flush(AVCodecContext *avctx)
s->last_superframe_len= 0;
}
-AVCodec ff_wmav1_decoder =
-{
- "wmav1",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_WMAV1,
- sizeof(WMACodecContext),
- wma_decode_init,
- NULL,
- ff_wma_end,
- wma_decode_superframe,
- .flush=flush,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
+AVCodec ff_wmav1_decoder = {
+ .name = "wmav1",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_WMAV1,
+ .priv_data_size = sizeof(WMACodecContext),
+ .init = wma_decode_init,
+ .close = ff_wma_end,
+ .decode = wma_decode_superframe,
+ .flush = flush,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
};
-AVCodec ff_wmav2_decoder =
-{
- "wmav2",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_WMAV2,
- sizeof(WMACodecContext),
- wma_decode_init,
- NULL,
- ff_wma_end,
- wma_decode_superframe,
- .flush=flush,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
+AVCodec ff_wmav2_decoder = {
+ .name = "wmav2",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_WMAV2,
+ .priv_data_size = sizeof(WMACodecContext),
+ .init = wma_decode_init,
+ .close = ff_wma_end,
+ .decode = wma_decode_superframe,
+ .flush = flush,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
};
diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c
index 3cdb4a0..c762a72 100644
--- a/libavcodec/wmaenc.c
+++ b/libavcodec/wmaenc.c
@@ -311,7 +311,7 @@ static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE],
put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[1], s->coef_vlcs[tindex]->huffcodes[1]);
}
if (s->version == 1 && s->nb_channels >= 2) {
- align_put_bits(&s->pb);
+ avpriv_align_put_bits(&s->pb);
}
}
return 0;
@@ -327,7 +327,7 @@ static int encode_frame(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE],
return INT_MAX;
}
- align_put_bits(&s->pb);
+ avpriv_align_put_bits(&s->pb);
return put_bits_count(&s->pb)/8 - s->block_align;
}
@@ -390,28 +390,26 @@ static int encode_superframe(AVCodecContext *avctx,
return put_bits_ptr(&s->pb) - s->pb.buf;
}
-AVCodec ff_wmav1_encoder =
-{
- "wmav1",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_WMAV1,
- sizeof(WMACodecContext),
- encode_init,
- encode_superframe,
- ff_wma_end,
- .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
+AVCodec ff_wmav1_encoder = {
+ .name = "wmav1",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_WMAV1,
+ .priv_data_size = sizeof(WMACodecContext),
+ .init = encode_init,
+ .encode = encode_superframe,
+ .close = ff_wma_end,
+ .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
};
-AVCodec ff_wmav2_encoder =
-{
- "wmav2",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_WMAV2,
- sizeof(WMACodecContext),
- encode_init,
- encode_superframe,
- ff_wma_end,
- .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
+AVCodec ff_wmav2_encoder = {
+ .name = "wmav2",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_WMAV2,
+ .priv_data_size = sizeof(WMACodecContext),
+ .init = encode_init,
+ .encode = encode_superframe,
+ .close = ff_wma_end,
+ .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
};
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index 4ba8c45..a1b82db 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -86,12 +86,15 @@
* subframe in order to reconstruct the output samples.
*/
+#include "libavutil/intfloat.h"
+#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "internal.h"
#include "get_bits.h"
#include "put_bits.h"
#include "wmaprodata.h"
#include "dsputil.h"
+#include "fmtconvert.h"
#include "sinewin.h"
#include "wma.h"
@@ -165,7 +168,9 @@ typedef struct {
typedef struct WMAProDecodeCtx {
/* generic decoder variables */
AVCodecContext* avctx; ///< codec context for av_log
+ AVFrame frame; ///< AVFrame for decoded output
DSPContext dsp; ///< accelerated DSP functions
+ FmtConvertContext fmt_conv;
uint8_t frame_data[MAX_FRAMESIZE +
FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data
PutBitContext pb; ///< context for filling the frame_data buffer
@@ -206,8 +211,6 @@ typedef struct WMAProDecodeCtx {
uint32_t frame_num; ///< current frame number (not used for decoding)
GetBitContext gb; ///< bitstream reader context
int buf_bit_size; ///< buffer size in bits
- float* samples; ///< current samplebuffer pointer
- float* samples_end; ///< maximum samplebuffer pointer
uint8_t drc_gain; ///< gain for the DRC tool
int8_t skip_frame; ///< skip output step
int8_t parsed_all_subframes; ///< all subframes decoded?
@@ -279,6 +282,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
s->avctx = avctx;
dsputil_init(&s->dsp, avctx);
+ ff_fmt_convert_init(&s->fmt_conv, avctx);
init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
@@ -309,10 +313,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate,
3, s->decode_flags);
- /** init previous block len */
- for (i = 0; i < avctx->channels; i++)
- s->channel[i].prev_block_len = s->samples_per_frame;
-
/** subframe info */
log2_max_num_subframes = ((s->decode_flags & 0x38) >> 3);
s->max_num_subframes = 1 << log2_max_num_subframes;
@@ -332,6 +332,18 @@ static av_cold int decode_init(AVCodecContext *avctx)
s->num_channels = avctx->channels;
+ if (s->num_channels < 0) {
+ av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", s->num_channels);
+ return AVERROR_INVALIDDATA;
+ } else if (s->num_channels > WMAPRO_MAX_CHANNELS) {
+ av_log_ask_for_sample(avctx, "unsupported number of channels\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ /** init previous block len */
+ for (i = 0; i < s->num_channels; i++)
+ s->channel[i].prev_block_len = s->samples_per_frame;
+
/** extract lfe channel position */
s->lfe_channel = -1;
@@ -343,14 +355,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
}
}
- if (s->num_channels < 0) {
- av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", s->num_channels);
- return AVERROR_INVALIDDATA;
- } else if (s->num_channels > WMAPRO_MAX_CHANNELS) {
- av_log_ask_for_sample(avctx, "unsupported number of channels\n");
- return AVERROR_PATCHWELCOME;
- }
-
INIT_VLC_STATIC(&sf_vlc, SCALEVLCBITS, HUFF_SCALE_SIZE,
scale_huffbits, 1, 1,
scale_huffcodes, 2, 2, 616);
@@ -449,6 +453,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
dump_context(s);
avctx->channel_layout = channel_mask;
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
@@ -767,7 +775,7 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c)
/* Integers 0..15 as single-precision floats. The table saves a
costly int to float conversion, and storing the values as
integers allows fast sign-flipping. */
- static const int fval_tab[16] = {
+ static const uint32_t fval_tab[16] = {
0x00000000, 0x3f800000, 0x40000000, 0x40400000,
0x40800000, 0x40a00000, 0x40c00000, 0x40e00000,
0x41000000, 0x41100000, 0x41200000, 0x41300000,
@@ -799,7 +807,7 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c)
4 vector coded large values) */
while ((s->transmit_num_vec_coeffs || !rl_mode) &&
(cur_coeff + 3 < ci->num_vec_coeffs)) {
- int vals[4];
+ uint32_t vals[4];
int i;
unsigned int idx;
@@ -809,15 +817,15 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c)
for (i = 0; i < 4; i += 2) {
idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH);
if (idx == HUFF_VEC2_SIZE - 1) {
- int v0, v1;
+ uint32_t v0, v1;
v0 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH);
if (v0 == HUFF_VEC1_SIZE - 1)
v0 += ff_wma_get_large_val(&s->gb);
v1 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH);
if (v1 == HUFF_VEC1_SIZE - 1)
v1 += ff_wma_get_large_val(&s->gb);
- ((float*)vals)[i ] = v0;
- ((float*)vals)[i+1] = v1;
+ vals[i ] = av_float2int(v0);
+ vals[i+1] = av_float2int(v1);
} else {
vals[i] = fval_tab[symbol_to_vec2[idx] >> 4 ];
vals[i+1] = fval_tab[symbol_to_vec2[idx] & 0xF];
@@ -833,8 +841,8 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c)
/** decode sign */
for (i = 0; i < 4; i++) {
if (vals[i]) {
- int sign = get_bits1(&s->gb) - 1;
- *(uint32_t*)&ci->coeffs[cur_coeff] = vals[i] ^ sign<<31;
+ uint32_t sign = get_bits1(&s->gb) - 1;
+ AV_WN32A(&ci->coeffs[cur_coeff], vals[i] ^ sign << 31);
num_zeros = 0;
} else {
ci->coeffs[cur_coeff] = 0;
@@ -1275,21 +1283,15 @@ static int decode_subframe(WMAProDecodeCtx *s)
*@return 0 if the trailer bit indicates that this is the last frame,
* 1 if there are additional frames
*/
-static int decode_frame(WMAProDecodeCtx *s)
+static int decode_frame(WMAProDecodeCtx *s, int *got_frame_ptr)
{
+ AVCodecContext *avctx = s->avctx;
GetBitContext* gb = &s->gb;
int more_frames = 0;
int len = 0;
- int i;
-
- /** check for potential output buffer overflow */
- if (s->num_channels * s->samples_per_frame > s->samples_end - s->samples) {
- /** return an error if no frame could be decoded at all */
- av_log(s->avctx, AV_LOG_ERROR,
- "not enough space for the output samples\n");
- s->packet_loss = 1;
- return 0;
- }
+ int i, ret;
+ const float *out_ptr[WMAPRO_MAX_CHANNELS];
+ float *samples;
/** get frame length */
if (s->len_prefix)
@@ -1355,19 +1357,22 @@ static int decode_frame(WMAProDecodeCtx *s)
}
}
+ /* get output buffer */
+ s->frame.nb_samples = s->samples_per_frame;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ s->packet_loss = 1;
+ return 0;
+ }
+ samples = (float *)s->frame.data[0];
+
/** interleave samples and write them to the output buffer */
- for (i = 0; i < s->num_channels; i++) {
- float* ptr = s->samples + i;
- int incr = s->num_channels;
- float* iptr = s->channel[i].out;
- float* iend = iptr + s->samples_per_frame;
-
- // FIXME should create/use a DSP function here
- while (iptr < iend) {
- *ptr = *iptr++;
- ptr += incr;
- }
+ for (i = 0; i < s->num_channels; i++)
+ out_ptr[i] = s->channel[i].out;
+ s->fmt_conv.float_interleave(samples, out_ptr, s->samples_per_frame,
+ s->num_channels);
+ for (i = 0; i < s->num_channels; i++) {
/** reuse second half of the IMDCT output for the next frame */
memcpy(&s->channel[i].out[0],
&s->channel[i].out[s->samples_per_frame],
@@ -1376,8 +1381,10 @@ static int decode_frame(WMAProDecodeCtx *s)
if (s->skip_frame) {
s->skip_frame = 0;
- } else
- s->samples += s->num_channels * s->samples_per_frame;
+ *got_frame_ptr = 0;
+ } else {
+ *got_frame_ptr = 1;
+ }
if (s->len_prefix) {
if (len != (get_bits_count(gb) - s->frame_offset) + 2) {
@@ -1419,7 +1426,7 @@ static int remaining_bits(WMAProDecodeCtx *s, GetBitContext *gb)
*@param s codec context
*@param gb bitstream reader context
*@param len length of the partial frame
- *@param append decides wether to reset the buffer or not
+ *@param append decides whether to reset the buffer or not
*/
static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
int append)
@@ -1446,14 +1453,14 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
s->num_saved_bits += len;
if (!append) {
- ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),
+ avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),
s->num_saved_bits);
} else {
int align = 8 - (get_bits_count(gb) & 7);
align = FFMIN(align, len);
put_bits(&s->pb, align, get_bits(gb, align));
len -= align;
- ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len);
+ avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len);
}
skip_bits_long(gb, len);
@@ -1474,8 +1481,8 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
*@param avpkt input packet
*@return number of bytes that were read from the input buffer
*/
-static int decode_packet(AVCodecContext *avctx,
- void *data, int *data_size, AVPacket* avpkt)
+static int decode_packet(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket* avpkt)
{
WMAProDecodeCtx *s = avctx->priv_data;
GetBitContext* gb = &s->pgb;
@@ -1484,9 +1491,7 @@ static int decode_packet(AVCodecContext *avctx,
int num_bits_prev_frame;
int packet_sequence_number;
- s->samples = data;
- s->samples_end = (float*)((int8_t*)data + *data_size);
- *data_size = 0;
+ *got_frame_ptr = 0;
if (s->packet_done || s->packet_loss) {
s->packet_done = 0;
@@ -1533,7 +1538,7 @@ static int decode_packet(AVCodecContext *avctx,
/** decode the cross packet frame if it is valid */
if (!s->packet_loss)
- decode_frame(s);
+ decode_frame(s, got_frame_ptr);
} else if (s->num_saved_bits - s->frame_offset) {
av_dlog(avctx, "ignoring %x previously saved bits\n",
s->num_saved_bits - s->frame_offset);
@@ -1556,7 +1561,7 @@ static int decode_packet(AVCodecContext *avctx,
(frame_size = show_bits(gb, s->log2_frame_size)) &&
frame_size <= remaining_bits(s, gb)) {
save_bits(s, gb, frame_size, 0);
- s->packet_done = !decode_frame(s);
+ s->packet_done = !decode_frame(s, got_frame_ptr);
} else if (!s->len_prefix
&& s->num_saved_bits > get_bits_count(&s->gb)) {
/** when the frames do not have a length prefix, we don't know
@@ -1566,7 +1571,7 @@ static int decode_packet(AVCodecContext *avctx,
therefore we save the incoming packet first, then we append
the "previous frame" data from the next packet so that
we get a buffer that only contains full frames */
- s->packet_done = !decode_frame(s);
+ s->packet_done = !decode_frame(s, got_frame_ptr);
} else
s->packet_done = 1;
}
@@ -1578,10 +1583,14 @@ static int decode_packet(AVCodecContext *avctx,
save_bits(s, gb, remaining_bits(s, gb), 0);
}
- *data_size = (int8_t *)s->samples - (int8_t *)data;
s->packet_offset = get_bits_count(gb) & 7;
+ if (s->packet_loss)
+ return AVERROR_INVALIDDATA;
+
+ if (*got_frame_ptr)
+ *(AVFrame *)data = s->frame;
- return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3;
+ return get_bits_count(gb) >> 3;
}
/**
@@ -1605,15 +1614,14 @@ static void flush(AVCodecContext *avctx)
*@brief wmapro decoder
*/
AVCodec ff_wmapro_decoder = {
- "wmapro",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_WMAPRO,
- sizeof(WMAProDecodeCtx),
- decode_init,
- NULL,
- decode_end,
- decode_packet,
- .capabilities = CODEC_CAP_SUBFRAMES,
+ .name = "wmapro",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_WMAPRO,
+ .priv_data_size = sizeof(WMAProDecodeCtx),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_packet,
+ .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
.flush= flush,
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"),
};
diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c
index eb3bcb0..8854e35 100644
--- a/libavcodec/wmavoice.c
+++ b/libavcodec/wmavoice.c
@@ -25,6 +25,8 @@
* @author Ronald S. Bultje <rsbultje at gmail.com>
*/
+#define UNCHECKED_BITSTREAM_READER 1
+
#include <math.h>
#include "avcodec.h"
#include "get_bits.h"
@@ -131,6 +133,7 @@ typedef struct {
* @name Global values specified in the stream header / extradata or used all over.
* @{
*/
+ AVFrame frame;
GetBitContext gb; ///< packet bitreader. During decoder init,
///< it contains the extradata from the
///< demuxer. During decoding, it contains
@@ -188,7 +191,7 @@ typedef struct {
* @{
*/
int spillover_nbits; ///< number of bits of the previous packet's
- ///< last superframe preceeding this
+ ///< last superframe preceding this
///< packet's first full superframe (useful
///< for re-synchronization also)
int has_residual_lsps; ///< if set, superframes contain one set of
@@ -401,6 +404,10 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
s->min_pitch_val = ((ctx->sample_rate << 8) / 400 + 50) >> 8;
s->max_pitch_val = ((ctx->sample_rate << 8) * 37 / 2000 + 50) >> 8;
pitch_range = s->max_pitch_val - s->min_pitch_val;
+ if (pitch_range <= 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid pitch range; broken extradata?\n");
+ return -1;
+ }
s->pitch_nbits = av_ceil_log2(pitch_range);
s->last_pitch_val = 40;
s->last_acb_type = ACB_TYPE_NONE;
@@ -422,6 +429,10 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
s->block_conv_table[2] = (pitch_range * 44) >> 6;
s->block_conv_table[3] = s->max_pitch_val - 1;
s->block_delta_pitch_hrange = (pitch_range >> 3) & ~0xF;
+ if (s->block_delta_pitch_hrange <= 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid delta pitch hrange; broken extradata?\n");
+ return -1;
+ }
s->block_delta_pitch_nbits = 1 + av_ceil_log2(s->block_delta_pitch_hrange);
s->block_pitch_range = s->block_conv_table[2] +
s->block_conv_table[3] + 1 +
@@ -430,6 +441,9 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
ctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ avcodec_get_frame_defaults(&s->frame);
+ ctx->coded_frame = &s->frame;
+
return 0;
}
@@ -1077,7 +1091,7 @@ static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb,
int excl_range = s->aw_pulse_range; // always 16 or 24
uint16_t *use_mask_ptr = &use_mask[idx >> 4];
int first_sh = 16 - (idx & 15);
- *use_mask_ptr++ &= 0xFFFF << first_sh;
+ *use_mask_ptr++ &= 0xFFFFu << first_sh;
excl_range -= first_sh;
if (excl_range >= 16) {
*use_mask_ptr++ = 0;
@@ -1717,8 +1731,7 @@ static int check_bits_for_superframe(GetBitContext *orig_gb,
* @return 0 on success, <0 on error or 1 if there was not enough data to
* fully parse the superframe
*/
-static int synth_superframe(AVCodecContext *ctx,
- float *samples, int *data_size)
+static int synth_superframe(AVCodecContext *ctx, int *got_frame_ptr)
{
WMAVoiceContext *s = ctx->priv_data;
GetBitContext *gb = &s->gb, s_gb;
@@ -1728,6 +1741,7 @@ static int synth_superframe(AVCodecContext *ctx,
wmavoice_mean_lsf16[s->lsp_def_mode] : wmavoice_mean_lsf10[s->lsp_def_mode];
float excitation[MAX_SIGNAL_HISTORY + MAX_SFRAMESIZE + 12];
float synth[MAX_LSPS + MAX_SFRAMESIZE];
+ float *samples;
memcpy(synth, s->synth_history,
s->lsps * sizeof(*synth));
@@ -1740,7 +1754,10 @@ static int synth_superframe(AVCodecContext *ctx,
s->sframe_cache_size = 0;
}
- if ((res = check_bits_for_superframe(gb, s)) == 1) return 1;
+ if ((res = check_bits_for_superframe(gb, s)) == 1) {
+ *got_frame_ptr = 0;
+ return 1;
+ }
/* First bit is speech/music bit, it differentiates between WMAVoice
* speech samples (the actual codec) and WMAVoice music samples, which
@@ -1781,7 +1798,16 @@ static int synth_superframe(AVCodecContext *ctx,
stabilize_lsps(lsps[n], s->lsps);
}
- /* Parse frames, optionally preceeded by per-frame (independent) LSPs. */
+ /* get output buffer */
+ s->frame.nb_samples = 480;
+ if ((res = ctx->get_buffer(ctx, &s->frame)) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return res;
+ }
+ s->frame.nb_samples = n_samples;
+ samples = (float *)s->frame.data[0];
+
+ /* Parse frames, optionally preceded by per-frame (independent) LSPs. */
for (n = 0; n < 3; n++) {
if (!s->has_residual_lsps) {
int m;
@@ -1800,8 +1826,10 @@ static int synth_superframe(AVCodecContext *ctx,
&samples[n * MAX_FRAMESIZE],
lsps[n], n == 0 ? s->prev_lsps : lsps[n - 1],
&excitation[s->history_nsamples + n * MAX_FRAMESIZE],
- &synth[s->lsps + n * MAX_FRAMESIZE])))
+ &synth[s->lsps + n * MAX_FRAMESIZE]))) {
+ *got_frame_ptr = 0;
return res;
+ }
}
/* Statistics? FIXME - we don't check for length, a slight overrun
@@ -1812,8 +1840,7 @@ static int synth_superframe(AVCodecContext *ctx,
skip_bits(gb, 10 * (res + 1));
}
- /* Specify nr. of output samples */
- *data_size = n_samples * sizeof(float);
+ *got_frame_ptr = 1;
/* Update history */
memcpy(s->prev_lsps, lsps[2],
@@ -1864,7 +1891,7 @@ static int parse_packet_header(WMAVoiceContext *s)
* @param size size of the source data, in bytes
* @param gb bit I/O context specifying the current position in the source.
* data. This function might use this to align the bit position to
- * a whole-byte boundary before calling #ff_copy_bits() on aligned
+ * a whole-byte boundary before calling #avpriv_copy_bits() on aligned
* source data
* @param nbits the amount of bits to copy from source to target
*
@@ -1880,10 +1907,12 @@ static void copy_bits(PutBitContext *pb,
rmn_bits = rmn_bytes = get_bits_left(gb);
if (rmn_bits < nbits)
return;
+ if (nbits > pb->size_in_bits - put_bits_count(pb))
+ return;
rmn_bits &= 7; rmn_bytes >>= 3;
if ((rmn_bits = FFMIN(rmn_bits, nbits)) > 0)
put_bits(pb, rmn_bits, get_bits(gb, rmn_bits));
- ff_copy_bits(pb, data + size - rmn_bytes,
+ avpriv_copy_bits(pb, data + size - rmn_bytes,
FFMIN(nbits - rmn_bits, rmn_bytes << 3));
}
@@ -1899,28 +1928,22 @@ static void copy_bits(PutBitContext *pb,
* For more information about frames, see #synth_superframe().
*/
static int wmavoice_decode_packet(AVCodecContext *ctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame_ptr, AVPacket *avpkt)
{
WMAVoiceContext *s = ctx->priv_data;
GetBitContext *gb = &s->gb;
int size, res, pos;
- if (*data_size < 480 * sizeof(float)) {
- av_log(ctx, AV_LOG_ERROR,
- "Output buffer too small (%d given - %zu needed)\n",
- *data_size, 480 * sizeof(float));
- return -1;
- }
- *data_size = 0;
-
/* Packets are sometimes a multiple of ctx->block_align, with a packet
* header at each ctx->block_align bytes. However, Libav's ASF demuxer
* feeds us ASF packets, which may concatenate multiple "codec" packets
* in a single "muxer" packet, so we artificially emulate that by
* capping the packet size at ctx->block_align. */
for (size = avpkt->size; size > ctx->block_align; size -= ctx->block_align);
- if (!size)
+ if (!size) {
+ *got_frame_ptr = 0;
return 0;
+ }
init_get_bits(&s->gb, avpkt->data, size << 3);
/* size == ctx->block_align is used to indicate whether we are dealing with
@@ -1939,10 +1962,11 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data,
copy_bits(&s->pb, avpkt->data, size, gb, s->spillover_nbits);
flush_put_bits(&s->pb);
s->sframe_cache_size += s->spillover_nbits;
- if ((res = synth_superframe(ctx, data, data_size)) == 0 &&
- *data_size > 0) {
+ if ((res = synth_superframe(ctx, got_frame_ptr)) == 0 &&
+ *got_frame_ptr) {
cnt += s->spillover_nbits;
s->skip_bits_next = cnt & 7;
+ *(AVFrame *)data = s->frame;
return cnt >> 3;
} else
skip_bits_long (gb, s->spillover_nbits - cnt +
@@ -1957,11 +1981,12 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data,
s->sframe_cache_size = 0;
s->skip_bits_next = 0;
pos = get_bits_left(gb);
- if ((res = synth_superframe(ctx, data, data_size)) < 0) {
+ if ((res = synth_superframe(ctx, got_frame_ptr)) < 0) {
return res;
- } else if (*data_size > 0) {
+ } else if (*got_frame_ptr) {
int cnt = get_bits_count(gb);
s->skip_bits_next = cnt & 7;
+ *(AVFrame *)data = s->frame;
return cnt >> 3;
} else if ((s->sframe_cache_size = pos) > 0) {
/* rewind bit reader to start of last (incomplete) superframe... */
@@ -2022,15 +2047,14 @@ static av_cold void wmavoice_flush(AVCodecContext *ctx)
}
AVCodec ff_wmavoice_decoder = {
- "wmavoice",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_WMAVOICE,
- sizeof(WMAVoiceContext),
- wmavoice_decode_init,
- NULL,
- wmavoice_decode_end,
- wmavoice_decode_packet,
- CODEC_CAP_SUBFRAMES,
+ .name = "wmavoice",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_WMAVOICE,
+ .priv_data_size = sizeof(WMAVoiceContext),
+ .init = wmavoice_decode_init,
+ .close = wmavoice_decode_end,
+ .decode = wmavoice_decode_packet,
+ .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
.flush = wmavoice_flush,
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"),
};
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index ede5236..21fc1cf 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -32,7 +32,7 @@
static void parse_mb_skip(Wmv2Context * w){
int mb_x, mb_y;
MpegEncContext * const s= &w->s;
- uint32_t * const mb_type= s->current_picture_ptr->mb_type;
+ uint32_t * const mb_type = s->current_picture_ptr->f.mb_type;
w->skip_type= get_bits(&s->gb, 2);
switch(w->skip_type){
@@ -257,11 +257,11 @@ static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){
wrap = s->b8_stride;
xy = s->block_index[0];
- mot_val = s->current_picture.motion_val[0][xy];
+ mot_val = s->current_picture.f.motion_val[0][xy];
- A = s->current_picture.motion_val[0][xy - 1];
- B = s->current_picture.motion_val[0][xy - wrap];
- C = s->current_picture.motion_val[0][xy + 2 - wrap];
+ A = s->current_picture.f.motion_val[0][xy - 1];
+ B = s->current_picture.f.motion_val[0][xy - wrap];
+ C = s->current_picture.f.motion_val[0][xy + 2 - wrap];
if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag)
diff= FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1]));
@@ -343,7 +343,7 @@ int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
if(w->j_type) return 0;
if (s->pict_type == AV_PICTURE_TYPE_P) {
- if(IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])){
+ if (IS_SKIP(s->current_picture.f.mb_type[s->mb_y * s->mb_stride + s->mb_x])) {
/* skip mb */
s->mb_intra = 0;
for(i=0;i<6;i++)
@@ -471,15 +471,14 @@ static av_cold int wmv2_decode_end(AVCodecContext *avctx)
}
AVCodec ff_wmv2_decoder = {
- "wmv2",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_WMV2,
- sizeof(Wmv2Context),
- wmv2_decode_init,
- NULL,
- wmv2_decode_end,
- ff_h263_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+ .name = "wmv2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_WMV2,
+ .priv_data_size = sizeof(Wmv2Context),
+ .init = wmv2_decode_init,
+ .close = wmv2_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
.max_lowres = 3,
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"),
.pix_fmts= ff_pixfmt_list_420,
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 9b7890c..9879cb8 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -212,13 +212,13 @@ void ff_wmv2_encode_mb(MpegEncContext * s,
}
AVCodec ff_wmv2_encoder = {
- "wmv2",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_WMV2,
- sizeof(Wmv2Context),
- wmv2_encode_init,
- MPV_encode_picture,
- MPV_encode_end,
+ .name = "wmv2",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_WMV2,
+ .priv_data_size = sizeof(Wmv2Context),
+ .init = wmv2_encode_init,
+ .encode = MPV_encode_picture,
+ .close = MPV_encode_end,
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 8"),
};
diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c
index 65ad9cd..f6e4694 100644
--- a/libavcodec/wnv1.c
+++ b/libavcodec/wnv1.c
@@ -157,14 +157,13 @@ static av_cold int decode_end(AVCodecContext *avctx){
}
AVCodec ff_wnv1_decoder = {
- "wnv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_WNV1,
- sizeof(WNV1Context),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "wnv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_WNV1,
+ .priv_data_size = sizeof(WNV1Context),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Winnov WNV1"),
};
diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c
index 534be56..b2d086e 100644
--- a/libavcodec/ws-snd1.c
+++ b/libavcodec/ws-snd1.c
@@ -25,98 +25,133 @@
/**
* @file
- * Westwood SNDx codecs.
+ * Westwood SNDx codecs
*
* Reference documents about VQA format and its audio codecs
* can be found here:
* http://www.multimedia.cx
*/
-static const int8_t ws_adpcm_2bit[] = { -2, -1, 0, 1};
static const int8_t ws_adpcm_4bit[] = {
-9, -8, -6, -5, -4, -3, -2, -1,
- 0, 1, 2, 3, 4, 5, 6, 8 };
+ 0, 1, 2, 3, 4, 5, 6, 8
+};
-#define CLIP8(a) if(a>127)a=127;if(a<-128)a=-128;
+typedef struct WSSndContext {
+ AVFrame frame;
+} WSSndContext;
-static av_cold int ws_snd_decode_init(AVCodecContext * avctx)
+static av_cold int ws_snd_decode_init(AVCodecContext *avctx)
{
-// WSSNDContext *c = avctx->priv_data;
+ WSSndContext *s = avctx->priv_data;
+
+ if (avctx->channels != 1) {
+ av_log_ask_for_sample(avctx, "unsupported number of channels\n");
+ return AVERROR(EINVAL);
+ }
+
+ avctx->sample_fmt = AV_SAMPLE_FMT_U8;
+
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
return 0;
}
-static int ws_snd_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int ws_snd_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
+ WSSndContext *s = avctx->priv_data;
const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
-// WSSNDContext *c = avctx->priv_data;
+ int buf_size = avpkt->size;
- int in_size, out_size;
- int sample = 0;
- int i;
- short *samples = data;
+ int in_size, out_size, ret;
+ int sample = 128;
+ uint8_t *samples;
+ uint8_t *samples_end;
if (!buf_size)
return 0;
+ if (buf_size < 4) {
+ av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
+ return AVERROR(EINVAL);
+ }
+
out_size = AV_RL16(&buf[0]);
- *data_size = out_size * 2;
- in_size = AV_RL16(&buf[2]);
+ in_size = AV_RL16(&buf[2]);
buf += 4;
- if (out_size > *data_size) {
- av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n");
- return -1;
- }
if (in_size > buf_size) {
av_log(avctx, AV_LOG_ERROR, "Frame data is larger than input buffer\n");
return -1;
}
+
+ /* get output buffer */
+ s->frame.nb_samples = out_size;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples = s->frame.data[0];
+ samples_end = samples + out_size;
+
if (in_size == out_size) {
- for (i = 0; i < out_size; i++)
- *samples++ = (*buf++ - 0x80) << 8;
+ memcpy(samples, buf, out_size);
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
return buf_size;
}
- while (out_size > 0) {
- int code;
+ while (samples < samples_end && buf - avpkt->data < buf_size) {
+ int code, smp, size;
uint8_t count;
- code = (*buf) >> 6;
- count = (*buf) & 0x3F;
+ code = *buf >> 6;
+ count = *buf & 0x3F;
buf++;
- switch(code) {
+
+ /* make sure we don't write past the output buffer */
+ switch (code) {
+ case 0: smp = 4; break;
+ case 1: smp = 2; break;
+ case 2: smp = (count & 0x20) ? 1 : count + 1; break;
+ default: smp = count + 1; break;
+ }
+ if (samples_end - samples < smp)
+ break;
+
+ /* make sure we don't read past the input buffer */
+ size = ((code == 2 && (count & 0x20)) || code == 3) ? 0 : count + 1;
+ if ((buf - avpkt->data) + size > buf_size)
+ break;
+
+ switch (code) {
case 0: /* ADPCM 2-bit */
for (count++; count > 0; count--) {
code = *buf++;
- sample += ws_adpcm_2bit[code & 0x3];
- CLIP8(sample);
- *samples++ = sample << 8;
- sample += ws_adpcm_2bit[(code >> 2) & 0x3];
- CLIP8(sample);
- *samples++ = sample << 8;
- sample += ws_adpcm_2bit[(code >> 4) & 0x3];
- CLIP8(sample);
- *samples++ = sample << 8;
- sample += ws_adpcm_2bit[(code >> 6) & 0x3];
- CLIP8(sample);
- *samples++ = sample << 8;
- out_size -= 4;
+ sample += ( code & 0x3) - 2;
+ sample = av_clip_uint8(sample);
+ *samples++ = sample;
+ sample += ((code >> 2) & 0x3) - 2;
+ sample = av_clip_uint8(sample);
+ *samples++ = sample;
+ sample += ((code >> 4) & 0x3) - 2;
+ sample = av_clip_uint8(sample);
+ *samples++ = sample;
+ sample += (code >> 6) - 2;
+ sample = av_clip_uint8(sample);
+ *samples++ = sample;
}
break;
case 1: /* ADPCM 4-bit */
for (count++; count > 0; count--) {
code = *buf++;
sample += ws_adpcm_4bit[code & 0xF];
- CLIP8(sample);
- *samples++ = sample << 8;
+ sample = av_clip_uint8(sample);
+ *samples++ = sample;
sample += ws_adpcm_4bit[code >> 4];
- CLIP8(sample);
- *samples++ = sample << 8;
- out_size -= 2;
+ sample = av_clip_uint8(sample);
+ *samples++ = sample;
}
break;
case 2: /* no compression */
@@ -125,35 +160,35 @@ static int ws_snd_decode_frame(AVCodecContext *avctx,
t = count;
t <<= 3;
sample += t >> 3;
- *samples++ = sample << 8;
- out_size--;
+ sample = av_clip_uint8(sample);
+ *samples++ = sample;
} else { /* copy */
- for (count++; count > 0; count--) {
- *samples++ = (*buf++ - 0x80) << 8;
- out_size--;
- }
- sample = buf[-1] - 0x80;
+ memcpy(samples, buf, smp);
+ samples += smp;
+ buf += smp;
+ sample = buf[-1];
}
break;
default: /* run */
- for(count++; count > 0; count--) {
- *samples++ = sample << 8;
- out_size--;
- }
+ memset(samples, sample, smp);
+ samples += smp;
}
}
+ s->frame.nb_samples = samples - s->frame.data[0];
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return buf_size;
}
AVCodec ff_ws_snd1_decoder = {
- "ws_snd1",
- AVMEDIA_TYPE_AUDIO,
- CODEC_ID_WESTWOOD_SND1,
- 0,
- ws_snd_decode_init,
- NULL,
- NULL,
- ws_snd_decode_frame,
+ .name = "ws_snd1",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = CODEC_ID_WESTWOOD_SND1,
+ .priv_data_size = sizeof(WSSndContext),
+ .init = ws_snd_decode_init,
+ .decode = ws_snd_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Westwood Audio (SND1)"),
};
diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile
index ea57bd1..aa97942 100644
--- a/libavcodec/x86/Makefile
+++ b/libavcodec/x86/Makefile
@@ -9,27 +9,36 @@ YASM-OBJS-FFT-$(HAVE_SSE) += x86/fft_sse.o
YASM-OBJS-$(CONFIG_FFT) += x86/fft_mmx.o \
$(YASM-OBJS-FFT-yes)
+YASM-OBJS-$(CONFIG_H264CHROMA) += x86/h264_chromamc.o \
+ x86/h264_chromamc_10bit.o
+
MMX-OBJS-$(CONFIG_H264DSP) += x86/h264dsp_mmx.o
YASM-OBJS-$(CONFIG_H264DSP) += x86/h264_deblock.o \
x86/h264_deblock_10bit.o \
x86/h264_idct.o \
x86/h264_idct_10bit.o \
x86/h264_weight.o \
+ x86/h264_weight_10bit.o \
YASM-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred.o \
x86/h264_intrapred_10bit.o
MMX-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred_init.o
+MMX-OBJS-$(CONFIG_RV40_DECODER) += x86/rv40dsp.o \
+
YASM-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp_yasm.o
MMX-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp_mmx.o
YASM-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp.o
MMX-OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp_mmx.o
+MMX-OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhd_mmx.o
MMX-OBJS-$(CONFIG_MPEGAUDIODSP) += x86/mpegaudiodec_mmx.o
MMX-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc_mmx.o
YASM-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc_yasm.o
MMX-OBJS-$(CONFIG_GPL) += x86/idct_mmx.o
MMX-OBJS-$(CONFIG_LPC) += x86/lpc_mmx.o
+YASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o
+MMX-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp-init.o
MMX-OBJS-$(CONFIG_DWT) += x86/snowdsp_mmx.o
MMX-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp_mmx.o
YASM-OBJS-$(CONFIG_VP3_DECODER) += x86/vp3dsp.o
@@ -43,14 +52,12 @@ MMX-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp-init.o
MMX-OBJS-$(HAVE_YASM) += x86/dsputil_yasm.o \
x86/deinterlace.o \
x86/fmtconvert.o \
- x86/h264_chromamc.o \
- x86/h264_chromamc_10bit.o \
+ x86/h264_qpel_10bit.o \
$(YASM-OBJS-yes)
MMX-OBJS-$(CONFIG_FFT) += x86/fft.o
-OBJS-$(HAVE_MMX) += x86/dnxhd_mmx.o \
- x86/dsputil_mmx.o \
+OBJS-$(HAVE_MMX) += x86/dsputil_mmx.o \
x86/fdct_mmx.o \
x86/fmtconvert_mmx.o \
x86/idct_mmx_xvid.o \
diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm
index 6892ec2..c1b0906 100644
--- a/libavcodec/x86/ac3dsp.asm
+++ b/libavcodec/x86/ac3dsp.asm
@@ -32,6 +32,11 @@ cextern ac3_bap_bits
pw_bap_mul1: dw 21846, 21846, 0, 32768, 21846, 21846, 0, 32768
pw_bap_mul2: dw 5, 7, 0, 7, 5, 7, 0, 7
+; used in ff_ac3_extract_exponents()
+pd_1: times 4 dd 1
+pd_151: times 4 dd 151
+pb_shuf_4dwb: db 0, 4, 8, 12
+
SECTION .text
;-----------------------------------------------------------------------------
@@ -346,3 +351,100 @@ cglobal ac3_compute_mantissa_size_sse2, 1,2,4, mant_cnt, sum
movd eax, m0
add eax, sumd
RET
+
+;------------------------------------------------------------------------------
+; void ff_ac3_extract_exponents(uint8_t *exp, int32_t *coef, int nb_coefs)
+;------------------------------------------------------------------------------
+
+%macro PABSD_MMX 2 ; src/dst, tmp
+ pxor %2, %2
+ pcmpgtd %2, %1
+ pxor %1, %2
+ psubd %1, %2
+%endmacro
+
+%macro PABSD_SSSE3 1-2 ; src/dst, unused
+ pabsd %1, %1
+%endmacro
+
+%ifdef HAVE_AMD3DNOW
+INIT_MMX
+cglobal ac3_extract_exponents_3dnow, 3,3,0, exp, coef, len
+ add expq, lenq
+ lea coefq, [coefq+4*lenq]
+ neg lenq
+ movq m3, [pd_1]
+ movq m4, [pd_151]
+.loop:
+ movq m0, [coefq+4*lenq ]
+ movq m1, [coefq+4*lenq+8]
+ PABSD_MMX m0, m2
+ PABSD_MMX m1, m2
+ pslld m0, 1
+ por m0, m3
+ pi2fd m2, m0
+ psrld m2, 23
+ movq m0, m4
+ psubd m0, m2
+ pslld m1, 1
+ por m1, m3
+ pi2fd m2, m1
+ psrld m2, 23
+ movq m1, m4
+ psubd m1, m2
+ packssdw m0, m0
+ packuswb m0, m0
+ packssdw m1, m1
+ packuswb m1, m1
+ punpcklwd m0, m1
+ movd [expq+lenq], m0
+ add lenq, 4
+ jl .loop
+ REP_RET
+%endif
+
+%macro AC3_EXTRACT_EXPONENTS 1
+cglobal ac3_extract_exponents_%1, 3,3,5, exp, coef, len
+ add expq, lenq
+ lea coefq, [coefq+4*lenq]
+ neg lenq
+ mova m2, [pd_1]
+ mova m3, [pd_151]
+%ifidn %1, ssse3 ;
+ movd m4, [pb_shuf_4dwb]
+%endif
+.loop:
+ ; move 4 32-bit coefs to xmm0
+ mova m0, [coefq+4*lenq]
+ ; absolute value
+ PABSD m0, m1
+ ; convert to float and extract exponents
+ pslld m0, 1
+ por m0, m2
+ cvtdq2ps m1, m0
+ psrld m1, 23
+ mova m0, m3
+ psubd m0, m1
+ ; move the lowest byte in each of 4 dwords to the low dword
+%ifidn %1, ssse3
+ pshufb m0, m4
+%else
+ packssdw m0, m0
+ packuswb m0, m0
+%endif
+ movd [expq+lenq], m0
+
+ add lenq, 4
+ jl .loop
+ REP_RET
+%endmacro
+
+%ifdef HAVE_SSE
+INIT_XMM
+%define PABSD PABSD_MMX
+AC3_EXTRACT_EXPONENTS sse2
+%ifdef HAVE_SSSE3
+%define PABSD PABSD_SSSE3
+AC3_EXTRACT_EXPONENTS ssse3
+%endif
+%endif
diff --git a/libavcodec/x86/ac3dsp_mmx.c b/libavcodec/x86/ac3dsp_mmx.c
index 2664736..d6bb469 100644
--- a/libavcodec/x86/ac3dsp_mmx.c
+++ b/libavcodec/x86/ac3dsp_mmx.c
@@ -44,11 +44,15 @@ extern void ff_float_to_fixed24_sse2 (int32_t *dst, const float *src, unsigned i
extern int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]);
+extern void ff_ac3_extract_exponents_3dnow(uint8_t *exp, int32_t *coef, int nb_coefs);
+extern void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs);
+extern void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs);
+
av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
{
+#if HAVE_YASM
int mm_flags = av_get_cpu_flags();
-#if HAVE_YASM
if (mm_flags & AV_CPU_FLAG_MMX) {
c->ac3_exponent_min = ff_ac3_exponent_min_mmx;
c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmx;
@@ -56,6 +60,7 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
c->ac3_rshift_int32 = ff_ac3_rshift_int32_mmx;
}
if (mm_flags & AV_CPU_FLAG_3DNOW && HAVE_AMD3DNOW) {
+ c->extract_exponents = ff_ac3_extract_exponents_3dnow;
if (!bit_exact) {
c->float_to_fixed24 = ff_float_to_fixed24_3dnow;
}
@@ -72,6 +77,7 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_sse2;
c->float_to_fixed24 = ff_float_to_fixed24_sse2;
c->compute_mantissa_size = ff_ac3_compute_mantissa_size_sse2;
+ c->extract_exponents = ff_ac3_extract_exponents_sse2;
if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
c->ac3_lshift_int16 = ff_ac3_lshift_int16_sse2;
c->ac3_rshift_int32 = ff_ac3_rshift_int32_sse2;
@@ -79,6 +85,9 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
}
if (mm_flags & AV_CPU_FLAG_SSSE3 && HAVE_SSSE3) {
c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_ssse3;
+ if (!(mm_flags & AV_CPU_FLAG_ATOM)) {
+ c->extract_exponents = ff_ac3_extract_exponents_ssse3;
+ }
}
#endif
}
diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h
new file mode 100644
index 0000000..3c3652d
--- /dev/null
+++ b/libavcodec/x86/cabac.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_X86_CABAC_H
+#define AVCODEC_X86_CABAC_H
+
+#include "libavcodec/cabac.h"
+#include "libavutil/attributes.h"
+#include "libavutil/x86_cpu.h"
+#include "config.h"
+
+#if HAVE_FAST_CMOV
+#define BRANCHLESS_GET_CABAC_UPDATE(ret, statep, low, lowword, range, tmp)\
+ "mov "tmp" , %%ecx \n\t"\
+ "shl $17 , "tmp" \n\t"\
+ "cmp "low" , "tmp" \n\t"\
+ "cmova %%ecx , "range" \n\t"\
+ "sbb %%ecx , %%ecx \n\t"\
+ "and %%ecx , "tmp" \n\t"\
+ "xor %%ecx , "ret" \n\t"\
+ "sub "tmp" , "low" \n\t"
+#else /* HAVE_FAST_CMOV */
+#define BRANCHLESS_GET_CABAC_UPDATE(ret, statep, low, lowword, range, tmp)\
+ "mov "tmp" , %%ecx \n\t"\
+ "shl $17 , "tmp" \n\t"\
+ "sub "low" , "tmp" \n\t"\
+ "sar $31 , "tmp" \n\t" /*lps_mask*/\
+ "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\
+ "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\
+ "add %%ecx , "range" \n\t" /*new range*/\
+ "shl $17 , %%ecx \n\t"\
+ "and "tmp" , %%ecx \n\t"\
+ "sub %%ecx , "low" \n\t"\
+ "xor "tmp" , "ret" \n\t"
+#endif /* HAVE_FAST_CMOV */
+
+#define BRANCHLESS_GET_CABAC(ret, statep, low, lowword, range, tmp, tmpbyte, byte) \
+ "movzbl "statep" , "ret" \n\t"\
+ "mov "range" , "tmp" \n\t"\
+ "and $0xC0 , "range" \n\t"\
+ "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\
+ "sub "range" , "tmp" \n\t"\
+ BRANCHLESS_GET_CABAC_UPDATE(ret, statep, low, lowword, range, tmp) \
+ "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\
+ "shl %%cl , "range" \n\t"\
+ "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\
+ "shl %%cl , "low" \n\t"\
+ "mov "tmpbyte" , "statep" \n\t"\
+ "test "lowword" , "lowword" \n\t"\
+ " jnz 1f \n\t"\
+ "mov "byte" , %%"REG_c" \n\t"\
+ "add"OPSIZE" $2 , "byte" \n\t"\
+ "movzwl (%%"REG_c") , "tmp" \n\t"\
+ "lea -1("low") , %%ecx \n\t"\
+ "xor "low" , %%ecx \n\t"\
+ "shr $15 , %%ecx \n\t"\
+ "bswap "tmp" \n\t"\
+ "shr $15 , "tmp" \n\t"\
+ "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\
+ "sub $0xFFFF , "tmp" \n\t"\
+ "neg %%ecx \n\t"\
+ "add $7 , %%ecx \n\t"\
+ "shl %%cl , "tmp" \n\t"\
+ "add "tmp" , "low" \n\t"\
+ "1: \n\t"
+
+#if HAVE_7REGS && !defined(BROKEN_RELOCATIONS)
+#define get_cabac_inline get_cabac_inline_x86
+static av_always_inline int get_cabac_inline_x86(CABACContext *c,
+ uint8_t *const state)
+{
+ int bit, tmp;
+
+ __asm__ volatile(
+ BRANCHLESS_GET_CABAC("%0", "(%5)", "%1", "%w1", "%2",
+ "%3", "%b3", "%4")
+ :"=&r"(bit), "+&r"(c->low), "+&r"(c->range), "=&q"(tmp),
+ "+m"(c->bytestream)
+ :"r"(state)
+ : "%"REG_c, "memory"
+ );
+ return bit & 1;
+}
+#endif /* HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */
+
+#define get_cabac_bypass_sign get_cabac_bypass_sign_x86
+static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val)
+{
+ x86_reg tmp;
+ __asm__ volatile(
+ "movl %4, %k1 \n\t"
+ "movl %2, %%eax \n\t"
+ "shl $17, %k1 \n\t"
+ "add %%eax, %%eax \n\t"
+ "sub %k1, %%eax \n\t"
+ "cltd \n\t"
+ "and %%edx, %k1 \n\t"
+ "add %k1, %%eax \n\t"
+ "xor %%edx, %%ecx \n\t"
+ "sub %%edx, %%ecx \n\t"
+ "test %%ax, %%ax \n\t"
+ " jnz 1f \n\t"
+ "mov %3, %1 \n\t"
+ "subl $0xFFFF, %%eax \n\t"
+ "movzwl (%1), %%edx \n\t"
+ "bswap %%edx \n\t"
+ "shrl $15, %%edx \n\t"
+ "add $2, %1 \n\t"
+ "addl %%edx, %%eax \n\t"
+ "mov %1, %3 \n\t"
+ "1: \n\t"
+ "movl %%eax, %2 \n\t"
+
+ :"+c"(val), "=&r"(tmp), "+m"(c->low), "+m"(c->bytestream)
+ :"m"(c->range)
+ : "%eax", "%edx"
+ );
+ return val;
+}
+
+#endif /* AVCODEC_X86_CABAC_H */
diff --git a/libavcodec/x86/dct32_sse.asm b/libavcodec/x86/dct32_sse.asm
index 46daa43..720a061 100644
--- a/libavcodec/x86/dct32_sse.asm
+++ b/libavcodec/x86/dct32_sse.asm
@@ -63,6 +63,13 @@ ps_p1p1m1m1: dd 0, 0, 0x80000000, 0x80000000, 0, 0, 0x80000000, 0x80000000
mulps %1, %3
%endmacro
+%macro BUTTERFLY0_SSE2 5
+ pshufd %4, %1, %5
+ xorps %1, %2
+ addps %1, %4
+ mulps %1, %3
+%endmacro
+
%macro BUTTERFLY0_AVX 5
vshufps %4, %1, %1, %5
vxorps %1, %1, %2
@@ -405,18 +412,17 @@ INIT_XMM
INIT_XMM
+%macro DCT32_FUNC 1
; void ff_dct32_float_sse(FFTSample *out, const FFTSample *in)
-cglobal dct32_float_sse, 2,3,16, out, in, tmp
+cglobal dct32_float_%1, 2,3,16, out, in, tmp
; pass 1
movaps m0, [inq+0]
- movaps m1, [inq+112]
- shufps m1, m1, 0x1b
+ LOAD_INV m1, [inq+112]
BUTTERFLY m0, m1, [ps_cos_vec], m3
movaps m7, [inq+64]
- movaps m4, [inq+48]
- shufps m4, m4, 0x1b
+ LOAD_INV m4, [inq+48]
BUTTERFLY m7, m4, [ps_cos_vec+32], m3
; pass 2
@@ -427,13 +433,11 @@ cglobal dct32_float_sse, 2,3,16, out, in, tmp
; pass 1
movaps m1, [inq+16]
- movaps m6, [inq+96]
- shufps m6, m6, 0x1b
+ LOAD_INV m6, [inq+96]
BUTTERFLY m1, m6, [ps_cos_vec+16], m3
movaps m4, [inq+80]
- movaps m5, [inq+32]
- shufps m5, m5, 0x1b
+ LOAD_INV m5, [inq+32]
BUTTERFLY m4, m5, [ps_cos_vec+48], m3
; pass 2
@@ -492,3 +496,20 @@ cglobal dct32_float_sse, 2,3,16, out, in, tmp
PASS5
PASS6
RET
+%endmacro
+
+%macro LOAD_INV_SSE 2
+ movaps %1, %2
+ shufps %1, %1, 0x1b
+%endmacro
+
+%define LOAD_INV LOAD_INV_SSE
+DCT32_FUNC sse
+
+%macro LOAD_INV_SSE2 2
+ pshufd %1, %2, 0x1b
+%endmacro
+
+%define LOAD_INV LOAD_INV_SSE2
+%define BUTTERFLY0 BUTTERFLY0_SSE2
+DCT32_FUNC sse2
diff --git a/libavcodec/x86/dnxhd_mmx.c b/libavcodec/x86/dnxhd_mmx.c
index f00ce9b..e193d62 100644
--- a/libavcodec/x86/dnxhd_mmx.c
+++ b/libavcodec/x86/dnxhd_mmx.c
@@ -53,6 +53,7 @@ static void get_pixels_8x4_sym_sse2(DCTELEM *block, const uint8_t *pixels, int l
void ff_dnxhd_init_mmx(DNXHDEncContext *ctx)
{
if (av_get_cpu_flags() & AV_CPU_FLAG_SSE2) {
- ctx->get_pixels_8x4_sym = get_pixels_8x4_sym_sse2;
+ if (ctx->cid_table->bit_depth == 8)
+ ctx->get_pixels_8x4_sym = get_pixels_8x4_sym_sse2;
}
}
diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c
index 5c5ecb2..e34b95b 100644
--- a/libavcodec/x86/dsputil_mmx.c
+++ b/libavcodec/x86/dsputil_mmx.c
@@ -42,7 +42,7 @@ DECLARE_ALIGNED(8, const uint64_t, ff_wtwo) = 0x0002000200020002ULL;
DECLARE_ALIGNED(16, const uint64_t, ff_pdw_80000000)[2] =
{0x8000000080000000ULL, 0x8000000080000000ULL};
-DECLARE_ALIGNED(8, const uint64_t, ff_pw_1 ) = 0x0001000100010001ULL;
+DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1 ) = {0x0001000100010001ULL, 0x0001000100010001ULL};
DECLARE_ALIGNED(16, const xmm_reg, ff_pw_2 ) = {0x0002000200020002ULL, 0x0002000200020002ULL};
DECLARE_ALIGNED(16, const xmm_reg, ff_pw_3 ) = {0x0003000300030003ULL, 0x0003000300030003ULL};
DECLARE_ALIGNED(16, const xmm_reg, ff_pw_4 ) = {0x0004000400040004ULL, 0x0004000400040004ULL};
@@ -64,6 +64,8 @@ DECLARE_ALIGNED(16, const xmm_reg, ff_pw_64 ) = {0x0040004000400040ULL, 0x00400
DECLARE_ALIGNED(8, const uint64_t, ff_pw_96 ) = 0x0060006000600060ULL;
DECLARE_ALIGNED(8, const uint64_t, ff_pw_128) = 0x0080008000800080ULL;
DECLARE_ALIGNED(8, const uint64_t, ff_pw_255) = 0x00ff00ff00ff00ffULL;
+DECLARE_ALIGNED(16, const xmm_reg, ff_pw_512) = {0x0200020002000200ULL, 0x0200020002000200ULL};
+DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1019)= {0x03FB03FB03FB03FBULL, 0x03FB03FB03FB03FBULL};
DECLARE_ALIGNED(16, const xmm_reg, ff_pb_0 ) = {0x0000000000000000ULL, 0x0000000000000000ULL};
DECLARE_ALIGNED(16, const xmm_reg, ff_pb_1 ) = {0x0101010101010101ULL, 0x0101010101010101ULL};
@@ -456,12 +458,12 @@ static void put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_si
"movdqu (%1,%3), %%xmm1 \n\t"
"movdqu (%1,%3,2), %%xmm2 \n\t"
"movdqu (%1,%4), %%xmm3 \n\t"
+ "lea (%1,%3,4), %1 \n\t"
"movdqa %%xmm0, (%2) \n\t"
"movdqa %%xmm1, (%2,%3) \n\t"
"movdqa %%xmm2, (%2,%3,2) \n\t"
"movdqa %%xmm3, (%2,%4) \n\t"
"subl $4, %0 \n\t"
- "lea (%1,%3,4), %1 \n\t"
"lea (%2,%3,4), %2 \n\t"
"jnz 1b \n\t"
: "+g"(h), "+r" (pixels), "+r" (block)
@@ -478,6 +480,7 @@ static void avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_si
"movdqu (%1,%3), %%xmm1 \n\t"
"movdqu (%1,%3,2), %%xmm2 \n\t"
"movdqu (%1,%4), %%xmm3 \n\t"
+ "lea (%1,%3,4), %1 \n\t"
"pavgb (%2), %%xmm0 \n\t"
"pavgb (%2,%3), %%xmm1 \n\t"
"pavgb (%2,%3,2), %%xmm2 \n\t"
@@ -487,7 +490,6 @@ static void avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_si
"movdqa %%xmm2, (%2,%3,2) \n\t"
"movdqa %%xmm3, (%2,%4) \n\t"
"subl $4, %0 \n\t"
- "lea (%1,%3,4), %1 \n\t"
"lea (%2,%3,4), %2 \n\t"
"jnz 1b \n\t"
: "+g"(h), "+r" (pixels), "+r" (block)
@@ -602,7 +604,7 @@ static void add_bytes_l2_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){
dst[i] = src1[i] + src2[i];
}
-#if HAVE_7REGS && HAVE_TEN_OPERANDS
+#if HAVE_7REGS
static void add_hfyu_median_prediction_cmov(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top) {
x86_reg w2 = -w;
x86_reg x;
@@ -1665,10 +1667,6 @@ QPEL_2TAP(put_, 8, 3dnow)
QPEL_2TAP(avg_, 8, 3dnow)
-#if 0
-static void just_return(void) { return; }
-#endif
-
#if HAVE_YASM
typedef void emu_edge_core_func (uint8_t *buf, const uint8_t *src,
x86_reg linesize, x86_reg start_y,
@@ -1879,7 +1877,7 @@ static void gmc_mmx(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int o
int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height)
{
gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
- width, height, &ff_emulated_edge_mc);
+ width, height, &ff_emulated_edge_mc_8);
}
#endif
@@ -1899,29 +1897,17 @@ PREFETCH(prefetch_3dnow, prefetch)
void ff_put_h264_chroma_mc8_mmx_rnd (uint8_t *dst, uint8_t *src,
int stride, int h, int x, int y);
-void ff_put_rv40_chroma_mc8_mmx (uint8_t *dst, uint8_t *src,
- int stride, int h, int x, int y);
void ff_avg_h264_chroma_mc8_mmx2_rnd (uint8_t *dst, uint8_t *src,
int stride, int h, int x, int y);
-void ff_avg_rv40_chroma_mc8_mmx2 (uint8_t *dst, uint8_t *src,
- int stride, int h, int x, int y);
void ff_avg_h264_chroma_mc8_3dnow_rnd (uint8_t *dst, uint8_t *src,
int stride, int h, int x, int y);
-void ff_avg_rv40_chroma_mc8_3dnow (uint8_t *dst, uint8_t *src,
- int stride, int h, int x, int y);
void ff_put_h264_chroma_mc4_mmx (uint8_t *dst, uint8_t *src,
int stride, int h, int x, int y);
-void ff_put_rv40_chroma_mc4_mmx (uint8_t *dst, uint8_t *src,
- int stride, int h, int x, int y);
void ff_avg_h264_chroma_mc4_mmx2 (uint8_t *dst, uint8_t *src,
int stride, int h, int x, int y);
-void ff_avg_rv40_chroma_mc4_mmx2 (uint8_t *dst, uint8_t *src,
- int stride, int h, int x, int y);
void ff_avg_h264_chroma_mc4_3dnow (uint8_t *dst, uint8_t *src,
int stride, int h, int x, int y);
-void ff_avg_rv40_chroma_mc4_3dnow (uint8_t *dst, uint8_t *src,
- int stride, int h, int x, int y);
void ff_put_h264_chroma_mc2_mmx2 (uint8_t *dst, uint8_t *src,
int stride, int h, int x, int y);
@@ -2429,10 +2415,24 @@ int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src, int w, i
float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);
+void ff_vector_clip_int32_mmx (int32_t *dst, const int32_t *src, int32_t min,
+ int32_t max, unsigned int len);
+void ff_vector_clip_int32_sse2 (int32_t *dst, const int32_t *src, int32_t min,
+ int32_t max, unsigned int len);
+void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src, int32_t min,
+ int32_t max, unsigned int len);
+void ff_vector_clip_int32_sse4 (int32_t *dst, const int32_t *src, int32_t min,
+ int32_t max, unsigned int len);
+
+extern void ff_butterflies_float_interleave_sse(float *dst, const float *src0,
+ const float *src1, int len);
+extern void ff_butterflies_float_interleave_avx(float *dst, const float *src0,
+ const float *src1, int len);
+
void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
{
int mm_flags = av_get_cpu_flags();
- const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8;
+ const int high_bit_depth = avctx->bits_per_raw_sample > 8;
const int bit_depth = avctx->bits_per_raw_sample;
if (avctx->dsp_mask) {
@@ -2460,7 +2460,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
if (mm_flags & AV_CPU_FLAG_MMX) {
const int idct_algo= avctx->idct_algo;
- if(avctx->lowres==0){
+ if (avctx->lowres == 0 && avctx->bits_per_raw_sample <= 8) {
if(idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_SIMPLEMMX){
c->idct_put= ff_simple_idct_put_mmx;
c->idct_add= ff_simple_idct_add_mmx;
@@ -2563,13 +2563,12 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
}
#if HAVE_YASM
- if (!high_bit_depth) {
+ if (!high_bit_depth && CONFIG_H264CHROMA) {
c->put_h264_chroma_pixels_tab[0]= ff_put_h264_chroma_mc8_mmx_rnd;
c->put_h264_chroma_pixels_tab[1]= ff_put_h264_chroma_mc4_mmx;
}
- c->put_rv40_chroma_pixels_tab[0]= ff_put_rv40_chroma_mc8_mmx;
- c->put_rv40_chroma_pixels_tab[1]= ff_put_rv40_chroma_mc4_mmx;
+ c->vector_clip_int32 = ff_vector_clip_int32_mmx;
#endif
if (mm_flags & AV_CPU_FLAG_MMX2) {
@@ -2616,56 +2615,65 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_exact_mmx2;
}
-#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU) \
- c->PFX ## _pixels_tab[IDX][ 0] = PFX ## SIZE ## _mc00_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][ 1] = PFX ## SIZE ## _mc10_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][ 2] = PFX ## SIZE ## _mc20_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][ 3] = PFX ## SIZE ## _mc30_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][ 4] = PFX ## SIZE ## _mc01_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][ 5] = PFX ## SIZE ## _mc11_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][ 6] = PFX ## SIZE ## _mc21_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][ 7] = PFX ## SIZE ## _mc31_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][ 8] = PFX ## SIZE ## _mc02_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][ 9] = PFX ## SIZE ## _mc12_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][10] = PFX ## SIZE ## _mc22_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][11] = PFX ## SIZE ## _mc32_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][12] = PFX ## SIZE ## _mc03_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][13] = PFX ## SIZE ## _mc13_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][14] = PFX ## SIZE ## _mc23_ ## CPU; \
- c->PFX ## _pixels_tab[IDX][15] = PFX ## SIZE ## _mc33_ ## CPU
-
- SET_QPEL_FUNCS(put_qpel, 0, 16, mmx2);
- SET_QPEL_FUNCS(put_qpel, 1, 8, mmx2);
- SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmx2);
- SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, mmx2);
- SET_QPEL_FUNCS(avg_qpel, 0, 16, mmx2);
- SET_QPEL_FUNCS(avg_qpel, 1, 8, mmx2);
+#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX) \
+ c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \
+ c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU
+
+ SET_QPEL_FUNCS(put_qpel, 0, 16, mmx2, );
+ SET_QPEL_FUNCS(put_qpel, 1, 8, mmx2, );
+ SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmx2, );
+ SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, mmx2, );
+ SET_QPEL_FUNCS(avg_qpel, 0, 16, mmx2, );
+ SET_QPEL_FUNCS(avg_qpel, 1, 8, mmx2, );
if (!high_bit_depth) {
- SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmx2);
- SET_QPEL_FUNCS(put_h264_qpel, 1, 8, mmx2);
- SET_QPEL_FUNCS(put_h264_qpel, 2, 4, mmx2);
- SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, mmx2);
- SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, mmx2);
- SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, mmx2);
+ SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmx2, );
+ SET_QPEL_FUNCS(put_h264_qpel, 1, 8, mmx2, );
+ SET_QPEL_FUNCS(put_h264_qpel, 2, 4, mmx2, );
+ SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, mmx2, );
+ SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, mmx2, );
+ SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, mmx2, );
+ }
+ else if (bit_depth == 10) {
+#if HAVE_YASM
+#if !ARCH_X86_64
+ SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_mmxext, ff_);
+ SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_mmxext, ff_);
+ SET_QPEL_FUNCS(put_h264_qpel, 1, 8, 10_mmxext, ff_);
+ SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, 10_mmxext, ff_);
+#endif
+ SET_QPEL_FUNCS(put_h264_qpel, 2, 4, 10_mmxext, ff_);
+ SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, 10_mmxext, ff_);
+#endif
}
- SET_QPEL_FUNCS(put_2tap_qpel, 0, 16, mmx2);
- SET_QPEL_FUNCS(put_2tap_qpel, 1, 8, mmx2);
- SET_QPEL_FUNCS(avg_2tap_qpel, 0, 16, mmx2);
- SET_QPEL_FUNCS(avg_2tap_qpel, 1, 8, mmx2);
+ SET_QPEL_FUNCS(put_2tap_qpel, 0, 16, mmx2, );
+ SET_QPEL_FUNCS(put_2tap_qpel, 1, 8, mmx2, );
+ SET_QPEL_FUNCS(avg_2tap_qpel, 0, 16, mmx2, );
+ SET_QPEL_FUNCS(avg_2tap_qpel, 1, 8, mmx2, );
#if HAVE_YASM
- c->avg_rv40_chroma_pixels_tab[0]= ff_avg_rv40_chroma_mc8_mmx2;
- c->avg_rv40_chroma_pixels_tab[1]= ff_avg_rv40_chroma_mc4_mmx2;
-
- if (!high_bit_depth) {
+ if (!high_bit_depth && CONFIG_H264CHROMA) {
c->avg_h264_chroma_pixels_tab[0]= ff_avg_h264_chroma_mc8_mmx2_rnd;
c->avg_h264_chroma_pixels_tab[1]= ff_avg_h264_chroma_mc4_mmx2;
c->avg_h264_chroma_pixels_tab[2]= ff_avg_h264_chroma_mc2_mmx2;
c->put_h264_chroma_pixels_tab[2]= ff_put_h264_chroma_mc2_mmx2;
}
- if (bit_depth == 10) {
+ if (bit_depth == 10 && CONFIG_H264CHROMA) {
c->put_h264_chroma_pixels_tab[2]= ff_put_h264_chroma_mc2_10_mmxext;
c->avg_h264_chroma_pixels_tab[2]= ff_avg_h264_chroma_mc2_10_mmxext;
c->put_h264_chroma_pixels_tab[1]= ff_put_h264_chroma_mc4_10_mmxext;
@@ -2674,13 +2682,13 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmx2;
#endif
-#if HAVE_7REGS && HAVE_TEN_OPERANDS
- if( mm_flags&AV_CPU_FLAG_3DNOW )
+#if HAVE_7REGS
+ if (HAVE_AMD3DNOW && (mm_flags & AV_CPU_FLAG_3DNOW))
c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov;
#endif
c->add_png_paeth_prediction= add_png_paeth_prediction_mmx2;
- } else if (mm_flags & AV_CPU_FLAG_3DNOW) {
+ } else if (HAVE_AMD3DNOW && (mm_flags & AV_CPU_FLAG_3DNOW)) {
c->prefetch = prefetch_3dnow;
if (!high_bit_depth) {
@@ -2714,35 +2722,33 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_exact_3dnow;
}
- SET_QPEL_FUNCS(put_qpel, 0, 16, 3dnow);
- SET_QPEL_FUNCS(put_qpel, 1, 8, 3dnow);
- SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, 3dnow);
- SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, 3dnow);
- SET_QPEL_FUNCS(avg_qpel, 0, 16, 3dnow);
- SET_QPEL_FUNCS(avg_qpel, 1, 8, 3dnow);
+ SET_QPEL_FUNCS(put_qpel, 0, 16, 3dnow, );
+ SET_QPEL_FUNCS(put_qpel, 1, 8, 3dnow, );
+ SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, 3dnow, );
+ SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, 3dnow, );
+ SET_QPEL_FUNCS(avg_qpel, 0, 16, 3dnow, );
+ SET_QPEL_FUNCS(avg_qpel, 1, 8, 3dnow, );
if (!high_bit_depth) {
- SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 3dnow);
- SET_QPEL_FUNCS(put_h264_qpel, 1, 8, 3dnow);
- SET_QPEL_FUNCS(put_h264_qpel, 2, 4, 3dnow);
- SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 3dnow);
- SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, 3dnow);
- SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, 3dnow);
+ SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 3dnow, );
+ SET_QPEL_FUNCS(put_h264_qpel, 1, 8, 3dnow, );
+ SET_QPEL_FUNCS(put_h264_qpel, 2, 4, 3dnow, );
+ SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 3dnow, );
+ SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, 3dnow, );
+ SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, 3dnow, );
}
- SET_QPEL_FUNCS(put_2tap_qpel, 0, 16, 3dnow);
- SET_QPEL_FUNCS(put_2tap_qpel, 1, 8, 3dnow);
- SET_QPEL_FUNCS(avg_2tap_qpel, 0, 16, 3dnow);
- SET_QPEL_FUNCS(avg_2tap_qpel, 1, 8, 3dnow);
+ SET_QPEL_FUNCS(put_2tap_qpel, 0, 16, 3dnow, );
+ SET_QPEL_FUNCS(put_2tap_qpel, 1, 8, 3dnow, );
+ SET_QPEL_FUNCS(avg_2tap_qpel, 0, 16, 3dnow, );
+ SET_QPEL_FUNCS(avg_2tap_qpel, 1, 8, 3dnow, );
#if HAVE_YASM
- if (!high_bit_depth) {
+ if (!high_bit_depth && CONFIG_H264CHROMA) {
c->avg_h264_chroma_pixels_tab[0]= ff_avg_h264_chroma_mc8_3dnow_rnd;
c->avg_h264_chroma_pixels_tab[1]= ff_avg_h264_chroma_mc4_3dnow;
}
- c->avg_rv40_chroma_pixels_tab[0]= ff_avg_rv40_chroma_mc8_3dnow;
- c->avg_rv40_chroma_pixels_tab[1]= ff_avg_rv40_chroma_mc4_3dnow;
#endif
}
@@ -2763,23 +2769,38 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
}
if(mm_flags & AV_CPU_FLAG_SSE2){
if (!high_bit_depth) {
- H264_QPEL_FUNCS(0, 1, sse2);
- H264_QPEL_FUNCS(0, 2, sse2);
- H264_QPEL_FUNCS(0, 3, sse2);
- H264_QPEL_FUNCS(1, 1, sse2);
- H264_QPEL_FUNCS(1, 2, sse2);
- H264_QPEL_FUNCS(1, 3, sse2);
- H264_QPEL_FUNCS(2, 1, sse2);
- H264_QPEL_FUNCS(2, 2, sse2);
- H264_QPEL_FUNCS(2, 3, sse2);
- H264_QPEL_FUNCS(3, 1, sse2);
- H264_QPEL_FUNCS(3, 2, sse2);
- H264_QPEL_FUNCS(3, 3, sse2);
+ H264_QPEL_FUNCS(0, 1, sse2);
+ H264_QPEL_FUNCS(0, 2, sse2);
+ H264_QPEL_FUNCS(0, 3, sse2);
+ H264_QPEL_FUNCS(1, 1, sse2);
+ H264_QPEL_FUNCS(1, 2, sse2);
+ H264_QPEL_FUNCS(1, 3, sse2);
+ H264_QPEL_FUNCS(2, 1, sse2);
+ H264_QPEL_FUNCS(2, 2, sse2);
+ H264_QPEL_FUNCS(2, 3, sse2);
+ H264_QPEL_FUNCS(3, 1, sse2);
+ H264_QPEL_FUNCS(3, 2, sse2);
+ H264_QPEL_FUNCS(3, 3, sse2);
}
#if HAVE_YASM
+#define H264_QPEL_FUNCS_10(x, y, CPU)\
+ c->put_h264_qpel_pixels_tab[0][x+y*4] = ff_put_h264_qpel16_mc##x##y##_10_##CPU;\
+ c->put_h264_qpel_pixels_tab[1][x+y*4] = ff_put_h264_qpel8_mc##x##y##_10_##CPU;\
+ c->avg_h264_qpel_pixels_tab[0][x+y*4] = ff_avg_h264_qpel16_mc##x##y##_10_##CPU;\
+ c->avg_h264_qpel_pixels_tab[1][x+y*4] = ff_avg_h264_qpel8_mc##x##y##_10_##CPU;
if (bit_depth == 10) {
- c->put_h264_chroma_pixels_tab[0]= ff_put_h264_chroma_mc8_10_sse2;
- c->avg_h264_chroma_pixels_tab[0]= ff_avg_h264_chroma_mc8_10_sse2;
+ SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_sse2, ff_);
+ SET_QPEL_FUNCS(put_h264_qpel, 1, 8, 10_sse2, ff_);
+ SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_sse2, ff_);
+ SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, 10_sse2, ff_);
+ H264_QPEL_FUNCS_10(1, 0, sse2_cache64)
+ H264_QPEL_FUNCS_10(2, 0, sse2_cache64)
+ H264_QPEL_FUNCS_10(3, 0, sse2_cache64)
+
+ if (CONFIG_H264CHROMA) {
+ c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_sse2;
+ c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_sse2;
+ }
}
#endif
}
@@ -2799,9 +2820,16 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
H264_QPEL_FUNCS(3, 2, ssse3);
H264_QPEL_FUNCS(3, 3, ssse3);
}
+#if HAVE_YASM
+ else if (bit_depth == 10) {
+ H264_QPEL_FUNCS_10(1, 0, ssse3_cache64)
+ H264_QPEL_FUNCS_10(2, 0, ssse3_cache64)
+ H264_QPEL_FUNCS_10(3, 0, ssse3_cache64)
+ }
+#endif
c->add_png_paeth_prediction= add_png_paeth_prediction_ssse3;
#if HAVE_YASM
- if (!high_bit_depth) {
+ if (!high_bit_depth && CONFIG_H264CHROMA) {
c->put_h264_chroma_pixels_tab[0]= ff_put_h264_chroma_mc8_ssse3_rnd;
c->avg_h264_chroma_pixels_tab[0]= ff_avg_h264_chroma_mc8_ssse3_rnd;
c->put_h264_chroma_pixels_tab[1]= ff_put_h264_chroma_mc4_ssse3;
@@ -2814,11 +2842,11 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
}
#endif
- if(mm_flags & AV_CPU_FLAG_3DNOW){
+ if (HAVE_AMD3DNOW && (mm_flags & AV_CPU_FLAG_3DNOW)) {
c->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow;
c->vector_fmul = vector_fmul_3dnow;
}
- if(mm_flags & AV_CPU_FLAG_3DNOWEXT){
+ if (HAVE_AMD3DNOWEXT && (mm_flags & AV_CPU_FLAG_3DNOWEXT)) {
c->vector_fmul_reverse = vector_fmul_reverse_3dnow2;
#if HAVE_6REGS
c->vector_fmul_window = vector_fmul_window_3dnow2;
@@ -2847,14 +2875,24 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
c->vector_clipf = vector_clipf_sse;
#if HAVE_YASM
c->scalarproduct_float = ff_scalarproduct_float_sse;
+ c->butterflies_float_interleave = ff_butterflies_float_interleave_sse;
+
+ if (!high_bit_depth)
+ c->emulated_edge_mc = emulated_edge_mc_sse;
+ c->gmc = gmc_sse;
#endif
}
- if(mm_flags & AV_CPU_FLAG_3DNOW)
+ if (HAVE_AMD3DNOW && (mm_flags & AV_CPU_FLAG_3DNOW))
c->vector_fmul_add = vector_fmul_add_3dnow; // faster than sse
if(mm_flags & AV_CPU_FLAG_SSE2){
#if HAVE_YASM
c->scalarproduct_int16 = ff_scalarproduct_int16_sse2;
c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2;
+ if (mm_flags & AV_CPU_FLAG_ATOM) {
+ c->vector_clip_int32 = ff_vector_clip_int32_int_sse2;
+ } else {
+ c->vector_clip_int32 = ff_vector_clip_int32_sse2;
+ }
if (avctx->flags & CODEC_FLAG_BITEXACT) {
c->apply_window_int16 = ff_apply_window_int16_sse2_ba;
} else {
@@ -2862,10 +2900,6 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
c->apply_window_int16 = ff_apply_window_int16_sse2;
}
}
-
- if (!high_bit_depth)
- c->emulated_edge_mc = emulated_edge_mc_sse;
- c->gmc= gmc_sse;
#endif
}
if (mm_flags & AV_CPU_FLAG_SSSE3) {
@@ -2880,51 +2914,32 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
}
#endif
}
+
+ if (mm_flags & AV_CPU_FLAG_SSE4 && HAVE_SSE) {
+#if HAVE_YASM
+ c->vector_clip_int32 = ff_vector_clip_int32_sse4;
+#endif
+ }
+
#if HAVE_AVX && HAVE_YASM
if (mm_flags & AV_CPU_FLAG_AVX) {
if (bit_depth == 10) {
- c->put_h264_chroma_pixels_tab[0]= ff_put_h264_chroma_mc8_10_avx;
- c->avg_h264_chroma_pixels_tab[0]= ff_avg_h264_chroma_mc8_10_avx;
+ //AVX implies !cache64.
+ //TODO: Port cache(32|64) detection from x264.
+ H264_QPEL_FUNCS_10(1, 0, sse2)
+ H264_QPEL_FUNCS_10(2, 0, sse2)
+ H264_QPEL_FUNCS_10(3, 0, sse2)
+
+ if (CONFIG_H264CHROMA) {
+ c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_avx;
+ c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_avx;
+ }
}
+ c->butterflies_float_interleave = ff_butterflies_float_interleave_avx;
}
#endif
}
if (CONFIG_ENCODERS)
dsputilenc_init_mmx(c, avctx);
-
-#if 0
- // for speed testing
- get_pixels = just_return;
- put_pixels_clamped = just_return;
- add_pixels_clamped = just_return;
-
- pix_abs16x16 = just_return;
- pix_abs16x16_x2 = just_return;
- pix_abs16x16_y2 = just_return;
- pix_abs16x16_xy2 = just_return;
-
- put_pixels_tab[0] = just_return;
- put_pixels_tab[1] = just_return;
- put_pixels_tab[2] = just_return;
- put_pixels_tab[3] = just_return;
-
- put_no_rnd_pixels_tab[0] = just_return;
- put_no_rnd_pixels_tab[1] = just_return;
- put_no_rnd_pixels_tab[2] = just_return;
- put_no_rnd_pixels_tab[3] = just_return;
-
- avg_pixels_tab[0] = just_return;
- avg_pixels_tab[1] = just_return;
- avg_pixels_tab[2] = just_return;
- avg_pixels_tab[3] = just_return;
-
- avg_no_rnd_pixels_tab[0] = just_return;
- avg_no_rnd_pixels_tab[1] = just_return;
- avg_no_rnd_pixels_tab[2] = just_return;
- avg_no_rnd_pixels_tab[3] = just_return;
-
- //av_fdct = just_return;
- //ff_idct = just_return;
-#endif
}
diff --git a/libavcodec/x86/dsputil_yasm.asm b/libavcodec/x86/dsputil_yasm.asm
index 8b19cc1..4d2fb6a 100644
--- a/libavcodec/x86/dsputil_yasm.asm
+++ b/libavcodec/x86/dsputil_yasm.asm
@@ -20,6 +20,7 @@
;******************************************************************************
%include "x86inc.asm"
+%include "x86util.asm"
SECTION_RODATA
pb_f: times 16 db 15
@@ -496,14 +497,14 @@ cglobal scalarproduct_float_sse, 3,3,2, v1, v2, offset
; ... and then the same for left/right extend also. See below for loop
; function implementations. Fast are fixed-width, slow is variable-width
-%macro EMU_EDGE_FUNC 1
+%macro EMU_EDGE_FUNC 0
%ifdef ARCH_X86_64
%define w_reg r10
-cglobal emu_edge_core_%1, 6, 7, 1
+cglobal emu_edge_core, 6, 7, 1
mov r11, r5 ; save block_h
%else
%define w_reg r6
-cglobal emu_edge_core_%1, 2, 7, 0
+cglobal emu_edge_core, 2, 7, 0
mov r4, r4m ; end_y
mov r5, r5m ; block_h
%endif
@@ -629,18 +630,18 @@ cglobal emu_edge_core_%1, 2, 7, 0
; - if (%2 & 3 == 3) fills 2 bytes into r6, and 1 into ebx
; - else fills remaining bytes into ebx
; writing data out is in the same way
-%macro READ_NUM_BYTES 3
+%macro READ_NUM_BYTES 2
%assign %%src_off 0 ; offset in source buffer
%assign %%smidx 0 ; mmx register idx
%assign %%sxidx 0 ; xmm register idx
-%ifnidn %3, mmx
+%if cpuflag(sse)
%rep %2/16
- movdqu xmm %+ %%sxidx, [r1+%%src_off]
+ movups xmm %+ %%sxidx, [r1+%%src_off]
%assign %%src_off %%src_off+16
%assign %%sxidx %%sxidx+1
%endrep ; %2/16
-%endif ; !mmx
+%endif
%ifdef ARCH_X86_64
%if (%2-%%src_off) == 8
@@ -678,14 +679,14 @@ cglobal emu_edge_core_%1, 2, 7, 0
%endif ; (%2-%%src_off) == 1/2/3
%endmacro ; READ_NUM_BYTES
-%macro WRITE_NUM_BYTES 3
+%macro WRITE_NUM_BYTES 2
%assign %%dst_off 0 ; offset in destination buffer
%assign %%dmidx 0 ; mmx register idx
%assign %%dxidx 0 ; xmm register idx
-%ifnidn %3, mmx
+%if cpuflag(sse)
%rep %2/16
- movdqu [r0+%%dst_off], xmm %+ %%dxidx
+ movups [r0+%%dst_off], xmm %+ %%dxidx
%assign %%dst_off %%dst_off+16
%assign %%dxidx %%dxidx+1
%endrep ; %2/16
@@ -733,7 +734,7 @@ cglobal emu_edge_core_%1, 2, 7, 0
; those out into the destination buffer
; r0=buf,r1=src,r2=linesize,r3(64)/r3m(32)=start_x,r4=end_y,r5=block_h
; r6(eax/64)/r3(ebx/32)=val_reg
-%macro VERTICAL_EXTEND 1
+%macro VERTICAL_EXTEND 0
%assign %%n 1
%rep 22
ALIGN 128
@@ -746,9 +747,9 @@ ALIGN 128
cmp dword r3m, 0
je .emuedge_copy_body_ %+ %%n %+ _loop
%endif ; ARCH_X86_64/32
- READ_NUM_BYTES top, %%n, %1 ; read bytes
+ READ_NUM_BYTES top, %%n ; read bytes
.emuedge_extend_top_ %+ %%n %+ _loop: ; do {
- WRITE_NUM_BYTES top, %%n, %1 ; write bytes
+ WRITE_NUM_BYTES top, %%n ; write bytes
add r0 , r2 ; dst += linesize
%ifdef ARCH_X86_64
dec r3d
@@ -759,8 +760,8 @@ ALIGN 128
; copy body pixels
.emuedge_copy_body_ %+ %%n %+ _loop: ; do {
- READ_NUM_BYTES body, %%n, %1 ; read bytes
- WRITE_NUM_BYTES body, %%n, %1 ; write bytes
+ READ_NUM_BYTES body, %%n ; read bytes
+ WRITE_NUM_BYTES body, %%n ; write bytes
add r0 , r2 ; dst += linesize
add r1 , r2 ; src += linesize
dec r4d
@@ -770,9 +771,9 @@ ALIGN 128
test r5 , r5 ; if (!block_h)
jz .emuedge_v_extend_end_ %+ %%n ; goto end
sub r1 , r2 ; src -= linesize
- READ_NUM_BYTES bottom, %%n, %1 ; read bytes
+ READ_NUM_BYTES bottom, %%n ; read bytes
.emuedge_extend_bottom_ %+ %%n %+ _loop: ; do {
- WRITE_NUM_BYTES bottom, %%n, %1 ; write bytes
+ WRITE_NUM_BYTES bottom, %%n ; write bytes
add r0 , r2 ; dst += linesize
dec r5d
jnz .emuedge_extend_bottom_ %+ %%n %+ _loop ; } while (--block_h)
@@ -795,17 +796,17 @@ ALIGN 128
; lowest two bytes of the register (so val*0x0101), and are splatted
; into each byte of mm0 as well if n_pixels >= 8
-%macro READ_V_PIXEL 3
+%macro READ_V_PIXEL 2
mov vall, %2
mov valh, vall
%if %1 >= 8
movd mm0, vald
-%ifidn %3, mmx
+%if cpuflag(mmx2)
+ pshufw mm0, mm0, 0
+%else ; mmx
punpcklwd mm0, mm0
punpckldq mm0, mm0
-%else ; !mmx
- pshufw mm0, mm0, 0
-%endif ; mmx
+%endif ; sse
%endif ; %1 >= 8
%endmacro
@@ -830,13 +831,13 @@ ALIGN 128
%endmacro
; r0=buf+block_h*linesize, r1=start_x, r2=linesize, r5=block_h, r6/r3=val
-%macro LEFT_EXTEND 1
+%macro LEFT_EXTEND 0
%assign %%n 2
%rep 11
ALIGN 64
.emuedge_extend_left_ %+ %%n: ; do {
sub r0, r2 ; dst -= linesize
- READ_V_PIXEL %%n, [r0+r1], %1 ; read pixels
+ READ_V_PIXEL %%n, [r0+r1] ; read pixels
WRITE_V_PIXEL %%n, r0 ; write pixels
dec r5
jnz .emuedge_extend_left_ %+ %%n ; } while (--block_h)
@@ -850,19 +851,19 @@ ALIGN 64
%endmacro ; LEFT_EXTEND
; r3/r0=buf+block_h*linesize, r2=linesize, r11/r5=block_h, r0/r6=end_x, r6/r3=val
-%macro RIGHT_EXTEND 1
+%macro RIGHT_EXTEND 0
%assign %%n 2
%rep 11
ALIGN 64
.emuedge_extend_right_ %+ %%n: ; do {
%ifdef ARCH_X86_64
sub r3, r2 ; dst -= linesize
- READ_V_PIXEL %%n, [r3+w_reg-1], %1 ; read pixels
+ READ_V_PIXEL %%n, [r3+w_reg-1] ; read pixels
WRITE_V_PIXEL %%n, r3+r4-%%n ; write pixels
dec r11
%else ; ARCH_X86_32
sub r0, r2 ; dst -= linesize
- READ_V_PIXEL %%n, [r0+w_reg-1], %1 ; read pixels
+ READ_V_PIXEL %%n, [r0+w_reg-1] ; read pixels
WRITE_V_PIXEL %%n, r0+r4-%%n ; write pixels
dec r5
%endif ; ARCH_X86_64/32
@@ -904,17 +905,17 @@ ALIGN 64
.%1_skip_%4_px:
%endmacro
-%macro V_COPY_ROW 3
+%macro V_COPY_ROW 2
%ifidn %1, bottom
sub r1, linesize
%endif
.%1_copy_loop:
xor cnt_reg, cnt_reg
-%ifidn %3, mmx
+%if notcpuflag(sse)
%define linesize r2m
V_COPY_NPX %1, mm0, movq, 8, 0xFFFFFFF8
-%else ; !mmx
- V_COPY_NPX %1, xmm0, movdqu, 16, 0xFFFFFFF0
+%else ; sse
+ V_COPY_NPX %1, xmm0, movups, 16, 0xFFFFFFF0
%ifdef ARCH_X86_64
%define linesize r2
V_COPY_NPX %1, rax , mov, 8
@@ -922,7 +923,7 @@ ALIGN 64
%define linesize r2m
V_COPY_NPX %1, mm0, movq, 8
%endif ; ARCH_X86_64/32
-%endif ; mmx
+%endif ; sse
V_COPY_NPX %1, vald, mov, 4
V_COPY_NPX %1, valw, mov, 2
V_COPY_NPX %1, vall, mov, 1
@@ -935,7 +936,7 @@ ALIGN 64
jnz .%1_copy_loop
%endmacro
-%macro SLOW_V_EXTEND 1
+%macro SLOW_V_EXTEND 0
.slow_v_extend_loop:
; r0=buf,r1=src,r2(64)/r2m(32)=linesize,r3(64)/r3m(32)=start_x,r4=end_y,r5=block_h
; r11(64)/r3(later-64)/r2(32)=cnt_reg,r6(64)/r3(32)=val_reg,r10(64)/r6(32)=w=end_x-start_x
@@ -944,16 +945,16 @@ ALIGN 64
test r3, r3
%define cnt_reg r11
jz .do_body_copy ; if (!start_y) goto do_body_copy
- V_COPY_ROW top, r3, %1
+ V_COPY_ROW top, r3
%else
cmp dword r3m, 0
%define cnt_reg r2
je .do_body_copy ; if (!start_y) goto do_body_copy
- V_COPY_ROW top, dword r3m, %1
+ V_COPY_ROW top, dword r3m
%endif
.do_body_copy:
- V_COPY_ROW body, r4, %1
+ V_COPY_ROW body, r4
%ifdef ARCH_X86_64
pop r11 ; restore old value of block_h
@@ -965,7 +966,7 @@ ALIGN 64
%else
jz .skip_bottom_extend
%endif
- V_COPY_ROW bottom, r5, %1
+ V_COPY_ROW bottom, r5
%ifdef ARCH_X86_32
.skip_bottom_extend:
mov r2, r2m
@@ -973,12 +974,12 @@ ALIGN 64
jmp .v_extend_end
%endmacro
-%macro SLOW_LEFT_EXTEND 1
+%macro SLOW_LEFT_EXTEND 0
.slow_left_extend_loop:
; r0=buf+block_h*linesize,r2=linesize,r6(64)/r3(32)=val,r5=block_h,r4=cntr,r10/r6=start_x
mov r4, 8
sub r0, linesize
- READ_V_PIXEL 8, [r0+w_reg], %1
+ READ_V_PIXEL 8, [r0+w_reg]
.left_extend_8px_loop:
movq [r0+r4-8], mm0
add r4, 8
@@ -1001,7 +1002,7 @@ ALIGN 64
jmp .right_extend
%endmacro
-%macro SLOW_RIGHT_EXTEND 1
+%macro SLOW_RIGHT_EXTEND 0
.slow_right_extend_loop:
; r3(64)/r0(32)=buf+block_h*linesize,r2=linesize,r4=block_w,r11(64)/r5(32)=block_h,
; r10(64)/r6(32)=end_x,r6/r3=val,r1=cntr
@@ -1014,7 +1015,7 @@ ALIGN 64
%endif
lea r1, [r4-8]
sub buf_reg, linesize
- READ_V_PIXEL 8, [buf_reg+w_reg-1], %1
+ READ_V_PIXEL 8, [buf_reg+w_reg-1]
.right_extend_8px_loop:
movq [buf_reg+r1], mm0
sub r1, 8
@@ -1035,16 +1036,145 @@ ALIGN 64
%endmacro
%macro emu_edge 1
-EMU_EDGE_FUNC %1
-VERTICAL_EXTEND %1
-LEFT_EXTEND %1
-RIGHT_EXTEND %1
-SLOW_V_EXTEND %1
-SLOW_LEFT_EXTEND %1
-SLOW_RIGHT_EXTEND %1
+INIT_XMM %1
+EMU_EDGE_FUNC
+VERTICAL_EXTEND
+LEFT_EXTEND
+RIGHT_EXTEND
+SLOW_V_EXTEND
+SLOW_LEFT_EXTEND
+SLOW_RIGHT_EXTEND
%endmacro
emu_edge sse
%ifdef ARCH_X86_32
emu_edge mmx
%endif
+
+;-----------------------------------------------------------------------------
+; void ff_vector_clip_int32(int32_t *dst, const int32_t *src, int32_t min,
+; int32_t max, unsigned int len)
+;-----------------------------------------------------------------------------
+
+; %1 = number of xmm registers used
+; %2 = number of inline load/process/store loops per asm loop
+; %3 = process 4*mmsize (%3=0) or 8*mmsize (%3=1) bytes per loop
+; %4 = CLIPD function takes min/max as float instead of int (CLIPD_SSE2)
+; %5 = suffix
+%macro VECTOR_CLIP_INT32 4-5
+cglobal vector_clip_int32%5, 5,5,%2, dst, src, min, max, len
+%if %4
+ cvtsi2ss m4, minm
+ cvtsi2ss m5, maxm
+%else
+ movd m4, minm
+ movd m5, maxm
+%endif
+ SPLATD m4
+ SPLATD m5
+.loop:
+%assign %%i 1
+%rep %2
+ mova m0, [srcq+mmsize*0*%%i]
+ mova m1, [srcq+mmsize*1*%%i]
+ mova m2, [srcq+mmsize*2*%%i]
+ mova m3, [srcq+mmsize*3*%%i]
+%if %3
+ mova m7, [srcq+mmsize*4*%%i]
+ mova m8, [srcq+mmsize*5*%%i]
+ mova m9, [srcq+mmsize*6*%%i]
+ mova m10, [srcq+mmsize*7*%%i]
+%endif
+ CLIPD m0, m4, m5, m6
+ CLIPD m1, m4, m5, m6
+ CLIPD m2, m4, m5, m6
+ CLIPD m3, m4, m5, m6
+%if %3
+ CLIPD m7, m4, m5, m6
+ CLIPD m8, m4, m5, m6
+ CLIPD m9, m4, m5, m6
+ CLIPD m10, m4, m5, m6
+%endif
+ mova [dstq+mmsize*0*%%i], m0
+ mova [dstq+mmsize*1*%%i], m1
+ mova [dstq+mmsize*2*%%i], m2
+ mova [dstq+mmsize*3*%%i], m3
+%if %3
+ mova [dstq+mmsize*4*%%i], m7
+ mova [dstq+mmsize*5*%%i], m8
+ mova [dstq+mmsize*6*%%i], m9
+ mova [dstq+mmsize*7*%%i], m10
+%endif
+%assign %%i %%i+1
+%endrep
+ add srcq, mmsize*4*(%2+%3)
+ add dstq, mmsize*4*(%2+%3)
+ sub lend, mmsize*(%2+%3)
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_MMX mmx
+%define SPLATD SPLATD_MMX
+%define CLIPD CLIPD_MMX
+VECTOR_CLIP_INT32 0, 1, 0, 0
+INIT_XMM sse2
+%define SPLATD SPLATD_SSE2
+VECTOR_CLIP_INT32 6, 1, 0, 0, _int
+%define CLIPD CLIPD_SSE2
+VECTOR_CLIP_INT32 6, 2, 0, 1
+INIT_XMM sse4
+%define CLIPD CLIPD_SSE41
+%ifdef m8
+VECTOR_CLIP_INT32 11, 1, 1, 0
+%else
+VECTOR_CLIP_INT32 6, 1, 0, 0
+%endif
+
+;-----------------------------------------------------------------------------
+; void ff_butterflies_float_interleave(float *dst, const float *src0,
+; const float *src1, int len);
+;-----------------------------------------------------------------------------
+
+%macro BUTTERFLIES_FLOAT_INTERLEAVE 0
+cglobal butterflies_float_interleave, 4,4,3, dst, src0, src1, len
+%ifdef ARCH_X86_64
+ movsxd lenq, lend
+%endif
+ test lenq, lenq
+ jz .end
+ shl lenq, 2
+ lea src0q, [src0q + lenq]
+ lea src1q, [src1q + lenq]
+ lea dstq, [ dstq + 2*lenq]
+ neg lenq
+.loop:
+ mova m0, [src0q + lenq]
+ mova m1, [src1q + lenq]
+ subps m2, m0, m1
+ addps m0, m0, m1
+ unpcklps m1, m0, m2
+ unpckhps m0, m0, m2
+%if cpuflag(avx)
+ vextractf128 [dstq + 2*lenq ], m1, 0
+ vextractf128 [dstq + 2*lenq + 16], m0, 0
+ vextractf128 [dstq + 2*lenq + 32], m1, 1
+ vextractf128 [dstq + 2*lenq + 48], m0, 1
+%else
+ mova [dstq + 2*lenq ], m1
+ mova [dstq + 2*lenq + mmsize], m0
+%endif
+ add lenq, mmsize
+ jl .loop
+%if mmsize == 32
+ vzeroupper
+ RET
+%endif
+.end:
+ REP_RET
+%endmacro
+
+INIT_XMM sse
+BUTTERFLIES_FLOAT_INTERLEAVE
+INIT_YMM avx
+BUTTERFLIES_FLOAT_INTERLEAVE
diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c
index 0373891..7362234 100644
--- a/libavcodec/x86/dsputilenc_mmx.c
+++ b/libavcodec/x86/dsputilenc_mmx.c
@@ -1098,10 +1098,12 @@ static int ssd_int8_vs_int16_mmx(const int8_t *pix1, const int16_t *pix2, int si
void dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx)
{
int mm_flags = av_get_cpu_flags();
+ int bit_depth = avctx->bits_per_raw_sample;
if (mm_flags & AV_CPU_FLAG_MMX) {
const int dct_algo = avctx->dct_algo;
- if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){
+ if (avctx->bits_per_raw_sample <= 8 &&
+ (dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX)) {
if(mm_flags & AV_CPU_FLAG_SSE2){
c->fdct = ff_fdct_sse2;
}else if(mm_flags & AV_CPU_FLAG_MMX2){
@@ -1111,7 +1113,8 @@ void dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx)
}
}
- c->get_pixels = get_pixels_mmx;
+ if (bit_depth <= 8)
+ c->get_pixels = get_pixels_mmx;
c->diff_pixels = diff_pixels_mmx;
c->pix_sum = pix_sum16_mmx;
@@ -1158,7 +1161,8 @@ void dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx)
}
if(mm_flags & AV_CPU_FLAG_SSE2){
- c->get_pixels = get_pixels_sse2;
+ if (bit_depth <= 8)
+ c->get_pixels = get_pixels_sse2;
c->sum_abs_dctelem= sum_abs_dctelem_sse2;
#if HAVE_YASM && HAVE_ALIGNED_STACK
c->hadamard8_diff[0]= ff_hadamard8_diff16_sse2;
diff --git a/libavcodec/x86/fft.c b/libavcodec/x86/fft.c
index 899f0f7..f7308cc 100644
--- a/libavcodec/x86/fft.c
+++ b/libavcodec/x86/fft.c
@@ -60,6 +60,8 @@ av_cold void ff_dct_init_mmx(DCTContext *s)
int has_vectors = av_get_cpu_flags();
if (has_vectors & AV_CPU_FLAG_AVX && HAVE_AVX)
s->dct32 = ff_dct32_float_avx;
+ else if (has_vectors & AV_CPU_FLAG_SSE2 && HAVE_SSE)
+ s->dct32 = ff_dct32_float_sse2;
else if (has_vectors & AV_CPU_FLAG_SSE && HAVE_SSE)
s->dct32 = ff_dct32_float_sse;
#endif
diff --git a/libavcodec/x86/fft.h b/libavcodec/x86/fft.h
index 0ade2b2..9d68d5b 100644
--- a/libavcodec/x86/fft.h
+++ b/libavcodec/x86/fft.h
@@ -35,6 +35,7 @@ void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input)
void ff_imdct_half_sse(FFTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_half_avx(FFTContext *s, FFTSample *output, const FFTSample *input);
void ff_dct32_float_sse(FFTSample *out, const FFTSample *in);
+void ff_dct32_float_sse2(FFTSample *out, const FFTSample *in);
void ff_dct32_float_avx(FFTSample *out, const FFTSample *in);
#endif /* AVCODEC_X86_FFT_H */
diff --git a/libavcodec/x86/fft_3dn2.c b/libavcodec/x86/fft_3dn2.c
index 05c0467..a724398 100644
--- a/libavcodec/x86/fft_3dn2.c
+++ b/libavcodec/x86/fft_3dn2.c
@@ -23,7 +23,7 @@
#include "libavcodec/dsputil.h"
#include "fft.h"
-DECLARE_ALIGNED(8, static const int, m1m1)[2] = { 1<<31, 1<<31 };
+DECLARE_ALIGNED(8, static const unsigned int, m1m1)[2] = { 1U<<31, 1U<<31 };
#ifdef EMULATE_3DNOWEXT
#define PSWAPD(s,d)\
@@ -70,7 +70,7 @@ void ff_imdct_half_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input
in1 = input;
in2 = input + n2 - 1;
#ifdef EMULATE_3DNOWEXT
- __asm__ volatile("movd %0, %%mm7" ::"r"(1<<31));
+ __asm__ volatile("movd %0, %%mm7" ::"r"(1U<<31));
#endif
for(k = 0; k < n4; k++) {
// FIXME a single block is faster, but gcc 2.95 and 3.4.x on 32bit can't compile it
diff --git a/libavcodec/x86/fft_sse.c b/libavcodec/x86/fft_sse.c
index add20dd..6be5be9 100644
--- a/libavcodec/x86/fft_sse.c
+++ b/libavcodec/x86/fft_sse.c
@@ -24,8 +24,8 @@
#include "fft.h"
#include "config.h"
-DECLARE_ASM_CONST(16, int, ff_m1m1m1m1)[4] =
- { 1 << 31, 1 << 31, 1 << 31, 1 << 31 };
+DECLARE_ASM_CONST(16, unsigned int, ff_m1m1m1m1)[4] =
+ { 1U << 31, 1U << 31, 1U << 31, 1U << 31 };
void ff_fft_dispatch_sse(FFTComplex *z, int nbits);
void ff_fft_dispatch_interleave_sse(FFTComplex *z, int nbits);
diff --git a/libavcodec/x86/fmtconvert.asm b/libavcodec/x86/fmtconvert.asm
index efab87d..d621089 100644
--- a/libavcodec/x86/fmtconvert.asm
+++ b/libavcodec/x86/fmtconvert.asm
@@ -24,6 +24,150 @@
SECTION_TEXT
+;---------------------------------------------------------------------------------
+; void int32_to_float_fmul_scalar(float *dst, const int *src, float mul, int len);
+;---------------------------------------------------------------------------------
+%macro INT32_TO_FLOAT_FMUL_SCALAR 2
+%ifdef UNIX64
+cglobal int32_to_float_fmul_scalar_%1, 3,3,%2, dst, src, len
+%else
+cglobal int32_to_float_fmul_scalar_%1, 4,4,%2, dst, src, mul, len
+%endif
+%ifdef WIN64
+ SWAP 0, 2
+%elifdef ARCH_X86_32
+ movss m0, mulm
+%endif
+ SPLATD m0
+ shl lenq, 2
+ add srcq, lenq
+ add dstq, lenq
+ neg lenq
+.loop:
+%ifidn %1, sse2
+ cvtdq2ps m1, [srcq+lenq ]
+ cvtdq2ps m2, [srcq+lenq+16]
+%else
+ cvtpi2ps m1, [srcq+lenq ]
+ cvtpi2ps m3, [srcq+lenq+ 8]
+ cvtpi2ps m2, [srcq+lenq+16]
+ cvtpi2ps m4, [srcq+lenq+24]
+ movlhps m1, m3
+ movlhps m2, m4
+%endif
+ mulps m1, m0
+ mulps m2, m0
+ mova [dstq+lenq ], m1
+ mova [dstq+lenq+16], m2
+ add lenq, 32
+ jl .loop
+ REP_RET
+%endmacro
+
+INIT_XMM
+%define SPLATD SPLATD_SSE
+%define movdqa movaps
+INT32_TO_FLOAT_FMUL_SCALAR sse, 5
+%undef movdqa
+%define SPLATD SPLATD_SSE2
+INT32_TO_FLOAT_FMUL_SCALAR sse2, 3
+%undef SPLATD
+
+
+;------------------------------------------------------------------------------
+; void ff_float_to_int16(int16_t *dst, const float *src, long len);
+;------------------------------------------------------------------------------
+%macro FLOAT_TO_INT16 2
+cglobal float_to_int16_%1, 3,3,%2, dst, src, len
+ add lenq, lenq
+ lea srcq, [srcq+2*lenq]
+ add dstq, lenq
+ neg lenq
+.loop:
+%ifidn %1, sse2
+ cvtps2dq m0, [srcq+2*lenq ]
+ cvtps2dq m1, [srcq+2*lenq+16]
+ packssdw m0, m1
+ mova [dstq+lenq], m0
+%else
+ cvtps2pi m0, [srcq+2*lenq ]
+ cvtps2pi m1, [srcq+2*lenq+ 8]
+ cvtps2pi m2, [srcq+2*lenq+16]
+ cvtps2pi m3, [srcq+2*lenq+24]
+ packssdw m0, m1
+ packssdw m2, m3
+ mova [dstq+lenq ], m0
+ mova [dstq+lenq+8], m2
+%endif
+ add lenq, 16
+ js .loop
+%ifnidn %1, sse2
+ emms
+%endif
+ REP_RET
+%endmacro
+
+INIT_XMM
+FLOAT_TO_INT16 sse2, 2
+INIT_MMX
+FLOAT_TO_INT16 sse, 0
+%define cvtps2pi pf2id
+FLOAT_TO_INT16 3dnow, 0
+%undef cvtps2pi
+
+
+;-------------------------------------------------------------------------------
+; void ff_float_to_int16_interleave2(int16_t *dst, const float **src, long len);
+;-------------------------------------------------------------------------------
+%macro FLOAT_TO_INT16_INTERLEAVE2 1
+cglobal float_to_int16_interleave2_%1, 3,4,2, dst, src0, src1, len
+ lea lenq, [4*r2q]
+ mov src1q, [src0q+gprsize]
+ mov src0q, [src0q]
+ add dstq, lenq
+ add src0q, lenq
+ add src1q, lenq
+ neg lenq
+.loop:
+%ifidn %1, sse2
+ cvtps2dq m0, [src0q+lenq]
+ cvtps2dq m1, [src1q+lenq]
+ packssdw m0, m1
+ movhlps m1, m0
+ punpcklwd m0, m1
+ mova [dstq+lenq], m0
+%else
+ cvtps2pi m0, [src0q+lenq ]
+ cvtps2pi m1, [src0q+lenq+8]
+ cvtps2pi m2, [src1q+lenq ]
+ cvtps2pi m3, [src1q+lenq+8]
+ packssdw m0, m1
+ packssdw m2, m3
+ mova m1, m0
+ punpcklwd m0, m2
+ punpckhwd m1, m2
+ mova [dstq+lenq ], m0
+ mova [dstq+lenq+8], m1
+%endif
+ add lenq, 16
+ js .loop
+%ifnidn %1, sse2
+ emms
+%endif
+ REP_RET
+%endmacro
+
+INIT_MMX
+%define cvtps2pi pf2id
+FLOAT_TO_INT16_INTERLEAVE2 3dnow
+%undef cvtps2pi
+%define movdqa movaps
+FLOAT_TO_INT16_INTERLEAVE2 sse
+%undef movdqa
+INIT_XMM
+FLOAT_TO_INT16_INTERLEAVE2 sse2
+
+
%macro PSWAPD_SSE 2
pshufw %1, %2, 0x4e
%endmacro
diff --git a/libavcodec/x86/fmtconvert_mmx.c b/libavcodec/x86/fmtconvert_mmx.c
index 253f60b..17079d3 100644
--- a/libavcodec/x86/fmtconvert_mmx.c
+++ b/libavcodec/x86/fmtconvert_mmx.c
@@ -26,133 +26,32 @@
#include "libavutil/x86_cpu.h"
#include "libavcodec/fmtconvert.h"
-static void int32_to_float_fmul_scalar_sse(float *dst, const int *src, float mul, int len)
-{
- x86_reg i = -4*len;
- __asm__ volatile(
- "movss %3, %%xmm4 \n"
- "shufps $0, %%xmm4, %%xmm4 \n"
- "1: \n"
- "cvtpi2ps (%2,%0), %%xmm0 \n"
- "cvtpi2ps 8(%2,%0), %%xmm1 \n"
- "cvtpi2ps 16(%2,%0), %%xmm2 \n"
- "cvtpi2ps 24(%2,%0), %%xmm3 \n"
- "movlhps %%xmm1, %%xmm0 \n"
- "movlhps %%xmm3, %%xmm2 \n"
- "mulps %%xmm4, %%xmm0 \n"
- "mulps %%xmm4, %%xmm2 \n"
- "movaps %%xmm0, (%1,%0) \n"
- "movaps %%xmm2, 16(%1,%0) \n"
- "add $32, %0 \n"
- "jl 1b \n"
- :"+r"(i)
- :"r"(dst+len), "r"(src+len), "m"(mul)
- );
-}
-
-static void int32_to_float_fmul_scalar_sse2(float *dst, const int *src, float mul, int len)
-{
- x86_reg i = -4*len;
- __asm__ volatile(
- "movss %3, %%xmm4 \n"
- "shufps $0, %%xmm4, %%xmm4 \n"
- "1: \n"
- "cvtdq2ps (%2,%0), %%xmm0 \n"
- "cvtdq2ps 16(%2,%0), %%xmm1 \n"
- "mulps %%xmm4, %%xmm0 \n"
- "mulps %%xmm4, %%xmm1 \n"
- "movaps %%xmm0, (%1,%0) \n"
- "movaps %%xmm1, 16(%1,%0) \n"
- "add $32, %0 \n"
- "jl 1b \n"
- :"+r"(i)
- :"r"(dst+len), "r"(src+len), "m"(mul)
- );
-}
+#if HAVE_YASM
-static void float_to_int16_3dnow(int16_t *dst, const float *src, long len){
- x86_reg reglen = 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"(reglen), "+r"(dst), "+r"(src)
- );
-}
+void ff_int32_to_float_fmul_scalar_sse (float *dst, const int *src, float mul, int len);
+void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int *src, float mul, int len);
-static void float_to_int16_sse(int16_t *dst, const float *src, long len){
- x86_reg reglen = 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"(reglen), "+r"(dst), "+r"(src)
- );
-}
+void ff_float_to_int16_3dnow(int16_t *dst, const float *src, long len);
+void ff_float_to_int16_sse (int16_t *dst, const float *src, long len);
+void ff_float_to_int16_sse2 (int16_t *dst, const float *src, long len);
-static void float_to_int16_sse2(int16_t *dst, const float *src, long len){
- x86_reg reglen = 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"(reglen), "+r"(dst), "+r"(src)
- );
-}
+void ff_float_to_int16_interleave2_3dnow(int16_t *dst, const float **src, long len);
+void ff_float_to_int16_interleave2_sse (int16_t *dst, const float **src, long len);
+void ff_float_to_int16_interleave2_sse2 (int16_t *dst, const float **src, long len);
void ff_float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len);
void ff_float_to_int16_interleave6_3dnow(int16_t *dst, const float **src, int len);
void ff_float_to_int16_interleave6_3dn2(int16_t *dst, const float **src, int len);
-#if !HAVE_YASM
-#define ff_float_to_int16_interleave6_sse(a,b,c) float_to_int16_interleave_misc_sse(a,b,c,6)
-#define ff_float_to_int16_interleave6_3dnow(a,b,c) float_to_int16_interleave_misc_3dnow(a,b,c,6)
-#define ff_float_to_int16_interleave6_3dn2(a,b,c) float_to_int16_interleave_misc_3dnow(a,b,c,6)
-#endif
#define ff_float_to_int16_interleave6_sse2 ff_float_to_int16_interleave6_sse
-#define FLOAT_TO_INT16_INTERLEAVE(cpu, body) \
+#define FLOAT_TO_INT16_INTERLEAVE(cpu) \
/* gcc pessimizes register allocation if this is in the same function as float_to_int16_interleave_sse2*/\
static av_noinline void float_to_int16_interleave_misc_##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);\
+ ff_float_to_int16_##cpu(tmp, src[c], len);\
for(i=0, j=c; i<len; i++, j+=channels)\
dst[j] = tmp[i];\
}\
@@ -160,73 +59,18 @@ static av_noinline void float_to_int16_interleave_misc_##cpu(int16_t *dst, const
\
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);\
+ ff_float_to_int16_##cpu(dst, src[0], len);\
else if(channels==2){\
- x86_reg reglen = len; \
- 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"(reglen), "+r"(dst), "+r"(src0), "+r"(src1)\
- );\
+ ff_float_to_int16_interleave2_##cpu(dst, src, len);\
}else if(channels==6){\
ff_float_to_int16_interleave6_##cpu(dst, src, len);\
}else\
float_to_int16_interleave_misc_##cpu(dst, src, len, channels);\
}
-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"
-)
+FLOAT_TO_INT16_INTERLEAVE(3dnow)
+FLOAT_TO_INT16_INTERLEAVE(sse)
+FLOAT_TO_INT16_INTERLEAVE(sse2)
static void float_to_int16_interleave_3dn2(int16_t *dst, const float **src, long len, int channels){
if(channels==6)
@@ -235,7 +79,6 @@ static void float_to_int16_interleave_3dn2(int16_t *dst, const float **src, long
float_to_int16_interleave_3dnow(dst, src, len, channels);
}
-#if HAVE_YASM
void ff_float_interleave2_mmx(float *dst, const float **src, unsigned int len);
void ff_float_interleave2_sse(float *dst, const float **src, unsigned int len);
@@ -269,34 +112,32 @@ void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx)
{
int mm_flags = av_get_cpu_flags();
- if (mm_flags & AV_CPU_FLAG_MMX) {
#if HAVE_YASM
+ if (mm_flags & AV_CPU_FLAG_MMX) {
c->float_interleave = float_interleave_mmx;
-#endif
- if(mm_flags & AV_CPU_FLAG_3DNOW){
+ if (HAVE_AMD3DNOW && mm_flags & AV_CPU_FLAG_3DNOW) {
if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
- c->float_to_int16 = float_to_int16_3dnow;
+ c->float_to_int16 = ff_float_to_int16_3dnow;
c->float_to_int16_interleave = float_to_int16_interleave_3dnow;
}
}
- if(mm_flags & AV_CPU_FLAG_3DNOWEXT){
+ if (HAVE_AMD3DNOWEXT && mm_flags & AV_CPU_FLAG_3DNOWEXT) {
if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
c->float_to_int16_interleave = float_to_int16_interleave_3dn2;
}
}
- if(mm_flags & AV_CPU_FLAG_SSE){
- c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse;
- c->float_to_int16 = float_to_int16_sse;
+ if (HAVE_SSE && mm_flags & AV_CPU_FLAG_SSE) {
+ c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse;
+ c->float_to_int16 = ff_float_to_int16_sse;
c->float_to_int16_interleave = float_to_int16_interleave_sse;
-#if HAVE_YASM
c->float_interleave = float_interleave_sse;
-#endif
}
- if(mm_flags & AV_CPU_FLAG_SSE2){
- c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse2;
- c->float_to_int16 = float_to_int16_sse2;
+ if (HAVE_SSE && mm_flags & AV_CPU_FLAG_SSE2) {
+ c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2;
+ c->float_to_int16 = ff_float_to_int16_sse2;
c->float_to_int16_interleave = float_to_int16_interleave_sse2;
}
}
+#endif
}
diff --git a/libavcodec/x86/h264_chromamc.asm b/libavcodec/x86/h264_chromamc.asm
index 0a37994..16cf2ec 100644
--- a/libavcodec/x86/h264_chromamc.asm
+++ b/libavcodec/x86/h264_chromamc.asm
@@ -72,17 +72,17 @@ SECTION .text
.next4rows
movq mm0, [r1 ]
movq mm1, [r1+r2]
+ add r1, r4
CHROMAMC_AVG mm0, [r0 ]
CHROMAMC_AVG mm1, [r0+r2]
movq [r0 ], mm0
movq [r0+r2], mm1
add r0, r4
- add r1, r4
movq mm0, [r1 ]
movq mm1, [r1+r2]
+ add r1, r4
CHROMAMC_AVG mm0, [r0 ]
CHROMAMC_AVG mm1, [r0+r2]
- add r1, r4
movq [r0 ], mm0
movq [r0+r2], mm1
add r0, r4
@@ -472,8 +472,8 @@ cglobal %1_%2_chroma_mc8_%3, 6, 7, 8
mov r6d, r4d
shl r4d, 8
sub r4, r6
- add r4, 8 ; x*288+8 = x<<8 | (8-x)
mov r6, 8
+ add r4, 8 ; x*288+8 = x<<8 | (8-x)
sub r6d, r5d
imul r6, r4 ; (8-y)*(x*255+8) = (8-y)*x<<8 | (8-y)*(8-x)
imul r4d, r5d ; y *(x*255+8) = y *x<<8 | y *(8-x)
@@ -481,24 +481,23 @@ cglobal %1_%2_chroma_mc8_%3, 6, 7, 8
movd m7, r6d
movd m6, r4d
movdqa m5, [rnd_2d_%2]
+ movq m0, [r1 ]
+ movq m1, [r1+1]
pshuflw m7, m7, 0
pshuflw m6, m6, 0
+ punpcklbw m0, m1
movlhps m7, m7
movlhps m6, m6
- movq m0, [r1 ]
- movq m1, [r1 +1]
- punpcklbw m0, m1
- add r1, r2
.next2rows
- movq m1, [r1 ]
- movq m2, [r1 +1]
- movq m3, [r1+r2 ]
- movq m4, [r1+r2+1]
+ movq m1, [r1+r2*1 ]
+ movq m2, [r1+r2*1+1]
+ movq m3, [r1+r2*2 ]
+ movq m4, [r1+r2*2+1]
lea r1, [r1+r2*2]
punpcklbw m1, m2
- punpcklbw m3, m4
movdqa m2, m1
+ punpcklbw m3, m4
movdqa m4, m3
pmaddubsw m0, m7
pmaddubsw m1, m6
@@ -508,8 +507,8 @@ cglobal %1_%2_chroma_mc8_%3, 6, 7, 8
paddw m2, m5
paddw m1, m0
paddw m3, m2
- movdqa m0, m4
psrlw m1, 6
+ movdqa m0, m4
psrlw m3, 6
%ifidn %1, avg
movq m2, [r0 ]
@@ -576,6 +575,7 @@ cglobal %1_%2_chroma_mc8_%3, 6, 7, 8
movq m1, [r1+r2 ]
movdqa m2, m1
movq m3, [r1+r2*2]
+ lea r1, [r1+r2*2]
punpcklbw m0, m1
punpcklbw m2, m3
pmaddubsw m0, m7
@@ -594,7 +594,6 @@ cglobal %1_%2_chroma_mc8_%3, 6, 7, 8
movhps [r0+r2], m0
sub r3d, 2
lea r0, [r0+r2*2]
- lea r1, [r1+r2*2]
jg .next2yrows
REP_RET
%endmacro
@@ -607,8 +606,8 @@ cglobal %1_%2_chroma_mc4_%3, 6, 7, 0
mov r6, r4
shl r4d, 8
sub r4d, r6d
- add r4d, 8 ; x*288+8
mov r6, 8
+ add r4d, 8 ; x*288+8
sub r6d, r5d
imul r6d, r4d ; (8-y)*(x*255+8) = (8-y)*x<<8 | (8-y)*(8-x)
imul r4d, r5d ; y *(x*255+8) = y *x<<8 | y *(8-x)
@@ -616,17 +615,16 @@ cglobal %1_%2_chroma_mc4_%3, 6, 7, 0
movd m7, r6d
movd m6, r4d
movq m5, [pw_32]
+ movd m0, [r1 ]
pshufw m7, m7, 0
+ punpcklbw m0, [r1+1]
pshufw m6, m6, 0
- movd m0, [r1 ]
- punpcklbw m0, [r1 +1]
- add r1, r2
.next2rows
- movd m1, [r1 ]
- movd m3, [r1+r2 ]
- punpcklbw m1, [r1 +1]
- punpcklbw m3, [r1+r2+1]
+ movd m1, [r1+r2*1 ]
+ movd m3, [r1+r2*2 ]
+ punpcklbw m1, [r1+r2*1+1]
+ punpcklbw m3, [r1+r2*2+1]
lea r1, [r1+r2*2]
movq m2, m1
movq m4, m3
@@ -638,8 +636,8 @@ cglobal %1_%2_chroma_mc4_%3, 6, 7, 0
paddw m2, m5
paddw m1, m0
paddw m3, m2
- movq m0, m4
psrlw m1, 6
+ movq m0, m4
psrlw m3, 6
packuswb m1, m1
packuswb m3, m3
diff --git a/libavcodec/x86/h264_deblock.asm b/libavcodec/x86/h264_deblock.asm
index 9831ca2..92f91ac 100644
--- a/libavcodec/x86/h264_deblock.asm
+++ b/libavcodec/x86/h264_deblock.asm
@@ -240,17 +240,17 @@ cextern pb_A1
; out: m1=p0' m2=q0'
; clobbers: m0,3-6
%macro DEBLOCK_P0_Q0 0
- pxor m5, m1, m2 ; p0^q0
- pand m5, [pb_1] ; (p0^q0)&1
pcmpeqb m4, m4
+ pxor m5, m1, m2 ; p0^q0
pxor m3, m4
+ pand m5, [pb_1] ; (p0^q0)&1
pavgb m3, m0 ; (p1 - q1 + 256)>>1
- pavgb m3, [pb_3] ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
pxor m4, m1
+ pavgb m3, [pb_3] ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
pavgb m4, m2 ; (q0 - p0 + 256)>>1
pavgb m3, m5
- paddusb m3, m4 ; d+128+33
mova m6, [pb_A1]
+ paddusb m3, m4 ; d+128+33
psubusb m6, m3
psubusb m3, [pb_A1]
pminub m6, m7
@@ -411,16 +411,16 @@ cglobal deblock_%2_luma_8_%1, 5,5
LOAD_MASK r2, r3
mov r3, r4mp
+ pcmpeqb m3, m3
movd m4, [r3] ; tc0
punpcklbw m4, m4
punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
mova [esp+%3], m4 ; tc
- pcmpeqb m3, m3
pcmpgtb m4, m3
+ mova m3, [r4] ; p2
pand m4, m7
mova [esp], m4 ; mask
- mova m3, [r4] ; p2
DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
pand m6, m4
pand m4, [esp+%3] ; tc
@@ -430,11 +430,10 @@ cglobal deblock_%2_luma_8_%1, 5,5
mova m4, [r0+2*r1] ; q2
DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
- mova m5, [esp] ; mask
- pand m6, m5
+ pand m6, [esp] ; mask
mova m5, [esp+%3] ; tc
- pand m5, m6
psubb m7, m6
+ pand m5, m6
mova m3, [r0+r1]
LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
@@ -482,10 +481,10 @@ cglobal deblock_h_luma_8_%1, 0,5
; transpose 16x4 -> original space (only the middle 4 rows were changed by the filter)
mov r0, r0mp
sub r0, 2
- lea r1, [r0+r4]
movq m0, [pix_tmp+0x10]
movq m1, [pix_tmp+0x20]
+ lea r1, [r0+r4]
movq m2, [pix_tmp+0x30]
movq m3, [pix_tmp+0x40]
TRANSPOSE8x4B_STORE PASS8ROWS(r0, r1, r3, r4)
diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h
index e2dffe1..e195e04 100644
--- a/libavcodec/x86/h264_i386.h
+++ b/libavcodec/x86/h264_i386.h
@@ -29,128 +29,121 @@
#ifndef AVCODEC_X86_H264_I386_H
#define AVCODEC_X86_H264_I386_H
+#include <stddef.h>
+
#include "libavcodec/cabac.h"
+#include "cabac.h"
//FIXME use some macros to avoid duplicating get_cabac (cannot be done yet
//as that would make optimization work hard)
-#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS)
+#if HAVE_7REGS && !defined(BROKEN_RELOCATIONS)
static int decode_significance_x86(CABACContext *c, int max_coeff,
uint8_t *significant_coeff_ctx_base,
int *index, x86_reg last_off){
void *end= significant_coeff_ctx_base + max_coeff - 1;
- int minusstart= -(int)significant_coeff_ctx_base;
- int minusindex= 4-(int)index;
- int coeff_count;
+ int minusstart= -(intptr_t)significant_coeff_ctx_base;
+ int minusindex= 4-(intptr_t)index;
+ int bit;
+ x86_reg coeff_count;
__asm__ volatile(
- "movl "RANGE "(%3), %%esi \n\t"
- "movl "LOW "(%3), %%ebx \n\t"
-
"2: \n\t"
- BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx",
- "%%bx", "%%esi", "%%eax", "%%al")
+ BRANCHLESS_GET_CABAC("%4", "(%1)", "%3",
+ "%w3", "%5", "%k0", "%b0", "%6")
- "test $1, %%edx \n\t"
+ "test $1, %4 \n\t"
" jz 3f \n\t"
- "add %7, %1 \n\t"
+ "add %10, %1 \n\t"
- BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx",
- "%%bx", "%%esi", "%%eax", "%%al")
+ BRANCHLESS_GET_CABAC("%4", "(%1)", "%3",
+ "%w3", "%5", "%k0", "%b0", "%6")
- "sub %7, %1 \n\t"
- "mov %2, %%"REG_a" \n\t"
- "movl %4, %%ecx \n\t"
+ "sub %10, %1 \n\t"
+ "mov %2, %0 \n\t"
+ "movl %7, %%ecx \n\t"
"add %1, %%"REG_c" \n\t"
- "movl %%ecx, (%%"REG_a") \n\t"
+ "movl %%ecx, (%0) \n\t"
- "test $1, %%edx \n\t"
+ "test $1, %4 \n\t"
" jnz 4f \n\t"
- "add $4, %%"REG_a" \n\t"
- "mov %%"REG_a", %2 \n\t"
+ "add"OPSIZE" $4, %2 \n\t"
"3: \n\t"
"add $1, %1 \n\t"
- "cmp %5, %1 \n\t"
+ "cmp %8, %1 \n\t"
" jb 2b \n\t"
- "mov %2, %%"REG_a" \n\t"
- "movl %4, %%ecx \n\t"
+ "mov %2, %0 \n\t"
+ "movl %7, %%ecx \n\t"
"add %1, %%"REG_c" \n\t"
- "movl %%ecx, (%%"REG_a") \n\t"
+ "movl %%ecx, (%0) \n\t"
"4: \n\t"
- "add %6, %%eax \n\t"
- "shr $2, %%eax \n\t"
-
- "movl %%esi, "RANGE "(%3) \n\t"
- "movl %%ebx, "LOW "(%3) \n\t"
- :"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index)
- :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off)
- : "%"REG_c, "%ebx", "%edx", "%esi", "memory"
+ "add %9, %k0 \n\t"
+ "shr $2, %k0 \n\t"
+ :"=&q"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index),
+ "+&r"(c->low), "=&r"(bit), "+&r"(c->range),
+ "+m"(c->bytestream)
+ :"m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off)
+ : "%"REG_c, "memory"
);
return coeff_count;
}
static int decode_significance_8x8_x86(CABACContext *c,
uint8_t *significant_coeff_ctx_base,
- int *index, x86_reg last_off, const uint8_t *sig_off){
- int minusindex= 4-(int)index;
- int coeff_count;
+ int *index, uint8_t *last_coeff_ctx_base, const uint8_t *sig_off){
+ int minusindex= 4-(intptr_t)index;
+ int bit;
+ x86_reg coeff_count;
x86_reg last=0;
+ x86_reg state;
__asm__ volatile(
- "movl "RANGE "(%3), %%esi \n\t"
- "movl "LOW "(%3), %%ebx \n\t"
-
- "mov %1, %%"REG_D" \n\t"
+ "mov %1, %6 \n\t"
"2: \n\t"
- "mov %6, %%"REG_a" \n\t"
- "movzbl (%%"REG_a", %%"REG_D"), %%edi \n\t"
- "add %5, %%"REG_D" \n\t"
+ "mov %10, %0 \n\t"
+ "movzbl (%0, %6), %k6 \n\t"
+ "add %9, %6 \n\t"
- BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%"REG_D")", "%%ebx",
- "%%bx", "%%esi", "%%eax", "%%al")
+ BRANCHLESS_GET_CABAC("%4", "(%6)", "%3",
+ "%w3", "%5", "%k0", "%b0", "%7")
- "mov %1, %%edi \n\t"
- "test $1, %%edx \n\t"
+ "mov %1, %k6 \n\t"
+ "test $1, %4 \n\t"
" jz 3f \n\t"
- "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t"
- "add %5, %%"REG_D" \n\t"
- "add %7, %%"REG_D" \n\t"
+ "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%k6), %k6\n\t"
+ "add %11, %6 \n\t"
- BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%"REG_D")", "%%ebx",
- "%%bx", "%%esi", "%%eax", "%%al")
+ BRANCHLESS_GET_CABAC("%4", "(%6)", "%3",
+ "%w3", "%5", "%k0", "%b0", "%7")
- "mov %2, %%"REG_a" \n\t"
- "mov %1, %%edi \n\t"
- "movl %%edi, (%%"REG_a") \n\t"
+ "mov %2, %0 \n\t"
+ "mov %1, %k6 \n\t"
+ "movl %k6, (%0) \n\t"
- "test $1, %%edx \n\t"
+ "test $1, %4 \n\t"
" jnz 4f \n\t"
- "add $4, %%"REG_a" \n\t"
- "mov %%"REG_a", %2 \n\t"
+ "add"OPSIZE" $4, %2 \n\t"
"3: \n\t"
- "addl $1, %%edi \n\t"
- "mov %%edi, %1 \n\t"
- "cmpl $63, %%edi \n\t"
+ "addl $1, %k6 \n\t"
+ "mov %k6, %1 \n\t"
+ "cmpl $63, %k6 \n\t"
" jb 2b \n\t"
- "mov %2, %%"REG_a" \n\t"
- "movl %%edi, (%%"REG_a") \n\t"
+ "mov %2, %0 \n\t"
+ "movl %k6, (%0) \n\t"
"4: \n\t"
- "addl %4, %%eax \n\t"
- "shr $2, %%eax \n\t"
-
- "movl %%esi, "RANGE "(%3) \n\t"
- "movl %%ebx, "LOW "(%3) \n\t"
- :"=&a"(coeff_count),"+m"(last), "+m"(index)
- :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off)
- : "%"REG_c, "%ebx", "%edx", "%esi", "%"REG_D, "memory"
+ "addl %8, %k0 \n\t"
+ "shr $2, %k0 \n\t"
+ :"=&q"(coeff_count),"+m"(last), "+m"(index), "+&r"(c->low), "=&r"(bit),
+ "+&r"(c->range), "=&r"(state), "+m"(c->bytestream)
+ :"m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_coeff_ctx_base)
+ : "%"REG_c, "memory"
);
return coeff_count;
}
-#endif /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE */
- /* !defined(BROKEN_RELOCATIONS) */
+#endif /* HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */
#endif /* AVCODEC_X86_H264_I386_H */
diff --git a/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm
index 4788da9..37c2c90 100644
--- a/libavcodec/x86/h264_idct.asm
+++ b/libavcodec/x86/h264_idct.asm
@@ -82,10 +82,10 @@ cglobal h264_idct_add_8_mmx, 3, 3, 0
RET
%macro IDCT8_1D 2
- mova m4, m5
mova m0, m1
- psraw m4, 1
psraw m1, 1
+ mova m4, m5
+ psraw m4, 1
paddw m4, m5
paddw m1, m0
paddw m4, m7
@@ -95,16 +95,16 @@ cglobal h264_idct_add_8_mmx, 3, 3, 0
psubw m0, m3
psubw m5, m3
+ psraw m3, 1
paddw m0, m7
psubw m5, m7
- psraw m3, 1
psraw m7, 1
psubw m0, m3
psubw m5, m7
- mova m3, m4
mova m7, m1
psraw m1, 2
+ mova m3, m4
psraw m3, 2
paddw m3, m0
psraw m0, 2
@@ -113,12 +113,12 @@ cglobal h264_idct_add_8_mmx, 3, 3, 0
psubw m0, m4
psubw m7, m5
- mova m4, m2
mova m5, m6
- psraw m4, 1
psraw m6, 1
- psubw m4, m5
+ mova m4, m2
+ psraw m4, 1
paddw m6, m2
+ psubw m4, m5
mova m2, %1
mova m5, %2
@@ -337,7 +337,7 @@ cglobal h264_idct8_add4_8_mmx, 5, 7, 0
test r6, r6
jz .skipblock
mov r6d, dword [r1+r5*4]
- lea r6, [r0+r6]
+ add r6, r0
add word [r2], 32
IDCT8_ADD_MMX_START r2 , rsp
IDCT8_ADD_MMX_START r2+8, rsp+64
@@ -391,7 +391,7 @@ cglobal h264_idct_add16_8_mmx2, 5, 7, 0
REP_RET
.no_dc
mov r6d, dword [r1+r5*4]
- lea r6, [r0+r6]
+ add r6, r0
IDCT4_ADD r6, r2, r3
.skipblock
inc r5
@@ -414,7 +414,7 @@ cglobal h264_idct_add16intra_8_mmx, 5, 7, 0
test r6, r6
jz .skipblock
mov r6d, dword [r1+r5*4]
- lea r6, [r0+r6]
+ add r6, r0
IDCT4_ADD r6, r2, r3
.skipblock
inc r5
@@ -456,7 +456,7 @@ cglobal h264_idct_add16intra_8_mmx2, 5, 7, 0
%define dst_regd r1d
%endif
mov dst_regd, dword [r1+r5*4]
- lea dst_reg, [r0+dst_reg]
+ add dst_reg, r0
DC_ADD_MMX2_OP movh, dst_reg, r3, r6
%ifndef ARCH_X86_64
mov r1, r1m
@@ -513,7 +513,7 @@ cglobal h264_idct8_add4_8_mmx2, 5, 7, 0
RET
.no_dc
mov r6d, dword [r1+r5*4]
- lea r6, [r0+r6]
+ add r6, r0
add word [r2], 32
IDCT8_ADD_MMX_START r2 , rsp
IDCT8_ADD_MMX_START r2+8, rsp+64
@@ -558,7 +558,7 @@ INIT_MMX
%define dst_regd r1d
%endif
mov dst_regd, dword [r1+r5*4]
- lea dst_reg, [r0+dst_reg]
+ add dst_reg, r0
DC_ADD_MMX2_OP mova, dst_reg, r3, r6
lea dst_reg, [dst_reg+r3*4]
DC_ADD_MMX2_OP mova, dst_reg, r3, r6
@@ -573,7 +573,7 @@ INIT_MMX
.no_dc
INIT_XMM
mov dst_regd, dword [r1+r5*4]
- lea dst_reg, [r0+dst_reg]
+ add dst_reg, r0
IDCT8_ADD_SSE dst_reg, r2, r3, r6
%ifndef ARCH_X86_64
mov r1, r1m
diff --git a/libavcodec/x86/h264_intrapred.asm b/libavcodec/x86/h264_intrapred.asm
index cbf3cf7..c1cd5c4 100644
--- a/libavcodec/x86/h264_intrapred.asm
+++ b/libavcodec/x86/h264_intrapred.asm
@@ -2611,12 +2611,11 @@ cglobal pred4x4_down_left_mmxext, 3,3
punpckldq m1, [r1]
movq m2, m1
movq m3, m1
- movq m4, m1
psllq m1, 8
pxor m2, m1
psrlq m2, 8
- pxor m3, m2
- PRED4x4_LOWPASS m0, m1, m3, m4, m5
+ pxor m2, m3
+ PRED4x4_LOWPASS m0, m1, m2, m3, m4
lea r1, [r0+r2*2]
psrlq m0, 8
movd [r0+r2*1], m0
diff --git a/libavcodec/x86/h264_intrapred_10bit.asm b/libavcodec/x86/h264_intrapred_10bit.asm
index 5cb593a..e14e31a 100644
--- a/libavcodec/x86/h264_intrapred_10bit.asm
+++ b/libavcodec/x86/h264_intrapred_10bit.asm
@@ -27,11 +27,23 @@
SECTION_RODATA
-SECTION .text
-
+cextern pw_16
+cextern pw_8
cextern pw_4
+cextern pw_2
cextern pw_1
+pw_m32101234: dw -3, -2, -1, 0, 1, 2, 3, 4
+pw_m3: times 8 dw -3
+pw_pixel_max: times 8 dw ((1 << 10)-1)
+pw_512: times 8 dw 512
+pd_17: times 4 dd 17
+pd_16: times 4 dd 16
+
+SECTION .text
+
+; dest, left, right, src
+; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
%macro PRED4x4_LOWPASS 4
paddw %2, %3
psrlw %2, 1
@@ -52,13 +64,11 @@ cglobal pred4x4_down_right_10_%1, 3,3
movq m3, [r0]
punpckhdq m1, m2
PALIGNR m3, m1, 10, m1
- mova m1, m3
movhps m4, [r1+r2*1-8]
- PALIGNR m3, m4, 14, m4
- mova m2, m3
+ PALIGNR m0, m3, m4, 14, m4
movhps m4, [r1+r2*2-8]
- PALIGNR m3, m4, 14, m4
- PRED4x4_LOWPASS m0, m3, m1, m2
+ PALIGNR m2, m0, m4, 14, m4
+ PRED4x4_LOWPASS m0, m2, m3, m0
movq [r1+r2*2], m0
psrldq m0, 2
movq [r1+r2*1], m0
@@ -92,22 +102,20 @@ cglobal pred4x4_vertical_right_10_%1, 3,3,6
pavgw m5, m0
movhps m1, [r0+r2*1-8]
PALIGNR m0, m1, 14, m1 ; ....t3t2t1t0ltl0
- mova m1, m0
movhps m2, [r0+r2*2-8]
- PALIGNR m0, m2, 14, m2 ; ..t3t2t1t0ltl0l1
- mova m2, m0
+ PALIGNR m1, m0, m2, 14, m2 ; ..t3t2t1t0ltl0l1
movhps m3, [r1+r2*1-8]
- PALIGNR m0, m3, 14, m3 ; t3t2t1t0ltl0l1l2
- PRED4x4_LOWPASS m3, m1, m0, m2
- pslldq m1, m3, 12
- psrldq m3, 4
+ PALIGNR m2, m1, m3, 14, m3 ; t3t2t1t0ltl0l1l2
+ PRED4x4_LOWPASS m1, m0, m2, m1
+ pslldq m0, m1, 12
+ psrldq m1, 4
movq [r0+r2*1], m5
- movq [r0+r2*2], m3
- PALIGNR m5, m1, 14, m2
- pslldq m1, 2
+ movq [r0+r2*2], m1
+ PALIGNR m5, m0, 14, m2
+ pslldq m0, 2
movq [r1+r2*1], m5
- PALIGNR m3, m1, 14, m1
- movq [r1+r2*2], m3
+ PALIGNR m1, m0, 14, m0
+ movq [r1+r2*2], m1
RET
%endmacro
@@ -140,9 +148,9 @@ cglobal pred4x4_horizontal_down_10_%1, 3,3
punpckhdq m1, m2 ; l0 l1 l2 l3
punpckhqdq m1, m0 ; t2 t1 t0 lt l0 l1 l2 l3
psrldq m0, m1, 4 ; .. .. t2 t1 t0 lt l0 l1
- psrldq m2, m1, 2 ; .. t2 t1 t0 lt l0 l1 l2
- pavgw m5, m1, m2
- PRED4x4_LOWPASS m3, m1, m0, m2
+ psrldq m3, m1, 2 ; .. t2 t1 t0 lt l0 l1 l2
+ pavgw m5, m1, m3
+ PRED4x4_LOWPASS m3, m1, m0, m3
punpcklwd m5, m3
psrldq m3, 8
PALIGNR m3, m5, 12, m4
@@ -208,17 +216,15 @@ cglobal pred4x4_dc_10_mmxext, 3,3
;-----------------------------------------------------------------------------
; void pred4x4_down_left(pixel *src, const pixel *topright, int stride)
;-----------------------------------------------------------------------------
-;TODO: more AVX here
%macro PRED4x4_DL 1
cglobal pred4x4_down_left_10_%1, 3,3
sub r0, r2
- movq m1, [r0]
- movhps m1, [r1]
- pslldq m5, m1, 2
- pxor m2, m5, m1
- psrldq m2, 2
- pxor m3, m1, m2
- PRED4x4_LOWPASS m0, m5, m3, m1
+ movq m0, [r0]
+ movhps m0, [r1]
+ psrldq m2, m0, 2
+ pslldq m3, m0, 2
+ pshufhw m2, m2, 10100100b
+ PRED4x4_LOWPASS m0, m3, m2, m0
lea r1, [r0+r2*2]
movhps [r1+r2*2], m0
psrldq m0, 2
@@ -245,10 +251,10 @@ cglobal pred4x4_vertical_left_10_%1, 3,3
sub r0, r2
movu m1, [r0]
movhps m1, [r1]
- psrldq m3, m1, 2
+ psrldq m0, m1, 2
psrldq m2, m1, 4
- pavgw m4, m3, m1
- PRED4x4_LOWPASS m0, m1, m2, m3
+ pavgw m4, m0, m1
+ PRED4x4_LOWPASS m0, m1, m2, m0
lea r1, [r0+r2*2]
movq [r0+r2*1], m4
movq [r0+r2*2], m0
@@ -286,13 +292,13 @@ cglobal pred4x4_horizontal_up_10_mmxext, 3,3
pavgw m2, m0
pshufw m5, m0, 11111110b
- PRED4x4_LOWPASS m3, m0, m5, m1
+ PRED4x4_LOWPASS m1, m0, m5, m1
movq m6, m2
- punpcklwd m6, m3
+ punpcklwd m6, m1
movq [r0+r2*1], m6
psrlq m2, 16
- psrlq m3, 16
- punpcklwd m2, m3
+ psrlq m1, 16
+ punpcklwd m2, m1
movq [r0+r2*2], m2
psrlq m2, 32
movd [r1+r2*1], m2
@@ -321,7 +327,7 @@ cglobal pred8x8_vertical_10_sse2, 2,2
;-----------------------------------------------------------------------------
INIT_XMM
cglobal pred8x8_horizontal_10_sse2, 2,3
- mov r2, 4
+ mov r2d, 4
.loop:
movq m0, [r0+r1*0-8]
movq m1, [r0+r1*1-8]
@@ -332,6 +338,871 @@ cglobal pred8x8_horizontal_10_sse2, 2,3
mova [r0+r1*0], m0
mova [r0+r1*1], m1
lea r0, [r0+r1*2]
- dec r2
+ dec r2d
+ jg .loop
+ REP_RET
+
+;-----------------------------------------------------------------------------
+; void predict_8x8_dc(pixel *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MOV8 2-3
+; sort of a hack, but it works
+%if mmsize==8
+ movq [%1+0], %2
+ movq [%1+8], %3
+%else
+ movdqa [%1], %2
+%endif
+%endmacro
+
+%macro PRED8x8_DC 2
+cglobal pred8x8_dc_10_%1, 2,6
+ sub r0, r1
+ pxor m4, m4
+ movq m0, [r0+0]
+ movq m1, [r0+8]
+%if mmsize==16
+ punpcklwd m0, m1
+ movhlps m1, m0
+ paddw m0, m1
+%else
+ pshufw m2, m0, 00001110b
+ pshufw m3, m1, 00001110b
+ paddw m0, m2
+ paddw m1, m3
+ punpcklwd m0, m1
+%endif
+ %2 m2, m0, 00001110b
+ paddw m0, m2
+
+ lea r5, [r1*3]
+ lea r4, [r0+r1*4]
+ movzx r2d, word [r0+r1*1-2]
+ movzx r3d, word [r0+r1*2-2]
+ add r2d, r3d
+ movzx r3d, word [r0+r5*1-2]
+ add r2d, r3d
+ movzx r3d, word [r4-2]
+ add r2d, r3d
+ movd m2, r2d ; s2
+
+ movzx r2d, word [r4+r1*1-2]
+ movzx r3d, word [r4+r1*2-2]
+ add r2d, r3d
+ movzx r3d, word [r4+r5*1-2]
+ add r2d, r3d
+ movzx r3d, word [r4+r1*4-2]
+ add r2d, r3d
+ movd m3, r2d ; s3
+
+ punpcklwd m2, m3
+ punpckldq m0, m2 ; s0, s1, s2, s3
+ %2 m3, m0, 11110110b ; s2, s1, s3, s3
+ %2 m0, m0, 01110100b ; s0, s1, s3, s1
+ paddw m0, m3
+ psrlw m0, 2
+ pavgw m0, m4 ; s0+s2, s1, s3, s1+s3
+%if mmsize==16
+ punpcklwd m0, m0
+ pshufd m3, m0, 11111010b
+ punpckldq m0, m0
+ SWAP 0,1
+%else
+ pshufw m1, m0, 0x00
+ pshufw m2, m0, 0x55
+ pshufw m3, m0, 0xaa
+ pshufw m4, m0, 0xff
+%endif
+ MOV8 r0+r1*1, m1, m2
+ MOV8 r0+r1*2, m1, m2
+ MOV8 r0+r5*1, m1, m2
+ MOV8 r0+r1*4, m1, m2
+ MOV8 r4+r1*1, m3, m4
+ MOV8 r4+r1*2, m3, m4
+ MOV8 r4+r5*1, m3, m4
+ MOV8 r4+r1*4, m3, m4
+ RET
+%endmacro
+
+INIT_MMX
+PRED8x8_DC mmxext, pshufw
+INIT_XMM
+PRED8x8_DC sse2 , pshuflw
+
+;-----------------------------------------------------------------------------
+; void pred8x8_top_dc(pixel *src, int stride)
+;-----------------------------------------------------------------------------
+INIT_XMM
+cglobal pred8x8_top_dc_10_sse2, 2,4
+ sub r0, r1
+ mova m0, [r0]
+ pshuflw m1, m0, 0x4e
+ pshufhw m1, m1, 0x4e
+ paddw m0, m1
+ pshuflw m1, m0, 0xb1
+ pshufhw m1, m1, 0xb1
+ paddw m0, m1
+ lea r2, [r1*3]
+ lea r3, [r0+r1*4]
+ paddw m0, [pw_2]
+ psrlw m0, 2
+ mova [r0+r1*1], m0
+ mova [r0+r1*2], m0
+ mova [r0+r2*1], m0
+ mova [r0+r1*4], m0
+ mova [r3+r1*1], m0
+ mova [r3+r1*2], m0
+ mova [r3+r2*1], m0
+ mova [r3+r1*4], m0
+ RET
+
+;-----------------------------------------------------------------------------
+; void pred8x8_plane(pixel *src, int stride)
+;-----------------------------------------------------------------------------
+INIT_XMM
+cglobal pred8x8_plane_10_sse2, 2,7,7
+ sub r0, r1
+ lea r2, [r1*3]
+ lea r3, [r0+r1*4]
+ mova m2, [r0]
+ pmaddwd m2, [pw_m32101234]
+ HADDD m2, m1
+ movd m0, [r0-4]
+ psrld m0, 14
+ psubw m2, m0 ; H
+ movd m0, [r3+r1*4-4]
+ movd m1, [r0+12]
+ paddw m0, m1
+ psllw m0, 4 ; 16*(src[7*stride-1] + src[-stride+7])
+ movzx r4d, word [r3+r1*1-2] ; src[4*stride-1]
+ movzx r5d, word [r0+r2*1-2] ; src[2*stride-1]
+ sub r4d, r5d
+ movzx r6d, word [r3+r1*2-2] ; src[5*stride-1]
+ movzx r5d, word [r0+r1*2-2] ; src[1*stride-1]
+ sub r6d, r5d
+ lea r4d, [r4+r6*2]
+ movzx r5d, word [r3+r2*1-2] ; src[6*stride-1]
+ movzx r6d, word [r0+r1*1-2] ; src[0*stride-1]
+ sub r5d, r6d
+ lea r5d, [r5*3]
+ add r4d, r5d
+ movzx r6d, word [r3+r1*4-2] ; src[7*stride-1]
+ movzx r5d, word [r0+r1*0-2] ; src[ -stride-1]
+ sub r6d, r5d
+ lea r4d, [r4+r6*4]
+ movd m3, r4d ; V
+ punpckldq m2, m3
+ pmaddwd m2, [pd_17]
+ paddd m2, [pd_16]
+ psrad m2, 5 ; b, c
+
+ mova m3, [pw_pixel_max]
+ pxor m1, m1
+ SPLATW m0, m0, 1
+ SPLATW m4, m2, 2
+ SPLATW m2, m2, 0
+ pmullw m2, [pw_m32101234] ; b
+ pmullw m5, m4, [pw_m3] ; c
+ paddw m5, [pw_16]
+ mov r2d, 8
+ add r0, r1
+.loop:
+ paddsw m6, m2, m5
+ paddsw m6, m0
+ psraw m6, 5
+ CLIPW m6, m1, m3
+ mova [r0], m6
+ paddw m5, m4
+ add r0, r1
+ dec r2d
jg .loop
REP_RET
+
+
+;-----------------------------------------------------------------------------
+; void pred8x8l_128_dc(pixel *src, int has_topleft, int has_topright, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED8x8L_128_DC 1
+cglobal pred8x8l_128_dc_10_%1, 4,4
+ mova m0, [pw_512] ; (1<<(BIT_DEPTH-1))
+ lea r1, [r3*3]
+ lea r2, [r0+r3*4]
+ MOV8 r0+r3*0, m0, m0
+ MOV8 r0+r3*1, m0, m0
+ MOV8 r0+r3*2, m0, m0
+ MOV8 r0+r1*1, m0, m0
+ MOV8 r2+r3*0, m0, m0
+ MOV8 r2+r3*1, m0, m0
+ MOV8 r2+r3*2, m0, m0
+ MOV8 r2+r1*1, m0, m0
+ RET
+%endmacro
+
+INIT_MMX
+PRED8x8L_128_DC mmxext
+INIT_XMM
+PRED8x8L_128_DC sse2
+
+;-----------------------------------------------------------------------------
+; void pred8x8l_top_dc(pixel *src, int has_topleft, int has_topright, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED8x8L_TOP_DC 1
+cglobal pred8x8l_top_dc_10_%1, 4,4,6
+ sub r0, r3
+ mova m0, [r0]
+ shr r1d, 14
+ shr r2d, 13
+ neg r1
+ pslldq m1, m0, 2
+ psrldq m2, m0, 2
+ pinsrw m1, [r0+r1], 0
+ pinsrw m2, [r0+r2+14], 7
+ lea r1, [r3*3]
+ lea r2, [r0+r3*4]
+ PRED4x4_LOWPASS m0, m2, m1, m0
+ HADDW m0, m1
+ paddw m0, [pw_4]
+ psrlw m0, 3
+ SPLATW m0, m0, 0
+ mova [r0+r3*1], m0
+ mova [r0+r3*2], m0
+ mova [r0+r1*1], m0
+ mova [r0+r3*4], m0
+ mova [r2+r3*1], m0
+ mova [r2+r3*2], m0
+ mova [r2+r1*1], m0
+ mova [r2+r3*4], m0
+ RET
+%endmacro
+
+INIT_XMM
+PRED8x8L_TOP_DC sse2
+%ifdef HAVE_AVX
+INIT_AVX
+PRED8x8L_TOP_DC avx
+%endif
+
+;-----------------------------------------------------------------------------
+;void pred8x8l_dc(pixel *src, int has_topleft, int has_topright, int stride)
+;-----------------------------------------------------------------------------
+;TODO: see if scalar is faster
+%macro PRED8x8L_DC 1
+cglobal pred8x8l_dc_10_%1, 4,6,6
+ sub r0, r3
+ lea r4, [r0+r3*4]
+ lea r5, [r3*3]
+ mova m0, [r0+r3*2-16]
+ punpckhwd m0, [r0+r3*1-16]
+ mova m1, [r4+r3*0-16]
+ punpckhwd m1, [r0+r5*1-16]
+ punpckhdq m1, m0
+ mova m2, [r4+r3*2-16]
+ punpckhwd m2, [r4+r3*1-16]
+ mova m3, [r4+r3*4-16]
+ punpckhwd m3, [r4+r5*1-16]
+ punpckhdq m3, m2
+ punpckhqdq m3, m1
+ mova m0, [r0]
+ shr r1d, 14
+ shr r2d, 13
+ neg r1
+ pslldq m1, m0, 2
+ psrldq m2, m0, 2
+ pinsrw m1, [r0+r1], 0
+ pinsrw m2, [r0+r2+14], 7
+ not r1
+ and r1, r3
+ pslldq m4, m3, 2
+ psrldq m5, m3, 2
+ pshuflw m4, m4, 11100101b
+ pinsrw m5, [r0+r1-2], 7
+ PRED4x4_LOWPASS m3, m4, m5, m3
+ PRED4x4_LOWPASS m0, m2, m1, m0
+ paddw m0, m3
+ HADDW m0, m1
+ paddw m0, [pw_8]
+ psrlw m0, 4
+ SPLATW m0, m0
+ mova [r0+r3*1], m0
+ mova [r0+r3*2], m0
+ mova [r0+r5*1], m0
+ mova [r0+r3*4], m0
+ mova [r4+r3*1], m0
+ mova [r4+r3*2], m0
+ mova [r4+r5*1], m0
+ mova [r4+r3*4], m0
+ RET
+%endmacro
+
+INIT_XMM
+PRED8x8L_DC sse2
+%ifdef HAVE_AVX
+INIT_AVX
+PRED8x8L_DC avx
+%endif
+
+;-----------------------------------------------------------------------------
+; void pred8x8l_vertical(pixel *src, int has_topleft, int has_topright, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED8x8L_VERTICAL 1
+cglobal pred8x8l_vertical_10_%1, 4,4,6
+ sub r0, r3
+ mova m0, [r0]
+ shr r1d, 14
+ shr r2d, 13
+ neg r1
+ pslldq m1, m0, 2
+ psrldq m2, m0, 2
+ pinsrw m1, [r0+r1], 0
+ pinsrw m2, [r0+r2+14], 7
+ lea r1, [r3*3]
+ lea r2, [r0+r3*4]
+ PRED4x4_LOWPASS m0, m2, m1, m0
+ mova [r0+r3*1], m0
+ mova [r0+r3*2], m0
+ mova [r0+r1*1], m0
+ mova [r0+r3*4], m0
+ mova [r2+r3*1], m0
+ mova [r2+r3*2], m0
+ mova [r2+r1*1], m0
+ mova [r2+r3*4], m0
+ RET
+%endmacro
+
+INIT_XMM
+PRED8x8L_VERTICAL sse2
+%ifdef HAVE_AVX
+INIT_AVX
+PRED8x8L_VERTICAL avx
+%endif
+
+;-----------------------------------------------------------------------------
+; void pred8x8l_horizontal(uint8_t *src, int has_topleft, int has_topright, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED8x8L_HORIZONTAL 1
+cglobal pred8x8l_horizontal_10_%1, 4,4,5
+ mova m0, [r0-16]
+ shr r1d, 14
+ dec r1
+ and r1, r3
+ sub r1, r3
+ punpckhwd m0, [r0+r1-16]
+ mova m1, [r0+r3*2-16]
+ punpckhwd m1, [r0+r3*1-16]
+ lea r2, [r0+r3*4]
+ lea r1, [r3*3]
+ punpckhdq m1, m0
+ mova m2, [r2+r3*0-16]
+ punpckhwd m2, [r0+r1-16]
+ mova m3, [r2+r3*2-16]
+ punpckhwd m3, [r2+r3*1-16]
+ punpckhdq m3, m2
+ punpckhqdq m3, m1
+ PALIGNR m4, m3, [r2+r1-16], 14, m0
+ pslldq m0, m4, 2
+ pshuflw m0, m0, 11100101b
+ PRED4x4_LOWPASS m4, m3, m0, m4
+ punpckhwd m3, m4, m4
+ punpcklwd m4, m4
+ pshufd m0, m3, 0xff
+ pshufd m1, m3, 0xaa
+ pshufd m2, m3, 0x55
+ pshufd m3, m3, 0x00
+ mova [r0+r3*0], m0
+ mova [r0+r3*1], m1
+ mova [r0+r3*2], m2
+ mova [r0+r1*1], m3
+ pshufd m0, m4, 0xff
+ pshufd m1, m4, 0xaa
+ pshufd m2, m4, 0x55
+ pshufd m3, m4, 0x00
+ mova [r2+r3*0], m0
+ mova [r2+r3*1], m1
+ mova [r2+r3*2], m2
+ mova [r2+r1*1], m3
+ RET
+%endmacro
+
+INIT_XMM
+%define PALIGNR PALIGNR_MMX
+PRED8x8L_HORIZONTAL sse2
+%define PALIGNR PALIGNR_SSSE3
+PRED8x8L_HORIZONTAL ssse3
+%ifdef HAVE_AVX
+INIT_AVX
+PRED8x8L_HORIZONTAL avx
+%endif
+
+;-----------------------------------------------------------------------------
+;void pred8x8l_down_left(pixel *src, int has_topleft, int has_topright, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED8x8L_DOWN_LEFT 1
+cglobal pred8x8l_down_left_10_%1, 4,4,7
+ sub r0, r3
+ mova m3, [r0]
+ shr r1d, 14
+ neg r1
+ shr r2d, 13
+ pslldq m1, m3, 2
+ psrldq m2, m3, 2
+ pinsrw m1, [r0+r1], 0
+ pinsrw m2, [r0+r2+14], 7
+ PRED4x4_LOWPASS m6, m2, m1, m3
+ jz .fix_tr ; flags from shr r2d
+ mova m1, [r0+16]
+ psrldq m5, m1, 2
+ PALIGNR m2, m1, m3, 14, m3
+ pshufhw m5, m5, 10100100b
+ PRED4x4_LOWPASS m1, m2, m5, m1
+.do_topright:
+ lea r1, [r3*3]
+ psrldq m5, m1, 14
+ lea r2, [r0+r3*4]
+ PALIGNR m2, m1, m6, 2, m0
+ PALIGNR m3, m1, m6, 14, m0
+ PALIGNR m5, m1, 2, m0
+ pslldq m4, m6, 2
+ PRED4x4_LOWPASS m6, m4, m2, m6
+ PRED4x4_LOWPASS m1, m3, m5, m1
+ mova [r2+r3*4], m1
+ PALIGNR m1, m6, 14, m2
+ pslldq m6, 2
+ mova [r2+r1*1], m1
+ PALIGNR m1, m6, 14, m2
+ pslldq m6, 2
+ mova [r2+r3*2], m1
+ PALIGNR m1, m6, 14, m2
+ pslldq m6, 2
+ mova [r2+r3*1], m1
+ PALIGNR m1, m6, 14, m2
+ pslldq m6, 2
+ mova [r0+r3*4], m1
+ PALIGNR m1, m6, 14, m2
+ pslldq m6, 2
+ mova [r0+r1*1], m1
+ PALIGNR m1, m6, 14, m2
+ pslldq m6, 2
+ mova [r0+r3*2], m1
+ PALIGNR m1, m6, 14, m6
+ mova [r0+r3*1], m1
+ RET
+.fix_tr:
+ punpckhwd m3, m3
+ pshufd m1, m3, 0xFF
+ jmp .do_topright
+%endmacro
+
+INIT_XMM
+%define PALIGNR PALIGNR_MMX
+PRED8x8L_DOWN_LEFT sse2
+%define PALIGNR PALIGNR_SSSE3
+PRED8x8L_DOWN_LEFT ssse3
+%ifdef HAVE_AVX
+INIT_AVX
+PRED8x8L_DOWN_LEFT avx
+%endif
+
+;-----------------------------------------------------------------------------
+;void pred8x8l_down_right(pixel *src, int has_topleft, int has_topright, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED8x8L_DOWN_RIGHT 1
+; standard forbids this when has_topleft is false
+; no need to check
+cglobal pred8x8l_down_right_10_%1, 4,5,8
+ sub r0, r3
+ lea r4, [r0+r3*4]
+ lea r1, [r3*3]
+ mova m0, [r0+r3*1-16]
+ punpckhwd m0, [r0+r3*0-16]
+ mova m1, [r0+r1*1-16]
+ punpckhwd m1, [r0+r3*2-16]
+ punpckhdq m1, m0
+ mova m2, [r4+r3*1-16]
+ punpckhwd m2, [r4+r3*0-16]
+ mova m3, [r4+r1*1-16]
+ punpckhwd m3, [r4+r3*2-16]
+ punpckhdq m3, m2
+ punpckhqdq m3, m1
+ mova m0, [r4+r3*4-16]
+ mova m1, [r0]
+ PALIGNR m4, m3, m0, 14, m0
+ PALIGNR m1, m3, 2, m2
+ pslldq m0, m4, 2
+ pshuflw m0, m0, 11100101b
+ PRED4x4_LOWPASS m6, m1, m4, m3
+ PRED4x4_LOWPASS m4, m3, m0, m4
+ mova m3, [r0]
+ shr r2d, 13
+ pslldq m1, m3, 2
+ psrldq m2, m3, 2
+ pinsrw m1, [r0-2], 0
+ pinsrw m2, [r0+r2+14], 7
+ PRED4x4_LOWPASS m3, m2, m1, m3
+ PALIGNR m2, m3, m6, 2, m0
+ PALIGNR m5, m3, m6, 14, m0
+ psrldq m7, m3, 2
+ PRED4x4_LOWPASS m6, m4, m2, m6
+ PRED4x4_LOWPASS m3, m5, m7, m3
+ mova [r4+r3*4], m6
+ PALIGNR m3, m6, 14, m2
+ pslldq m6, 2
+ mova [r0+r3*1], m3
+ PALIGNR m3, m6, 14, m2
+ pslldq m6, 2
+ mova [r0+r3*2], m3
+ PALIGNR m3, m6, 14, m2
+ pslldq m6, 2
+ mova [r0+r1*1], m3
+ PALIGNR m3, m6, 14, m2
+ pslldq m6, 2
+ mova [r0+r3*4], m3
+ PALIGNR m3, m6, 14, m2
+ pslldq m6, 2
+ mova [r4+r3*1], m3
+ PALIGNR m3, m6, 14, m2
+ pslldq m6, 2
+ mova [r4+r3*2], m3
+ PALIGNR m3, m6, 14, m6
+ mova [r4+r1*1], m3
+ RET
+%endmacro
+
+INIT_XMM
+%define PALIGNR PALIGNR_MMX
+PRED8x8L_DOWN_RIGHT sse2
+%define PALIGNR PALIGNR_SSSE3
+PRED8x8L_DOWN_RIGHT ssse3
+%ifdef HAVE_AVX
+INIT_AVX
+PRED8x8L_DOWN_RIGHT avx
+%endif
+
+;-----------------------------------------------------------------------------
+; void pred8x8l_vertical_right(pixel *src, int has_topleft, int has_topright, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED8x8L_VERTICAL_RIGHT 1
+; likewise with 8x8l_down_right
+cglobal pred8x8l_vertical_right_10_%1, 4,5,7
+ sub r0, r3
+ lea r4, [r0+r3*4]
+ lea r1, [r3*3]
+ mova m0, [r0+r3*1-16]
+ punpckhwd m0, [r0+r3*0-16]
+ mova m1, [r0+r1*1-16]
+ punpckhwd m1, [r0+r3*2-16]
+ punpckhdq m1, m0
+ mova m2, [r4+r3*1-16]
+ punpckhwd m2, [r4+r3*0-16]
+ mova m3, [r4+r1*1-16]
+ punpckhwd m3, [r4+r3*2-16]
+ punpckhdq m3, m2
+ punpckhqdq m3, m1
+ mova m0, [r4+r3*4-16]
+ mova m1, [r0]
+ PALIGNR m4, m3, m0, 14, m0
+ PALIGNR m1, m3, 2, m2
+ PRED4x4_LOWPASS m3, m1, m4, m3
+ mova m2, [r0]
+ shr r2d, 13
+ pslldq m1, m2, 2
+ psrldq m5, m2, 2
+ pinsrw m1, [r0-2], 0
+ pinsrw m5, [r0+r2+14], 7
+ PRED4x4_LOWPASS m2, m5, m1, m2
+ PALIGNR m6, m2, m3, 12, m1
+ PALIGNR m5, m2, m3, 14, m0
+ PRED4x4_LOWPASS m0, m6, m2, m5
+ pavgw m2, m5
+ mova [r0+r3*2], m0
+ mova [r0+r3*1], m2
+ pslldq m6, m3, 4
+ pslldq m1, m3, 2
+ PRED4x4_LOWPASS m1, m3, m6, m1
+ PALIGNR m2, m1, 14, m4
+ mova [r0+r1*1], m2
+ pslldq m1, 2
+ PALIGNR m0, m1, 14, m3
+ mova [r0+r3*4], m0
+ pslldq m1, 2
+ PALIGNR m2, m1, 14, m4
+ mova [r4+r3*1], m2
+ pslldq m1, 2
+ PALIGNR m0, m1, 14, m3
+ mova [r4+r3*2], m0
+ pslldq m1, 2
+ PALIGNR m2, m1, 14, m4
+ mova [r4+r1*1], m2
+ pslldq m1, 2
+ PALIGNR m0, m1, 14, m1
+ mova [r4+r3*4], m0
+ RET
+%endmacro
+
+INIT_XMM
+%define PALIGNR PALIGNR_MMX
+PRED8x8L_VERTICAL_RIGHT sse2
+%define PALIGNR PALIGNR_SSSE3
+PRED8x8L_VERTICAL_RIGHT ssse3
+%ifdef HAVE_AVX
+INIT_AVX
+PRED8x8L_VERTICAL_RIGHT avx
+%endif
+
+;-----------------------------------------------------------------------------
+; void pred8x8l_horizontal_up(pixel *src, int has_topleft, int has_topright, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED8x8L_HORIZONTAL_UP 1
+cglobal pred8x8l_horizontal_up_10_%1, 4,4,6
+ mova m0, [r0+r3*0-16]
+ punpckhwd m0, [r0+r3*1-16]
+ shr r1d, 14
+ dec r1
+ and r1, r3
+ sub r1, r3
+ mova m4, [r0+r1*1-16]
+ lea r1, [r3*3]
+ lea r2, [r0+r3*4]
+ mova m1, [r0+r3*2-16]
+ punpckhwd m1, [r0+r1*1-16]
+ punpckhdq m0, m1
+ mova m2, [r2+r3*0-16]
+ punpckhwd m2, [r2+r3*1-16]
+ mova m3, [r2+r3*2-16]
+ punpckhwd m3, [r2+r1*1-16]
+ punpckhdq m2, m3
+ punpckhqdq m0, m2
+ PALIGNR m1, m0, m4, 14, m4
+ psrldq m2, m0, 2
+ pshufhw m2, m2, 10100100b
+ PRED4x4_LOWPASS m0, m1, m2, m0
+ psrldq m1, m0, 2
+ psrldq m2, m0, 4
+ pshufhw m1, m1, 10100100b
+ pshufhw m2, m2, 01010100b
+ pavgw m4, m0, m1
+ PRED4x4_LOWPASS m1, m2, m0, m1
+ punpckhwd m5, m4, m1
+ punpcklwd m4, m1
+ mova [r2+r3*0], m5
+ mova [r0+r3*0], m4
+ pshufd m0, m5, 11111001b
+ pshufd m1, m5, 11111110b
+ pshufd m2, m5, 11111111b
+ mova [r2+r3*1], m0
+ mova [r2+r3*2], m1
+ mova [r2+r1*1], m2
+ PALIGNR m2, m5, m4, 4, m0
+ PALIGNR m3, m5, m4, 8, m1
+ PALIGNR m5, m5, m4, 12, m4
+ mova [r0+r3*1], m2
+ mova [r0+r3*2], m3
+ mova [r0+r1*1], m5
+ RET
+%endmacro
+
+INIT_XMM
+%define PALIGNR PALIGNR_MMX
+PRED8x8L_HORIZONTAL_UP sse2
+%define PALIGNR PALIGNR_SSSE3
+PRED8x8L_HORIZONTAL_UP ssse3
+%ifdef HAVE_AVX
+INIT_AVX
+PRED8x8L_HORIZONTAL_UP avx
+%endif
+
+
+;-----------------------------------------------------------------------------
+; void pred16x16_vertical(pixel *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MOV16 3-5
+ mova [%1+ 0], %2
+ mova [%1+mmsize], %3
+%if mmsize==8
+ mova [%1+ 16], %4
+ mova [%1+ 24], %5
+%endif
+%endmacro
+
+%macro PRED16x16_VERTICAL 1
+cglobal pred16x16_vertical_10_%1, 2,3
+ sub r0, r1
+ mov r2d, 8
+ mova m0, [r0+ 0]
+ mova m1, [r0+mmsize]
+%if mmsize==8
+ mova m2, [r0+16]
+ mova m3, [r0+24]
+%endif
+.loop:
+ MOV16 r0+r1*1, m0, m1, m2, m3
+ MOV16 r0+r1*2, m0, m1, m2, m3
+ lea r0, [r0+r1*2]
+ dec r2d
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_MMX
+PRED16x16_VERTICAL mmxext
+INIT_XMM
+PRED16x16_VERTICAL sse2
+
+;-----------------------------------------------------------------------------
+; void pred16x16_horizontal(pixel *src, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED16x16_HORIZONTAL 1
+cglobal pred16x16_horizontal_10_%1, 2,3
+ mov r2d, 8
+.vloop:
+ movd m0, [r0+r1*0-4]
+ movd m1, [r0+r1*1-4]
+ SPLATW m0, m0, 1
+ SPLATW m1, m1, 1
+ MOV16 r0+r1*0, m0, m0, m0, m0
+ MOV16 r0+r1*1, m1, m1, m1, m1
+ lea r0, [r0+r1*2]
+ dec r2d
+ jg .vloop
+ REP_RET
+%endmacro
+
+INIT_MMX
+PRED16x16_HORIZONTAL mmxext
+INIT_XMM
+PRED16x16_HORIZONTAL sse2
+
+;-----------------------------------------------------------------------------
+; void pred16x16_dc(pixel *src, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED16x16_DC 1
+cglobal pred16x16_dc_10_%1, 2,6
+ mov r5, r0
+ sub r0, r1
+ mova m0, [r0+0]
+ paddw m0, [r0+mmsize]
+%if mmsize==8
+ paddw m0, [r0+16]
+ paddw m0, [r0+24]
+%endif
+ HADDW m0, m2
+
+ lea r0, [r0+r1-2]
+ movzx r3d, word [r0]
+ movzx r4d, word [r0+r1]
+%rep 7
+ lea r0, [r0+r1*2]
+ movzx r2d, word [r0]
+ add r3d, r2d
+ movzx r2d, word [r0+r1]
+ add r4d, r2d
+%endrep
+ lea r3d, [r3+r4+16]
+
+ movd m1, r3d
+ paddw m0, m1
+ psrlw m0, 5
+ SPLATW m0, m0
+ mov r3d, 8
+.loop:
+ MOV16 r5+r1*0, m0, m0, m0, m0
+ MOV16 r5+r1*1, m0, m0, m0, m0
+ lea r5, [r5+r1*2]
+ dec r3d
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_MMX
+PRED16x16_DC mmxext
+INIT_XMM
+PRED16x16_DC sse2
+
+;-----------------------------------------------------------------------------
+; void pred16x16_top_dc(pixel *src, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED16x16_TOP_DC 1
+cglobal pred16x16_top_dc_10_%1, 2,3
+ sub r0, r1
+ mova m0, [r0+0]
+ paddw m0, [r0+mmsize]
+%if mmsize==8
+ paddw m0, [r0+16]
+ paddw m0, [r0+24]
+%endif
+ HADDW m0, m2
+
+ SPLATW m0, m0
+ paddw m0, [pw_8]
+ psrlw m0, 4
+ mov r2d, 8
+.loop:
+ MOV16 r0+r1*1, m0, m0, m0, m0
+ MOV16 r0+r1*2, m0, m0, m0, m0
+ lea r0, [r0+r1*2]
+ dec r2d
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_MMX
+PRED16x16_TOP_DC mmxext
+INIT_XMM
+PRED16x16_TOP_DC sse2
+
+;-----------------------------------------------------------------------------
+; void pred16x16_left_dc(pixel *src, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED16x16_LEFT_DC 1
+cglobal pred16x16_left_dc_10_%1, 2,6
+ mov r5, r0
+
+ sub r0, 2
+ movzx r3d, word [r0]
+ movzx r4d, word [r0+r1]
+%rep 7
+ lea r0, [r0+r1*2]
+ movzx r2d, word [r0]
+ add r3d, r2d
+ movzx r2d, word [r0+r1]
+ add r4d, r2d
+%endrep
+ lea r3d, [r3+r4+8]
+ shr r3d, 4
+
+ movd m0, r3d
+ SPLATW m0, m0
+ mov r3d, 8
+.loop:
+ MOV16 r5+r1*0, m0, m0, m0, m0
+ MOV16 r5+r1*1, m0, m0, m0, m0
+ lea r5, [r5+r1*2]
+ dec r3d
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_MMX
+PRED16x16_LEFT_DC mmxext
+INIT_XMM
+PRED16x16_LEFT_DC sse2
+
+;-----------------------------------------------------------------------------
+; void pred16x16_128_dc(pixel *src, int stride)
+;-----------------------------------------------------------------------------
+%macro PRED16x16_128_DC 1
+cglobal pred16x16_128_dc_10_%1, 2,3
+ mova m0, [pw_512]
+ mov r2d, 8
+.loop:
+ MOV16 r0+r1*0, m0, m0, m0, m0
+ MOV16 r0+r1*1, m0, m0, m0, m0
+ lea r0, [r0+r1*2]
+ dec r2d
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_MMX
+PRED16x16_128_DC mmxext
+INIT_XMM
+PRED16x16_128_DC sse2
diff --git a/libavcodec/x86/h264_intrapred_init.c b/libavcodec/x86/h264_intrapred_init.c
index 9d6726c..41e611e 100644
--- a/libavcodec/x86/h264_intrapred_init.c
+++ b/libavcodec/x86/h264_intrapred_init.c
@@ -43,9 +43,56 @@ PRED4x4(horizontal_down, 10, avx)
#define PRED8x8(TYPE, DEPTH, OPT) \
void ff_pred8x8_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, int stride);
+PRED8x8(dc, 10, mmxext)
+PRED8x8(dc, 10, sse2)
+PRED8x8(top_dc, 10, sse2)
+PRED8x8(plane, 10, sse2)
PRED8x8(vertical, 10, sse2)
PRED8x8(horizontal, 10, sse2)
+#define PRED8x8L(TYPE, DEPTH, OPT)\
+void ff_pred8x8l_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, int has_topleft, int has_topright, int stride);
+
+PRED8x8L(dc, 10, sse2)
+PRED8x8L(dc, 10, avx)
+PRED8x8L(128_dc, 10, mmxext)
+PRED8x8L(128_dc, 10, sse2)
+PRED8x8L(top_dc, 10, sse2)
+PRED8x8L(top_dc, 10, avx)
+PRED8x8L(vertical, 10, sse2)
+PRED8x8L(vertical, 10, avx)
+PRED8x8L(horizontal, 10, sse2)
+PRED8x8L(horizontal, 10, ssse3)
+PRED8x8L(horizontal, 10, avx)
+PRED8x8L(down_left, 10, sse2)
+PRED8x8L(down_left, 10, ssse3)
+PRED8x8L(down_left, 10, avx)
+PRED8x8L(down_right, 10, sse2)
+PRED8x8L(down_right, 10, ssse3)
+PRED8x8L(down_right, 10, avx)
+PRED8x8L(vertical_right, 10, sse2)
+PRED8x8L(vertical_right, 10, ssse3)
+PRED8x8L(vertical_right, 10, avx)
+PRED8x8L(horizontal_up, 10, sse2)
+PRED8x8L(horizontal_up, 10, ssse3)
+PRED8x8L(horizontal_up, 10, avx)
+
+#define PRED16x16(TYPE, DEPTH, OPT)\
+void ff_pred16x16_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, int stride);
+
+PRED16x16(dc, 10, mmxext)
+PRED16x16(dc, 10, sse2)
+PRED16x16(top_dc, 10, mmxext)
+PRED16x16(top_dc, 10, sse2)
+PRED16x16(128_dc, 10, mmxext)
+PRED16x16(128_dc, 10, sse2)
+PRED16x16(left_dc, 10, mmxext)
+PRED16x16(left_dc, 10, sse2)
+PRED16x16(vertical, 10, mmxext)
+PRED16x16(vertical, 10, sse2)
+PRED16x16(horizontal, 10, mmxext)
+PRED16x16(horizontal, 10, sse2)
+
void ff_pred16x16_vertical_mmx (uint8_t *src, int stride);
void ff_pred16x16_vertical_sse (uint8_t *src, int stride);
void ff_pred16x16_horizontal_mmx (uint8_t *src, int stride);
@@ -120,23 +167,26 @@ void ff_pred4x4_tm_vp8_mmxext (uint8_t *src, const uint8_t *topright, int s
void ff_pred4x4_tm_vp8_ssse3 (uint8_t *src, const uint8_t *topright, int stride);
void ff_pred4x4_vertical_vp8_mmxext(uint8_t *src, const uint8_t *topright, int stride);
-void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth)
+void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc)
{
+#if HAVE_YASM
int mm_flags = av_get_cpu_flags();
-#if HAVE_YASM
if (bit_depth == 8) {
if (mm_flags & AV_CPU_FLAG_MMX) {
h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_mmx;
h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_mmx;
- h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x8_vertical_mmx;
- h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_mmx;
+ if (chroma_format_idc == 1) {
+ h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x8_vertical_mmx;
+ h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_mmx;
+ }
if (codec_id == CODEC_ID_VP8) {
h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_mmx;
h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_mmx;
h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_mmx;
} else {
- h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_mmx;
+ if (chroma_format_idc == 1)
+ h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_mmx;
if (codec_id == CODEC_ID_SVQ3) {
h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_mmx;
} else if (codec_id == CODEC_ID_RV40) {
@@ -150,7 +200,8 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
if (mm_flags & AV_CPU_FLAG_MMX2) {
h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_mmxext;
h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_mmxext;
- h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_mmxext;
+ if (chroma_format_idc == 1)
+ h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_mmxext;
h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_mmxext;
h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_mmxext;
h->pred8x8l [HOR_PRED ] = ff_pred8x8l_horizontal_mmxext;
@@ -174,8 +225,10 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
h->pred4x4 [HOR_UP_PRED ] = ff_pred4x4_horizontal_up_mmxext;
}
if (codec_id == CODEC_ID_SVQ3 || codec_id == CODEC_ID_H264) {
- h->pred8x8 [TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_mmxext;
- h->pred8x8 [DC_PRED8x8 ] = ff_pred8x8_dc_mmxext;
+ if (chroma_format_idc == 1) {
+ h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_mmxext;
+ h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_mmxext;
+ }
}
if (codec_id == CODEC_ID_VP8) {
h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_mmxext;
@@ -184,7 +237,8 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_mmxext;
h->pred4x4 [VERT_PRED ] = ff_pred4x4_vertical_vp8_mmxext;
} else {
- h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_mmx2;
+ if (chroma_format_idc == 1)
+ h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_mmx2;
if (codec_id == CODEC_ID_SVQ3) {
h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_svq3_mmx2;
} else if (codec_id == CODEC_ID_RV40) {
@@ -210,7 +264,8 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_sse2;
h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_sse2;
} else {
- h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_plane_sse2;
+ if (chroma_format_idc == 1)
+ h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_sse2;
if (codec_id == CODEC_ID_SVQ3) {
h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_sse2;
} else if (codec_id == CODEC_ID_RV40) {
@@ -224,7 +279,8 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
if (mm_flags & AV_CPU_FLAG_SSSE3) {
h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_ssse3;
h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_ssse3;
- h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_ssse3;
+ if (chroma_format_idc == 1)
+ h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_ssse3;
h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_ssse3;
h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_ssse3;
h->pred8x8l [HOR_PRED ] = ff_pred8x8l_horizontal_ssse3;
@@ -239,7 +295,8 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_ssse3;
h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_ssse3;
} else {
- h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_ssse3;
+ if (chroma_format_idc == 1)
+ h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_ssse3;
if (codec_id == CODEC_ID_SVQ3) {
h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_ssse3;
} else if (codec_id == CODEC_ID_RV40) {
@@ -253,6 +310,18 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
if (mm_flags & AV_CPU_FLAG_MMX2) {
h->pred4x4[DC_PRED ] = ff_pred4x4_dc_10_mmxext;
h->pred4x4[HOR_UP_PRED ] = ff_pred4x4_horizontal_up_10_mmxext;
+
+ if (chroma_format_idc == 1)
+ h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_10_mmxext;
+
+ h->pred8x8l[DC_128_PRED ] = ff_pred8x8l_128_dc_10_mmxext;
+
+ h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_10_mmxext;
+ h->pred16x16[TOP_DC_PRED8x8 ] = ff_pred16x16_top_dc_10_mmxext;
+ h->pred16x16[DC_128_PRED8x8 ] = ff_pred16x16_128_dc_10_mmxext;
+ h->pred16x16[LEFT_DC_PRED8x8 ] = ff_pred16x16_left_dc_10_mmxext;
+ h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_10_mmxext;
+ h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_10_mmxext;
}
if (mm_flags & AV_CPU_FLAG_SSE2) {
h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_sse2;
@@ -261,20 +330,58 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_sse2;
h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_sse2;
- h->pred8x8[VERT_PRED8x8 ] = ff_pred8x8_vertical_10_sse2;
- h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_10_sse2;
+ if (chroma_format_idc == 1) {
+ h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_10_sse2;
+ h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_10_sse2;
+ h->pred8x8[PLANE_PRED8x8 ] = ff_pred8x8_plane_10_sse2;
+ h->pred8x8[VERT_PRED8x8 ] = ff_pred8x8_vertical_10_sse2;
+ h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_10_sse2;
+ }
+
+ h->pred8x8l[VERT_PRED ] = ff_pred8x8l_vertical_10_sse2;
+ h->pred8x8l[HOR_PRED ] = ff_pred8x8l_horizontal_10_sse2;
+ h->pred8x8l[DC_PRED ] = ff_pred8x8l_dc_10_sse2;
+ h->pred8x8l[DC_128_PRED ] = ff_pred8x8l_128_dc_10_sse2;
+ h->pred8x8l[TOP_DC_PRED ] = ff_pred8x8l_top_dc_10_sse2;
+ h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_sse2;
+ h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_sse2;
+ h->pred8x8l[VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_10_sse2;
+ h->pred8x8l[HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_10_sse2;
+
+ h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_10_sse2;
+ h->pred16x16[TOP_DC_PRED8x8 ] = ff_pred16x16_top_dc_10_sse2;
+ h->pred16x16[DC_128_PRED8x8 ] = ff_pred16x16_128_dc_10_sse2;
+ h->pred16x16[LEFT_DC_PRED8x8 ] = ff_pred16x16_left_dc_10_sse2;
+ h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_10_sse2;
+ h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_10_sse2;
}
if (mm_flags & AV_CPU_FLAG_SSSE3) {
h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_ssse3;
h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_ssse3;
h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_ssse3;
+
+ h->pred8x8l[HOR_PRED ] = ff_pred8x8l_horizontal_10_ssse3;
+ h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_ssse3;
+ h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_ssse3;
+ h->pred8x8l[VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_10_ssse3;
+ h->pred8x8l[HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_10_ssse3;
}
#if HAVE_AVX
if (mm_flags & AV_CPU_FLAG_AVX) {
h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_avx;
h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_avx;
+ h->pred4x4[VERT_LEFT_PRED ] = ff_pred4x4_vertical_left_10_avx;
h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_avx;
h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_avx;
+
+ h->pred8x8l[VERT_PRED ] = ff_pred8x8l_vertical_10_avx;
+ h->pred8x8l[HOR_PRED ] = ff_pred8x8l_horizontal_10_avx;
+ h->pred8x8l[DC_PRED ] = ff_pred8x8l_dc_10_avx;
+ h->pred8x8l[TOP_DC_PRED ] = ff_pred8x8l_top_dc_10_avx;
+ h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_avx;
+ h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_avx;
+ h->pred8x8l[VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_10_avx;
+ h->pred8x8l[HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_10_avx;
}
#endif /* HAVE_AVX */
}
diff --git a/libavcodec/x86/h264_qpel_10bit.asm b/libavcodec/x86/h264_qpel_10bit.asm
new file mode 100644
index 0000000..15dd72c
--- /dev/null
+++ b/libavcodec/x86/h264_qpel_10bit.asm
@@ -0,0 +1,891 @@
+;*****************************************************************************
+;* MMX/SSE2/AVX-optimized 10-bit H.264 qpel code
+;*****************************************************************************
+;* Copyright (C) 2011 x264 project
+;*
+;* Authors: Daniel Kang <daniel.d.kang at gmail.com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "x86inc.asm"
+%include "x86util.asm"
+
+SECTION_RODATA 32
+
+cextern pw_16
+cextern pw_1
+cextern pb_0
+
+pw_pixel_max: times 8 dw ((1 << 10)-1)
+
+pad10: times 8 dw 10*1023
+pad20: times 8 dw 20*1023
+pad30: times 8 dw 30*1023
+depad: times 4 dd 32*20*1023 + 512
+depad2: times 8 dw 20*1023 + 16*1022 + 16
+unpad: times 8 dw 16*1022/32 ; needs to be mod 16
+
+tap1: times 4 dw 1, -5
+tap2: times 4 dw 20, 20
+tap3: times 4 dw -5, 1
+pd_0f: times 4 dd 0xffff
+
+SECTION .text
+
+
+%macro AVG_MOV 2
+ pavgw %2, %1
+ mova %1, %2
+%endmacro
+
+%macro ADDW 3
+%if mmsize == 8
+ paddw %1, %2
+%else
+ movu %3, %2
+ paddw %1, %3
+%endif
+%endmacro
+
+%macro FILT_H 4
+ paddw %1, %4
+ psubw %1, %2 ; a-b
+ psraw %1, 2 ; (a-b)/4
+ psubw %1, %2 ; (a-b)/4-b
+ paddw %1, %3 ; (a-b)/4-b+c
+ psraw %1, 2 ; ((a-b)/4-b+c)/4
+ paddw %1, %3 ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
+%endmacro
+
+%macro PRELOAD_V 0
+ lea r3, [r2*3]
+ sub r1, r3
+ movu m0, [r1+r2]
+ movu m1, [r1+r2*2]
+ add r1, r3
+ movu m2, [r1]
+ movu m3, [r1+r2]
+ movu m4, [r1+r2*2]
+ add r1, r3
+%endmacro
+
+%macro FILT_V 8
+ movu %6, [r1]
+ paddw %1, %6
+ mova %7, %2
+ paddw %7, %5
+ mova %8, %3
+ paddw %8, %4
+ FILT_H %1, %7, %8, [pw_16]
+ psraw %1, 1
+ CLIPW %1, [pb_0], [pw_pixel_max]
+%endmacro
+
+%macro MC 1
+%define OP_MOV mova
+INIT_MMX
+%1 mmxext, put, 4
+INIT_XMM
+%1 sse2 , put, 8
+
+%define OP_MOV AVG_MOV
+INIT_MMX
+%1 mmxext, avg, 4
+INIT_XMM
+%1 sse2 , avg, 8
+%endmacro
+
+%macro MCAxA 8
+%ifdef ARCH_X86_64
+%ifnidn %1,mmxext
+MCAxA_OP %1,%2,%3,%4,%5,%6,%7,%8
+%endif
+%else
+MCAxA_OP %1,%2,%3,%4,%5,%6,%7,%8
+%endif
+%endmacro
+
+%macro MCAxA_OP 8
+cglobal %2_h264_qpel%5_%3_10_%1, %6,%7,%8
+%ifdef ARCH_X86_32
+ call stub_%2_h264_qpel%4_%3_10_%1
+ mov r0, r0m
+ mov r1, r1m
+ add r0, %4*2
+ add r1, %4*2
+ call stub_%2_h264_qpel%4_%3_10_%1
+ mov r0, r0m
+ mov r1, r1m
+ lea r0, [r0+r2*%4]
+ lea r1, [r1+r2*%4]
+ call stub_%2_h264_qpel%4_%3_10_%1
+ mov r0, r0m
+ mov r1, r1m
+ lea r0, [r0+r2*%4+%4*2]
+ lea r1, [r1+r2*%4+%4*2]
+ call stub_%2_h264_qpel%4_%3_10_%1
+ RET
+%else ; ARCH_X86_64
+ mov r10, r0
+ mov r11, r1
+ call stub_%2_h264_qpel%4_%3_10_%1
+ lea r0, [r10+%4*2]
+ lea r1, [r11+%4*2]
+ call stub_%2_h264_qpel%4_%3_10_%1
+ lea r0, [r10+r2*%4]
+ lea r1, [r11+r2*%4]
+ call stub_%2_h264_qpel%4_%3_10_%1
+ lea r0, [r10+r2*%4+%4*2]
+ lea r1, [r11+r2*%4+%4*2]
+%ifndef UNIX64 ; fall through to function
+ call stub_%2_h264_qpel%4_%3_10_%1
+ RET
+%endif
+%endif
+%endmacro
+
+;cpu, put/avg, mc, 4/8, ...
+%macro cglobal_mc 7
+%assign i %4*2
+MCAxA %1, %2, %3, %4, i, %5,%6,%7
+
+cglobal %2_h264_qpel%4_%3_10_%1, %5,%6,%7
+%ifndef UNIX64 ; no prologue or epilogue for UNIX64
+ call stub_%2_h264_qpel%4_%3_10_%1
+ RET
+%endif
+
+stub_%2_h264_qpel%4_%3_10_%1:
+%endmacro
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc00(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro COPY4 0
+ movu m0, [r1 ]
+ OP_MOV [r0 ], m0
+ movu m0, [r1+r2 ]
+ OP_MOV [r0+r2 ], m0
+ movu m0, [r1+r2*2]
+ OP_MOV [r0+r2*2], m0
+ movu m0, [r1+r3 ]
+ OP_MOV [r0+r3 ], m0
+%endmacro
+
+%macro MC00 1
+INIT_MMX
+cglobal_mc mmxext, %1, mc00, 4, 3,4,0
+ lea r3, [r2*3]
+ COPY4
+ ret
+
+INIT_XMM
+cglobal %1_h264_qpel8_mc00_10_sse2, 3,4
+ lea r3, [r2*3]
+ COPY4
+ lea r0, [r0+r2*4]
+ lea r1, [r1+r2*4]
+ COPY4
+ RET
+
+cglobal %1_h264_qpel16_mc00_10_sse2, 3,4
+ mov r3d, 8
+.loop:
+ movu m0, [r1 ]
+ movu m1, [r1 +16]
+ OP_MOV [r0 ], m0
+ OP_MOV [r0 +16], m1
+ movu m0, [r1+r2 ]
+ movu m1, [r1+r2+16]
+ OP_MOV [r0+r2 ], m0
+ OP_MOV [r0+r2+16], m1
+ lea r0, [r0+r2*2]
+ lea r1, [r1+r2*2]
+ dec r3d
+ jg .loop
+ REP_RET
+%endmacro
+
+%define OP_MOV mova
+MC00 put
+
+%define OP_MOV AVG_MOV
+MC00 avg
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc20(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC_CACHE 1
+%define OP_MOV mova
+%define PALIGNR PALIGNR_MMX
+INIT_MMX
+%1 mmxext , put, 4
+INIT_XMM
+%1 sse2_cache64 , put, 8
+%define PALIGNR PALIGNR_SSSE3
+%1 ssse3_cache64, put, 8
+%1 sse2 , put, 8, 0
+
+%define OP_MOV AVG_MOV
+%define PALIGNR PALIGNR_MMX
+INIT_MMX
+%1 mmxext , avg, 4
+INIT_XMM
+%1 sse2_cache64 , avg, 8
+%define PALIGNR PALIGNR_SSSE3
+%1 ssse3_cache64, avg, 8
+%1 sse2 , avg, 8, 0
+%endmacro
+
+%macro MC20 3-4
+cglobal_mc %1, %2, mc20, %3, 3,4,9
+ mov r3d, %3
+ mova m1, [pw_pixel_max]
+%if num_mmregs > 8
+ mova m8, [pw_16]
+ %define p16 m8
+%else
+ %define p16 [pw_16]
+%endif
+.nextrow
+%if %0 == 4
+ movu m2, [r1-4]
+ movu m3, [r1-2]
+ movu m4, [r1+0]
+ ADDW m2, [r1+6], m5
+ ADDW m3, [r1+4], m5
+ ADDW m4, [r1+2], m5
+%else ; movu is slow on these processors
+%if mmsize==16
+ movu m2, [r1-4]
+ movu m0, [r1+6]
+ mova m6, m0
+ psrldq m0, 6
+
+ paddw m6, m2
+ PALIGNR m3, m0, m2, 2, m5
+ PALIGNR m7, m0, m2, 8, m5
+ paddw m3, m7
+ PALIGNR m4, m0, m2, 4, m5
+ PALIGNR m7, m0, m2, 6, m5
+ paddw m4, m7
+ SWAP 2, 6
+%else
+ movu m2, [r1-4]
+ movu m6, [r1+4]
+ PALIGNR m3, m6, m2, 2, m5
+ paddw m3, m6
+ PALIGNR m4, m6, m2, 4, m5
+ PALIGNR m7, m6, m2, 6, m5
+ paddw m4, m7
+ paddw m2, [r1+6]
+%endif
+%endif
+
+ FILT_H m2, m3, m4, p16
+ psraw m2, 1
+ pxor m0, m0
+ CLIPW m2, m0, m1
+ OP_MOV [r0], m2
+ add r0, r2
+ add r1, r2
+ dec r3d
+ jg .nextrow
+ rep ret
+%endmacro
+
+MC_CACHE MC20
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc30(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC30 3-4
+cglobal_mc %1, %2, mc30, %3, 3,5,9
+ lea r4, [r1+2]
+ jmp stub_%2_h264_qpel%3_mc10_10_%1.body
+%endmacro
+
+MC_CACHE MC30
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc10(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC10 3-4
+cglobal_mc %1, %2, mc10, %3, 3,5,9
+ mov r4, r1
+.body
+ mov r3d, %3
+ mova m1, [pw_pixel_max]
+%if num_mmregs > 8
+ mova m8, [pw_16]
+ %define p16 m8
+%else
+ %define p16 [pw_16]
+%endif
+.nextrow
+%if %0 == 4
+ movu m2, [r1-4]
+ movu m3, [r1-2]
+ movu m4, [r1+0]
+ ADDW m2, [r1+6], m5
+ ADDW m3, [r1+4], m5
+ ADDW m4, [r1+2], m5
+%else ; movu is slow on these processors
+%if mmsize==16
+ movu m2, [r1-4]
+ movu m0, [r1+6]
+ mova m6, m0
+ psrldq m0, 6
+
+ paddw m6, m2
+ PALIGNR m3, m0, m2, 2, m5
+ PALIGNR m7, m0, m2, 8, m5
+ paddw m3, m7
+ PALIGNR m4, m0, m2, 4, m5
+ PALIGNR m7, m0, m2, 6, m5
+ paddw m4, m7
+ SWAP 2, 6
+%else
+ movu m2, [r1-4]
+ movu m6, [r1+4]
+ PALIGNR m3, m6, m2, 2, m5
+ paddw m3, m6
+ PALIGNR m4, m6, m2, 4, m5
+ PALIGNR m7, m6, m2, 6, m5
+ paddw m4, m7
+ paddw m2, [r1+6]
+%endif
+%endif
+
+ FILT_H m2, m3, m4, p16
+ psraw m2, 1
+ pxor m0, m0
+ CLIPW m2, m0, m1
+ movu m3, [r4]
+ pavgw m2, m3
+ OP_MOV [r0], m2
+ add r0, r2
+ add r1, r2
+ add r4, r2
+ dec r3d
+ jg .nextrow
+ rep ret
+%endmacro
+
+MC_CACHE MC10
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc02(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro V_FILT 11
+v_filt%9_%10_10_%11:
+ add r4, r2
+.no_addr4:
+ FILT_V m0, m1, m2, m3, m4, m5, m6, m7
+ add r1, r2
+ add r0, r2
+ ret
+%endmacro
+
+INIT_MMX
+RESET_MM_PERMUTATION
+%assign i 0
+%rep 4
+V_FILT m0, m1, m2, m3, m4, m5, m6, m7, 4, i, mmxext
+SWAP 0,1,2,3,4,5
+%assign i i+1
+%endrep
+
+INIT_XMM
+RESET_MM_PERMUTATION
+%assign i 0
+%rep 6
+V_FILT m0, m1, m2, m3, m4, m5, m6, m7, 8, i, sse2
+SWAP 0,1,2,3,4,5
+%assign i i+1
+%endrep
+
+%macro MC02 3
+cglobal_mc %1, %2, mc02, %3, 3,4,8
+ PRELOAD_V
+
+ sub r0, r2
+%assign j 0
+%rep %3
+ %assign i (j % 6)
+ call v_filt%3_ %+ i %+ _10_%1.no_addr4
+ OP_MOV [r0], m0
+ SWAP 0,1,2,3,4,5
+ %assign j j+1
+%endrep
+ ret
+%endmacro
+
+MC MC02
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc01(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC01 3
+cglobal_mc %1, %2, mc01, %3, 3,5,8
+ mov r4, r1
+.body
+ PRELOAD_V
+
+ sub r4, r2
+ sub r0, r2
+%assign j 0
+%rep %3
+ %assign i (j % 6)
+ call v_filt%3_ %+ i %+ _10_%1
+ movu m7, [r4]
+ pavgw m0, m7
+ OP_MOV [r0], m0
+ SWAP 0,1,2,3,4,5
+ %assign j j+1
+%endrep
+ ret
+%endmacro
+
+MC MC01
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc03(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC03 3
+cglobal_mc %1, %2, mc03, %3, 3,5,8
+ lea r4, [r1+r2]
+ jmp stub_%2_h264_qpel%3_mc01_10_%1.body
+%endmacro
+
+MC MC03
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc11(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro H_FILT_AVG 3-4
+h_filt%2_%3_10_%1:
+;FILT_H with fewer registers and averaged with the FILT_V result
+;m6,m7 are tmp registers, m0 is the FILT_V result, the rest are to be used next in the next iteration
+;unfortunately I need three registers, so m5 will have to be re-read from memory
+ movu m5, [r4-4]
+ ADDW m5, [r4+6], m7
+ movu m6, [r4-2]
+ ADDW m6, [r4+4], m7
+ paddw m5, [pw_16]
+ psubw m5, m6 ; a-b
+ psraw m5, 2 ; (a-b)/4
+ psubw m5, m6 ; (a-b)/4-b
+ movu m6, [r4+0]
+ ADDW m6, [r4+2], m7
+ paddw m5, m6 ; (a-b)/4-b+c
+ psraw m5, 2 ; ((a-b)/4-b+c)/4
+ paddw m5, m6 ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
+ psraw m5, 1
+ CLIPW m5, [pb_0], [pw_pixel_max]
+;avg FILT_V, FILT_H
+ pavgw m0, m5
+%if %0!=4
+ movu m5, [r1+r5]
+%endif
+ ret
+%endmacro
+
+INIT_MMX
+RESET_MM_PERMUTATION
+%assign i 0
+%rep 3
+H_FILT_AVG mmxext, 4, i
+SWAP 0,1,2,3,4,5
+%assign i i+1
+%endrep
+H_FILT_AVG mmxext, 4, i, 0
+
+INIT_XMM
+RESET_MM_PERMUTATION
+%assign i 0
+%rep 6
+%if i==1
+H_FILT_AVG sse2, 8, i, 0
+%else
+H_FILT_AVG sse2, 8, i
+%endif
+SWAP 0,1,2,3,4,5
+%assign i i+1
+%endrep
+
+%macro MC11 3
+; this REALLY needs x86_64
+cglobal_mc %1, %2, mc11, %3, 3,6,8
+ mov r4, r1
+.body
+ PRELOAD_V
+
+ sub r0, r2
+ sub r4, r2
+ mov r5, r2
+ neg r5
+%assign j 0
+%rep %3
+ %assign i (j % 6)
+ call v_filt%3_ %+ i %+ _10_%1
+ call h_filt%3_ %+ i %+ _10_%1
+%if %3==8 && i==1
+ movu m5, [r1+r5]
+%endif
+ OP_MOV [r0], m0
+ SWAP 0,1,2,3,4,5
+ %assign j j+1
+%endrep
+ ret
+%endmacro
+
+MC MC11
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc31(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC31 3
+cglobal_mc %1, %2, mc31, %3, 3,6,8
+ mov r4, r1
+ add r1, 2
+ jmp stub_%2_h264_qpel%3_mc11_10_%1.body
+%endmacro
+
+MC MC31
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc13(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC13 3
+cglobal_mc %1, %2, mc13, %3, 3,7,12
+ lea r4, [r1+r2]
+ jmp stub_%2_h264_qpel%3_mc11_10_%1.body
+%endmacro
+
+MC MC13
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc33(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC33 3
+cglobal_mc %1, %2, mc33, %3, 3,6,8
+ lea r4, [r1+r2]
+ add r1, 2
+ jmp stub_%2_h264_qpel%3_mc11_10_%1.body
+%endmacro
+
+MC MC33
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc22(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro FILT_H2 3
+ psubw %1, %2 ; a-b
+ psubw %2, %3 ; b-c
+ psllw %2, 2
+ psubw %1, %2 ; a-5*b+4*c
+ psllw %3, 4
+ paddw %1, %3 ; a-5*b+20*c
+%endmacro
+
+%macro FILT_VNRD 8
+ movu %6, [r1]
+ paddw %1, %6
+ mova %7, %2
+ paddw %7, %5
+ mova %8, %3
+ paddw %8, %4
+ FILT_H2 %1, %7, %8
+%endmacro
+
+%macro HV 2
+%ifidn %1,sse2
+%define PAD 12
+%define COUNT 2
+%else
+%define PAD 0
+%define COUNT 3
+%endif
+put_hv%2_10_%1:
+ neg r2 ; This actually saves instructions
+ lea r1, [r1+r2*2-mmsize+PAD]
+ lea r4, [rsp+PAD+gprsize]
+ mov r3d, COUNT
+.v_loop:
+ movu m0, [r1]
+ sub r1, r2
+ movu m1, [r1]
+ sub r1, r2
+ movu m2, [r1]
+ sub r1, r2
+ movu m3, [r1]
+ sub r1, r2
+ movu m4, [r1]
+ sub r1, r2
+%assign i 0
+%rep %2-1
+ FILT_VNRD m0, m1, m2, m3, m4, m5, m6, m7
+ psubw m0, [pad20]
+ movu [r4+i*mmsize*3], m0
+ sub r1, r2
+ SWAP 0,1,2,3,4,5
+%assign i i+1
+%endrep
+ FILT_VNRD m0, m1, m2, m3, m4, m5, m6, m7
+ psubw m0, [pad20]
+ movu [r4+i*mmsize*3], m0
+ add r4, mmsize
+ lea r1, [r1+r2*8+mmsize]
+%if %2==8
+ lea r1, [r1+r2*4]
+%endif
+ dec r3d
+ jg .v_loop
+ neg r2
+ ret
+%endmacro
+
+INIT_MMX
+HV mmxext, 4
+INIT_XMM
+HV sse2 , 8
+
+%macro H_LOOP 2
+%if num_mmregs > 8
+ %define s1 m8
+ %define s2 m9
+ %define s3 m10
+ %define d1 m11
+%else
+ %define s1 [tap1]
+ %define s2 [tap2]
+ %define s3 [tap3]
+ %define d1 [depad]
+%endif
+h%2_loop_op_%1:
+ movu m1, [r1+mmsize-4]
+ movu m2, [r1+mmsize-2]
+ mova m3, [r1+mmsize+0]
+ movu m4, [r1+mmsize+2]
+ movu m5, [r1+mmsize+4]
+ movu m6, [r1+mmsize+6]
+%if num_mmregs > 8
+ pmaddwd m1, s1
+ pmaddwd m2, s1
+ pmaddwd m3, s2
+ pmaddwd m4, s2
+ pmaddwd m5, s3
+ pmaddwd m6, s3
+ paddd m1, d1
+ paddd m2, d1
+%else
+ mova m0, s1
+ pmaddwd m1, m0
+ pmaddwd m2, m0
+ mova m0, s2
+ pmaddwd m3, m0
+ pmaddwd m4, m0
+ mova m0, s3
+ pmaddwd m5, m0
+ pmaddwd m6, m0
+ mova m0, d1
+ paddd m1, m0
+ paddd m2, m0
+%endif
+ paddd m3, m5
+ paddd m4, m6
+ paddd m1, m3
+ paddd m2, m4
+ psrad m1, 10
+ psrad m2, 10
+ pslld m2, 16
+ pand m1, [pd_0f]
+ por m1, m2
+%if num_mmregs <= 8
+ pxor m0, m0
+%endif
+ CLIPW m1, m0, m7
+ add r1, mmsize*3
+ ret
+%endmacro
+
+INIT_MMX
+H_LOOP mmxext, 4
+INIT_XMM
+H_LOOP sse2 , 8
+
+%macro MC22 3
+cglobal_mc %1, %2, mc22, %3, 3,7,12
+%define PAD mmsize*8*4*2 ; SIZE*16*4*sizeof(pixel)
+ mov r6, rsp ; backup stack pointer
+ and rsp, ~(mmsize-1) ; align stack
+ sub rsp, PAD
+
+ call put_hv%3_10_%1
+
+ mov r3d, %3
+ mova m7, [pw_pixel_max]
+%if num_mmregs > 8
+ pxor m0, m0
+ mova m8, [tap1]
+ mova m9, [tap2]
+ mova m10, [tap3]
+ mova m11, [depad]
+%endif
+ mov r1, rsp
+.h_loop:
+ call h%3_loop_op_%1
+
+ OP_MOV [r0], m1
+ add r0, r2
+ dec r3d
+ jg .h_loop
+
+ mov rsp, r6 ; restore stack pointer
+ ret
+%endmacro
+
+MC MC22
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc12(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC12 3
+cglobal_mc %1, %2, mc12, %3, 3,7,12
+%define PAD mmsize*8*4*2 ; SIZE*16*4*sizeof(pixel)
+ mov r6, rsp ; backup stack pointer
+ and rsp, ~(mmsize-1) ; align stack
+ sub rsp, PAD
+
+ call put_hv%3_10_%1
+
+ xor r4d, r4d
+.body
+ mov r3d, %3
+ pxor m0, m0
+ mova m7, [pw_pixel_max]
+%if num_mmregs > 8
+ mova m8, [tap1]
+ mova m9, [tap2]
+ mova m10, [tap3]
+ mova m11, [depad]
+%endif
+ mov r1, rsp
+.h_loop:
+ call h%3_loop_op_%1
+
+ movu m3, [r1+r4-2*mmsize] ; movu needed for mc32, etc
+ paddw m3, [depad2]
+ psrlw m3, 5
+ psubw m3, [unpad]
+ CLIPW m3, m0, m7
+ pavgw m1, m3
+
+ OP_MOV [r0], m1
+ add r0, r2
+ dec r3d
+ jg .h_loop
+
+ mov rsp, r6 ; restore stack pointer
+ ret
+%endmacro
+
+MC MC12
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc32(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC32 3
+cglobal_mc %1, %2, mc32, %3, 3,7,12
+%define PAD mmsize*8*3*2 ; SIZE*16*4*sizeof(pixel)
+ mov r6, rsp ; backup stack pointer
+ and rsp, ~(mmsize-1) ; align stack
+ sub rsp, PAD
+
+ call put_hv%3_10_%1
+
+ mov r4d, 2 ; sizeof(pixel)
+ jmp stub_%2_h264_qpel%3_mc12_10_%1.body
+%endmacro
+
+MC MC32
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc21(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro H_NRD 2
+put_h%2_10_%1:
+ add rsp, gprsize
+ mov r3d, %2
+ xor r4d, r4d
+ mova m6, [pad20]
+.nextrow
+ movu m2, [r5-4]
+ movu m3, [r5-2]
+ movu m4, [r5+0]
+ ADDW m2, [r5+6], m5
+ ADDW m3, [r5+4], m5
+ ADDW m4, [r5+2], m5
+
+ FILT_H2 m2, m3, m4
+ psubw m2, m6
+ mova [rsp+r4], m2
+ add r4d, mmsize*3
+ add r5, r2
+ dec r3d
+ jg .nextrow
+ sub rsp, gprsize
+ ret
+%endmacro
+
+INIT_MMX
+H_NRD mmxext, 4
+INIT_XMM
+H_NRD sse2 , 8
+
+%macro MC21 3
+cglobal_mc %1, %2, mc21, %3, 3,7,12
+ mov r5, r1
+.body
+%define PAD mmsize*8*3*2 ; SIZE*16*4*sizeof(pixel)
+ mov r6, rsp ; backup stack pointer
+ and rsp, ~(mmsize-1) ; align stack
+
+ sub rsp, PAD
+ call put_h%3_10_%1
+
+ sub rsp, PAD
+ call put_hv%3_10_%1
+
+ mov r4d, PAD-mmsize ; H buffer
+ jmp stub_%2_h264_qpel%3_mc12_10_%1.body
+%endmacro
+
+MC MC21
+
+;-----------------------------------------------------------------------------
+; void h264_qpel_mc23(uint8_t *dst, uint8_t *src, int stride)
+;-----------------------------------------------------------------------------
+%macro MC23 3
+cglobal_mc %1, %2, mc23, %3, 3,7,12
+ lea r5, [r1+r2]
+ jmp stub_%2_h264_qpel%3_mc21_10_%1.body
+%endmacro
+
+MC MC23
diff --git a/libavcodec/x86/h264_qpel_mmx.c b/libavcodec/x86/h264_qpel_mmx.c
index 066f794..b7a4183 100644
--- a/libavcodec/x86/h264_qpel_mmx.c
+++ b/libavcodec/x86/h264_qpel_mmx.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt
+ * Copyright (c) 2011 Daniel Kang
*
* This file is part of Libav.
*
@@ -398,7 +399,7 @@ static av_noinline void OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst,
"2: \n\t"\
\
: "+a"(src), "+c"(dst)\
- : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "g"(h)\
+ : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "rm"(h)\
: "memory"\
);\
src += 4-(h+5)*srcStride;\
@@ -446,7 +447,7 @@ static av_always_inline void OPNAME ## h264_qpel8or16_hv1_lowpass_ ## MMX(int16_
QPEL_H264HV(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, 15*48)\
"2: \n\t"\
: "+a"(src)\
- : "c"(tmp), "S"((x86_reg)srcStride), "g"(size)\
+ : "c"(tmp), "S"((x86_reg)srcStride), "rm"(size)\
: "memory"\
);\
tmp += 4;\
@@ -823,7 +824,7 @@ static av_noinline void OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst,
"2: \n\t"\
\
: "+a"(src), "+c"(dst)\
- : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "g"(h)\
+ : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "rm"(h)\
: XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3", \
"%xmm4", "%xmm5", "%xmm6", "%xmm7",)\
"memory"\
@@ -878,7 +879,7 @@ static av_always_inline void put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, u
QPEL_H264HV_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, 15*48)
"2: \n\t"
: "+a"(src)
- : "c"(tmp), "S"((x86_reg)srcStride), "g"(size)
+ : "c"(tmp), "S"((x86_reg)srcStride), "rm"(size)
: XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3",
"%xmm4", "%xmm5", "%xmm6", "%xmm7",)
"memory"
@@ -1199,3 +1200,100 @@ H264_MC_816(H264_MC_HV, sse2)
H264_MC_816(H264_MC_H, ssse3)
H264_MC_816(H264_MC_HV, ssse3)
#endif
+
+
+
+//10bit
+#define LUMA_MC_OP(OP, NUM, DEPTH, TYPE, OPT) \
+void ff_ ## OP ## _h264_qpel ## NUM ## _ ## TYPE ## _ ## DEPTH ## _ ## OPT \
+ (uint8_t *dst, uint8_t *src, int stride);
+
+#define LUMA_MC_ALL(DEPTH, TYPE, OPT) \
+ LUMA_MC_OP(put, 4, DEPTH, TYPE, OPT) \
+ LUMA_MC_OP(avg, 4, DEPTH, TYPE, OPT) \
+ LUMA_MC_OP(put, 8, DEPTH, TYPE, OPT) \
+ LUMA_MC_OP(avg, 8, DEPTH, TYPE, OPT) \
+ LUMA_MC_OP(put, 16, DEPTH, TYPE, OPT) \
+ LUMA_MC_OP(avg, 16, DEPTH, TYPE, OPT)
+
+#define LUMA_MC_816(DEPTH, TYPE, OPT) \
+ LUMA_MC_OP(put, 8, DEPTH, TYPE, OPT) \
+ LUMA_MC_OP(avg, 8, DEPTH, TYPE, OPT) \
+ LUMA_MC_OP(put, 16, DEPTH, TYPE, OPT) \
+ LUMA_MC_OP(avg, 16, DEPTH, TYPE, OPT)
+
+LUMA_MC_ALL(10, mc00, mmxext)
+LUMA_MC_ALL(10, mc10, mmxext)
+LUMA_MC_ALL(10, mc20, mmxext)
+LUMA_MC_ALL(10, mc30, mmxext)
+LUMA_MC_ALL(10, mc01, mmxext)
+LUMA_MC_ALL(10, mc11, mmxext)
+LUMA_MC_ALL(10, mc21, mmxext)
+LUMA_MC_ALL(10, mc31, mmxext)
+LUMA_MC_ALL(10, mc02, mmxext)
+LUMA_MC_ALL(10, mc12, mmxext)
+LUMA_MC_ALL(10, mc22, mmxext)
+LUMA_MC_ALL(10, mc32, mmxext)
+LUMA_MC_ALL(10, mc03, mmxext)
+LUMA_MC_ALL(10, mc13, mmxext)
+LUMA_MC_ALL(10, mc23, mmxext)
+LUMA_MC_ALL(10, mc33, mmxext)
+
+LUMA_MC_816(10, mc00, sse2)
+LUMA_MC_816(10, mc10, sse2)
+LUMA_MC_816(10, mc10, sse2_cache64)
+LUMA_MC_816(10, mc10, ssse3_cache64)
+LUMA_MC_816(10, mc20, sse2)
+LUMA_MC_816(10, mc20, sse2_cache64)
+LUMA_MC_816(10, mc20, ssse3_cache64)
+LUMA_MC_816(10, mc30, sse2)
+LUMA_MC_816(10, mc30, sse2_cache64)
+LUMA_MC_816(10, mc30, ssse3_cache64)
+LUMA_MC_816(10, mc01, sse2)
+LUMA_MC_816(10, mc11, sse2)
+LUMA_MC_816(10, mc21, sse2)
+LUMA_MC_816(10, mc31, sse2)
+LUMA_MC_816(10, mc02, sse2)
+LUMA_MC_816(10, mc12, sse2)
+LUMA_MC_816(10, mc22, sse2)
+LUMA_MC_816(10, mc32, sse2)
+LUMA_MC_816(10, mc03, sse2)
+LUMA_MC_816(10, mc13, sse2)
+LUMA_MC_816(10, mc23, sse2)
+LUMA_MC_816(10, mc33, sse2)
+
+#define QPEL16_OPMC(OP, MC, MMX)\
+void ff_ ## OP ## _h264_qpel16_ ## MC ## _10_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+ ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst , src , stride);\
+ ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst+16, src+16, stride);\
+ src += 8*stride;\
+ dst += 8*stride;\
+ ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst , src , stride);\
+ ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst+16, src+16, stride);\
+}
+
+#define QPEL16_OP(MC, MMX)\
+QPEL16_OPMC(put, MC, MMX)\
+QPEL16_OPMC(avg, MC, MMX)
+
+#define QPEL16(MMX)\
+QPEL16_OP(mc00, MMX)\
+QPEL16_OP(mc01, MMX)\
+QPEL16_OP(mc02, MMX)\
+QPEL16_OP(mc03, MMX)\
+QPEL16_OP(mc10, MMX)\
+QPEL16_OP(mc11, MMX)\
+QPEL16_OP(mc12, MMX)\
+QPEL16_OP(mc13, MMX)\
+QPEL16_OP(mc20, MMX)\
+QPEL16_OP(mc21, MMX)\
+QPEL16_OP(mc22, MMX)\
+QPEL16_OP(mc23, MMX)\
+QPEL16_OP(mc30, MMX)\
+QPEL16_OP(mc31, MMX)\
+QPEL16_OP(mc32, MMX)\
+QPEL16_OP(mc33, MMX)
+
+#if ARCH_X86_32 && HAVE_YASM // ARCH_X86_64 implies sse2+
+QPEL16(mmxext)
+#endif
diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm
index d80ca32..bd0d9d6 100644
--- a/libavcodec/x86/h264_weight.asm
+++ b/libavcodec/x86/h264_weight.asm
@@ -28,21 +28,20 @@ SECTION .text
;-----------------------------------------------------------------------------
; biweight pred:
;
-; void h264_biweight_16x16_sse2(uint8_t *dst, uint8_t *src, int stride,
-; int log2_denom, int weightd, int weights,
-; int offset);
+; void h264_biweight_16_sse2(uint8_t *dst, uint8_t *src, int stride,
+; int height, int log2_denom, int weightd,
+; int weights, int offset);
; and
-; void h264_weight_16x16_sse2(uint8_t *dst, int stride,
-; int log2_denom, int weight,
-; int offset);
+; void h264_weight_16_sse2(uint8_t *dst, int stride, int height,
+; int log2_denom, int weight, int offset);
;-----------------------------------------------------------------------------
%macro WEIGHT_SETUP 0
- add r4, r4
- inc r4
- movd m3, r3d
- movd m5, r4d
- movd m6, r2d
+ add r5, r5
+ inc r5
+ movd m3, r4d
+ movd m5, r5d
+ movd m6, r3d
pslld m5, m6
psrld m5, 1
%if mmsize == 16
@@ -71,60 +70,41 @@ SECTION .text
packuswb m0, m1
%endmacro
-%macro WEIGHT_FUNC_DBL_MM 1
-cglobal h264_weight_16x%1_mmx2, 5, 5, 0
+INIT_MMX
+cglobal h264_weight_16_mmx2, 6, 6, 0
WEIGHT_SETUP
- mov r2, %1
-%if %1 == 16
.nextrow
WEIGHT_OP 0, 4
mova [r0 ], m0
WEIGHT_OP 8, 12
mova [r0+8], m0
add r0, r1
- dec r2
+ dec r2d
jnz .nextrow
REP_RET
-%else
- jmp mangle(ff_h264_weight_16x16_mmx2.nextrow)
-%endif
-%endmacro
-INIT_MMX
-WEIGHT_FUNC_DBL_MM 16
-WEIGHT_FUNC_DBL_MM 8
-
-%macro WEIGHT_FUNC_MM 4
-cglobal h264_weight_%1x%2_%4, 7, 7, %3
+%macro WEIGHT_FUNC_MM 3
+cglobal h264_weight_%1_%3, 6, 6, %2
WEIGHT_SETUP
- mov r2, %2
-%if %2 == 16
.nextrow
WEIGHT_OP 0, mmsize/2
mova [r0], m0
add r0, r1
- dec r2
+ dec r2d
jnz .nextrow
REP_RET
-%else
- jmp mangle(ff_h264_weight_%1x16_%4.nextrow)
-%endif
%endmacro
INIT_MMX
-WEIGHT_FUNC_MM 8, 16, 0, mmx2
-WEIGHT_FUNC_MM 8, 8, 0, mmx2
-WEIGHT_FUNC_MM 8, 4, 0, mmx2
+WEIGHT_FUNC_MM 8, 0, mmx2
INIT_XMM
-WEIGHT_FUNC_MM 16, 16, 8, sse2
-WEIGHT_FUNC_MM 16, 8, 8, sse2
+WEIGHT_FUNC_MM 16, 8, sse2
-%macro WEIGHT_FUNC_HALF_MM 5
-cglobal h264_weight_%1x%2_%5, 5, 5, %4
+%macro WEIGHT_FUNC_HALF_MM 3
+cglobal h264_weight_%1_%3, 6, 6, %2
WEIGHT_SETUP
- mov r2, %2/2
+ sar r2d, 1
lea r3, [r1*2]
-%if %2 == mmsize
.nextrow
WEIGHT_OP 0, r1
movh [r0], m0
@@ -135,31 +115,30 @@ cglobal h264_weight_%1x%2_%5, 5, 5, %4
movh [r0+r1], m0
%endif
add r0, r3
- dec r2
+ dec r2d
jnz .nextrow
REP_RET
-%else
- jmp mangle(ff_h264_weight_%1x%3_%5.nextrow)
-%endif
%endmacro
INIT_MMX
-WEIGHT_FUNC_HALF_MM 4, 8, 8, 0, mmx2
-WEIGHT_FUNC_HALF_MM 4, 4, 8, 0, mmx2
-WEIGHT_FUNC_HALF_MM 4, 2, 8, 0, mmx2
+WEIGHT_FUNC_HALF_MM 4, 0, mmx2
INIT_XMM
-WEIGHT_FUNC_HALF_MM 8, 16, 16, 8, sse2
-WEIGHT_FUNC_HALF_MM 8, 8, 16, 8, sse2
-WEIGHT_FUNC_HALF_MM 8, 4, 16, 8, sse2
+WEIGHT_FUNC_HALF_MM 8, 8, sse2
%macro BIWEIGHT_SETUP 0
- add r6, 1
- or r6, 1
- add r3, 1
- movd m3, r4d
- movd m4, r5d
- movd m5, r6d
- movd m6, r3d
+%ifdef ARCH_X86_64
+%define off_regd r11d
+%else
+%define off_regd r3d
+%endif
+ mov off_regd, r7m
+ add off_regd, 1
+ or off_regd, 1
+ add r4, 1
+ movd m3, r5d
+ movd m4, r6d
+ movd m5, off_regd
+ movd m6, r4d
pslld m5, m6
psrld m5, 1
%if mmsize == 16
@@ -195,11 +174,10 @@ WEIGHT_FUNC_HALF_MM 8, 4, 16, 8, sse2
packuswb m0, m1
%endmacro
-%macro BIWEIGHT_FUNC_DBL_MM 1
-cglobal h264_biweight_16x%1_mmx2, 7, 7, 0
+INIT_MMX
+cglobal h264_biweight_16_mmx2, 7, 7, 0
BIWEIGHT_SETUP
- mov r3, %1
-%if %1 == 16
+ movifnidn r3d, r3m
.nextrow
BIWEIGHT_STEPA 0, 1, 0
BIWEIGHT_STEPA 1, 2, 4
@@ -211,23 +189,14 @@ cglobal h264_biweight_16x%1_mmx2, 7, 7, 0
mova [r0+8], m0
add r0, r2
add r1, r2
- dec r3
+ dec r3d
jnz .nextrow
REP_RET
-%else
- jmp mangle(ff_h264_biweight_16x16_mmx2.nextrow)
-%endif
-%endmacro
-INIT_MMX
-BIWEIGHT_FUNC_DBL_MM 16
-BIWEIGHT_FUNC_DBL_MM 8
-
-%macro BIWEIGHT_FUNC_MM 4
-cglobal h264_biweight_%1x%2_%4, 7, 7, %3
+%macro BIWEIGHT_FUNC_MM 3
+cglobal h264_biweight_%1_%3, 7, 7, %2
BIWEIGHT_SETUP
- mov r3, %2
-%if %2 == 16
+ movifnidn r3d, r3m
.nextrow
BIWEIGHT_STEPA 0, 1, 0
BIWEIGHT_STEPA 1, 2, mmsize/2
@@ -235,28 +204,22 @@ cglobal h264_biweight_%1x%2_%4, 7, 7, %3
mova [r0], m0
add r0, r2
add r1, r2
- dec r3
+ dec r3d
jnz .nextrow
REP_RET
-%else
- jmp mangle(ff_h264_biweight_%1x16_%4.nextrow)
-%endif
%endmacro
INIT_MMX
-BIWEIGHT_FUNC_MM 8, 16, 0, mmx2
-BIWEIGHT_FUNC_MM 8, 8, 0, mmx2
-BIWEIGHT_FUNC_MM 8, 4, 0, mmx2
+BIWEIGHT_FUNC_MM 8, 0, mmx2
INIT_XMM
-BIWEIGHT_FUNC_MM 16, 16, 8, sse2
-BIWEIGHT_FUNC_MM 16, 8, 8, sse2
+BIWEIGHT_FUNC_MM 16, 8, sse2
-%macro BIWEIGHT_FUNC_HALF_MM 5
-cglobal h264_biweight_%1x%2_%5, 7, 7, %4
+%macro BIWEIGHT_FUNC_HALF_MM 3
+cglobal h264_biweight_%1_%3, 7, 7, %2
BIWEIGHT_SETUP
- mov r3, %2/2
+ movifnidn r3d, r3m
+ sar r3, 1
lea r4, [r2*2]
-%if %2 == mmsize
.nextrow
BIWEIGHT_STEPA 0, 1, 0
BIWEIGHT_STEPA 1, 2, r2
@@ -270,31 +233,30 @@ cglobal h264_biweight_%1x%2_%5, 7, 7, %4
%endif
add r0, r4
add r1, r4
- dec r3
+ dec r3d
jnz .nextrow
REP_RET
-%else
- jmp mangle(ff_h264_biweight_%1x%3_%5.nextrow)
-%endif
%endmacro
INIT_MMX
-BIWEIGHT_FUNC_HALF_MM 4, 8, 8, 0, mmx2
-BIWEIGHT_FUNC_HALF_MM 4, 4, 8, 0, mmx2
-BIWEIGHT_FUNC_HALF_MM 4, 2, 8, 0, mmx2
+BIWEIGHT_FUNC_HALF_MM 4, 0, mmx2
INIT_XMM
-BIWEIGHT_FUNC_HALF_MM 8, 16, 16, 8, sse2
-BIWEIGHT_FUNC_HALF_MM 8, 8, 16, 8, sse2
-BIWEIGHT_FUNC_HALF_MM 8, 4, 16, 8, sse2
+BIWEIGHT_FUNC_HALF_MM 8, 8, sse2
%macro BIWEIGHT_SSSE3_SETUP 0
- add r6, 1
- or r6, 1
- add r3, 1
- movd m4, r4d
- movd m0, r5d
- movd m5, r6d
- movd m6, r3d
+%ifdef ARCH_X86_64
+%define off_regd r11d
+%else
+%define off_regd r3d
+%endif
+ mov off_regd, r7m
+ add off_regd, 1
+ or off_regd, 1
+ add r4, 1
+ movd m4, r5d
+ movd m0, r6d
+ movd m5, off_regd
+ movd m6, r4d
pslld m5, m6
psrld m5, 1
punpcklbw m4, m0
@@ -314,12 +276,11 @@ BIWEIGHT_FUNC_HALF_MM 8, 4, 16, 8, sse2
packuswb m0, m2
%endmacro
-%macro BIWEIGHT_SSSE3_16 1
-cglobal h264_biweight_16x%1_ssse3, 7, 7, 8
+INIT_XMM
+cglobal h264_biweight_16_ssse3, 7, 7, 8
BIWEIGHT_SSSE3_SETUP
- mov r3, %1
+ movifnidn r3d, r3m
-%if %1 == 16
.nextrow
movh m0, [r0]
movh m2, [r0+8]
@@ -330,25 +291,17 @@ cglobal h264_biweight_16x%1_ssse3, 7, 7, 8
mova [r0], m0
add r0, r2
add r1, r2
- dec r3
+ dec r3d
jnz .nextrow
REP_RET
-%else
- jmp mangle(ff_h264_biweight_16x16_ssse3.nextrow)
-%endif
-%endmacro
INIT_XMM
-BIWEIGHT_SSSE3_16 16
-BIWEIGHT_SSSE3_16 8
-
-%macro BIWEIGHT_SSSE3_8 1
-cglobal h264_biweight_8x%1_ssse3, 7, 7, 8
+cglobal h264_biweight_8_ssse3, 7, 7, 8
BIWEIGHT_SSSE3_SETUP
- mov r3, %1/2
+ movifnidn r3d, r3m
+ sar r3, 1
lea r4, [r2*2]
-%if %1 == 16
.nextrow
movh m0, [r0]
movh m1, [r1]
@@ -361,15 +314,6 @@ cglobal h264_biweight_8x%1_ssse3, 7, 7, 8
movhps [r0+r2], m0
add r0, r4
add r1, r4
- dec r3
+ dec r3d
jnz .nextrow
REP_RET
-%else
- jmp mangle(ff_h264_biweight_8x16_ssse3.nextrow)
-%endif
-%endmacro
-
-INIT_XMM
-BIWEIGHT_SSSE3_8 16
-BIWEIGHT_SSSE3_8 8
-BIWEIGHT_SSSE3_8 4
diff --git a/libavcodec/x86/h264_weight_10bit.asm b/libavcodec/x86/h264_weight_10bit.asm
new file mode 100644
index 0000000..9c4b276
--- /dev/null
+++ b/libavcodec/x86/h264_weight_10bit.asm
@@ -0,0 +1,277 @@
+;*****************************************************************************
+;* MMX/SSE2/AVX-optimized 10-bit H.264 weighted prediction code
+;*****************************************************************************
+;* Copyright (C) 2005-2011 x264 project
+;*
+;* Authors: Daniel Kang <daniel.d.kang at gmail.com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "x86inc.asm"
+%include "x86util.asm"
+
+SECTION_RODATA 32
+
+pw_pixel_max: times 8 dw ((1 << 10)-1)
+sq_1: dq 1
+ dq 0
+
+cextern pw_1
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+; void h264_weight(uint8_t *dst, int stride, int height, int log2_denom,
+; int weight, int offset);
+;-----------------------------------------------------------------------------
+%macro WEIGHT_PROLOGUE 0
+.prologue
+ PROLOGUE 0,6,8
+ movifnidn r0, r0mp
+ movifnidn r1d, r1m
+ movifnidn r2d, r2m
+ movifnidn r4d, r4m
+ movifnidn r5d, r5m
+%endmacro
+
+%macro WEIGHT_SETUP 1
+ mova m0, [pw_1]
+ movd m2, r3m
+ pslld m0, m2 ; 1<<log2_denom
+ SPLATW m0, m0
+ shl r5, 19 ; *8, move to upper half of dword
+ lea r5, [r5+r4*2+0x10000]
+ movd m3, r5d ; weight<<1 | 1+(offset<<(3))
+ pshufd m3, m3, 0
+ mova m4, [pw_pixel_max]
+ paddw m2, [sq_1] ; log2_denom+1
+%ifnidn %1, sse4
+ pxor m7, m7
+%endif
+%endmacro
+
+%macro WEIGHT_OP 2-3
+%if %0==2
+ mova m5, [r0+%2]
+ punpckhwd m6, m5, m0
+ punpcklwd m5, m0
+%else
+ movq m5, [r0+%2]
+ movq m6, [r0+%3]
+ punpcklwd m5, m0
+ punpcklwd m6, m0
+%endif
+ pmaddwd m5, m3
+ pmaddwd m6, m3
+ psrad m5, m2
+ psrad m6, m2
+%ifidn %1, sse4
+ packusdw m5, m6
+ pminsw m5, m4
+%else
+ packssdw m5, m6
+ CLIPW m5, m7, m4
+%endif
+%endmacro
+
+%macro WEIGHT_FUNC_DBL 1
+cglobal h264_weight_16_10_%1
+ WEIGHT_PROLOGUE
+ WEIGHT_SETUP %1
+.nextrow
+ WEIGHT_OP %1, 0
+ mova [r0 ], m5
+ WEIGHT_OP %1, 16
+ mova [r0+16], m5
+ add r0, r1
+ dec r2d
+ jnz .nextrow
+ REP_RET
+%endmacro
+
+INIT_XMM
+WEIGHT_FUNC_DBL sse2
+WEIGHT_FUNC_DBL sse4
+
+
+%macro WEIGHT_FUNC_MM 1
+cglobal h264_weight_8_10_%1
+ WEIGHT_PROLOGUE
+ WEIGHT_SETUP %1
+.nextrow
+ WEIGHT_OP %1, 0
+ mova [r0], m5
+ add r0, r1
+ dec r2d
+ jnz .nextrow
+ REP_RET
+%endmacro
+
+INIT_XMM
+WEIGHT_FUNC_MM sse2
+WEIGHT_FUNC_MM sse4
+
+
+%macro WEIGHT_FUNC_HALF_MM 1
+cglobal h264_weight_4_10_%1
+ WEIGHT_PROLOGUE
+ sar r2d, 1
+ WEIGHT_SETUP %1
+ lea r3, [r1*2]
+.nextrow
+ WEIGHT_OP %1, 0, r1
+ movh [r0], m5
+ movhps [r0+r1], m5
+ add r0, r3
+ dec r2d
+ jnz .nextrow
+ REP_RET
+%endmacro
+
+INIT_XMM
+WEIGHT_FUNC_HALF_MM sse2
+WEIGHT_FUNC_HALF_MM sse4
+
+
+;-----------------------------------------------------------------------------
+; void h264_biweight(uint8_t *dst, uint8_t *src, int stride, int height,
+; int log2_denom, int weightd, int weights, int offset);
+;-----------------------------------------------------------------------------
+%ifdef ARCH_X86_32
+DECLARE_REG_TMP 3
+%else
+DECLARE_REG_TMP 10
+%endif
+
+%macro BIWEIGHT_PROLOGUE 0
+.prologue
+ PROLOGUE 0,7,8
+ movifnidn r0, r0mp
+ movifnidn r1, r1mp
+ movifnidn r2d, r2m
+ movifnidn r5d, r5m
+ movifnidn r6d, r6m
+ movifnidn t0d, r7m
+%endmacro
+
+%macro BIWEIGHT_SETUP 1
+ lea t0, [t0*4+1] ; (offset<<2)+1
+ or t0, 1
+ shl r6, 16
+ or r5, r6
+ movd m4, r5d ; weightd | weights
+ movd m5, t0d ; (offset+1)|1
+ movd m6, r4m ; log2_denom
+ pslld m5, m6 ; (((offset<<2)+1)|1)<<log2_denom
+ paddd m6, [sq_1]
+ pshufd m4, m4, 0
+ pshufd m5, m5, 0
+ mova m3, [pw_pixel_max]
+ movifnidn r3d, r3m
+%ifnidn %1, sse4
+ pxor m7, m7
+%endif
+%endmacro
+
+%macro BIWEIGHT 2-3
+%if %0==2
+ mova m0, [r0+%2]
+ mova m1, [r1+%2]
+ punpckhwd m2, m0, m1
+ punpcklwd m0, m1
+%else
+ movq m0, [r0+%2]
+ movq m1, [r1+%2]
+ punpcklwd m0, m1
+ movq m2, [r0+%3]
+ movq m1, [r1+%3]
+ punpcklwd m2, m1
+%endif
+ pmaddwd m0, m4
+ pmaddwd m2, m4
+ paddd m0, m5
+ paddd m2, m5
+ psrad m0, m6
+ psrad m2, m6
+%ifidn %1, sse4
+ packusdw m0, m2
+ pminsw m0, m3
+%else
+ packssdw m0, m2
+ CLIPW m0, m7, m3
+%endif
+%endmacro
+
+%macro BIWEIGHT_FUNC_DBL 1
+cglobal h264_biweight_16_10_%1
+ BIWEIGHT_PROLOGUE
+ BIWEIGHT_SETUP %1
+.nextrow
+ BIWEIGHT %1, 0
+ mova [r0 ], m0
+ BIWEIGHT %1, 16
+ mova [r0+16], m0
+ add r0, r2
+ add r1, r2
+ dec r3d
+ jnz .nextrow
+ REP_RET
+%endmacro
+
+INIT_XMM
+BIWEIGHT_FUNC_DBL sse2
+BIWEIGHT_FUNC_DBL sse4
+
+%macro BIWEIGHT_FUNC 1
+cglobal h264_biweight_8_10_%1
+ BIWEIGHT_PROLOGUE
+ BIWEIGHT_SETUP %1
+.nextrow
+ BIWEIGHT %1, 0
+ mova [r0], m0
+ add r0, r2
+ add r1, r2
+ dec r3d
+ jnz .nextrow
+ REP_RET
+%endmacro
+
+INIT_XMM
+BIWEIGHT_FUNC sse2
+BIWEIGHT_FUNC sse4
+
+%macro BIWEIGHT_FUNC_HALF 1
+cglobal h264_biweight_4_10_%1
+ BIWEIGHT_PROLOGUE
+ BIWEIGHT_SETUP %1
+ sar r3d, 1
+ lea r4, [r2*2]
+.nextrow
+ BIWEIGHT %1, 0, r2
+ movh [r0 ], m0
+ movhps [r0+r2], m0
+ add r0, r4
+ add r1, r4
+ dec r3d
+ jnz .nextrow
+ REP_RET
+%endmacro
+
+INIT_XMM
+BIWEIGHT_FUNC_HALF sse2
+BIWEIGHT_FUNC_HALF sse4
diff --git a/libavcodec/x86/h264dsp_mmx.c b/libavcodec/x86/h264dsp_mmx.c
index 3fccd08..dcd9180 100644
--- a/libavcodec/x86/h264dsp_mmx.c
+++ b/libavcodec/x86/h264dsp_mmx.c
@@ -298,42 +298,57 @@ LF_IFUNC(v, luma_intra, 10, mmxext)
/***********************************/
/* weighted prediction */
-#define H264_WEIGHT(W, H, OPT) \
-void ff_h264_weight_ ## W ## x ## H ## _ ## OPT(uint8_t *dst, \
- int stride, int log2_denom, int weight, int offset);
+#define H264_WEIGHT(W, OPT) \
+void ff_h264_weight_ ## W ## _ ## OPT(uint8_t *dst, \
+ int stride, int height, int log2_denom, int weight, int offset);
-#define H264_BIWEIGHT(W, H, OPT) \
-void ff_h264_biweight_ ## W ## x ## H ## _ ## OPT(uint8_t *dst, \
- uint8_t *src, int stride, int log2_denom, int weightd, \
+#define H264_BIWEIGHT(W, OPT) \
+void ff_h264_biweight_ ## W ## _ ## OPT(uint8_t *dst, \
+ uint8_t *src, int stride, int height, int log2_denom, int weightd, \
int weights, int offset);
-#define H264_BIWEIGHT_MMX(W,H) \
-H264_WEIGHT (W, H, mmx2) \
-H264_BIWEIGHT(W, H, mmx2)
-
-#define H264_BIWEIGHT_MMX_SSE(W,H) \
-H264_BIWEIGHT_MMX(W, H) \
-H264_WEIGHT (W, H, sse2) \
-H264_BIWEIGHT (W, H, sse2) \
-H264_BIWEIGHT (W, H, ssse3)
-
-H264_BIWEIGHT_MMX_SSE(16, 16)
-H264_BIWEIGHT_MMX_SSE(16, 8)
-H264_BIWEIGHT_MMX_SSE( 8, 16)
-H264_BIWEIGHT_MMX_SSE( 8, 8)
-H264_BIWEIGHT_MMX_SSE( 8, 4)
-H264_BIWEIGHT_MMX ( 4, 8)
-H264_BIWEIGHT_MMX ( 4, 4)
-H264_BIWEIGHT_MMX ( 4, 2)
-
-void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth)
+#define H264_BIWEIGHT_MMX(W) \
+H264_WEIGHT (W, mmx2) \
+H264_BIWEIGHT(W, mmx2)
+
+#define H264_BIWEIGHT_MMX_SSE(W) \
+H264_BIWEIGHT_MMX(W) \
+H264_WEIGHT (W, sse2) \
+H264_BIWEIGHT (W, sse2) \
+H264_BIWEIGHT (W, ssse3)
+
+H264_BIWEIGHT_MMX_SSE(16)
+H264_BIWEIGHT_MMX_SSE( 8)
+H264_BIWEIGHT_MMX ( 4)
+
+#define H264_WEIGHT_10(W, DEPTH, OPT) \
+void ff_h264_weight_ ## W ## _ ## DEPTH ## _ ## OPT(uint8_t *dst, \
+ int stride, int height, int log2_denom, int weight, int offset);
+
+#define H264_BIWEIGHT_10(W, DEPTH, OPT) \
+void ff_h264_biweight_ ## W ## _ ## DEPTH ## _ ## OPT \
+ (uint8_t *dst, uint8_t *src, int stride, int height, int log2_denom, \
+ int weightd, int weights, int offset);
+
+#define H264_BIWEIGHT_10_SSE(W, DEPTH) \
+H264_WEIGHT_10 (W, DEPTH, sse2) \
+H264_WEIGHT_10 (W, DEPTH, sse4) \
+H264_BIWEIGHT_10(W, DEPTH, sse2) \
+H264_BIWEIGHT_10(W, DEPTH, sse4)
+
+H264_BIWEIGHT_10_SSE(16, 10)
+H264_BIWEIGHT_10_SSE( 8, 10)
+H264_BIWEIGHT_10_SSE( 4, 10)
+
+void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
{
int mm_flags = av_get_cpu_flags();
- if (bit_depth == 8) {
- if (mm_flags & AV_CPU_FLAG_MMX2) {
+ if (chroma_format_idc == 1 && mm_flags & AV_CPU_FLAG_MMX2) {
c->h264_loop_filter_strength= h264_loop_filter_strength_mmx2;
}
+
+ if (bit_depth == 8) {
#if HAVE_YASM
if (mm_flags & AV_CPU_FLAG_MMX) {
c->h264_idct_dc_add =
@@ -343,7 +358,8 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth)
c->h264_idct_add16 = ff_h264_idct_add16_8_mmx;
c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmx;
- c->h264_idct_add8 = ff_h264_idct_add8_8_mmx;
+ if (chroma_format_idc == 1)
+ c->h264_idct_add8 = ff_h264_idct_add8_8_mmx;
c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmx;
c->h264_luma_dc_dequant_idct= ff_h264_luma_dc_dequant_idct_mmx;
@@ -352,57 +368,45 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth)
c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmx2;
c->h264_idct_add16 = ff_h264_idct_add16_8_mmx2;
c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmx2;
- c->h264_idct_add8 = ff_h264_idct_add8_8_mmx2;
+ if (chroma_format_idc == 1)
+ c->h264_idct_add8 = ff_h264_idct_add8_8_mmx2;
c->h264_idct_add16intra= ff_h264_idct_add16intra_8_mmx2;
c->h264_v_loop_filter_chroma= ff_deblock_v_chroma_8_mmxext;
- c->h264_h_loop_filter_chroma= ff_deblock_h_chroma_8_mmxext;
c->h264_v_loop_filter_chroma_intra= ff_deblock_v_chroma_intra_8_mmxext;
- c->h264_h_loop_filter_chroma_intra= ff_deblock_h_chroma_intra_8_mmxext;
+ if (chroma_format_idc == 1) {
+ c->h264_h_loop_filter_chroma= ff_deblock_h_chroma_8_mmxext;
+ c->h264_h_loop_filter_chroma_intra= ff_deblock_h_chroma_intra_8_mmxext;
+ }
#if ARCH_X86_32
c->h264_v_loop_filter_luma= ff_deblock_v_luma_8_mmxext;
c->h264_h_loop_filter_luma= ff_deblock_h_luma_8_mmxext;
c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_mmxext;
c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmxext;
#endif
- c->weight_h264_pixels_tab[0]= ff_h264_weight_16x16_mmx2;
- c->weight_h264_pixels_tab[1]= ff_h264_weight_16x8_mmx2;
- c->weight_h264_pixels_tab[2]= ff_h264_weight_8x16_mmx2;
- c->weight_h264_pixels_tab[3]= ff_h264_weight_8x8_mmx2;
- c->weight_h264_pixels_tab[4]= ff_h264_weight_8x4_mmx2;
- c->weight_h264_pixels_tab[5]= ff_h264_weight_4x8_mmx2;
- c->weight_h264_pixels_tab[6]= ff_h264_weight_4x4_mmx2;
- c->weight_h264_pixels_tab[7]= ff_h264_weight_4x2_mmx2;
-
- c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16x16_mmx2;
- c->biweight_h264_pixels_tab[1]= ff_h264_biweight_16x8_mmx2;
- c->biweight_h264_pixels_tab[2]= ff_h264_biweight_8x16_mmx2;
- c->biweight_h264_pixels_tab[3]= ff_h264_biweight_8x8_mmx2;
- c->biweight_h264_pixels_tab[4]= ff_h264_biweight_8x4_mmx2;
- c->biweight_h264_pixels_tab[5]= ff_h264_biweight_4x8_mmx2;
- c->biweight_h264_pixels_tab[6]= ff_h264_biweight_4x4_mmx2;
- c->biweight_h264_pixels_tab[7]= ff_h264_biweight_4x2_mmx2;
+ c->weight_h264_pixels_tab[0]= ff_h264_weight_16_mmx2;
+ c->weight_h264_pixels_tab[1]= ff_h264_weight_8_mmx2;
+ c->weight_h264_pixels_tab[2]= ff_h264_weight_4_mmx2;
+
+ c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16_mmx2;
+ c->biweight_h264_pixels_tab[1]= ff_h264_biweight_8_mmx2;
+ c->biweight_h264_pixels_tab[2]= ff_h264_biweight_4_mmx2;
if (mm_flags&AV_CPU_FLAG_SSE2) {
c->h264_idct8_add = ff_h264_idct8_add_8_sse2;
c->h264_idct_add16 = ff_h264_idct_add16_8_sse2;
c->h264_idct8_add4 = ff_h264_idct8_add4_8_sse2;
- c->h264_idct_add8 = ff_h264_idct_add8_8_sse2;
+ if (chroma_format_idc == 1)
+ c->h264_idct_add8 = ff_h264_idct_add8_8_sse2;
c->h264_idct_add16intra = ff_h264_idct_add16intra_8_sse2;
c->h264_luma_dc_dequant_idct= ff_h264_luma_dc_dequant_idct_sse2;
- c->weight_h264_pixels_tab[0]= ff_h264_weight_16x16_sse2;
- c->weight_h264_pixels_tab[1]= ff_h264_weight_16x8_sse2;
- c->weight_h264_pixels_tab[2]= ff_h264_weight_8x16_sse2;
- c->weight_h264_pixels_tab[3]= ff_h264_weight_8x8_sse2;
- c->weight_h264_pixels_tab[4]= ff_h264_weight_8x4_sse2;
+ c->weight_h264_pixels_tab[0]= ff_h264_weight_16_sse2;
+ c->weight_h264_pixels_tab[1]= ff_h264_weight_8_sse2;
- c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16x16_sse2;
- c->biweight_h264_pixels_tab[1]= ff_h264_biweight_16x8_sse2;
- c->biweight_h264_pixels_tab[2]= ff_h264_biweight_8x16_sse2;
- c->biweight_h264_pixels_tab[3]= ff_h264_biweight_8x8_sse2;
- c->biweight_h264_pixels_tab[4]= ff_h264_biweight_8x4_sse2;
+ c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16_sse2;
+ c->biweight_h264_pixels_tab[1]= ff_h264_biweight_8_sse2;
#if HAVE_ALIGNED_STACK
c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_sse2;
@@ -412,11 +416,8 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth)
#endif
}
if (mm_flags&AV_CPU_FLAG_SSSE3) {
- c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16x16_ssse3;
- c->biweight_h264_pixels_tab[1]= ff_h264_biweight_16x8_ssse3;
- c->biweight_h264_pixels_tab[2]= ff_h264_biweight_8x16_ssse3;
- c->biweight_h264_pixels_tab[3]= ff_h264_biweight_8x8_ssse3;
- c->biweight_h264_pixels_tab[4]= ff_h264_biweight_8x4_ssse3;
+ c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16_ssse3;
+ c->biweight_h264_pixels_tab[1]= ff_h264_biweight_8_ssse3;
}
if (mm_flags&AV_CPU_FLAG_AVX) {
#if HAVE_ALIGNED_STACK
@@ -447,13 +448,22 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth)
c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_sse2;
c->h264_idct_add16 = ff_h264_idct_add16_10_sse2;
- c->h264_idct_add8 = ff_h264_idct_add8_10_sse2;
+ if (chroma_format_idc == 1)
+ c->h264_idct_add8 = ff_h264_idct_add8_10_sse2;
c->h264_idct_add16intra= ff_h264_idct_add16intra_10_sse2;
#if HAVE_ALIGNED_STACK
c->h264_idct8_add = ff_h264_idct8_add_10_sse2;
c->h264_idct8_add4 = ff_h264_idct8_add4_10_sse2;
#endif
+ c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse2;
+ c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse2;
+ c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse2;
+
+ c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse2;
+ c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse2;
+ c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse2;
+
c->h264_v_loop_filter_chroma= ff_deblock_v_chroma_10_sse2;
c->h264_v_loop_filter_chroma_intra= ff_deblock_v_chroma_intra_10_sse2;
#if HAVE_ALIGNED_STACK
@@ -463,6 +473,15 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth)
c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_sse2;
#endif
}
+ if (mm_flags&AV_CPU_FLAG_SSE4) {
+ c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse4;
+ c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse4;
+ c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse4;
+
+ c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse4;
+ c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse4;
+ c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse4;
+ }
#if HAVE_AVX
if (mm_flags&AV_CPU_FLAG_AVX) {
c->h264_idct_dc_add =
@@ -470,7 +489,8 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth)
c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_avx;
c->h264_idct_add16 = ff_h264_idct_add16_10_avx;
- c->h264_idct_add8 = ff_h264_idct_add8_10_avx;
+ if (chroma_format_idc == 1)
+ c->h264_idct_add8 = ff_h264_idct_add8_10_avx;
c->h264_idct_add16intra= ff_h264_idct_add16intra_10_avx;
#if HAVE_ALIGNED_STACK
c->h264_idct8_add = ff_h264_idct8_add_10_avx;
diff --git a/libavcodec/x86/idct_mmx.c b/libavcodec/x86/idct_mmx.c
index 57fa818..ed2d321 100644
--- a/libavcodec/x86/idct_mmx.c
+++ b/libavcodec/x86/idct_mmx.c
@@ -1,5 +1,4 @@
/*
- * idct_mmx.c
* Copyright (C) 1999-2001 Aaron Holtzman <aholtzma at ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
diff --git a/libavcodec/x86/idct_sse2_xvid.c b/libavcodec/x86/idct_sse2_xvid.c
index 4b6885f..968b400 100644
--- a/libavcodec/x86/idct_sse2_xvid.c
+++ b/libavcodec/x86/idct_sse2_xvid.c
@@ -43,7 +43,7 @@
#include "idct_xvid.h"
#include "dsputil_mmx.h"
-/*!
+/**
* @file
* @brief SSE2 idct compatible with xvidmmx
*/
diff --git a/libavcodec/x86/idct_xvid.h b/libavcodec/x86/idct_xvid.h
index 1ff039d..495d2ca 100644
--- a/libavcodec/x86/idct_xvid.h
+++ b/libavcodec/x86/idct_xvid.h
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/*!
+/**
* @file
* header for Xvid IDCT functions
*/
diff --git a/libavcodec/x86/mlpdsp.c b/libavcodec/x86/mlpdsp.c
index 333dc56..400855d 100644
--- a/libavcodec/x86/mlpdsp.c
+++ b/libavcodec/x86/mlpdsp.c
@@ -23,7 +23,7 @@
#include "libavcodec/dsputil.h"
#include "libavcodec/mlp.h"
-#if HAVE_7REGS && HAVE_TEN_OPERANDS
+#if HAVE_7REGS
extern void ff_mlp_firorder_8;
extern void ff_mlp_firorder_7;
@@ -171,11 +171,11 @@ static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff,
);
}
-#endif /* HAVE_7REGS && HAVE_TEN_OPERANDS */
+#endif /* HAVE_7REGS */
void ff_mlp_init_x86(DSPContext* c, AVCodecContext *avctx)
{
-#if HAVE_7REGS && HAVE_TEN_OPERANDS
+#if HAVE_7REGS
c->mlp_filter_channel = mlp_filter_channel_x86;
#endif
}
diff --git a/libavcodec/x86/mpegvideo_mmx_template.c b/libavcodec/x86/mpegvideo_mmx_template.c
index 0f01cb2..0b6cff3 100644
--- a/libavcodec/x86/mpegvideo_mmx_template.c
+++ b/libavcodec/x86/mpegvideo_mmx_template.c
@@ -98,7 +98,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
x86_reg last_non_zero_p1;
int level=0, q; //=0 is because gcc says uninitialized ...
const uint16_t *qmat, *bias;
- DECLARE_ALIGNED(16, int16_t, temp_block)[64];
+ LOCAL_ALIGNED_16(int16_t, temp_block, [64]);
assert((7&(int)(&temp_block[0])) == 0); //did gcc align it correctly?
diff --git a/libavcodec/x86/proresdsp-init.c b/libavcodec/x86/proresdsp-init.c
new file mode 100644
index 0000000..f202f9f
--- /dev/null
+++ b/libavcodec/x86/proresdsp-init.c
@@ -0,0 +1,54 @@
+/*
+ * Apple ProRes compatible decoder
+ *
+ * Copyright (c) 2010-2011 Maxim Poliakovski
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavcodec/proresdsp.h"
+
+void ff_prores_idct_put_10_sse2(uint16_t *dst, int linesize,
+ DCTELEM *block, const int16_t *qmat);
+void ff_prores_idct_put_10_sse4(uint16_t *dst, int linesize,
+ DCTELEM *block, const int16_t *qmat);
+void ff_prores_idct_put_10_avx (uint16_t *dst, int linesize,
+ DCTELEM *block, const int16_t *qmat);
+
+void ff_proresdsp_x86_init(ProresDSPContext *dsp)
+{
+#if ARCH_X86_64 && HAVE_YASM
+ int flags = av_get_cpu_flags();
+
+ if (flags & AV_CPU_FLAG_SSE2) {
+ dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
+ dsp->idct_put = ff_prores_idct_put_10_sse2;
+ }
+
+ if (flags & AV_CPU_FLAG_SSE4) {
+ dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
+ dsp->idct_put = ff_prores_idct_put_10_sse4;
+ }
+
+#if HAVE_AVX
+ if (flags & AV_CPU_FLAG_AVX) {
+ dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
+ dsp->idct_put = ff_prores_idct_put_10_avx;
+ }
+#endif /* HAVE_AVX */
+#endif /* ARCH_X86_64 && HAVE_YASM */
+}
diff --git a/libavcodec/x86/proresdsp.asm b/libavcodec/x86/proresdsp.asm
new file mode 100644
index 0000000..9365bf1
--- /dev/null
+++ b/libavcodec/x86/proresdsp.asm
@@ -0,0 +1,432 @@
+;******************************************************************************
+;* x86-SIMD-optimized IDCT for prores
+;* this is identical to "simple" IDCT except for the clip range
+;*
+;* Copyright (c) 2011 Ronald S. Bultje <rsbultje at gmail.com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "x86inc.asm"
+%include "x86util.asm"
+
+%define W1sh2 22725 ; W1 = 90901 = 22725<<2 + 1
+%define W2sh2 21407 ; W2 = 85627 = 21407<<2 - 1
+%define W3sh2 19265 ; W3 = 77062 = 19265<<2 + 2
+%define W4sh2 16384 ; W4 = 65535 = 16384<<2 - 1
+%define W5sh2 12873 ; W5 = 51491 = 12873<<2 - 1
+%define W6sh2 8867 ; W6 = 35468 = 8867<<2
+%define W7sh2 4520 ; W7 = 18081 = 4520<<2 + 1
+
+%ifdef ARCH_X86_64
+
+SECTION_RODATA
+
+w4_plus_w2: times 4 dw W4sh2, +W2sh2
+w4_min_w2: times 4 dw W4sh2, -W2sh2
+w4_plus_w6: times 4 dw W4sh2, +W6sh2
+w4_min_w6: times 4 dw W4sh2, -W6sh2
+w1_plus_w3: times 4 dw W1sh2, +W3sh2
+w3_min_w1: times 4 dw W3sh2, -W1sh2
+w7_plus_w3: times 4 dw W7sh2, +W3sh2
+w3_min_w7: times 4 dw W3sh2, -W7sh2
+w1_plus_w5: times 4 dw W1sh2, +W5sh2
+w5_min_w1: times 4 dw W5sh2, -W1sh2
+w5_plus_w7: times 4 dw W5sh2, +W7sh2
+w7_min_w5: times 4 dw W7sh2, -W5sh2
+row_round: times 8 dw (1<<14)
+
+cextern pw_4
+cextern pw_8
+cextern pw_512
+cextern pw_1019
+
+section .text align=16
+
+; interleave data while maintaining source
+; %1=type, %2=dstlo, %3=dsthi, %4=src, %5=interleave
+%macro SBUTTERFLY3 5
+ punpckl%1 m%2, m%4, m%5
+ punpckh%1 m%3, m%4, m%5
+%endmacro
+
+; %1/%2=src1/dst1, %3/%4=dst2, %5/%6=src2, %7=shift
+; action: %3/%4 = %1/%2 - %5/%6; %1/%2 += %5/%6
+; %1/%2/%3/%4 >>= %7; dword -> word (in %1/%3)
+%macro SUMSUB_SHPK 7
+ psubd %3, %1, %5 ; { a0 - b0 }[0-3]
+ psubd %4, %2, %6 ; { a0 - b0 }[4-7]
+ paddd %1, %5 ; { a0 + b0 }[0-3]
+ paddd %2, %6 ; { a0 + b0 }[4-7]
+ psrad %1, %7
+ psrad %2, %7
+ psrad %3, %7
+ psrad %4, %7
+ packssdw %1, %2 ; row[0]
+ packssdw %3, %4 ; row[7]
+%endmacro
+
+; %1 = row or col (for rounding variable)
+; %2 = number of bits to shift at the end
+; %3 = optimization
+%macro IDCT_1D 3
+ ; a0 = (W4 * row[0]) + (1 << (15 - 1));
+ ; a1 = a0;
+ ; a2 = a0;
+ ; a3 = a0;
+ ; a0 += W2 * row[2];
+ ; a1 += W6 * row[2];
+ ; a2 -= W6 * row[2];
+ ; a3 -= W2 * row[2];
+%ifidn %1, col
+ paddw m10,[pw_8]
+%endif
+ SBUTTERFLY3 wd, 0, 1, 10, 8 ; { row[0], row[2] }[0-3]/[4-7]
+%ifidn %1, row
+ psubw m10,[row_round]
+%endif
+ SIGNEXTEND m8, m9, m14 ; { row[2] }[0-3] / [4-7]
+ SIGNEXTEND m10, m11, m14 ; { row[0] }[0-3] / [4-7]
+ pmaddwd m2, m0, [w4_plus_w6]
+ pmaddwd m3, m1, [w4_plus_w6]
+ pmaddwd m4, m0, [w4_min_w6]
+ pmaddwd m5, m1, [w4_min_w6]
+ pmaddwd m6, m0, [w4_min_w2]
+ pmaddwd m7, m1, [w4_min_w2]
+ pmaddwd m0, [w4_plus_w2]
+ pmaddwd m1, [w4_plus_w2]
+ pslld m2, 2
+ pslld m3, 2
+ pslld m4, 2
+ pslld m5, 2
+ pslld m6, 2
+ pslld m7, 2
+ pslld m0, 2
+ pslld m1, 2
+
+ ; a0: -1*row[0]-1*row[2]
+ ; a1: -1*row[0]
+ ; a2: -1*row[0]
+ ; a3: -1*row[0]+1*row[2]
+ psubd m2, m10 ; a1[0-3]
+ psubd m3, m11 ; a1[4-7]
+ psubd m4, m10 ; a2[0-3]
+ psubd m5, m11 ; a2[4-7]
+ psubd m0, m10
+ psubd m1, m11
+ psubd m6, m10
+ psubd m7, m11
+ psubd m0, m8 ; a0[0-3]
+ psubd m1, m9 ; a0[4-7]
+ paddd m6, m8 ; a3[0-3]
+ paddd m7, m9 ; a3[4-7]
+
+ ; a0 += W4*row[4] + W6*row[6]; i.e. -1*row[4]
+ ; a1 -= W4*row[4] + W2*row[6]; i.e. -1*row[4]-1*row[6]
+ ; a2 -= W4*row[4] - W2*row[6]; i.e. -1*row[4]+1*row[6]
+ ; a3 += W4*row[4] - W6*row[6]; i.e. -1*row[4]
+ SBUTTERFLY3 wd, 8, 9, 13, 12 ; { row[4], row[6] }[0-3]/[4-7]
+ SIGNEXTEND m13, m14, m10 ; { row[4] }[0-3] / [4-7]
+ pmaddwd m10, m8, [w4_plus_w6]
+ pmaddwd m11, m9, [w4_plus_w6]
+ pslld m10, 2
+ pslld m11, 2
+ psubd m10, m13
+ psubd m11, m14
+ paddd m0, m10 ; a0[0-3]
+ paddd m1, m11 ; a0[4-7]
+ pmaddwd m10, m8, [w4_min_w6]
+ pmaddwd m11, m9, [w4_min_w6]
+ pslld m10, 2
+ pslld m11, 2
+ psubd m10, m13
+ psubd m11, m14
+ paddd m6, m10 ; a3[0-3]
+ paddd m7, m11 ; a3[4-7]
+ pmaddwd m10, m8, [w4_min_w2]
+ pmaddwd m11, m9, [w4_min_w2]
+ pmaddwd m8, [w4_plus_w2]
+ pmaddwd m9, [w4_plus_w2]
+ pslld m10, 2
+ pslld m11, 2
+ pslld m8, 2
+ pslld m9, 2
+ psubd m10, m13
+ psubd m11, m14
+ psubd m8, m13
+ psubd m9, m14
+ psubd m4, m10 ; a2[0-3] intermediate
+ psubd m5, m11 ; a2[4-7] intermediate
+ psubd m2, m8 ; a1[0-3] intermediate
+ psubd m3, m9 ; a1[4-7] intermediate
+ SIGNEXTEND m12, m13, m10 ; { row[6] }[0-3] / [4-7]
+ psubd m4, m12 ; a2[0-3]
+ psubd m5, m13 ; a2[4-7]
+ paddd m2, m12 ; a1[0-3]
+ paddd m3, m13 ; a1[4-7]
+
+ ; load/store
+ mova [r2+ 0], m0
+ mova [r2+ 32], m2
+ mova [r2+ 64], m4
+ mova [r2+ 96], m6
+ mova m10,[r2+ 16] ; { row[1] }[0-7]
+ mova m8, [r2+ 48] ; { row[3] }[0-7]
+ mova m13,[r2+ 80] ; { row[5] }[0-7]
+ mova m14,[r2+112] ; { row[7] }[0-7]
+ mova [r2+ 16], m1
+ mova [r2+ 48], m3
+ mova [r2+ 80], m5
+ mova [r2+112], m7
+%ifidn %1, row
+ pmullw m10,[r3+ 16]
+ pmullw m8, [r3+ 48]
+ pmullw m13,[r3+ 80]
+ pmullw m14,[r3+112]
+%endif
+
+ ; b0 = MUL(W1, row[1]);
+ ; MAC(b0, W3, row[3]);
+ ; b1 = MUL(W3, row[1]);
+ ; MAC(b1, -W7, row[3]);
+ ; b2 = MUL(W5, row[1]);
+ ; MAC(b2, -W1, row[3]);
+ ; b3 = MUL(W7, row[1]);
+ ; MAC(b3, -W5, row[3]);
+ SBUTTERFLY3 wd, 0, 1, 10, 8 ; { row[1], row[3] }[0-3]/[4-7]
+ SIGNEXTEND m10, m11, m12 ; { row[1] }[0-3] / [4-7]
+ SIGNEXTEND m8, m9, m12 ; { row[3] }[0-3] / [4-7]
+ pmaddwd m2, m0, [w3_min_w7]
+ pmaddwd m3, m1, [w3_min_w7]
+ pmaddwd m4, m0, [w5_min_w1]
+ pmaddwd m5, m1, [w5_min_w1]
+ pmaddwd m6, m0, [w7_min_w5]
+ pmaddwd m7, m1, [w7_min_w5]
+ pmaddwd m0, [w1_plus_w3]
+ pmaddwd m1, [w1_plus_w3]
+ pslld m2, 2
+ pslld m3, 2
+ pslld m4, 2
+ pslld m5, 2
+ pslld m6, 2
+ pslld m7, 2
+ pslld m0, 2
+ pslld m1, 2
+
+ ; b0: +1*row[1]+2*row[3]
+ ; b1: +2*row[1]-1*row[3]
+ ; b2: -1*row[1]-1*row[3]
+ ; b3: +1*row[1]+1*row[3]
+ psubd m2, m8
+ psubd m3, m9
+ paddd m0, m8
+ paddd m1, m9
+ paddd m8, m10 ; { row[1] + row[3] }[0-3]
+ paddd m9, m11 ; { row[1] + row[3] }[4-7]
+ paddd m10, m10
+ paddd m11, m11
+ paddd m0, m8 ; b0[0-3]
+ paddd m1, m9 ; b0[4-7]
+ paddd m2, m10 ; b1[0-3]
+ paddd m3, m11 ; b2[4-7]
+ psubd m4, m8 ; b2[0-3]
+ psubd m5, m9 ; b2[4-7]
+ paddd m6, m8 ; b3[0-3]
+ paddd m7, m9 ; b3[4-7]
+
+ ; MAC(b0, W5, row[5]);
+ ; MAC(b0, W7, row[7]);
+ ; MAC(b1, -W1, row[5]);
+ ; MAC(b1, -W5, row[7]);
+ ; MAC(b2, W7, row[5]);
+ ; MAC(b2, W3, row[7]);
+ ; MAC(b3, W3, row[5]);
+ ; MAC(b3, -W1, row[7]);
+ SBUTTERFLY3 wd, 8, 9, 13, 14 ; { row[5], row[7] }[0-3]/[4-7]
+ SIGNEXTEND m13, m12, m11 ; { row[5] }[0-3] / [4-7]
+ SIGNEXTEND m14, m11, m10 ; { row[7] }[0-3] / [4-7]
+
+ ; b0: -1*row[5]+1*row[7]
+ ; b1: -1*row[5]+1*row[7]
+ ; b2: +1*row[5]+2*row[7]
+ ; b3: +2*row[5]-1*row[7]
+ paddd m4, m13
+ paddd m5, m12
+ paddd m6, m13
+ paddd m7, m12
+ psubd m13, m14 ; { row[5] - row[7] }[0-3]
+ psubd m12, m11 ; { row[5] - row[7] }[4-7]
+ paddd m14, m14
+ paddd m11, m11
+ psubd m0, m13
+ psubd m1, m12
+ psubd m2, m13
+ psubd m3, m12
+ paddd m4, m14
+ paddd m5, m11
+ paddd m6, m13
+ paddd m7, m12
+
+ pmaddwd m10, m8, [w1_plus_w5]
+ pmaddwd m11, m9, [w1_plus_w5]
+ pmaddwd m12, m8, [w5_plus_w7]
+ pmaddwd m13, m9, [w5_plus_w7]
+ pslld m10, 2
+ pslld m11, 2
+ pslld m12, 2
+ pslld m13, 2
+ psubd m2, m10 ; b1[0-3]
+ psubd m3, m11 ; b1[4-7]
+ paddd m0, m12 ; b0[0-3]
+ paddd m1, m13 ; b0[4-7]
+ pmaddwd m12, m8, [w7_plus_w3]
+ pmaddwd m13, m9, [w7_plus_w3]
+ pmaddwd m8, [w3_min_w1]
+ pmaddwd m9, [w3_min_w1]
+ pslld m12, 2
+ pslld m13, 2
+ pslld m8, 2
+ pslld m9, 2
+ paddd m4, m12 ; b2[0-3]
+ paddd m5, m13 ; b2[4-7]
+ paddd m6, m8 ; b3[0-3]
+ paddd m7, m9 ; b3[4-7]
+
+ ; row[0] = (a0 + b0) >> 15;
+ ; row[7] = (a0 - b0) >> 15;
+ ; row[1] = (a1 + b1) >> 15;
+ ; row[6] = (a1 - b1) >> 15;
+ ; row[2] = (a2 + b2) >> 15;
+ ; row[5] = (a2 - b2) >> 15;
+ ; row[3] = (a3 + b3) >> 15;
+ ; row[4] = (a3 - b3) >> 15;
+ mova m8, [r2+ 0] ; a0[0-3]
+ mova m9, [r2+16] ; a0[4-7]
+ SUMSUB_SHPK m8, m9, m10, m11, m0, m1, %2
+ mova m0, [r2+32] ; a1[0-3]
+ mova m1, [r2+48] ; a1[4-7]
+ SUMSUB_SHPK m0, m1, m9, m11, m2, m3, %2
+ mova m1, [r2+64] ; a2[0-3]
+ mova m2, [r2+80] ; a2[4-7]
+ SUMSUB_SHPK m1, m2, m11, m3, m4, m5, %2
+ mova m2, [r2+96] ; a3[0-3]
+ mova m3, [r2+112] ; a3[4-7]
+ SUMSUB_SHPK m2, m3, m4, m5, m6, m7, %2
+%endmacro
+
+; void prores_idct_put_10_<opt>(uint8_t *pixels, int stride,
+; DCTELEM *block, const int16_t *qmat);
+%macro idct_put_fn 2
+cglobal prores_idct_put_10_%1, 4, 4, %2
+ movsxd r1, r1d
+ pxor m15, m15 ; zero
+
+ ; for (i = 0; i < 8; i++)
+ ; idctRowCondDC(block + i*8);
+ mova m10,[r2+ 0] ; { row[0] }[0-7]
+ mova m8, [r2+32] ; { row[2] }[0-7]
+ mova m13,[r2+64] ; { row[4] }[0-7]
+ mova m12,[r2+96] ; { row[6] }[0-7]
+
+ pmullw m10,[r3+ 0]
+ pmullw m8, [r3+32]
+ pmullw m13,[r3+64]
+ pmullw m12,[r3+96]
+
+ IDCT_1D row, 17, %1
+
+ ; transpose for second part of IDCT
+ TRANSPOSE8x8W 8, 0, 1, 2, 4, 11, 9, 10, 3
+ mova [r2+ 16], m0
+ mova [r2+ 48], m2
+ mova [r2+ 80], m11
+ mova [r2+112], m10
+ SWAP 8, 10
+ SWAP 1, 8
+ SWAP 4, 13
+ SWAP 9, 12
+
+ ; for (i = 0; i < 8; i++)
+ ; idctSparseColAdd(dest + i, line_size, block + i);
+ IDCT_1D col, 20, %1
+
+ ; clip/store
+ mova m6, [pw_512]
+ mova m3, [pw_4]
+ mova m5, [pw_1019]
+ paddw m8, m6
+ paddw m0, m6
+ paddw m1, m6
+ paddw m2, m6
+ paddw m4, m6
+ paddw m11, m6
+ paddw m9, m6
+ paddw m10, m6
+ pmaxsw m8, m3
+ pmaxsw m0, m3
+ pmaxsw m1, m3
+ pmaxsw m2, m3
+ pmaxsw m4, m3
+ pmaxsw m11, m3
+ pmaxsw m9, m3
+ pmaxsw m10, m3
+ pminsw m8, m5
+ pminsw m0, m5
+ pminsw m1, m5
+ pminsw m2, m5
+ pminsw m4, m5
+ pminsw m11, m5
+ pminsw m9, m5
+ pminsw m10, m5
+
+ lea r2, [r1*3]
+ mova [r0 ], m8
+ mova [r0+r1 ], m0
+ mova [r0+r1*2], m1
+ mova [r0+r2 ], m2
+ lea r0, [r0+r1*4]
+ mova [r0 ], m4
+ mova [r0+r1 ], m11
+ mova [r0+r1*2], m9
+ mova [r0+r2 ], m10
+ RET
+%endmacro
+
+%macro signextend_sse2 3 ; dstlow, dsthigh, tmp
+ pxor %3, %3
+ pcmpgtw %3, %1
+ mova %2, %1
+ punpcklwd %1, %3
+ punpckhwd %2, %3
+%endmacro
+
+%macro signextend_sse4 2-3 ; dstlow, dsthigh
+ movhlps %2, %1
+ pmovsxwd %1, %1
+ pmovsxwd %2, %2
+%endmacro
+
+INIT_XMM
+%define SIGNEXTEND signextend_sse2
+idct_put_fn sse2, 16
+INIT_XMM
+%define SIGNEXTEND signextend_sse4
+idct_put_fn sse4, 16
+INIT_AVX
+idct_put_fn avx, 16
+
+%endif
diff --git a/libavcodec/x86/rv40dsp.c b/libavcodec/x86/rv40dsp.c
new file mode 100644
index 0000000..9f90ad8
--- /dev/null
+++ b/libavcodec/x86/rv40dsp.c
@@ -0,0 +1,60 @@
+/*
+ * RV40 decoder motion compensation functions x86-optimised
+ * Copyright (c) 2008 Konstantin Shishkov
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * RV40 decoder motion compensation functions x86-optimised
+ */
+
+#include "libavcodec/rv34dsp.h"
+
+void ff_put_rv40_chroma_mc8_mmx (uint8_t *dst, uint8_t *src,
+ int stride, int h, int x, int y);
+void ff_avg_rv40_chroma_mc8_mmx2 (uint8_t *dst, uint8_t *src,
+ int stride, int h, int x, int y);
+void ff_avg_rv40_chroma_mc8_3dnow(uint8_t *dst, uint8_t *src,
+ int stride, int h, int x, int y);
+
+void ff_put_rv40_chroma_mc4_mmx (uint8_t *dst, uint8_t *src,
+ int stride, int h, int x, int y);
+void ff_avg_rv40_chroma_mc4_mmx2 (uint8_t *dst, uint8_t *src,
+ int stride, int h, int x, int y);
+void ff_avg_rv40_chroma_mc4_3dnow(uint8_t *dst, uint8_t *src,
+ int stride, int h, int x, int y);
+
+void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp)
+{
+ av_unused int mm_flags = av_get_cpu_flags();
+
+#if HAVE_YASM
+ if (mm_flags & AV_CPU_FLAG_MMX) {
+ c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx;
+ c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx;
+ }
+ if (mm_flags & AV_CPU_FLAG_MMX2) {
+ c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_mmx2;
+ c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_mmx2;
+ } else if (mm_flags & AV_CPU_FLAG_3DNOW) {
+ c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow;
+ c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow;
+ }
+#endif
+}
diff --git a/libavcodec/x86/simple_idct_mmx.c b/libavcodec/x86/simple_idct_mmx.c
index d78ae6b..dc285cf 100644
--- a/libavcodec/x86/simple_idct_mmx.c
+++ b/libavcodec/x86/simple_idct_mmx.c
@@ -37,11 +37,7 @@
#define C1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define C2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define C3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-#if 0
-#define C4 16384 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-#else
#define C4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) - 0.5
-#endif
#define C5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define C6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
#define C7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
@@ -80,135 +76,6 @@ DECLARE_ALIGNED(8, static const int16_t, coeffs)[]= {
C3, -C1, C3, -C1
};
-#if 0
-static void unused_var_killer(void)
-{
- int a= wm1010 + d40000;
- temp[0]=a;
-}
-
-static void inline idctCol (int16_t * col, int16_t *input)
-{
-#undef C0
-#undef C1
-#undef C2
-#undef C3
-#undef C4
-#undef C5
-#undef C6
-#undef C7
- int a0, a1, a2, a3, b0, b1, b2, b3;
- const int C0 = 23170; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C1 = 22725; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C2 = 21407; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C3 = 19266; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C4 = 16383; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C5 = 12873; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C6 = 8867; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C7 = 4520; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-/*
- if( !(col[8*1] | col[8*2] |col[8*3] |col[8*4] |col[8*5] |col[8*6] | col[8*7])) {
- col[8*0] = col[8*1] = col[8*2] = col[8*3] = col[8*4] =
- col[8*5] = col[8*6] = col[8*7] = col[8*0]<<3;
- return;
- }*/
-
-col[8*0] = input[8*0 + 0];
-col[8*1] = input[8*2 + 0];
-col[8*2] = input[8*0 + 1];
-col[8*3] = input[8*2 + 1];
-col[8*4] = input[8*4 + 0];
-col[8*5] = input[8*6 + 0];
-col[8*6] = input[8*4 + 1];
-col[8*7] = input[8*6 + 1];
-
- a0 = C4*col[8*0] + C2*col[8*2] + C4*col[8*4] + C6*col[8*6] + (1<<(COL_SHIFT-1));
- a1 = C4*col[8*0] + C6*col[8*2] - C4*col[8*4] - C2*col[8*6] + (1<<(COL_SHIFT-1));
- a2 = C4*col[8*0] - C6*col[8*2] - C4*col[8*4] + C2*col[8*6] + (1<<(COL_SHIFT-1));
- a3 = C4*col[8*0] - C2*col[8*2] + C4*col[8*4] - C6*col[8*6] + (1<<(COL_SHIFT-1));
-
- b0 = C1*col[8*1] + C3*col[8*3] + C5*col[8*5] + C7*col[8*7];
- b1 = C3*col[8*1] - C7*col[8*3] - C1*col[8*5] - C5*col[8*7];
- b2 = C5*col[8*1] - C1*col[8*3] + C7*col[8*5] + C3*col[8*7];
- b3 = C7*col[8*1] - C5*col[8*3] + C3*col[8*5] - C1*col[8*7];
-
- col[8*0] = (a0 + b0) >> COL_SHIFT;
- col[8*1] = (a1 + b1) >> COL_SHIFT;
- col[8*2] = (a2 + b2) >> COL_SHIFT;
- col[8*3] = (a3 + b3) >> COL_SHIFT;
- col[8*4] = (a3 - b3) >> COL_SHIFT;
- col[8*5] = (a2 - b2) >> COL_SHIFT;
- col[8*6] = (a1 - b1) >> COL_SHIFT;
- col[8*7] = (a0 - b0) >> COL_SHIFT;
-}
-
-static void inline idctRow (int16_t * output, int16_t * input)
-{
- int16_t row[8];
-
- int a0, a1, a2, a3, b0, b1, b2, b3;
- const int C0 = 23170; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C1 = 22725; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C2 = 21407; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C3 = 19266; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C4 = 16383; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C5 = 12873; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C6 = 8867; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
- const int C7 = 4520; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
-
-row[0] = input[0];
-row[2] = input[1];
-row[4] = input[4];
-row[6] = input[5];
-row[1] = input[8];
-row[3] = input[9];
-row[5] = input[12];
-row[7] = input[13];
-
- if( !(row[1] | row[2] |row[3] |row[4] |row[5] |row[6] | row[7]) ) {
- row[0] = row[1] = row[2] = row[3] = row[4] =
- row[5] = row[6] = row[7] = row[0]<<3;
- output[0] = row[0];
- output[2] = row[1];
- output[4] = row[2];
- output[6] = row[3];
- output[8] = row[4];
- output[10] = row[5];
- output[12] = row[6];
- output[14] = row[7];
- return;
- }
-
- a0 = C4*row[0] + C2*row[2] + C4*row[4] + C6*row[6] + (1<<(ROW_SHIFT-1));
- a1 = C4*row[0] + C6*row[2] - C4*row[4] - C2*row[6] + (1<<(ROW_SHIFT-1));
- a2 = C4*row[0] - C6*row[2] - C4*row[4] + C2*row[6] + (1<<(ROW_SHIFT-1));
- a3 = C4*row[0] - C2*row[2] + C4*row[4] - C6*row[6] + (1<<(ROW_SHIFT-1));
-
- b0 = C1*row[1] + C3*row[3] + C5*row[5] + C7*row[7];
- b1 = C3*row[1] - C7*row[3] - C1*row[5] - C5*row[7];
- b2 = C5*row[1] - C1*row[3] + C7*row[5] + C3*row[7];
- b3 = C7*row[1] - C5*row[3] + C3*row[5] - C1*row[7];
-
- row[0] = (a0 + b0) >> ROW_SHIFT;
- row[1] = (a1 + b1) >> ROW_SHIFT;
- row[2] = (a2 + b2) >> ROW_SHIFT;
- row[3] = (a3 + b3) >> ROW_SHIFT;
- row[4] = (a3 - b3) >> ROW_SHIFT;
- row[5] = (a2 - b2) >> ROW_SHIFT;
- row[6] = (a1 - b1) >> ROW_SHIFT;
- row[7] = (a0 - b0) >> ROW_SHIFT;
-
- output[0] = row[0];
- output[2] = row[1];
- output[4] = row[2];
- output[6] = row[3];
- output[8] = row[4];
- output[10] = row[5];
- output[12] = row[6];
- output[14] = row[7];
-}
-#endif
-
static inline void idct(int16_t *block)
{
DECLARE_ALIGNED(8, int64_t, align_tmp)[16];
diff --git a/libavcodec/x86/vc1dsp_yasm.asm b/libavcodec/x86/vc1dsp_yasm.asm
index 220cc03..66f61db 100644
--- a/libavcodec/x86/vc1dsp_yasm.asm
+++ b/libavcodec/x86/vc1dsp_yasm.asm
@@ -227,7 +227,7 @@ section .text
imul r2, 0x01010101
%endmacro
-; I dont know why the sign extension is needed...
+; I do not know why the sign extension is needed...
%macro PSIGNW_SRA_MMX 2
psraw %2, 15
PSIGNW_MMX %1, %2
diff --git a/libavcodec/x86/vp8dsp-init.c b/libavcodec/x86/vp8dsp-init.c
index 8b27b0d..f5e89fa 100644
--- a/libavcodec/x86/vp8dsp-init.c
+++ b/libavcodec/x86/vp8dsp-init.c
@@ -283,9 +283,9 @@ DECLARE_LOOP_FILTER(sse4)
av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
{
+#if HAVE_YASM
int mm_flags = av_get_cpu_flags();
-#if HAVE_YASM
if (mm_flags & AV_CPU_FLAG_MMX) {
c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx;
c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_mmx;
diff --git a/libavcodec/x86/x86inc.asm b/libavcodec/x86/x86inc.asm
deleted file mode 100644
index c84d556..0000000
--- a/libavcodec/x86/x86inc.asm
+++ /dev/null
@@ -1,905 +0,0 @@
-;*****************************************************************************
-;* x86inc.asm
-;*****************************************************************************
-;* Copyright (C) 2005-2011 x264 project
-;*
-;* Authors: Loren Merritt <lorenm at u.washington.edu>
-;* Anton Mitrofanov <BugMaster at narod.ru>
-;* Jason Garrett-Glaser <darkshikari at gmail.com>
-;*
-;* Permission to use, copy, modify, and/or distribute this software for any
-;* purpose with or without fee is hereby granted, provided that the above
-;* copyright notice and this permission notice appear in all copies.
-;*
-;* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;*****************************************************************************
-
-; This is a header file for the x264ASM assembly language, which uses
-; NASM/YASM syntax combined with a large number of macros to provide easy
-; abstraction between different calling conventions (x86_32, win64, linux64).
-; It also has various other useful features to simplify writing the kind of
-; DSP functions that are most often used in x264.
-
-; Unlike the rest of x264, this file is available under an ISC license, as it
-; has significant usefulness outside of x264 and we want it to be available
-; to the largest audience possible. Of course, if you modify it for your own
-; purposes to add a new feature, we strongly encourage contributing a patch
-; as this feature might be useful for others as well. Send patches or ideas
-; to x264-devel at videolan.org .
-
-%define program_name ff
-
-%ifdef ARCH_X86_64
- %ifidn __OUTPUT_FORMAT__,win32
- %define WIN64
- %else
- %define UNIX64
- %endif
-%endif
-
-%ifdef PREFIX
- %define mangle(x) _ %+ x
-%else
- %define mangle(x) x
-%endif
-
-; FIXME: All of the 64bit asm functions that take a stride as an argument
-; via register, assume that the high dword of that register is filled with 0.
-; This is true in practice (since we never do any 64bit arithmetic on strides,
-; and x264's strides are all positive), but is not guaranteed by the ABI.
-
-; Name of the .rodata section.
-; Kludge: Something on OS X fails to align .rodata even given an align attribute,
-; so use a different read-only section.
-%macro SECTION_RODATA 0-1 16
- %ifidn __OUTPUT_FORMAT__,macho64
- SECTION .text align=%1
- %elifidn __OUTPUT_FORMAT__,macho
- SECTION .text align=%1
- fakegot:
- %elifidn __OUTPUT_FORMAT__,aout
- section .text
- %else
- SECTION .rodata align=%1
- %endif
-%endmacro
-
-; aout does not support align=
-%macro SECTION_TEXT 0-1 16
- %ifidn __OUTPUT_FORMAT__,aout
- SECTION .text
- %else
- SECTION .text align=%1
- %endif
-%endmacro
-
-%ifdef WIN64
- %define PIC
-%elifndef ARCH_X86_64
-; x86_32 doesn't require PIC.
-; Some distros prefer shared objects to be PIC, but nothing breaks if
-; the code contains a few textrels, so we'll skip that complexity.
- %undef PIC
-%endif
-%ifdef PIC
- default rel
-%endif
-
-; Macros to eliminate most code duplication between x86_32 and x86_64:
-; Currently this works only for leaf functions which load all their arguments
-; into registers at the start, and make no other use of the stack. Luckily that
-; covers most of x264's asm.
-
-; PROLOGUE:
-; %1 = number of arguments. loads them from stack if needed.
-; %2 = number of registers used. pushes callee-saved regs if needed.
-; %3 = number of xmm registers used. pushes callee-saved xmm regs if needed.
-; %4 = list of names to define to registers
-; PROLOGUE can also be invoked by adding the same options to cglobal
-
-; e.g.
-; cglobal foo, 2,3,0, dst, src, tmp
-; declares a function (foo), taking two args (dst and src) and one local variable (tmp)
-
-; TODO Some functions can use some args directly from the stack. If they're the
-; last args then you can just not declare them, but if they're in the middle
-; we need more flexible macro.
-
-; RET:
-; Pops anything that was pushed by PROLOGUE
-
-; REP_RET:
-; Same, but if it doesn't pop anything it becomes a 2-byte ret, for athlons
-; which are slow when a normal ret follows a branch.
-
-; registers:
-; rN and rNq are the native-size register holding function argument N
-; rNd, rNw, rNb are dword, word, and byte size
-; rNm is the original location of arg N (a register or on the stack), dword
-; rNmp is native size
-
-%macro DECLARE_REG 6
- %define r%1q %2
- %define r%1d %3
- %define r%1w %4
- %define r%1b %5
- %define r%1m %6
- %ifid %6 ; i.e. it's a register
- %define r%1mp %2
- %elifdef ARCH_X86_64 ; memory
- %define r%1mp qword %6
- %else
- %define r%1mp dword %6
- %endif
- %define r%1 %2
-%endmacro
-
-%macro DECLARE_REG_SIZE 2
- %define r%1q r%1
- %define e%1q r%1
- %define r%1d e%1
- %define e%1d e%1
- %define r%1w %1
- %define e%1w %1
- %define r%1b %2
- %define e%1b %2
-%ifndef ARCH_X86_64
- %define r%1 e%1
-%endif
-%endmacro
-
-DECLARE_REG_SIZE ax, al
-DECLARE_REG_SIZE bx, bl
-DECLARE_REG_SIZE cx, cl
-DECLARE_REG_SIZE dx, dl
-DECLARE_REG_SIZE si, sil
-DECLARE_REG_SIZE di, dil
-DECLARE_REG_SIZE bp, bpl
-
-; t# defines for when per-arch register allocation is more complex than just function arguments
-
-%macro DECLARE_REG_TMP 1-*
- %assign %%i 0
- %rep %0
- CAT_XDEFINE t, %%i, r%1
- %assign %%i %%i+1
- %rotate 1
- %endrep
-%endmacro
-
-%macro DECLARE_REG_TMP_SIZE 0-*
- %rep %0
- %define t%1q t%1 %+ q
- %define t%1d t%1 %+ d
- %define t%1w t%1 %+ w
- %define t%1b t%1 %+ b
- %rotate 1
- %endrep
-%endmacro
-
-DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9
-
-%ifdef ARCH_X86_64
- %define gprsize 8
-%else
- %define gprsize 4
-%endif
-
-%macro PUSH 1
- push %1
- %assign stack_offset stack_offset+gprsize
-%endmacro
-
-%macro POP 1
- pop %1
- %assign stack_offset stack_offset-gprsize
-%endmacro
-
-%macro SUB 2
- sub %1, %2
- %ifidn %1, rsp
- %assign stack_offset stack_offset+(%2)
- %endif
-%endmacro
-
-%macro ADD 2
- add %1, %2
- %ifidn %1, rsp
- %assign stack_offset stack_offset-(%2)
- %endif
-%endmacro
-
-%macro movifnidn 2
- %ifnidn %1, %2
- mov %1, %2
- %endif
-%endmacro
-
-%macro movsxdifnidn 2
- %ifnidn %1, %2
- movsxd %1, %2
- %endif
-%endmacro
-
-%macro ASSERT 1
- %if (%1) == 0
- %error assert failed
- %endif
-%endmacro
-
-%macro DEFINE_ARGS 0-*
- %ifdef n_arg_names
- %assign %%i 0
- %rep n_arg_names
- CAT_UNDEF arg_name %+ %%i, q
- CAT_UNDEF arg_name %+ %%i, d
- CAT_UNDEF arg_name %+ %%i, w
- CAT_UNDEF arg_name %+ %%i, b
- CAT_UNDEF arg_name %+ %%i, m
- CAT_UNDEF arg_name, %%i
- %assign %%i %%i+1
- %endrep
- %endif
-
- %assign %%i 0
- %rep %0
- %xdefine %1q r %+ %%i %+ q
- %xdefine %1d r %+ %%i %+ d
- %xdefine %1w r %+ %%i %+ w
- %xdefine %1b r %+ %%i %+ b
- %xdefine %1m r %+ %%i %+ m
- CAT_XDEFINE arg_name, %%i, %1
- %assign %%i %%i+1
- %rotate 1
- %endrep
- %assign n_arg_names %%i
-%endmacro
-
-%ifdef WIN64 ; Windows x64 ;=================================================
-
-DECLARE_REG 0, rcx, ecx, cx, cl, ecx
-DECLARE_REG 1, rdx, edx, dx, dl, edx
-DECLARE_REG 2, r8, r8d, r8w, r8b, r8d
-DECLARE_REG 3, r9, r9d, r9w, r9b, r9d
-DECLARE_REG 4, rdi, edi, di, dil, [rsp + stack_offset + 40]
-DECLARE_REG 5, rsi, esi, si, sil, [rsp + stack_offset + 48]
-DECLARE_REG 6, rax, eax, ax, al, [rsp + stack_offset + 56]
-%define r7m [rsp + stack_offset + 64]
-%define r8m [rsp + stack_offset + 72]
-
-%macro LOAD_IF_USED 2 ; reg_id, number_of_args
- %if %1 < %2
- mov r%1, [rsp + stack_offset + 8 + %1*8]
- %endif
-%endmacro
-
-%macro PROLOGUE 2-4+ 0 ; #args, #regs, #xmm_regs, arg_names...
- ASSERT %2 >= %1
- %assign regs_used %2
- ASSERT regs_used <= 7
- %if regs_used > 4
- push r4
- push r5
- %assign stack_offset stack_offset+16
- %endif
- WIN64_SPILL_XMM %3
- LOAD_IF_USED 4, %1
- LOAD_IF_USED 5, %1
- LOAD_IF_USED 6, %1
- DEFINE_ARGS %4
-%endmacro
-
-%macro WIN64_SPILL_XMM 1
- %assign xmm_regs_used %1
- ASSERT xmm_regs_used <= 16
- %if xmm_regs_used > 6
- sub rsp, (xmm_regs_used-6)*16+16
- %assign stack_offset stack_offset+(xmm_regs_used-6)*16+16
- %assign %%i xmm_regs_used
- %rep (xmm_regs_used-6)
- %assign %%i %%i-1
- movdqa [rsp + (%%i-6)*16+8], xmm %+ %%i
- %endrep
- %endif
-%endmacro
-
-%macro WIN64_RESTORE_XMM_INTERNAL 1
- %if xmm_regs_used > 6
- %assign %%i xmm_regs_used
- %rep (xmm_regs_used-6)
- %assign %%i %%i-1
- movdqa xmm %+ %%i, [%1 + (%%i-6)*16+8]
- %endrep
- add %1, (xmm_regs_used-6)*16+16
- %endif
-%endmacro
-
-%macro WIN64_RESTORE_XMM 1
- WIN64_RESTORE_XMM_INTERNAL %1
- %assign stack_offset stack_offset-(xmm_regs_used-6)*16+16
- %assign xmm_regs_used 0
-%endmacro
-
-%macro RET 0
- WIN64_RESTORE_XMM_INTERNAL rsp
- %if regs_used > 4
- pop r5
- pop r4
- %endif
- ret
-%endmacro
-
-%macro REP_RET 0
- %if regs_used > 4 || xmm_regs_used > 6
- RET
- %else
- rep ret
- %endif
-%endmacro
-
-%elifdef ARCH_X86_64 ; *nix x64 ;=============================================
-
-DECLARE_REG 0, rdi, edi, di, dil, edi
-DECLARE_REG 1, rsi, esi, si, sil, esi
-DECLARE_REG 2, rdx, edx, dx, dl, edx
-DECLARE_REG 3, rcx, ecx, cx, cl, ecx
-DECLARE_REG 4, r8, r8d, r8w, r8b, r8d
-DECLARE_REG 5, r9, r9d, r9w, r9b, r9d
-DECLARE_REG 6, rax, eax, ax, al, [rsp + stack_offset + 8]
-%define r7m [rsp + stack_offset + 16]
-%define r8m [rsp + stack_offset + 24]
-
-%macro LOAD_IF_USED 2 ; reg_id, number_of_args
- %if %1 < %2
- mov r%1, [rsp - 40 + %1*8]
- %endif
-%endmacro
-
-%macro PROLOGUE 2-4+ ; #args, #regs, #xmm_regs, arg_names...
- ASSERT %2 >= %1
- ASSERT %2 <= 7
- LOAD_IF_USED 6, %1
- DEFINE_ARGS %4
-%endmacro
-
-%macro RET 0
- ret
-%endmacro
-
-%macro REP_RET 0
- rep ret
-%endmacro
-
-%else ; X86_32 ;==============================================================
-
-DECLARE_REG 0, eax, eax, ax, al, [esp + stack_offset + 4]
-DECLARE_REG 1, ecx, ecx, cx, cl, [esp + stack_offset + 8]
-DECLARE_REG 2, edx, edx, dx, dl, [esp + stack_offset + 12]
-DECLARE_REG 3, ebx, ebx, bx, bl, [esp + stack_offset + 16]
-DECLARE_REG 4, esi, esi, si, null, [esp + stack_offset + 20]
-DECLARE_REG 5, edi, edi, di, null, [esp + stack_offset + 24]
-DECLARE_REG 6, ebp, ebp, bp, null, [esp + stack_offset + 28]
-%define r7m [esp + stack_offset + 32]
-%define r8m [esp + stack_offset + 36]
-%define rsp esp
-
-%macro PUSH_IF_USED 1 ; reg_id
- %if %1 < regs_used
- push r%1
- %assign stack_offset stack_offset+4
- %endif
-%endmacro
-
-%macro POP_IF_USED 1 ; reg_id
- %if %1 < regs_used
- pop r%1
- %endif
-%endmacro
-
-%macro LOAD_IF_USED 2 ; reg_id, number_of_args
- %if %1 < %2
- mov r%1, [esp + stack_offset + 4 + %1*4]
- %endif
-%endmacro
-
-%macro PROLOGUE 2-4+ ; #args, #regs, #xmm_regs, arg_names...
- ASSERT %2 >= %1
- %assign regs_used %2
- ASSERT regs_used <= 7
- PUSH_IF_USED 3
- PUSH_IF_USED 4
- PUSH_IF_USED 5
- PUSH_IF_USED 6
- LOAD_IF_USED 0, %1
- LOAD_IF_USED 1, %1
- LOAD_IF_USED 2, %1
- LOAD_IF_USED 3, %1
- LOAD_IF_USED 4, %1
- LOAD_IF_USED 5, %1
- LOAD_IF_USED 6, %1
- DEFINE_ARGS %4
-%endmacro
-
-%macro RET 0
- POP_IF_USED 6
- POP_IF_USED 5
- POP_IF_USED 4
- POP_IF_USED 3
- ret
-%endmacro
-
-%macro REP_RET 0
- %if regs_used > 3
- RET
- %else
- rep ret
- %endif
-%endmacro
-
-%endif ;======================================================================
-
-%ifndef WIN64
-%macro WIN64_SPILL_XMM 1
-%endmacro
-%macro WIN64_RESTORE_XMM 1
-%endmacro
-%endif
-
-
-
-;=============================================================================
-; arch-independent part
-;=============================================================================
-
-%assign function_align 16
-
-; Symbol prefix for C linkage
-%macro cglobal 1-2+
- %xdefine %1 mangle(program_name %+ _ %+ %1)
- %xdefine %1.skip_prologue %1 %+ .skip_prologue
- %ifidn __OUTPUT_FORMAT__,elf
- global %1:function hidden
- %else
- global %1
- %endif
- align function_align
- %1:
- RESET_MM_PERMUTATION ; not really needed, but makes disassembly somewhat nicer
- %assign stack_offset 0
- %if %0 > 1
- PROLOGUE %2
- %endif
-%endmacro
-
-%macro cextern 1
- %xdefine %1 mangle(program_name %+ _ %+ %1)
- extern %1
-%endmacro
-
-;like cextern, but without the prefix
-%macro cextern_naked 1
- %xdefine %1 mangle(%1)
- extern %1
-%endmacro
-
-%macro const 2+
- %xdefine %1 mangle(program_name %+ _ %+ %1)
- global %1
- %1: %2
-%endmacro
-
-; This is needed for ELF, otherwise the GNU linker assumes the stack is
-; executable by default.
-%ifidn __OUTPUT_FORMAT__,elf
-SECTION .note.GNU-stack noalloc noexec nowrite progbits
-%endif
-
-; merge mmx and sse*
-
-%macro CAT_XDEFINE 3
- %xdefine %1%2 %3
-%endmacro
-
-%macro CAT_UNDEF 2
- %undef %1%2
-%endmacro
-
-%macro INIT_MMX 0
- %assign avx_enabled 0
- %define RESET_MM_PERMUTATION INIT_MMX
- %define mmsize 8
- %define num_mmregs 8
- %define mova movq
- %define movu movq
- %define movh movd
- %define movnta movntq
- %assign %%i 0
- %rep 8
- CAT_XDEFINE m, %%i, mm %+ %%i
- CAT_XDEFINE nmm, %%i, %%i
- %assign %%i %%i+1
- %endrep
- %rep 8
- CAT_UNDEF m, %%i
- CAT_UNDEF nmm, %%i
- %assign %%i %%i+1
- %endrep
-%endmacro
-
-%macro INIT_XMM 0
- %assign avx_enabled 0
- %define RESET_MM_PERMUTATION INIT_XMM
- %define mmsize 16
- %define num_mmregs 8
- %ifdef ARCH_X86_64
- %define num_mmregs 16
- %endif
- %define mova movdqa
- %define movu movdqu
- %define movh movq
- %define movnta movntdq
- %assign %%i 0
- %rep num_mmregs
- CAT_XDEFINE m, %%i, xmm %+ %%i
- CAT_XDEFINE nxmm, %%i, %%i
- %assign %%i %%i+1
- %endrep
-%endmacro
-
-%macro INIT_AVX 0
- INIT_XMM
- %assign avx_enabled 1
- %define PALIGNR PALIGNR_SSSE3
- %define RESET_MM_PERMUTATION INIT_AVX
-%endmacro
-
-%macro INIT_YMM 0
- %assign avx_enabled 1
- %define RESET_MM_PERMUTATION INIT_YMM
- %define mmsize 32
- %define num_mmregs 8
- %ifdef ARCH_X86_64
- %define num_mmregs 16
- %endif
- %define mova vmovaps
- %define movu vmovups
- %assign %%i 0
- %rep num_mmregs
- CAT_XDEFINE m, %%i, ymm %+ %%i
- CAT_XDEFINE nymm, %%i, %%i
- %assign %%i %%i+1
- %endrep
-%endmacro
-
-INIT_MMX
-
-; I often want to use macros that permute their arguments. e.g. there's no
-; efficient way to implement butterfly or transpose or dct without swapping some
-; arguments.
-;
-; I would like to not have to manually keep track of the permutations:
-; If I insert a permutation in the middle of a function, it should automatically
-; change everything that follows. For more complex macros I may also have multiple
-; implementations, e.g. the SSE2 and SSSE3 versions may have different permutations.
-;
-; Hence these macros. Insert a PERMUTE or some SWAPs at the end of a macro that
-; permutes its arguments. It's equivalent to exchanging the contents of the
-; registers, except that this way you exchange the register names instead, so it
-; doesn't cost any cycles.
-
-%macro PERMUTE 2-* ; takes a list of pairs to swap
-%rep %0/2
- %xdefine tmp%2 m%2
- %xdefine ntmp%2 nm%2
- %rotate 2
-%endrep
-%rep %0/2
- %xdefine m%1 tmp%2
- %xdefine nm%1 ntmp%2
- %undef tmp%2
- %undef ntmp%2
- %rotate 2
-%endrep
-%endmacro
-
-%macro SWAP 2-* ; swaps a single chain (sometimes more concise than pairs)
-%rep %0-1
-%ifdef m%1
- %xdefine tmp m%1
- %xdefine m%1 m%2
- %xdefine m%2 tmp
- CAT_XDEFINE n, m%1, %1
- CAT_XDEFINE n, m%2, %2
-%else
- ; If we were called as "SWAP m0,m1" rather than "SWAP 0,1" infer the original numbers here.
- ; Be careful using this mode in nested macros though, as in some cases there may be
- ; other copies of m# that have already been dereferenced and don't get updated correctly.
- %xdefine %%n1 n %+ %1
- %xdefine %%n2 n %+ %2
- %xdefine tmp m %+ %%n1
- CAT_XDEFINE m, %%n1, m %+ %%n2
- CAT_XDEFINE m, %%n2, tmp
- CAT_XDEFINE n, m %+ %%n1, %%n1
- CAT_XDEFINE n, m %+ %%n2, %%n2
-%endif
- %undef tmp
- %rotate 1
-%endrep
-%endmacro
-
-; If SAVE_MM_PERMUTATION is placed at the end of a function and given the
-; function name, then any later calls to that function will automatically
-; load the permutation, so values can be returned in mmregs.
-%macro SAVE_MM_PERMUTATION 1 ; name to save as
- %assign %%i 0
- %rep num_mmregs
- CAT_XDEFINE %1_m, %%i, m %+ %%i
- %assign %%i %%i+1
- %endrep
-%endmacro
-
-%macro LOAD_MM_PERMUTATION 1 ; name to load from
- %assign %%i 0
- %rep num_mmregs
- CAT_XDEFINE m, %%i, %1_m %+ %%i
- CAT_XDEFINE n, m %+ %%i, %%i
- %assign %%i %%i+1
- %endrep
-%endmacro
-
-%macro call 1
- call %1
- %ifdef %1_m0
- LOAD_MM_PERMUTATION %1
- %endif
-%endmacro
-
-; Substitutions that reduce instruction size but are functionally equivalent
-%macro add 2
- %ifnum %2
- %if %2==128
- sub %1, -128
- %else
- add %1, %2
- %endif
- %else
- add %1, %2
- %endif
-%endmacro
-
-%macro sub 2
- %ifnum %2
- %if %2==128
- add %1, -128
- %else
- sub %1, %2
- %endif
- %else
- sub %1, %2
- %endif
-%endmacro
-
-;=============================================================================
-; AVX abstraction layer
-;=============================================================================
-
-%assign i 0
-%rep 16
- %if i < 8
- CAT_XDEFINE sizeofmm, i, 8
- %endif
- CAT_XDEFINE sizeofxmm, i, 16
- CAT_XDEFINE sizeofymm, i, 32
-%assign i i+1
-%endrep
-%undef i
-
-;%1 == instruction
-;%2 == 1 if float, 0 if int
-;%3 == 0 if 3-operand (xmm, xmm, xmm), 1 if 4-operand (xmm, xmm, xmm, imm)
-;%4 == number of operands given
-;%5+: operands
-%macro RUN_AVX_INSTR 6-7+
- %if sizeof%5==32
- v%1 %5, %6, %7
- %else
- %if sizeof%5==8
- %define %%regmov movq
- %elif %2
- %define %%regmov movaps
- %else
- %define %%regmov movdqa
- %endif
-
- %if %4>=3+%3
- %ifnidn %5, %6
- %if avx_enabled && sizeof%5==16
- v%1 %5, %6, %7
- %else
- %%regmov %5, %6
- %1 %5, %7
- %endif
- %else
- %1 %5, %7
- %endif
- %elif %3
- %1 %5, %6, %7
- %else
- %1 %5, %6
- %endif
- %endif
-%endmacro
-
-;%1 == instruction
-;%2 == 1 if float, 0 if int
-;%3 == 0 if 3-operand (xmm, xmm, xmm), 1 if 4-operand (xmm, xmm, xmm, imm)
-%macro AVX_INSTR 3
- %macro %1 2-8 fnord, fnord, fnord, %1, %2, %3
- %ifidn %3, fnord
- RUN_AVX_INSTR %6, %7, %8, 2, %1, %2
- %elifidn %4, fnord
- RUN_AVX_INSTR %6, %7, %8, 3, %1, %2, %3
- %elifidn %5, fnord
- RUN_AVX_INSTR %6, %7, %8, 4, %1, %2, %3, %4
- %else
- RUN_AVX_INSTR %6, %7, %8, 5, %1, %2, %3, %4, %5
- %endif
- %endmacro
-%endmacro
-
-AVX_INSTR addpd, 1, 0
-AVX_INSTR addps, 1, 0
-AVX_INSTR addsd, 1, 0
-AVX_INSTR addss, 1, 0
-AVX_INSTR addsubpd, 1, 0
-AVX_INSTR addsubps, 1, 0
-AVX_INSTR andpd, 1, 0
-AVX_INSTR andps, 1, 0
-AVX_INSTR andnpd, 1, 0
-AVX_INSTR andnps, 1, 0
-AVX_INSTR blendpd, 1, 0
-AVX_INSTR blendps, 1, 0
-AVX_INSTR blendvpd, 1, 0
-AVX_INSTR blendvps, 1, 0
-AVX_INSTR cmppd, 1, 0
-AVX_INSTR cmpps, 1, 0
-AVX_INSTR cmpsd, 1, 0
-AVX_INSTR cmpss, 1, 0
-AVX_INSTR divpd, 1, 0
-AVX_INSTR divps, 1, 0
-AVX_INSTR divsd, 1, 0
-AVX_INSTR divss, 1, 0
-AVX_INSTR dppd, 1, 0
-AVX_INSTR dpps, 1, 0
-AVX_INSTR haddpd, 1, 0
-AVX_INSTR haddps, 1, 0
-AVX_INSTR hsubpd, 1, 0
-AVX_INSTR hsubps, 1, 0
-AVX_INSTR maxpd, 1, 0
-AVX_INSTR maxps, 1, 0
-AVX_INSTR maxsd, 1, 0
-AVX_INSTR maxss, 1, 0
-AVX_INSTR minpd, 1, 0
-AVX_INSTR minps, 1, 0
-AVX_INSTR minsd, 1, 0
-AVX_INSTR minss, 1, 0
-AVX_INSTR mpsadbw, 0, 1
-AVX_INSTR mulpd, 1, 0
-AVX_INSTR mulps, 1, 0
-AVX_INSTR mulsd, 1, 0
-AVX_INSTR mulss, 1, 0
-AVX_INSTR orpd, 1, 0
-AVX_INSTR orps, 1, 0
-AVX_INSTR packsswb, 0, 0
-AVX_INSTR packssdw, 0, 0
-AVX_INSTR packuswb, 0, 0
-AVX_INSTR packusdw, 0, 0
-AVX_INSTR paddb, 0, 0
-AVX_INSTR paddw, 0, 0
-AVX_INSTR paddd, 0, 0
-AVX_INSTR paddq, 0, 0
-AVX_INSTR paddsb, 0, 0
-AVX_INSTR paddsw, 0, 0
-AVX_INSTR paddusb, 0, 0
-AVX_INSTR paddusw, 0, 0
-AVX_INSTR palignr, 0, 1
-AVX_INSTR pand, 0, 0
-AVX_INSTR pandn, 0, 0
-AVX_INSTR pavgb, 0, 0
-AVX_INSTR pavgw, 0, 0
-AVX_INSTR pblendvb, 0, 0
-AVX_INSTR pblendw, 0, 1
-AVX_INSTR pcmpestri, 0, 0
-AVX_INSTR pcmpestrm, 0, 0
-AVX_INSTR pcmpistri, 0, 0
-AVX_INSTR pcmpistrm, 0, 0
-AVX_INSTR pcmpeqb, 0, 0
-AVX_INSTR pcmpeqw, 0, 0
-AVX_INSTR pcmpeqd, 0, 0
-AVX_INSTR pcmpeqq, 0, 0
-AVX_INSTR pcmpgtb, 0, 0
-AVX_INSTR pcmpgtw, 0, 0
-AVX_INSTR pcmpgtd, 0, 0
-AVX_INSTR pcmpgtq, 0, 0
-AVX_INSTR phaddw, 0, 0
-AVX_INSTR phaddd, 0, 0
-AVX_INSTR phaddsw, 0, 0
-AVX_INSTR phsubw, 0, 0
-AVX_INSTR phsubd, 0, 0
-AVX_INSTR phsubsw, 0, 0
-AVX_INSTR pmaddwd, 0, 0
-AVX_INSTR pmaddubsw, 0, 0
-AVX_INSTR pmaxsb, 0, 0
-AVX_INSTR pmaxsw, 0, 0
-AVX_INSTR pmaxsd, 0, 0
-AVX_INSTR pmaxub, 0, 0
-AVX_INSTR pmaxuw, 0, 0
-AVX_INSTR pmaxud, 0, 0
-AVX_INSTR pminsb, 0, 0
-AVX_INSTR pminsw, 0, 0
-AVX_INSTR pminsd, 0, 0
-AVX_INSTR pminub, 0, 0
-AVX_INSTR pminuw, 0, 0
-AVX_INSTR pminud, 0, 0
-AVX_INSTR pmulhuw, 0, 0
-AVX_INSTR pmulhrsw, 0, 0
-AVX_INSTR pmulhw, 0, 0
-AVX_INSTR pmullw, 0, 0
-AVX_INSTR pmulld, 0, 0
-AVX_INSTR pmuludq, 0, 0
-AVX_INSTR pmuldq, 0, 0
-AVX_INSTR por, 0, 0
-AVX_INSTR psadbw, 0, 0
-AVX_INSTR pshufb, 0, 0
-AVX_INSTR psignb, 0, 0
-AVX_INSTR psignw, 0, 0
-AVX_INSTR psignd, 0, 0
-AVX_INSTR psllw, 0, 0
-AVX_INSTR pslld, 0, 0
-AVX_INSTR psllq, 0, 0
-AVX_INSTR pslldq, 0, 0
-AVX_INSTR psraw, 0, 0
-AVX_INSTR psrad, 0, 0
-AVX_INSTR psrlw, 0, 0
-AVX_INSTR psrld, 0, 0
-AVX_INSTR psrlq, 0, 0
-AVX_INSTR psrldq, 0, 0
-AVX_INSTR psubb, 0, 0
-AVX_INSTR psubw, 0, 0
-AVX_INSTR psubd, 0, 0
-AVX_INSTR psubq, 0, 0
-AVX_INSTR psubsb, 0, 0
-AVX_INSTR psubsw, 0, 0
-AVX_INSTR psubusb, 0, 0
-AVX_INSTR psubusw, 0, 0
-AVX_INSTR punpckhbw, 0, 0
-AVX_INSTR punpckhwd, 0, 0
-AVX_INSTR punpckhdq, 0, 0
-AVX_INSTR punpckhqdq, 0, 0
-AVX_INSTR punpcklbw, 0, 0
-AVX_INSTR punpcklwd, 0, 0
-AVX_INSTR punpckldq, 0, 0
-AVX_INSTR punpcklqdq, 0, 0
-AVX_INSTR pxor, 0, 0
-AVX_INSTR shufps, 0, 1
-AVX_INSTR subpd, 1, 0
-AVX_INSTR subps, 1, 0
-AVX_INSTR subsd, 1, 0
-AVX_INSTR subss, 1, 0
-AVX_INSTR unpckhpd, 1, 0
-AVX_INSTR unpckhps, 1, 0
-AVX_INSTR unpcklpd, 1, 0
-AVX_INSTR unpcklps, 1, 0
-AVX_INSTR xorpd, 1, 0
-AVX_INSTR xorps, 1, 0
-
-; 3DNow instructions, for sharing code between AVX, SSE and 3DN
-AVX_INSTR pfadd, 1, 0
-AVX_INSTR pfsub, 1, 0
-AVX_INSTR pfmul, 1, 0
diff --git a/libavcodec/x86/x86util.asm b/libavcodec/x86/x86util.asm
deleted file mode 100644
index 141e960..0000000
--- a/libavcodec/x86/x86util.asm
+++ /dev/null
@@ -1,534 +0,0 @@
-;*****************************************************************************
-;* x86util.asm
-;*****************************************************************************
-;* Copyright (C) 2008-2010 x264 project
-;*
-;* Authors: Loren Merritt <lorenm at u.washington.edu>
-;* Holger Lubitz <holger at lubitz.org>
-;*
-;* This file is part of Libav.
-;*
-;* Libav is free software; you can redistribute it and/or
-;* modify it under the terms of the GNU Lesser General Public
-;* License as published by the Free Software Foundation; either
-;* version 2.1 of the License, or (at your option) any later version.
-;*
-;* Libav is distributed in the hope that it will be useful,
-;* but WITHOUT ANY WARRANTY; without even the implied warranty of
-;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-;* Lesser General Public License for more details.
-;*
-;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
-;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-;******************************************************************************
-
-%macro SBUTTERFLY 4
-%if avx_enabled == 0
- mova m%4, m%2
- punpckl%1 m%2, m%3
- punpckh%1 m%4, m%3
-%else
- punpckh%1 m%4, m%2, m%3
- punpckl%1 m%2, m%3
-%endif
- SWAP %3, %4
-%endmacro
-
-%macro SBUTTERFLY2 4
- punpckl%1 m%4, m%2, m%3
- punpckh%1 m%2, m%2, m%3
- SWAP %2, %4, %3
-%endmacro
-
-%macro SBUTTERFLYPS 3
- movaps m%3, m%1
- unpcklps m%1, m%2
- unpckhps m%3, m%2
- SWAP %2, %3
-%endmacro
-
-%macro TRANSPOSE4x4B 5
- SBUTTERFLY bw, %1, %2, %5
- SBUTTERFLY bw, %3, %4, %5
- SBUTTERFLY wd, %1, %3, %5
- SBUTTERFLY wd, %2, %4, %5
- SWAP %2, %3
-%endmacro
-
-%macro TRANSPOSE4x4W 5
- SBUTTERFLY wd, %1, %2, %5
- SBUTTERFLY wd, %3, %4, %5
- SBUTTERFLY dq, %1, %3, %5
- SBUTTERFLY dq, %2, %4, %5
- SWAP %2, %3
-%endmacro
-
-%macro TRANSPOSE2x4x4W 5
- SBUTTERFLY wd, %1, %2, %5
- SBUTTERFLY wd, %3, %4, %5
- SBUTTERFLY dq, %1, %3, %5
- SBUTTERFLY dq, %2, %4, %5
- SBUTTERFLY qdq, %1, %2, %5
- SBUTTERFLY qdq, %3, %4, %5
-%endmacro
-
-%macro TRANSPOSE4x4D 5
- SBUTTERFLY dq, %1, %2, %5
- SBUTTERFLY dq, %3, %4, %5
- SBUTTERFLY qdq, %1, %3, %5
- SBUTTERFLY qdq, %2, %4, %5
- SWAP %2, %3
-%endmacro
-
-; identical behavior to TRANSPOSE4x4D, but using SSE1 float ops
-%macro TRANSPOSE4x4PS 5
- SBUTTERFLYPS %1, %2, %5
- SBUTTERFLYPS %3, %4, %5
- movaps m%5, m%1
- movlhps m%1, m%3
- movhlps m%3, m%5
- movaps m%5, m%2
- movlhps m%2, m%4
- movhlps m%4, m%5
- SWAP %2, %3
-%endmacro
-
-%macro TRANSPOSE8x8W 9-11
-%ifdef ARCH_X86_64
- SBUTTERFLY wd, %1, %2, %9
- SBUTTERFLY wd, %3, %4, %9
- SBUTTERFLY wd, %5, %6, %9
- SBUTTERFLY wd, %7, %8, %9
- SBUTTERFLY dq, %1, %3, %9
- SBUTTERFLY dq, %2, %4, %9
- SBUTTERFLY dq, %5, %7, %9
- SBUTTERFLY dq, %6, %8, %9
- SBUTTERFLY qdq, %1, %5, %9
- SBUTTERFLY qdq, %2, %6, %9
- SBUTTERFLY qdq, %3, %7, %9
- SBUTTERFLY qdq, %4, %8, %9
- SWAP %2, %5
- SWAP %4, %7
-%else
-; in: m0..m7, unless %11 in which case m6 is in %9
-; out: m0..m7, unless %11 in which case m4 is in %10
-; spills into %9 and %10
-%if %0<11
- movdqa %9, m%7
-%endif
- SBUTTERFLY wd, %1, %2, %7
- movdqa %10, m%2
- movdqa m%7, %9
- SBUTTERFLY wd, %3, %4, %2
- SBUTTERFLY wd, %5, %6, %2
- SBUTTERFLY wd, %7, %8, %2
- SBUTTERFLY dq, %1, %3, %2
- movdqa %9, m%3
- movdqa m%2, %10
- SBUTTERFLY dq, %2, %4, %3
- SBUTTERFLY dq, %5, %7, %3
- SBUTTERFLY dq, %6, %8, %3
- SBUTTERFLY qdq, %1, %5, %3
- SBUTTERFLY qdq, %2, %6, %3
- movdqa %10, m%2
- movdqa m%3, %9
- SBUTTERFLY qdq, %3, %7, %2
- SBUTTERFLY qdq, %4, %8, %2
- SWAP %2, %5
- SWAP %4, %7
-%if %0<11
- movdqa m%5, %10
-%endif
-%endif
-%endmacro
-
-; PABSW macros assume %1 != %2, while ABS1/2 macros work in-place
-%macro PABSW_MMX 2
- pxor %1, %1
- pcmpgtw %1, %2
- pxor %2, %1
- psubw %2, %1
- SWAP %1, %2
-%endmacro
-
-%macro PSIGNW_MMX 2
- pxor %1, %2
- psubw %1, %2
-%endmacro
-
-%macro PABSW_MMX2 2
- pxor %1, %1
- psubw %1, %2
- pmaxsw %1, %2
-%endmacro
-
-%macro PABSW_SSSE3 2
- pabsw %1, %2
-%endmacro
-
-%macro PSIGNW_SSSE3 2
- psignw %1, %2
-%endmacro
-
-%macro ABS1_MMX 2 ; a, tmp
- pxor %2, %2
- pcmpgtw %2, %1
- pxor %1, %2
- psubw %1, %2
-%endmacro
-
-%macro ABS2_MMX 4 ; a, b, tmp0, tmp1
- pxor %3, %3
- pxor %4, %4
- pcmpgtw %3, %1
- pcmpgtw %4, %2
- pxor %1, %3
- pxor %2, %4
- psubw %1, %3
- psubw %2, %4
-%endmacro
-
-%macro ABS1_MMX2 2 ; a, tmp
- pxor %2, %2
- psubw %2, %1
- pmaxsw %1, %2
-%endmacro
-
-%macro ABS2_MMX2 4 ; a, b, tmp0, tmp1
- pxor %3, %3
- pxor %4, %4
- psubw %3, %1
- psubw %4, %2
- pmaxsw %1, %3
- pmaxsw %2, %4
-%endmacro
-
-%macro ABS1_SSSE3 2
- pabsw %1, %1
-%endmacro
-
-%macro ABS2_SSSE3 4
- pabsw %1, %1
- pabsw %2, %2
-%endmacro
-
-%macro ABSB_MMX 2
- pxor %2, %2
- psubb %2, %1
- pminub %1, %2
-%endmacro
-
-%macro ABSB2_MMX 4
- pxor %3, %3
- pxor %4, %4
- psubb %3, %1
- psubb %4, %2
- pminub %1, %3
- pminub %2, %4
-%endmacro
-
-%macro ABSD2_MMX 4
- pxor %3, %3
- pxor %4, %4
- pcmpgtd %3, %1
- pcmpgtd %4, %2
- pxor %1, %3
- pxor %2, %4
- psubd %1, %3
- psubd %2, %4
-%endmacro
-
-%macro ABSB_SSSE3 2
- pabsb %1, %1
-%endmacro
-
-%macro ABSB2_SSSE3 4
- pabsb %1, %1
- pabsb %2, %2
-%endmacro
-
-%macro ABS4 6
- ABS2 %1, %2, %5, %6
- ABS2 %3, %4, %5, %6
-%endmacro
-
-%define ABS1 ABS1_MMX
-%define ABS2 ABS2_MMX
-%define ABSB ABSB_MMX
-%define ABSB2 ABSB2_MMX
-
-%macro SPLATB_MMX 3
- movd %1, [%2-3] ;to avoid crossing a cacheline
- punpcklbw %1, %1
- SPLATW %1, %1, 3
-%endmacro
-
-%macro SPLATB_SSSE3 3
- movd %1, [%2-3]
- pshufb %1, %3
-%endmacro
-
-%macro PALIGNR_MMX 4-5 ; [dst,] src1, src2, imm, tmp
- %define %%dst %1
-%if %0==5
-%ifnidn %1, %2
- mova %%dst, %2
-%endif
- %rotate 1
-%endif
-%ifnidn %4, %2
- mova %4, %2
-%endif
-%if mmsize==8
- psllq %%dst, (8-%3)*8
- psrlq %4, %3*8
-%else
- pslldq %%dst, 16-%3
- psrldq %4, %3
-%endif
- por %%dst, %4
-%endmacro
-
-%macro PALIGNR_SSSE3 4-5
-%if %0==5
- palignr %1, %2, %3, %4
-%else
- palignr %1, %2, %3
-%endif
-%endmacro
-
-%macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
-%ifnum %5
- pand m%3, m%5, m%4 ; src .. y6 .. y4
- pand m%1, m%5, m%2 ; dst .. y6 .. y4
-%else
- mova m%1, %5
- pand m%3, m%1, m%4 ; src .. y6 .. y4
- pand m%1, m%1, m%2 ; dst .. y6 .. y4
-%endif
- psrlw m%2, 8 ; dst .. y7 .. y5
- psrlw m%4, 8 ; src .. y7 .. y5
-%endmacro
-
-%macro SUMSUB_BA 3-4
-%if %0==3
- padd%1 m%2, m%3
- padd%1 m%3, m%3
- psub%1 m%3, m%2
-%else
-%if avx_enabled == 0
- mova m%4, m%2
- padd%1 m%2, m%3
- psub%1 m%3, m%4
-%else
- padd%1 m%4, m%2, m%3
- psub%1 m%3, m%2
- SWAP %2, %4
-%endif
-%endif
-%endmacro
-
-%macro SUMSUB_BADC 5-6
-%if %0==6
- SUMSUB_BA %1, %2, %3, %6
- SUMSUB_BA %1, %4, %5, %6
-%else
- padd%1 m%2, m%3
- padd%1 m%4, m%5
- padd%1 m%3, m%3
- padd%1 m%5, m%5
- psub%1 m%3, m%2
- psub%1 m%5, m%4
-%endif
-%endmacro
-
-%macro SUMSUB2_AB 4
-%ifnum %3
- psub%1 m%4, m%2, m%3
- psub%1 m%4, m%3
- padd%1 m%2, m%2
- padd%1 m%2, m%3
-%else
- mova m%4, m%2
- padd%1 m%2, m%2
- padd%1 m%2, %3
- psub%1 m%4, %3
- psub%1 m%4, %3
-%endif
-%endmacro
-
-%macro SUMSUB2_BA 4
-%if avx_enabled == 0
- mova m%4, m%2
- padd%1 m%2, m%3
- padd%1 m%2, m%3
- psub%1 m%3, m%4
- psub%1 m%3, m%4
-%else
- padd%1 m%4, m%2, m%3
- padd%1 m%4, m%3
- psub%1 m%3, m%2
- psub%1 m%3, m%2
- SWAP %2, %4
-%endif
-%endmacro
-
-%macro SUMSUBD2_AB 5
-%ifnum %4
- psra%1 m%5, m%2, 1 ; %3: %3>>1
- psra%1 m%4, m%3, 1 ; %2: %2>>1
- padd%1 m%4, m%2 ; %3: %3>>1+%2
- psub%1 m%5, m%3 ; %2: %2>>1-%3
- SWAP %2, %5
- SWAP %3, %4
-%else
- mova %5, m%2
- mova %4, m%3
- psra%1 m%3, 1 ; %3: %3>>1
- psra%1 m%2, 1 ; %2: %2>>1
- padd%1 m%3, %5 ; %3: %3>>1+%2
- psub%1 m%2, %4 ; %2: %2>>1-%3
-%endif
-%endmacro
-
-%macro DCT4_1D 5
-%ifnum %5
- SUMSUB_BADC w, %4, %1, %3, %2, %5
- SUMSUB_BA w, %3, %4, %5
- SUMSUB2_AB w, %1, %2, %5
- SWAP %1, %3, %4, %5, %2
-%else
- SUMSUB_BADC w, %4, %1, %3, %2
- SUMSUB_BA w, %3, %4
- mova [%5], m%2
- SUMSUB2_AB w, %1, [%5], %2
- SWAP %1, %3, %4, %2
-%endif
-%endmacro
-
-%macro IDCT4_1D 6-7
-%ifnum %6
- SUMSUBD2_AB %1, %3, %5, %7, %6
- ; %3: %3>>1-%5 %5: %3+%5>>1
- SUMSUB_BA %1, %4, %2, %7
- ; %4: %2+%4 %2: %2-%4
- SUMSUB_BADC %1, %5, %4, %3, %2, %7
- ; %5: %2+%4 + (%3+%5>>1)
- ; %4: %2+%4 - (%3+%5>>1)
- ; %3: %2-%4 + (%3>>1-%5)
- ; %2: %2-%4 - (%3>>1-%5)
-%else
-%ifidn %1, w
- SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
-%else
- SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
-%endif
- SUMSUB_BA %1, %4, %2
- SUMSUB_BADC %1, %5, %4, %3, %2
-%endif
- SWAP %2, %5, %4
- ; %2: %2+%4 + (%3+%5>>1) row0
- ; %3: %2-%4 + (%3>>1-%5) row1
- ; %4: %2-%4 - (%3>>1-%5) row2
- ; %5: %2+%4 - (%3+%5>>1) row3
-%endmacro
-
-
-%macro LOAD_DIFF 5
-%ifidn %3, none
- movh %1, %4
- movh %2, %5
- punpcklbw %1, %2
- punpcklbw %2, %2
- psubw %1, %2
-%else
- movh %1, %4
- punpcklbw %1, %3
- movh %2, %5
- punpcklbw %2, %3
- psubw %1, %2
-%endif
-%endmacro
-
-%macro STORE_DCT 6
- movq [%5+%6+ 0], m%1
- movq [%5+%6+ 8], m%2
- movq [%5+%6+16], m%3
- movq [%5+%6+24], m%4
- movhps [%5+%6+32], m%1
- movhps [%5+%6+40], m%2
- movhps [%5+%6+48], m%3
- movhps [%5+%6+56], m%4
-%endmacro
-
-%macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
- LOAD_DIFF m%1, m%5, m%7, [%8], [%9]
- LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3]
- LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
- LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5]
-%if %10
- lea %8, [%8+4*r1]
- lea %9, [%9+4*r3]
-%endif
-%endmacro
-
-%macro DIFFx2 6-7
- movh %3, %5
- punpcklbw %3, %4
- psraw %1, 6
- paddsw %1, %3
- movh %3, %6
- punpcklbw %3, %4
- psraw %2, 6
- paddsw %2, %3
- packuswb %2, %1
-%endmacro
-
-%macro STORE_DIFF 4
- movh %2, %4
- punpcklbw %2, %3
- psraw %1, 6
- paddsw %1, %2
- packuswb %1, %1
- movh %4, %1
-%endmacro
-
-%macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride
- movh %3, [%7]
- movh %4, [%7+%8]
- punpcklbw %3, %5
- punpcklbw %4, %5
- psraw %1, %6
- psraw %2, %6
- paddw %3, %1
- paddw %4, %2
- packuswb %3, %5
- packuswb %4, %5
- movh [%7], %3
- movh [%7+%8], %4
-%endmacro
-
-%macro PMINUB_MMX 3 ; dst, src, tmp
- mova %3, %1
- psubusb %3, %2
- psubb %1, %3
-%endmacro
-
-%macro PMINUB_MMXEXT 3 ; dst, src, ignored
- pminub %1, %2
-%endmacro
-
-%macro SPLATW 2-3 0
-%if mmsize == 16
- pshuflw %1, %2, (%3)*0x55
- punpcklqdq %1, %1
-%else
- pshufw %1, %2, (%3)*0x55
-%endif
-%endmacro
-
-%macro CLIPW 3 ;(dst, min, max)
- pmaxsw %1, %2
- pminsw %1, %3
-%endmacro
diff --git a/libavcodec/xan.c b/libavcodec/xan.c
index 88a9adb..4c4721a 100644
--- a/libavcodec/xan.c
+++ b/libavcodec/xan.c
@@ -35,7 +35,7 @@
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "bytestream.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
// for av_memcpy_backptr
#include "libavutil/lzo.h"
@@ -111,10 +111,13 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len,
init_get_bits(&gb, ptr, ptr_len * 8);
- while ( val != 0x16 ) {
- val = src[val - 0x17 + get_bits1(&gb) * byte];
+ while (val != 0x16) {
+ unsigned idx = val - 0x17 + get_bits1(&gb) * byte;
+ if (idx >= 2 * byte)
+ return -1;
+ val = src[idx];
- if ( val < 0x16 ) {
+ if (val < 0x16) {
if (dest >= dest_end)
return 0;
*dest++ = val;
@@ -130,40 +133,41 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len,
*
* @param dest destination buffer of dest_len, must be padded with at least 130 bytes
*/
-static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_len)
+static void xan_unpack(unsigned char *dest, int dest_len,
+ const unsigned char *src, int src_len)
{
unsigned char opcode;
int size;
+ unsigned char *dest_org = dest;
unsigned char *dest_end = dest + dest_len;
+ const unsigned char *src_end = src + src_len;
- while (dest < dest_end) {
+ while (dest < dest_end && src < src_end) {
opcode = *src++;
if (opcode < 0xe0) {
int size2, back;
- if ( (opcode & 0x80) == 0 ) {
-
+ if ((opcode & 0x80) == 0) {
size = opcode & 3;
back = ((opcode & 0x60) << 3) + *src++ + 1;
size2 = ((opcode & 0x1c) >> 2) + 3;
-
- } else if ( (opcode & 0x40) == 0 ) {
-
+ } else if ((opcode & 0x40) == 0) {
size = *src >> 6;
back = (bytestream_get_be16(&src) & 0x3fff) + 1;
size2 = (opcode & 0x3f) + 4;
-
} else {
-
size = opcode & 3;
back = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1;
size2 = ((opcode & 0x0c) << 6) + *src++ + 5;
- if (size + size2 > dest_end - dest)
- return;
}
+
+ if (dest_end - dest < size + size2 ||
+ dest + size - dest_org < back ||
+ src_end - src < size)
+ return;
memcpy(dest, src, size); dest += size; src += size;
av_memcpy_backptr(dest, back, size2);
dest += size2;
@@ -171,6 +175,8 @@ static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_l
int finish = opcode >= 0xfc;
size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
+ if (dest_end - dest < size || src_end - src < size)
+ return;
memcpy(dest, src, size); dest += size; src += size;
if (finish)
return;
@@ -193,7 +199,7 @@ static inline void xan_wc3_output_pixel_run(XanContext *s,
line_inc = stride - width;
index = y * stride + x;
current_x = x;
- while(pixel_count && (index < s->frame_size)) {
+ while (pixel_count && index < s->frame_size) {
int count = FFMIN(pixel_count, width - current_x);
memcpy(palette_plane + index, pixel_buffer, count);
pixel_count -= count;
@@ -208,8 +214,9 @@ static inline void xan_wc3_output_pixel_run(XanContext *s,
}
}
-static inline void xan_wc3_copy_pixel_run(XanContext *s,
- int x, int y, int pixel_count, int motion_x, int motion_y)
+static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y,
+ int pixel_count, int motion_x,
+ int motion_y)
{
int stride;
int line_inc;
@@ -218,18 +225,28 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s,
int width = s->avctx->width;
unsigned char *palette_plane, *prev_palette_plane;
+ if (y + motion_y < 0 || y + motion_y >= s->avctx->height ||
+ x + motion_x < 0 || x + motion_x >= s->avctx->width)
+ return;
+
palette_plane = s->current_frame.data[0];
prev_palette_plane = s->last_frame.data[0];
+ if (!prev_palette_plane)
+ prev_palette_plane = palette_plane;
stride = s->current_frame.linesize[0];
line_inc = stride - width;
curframe_index = y * stride + x;
curframe_x = x;
prevframe_index = (y + motion_y) * stride + x + motion_x;
prevframe_x = x + motion_x;
- while(pixel_count && (curframe_index < s->frame_size)) {
- int count = FFMIN3(pixel_count, width - curframe_x, width - prevframe_x);
-
- memcpy(palette_plane + curframe_index, prev_palette_plane + prevframe_index, count);
+ while (pixel_count &&
+ curframe_index < s->frame_size &&
+ prevframe_index < s->frame_size) {
+ int count = FFMIN3(pixel_count, width - curframe_x,
+ width - prevframe_x);
+
+ memcpy(palette_plane + curframe_index,
+ prev_palette_plane + prevframe_index, count);
pixel_count -= count;
curframe_index += count;
prevframe_index += count;
@@ -250,7 +267,7 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s,
static int xan_wc3_decode_frame(XanContext *s) {
- int width = s->avctx->width;
+ int width = s->avctx->width;
int height = s->avctx->height;
int total_pixels = width * height;
unsigned char opcode;
@@ -260,6 +277,7 @@ static int xan_wc3_decode_frame(XanContext *s) {
int x, y;
unsigned char *opcode_buffer = s->buffer1;
+ unsigned char *opcode_buffer_end = s->buffer1 + s->buffer1_size;
int opcode_buffer_size = s->buffer1_size;
const unsigned char *imagedata_buffer = s->buffer2;
@@ -268,7 +286,8 @@ static int xan_wc3_decode_frame(XanContext *s) {
const unsigned char *size_segment;
const unsigned char *vector_segment;
const unsigned char *imagedata_segment;
- int huffman_offset, size_offset, vector_offset, imagedata_offset;
+ int huffman_offset, size_offset, vector_offset, imagedata_offset,
+ imagedata_size;
if (s->size < 8)
return AVERROR_INVALIDDATA;
@@ -293,14 +312,18 @@ static int xan_wc3_decode_frame(XanContext *s) {
huffman_segment, s->size - huffman_offset) < 0)
return AVERROR_INVALIDDATA;
- if (imagedata_segment[0] == 2)
- xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size);
- else
+ if (imagedata_segment[0] == 2) {
+ xan_unpack(s->buffer2, s->buffer2_size,
+ &imagedata_segment[1], s->size - imagedata_offset - 1);
+ imagedata_size = s->buffer2_size;
+ } else {
+ imagedata_size = s->size - imagedata_offset - 1;
imagedata_buffer = &imagedata_segment[1];
+ }
/* use the decoded data segments to build the frame */
x = y = 0;
- while (total_pixels) {
+ while (total_pixels && opcode_buffer < opcode_buffer_end) {
opcode = *opcode_buffer++;
size = 0;
@@ -350,6 +373,9 @@ static int xan_wc3_decode_frame(XanContext *s) {
break;
}
+ if (size > total_pixels)
+ break;
+
if (opcode < 12) {
flag ^= 1;
if (flag) {
@@ -357,8 +383,11 @@ static int xan_wc3_decode_frame(XanContext *s) {
xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
} else {
/* output a run of pixels from imagedata_buffer */
+ if (imagedata_size < size)
+ break;
xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
imagedata_buffer += size;
+ imagedata_size -= size;
}
} else {
/* run-based motion compensation from last frame */
@@ -488,7 +517,8 @@ static int xan_decode_frame(AVCodecContext *avctx,
return AVERROR_INVALIDDATA;
if (s->palettes_count >= PALETTES_MAX)
return AVERROR_INVALIDDATA;
- tmpptr = av_realloc(s->palettes, (s->palettes_count + 1) * AVPALETTE_SIZE);
+ tmpptr = av_realloc(s->palettes,
+ (s->palettes_count + 1) * AVPALETTE_SIZE);
if (!tmpptr)
return AVERROR(ENOMEM);
s->palettes = tmpptr;
@@ -525,6 +555,11 @@ static int xan_decode_frame(AVCodecContext *avctx,
}
buf_size = buf_end - buf;
}
+ if (s->palettes_count <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "No palette found\n");
+ return AVERROR_INVALIDDATA;
+ }
+
if ((ret = avctx->get_buffer(avctx, &s->current_frame))) {
av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret;
@@ -534,7 +569,8 @@ static int xan_decode_frame(AVCodecContext *avctx,
if (!s->frame_size)
s->frame_size = s->current_frame.linesize[0] * s->avctx->height;
- memcpy(s->current_frame.data[1], s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
+ memcpy(s->current_frame.data[1],
+ s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
s->buf = buf;
s->size = buf_size;
@@ -574,15 +610,13 @@ static av_cold int xan_decode_end(AVCodecContext *avctx)
}
AVCodec ff_xan_wc3_decoder = {
- "xan_wc3",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_XAN_WC3,
- sizeof(XanContext),
- xan_decode_init,
- NULL,
- xan_decode_end,
- xan_decode_frame,
- CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
+ .name = "xan_wc3",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_XAN_WC3,
+ .priv_data_size = sizeof(XanContext),
+ .init = xan_decode_init,
+ .close = xan_decode_end,
+ .decode = xan_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
};
-
diff --git a/libavcodec/xiph.c b/libavcodec/xiph.c
index 0bcfd45..7c3c710 100644
--- a/libavcodec/xiph.c
+++ b/libavcodec/xiph.c
@@ -21,7 +21,7 @@
#include "libavutil/intreadwrite.h"
#include "xiph.h"
-int ff_split_xiph_headers(uint8_t *extradata, int extradata_size,
+int avpriv_split_xiph_headers(uint8_t *extradata, int extradata_size,
int first_header_size, uint8_t *header_start[3],
int header_len[3])
{
diff --git a/libavcodec/xiph.h b/libavcodec/xiph.h
index da18c9c..afaece7 100644
--- a/libavcodec/xiph.h
+++ b/libavcodec/xiph.h
@@ -36,8 +36,8 @@
* @param[out] header_len The sizes of each of the three headers.
* @return On error a negative value is returned, on success zero.
*/
-int ff_split_xiph_headers(uint8_t *extradata, int extradata_size,
- int first_header_size, uint8_t *header_start[3],
- int header_len[3]);
+int avpriv_split_xiph_headers(uint8_t *extradata, int extradata_size,
+ int first_header_size, uint8_t *header_start[3],
+ int header_len[3]);
#endif /* AVCODEC_XIPH_H */
diff --git a/libavcodec/xl.c b/libavcodec/xl.c
index 4f17ae5..0ebc946 100644
--- a/libavcodec/xl.c
+++ b/libavcodec/xl.c
@@ -68,6 +68,12 @@ static int decode_frame(AVCodecContext *avctx,
V = a->pic.data[2];
stride = avctx->width - 4;
+
+ if (buf_size < avctx->width * avctx->height) {
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
for (i = 0; i < avctx->height; i++) {
/* lines are stored in reversed order */
buf += stride;
@@ -139,14 +145,13 @@ static av_cold int decode_end(AVCodecContext *avctx){
}
AVCodec ff_xl_decoder = {
- "xl",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_VIXL,
- sizeof(VideoXLContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "xl",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_VIXL,
+ .priv_data_size = sizeof(VideoXLContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Miro VideoXL"),
};
diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c
index 097cbc6..af87388 100644
--- a/libavcodec/xsubdec.c
+++ b/libavcodec/xsubdec.c
@@ -18,6 +18,8 @@
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
+#include "libavutil/mathematics.h"
#include "libavutil/imgutils.h"
#include "avcodec.h"
#include "get_bits.h"
@@ -132,13 +134,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
}
AVCodec ff_xsub_decoder = {
- "xsub",
- AVMEDIA_TYPE_SUBTITLE,
- CODEC_ID_XSUB,
- 0,
- decode_init,
- NULL,
- NULL,
- decode_frame,
+ .name = "xsub",
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = CODEC_ID_XSUB,
+ .init = decode_init,
+ .decode = decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("XSUB"),
};
diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c
index 87dc75c..bd66f86 100644
--- a/libavcodec/xsubenc.c
+++ b/libavcodec/xsubenc.c
@@ -36,8 +36,8 @@
/**
* Encode a single color run. At most 16 bits will be used.
- * \param len length of the run, values > 255 mean "until end of line", may not be < 0.
- * \param color color to encode, only the lowest two bits are used and all others must be 0.
+ * @param len length of the run, values > 255 mean "until end of line", may not be < 0.
+ * @param color color to encode, only the lowest two bits are used and all others must be 0.
*/
static void put_xsub_rle(PutBitContext *pb, int len, int color)
{
@@ -90,7 +90,7 @@ static int xsub_encode_rle(PutBitContext *pb, const uint8_t *bitmap,
if (color != PADDING_COLOR && (PADDING + (w&1)))
put_xsub_rle(pb, PADDING + (w&1), PADDING_COLOR);
- align_put_bits(pb);
+ avpriv_align_put_bits(pb);
bitmap += linesize;
}
@@ -194,7 +194,7 @@ static int xsub_encode(AVCodecContext *avctx, unsigned char *buf,
// Enforce total height to be be multiple of 2
if (h->rects[0]->h & 1) {
put_xsub_rle(&pb, h->rects[0]->w, PADDING_COLOR);
- align_put_bits(&pb);
+ avpriv_align_put_bits(&pb);
}
flush_put_bits(&pb);
@@ -211,12 +211,10 @@ static av_cold int xsub_encoder_init(AVCodecContext *avctx)
}
AVCodec ff_xsub_encoder = {
- "xsub",
- AVMEDIA_TYPE_SUBTITLE,
- CODEC_ID_XSUB,
- 0,
- xsub_encoder_init,
- xsub_encode,
- NULL,
+ .name = "xsub",
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = CODEC_ID_XSUB,
+ .init = xsub_encoder_init,
+ .encode = xsub_encode,
.long_name = NULL_IF_CONFIG_SMALL("DivX subtitles (XSUB)"),
};
diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c
index 28c868d..58c80c0 100644
--- a/libavcodec/xxan.c
+++ b/libavcodec/xxan.c
@@ -23,7 +23,7 @@
#include "avcodec.h"
#include "libavutil/intreadwrite.h"
#include "bytestream.h"
-#define ALT_BITSTREAM_READER_LE
+#define BITSTREAM_READER_LE
#include "get_bits.h"
// for av_memcpy_backptr
#include "libavutil/lzo.h"
@@ -415,15 +415,14 @@ static av_cold int xan_decode_end(AVCodecContext *avctx)
}
AVCodec ff_xan_wc4_decoder = {
- "xan_wc4",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_XAN_WC4,
- sizeof(XanContext),
- xan_decode_init,
- NULL,
- xan_decode_end,
- xan_decode_frame,
- CODEC_CAP_DR1,
+ .name = "xan_wc4",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_XAN_WC4,
+ .priv_data_size = sizeof(XanContext),
+ .init = xan_decode_init,
+ .close = xan_decode_end,
+ .decode = xan_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"),
};
diff --git a/libavcodec/yop.c b/libavcodec/yop.c
index 1f1314b..3c2d8b8 100644
--- a/libavcodec/yop.c
+++ b/libavcodec/yop.c
@@ -1,5 +1,4 @@
-/**
- * @file
+/*
* Psygnosis YOP decoder
*
* Copyright (C) 2010 Mohamed Naufal Basheer <naufal11 at gmail.com>
@@ -249,13 +248,12 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
}
AVCodec ff_yop_decoder = {
- "yop",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_YOP,
- sizeof(YopDecContext),
- yop_decode_init,
- NULL,
- yop_decode_close,
- yop_decode_frame,
+ .name = "yop",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_YOP,
+ .priv_data_size = sizeof(YopDecContext),
+ .init = yop_decode_init,
+ .close = yop_decode_close,
+ .decode = yop_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"),
};
diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c
index deae580..3213480 100644
--- a/libavcodec/zmbv.c
+++ b/libavcodec/zmbv.c
@@ -88,8 +88,8 @@ static int zmbv_decode_xor_8(ZmbvContext *c)
output = c->cur;
prev = c->prev;
- if(c->flags & ZMBV_DELTAPAL){
- for(i = 0; i < 768; i++)
+ if (c->flags & ZMBV_DELTAPAL) {
+ for (i = 0; i < 768; i++)
c->pal[i] ^= *src++;
}
@@ -97,9 +97,9 @@ static int zmbv_decode_xor_8(ZmbvContext *c)
src += ((c->bx * c->by * 2 + 3) & ~3);
block = 0;
- for(y = 0; y < c->height; y += c->bh) {
+ for (y = 0; y < c->height; y += c->bh) {
bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
- for(x = 0; x < c->width; x += c->bw) {
+ for (x = 0; x < c->width; x += c->bw) {
uint8_t *out, *tprev;
d = mvec[block] & 1;
@@ -114,12 +114,12 @@ static int zmbv_decode_xor_8(ZmbvContext *c)
tprev = prev + x + dx + dy * c->width;
mx = x + dx;
my = y + dy;
- for(j = 0; j < bh2; j++){
- if((my + j < 0) || (my + j >= c->height)) {
+ for (j = 0; j < bh2; j++) {
+ if (my + j < 0 || my + j >= c->height) {
memset(out, 0, bw2);
} else {
- for(i = 0; i < bw2; i++){
- if((mx + i < 0) || (mx + i >= c->width))
+ for (i = 0; i < bw2; i++) {
+ if (mx + i < 0 || mx + i >= c->width)
out[i] = 0;
else
out[i] = tprev[i];
@@ -129,10 +129,10 @@ static int zmbv_decode_xor_8(ZmbvContext *c)
tprev += c->width;
}
- if(d) { /* apply XOR'ed difference */
+ if (d) { /* apply XOR'ed difference */
out = output + x;
- for(j = 0; j < bh2; j++){
- for(i = 0; i < bw2; i++)
+ for (j = 0; j < bh2; j++) {
+ for (i = 0; i < bw2; i++)
out[i] ^= *src++;
out += c->width;
}
@@ -141,8 +141,9 @@ static int zmbv_decode_xor_8(ZmbvContext *c)
output += c->width * c->bh;
prev += c->width * c->bh;
}
- if(src - c->decomp_buf != c->decomp_len)
- av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len);
+ if (src - c->decomp_buf != c->decomp_len)
+ av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n",
+ src-c->decomp_buf, c->decomp_len);
return 0;
}
@@ -168,9 +169,9 @@ static int zmbv_decode_xor_16(ZmbvContext *c)
src += ((c->bx * c->by * 2 + 3) & ~3);
block = 0;
- for(y = 0; y < c->height; y += c->bh) {
+ for (y = 0; y < c->height; y += c->bh) {
bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
- for(x = 0; x < c->width; x += c->bw) {
+ for (x = 0; x < c->width; x += c->bw) {
uint16_t *out, *tprev;
d = mvec[block] & 1;
@@ -185,12 +186,12 @@ static int zmbv_decode_xor_16(ZmbvContext *c)
tprev = prev + x + dx + dy * c->width;
mx = x + dx;
my = y + dy;
- for(j = 0; j < bh2; j++){
- if((my + j < 0) || (my + j >= c->height)) {
+ for (j = 0; j < bh2; j++) {
+ if (my + j < 0 || my + j >= c->height) {
memset(out, 0, bw2 * 2);
} else {
- for(i = 0; i < bw2; i++){
- if((mx + i < 0) || (mx + i >= c->width))
+ for (i = 0; i < bw2; i++) {
+ if (mx + i < 0 || mx + i >= c->width)
out[i] = 0;
else
out[i] = tprev[i];
@@ -200,10 +201,10 @@ static int zmbv_decode_xor_16(ZmbvContext *c)
tprev += c->width;
}
- if(d) { /* apply XOR'ed difference */
+ if (d) { /* apply XOR'ed difference */
out = output + x;
- for(j = 0; j < bh2; j++){
- for(i = 0; i < bw2; i++) {
+ for (j = 0; j < bh2; j++){
+ for (i = 0; i < bw2; i++) {
out[i] ^= *((uint16_t*)src);
src += 2;
}
@@ -214,8 +215,9 @@ static int zmbv_decode_xor_16(ZmbvContext *c)
output += c->width * c->bh;
prev += c->width * c->bh;
}
- if(src - c->decomp_buf != c->decomp_len)
- av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len);
+ if (src - c->decomp_buf != c->decomp_len)
+ av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n",
+ src-c->decomp_buf, c->decomp_len);
return 0;
}
@@ -244,9 +246,9 @@ static int zmbv_decode_xor_24(ZmbvContext *c)
src += ((c->bx * c->by * 2 + 3) & ~3);
block = 0;
- for(y = 0; y < c->height; y += c->bh) {
+ for (y = 0; y < c->height; y += c->bh) {
bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
- for(x = 0; x < c->width; x += c->bw) {
+ for (x = 0; x < c->width; x += c->bw) {
uint8_t *out, *tprev;
d = mvec[block] & 1;
@@ -261,12 +263,12 @@ static int zmbv_decode_xor_24(ZmbvContext *c)
tprev = prev + (x + dx) * 3 + dy * stride;
mx = x + dx;
my = y + dy;
- for(j = 0; j < bh2; j++){
- if((my + j < 0) || (my + j >= c->height)) {
+ for (j = 0; j < bh2; j++) {
+ if (my + j < 0 || my + j >= c->height) {
memset(out, 0, bw2 * 3);
} else {
- for(i = 0; i < bw2; i++){
- if((mx + i < 0) || (mx + i >= c->width)) {
+ for (i = 0; i < bw2; i++){
+ if (mx + i < 0 || mx + i >= c->width) {
out[i * 3 + 0] = 0;
out[i * 3 + 1] = 0;
out[i * 3 + 2] = 0;
@@ -281,10 +283,10 @@ static int zmbv_decode_xor_24(ZmbvContext *c)
tprev += stride;
}
- if(d) { /* apply XOR'ed difference */
+ if (d) { /* apply XOR'ed difference */
out = output + x * 3;
- for(j = 0; j < bh2; j++){
- for(i = 0; i < bw2; i++) {
+ for (j = 0; j < bh2; j++) {
+ for (i = 0; i < bw2; i++) {
out[i * 3 + 0] ^= *src++;
out[i * 3 + 1] ^= *src++;
out[i * 3 + 2] ^= *src++;
@@ -296,8 +298,9 @@ static int zmbv_decode_xor_24(ZmbvContext *c)
output += stride * c->bh;
prev += stride * c->bh;
}
- if(src - c->decomp_buf != c->decomp_len)
- av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len);
+ if (src - c->decomp_buf != c->decomp_len)
+ av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n",
+ src-c->decomp_buf, c->decomp_len);
return 0;
}
#endif //ZMBV_ENABLE_24BPP
@@ -324,9 +327,9 @@ static int zmbv_decode_xor_32(ZmbvContext *c)
src += ((c->bx * c->by * 2 + 3) & ~3);
block = 0;
- for(y = 0; y < c->height; y += c->bh) {
+ for (y = 0; y < c->height; y += c->bh) {
bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
- for(x = 0; x < c->width; x += c->bw) {
+ for (x = 0; x < c->width; x += c->bw) {
uint32_t *out, *tprev;
d = mvec[block] & 1;
@@ -341,12 +344,12 @@ static int zmbv_decode_xor_32(ZmbvContext *c)
tprev = prev + x + dx + dy * c->width;
mx = x + dx;
my = y + dy;
- for(j = 0; j < bh2; j++){
- if((my + j < 0) || (my + j >= c->height)) {
+ for (j = 0; j < bh2; j++) {
+ if (my + j < 0 || my + j >= c->height) {
memset(out, 0, bw2 * 4);
} else {
- for(i = 0; i < bw2; i++){
- if((mx + i < 0) || (mx + i >= c->width))
+ for (i = 0; i < bw2; i++){
+ if (mx + i < 0 || mx + i >= c->width)
out[i] = 0;
else
out[i] = tprev[i];
@@ -356,11 +359,11 @@ static int zmbv_decode_xor_32(ZmbvContext *c)
tprev += c->width;
}
- if(d) { /* apply XOR'ed difference */
+ if (d) { /* apply XOR'ed difference */
out = output + x;
- for(j = 0; j < bh2; j++){
- for(i = 0; i < bw2; i++) {
- out[i] ^= *((uint32_t*)src);
+ for (j = 0; j < bh2; j++){
+ for (i = 0; i < bw2; i++) {
+ out[i] ^= *((uint32_t *) src);
src += 4;
}
out += c->width;
@@ -368,10 +371,11 @@ static int zmbv_decode_xor_32(ZmbvContext *c)
}
}
output += c->width * c->bh;
- prev += c->width * c->bh;
+ prev += c->width * c->bh;
}
- if(src - c->decomp_buf != c->decomp_len)
- av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len);
+ if (src - c->decomp_buf != c->decomp_len)
+ av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n",
+ src-c->decomp_buf, c->decomp_len);
return 0;
}
@@ -401,12 +405,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
int len = buf_size;
int hi_ver, lo_ver;
- if(c->pic.data[0])
+ if (c->pic.data[0])
avctx->release_buffer(avctx, &c->pic);
c->pic.reference = 1;
c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
- if(avctx->get_buffer(avctx, &c->pic) < 0){
+ if (avctx->get_buffer(avctx, &c->pic) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
@@ -414,7 +418,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
/* parse header */
c->flags = buf[0];
buf++; len--;
- if(c->flags & ZMBV_KEYFRAME) {
+ if (c->flags & ZMBV_KEYFRAME) {
hi_ver = buf[0];
lo_ver = buf[1];
c->comp = buf[2];
@@ -424,21 +428,26 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
buf += 6;
len -= 6;
- av_log(avctx, AV_LOG_DEBUG, "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",c->flags,hi_ver,lo_ver,c->comp,c->fmt,c->bw,c->bh);
- if(hi_ver != 0 || lo_ver != 1) {
- av_log(avctx, AV_LOG_ERROR, "Unsupported version %i.%i\n", hi_ver, lo_ver);
+ av_log(avctx, AV_LOG_DEBUG,
+ "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",
+ c->flags,hi_ver,lo_ver,c->comp,c->fmt,c->bw,c->bh);
+ if (hi_ver != 0 || lo_ver != 1) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported version %i.%i\n",
+ hi_ver, lo_ver);
return -1;
}
- if(c->bw == 0 || c->bh == 0) {
- av_log(avctx, AV_LOG_ERROR, "Unsupported block size %ix%i\n", c->bw, c->bh);
+ if (c->bw == 0 || c->bh == 0) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported block size %ix%i\n",
+ c->bw, c->bh);
return -1;
}
- if(c->comp != 0 && c->comp != 1) {
- av_log(avctx, AV_LOG_ERROR, "Unsupported compression type %i\n", c->comp);
+ if (c->comp != 0 && c->comp != 1) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported compression type %i\n",
+ c->comp);
return -1;
}
- switch(c->fmt) {
+ switch (c->fmt) {
case ZMBV_FMT_8BPP:
c->bpp = 8;
c->decode_intra = zmbv_decode_intra;
@@ -465,7 +474,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
default:
c->decode_intra = NULL;
c->decode_xor = NULL;
- av_log(avctx, AV_LOG_ERROR, "Unsupported (for now) format %i\n", c->fmt);
+ av_log(avctx, AV_LOG_ERROR,
+ "Unsupported (for now) format %i\n", c->fmt);
return -1;
}
@@ -473,23 +483,23 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
if (zret != Z_OK) {
av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
return -1;
- }
-
- c->cur = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8));
- c->prev = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8));
- c->bx = (c->width + c->bw - 1) / c->bw;
- c->by = (c->height+ c->bh - 1) / c->bh;
- }
-
- if(c->decode_intra == NULL) {
- av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n");
- return -1;
- }
-
- if(c->comp == 0) { //Uncompressed data
- memcpy(c->decomp_buf, buf, len);
- c->decomp_size = 1;
- } else { // ZLIB-compressed data
+ }
+
+ c->cur = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8));
+ c->prev = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8));
+ c->bx = (c->width + c->bw - 1) / c->bw;
+ c->by = (c->height+ c->bh - 1) / c->bh;
+ }
+
+ if (c->decode_intra == NULL) {
+ av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n");
+ return -1;
+ }
+
+ if (c->comp == 0) { //Uncompressed data
+ memcpy(c->decomp_buf, buf, len);
+ c->decomp_size = 1;
+ } else { // ZLIB-compressed data
c->zstream.total_in = c->zstream.total_out = 0;
c->zstream.next_in = buf;
c->zstream.avail_in = len;
@@ -498,14 +508,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
inflate(&c->zstream, Z_FINISH);
c->decomp_len = c->zstream.total_out;
}
- if(c->flags & ZMBV_KEYFRAME) {
+ if (c->flags & ZMBV_KEYFRAME) {
c->pic.key_frame = 1;
c->pic.pict_type = AV_PICTURE_TYPE_I;
c->decode_intra(c);
} else {
c->pic.key_frame = 0;
c->pic.pict_type = AV_PICTURE_TYPE_P;
- if(c->decomp_len)
+ if (c->decomp_len)
c->decode_xor(c);
}
@@ -516,10 +526,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
out = c->pic.data[0];
src = c->cur;
- switch(c->fmt) {
+ switch (c->fmt) {
case ZMBV_FMT_8BPP:
- for(j = 0; j < c->height; j++) {
- for(i = 0; i < c->width; i++) {
+ for (j = 0; j < c->height; j++) {
+ for (i = 0; i < c->width; i++) {
out[i * 3 + 0] = c->pal[(*src) * 3 + 0];
out[i * 3 + 1] = c->pal[(*src) * 3 + 1];
out[i * 3 + 2] = c->pal[(*src) * 3 + 2];
@@ -529,8 +539,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
}
break;
case ZMBV_FMT_15BPP:
- for(j = 0; j < c->height; j++) {
- for(i = 0; i < c->width; i++) {
+ for (j = 0; j < c->height; j++) {
+ for (i = 0; i < c->width; i++) {
uint16_t tmp = AV_RL16(src);
src += 2;
out[i * 3 + 0] = (tmp & 0x7C00) >> 7;
@@ -541,8 +551,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
}
break;
case ZMBV_FMT_16BPP:
- for(j = 0; j < c->height; j++) {
- for(i = 0; i < c->width; i++) {
+ for (j = 0; j < c->height; j++) {
+ for (i = 0; i < c->width; i++) {
uint16_t tmp = AV_RL16(src);
src += 2;
out[i * 3 + 0] = (tmp & 0xF800) >> 8;
@@ -554,7 +564,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
break;
#ifdef ZMBV_ENABLE_24BPP
case ZMBV_FMT_24BPP:
- for(j = 0; j < c->height; j++) {
+ for (j = 0; j < c->height; j++) {
memcpy(out, src, c->width * 3);
src += c->width * 3;
out += c->pic.linesize[0];
@@ -562,8 +572,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
break;
#endif //ZMBV_ENABLE_24BPP
case ZMBV_FMT_32BPP:
- for(j = 0; j < c->height; j++) {
- for(i = 0; i < c->width; i++) {
+ for (j = 0; j < c->height; j++) {
+ for (i = 0; i < c->width; i++) {
uint32_t tmp = AV_RL32(src);
src += 4;
AV_WB24(out+(i*3), tmp);
@@ -574,7 +584,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
default:
av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt);
}
- memcpy(c->prev, c->cur, c->width * c->height * (c->bpp / 8));
+ FFSWAP(uint8_t *, c->cur, c->prev);
}
*data_size = sizeof(AVFrame);
*(AVFrame*)data = c->pic;
@@ -611,7 +621,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
/* Allocate decompression buffer */
if (c->decomp_size) {
if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) {
- av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
+ av_log(avctx, AV_LOG_ERROR,
+ "Can't allocate decompression buffer.\n");
return 1;
}
}
@@ -651,15 +662,14 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_zmbv_decoder = {
- "zmbv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ZMBV,
- sizeof(ZmbvContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "zmbv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ZMBV,
+ .priv_data_size = sizeof(ZmbvContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"),
};
diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c
index e4f4860..2230436 100644
--- a/libavcodec/zmbvenc.c
+++ b/libavcodec/zmbvenc.c
@@ -324,13 +324,13 @@ static av_cold int encode_end(AVCodecContext *avctx)
}
AVCodec ff_zmbv_encoder = {
- "zmbv",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_ZMBV,
- sizeof(ZmbvEncContext),
- encode_init,
- encode_frame,
- encode_end,
+ .name = "zmbv",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_ZMBV,
+ .priv_data_size = sizeof(ZmbvEncContext),
+ .init = encode_init,
+ .encode = encode_frame,
+ .close = encode_end,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_PAL8, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"),
};
diff --git a/libavdevice/Makefile b/libavdevice/Makefile
index 5cfc5e8..1a1e2f1 100644
--- a/libavdevice/Makefile
+++ b/libavdevice/Makefile
@@ -1,5 +1,3 @@
-include $(SUBDIR)../config.mak
-
NAME = avdevice
FFLIBS = avformat avcodec avutil
@@ -15,9 +13,10 @@ OBJS-$(CONFIG_ALSA_OUTDEV) += alsa-audio-common.o \
OBJS-$(CONFIG_BKTR_INDEV) += bktr.o
OBJS-$(CONFIG_DV1394_INDEV) += dv1394.o
OBJS-$(CONFIG_FBDEV_INDEV) += fbdev.o
-OBJS-$(CONFIG_JACK_INDEV) += jack_audio.o
+OBJS-$(CONFIG_JACK_INDEV) += jack_audio.o timefilter.o
OBJS-$(CONFIG_OSS_INDEV) += oss_audio.o
OBJS-$(CONFIG_OSS_OUTDEV) += oss_audio.o
+OBJS-$(CONFIG_PULSE_INDEV) += pulse.o
OBJS-$(CONFIG_SNDIO_INDEV) += sndio_common.o sndio_dec.o
OBJS-$(CONFIG_SNDIO_OUTDEV) += sndio_common.o sndio_enc.o
OBJS-$(CONFIG_V4L2_INDEV) += v4l2.o
@@ -26,9 +25,10 @@ OBJS-$(CONFIG_VFWCAP_INDEV) += vfwcap.o
OBJS-$(CONFIG_X11_GRAB_DEVICE_INDEV) += x11grab.o
# external libraries
+OBJS-$(CONFIG_LIBCDIO_INDEV) += libcdio.o
OBJS-$(CONFIG_LIBDC1394_INDEV) += libdc1394.o
SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H) += alsa-audio.h
SKIPHEADERS-$(HAVE_SNDIO_H) += sndio_common.h
-include $(SUBDIR)../subdir.mak
+TESTPROGS = timefilter
diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c
index e7bfb02..e65644b 100644
--- a/libavdevice/alldevices.c
+++ b/libavdevice/alldevices.c
@@ -45,6 +45,7 @@ void avdevice_register_all(void)
REGISTER_INDEV (FBDEV, fbdev);
REGISTER_INDEV (JACK, jack);
REGISTER_INOUTDEV (OSS, oss);
+ REGISTER_INDEV (PULSE, pulse);
REGISTER_INOUTDEV (SNDIO, sndio);
REGISTER_INDEV (V4L2, v4l2);
#if FF_API_V4L
@@ -54,5 +55,6 @@ void avdevice_register_all(void)
REGISTER_INDEV (X11_GRAB_DEVICE, x11_grab_device);
/* external libraries */
+ REGISTER_INDEV (LIBCDIO, libcdio);
REGISTER_INDEV (LIBDC1394, libdc1394);
}
diff --git a/libavdevice/alsa-audio-common.c b/libavdevice/alsa-audio-common.c
index 825fcb1..cfee28c 100644
--- a/libavdevice/alsa-audio-common.c
+++ b/libavdevice/alsa-audio-common.c
@@ -30,6 +30,8 @@
#include <alsa/asoundlib.h>
#include "libavformat/avformat.h"
+#include "libavutil/avassert.h"
+#include "libavutil/audioconvert.h"
#include "alsa-audio.h"
@@ -60,6 +62,127 @@ static av_cold snd_pcm_format_t codec_id_to_pcm_format(int codec_id)
}
}
+#define REORDER_OUT_50(NAME, TYPE) \
+static void alsa_reorder_ ## NAME ## _out_50(const void *in_v, void *out_v, int n) \
+{ \
+ const TYPE *in = in_v; \
+ TYPE *out = out_v; \
+\
+ while (n-- > 0) { \
+ out[0] = in[0]; \
+ out[1] = in[1]; \
+ out[2] = in[3]; \
+ out[3] = in[4]; \
+ out[4] = in[2]; \
+ in += 5; \
+ out += 5; \
+ } \
+}
+
+#define REORDER_OUT_51(NAME, TYPE) \
+static void alsa_reorder_ ## NAME ## _out_51(const void *in_v, void *out_v, int n) \
+{ \
+ const TYPE *in = in_v; \
+ TYPE *out = out_v; \
+\
+ while (n-- > 0) { \
+ out[0] = in[0]; \
+ out[1] = in[1]; \
+ out[2] = in[4]; \
+ out[3] = in[5]; \
+ out[4] = in[2]; \
+ out[5] = in[3]; \
+ in += 6; \
+ out += 6; \
+ } \
+}
+
+#define REORDER_OUT_71(NAME, TYPE) \
+static void alsa_reorder_ ## NAME ## _out_71(const void *in_v, void *out_v, int n) \
+{ \
+ const TYPE *in = in_v; \
+ TYPE *out = out_v; \
+\
+ while (n-- > 0) { \
+ out[0] = in[0]; \
+ out[1] = in[1]; \
+ out[2] = in[4]; \
+ out[3] = in[5]; \
+ out[4] = in[2]; \
+ out[5] = in[3]; \
+ out[6] = in[6]; \
+ out[7] = in[7]; \
+ in += 8; \
+ out += 8; \
+ } \
+}
+
+REORDER_OUT_50(int8, int8_t)
+REORDER_OUT_51(int8, int8_t)
+REORDER_OUT_71(int8, int8_t)
+REORDER_OUT_50(int16, int16_t)
+REORDER_OUT_51(int16, int16_t)
+REORDER_OUT_71(int16, int16_t)
+REORDER_OUT_50(int32, int32_t)
+REORDER_OUT_51(int32, int32_t)
+REORDER_OUT_71(int32, int32_t)
+REORDER_OUT_50(f32, float)
+REORDER_OUT_51(f32, float)
+REORDER_OUT_71(f32, float)
+
+#define FORMAT_I8 0
+#define FORMAT_I16 1
+#define FORMAT_I32 2
+#define FORMAT_F32 3
+
+#define PICK_REORDER(layout)\
+switch(format) {\
+ case FORMAT_I8: s->reorder_func = alsa_reorder_int8_out_ ##layout; break;\
+ case FORMAT_I16: s->reorder_func = alsa_reorder_int16_out_ ##layout; break;\
+ case FORMAT_I32: s->reorder_func = alsa_reorder_int32_out_ ##layout; break;\
+ case FORMAT_F32: s->reorder_func = alsa_reorder_f32_out_ ##layout; break;\
+}
+
+static av_cold int find_reorder_func(AlsaData *s, int codec_id, uint64_t layout, int out)
+{
+ int format;
+
+ /* reordering input is not currently supported */
+ if (!out)
+ return AVERROR(ENOSYS);
+
+ /* reordering is not needed for QUAD or 2_2 layout */
+ if (layout == AV_CH_LAYOUT_QUAD || layout == AV_CH_LAYOUT_2_2)
+ return 0;
+
+ switch (codec_id) {
+ case CODEC_ID_PCM_S8:
+ case CODEC_ID_PCM_U8:
+ case CODEC_ID_PCM_ALAW:
+ case CODEC_ID_PCM_MULAW: format = FORMAT_I8; break;
+ case CODEC_ID_PCM_S16LE:
+ case CODEC_ID_PCM_S16BE:
+ case CODEC_ID_PCM_U16LE:
+ case CODEC_ID_PCM_U16BE: format = FORMAT_I16; break;
+ case CODEC_ID_PCM_S32LE:
+ case CODEC_ID_PCM_S32BE:
+ case CODEC_ID_PCM_U32LE:
+ case CODEC_ID_PCM_U32BE: format = FORMAT_I32; break;
+ case CODEC_ID_PCM_F32LE:
+ case CODEC_ID_PCM_F32BE: format = FORMAT_F32; break;
+ default: return AVERROR(ENOSYS);
+ }
+
+ if (layout == AV_CH_LAYOUT_5POINT0_BACK || layout == AV_CH_LAYOUT_5POINT0)
+ PICK_REORDER(50)
+ else if (layout == AV_CH_LAYOUT_5POINT1_BACK || layout == AV_CH_LAYOUT_5POINT1)
+ PICK_REORDER(51)
+ else if (layout == AV_CH_LAYOUT_7POINT1)
+ PICK_REORDER(71)
+
+ return s->reorder_func ? 0 : AVERROR(ENOSYS);
+}
+
av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
unsigned int *sample_rate,
int channels, enum CodecID *codec_id)
@@ -71,6 +194,7 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
snd_pcm_t *h;
snd_pcm_hw_params_t *hw_params;
snd_pcm_uframes_t buffer_size, period_size;
+ uint64_t layout = ctx->streams[0]->codec->channel_layout;
if (ctx->filename[0] == 0) audio_device = "default";
else audio_device = ctx->filename;
@@ -166,6 +290,21 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
snd_pcm_hw_params_free(hw_params);
+ if (channels > 2 && layout) {
+ if (find_reorder_func(s, *codec_id, layout, mode == SND_PCM_STREAM_PLAYBACK) < 0) {
+ char name[128];
+ av_get_channel_layout_string(name, sizeof(name), channels, layout);
+ av_log(ctx, AV_LOG_WARNING, "ALSA channel layout unknown or unimplemented for %s %s.\n",
+ name, mode == SND_PCM_STREAM_PLAYBACK ? "playback" : "capture");
+ }
+ if (s->reorder_func) {
+ s->reorder_buf_size = buffer_size;
+ s->reorder_buf = av_malloc(s->reorder_buf_size * s->frame_size);
+ if (!s->reorder_buf)
+ goto fail1;
+ }
+ }
+
s->h = h;
return 0;
@@ -180,6 +319,7 @@ av_cold int ff_alsa_close(AVFormatContext *s1)
{
AlsaData *s = s1->priv_data;
+ av_freep(&s->reorder_buf);
snd_pcm_close(s->h);
return 0;
}
@@ -204,3 +344,19 @@ int ff_alsa_xrun_recover(AVFormatContext *s1, int err)
}
return err;
}
+
+int ff_alsa_extend_reorder_buf(AlsaData *s, int min_size)
+{
+ int size = s->reorder_buf_size;
+ void *r;
+
+ av_assert0(size != 0);
+ while (size < min_size)
+ size *= 2;
+ r = av_realloc(s->reorder_buf, size * s->frame_size);
+ if (!r)
+ return AVERROR(ENOMEM);
+ s->reorder_buf = r;
+ s->reorder_buf_size = size;
+ return 0;
+}
diff --git a/libavdevice/alsa-audio-dec.c b/libavdevice/alsa-audio-dec.c
index 937f6a6..5344b19 100644
--- a/libavdevice/alsa-audio-dec.c
+++ b/libavdevice/alsa-audio-dec.c
@@ -47,6 +47,7 @@
#include <alsa/asoundlib.h>
#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
#include "libavutil/opt.h"
#include "alsa-audio.h"
@@ -60,15 +61,7 @@ static av_cold int audio_read_header(AVFormatContext *s1,
enum CodecID codec_id;
snd_pcm_sw_params_t *sw_params;
-#if FF_API_FORMAT_PARAMETERS
- if (ap->sample_rate > 0)
- s->sample_rate = ap->sample_rate;
-
- if (ap->channels > 0)
- s->channels = ap->channels;
-#endif
-
- st = av_new_stream(s1, 0);
+ st = avformat_new_stream(s1, NULL);
if (!st) {
av_log(s1, AV_LOG_ERROR, "Cannot add stream\n");
@@ -110,7 +103,7 @@ static av_cold int audio_read_header(AVFormatContext *s1,
st->codec->codec_id = codec_id;
st->codec->sample_rate = s->sample_rate;
st->codec->channels = s->channels;
- av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
return 0;
@@ -159,8 +152,8 @@ static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
}
static const AVOption options[] = {
- { "sample_rate", "", offsetof(AlsaData, sample_rate), FF_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
- { "channels", "", offsetof(AlsaData, channels), FF_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "sample_rate", "", offsetof(AlsaData, sample_rate), AV_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "channels", "", offsetof(AlsaData, channels), AV_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
};
@@ -172,13 +165,12 @@ static const AVClass alsa_demuxer_class = {
};
AVInputFormat ff_alsa_demuxer = {
- "alsa",
- NULL_IF_CONFIG_SMALL("ALSA audio input"),
- sizeof(AlsaData),
- NULL,
- audio_read_header,
- audio_read_packet,
- ff_alsa_close,
- .flags = AVFMT_NOFILE,
- .priv_class = &alsa_demuxer_class,
+ .name = "alsa",
+ .long_name = NULL_IF_CONFIG_SMALL("ALSA audio input"),
+ .priv_data_size = sizeof(AlsaData),
+ .read_header = audio_read_header,
+ .read_packet = audio_read_packet,
+ .read_close = ff_alsa_close,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &alsa_demuxer_class,
};
diff --git a/libavdevice/alsa-audio-enc.c b/libavdevice/alsa-audio-enc.c
index ebe598c..95887c1 100644
--- a/libavdevice/alsa-audio-enc.c
+++ b/libavdevice/alsa-audio-enc.c
@@ -76,7 +76,15 @@ static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt)
int size = pkt->size;
uint8_t *buf = pkt->data;
- while((res = snd_pcm_writei(s->h, buf, size / s->frame_size)) < 0) {
+ size /= s->frame_size;
+ if (s->reorder_func) {
+ if (size > s->reorder_buf_size)
+ if (ff_alsa_extend_reorder_buf(s, size))
+ return AVERROR(ENOMEM);
+ s->reorder_func(buf, s->reorder_buf, size);
+ buf = s->reorder_buf;
+ }
+ while ((res = snd_pcm_writei(s->h, buf, size)) < 0) {
if (res == -EAGAIN) {
return AVERROR(EAGAIN);
@@ -94,15 +102,13 @@ static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt)
}
AVOutputFormat ff_alsa_muxer = {
- "alsa",
- NULL_IF_CONFIG_SMALL("ALSA audio output"),
- "",
- "",
- sizeof(AlsaData),
- DEFAULT_CODEC_ID,
- CODEC_ID_NONE,
- audio_write_header,
- audio_write_packet,
- ff_alsa_close,
- .flags = AVFMT_NOFILE,
+ .name = "alsa",
+ .long_name = NULL_IF_CONFIG_SMALL("ALSA audio output"),
+ .priv_data_size = sizeof(AlsaData),
+ .audio_codec = DEFAULT_CODEC_ID,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = audio_write_header,
+ .write_packet = audio_write_packet,
+ .write_trailer = ff_alsa_close,
+ .flags = AVFMT_NOFILE,
};
diff --git a/libavdevice/alsa-audio.h b/libavdevice/alsa-audio.h
index c8c6ea4..ee43463 100644
--- a/libavdevice/alsa-audio.h
+++ b/libavdevice/alsa-audio.h
@@ -49,6 +49,9 @@ typedef struct {
int period_size; ///< bytes per sample * channels
int sample_rate; ///< sample rate set by user
int channels; ///< number of channels set by user
+ void (*reorder_func)(const void *, void *, int);
+ void *reorder_buf;
+ int reorder_buf_size; ///< in frames
} AlsaData;
/**
@@ -88,4 +91,6 @@ int ff_alsa_close(AVFormatContext *s1);
*/
int ff_alsa_xrun_recover(AVFormatContext *s1, int err);
+int ff_alsa_extend_reorder_buf(AlsaData *s, int size);
+
#endif /* AVDEVICE_ALSA_AUDIO_H */
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index d82b26f..e6c86cb 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -19,10 +19,32 @@
#ifndef AVDEVICE_AVDEVICE_H
#define AVDEVICE_AVDEVICE_H
+/**
+ * @file
+ * @ingroup lavd
+ * Main libavdevice API header
+ */
+
+/**
+ * @defgroup lavd Special devices muxing/demuxing library
+ * @{
+ * Libavdevice is a complementary library to @ref libavf "libavformat". It
+ * provides various "special" platform-specific muxers and demuxers, e.g. for
+ * grabbing devices, audio capture and playback etc. As a consequence, the
+ * (de)muxers in libavdevice are of the AVFMT_NOFILE type (they use their own
+ * I/O functions). The filename passed to avformat_open_input() often does not
+ * refer to an actually existing file, but has some special device-specific
+ * meaning - e.g. for the x11grab device it is the display name.
+ *
+ * To use libavdevice, simply call avdevice_register_all() to register all
+ * compiled muxers and demuxers. They all use standard libavformat API.
+ * @}
+ */
+
#include "libavutil/avutil.h"
#define LIBAVDEVICE_VERSION_MAJOR 53
-#define LIBAVDEVICE_VERSION_MINOR 0
+#define LIBAVDEVICE_VERSION_MINOR 2
#define LIBAVDEVICE_VERSION_MICRO 0
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
diff --git a/libavdevice/bktr.c b/libavdevice/bktr.c
index 4d3933f..e6a1e8b 100644
--- a/libavdevice/bktr.c
+++ b/libavdevice/bktr.c
@@ -25,6 +25,7 @@
*/
#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
@@ -47,7 +48,6 @@
#include <sys/time.h>
#include <signal.h>
#include <stdint.h>
-#include <strings.h>
typedef struct {
AVClass *class;
@@ -248,22 +248,11 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
VideoData *s = s1->priv_data;
AVStream *st;
int width, height;
- AVRational fps;
+ AVRational framerate;
int ret = 0;
-#if FF_API_FORMAT_PARAMETERS
- if (ap->standard) {
- if (!strcasecmp(ap->standard, "pal"))
- s->standard = PAL;
- else if (!strcasecmp(ap->standard, "secam"))
- s->standard = SECAM;
- else if (!strcasecmp(ap->standard, "ntsc"))
- s->standard = NTSC;
- }
-#endif
-
if ((ret = av_parse_video_size(&width, &height, s->video_size)) < 0) {
- av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n");
+ av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n", s->video_size);
goto out;
}
@@ -277,37 +266,29 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
ret = AVERROR(EINVAL);
goto out;
}
- if ((ret = av_parse_video_rate(&fps, s->framerate)) < 0) {
- av_log(s1, AV_LOG_ERROR, "Couldn't parse framerate.\n");
+ if ((ret = av_parse_video_rate(&framerate, s->framerate)) < 0) {
+ av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", s->framerate);
goto out;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->width > 0)
- width = ap->width;
- if (ap->height > 0)
- height = ap->height;
- if (ap->time_base.num)
- fps = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
- st = av_new_stream(s1, 0);
+ st = avformat_new_stream(s1, NULL);
if (!st) {
ret = AVERROR(ENOMEM);
goto out;
}
- av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in use */
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in use */
s->width = width;
s->height = height;
- s->per_frame = ((uint64_t)1000000 * fps.den) / fps.num;
+ s->per_frame = ((uint64_t)1000000 * framerate.den) / framerate.num;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->pix_fmt = PIX_FMT_YUV420P;
st->codec->codec_id = CODEC_ID_RAWVIDEO;
st->codec->width = width;
st->codec->height = height;
- st->codec->time_base.den = fps.num;
- st->codec->time_base.num = fps.den;
+ st->codec->time_base.den = framerate.num;
+ st->codec->time_base.num = framerate.den;
if (bktr_init(s1->filename, width, height, s->standard,
@@ -344,15 +325,15 @@ static int grab_read_close(AVFormatContext *s1)
#define OFFSET(x) offsetof(VideoData, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "standard", "", offsetof(VideoData, standard), FF_OPT_TYPE_INT, {.dbl = VIDEO_FORMAT}, PAL, NTSCJ, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "PAL", "", 0, FF_OPT_TYPE_CONST, {.dbl = PAL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "NTSC", "", 0, FF_OPT_TYPE_CONST, {.dbl = NTSC}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "SECAM", "", 0, FF_OPT_TYPE_CONST, {.dbl = SECAM}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "PALN", "", 0, FF_OPT_TYPE_CONST, {.dbl = PALN}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "PALM", "", 0, FF_OPT_TYPE_CONST, {.dbl = PALM}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "NTSCJ", "", 0, FF_OPT_TYPE_CONST, {.dbl = NTSCJ}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = "vga"}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "standard", "", offsetof(VideoData, standard), AV_OPT_TYPE_INT, {.dbl = VIDEO_FORMAT}, PAL, NTSCJ, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "PAL", "", 0, AV_OPT_TYPE_CONST, {.dbl = PAL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "NTSC", "", 0, AV_OPT_TYPE_CONST, {.dbl = NTSC}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "SECAM", "", 0, AV_OPT_TYPE_CONST, {.dbl = SECAM}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "PALN", "", 0, AV_OPT_TYPE_CONST, {.dbl = PALN}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "PALM", "", 0, AV_OPT_TYPE_CONST, {.dbl = PALM}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "NTSCJ", "", 0, AV_OPT_TYPE_CONST, {.dbl = NTSCJ}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "vga"}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
{ NULL },
};
@@ -364,13 +345,12 @@ static const AVClass bktr_class = {
};
AVInputFormat ff_bktr_demuxer = {
- "bktr",
- NULL_IF_CONFIG_SMALL("video grab"),
- sizeof(VideoData),
- NULL,
- grab_read_header,
- grab_read_packet,
- grab_read_close,
- .flags = AVFMT_NOFILE,
- .priv_class = &bktr_class,
+ .name = "bktr",
+ .long_name = NULL_IF_CONFIG_SMALL("video grab"),
+ .priv_data_size = sizeof(VideoData),
+ .read_header = grab_read_header,
+ .read_packet = grab_read_packet,
+ .read_close = grab_read_close,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &bktr_class,
};
diff --git a/libavdevice/dv1394.c b/libavdevice/dv1394.c
index 565cf4c..69e59ec 100644
--- a/libavdevice/dv1394.c
+++ b/libavdevice/dv1394.c
@@ -28,7 +28,6 @@
#include <sys/mman.h>
#include <sys/time.h>
#include <time.h>
-#include <strings.h>
#include "libavutil/log.h"
#include "libavutil/opt.h"
@@ -86,22 +85,10 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
{
struct dv1394_data *dv = context->priv_data;
- dv->dv_demux = dv_init_demux(context);
+ dv->dv_demux = avpriv_dv_init_demux(context);
if (!dv->dv_demux)
goto failed;
-#if FF_API_FORMAT_PARAMETERS
- if (ap->standard) {
- if (!strcasecmp(ap->standard, "pal"))
- dv->format = DV1394_PAL;
- else
- dv->format = DV1394_NTSC;
- }
-
- if (ap->channel)
- dv->channel = ap->channel;
-#endif
-
/* Open and initialize DV1394 device */
dv->fd = open(context->filename, O_RDONLY);
if (dv->fd < 0) {
@@ -136,7 +123,7 @@ static int dv1394_read_packet(AVFormatContext *context, AVPacket *pkt)
struct dv1394_data *dv = context->priv_data;
int size;
- size = dv_get_packet(dv->dv_demux, pkt);
+ size = avpriv_dv_get_packet(dv->dv_demux, pkt);
if (size > 0)
return size;
@@ -198,7 +185,7 @@ restart_poll:
av_dlog(context, "index %d, avail %d, done %d\n", dv->index, dv->avail,
dv->done);
- size = dv_produce_packet(dv->dv_demux, pkt,
+ size = avpriv_dv_produce_packet(dv->dv_demux, pkt,
dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE),
DV1394_PAL_FRAME_SIZE);
dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
@@ -226,10 +213,10 @@ static int dv1394_close(AVFormatContext * context)
}
static const AVOption options[] = {
- { "standard", "", offsetof(struct dv1394_data, format), FF_OPT_TYPE_INT, {.dbl = DV1394_NTSC}, DV1394_PAL, DV1394_NTSC, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "PAL", "", 0, FF_OPT_TYPE_CONST, {.dbl = DV1394_PAL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "NTSC", "", 0, FF_OPT_TYPE_CONST, {.dbl = DV1394_NTSC}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "channel", "", offsetof(struct dv1394_data, channel), FF_OPT_TYPE_INT, {.dbl = DV1394_DEFAULT_CHANNEL}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "standard", "", offsetof(struct dv1394_data, format), AV_OPT_TYPE_INT, {.dbl = DV1394_NTSC}, DV1394_PAL, DV1394_NTSC, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "PAL", "", 0, AV_OPT_TYPE_CONST, {.dbl = DV1394_PAL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "NTSC", "", 0, AV_OPT_TYPE_CONST, {.dbl = DV1394_NTSC}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "channel", "", offsetof(struct dv1394_data, channel), AV_OPT_TYPE_INT, {.dbl = DV1394_DEFAULT_CHANNEL}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
};
diff --git a/libavdevice/fbdev.c b/libavdevice/fbdev.c
index afd6b94..7444f47 100644
--- a/libavdevice/fbdev.c
+++ b/libavdevice/fbdev.c
@@ -24,7 +24,7 @@
* @file
* Linux framebuffer input device,
* inspired by code from fbgrab.c by Gunnar Monell.
- * See also http://linux-fbdev.sourceforge.net/.
+ * @see http://linux-fbdev.sourceforge.net/
*/
/* #define DEBUG */
@@ -43,6 +43,7 @@
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
struct rgb_pixfmt_map_entry {
int bits_per_pixel;
@@ -79,12 +80,12 @@ static enum PixelFormat get_pixfmt_from_fb_varinfo(struct fb_var_screeninfo *var
typedef struct {
AVClass *class; ///< class for private options
int frame_size; ///< size in bytes of a grabbed frame
- AVRational fps; ///< framerate
+ AVRational framerate_q; ///< framerate
char *framerate; ///< framerate string set by a private option
int64_t time_frame; ///< time for the next frame to output (in 1/1000000 units)
int fd; ///< framebuffer device file descriptor
- int width, heigth; ///< assumed frame resolution
+ int width, height; ///< assumed frame resolution
int frame_linesize; ///< linesize of the output frame, it is assumed to be constant
int bytes_per_pixel;
@@ -102,19 +103,15 @@ av_cold static int fbdev_read_header(AVFormatContext *avctx,
enum PixelFormat pix_fmt;
int ret, flags = O_RDONLY;
- ret = av_parse_video_rate(&fbdev->fps, fbdev->framerate);
+ ret = av_parse_video_rate(&fbdev->framerate_q, fbdev->framerate);
if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Couldn't parse framerate.\n");
+ av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", fbdev->framerate);
return ret;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->time_base.num)
- fbdev->fps = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
- if (!(st = av_new_stream(avctx, 0)))
+ if (!(st = avformat_new_stream(avctx, NULL)))
return AVERROR(ENOMEM);
- av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in microseconds */
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in microseconds */
/* NONBLOCK is ignored by the fbdev driver, only set for consistency */
if (avctx->flags & AVFMT_FLAG_NONBLOCK)
@@ -151,10 +148,10 @@ av_cold static int fbdev_read_header(AVFormatContext *avctx,
}
fbdev->width = fbdev->varinfo.xres;
- fbdev->heigth = fbdev->varinfo.yres;
+ fbdev->height = fbdev->varinfo.yres;
fbdev->bytes_per_pixel = (fbdev->varinfo.bits_per_pixel + 7) >> 3;
fbdev->frame_linesize = fbdev->width * fbdev->bytes_per_pixel;
- fbdev->frame_size = fbdev->frame_linesize * fbdev->heigth;
+ fbdev->frame_size = fbdev->frame_linesize * fbdev->height;
fbdev->time_frame = AV_NOPTS_VALUE;
fbdev->data = mmap(NULL, fbdev->fixinfo.smem_len, PROT_READ, MAP_SHARED, fbdev->fd, 0);
if (fbdev->data == MAP_FAILED) {
@@ -166,17 +163,17 @@ av_cold static int fbdev_read_header(AVFormatContext *avctx,
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_RAWVIDEO;
st->codec->width = fbdev->width;
- st->codec->height = fbdev->heigth;
+ st->codec->height = fbdev->height;
st->codec->pix_fmt = pix_fmt;
- st->codec->time_base = (AVRational){fbdev->fps.den, fbdev->fps.num};
+ st->codec->time_base = (AVRational){fbdev->framerate_q.den, fbdev->framerate_q.num};
st->codec->bit_rate =
- fbdev->width * fbdev->heigth * fbdev->bytes_per_pixel * av_q2d(fbdev->fps) * 8;
+ fbdev->width * fbdev->height * fbdev->bytes_per_pixel * av_q2d(fbdev->framerate_q) * 8;
av_log(avctx, AV_LOG_INFO,
"w:%d h:%d bpp:%d pixfmt:%s fps:%d/%d bit_rate:%d\n",
- fbdev->width, fbdev->heigth, fbdev->varinfo.bits_per_pixel,
+ fbdev->width, fbdev->height, fbdev->varinfo.bits_per_pixel,
av_pix_fmt_descriptors[pix_fmt].name,
- fbdev->fps.num, fbdev->fps.den,
+ fbdev->framerate_q.num, fbdev->framerate_q.den,
st->codec->bit_rate);
return 0;
@@ -210,7 +207,7 @@ static int fbdev_read_packet(AVFormatContext *avctx, AVPacket *pkt)
while (nanosleep(&ts, &ts) < 0 && errno == EINTR);
}
/* compute the time of the next frame */
- fbdev->time_frame += INT64_C(1000000) / av_q2d(fbdev->fps);
+ fbdev->time_frame += INT64_C(1000000) / av_q2d(fbdev->framerate_q);
if ((ret = av_new_packet(pkt, fbdev->frame_size)) < 0)
return ret;
@@ -228,7 +225,7 @@ static int fbdev_read_packet(AVFormatContext *avctx, AVPacket *pkt)
pout = pkt->data;
// TODO it'd be nice if the lines were aligned
- for (i = 0; i < fbdev->heigth; i++) {
+ for (i = 0; i < fbdev->height; i++) {
memcpy(pout, pin, fbdev->frame_linesize);
pin += fbdev->fixinfo.line_length;
pout += fbdev->frame_linesize;
@@ -250,7 +247,7 @@ av_cold static int fbdev_read_close(AVFormatContext *avctx)
#define OFFSET(x) offsetof(FBDevContext, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "framerate","", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+ { "framerate","", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
{ NULL },
};
diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c
index 4af89bd..e68559e 100644
--- a/libavdevice/jack_audio.c
+++ b/libavdevice/jack_audio.c
@@ -26,9 +26,11 @@
#include "libavutil/log.h"
#include "libavutil/fifo.h"
+#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
-#include "libavformat/timefilter.h"
+#include "libavformat/internal.h"
+#include "timefilter.h"
/**
* Size of the internal FIFO buffers as a number of audio packets
@@ -36,6 +38,7 @@
#define FIFO_PACKETS_NUM 16
typedef struct {
+ AVClass *class;
jack_client_t * client;
int activated;
sem_t packet_count;
@@ -136,7 +139,7 @@ static int supply_new_packets(JackData *self, AVFormatContext *context)
return 0;
}
-static int start_jack(AVFormatContext *context, AVFormatParameters *params)
+static int start_jack(AVFormatContext *context)
{
JackData *self = context->priv_data;
jack_status_t status;
@@ -153,7 +156,6 @@ static int start_jack(AVFormatContext *context, AVFormatParameters *params)
sem_init(&self->packet_count, 0, 0);
self->sample_rate = jack_get_sample_rate(self->client);
- self->nports = params->channels;
self->ports = av_malloc(self->nports * sizeof(*self->ports));
self->buffer_size = jack_get_buffer_size(self->client);
@@ -225,13 +227,10 @@ static int audio_read_header(AVFormatContext *context, AVFormatParameters *param
AVStream *stream;
int test;
- if (params->sample_rate <= 0 || params->channels <= 0)
- return -1;
-
- if ((test = start_jack(context, params)))
+ if ((test = start_jack(context)))
return test;
- stream = av_new_stream(context, 0);
+ stream = avformat_new_stream(context, NULL);
if (!stream) {
stop_jack(self);
return AVERROR(ENOMEM);
@@ -246,7 +245,7 @@ static int audio_read_header(AVFormatContext *context, AVFormatParameters *param
stream->codec->sample_rate = self->sample_rate;
stream->codec->channels = self->nports;
- av_set_pts_info(stream, 64, 1, 1000000); /* 64 bits pts in us */
+ avpriv_set_pts_info(stream, 64, 1, 1000000); /* 64 bits pts in us */
return 0;
}
@@ -272,7 +271,7 @@ static int audio_read_packet(AVFormatContext *context, AVPacket *pkt)
}
}
- /* Wait for a packet comming back from process_callback(), if one isn't available yet */
+ /* Wait for a packet coming back from process_callback(), if one isn't available yet */
timeout.tv_sec = av_gettime() / 1000000 + 2;
if (sem_timedwait(&self->packet_count, &timeout)) {
if (errno == ETIMEDOUT) {
@@ -314,13 +313,26 @@ static int audio_read_close(AVFormatContext *context)
return 0;
}
+#define OFFSET(x) offsetof(JackData, x)
+static const AVOption options[] = {
+ { "channels", "Number of audio channels.", OFFSET(nports), AV_OPT_TYPE_INT, { 2 }, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { NULL },
+};
+
+static const AVClass jack_indev_class = {
+ .class_name = "JACK indev",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_jack_demuxer = {
- "jack",
- NULL_IF_CONFIG_SMALL("JACK Audio Connection Kit"),
- sizeof(JackData),
- NULL,
- audio_read_header,
- audio_read_packet,
- audio_read_close,
- .flags = AVFMT_NOFILE,
+ .name = "jack",
+ .long_name = NULL_IF_CONFIG_SMALL("JACK Audio Connection Kit"),
+ .priv_data_size = sizeof(JackData),
+ .read_header = audio_read_header,
+ .read_packet = audio_read_packet,
+ .read_close = audio_read_close,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &jack_indev_class,
};
diff --git a/libavdevice/libcdio.c b/libavdevice/libcdio.c
new file mode 100644
index 0000000..e00272c
--- /dev/null
+++ b/libavdevice/libcdio.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2011 Anton Khirnov <anton at khirnov.net>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * libcdio CD grabbing
+ */
+
+#include <cdio/cdda.h>
+#include <cdio/paranoia.h>
+
+#include "libavutil/log.h"
+#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+
+#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
+
+/* cdio returns some malloced strings that need to be free()d */
+#undef free
+
+typedef struct CDIOContext {
+ cdrom_drive_t *drive;
+ cdrom_paranoia_t *paranoia;
+ int32_t last_sector;
+
+ /* private options */
+ int speed;
+ int paranoia_mode;
+} CDIOContext;
+
+static av_cold int read_header(AVFormatContext *ctx, AVFormatParameters *ap)
+{
+ CDIOContext *s = ctx->priv_data;
+ AVStream *st;
+ int ret, i;
+ char *err = NULL;
+
+ if (!(st = avformat_new_stream(ctx, NULL)))
+ return AVERROR(ENOMEM);
+ s->drive = cdio_cddap_identify(ctx->filename, CDDA_MESSAGE_LOGIT, &err);
+ if (!s->drive) {
+ av_log(ctx, AV_LOG_ERROR, "Could not open drive %s.\n", ctx->filename);
+ return AVERROR(EINVAL);
+ }
+ if (err) {
+ av_log(ctx, AV_LOG_VERBOSE, "%s\n", err);
+ free(err);
+ }
+ if ((ret = cdio_cddap_open(s->drive)) < 0 || !s->drive->opened) {
+ av_log(ctx, AV_LOG_ERROR, "Could not open disk in drive %s.\n", ctx->filename);
+ return AVERROR(EINVAL);
+ }
+
+ cdio_cddap_verbose_set(s->drive, CDDA_MESSAGE_LOGIT, CDDA_MESSAGE_LOGIT);
+ if (s->speed)
+ cdio_cddap_speed_set(s->drive, s->speed);
+
+ s->paranoia = cdio_paranoia_init(s->drive);
+ if (!s->paranoia) {
+ av_log(ctx, AV_LOG_ERROR, "Could not init paranoia.\n");
+ return AVERROR(EINVAL);
+ }
+ cdio_paranoia_modeset(s->paranoia, s->paranoia_mode);
+
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ if (s->drive->bigendianp)
+ st->codec->codec_id = CODEC_ID_PCM_S16BE;
+ else
+ st->codec->codec_id = CODEC_ID_PCM_S16LE;
+ st->codec->sample_rate = 44100;
+ st->codec->channels = 2;
+ if (s->drive->audio_last_sector != CDIO_INVALID_LSN &&
+ s->drive->audio_first_sector != CDIO_INVALID_LSN)
+ st->duration = s->drive->audio_last_sector - s->drive->audio_first_sector;
+ else if (s->drive->tracks)
+ st->duration = s->drive->disc_toc[s->drive->tracks].dwStartSector;
+ avpriv_set_pts_info(st, 64, CDIO_CD_FRAMESIZE_RAW, 2*st->codec->channels*st->codec->sample_rate);
+
+ for (i = 0; i < s->drive->tracks; i++) {
+ char title[16];
+ snprintf(title, sizeof(title), "track %02d", s->drive->disc_toc[i].bTrack);
+ avpriv_new_chapter(ctx, i, st->time_base, s->drive->disc_toc[i].dwStartSector,
+ s->drive->disc_toc[i+1].dwStartSector, title);
+ }
+
+ s->last_sector = cdio_cddap_disc_lastsector(s->drive);
+
+ return 0;
+}
+
+static int read_packet(AVFormatContext *ctx, AVPacket *pkt)
+{
+ CDIOContext *s = ctx->priv_data;
+ int ret;
+ uint16_t *buf;
+ char *err = NULL;
+
+ if (ctx->streams[0]->cur_dts > s->last_sector)
+ return AVERROR_EOF;
+
+ buf = cdio_paranoia_read(s->paranoia, NULL);
+ if (!buf)
+ return AVERROR_EOF;
+
+ if (err = cdio_cddap_errors(s->drive)) {
+ av_log(ctx, AV_LOG_ERROR, "%s\n", err);
+ free(err);
+ err = NULL;
+ }
+ if (err = cdio_cddap_messages(s->drive)) {
+ av_log(ctx, AV_LOG_VERBOSE, "%s\n", err);
+ free(err);
+ err = NULL;
+ }
+
+ if ((ret = av_new_packet(pkt, CDIO_CD_FRAMESIZE_RAW)) < 0)
+ return ret;
+ memcpy(pkt->data, buf, CDIO_CD_FRAMESIZE_RAW);
+ return 0;
+}
+
+static av_cold int read_close(AVFormatContext *ctx)
+{
+ CDIOContext *s = ctx->priv_data;
+ cdio_paranoia_free(s->paranoia);
+ cdio_cddap_close(s->drive);
+ return 0;
+}
+
+static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp,
+ int flags)
+{
+ CDIOContext *s = ctx->priv_data;
+ AVStream *st = ctx->streams[0];
+
+ cdio_paranoia_seek(s->paranoia, timestamp, SEEK_SET);
+ st->cur_dts = timestamp;
+ return 0;
+}
+
+#define OFFSET(x) offsetof(CDIOContext, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ { "speed", "Drive reading speed.", OFFSET(speed), AV_OPT_TYPE_INT, { 0 }, 0, INT_MAX, DEC },
+ { "paranoia_mode", "Error recovery mode.", OFFSET(paranoia_mode), AV_OPT_TYPE_FLAGS, { 0 }, INT_MIN, INT_MAX, DEC, "paranoia_mode" },
+ { "verify", "Verify data integrity in overlap area", 0, AV_OPT_TYPE_CONST, { PARANOIA_MODE_VERIFY }, 0, 0, DEC, "paranoia_mode" },
+ { "overlap", "Perform overlapped reads.", 0, AV_OPT_TYPE_CONST, { PARANOIA_MODE_OVERLAP }, 0, 0, DEC, "paranoia_mode" },
+ { "neverskip", "Do not skip failed reads.", 0, AV_OPT_TYPE_CONST, { PARANOIA_MODE_NEVERSKIP }, 0, 0, DEC, "paranoia_mode" },
+ { NULL },
+};
+
+static const AVClass libcdio_class = {
+ .class_name = "libcdio indev",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_libcdio_demuxer = {
+ .name = "libcdio",
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .read_close = read_close,
+ .read_seek = read_seek,
+ .priv_data_size = sizeof(CDIOContext),
+ .flags = AVFMT_NOFILE,
+ .priv_class = &libcdio_class,
+};
diff --git a/libavdevice/libdc1394.c b/libavdevice/libdc1394.c
index 622579b..ac4bb09 100644
--- a/libavdevice/libdc1394.c
+++ b/libavdevice/libdc1394.c
@@ -22,7 +22,9 @@
#include "config.h"
#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
@@ -99,11 +101,11 @@ struct dc1394_frame_rate {
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
#if HAVE_LIBDC1394_1
- { "channel", "", offsetof(dc1394_data, channel), FF_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "channel", "", offsetof(dc1394_data, channel), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
#endif
- { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = "qvga"}, 0, 0, DEC },
- { "pixel_format", "", OFFSET(pixel_format), FF_OPT_TYPE_STRING, {.str = "uyvy422"}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC },
+ { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "qvga"}, 0, 0, DEC },
+ { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "uyvy422"}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC },
{ NULL },
};
@@ -134,23 +136,13 @@ static inline int dc1394_read_common(AVFormatContext *c, AVFormatParameters *ap,
}
if ((ret = av_parse_video_size(&width, &height, dc1394->video_size)) < 0) {
- av_log(c, AV_LOG_ERROR, "Couldn't parse video size.\n");
+ av_log(c, AV_LOG_ERROR, "Could not parse video size '%s'.\n", dc1394->video_size);
goto out;
}
if ((ret = av_parse_video_rate(&framerate, dc1394->framerate)) < 0) {
- av_log(c, AV_LOG_ERROR, "Couldn't parse framerate.\n");
+ av_log(c, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", dc1394->framerate);
goto out;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->width > 0)
- width = ap->width;
- if (ap->height > 0)
- height = ap->height;
- if (ap->pix_fmt)
- pix_fmt = ap->pix_fmt;
- if (ap->time_base.num)
- framerate = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
dc1394->frame_rate = av_rescale(1000, framerate.num, framerate.den);
for (fmt = dc1394_frame_formats; fmt->width; fmt++)
@@ -169,12 +161,12 @@ static inline int dc1394_read_common(AVFormatContext *c, AVFormatParameters *ap,
}
/* create a video stream */
- vst = av_new_stream(c, 0);
+ vst = avformat_new_stream(c, NULL);
if (!vst) {
ret = AVERROR(ENOMEM);
goto out;
}
- av_set_pts_info(vst, 64, 1, 1000);
+ avpriv_set_pts_info(vst, 64, 1, 1000);
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vst->codec->codec_id = CODEC_ID_RAWVIDEO;
vst->codec->time_base.den = framerate.num;
@@ -211,11 +203,6 @@ static int dc1394_v1_read_header(AVFormatContext *c, AVFormatParameters * ap)
if (dc1394_read_common(c,ap,&fmt,&fps) != 0)
return -1;
-#if FF_API_FORMAT_PARAMETERS
- if (ap->channel)
- dc1394->channel = ap->channel;
-#endif
-
/* Now let us prep the hardware. */
dc1394->handle = dc1394_create_handle(0); /* FIXME: gotta have ap->port */
if (!dc1394->handle) {
@@ -384,8 +371,8 @@ static int dc1394_v2_read_packet(AVFormatContext *c, AVPacket *pkt)
res = dc1394_capture_dequeue(dc1394->camera, DC1394_CAPTURE_POLICY_WAIT, &dc1394->frame);
if (res == DC1394_SUCCESS) {
- dc1394->packet.data = (uint8_t *)(dc1394->frame->image);
- dc1394->packet.pts = (dc1394->current_frame * 1000000) / (dc1394->frame_rate);
+ dc1394->packet.data = (uint8_t *) dc1394->frame->image;
+ dc1394->packet.pts = dc1394->current_frame * 1000000 / dc1394->frame_rate;
res = dc1394->frame->image_bytes;
} else {
av_log(c, AV_LOG_ERROR, "DMA capture failed\n");
diff --git a/libavdevice/oss_audio.c b/libavdevice/oss_audio.c
index fcbe26b..308fc0d 100644
--- a/libavdevice/oss_audio.c
+++ b/libavdevice/oss_audio.c
@@ -40,6 +40,7 @@
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
#define AUDIO_BLOCK_SIZE 4096
@@ -80,13 +81,6 @@ static int audio_open(AVFormatContext *s1, int is_output, const char *audio_devi
fcntl(audio_fd, F_SETFL, O_NONBLOCK);
s->frame_size = AUDIO_BLOCK_SIZE;
-#if 0
- tmp = (NB_FRAGMENTS << 16) | FRAGMENT_BITS;
- err = ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &tmp);
- if (err < 0) {
- perror("SNDCTL_DSP_SETFRAGMENT");
- }
-#endif
/* select format : favour native format */
err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp);
@@ -216,14 +210,7 @@ static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap)
AVStream *st;
int ret;
-#if FF_API_FORMAT_PARAMETERS
- if (ap->sample_rate > 0)
- s->sample_rate = ap->sample_rate;
- if (ap->channels > 0)
- s->channels = ap->channels;
-#endif
-
- st = av_new_stream(s1, 0);
+ st = avformat_new_stream(s1, NULL);
if (!st) {
return AVERROR(ENOMEM);
}
@@ -239,7 +226,7 @@ static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap)
st->codec->sample_rate = s->sample_rate;
st->codec->channels = s->channels;
- av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
return 0;
}
@@ -296,8 +283,8 @@ static int audio_read_close(AVFormatContext *s1)
#if CONFIG_OSS_INDEV
static const AVOption options[] = {
- { "sample_rate", "", offsetof(AudioData, sample_rate), FF_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
- { "channels", "", offsetof(AudioData, channels), FF_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "sample_rate", "", offsetof(AudioData, sample_rate), AV_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "channels", "", offsetof(AudioData, channels), AV_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
};
@@ -309,33 +296,30 @@ static const AVClass oss_demuxer_class = {
};
AVInputFormat ff_oss_demuxer = {
- "oss",
- NULL_IF_CONFIG_SMALL("Open Sound System capture"),
- sizeof(AudioData),
- NULL,
- audio_read_header,
- audio_read_packet,
- audio_read_close,
- .flags = AVFMT_NOFILE,
- .priv_class = &oss_demuxer_class,
+ .name = "oss",
+ .long_name = NULL_IF_CONFIG_SMALL("Open Sound System capture"),
+ .priv_data_size = sizeof(AudioData),
+ .read_header = audio_read_header,
+ .read_packet = audio_read_packet,
+ .read_close = audio_read_close,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &oss_demuxer_class,
};
#endif
#if CONFIG_OSS_OUTDEV
AVOutputFormat ff_oss_muxer = {
- "oss",
- NULL_IF_CONFIG_SMALL("Open Sound System playback"),
- "",
- "",
- sizeof(AudioData),
+ .name = "oss",
+ .long_name = NULL_IF_CONFIG_SMALL("Open Sound System playback"),
+ .priv_data_size = sizeof(AudioData),
/* XXX: we make the assumption that the soundcard accepts this format */
/* XXX: find better solution with "preinit" method, needed also in
other formats */
- AV_NE(CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE),
- CODEC_ID_NONE,
- audio_write_header,
- audio_write_packet,
- audio_write_trailer,
- .flags = AVFMT_NOFILE,
+ .audio_codec = AV_NE(CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE),
+ .video_codec = CODEC_ID_NONE,
+ .write_header = audio_write_header,
+ .write_packet = audio_write_packet,
+ .write_trailer = audio_write_trailer,
+ .flags = AVFMT_NOFILE,
};
#endif
diff --git a/libavdevice/pulse.c b/libavdevice/pulse.c
new file mode 100644
index 0000000..bffe391
--- /dev/null
+++ b/libavdevice/pulse.c
@@ -0,0 +1,191 @@
+/*
+ * Pulseaudio input
+ * Copyright (c) 2011 Luca Barbato <lu_zero at gentoo.org>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * PulseAudio input using the simple API.
+ * @author Luca Barbato <lu_zero at gentoo.org>
+ */
+
+#include <pulse/simple.h>
+#include <pulse/rtclock.h>
+#include <pulse/error.h>
+
+#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
+#include "libavutil/opt.h"
+
+#define DEFAULT_CODEC_ID AV_NE(CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE)
+
+typedef struct PulseData {
+ AVClass *class;
+ char *server;
+ char *name;
+ char *stream_name;
+ int sample_rate;
+ int channels;
+ int frame_size;
+ int fragment_size;
+ pa_simple *s;
+ int64_t pts;
+ int64_t frame_duration;
+} PulseData;
+
+static pa_sample_format_t codec_id_to_pulse_format(int codec_id) {
+ switch (codec_id) {
+ case CODEC_ID_PCM_U8: return PA_SAMPLE_U8;
+ case CODEC_ID_PCM_ALAW: return PA_SAMPLE_ALAW;
+ case CODEC_ID_PCM_MULAW: return PA_SAMPLE_ULAW;
+ case CODEC_ID_PCM_S16LE: return PA_SAMPLE_S16LE;
+ case CODEC_ID_PCM_S16BE: return PA_SAMPLE_S16BE;
+ case CODEC_ID_PCM_F32LE: return PA_SAMPLE_FLOAT32LE;
+ case CODEC_ID_PCM_F32BE: return PA_SAMPLE_FLOAT32BE;
+ case CODEC_ID_PCM_S32LE: return PA_SAMPLE_S32LE;
+ case CODEC_ID_PCM_S32BE: return PA_SAMPLE_S32BE;
+ case CODEC_ID_PCM_S24LE: return PA_SAMPLE_S24LE;
+ case CODEC_ID_PCM_S24BE: return PA_SAMPLE_S24BE;
+ default: return PA_SAMPLE_INVALID;
+ }
+}
+
+static av_cold int pulse_read_header(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ PulseData *pd = s->priv_data;
+ AVStream *st;
+ char *device = NULL;
+ int ret;
+ enum CodecID codec_id =
+ s->audio_codec_id == CODEC_ID_NONE ? DEFAULT_CODEC_ID : s->audio_codec_id;
+ const pa_sample_spec ss = { codec_id_to_pulse_format(codec_id),
+ pd->sample_rate,
+ pd->channels };
+
+ pa_buffer_attr attr = { -1 };
+
+ st = avformat_new_stream(s, NULL);
+
+ if (!st) {
+ av_log(s, AV_LOG_ERROR, "Cannot add stream\n");
+ return AVERROR(ENOMEM);
+ }
+
+ attr.fragsize = pd->fragment_size;
+
+ if (strcmp(s->filename, "default"))
+ device = s->filename;
+
+ pd->s = pa_simple_new(pd->server, pd->name,
+ PA_STREAM_RECORD,
+ device, pd->stream_name, &ss,
+ NULL, &attr, &ret);
+
+ if (!pd->s) {
+ av_log(s, AV_LOG_ERROR, "pa_simple_new failed: %s\n",
+ pa_strerror(ret));
+ return AVERROR(EIO);
+ }
+ /* take real parameters */
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = codec_id;
+ st->codec->sample_rate = pd->sample_rate;
+ st->codec->channels = pd->channels;
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+
+ pd->pts = AV_NOPTS_VALUE;
+ pd->frame_duration = (pd->frame_size * 1000000LL * 8) /
+ (pd->sample_rate * pd->channels * av_get_bits_per_sample(codec_id));
+
+ return 0;
+}
+
+static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ PulseData *pd = s->priv_data;
+ int res;
+ pa_usec_t latency;
+
+ if (av_new_packet(pkt, pd->frame_size) < 0) {
+ return AVERROR(ENOMEM);
+ }
+
+ if ((pa_simple_read(pd->s, pkt->data, pkt->size, &res)) < 0) {
+ av_log(s, AV_LOG_ERROR, "pa_simple_read failed: %s\n",
+ pa_strerror(res));
+ av_free_packet(pkt);
+ return AVERROR(EIO);
+ }
+
+ if ((latency = pa_simple_get_latency(pd->s, &res)) == (pa_usec_t) -1) {
+ av_log(s, AV_LOG_ERROR, "pa_simple_get_latency() failed: %s\n",
+ pa_strerror(res));
+ return AVERROR(EIO);
+ }
+
+ if (pd->pts == AV_NOPTS_VALUE) {
+ pd->pts = -latency;
+ }
+
+ pkt->pts = pd->pts;
+
+ pd->pts += pd->frame_duration;
+
+ return 0;
+}
+
+static av_cold int pulse_close(AVFormatContext *s)
+{
+ PulseData *pd = s->priv_data;
+ pa_simple_free(pd->s);
+ return 0;
+}
+
+#define OFFSET(a) offsetof(PulseData, a)
+#define D AV_OPT_FLAG_DECODING_PARAM
+
+static const AVOption options[] = {
+ { "server", "pulse server name", OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D },
+ { "name", "application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = "libav"}, 0, 0, D },
+ { "stream_name", "stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D },
+ { "sample_rate", "sample rate in Hz", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, D },
+ { "channels", "number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, D },
+ { "frame_size", "number of bytes per frame", OFFSET(frame_size), AV_OPT_TYPE_INT, {.dbl = 1024}, 1, INT_MAX, D },
+ { "fragment_size", "buffering size, affects latency and cpu usage", OFFSET(fragment_size), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX, D },
+ { NULL },
+};
+
+static const AVClass pulse_demuxer_class = {
+ .class_name = "Pulse demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_pulse_demuxer = {
+ .name = "pulse",
+ .long_name = NULL_IF_CONFIG_SMALL("Pulse audio input"),
+ .priv_data_size = sizeof(PulseData),
+ .read_header = pulse_read_header,
+ .read_packet = pulse_read_packet,
+ .read_close = pulse_close,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &pulse_demuxer_class,
+};
diff --git a/libavdevice/sndio_dec.c b/libavdevice/sndio_dec.c
index 2690ee3..cc74c38 100644
--- a/libavdevice/sndio_dec.c
+++ b/libavdevice/sndio_dec.c
@@ -23,6 +23,7 @@
#include <sndio.h>
#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
#include "libavutil/opt.h"
#include "sndio_common.h"
@@ -34,14 +35,7 @@ static av_cold int audio_read_header(AVFormatContext *s1,
AVStream *st;
int ret;
-#if FF_API_FORMAT_PARAMETERS
- if (ap->sample_rate > 0)
- s->sample_rate = ap->sample_rate;
- if (ap->channels > 0)
- s->channels = ap->channels;
-#endif
-
- st = av_new_stream(s1, 0);
+ st = avformat_new_stream(s1, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -55,7 +49,7 @@ static av_cold int audio_read_header(AVFormatContext *s1,
st->codec->sample_rate = s->sample_rate;
st->codec->channels = s->channels;
- av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
return 0;
}
@@ -100,8 +94,8 @@ static av_cold int audio_read_close(AVFormatContext *s1)
}
static const AVOption options[] = {
- { "sample_rate", "", offsetof(SndioData, sample_rate), FF_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
- { "channels", "", offsetof(SndioData, channels), FF_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "sample_rate", "", offsetof(SndioData, sample_rate), AV_OPT_TYPE_INT, {.dbl = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "channels", "", offsetof(SndioData, channels), AV_OPT_TYPE_INT, {.dbl = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
};
diff --git a/libavdevice/timefilter.c b/libavdevice/timefilter.c
new file mode 100644
index 0000000..332d33b
--- /dev/null
+++ b/libavdevice/timefilter.c
@@ -0,0 +1,151 @@
+/*
+ * Delay Locked Loop based time filter
+ * Copyright (c) 2009 Samalyse
+ * Copyright (c) 2009 Michael Niedermayer
+ * Author: Olivier Guilyardi <olivier samalyse com>
+ * Michael Niedermayer <michaelni gmx at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include "config.h"
+#include "timefilter.h"
+#include "libavutil/mem.h"
+
+struct TimeFilter {
+ /// Delay Locked Loop data. These variables refer to mathematical
+ /// concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf
+ double cycle_time;
+ double feedback2_factor;
+ double feedback3_factor;
+ double clock_period;
+ int count;
+};
+
+TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor)
+{
+ TimeFilter *self = av_mallocz(sizeof(TimeFilter));
+ self->clock_period = clock_period;
+ self->feedback2_factor = feedback2_factor;
+ self->feedback3_factor = feedback3_factor;
+ return self;
+}
+
+void ff_timefilter_destroy(TimeFilter *self)
+{
+ av_freep(&self);
+}
+
+void ff_timefilter_reset(TimeFilter *self)
+{
+ self->count = 0;
+}
+
+double ff_timefilter_update(TimeFilter *self, double system_time, double period)
+{
+ self->count++;
+ if (self->count==1) {
+ /// init loop
+ self->cycle_time = system_time;
+ } else {
+ double loop_error;
+ self->cycle_time += self->clock_period * period;
+ /// calculate loop error
+ loop_error = system_time - self->cycle_time;
+
+ /// update loop
+ self->cycle_time += FFMAX(self->feedback2_factor, 1.0/(self->count)) * loop_error;
+ self->clock_period += self->feedback3_factor * loop_error / period;
+ }
+ return self->cycle_time;
+}
+
+#ifdef TEST
+#include "libavutil/lfg.h"
+#define LFG_MAX ((1LL << 32) - 1)
+
+#undef printf
+
+int main(void)
+{
+ AVLFG prng;
+ double n0,n1;
+#define SAMPLES 1000
+ double ideal[SAMPLES];
+ double samples[SAMPLES];
+#if 1
+ for(n0= 0; n0<40; n0=2*n0+1){
+ for(n1= 0; n1<10; n1=2*n1+1){
+#else
+ {{
+ n0=7;
+ n1=1;
+#endif
+ double best_error= 1000000000;
+ double bestpar0=1;
+ double bestpar1=0.001;
+ int better, i;
+
+ av_lfg_init(&prng, 123);
+ for(i=0; i<SAMPLES; i++){
+ ideal[i] = 10 + i + n1*i/(1000);
+ samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2)
+ / (LFG_MAX * 10LL);
+ }
+
+ do{
+ double par0, par1;
+ better=0;
+ for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){
+ for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){
+ double error=0;
+ TimeFilter *tf= ff_timefilter_new(1, par0, par1);
+ for(i=0; i<SAMPLES; i++){
+ double filtered;
+ filtered= ff_timefilter_update(tf, samples[i], 1);
+ error += (filtered - ideal[i]) * (filtered - ideal[i]);
+ }
+ ff_timefilter_destroy(tf);
+ if(error < best_error){
+ best_error= error;
+ bestpar0= par0;
+ bestpar1= par1;
+ better=1;
+ }
+ }
+ }
+ }while(better);
+#if 0
+ double lastfil=9;
+ TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1);
+ for(i=0; i<SAMPLES; i++){
+ double filtered;
+ filtered= ff_timefilter_update(tf, samples[i], 1);
+ printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil);
+ lastfil= filtered;
+ }
+ ff_timefilter_destroy(tf);
+#else
+ printf(" [%f %f %9f]", bestpar0, bestpar1, best_error);
+#endif
+ }
+ printf("\n");
+ }
+ return 0;
+}
+#endif
diff --git a/libavdevice/timefilter.h b/libavdevice/timefilter.h
new file mode 100644
index 0000000..8cadd8b
--- /dev/null
+++ b/libavdevice/timefilter.h
@@ -0,0 +1,97 @@
+/*
+ * Delay Locked Loop based time filter prototypes and declarations
+ * Copyright (c) 2009 Samalyse
+ * Copyright (c) 2009 Michael Niedermayer
+ * Author: Olivier Guilyardi <olivier samalyse com>
+ * Michael Niedermayer <michaelni gmx at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVDEVICE_TIMEFILTER_H
+#define AVDEVICE_TIMEFILTER_H
+
+/**
+ * Opaque type representing a time filter state
+ *
+ * The purpose of this filter is to provide a way to compute accurate time
+ * stamps that can be compared to wall clock time, especially when dealing
+ * with two clocks: the system clock and a hardware device clock, such as
+ * a soundcard.
+ */
+typedef struct TimeFilter TimeFilter;
+
+
+/**
+ * Create a new Delay Locked Loop time filter
+ *
+ * feedback2_factor and feedback3_factor are the factors used for the
+ * multiplications that are respectively performed in the second and third
+ * feedback paths of the loop.
+ *
+ * Unless you know what you are doing, you should set these as follow:
+ *
+ * o = 2 * M_PI * bandwidth * period
+ * feedback2_factor = sqrt(2 * o)
+ * feedback3_factor = o * o
+ *
+ * Where bandwidth is up to you to choose. Smaller values will filter out more
+ * of the jitter, but also take a longer time for the loop to settle. A good
+ * starting point is something between 0.3 and 3 Hz.
+ *
+ * @param clock_period period of the hardware clock in seconds
+ * (for example 1.0/44100)
+ *
+ * For more details about these parameters and background concepts please see:
+ * http://www.kokkinizita.net/papers/usingdll.pdf
+ */
+TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor);
+
+/**
+ * Update the filter
+ *
+ * This function must be called in real time, at each process cycle.
+ *
+ * @param period the device cycle duration in clock_periods. For example, at
+ * 44.1kHz and a buffer size of 512 frames, period = 512 when clock_period
+ * was 1.0/44100, or 512/44100 if clock_period was 1.
+ *
+ * system_time, in seconds, should be the value of the system clock time,
+ * at (or as close as possible to) the moment the device hardware interrupt
+ * occurred (or any other event the device clock raises at the beginning of a
+ * cycle).
+ *
+ * @return the filtered time, in seconds
+ */
+double ff_timefilter_update(TimeFilter *self, double system_time, double period);
+
+/**
+ * Reset the filter
+ *
+ * This function should mainly be called in case of XRUN.
+ *
+ * Warning: after calling this, the filter is in an undetermined state until
+ * the next call to ff_timefilter_update()
+ */
+void ff_timefilter_reset(TimeFilter *);
+
+/**
+ * Free all resources associated with the filter
+ */
+void ff_timefilter_destroy(TimeFilter *);
+
+#endif /* AVDEVICE_TIMEFILTER_H */
diff --git a/libavdevice/v4l.c b/libavdevice/v4l.c
index 1be7adf..bdfee2d 100644
--- a/libavdevice/v4l.c
+++ b/libavdevice/v4l.c
@@ -30,6 +30,7 @@
#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
#include "libavcodec/dsputil.h"
#include <unistd.h>
#include <fcntl.h>
@@ -39,7 +40,6 @@
#define _LINUX_TIME_H 1
#include <linux/videodev.h>
#include <time.h>
-#include <strings.h>
typedef struct {
AVClass *class;
@@ -98,10 +98,10 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
s->video_win.width = ap->width;
s->video_win.height = ap->height;
- st = av_new_stream(s1, 0);
+ st = avformat_new_stream(s1, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
video_fd = open(s1->filename, O_RDWR);
if (video_fd < 0) {
@@ -142,16 +142,6 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
/* set tv standard */
if (!ioctl(video_fd, VIDIOCGTUNER, &tuner)) {
-#if FF_API_FORMAT_PARAMETERS
- if (ap->standard) {
- if (!strcasecmp(ap->standard, "pal"))
- s->standard = VIDEO_MODE_PAL;
- else if (!strcasecmp(ap->standard, "secam"))
- s->standard = VIDEO_MODE_SECAM;
- else
- s->standard = VIDEO_MODE_NTSC;
- }
-#endif
tuner.mode = s->standard;
ioctl(video_fd, VIDIOCSTUNER, &tuner);
}
@@ -349,10 +339,10 @@ static int grab_read_close(AVFormatContext *s1)
}
static const AVOption options[] = {
- { "standard", "", offsetof(VideoData, standard), FF_OPT_TYPE_INT, {.dbl = VIDEO_MODE_NTSC}, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "PAL", "", 0, FF_OPT_TYPE_CONST, {.dbl = VIDEO_MODE_PAL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "SECAM", "", 0, FF_OPT_TYPE_CONST, {.dbl = VIDEO_MODE_SECAM}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
- { "NTSC", "", 0, FF_OPT_TYPE_CONST, {.dbl = VIDEO_MODE_NTSC}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "standard", "", offsetof(VideoData, standard), AV_OPT_TYPE_INT, {.dbl = VIDEO_MODE_NTSC}, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "PAL", "", 0, AV_OPT_TYPE_CONST, {.dbl = VIDEO_MODE_PAL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "SECAM", "", 0, AV_OPT_TYPE_CONST, {.dbl = VIDEO_MODE_SECAM}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+ { "NTSC", "", 0, AV_OPT_TYPE_CONST, {.dbl = VIDEO_MODE_NTSC}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
{ NULL },
};
@@ -364,14 +354,13 @@ static const AVClass v4l_class = {
};
AVInputFormat ff_v4l_demuxer = {
- "video4linux",
- NULL_IF_CONFIG_SMALL("Video4Linux device grab"),
- sizeof(VideoData),
- NULL,
- grab_read_header,
- grab_read_packet,
- grab_read_close,
- .flags = AVFMT_NOFILE,
- .priv_class = &v4l_class,
+ .name = "video4linux",
+ .long_name = NULL_IF_CONFIG_SMALL("Video4Linux device grab"),
+ .priv_data_size = sizeof(VideoData),
+ .read_header = grab_read_header,
+ .read_packet = grab_read_packet,
+ .read_close = grab_read_close,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &v4l_class,
};
#endif /* FF_API_V4L */
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 2553bca..eb16171 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -30,6 +30,7 @@
#undef __STRICT_ANSI__ //workaround due to broken kernel headers
#include "config.h"
#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
@@ -38,16 +39,15 @@
#if HAVE_SYS_VIDEOIO_H
#include <sys/videoio.h>
#else
-#include <asm/types.h>
#include <linux/videodev2.h>
#endif
#include <time.h>
-#include <strings.h>
#include "libavutil/imgutils.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
+#include "libavutil/avstring.h"
static const int desired_video_buffers = 256;
@@ -455,20 +455,14 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
struct v4l2_streamparm streamparm = { 0 };
struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
int i, ret;
- AVRational fps;
+ AVRational framerate_q;
streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (s->framerate && (ret = av_parse_video_rate(&fps, s->framerate)) < 0) {
- av_log(s1, AV_LOG_ERROR, "Couldn't parse framerate.\n");
+ if (s->framerate && (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
+ av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", s->framerate);
return ret;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->channel > 0)
- s->channel = ap->channel;
- if (ap->time_base.num)
- fps = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
/* set tv video input */
memset (&input, 0, sizeof (input));
@@ -486,13 +480,6 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
return AVERROR(EIO);
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->standard) {
- av_freep(&s->standard);
- s->standard = av_strdup(ap->standard);
- }
-#endif
-
if (s->standard) {
av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
s->standard);
@@ -506,7 +493,7 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
return AVERROR(EIO);
}
- if (!strcasecmp(standard.name, s->standard)) {
+ if (!av_strcasecmp(standard.name, s->standard)) {
break;
}
}
@@ -520,23 +507,23 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
}
}
- if (fps.num && fps.den) {
+ if (framerate_q.num && framerate_q.den) {
av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
- fps.den, fps.num);
- tpf->numerator = fps.den;
- tpf->denominator = fps.num;
+ framerate_q.den, framerate_q.num);
+ tpf->numerator = framerate_q.den;
+ tpf->denominator = framerate_q.num;
if (ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
av_log(s1, AV_LOG_ERROR,
"ioctl set time per frame(%d/%d) failed\n",
- fps.den, fps.num);
+ framerate_q.den, framerate_q.num);
return AVERROR(EIO);
}
- if (fps.num != tpf->denominator ||
- fps.den != tpf->numerator) {
+ if (framerate_q.num != tpf->denominator ||
+ framerate_q.den != tpf->numerator) {
av_log(s1, AV_LOG_INFO,
"The driver changed the time per frame from %d/%d to %d/%d\n",
- fps.den, fps.num,
+ framerate_q.den, framerate_q.num,
tpf->numerator, tpf->denominator);
}
} else {
@@ -593,15 +580,15 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
enum CodecID codec_id;
enum PixelFormat pix_fmt = PIX_FMT_NONE;
- st = av_new_stream(s1, 0);
+ st = avformat_new_stream(s1, NULL);
if (!st) {
res = AVERROR(ENOMEM);
goto out;
}
- av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
if (s->video_size && (res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) {
- av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n");
+ av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n", s->video_size);
goto out;
}
if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) {
@@ -609,14 +596,6 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
res = AVERROR(EINVAL);
goto out;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->width > 0)
- s->width = ap->width;
- if (ap->height > 0)
- s->height = ap->height;
- if (ap->pix_fmt)
- pix_fmt = ap->pix_fmt;
-#endif
capabilities = 0;
s->fd = device_open(s1, &capabilities);
@@ -730,11 +709,11 @@ static int v4l2_read_close(AVFormatContext *s1)
#define OFFSET(x) offsetof(struct video_data, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "standard", "", offsetof(struct video_data, standard), FF_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
- { "channel", "", offsetof(struct video_data, channel), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
- { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "pixel_format", "", OFFSET(pixel_format), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "standard", "", offsetof(struct video_data, standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
+ { "channel", "", offsetof(struct video_data, channel), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
{ NULL },
};
@@ -746,13 +725,12 @@ static const AVClass v4l2_class = {
};
AVInputFormat ff_v4l2_demuxer = {
- "video4linux2",
- NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
- sizeof(struct video_data),
- NULL,
- v4l2_read_header,
- v4l2_read_packet,
- v4l2_read_close,
- .flags = AVFMT_NOFILE,
- .priv_class = &v4l2_class,
+ .name = "video4linux2",
+ .long_name = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
+ .priv_data_size = sizeof(struct video_data),
+ .read_header = v4l2_read_header,
+ .read_packet = v4l2_read_packet,
+ .read_close = v4l2_read_close,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &v4l2_class,
};
diff --git a/libavdevice/vfwcap.c b/libavdevice/vfwcap.c
index 95dd4c3..b5baee3 100644
--- a/libavdevice/vfwcap.c
+++ b/libavdevice/vfwcap.c
@@ -20,6 +20,7 @@
*/
#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
@@ -249,7 +250,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap)
DWORD biCompression;
WORD biBitCount;
int ret;
- AVRational fps;
+ AVRational framerate_q;
if (!strcmp(s->filename, "list")) {
for (devnum = 0; devnum <= 9; devnum++) {
@@ -267,11 +268,6 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap)
return AVERROR(EIO);
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->time_base.num)
- fps = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
-
ctx->hwnd = capCreateCaptureWindow(NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0);
if(!ctx->hwnd) {
av_log(s, AV_LOG_ERROR, "Could not create capture window.\n");
@@ -300,7 +296,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap)
SetWindowLongPtr(ctx->hwnd, GWLP_USERDATA, (LONG_PTR) s);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if(!st) {
vfw_read_close(s);
return AVERROR(ENOMEM);
@@ -329,12 +325,6 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap)
goto fail_bi;
}
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->width > 0)
- bi->bmiHeader.biWidth = ap->width;
- if (ap->height > 0)
- bi->bmiHeader.biHeight = ap->height;
-#endif
if (0) {
/* For testing yet unsupported compressions
@@ -369,7 +359,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap)
cparms.fYield = 1; // Spawn a background thread
cparms.dwRequestMicroSecPerFrame =
- (fps.den*1000000) / fps.num;
+ (framerate_q.den*1000000) / framerate_q.num;
cparms.fAbortLeftMouse = 0;
cparms.fAbortRightMouse = 0;
cparms.fCaptureAudio = 0;
@@ -381,7 +371,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap)
goto fail_io;
codec = st->codec;
- codec->time_base = (AVRational){fps.den, fps.num};
+ codec->time_base = (AVRational){framerate_q.den, framerate_q.num};
codec->codec_type = AVMEDIA_TYPE_VIDEO;
codec->width = bi->bmiHeader.biWidth;
codec->height = bi->bmiHeader.biHeight;
@@ -407,7 +397,7 @@ static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
}
- av_set_pts_info(st, 32, 1, 1000);
+ avpriv_set_pts_info(st, 32, 1, 1000);
ctx->mutex = CreateMutex(NULL, 0, NULL);
if(!ctx->mutex) {
@@ -468,8 +458,8 @@ static int vfw_read_packet(AVFormatContext *s, AVPacket *pkt)
#define OFFSET(x) offsetof(struct vfw_ctx, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC },
+ { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC },
{ NULL },
};
@@ -481,13 +471,12 @@ static const AVClass vfw_class = {
};
AVInputFormat ff_vfwcap_demuxer = {
- "vfwcap",
- NULL_IF_CONFIG_SMALL("VFW video capture"),
- sizeof(struct vfw_ctx),
- NULL,
- vfw_read_header,
- vfw_read_packet,
- vfw_read_close,
- .flags = AVFMT_NOFILE,
- .priv_class = &vfw_class,
+ .name = "vfwcap",
+ .long_name = NULL_IF_CONFIG_SMALL("VfW video capture"),
+ .priv_data_size = sizeof(struct vfw_ctx),
+ .read_header = vfw_read_header,
+ .read_packet = vfw_read_packet,
+ .read_close = vfw_read_close,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &vfw_class,
};
diff --git a/libavdevice/x11grab.c b/libavdevice/x11grab.c
index 6e77a5c..9d12b2f 100644
--- a/libavdevice/x11grab.c
+++ b/libavdevice/x11grab.c
@@ -31,12 +31,14 @@
/**
* @file
- * X11 frame device demuxer by Clemens Fruhwirth <clemens at endorphin.org>
- * and Edouard Gomez <ed.gomez at free.fr>.
+ * X11 frame device demuxer
+ * @author Clemens Fruhwirth <clemens at endorphin.org>
+ * @author Edouard Gomez <ed.gomez at free.fr>
*/
#include "config.h"
#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
@@ -47,6 +49,7 @@
#include <X11/Xproto.h>
#include <X11/Xutil.h>
#include <sys/shm.h>
+#include <X11/extensions/shape.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/Xfixes.h>
@@ -70,10 +73,75 @@ struct x11_grab
XImage *image; /**< X11 image holding the grab */
int use_shm; /**< !0 when using XShm extension */
XShmSegmentInfo shminfo; /**< When using XShm, keeps track of XShm infos */
- int nomouse;
+ int draw_mouse; /**< Set by a private option. */
+ int follow_mouse; /**< Set by a private option. */
+ int show_region; /**< set by a private option. */
char *framerate; /**< Set by a private option. */
+
+ Window region_win; /**< This is used by show_region option. */
};
+#define REGION_WIN_BORDER 3
+/**
+ * Draw grabbing region window
+ *
+ * @param s x11_grab context
+ */
+static void
+x11grab_draw_region_win(struct x11_grab *s)
+{
+ Display *dpy = s->dpy;
+ int screen;
+ Window win = s->region_win;
+ GC gc;
+
+ screen = DefaultScreen(dpy);
+ gc = XCreateGC(dpy, win, 0, 0);
+ XSetForeground(dpy, gc, WhitePixel(dpy, screen));
+ XSetBackground(dpy, gc, BlackPixel(dpy, screen));
+ XSetLineAttributes(dpy, gc, REGION_WIN_BORDER, LineDoubleDash, 0, 0);
+ XDrawRectangle(dpy, win, gc,
+ 1, 1,
+ (s->width + REGION_WIN_BORDER * 2) - 1 * 2 - 1,
+ (s->height + REGION_WIN_BORDER * 2) - 1 * 2 - 1);
+ XFreeGC(dpy, gc);
+}
+
+/**
+ * Initialize grabbing region window
+ *
+ * @param s x11_grab context
+ */
+static void
+x11grab_region_win_init(struct x11_grab *s)
+{
+ Display *dpy = s->dpy;
+ int screen;
+ XSetWindowAttributes attribs;
+ XRectangle rect;
+
+ screen = DefaultScreen(dpy);
+ attribs.override_redirect = True;
+ s->region_win = XCreateWindow(dpy, RootWindow(dpy, screen),
+ s->x_off - REGION_WIN_BORDER,
+ s->y_off - REGION_WIN_BORDER,
+ s->width + REGION_WIN_BORDER * 2,
+ s->height + REGION_WIN_BORDER * 2,
+ 0, CopyFromParent,
+ InputOutput, CopyFromParent,
+ CWOverrideRedirect, &attribs);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = s->width;
+ rect.height = s->height;
+ XShapeCombineRectangles(dpy, s->region_win,
+ ShapeBounding, REGION_WIN_BORDER, REGION_WIN_BORDER,
+ &rect, 1, ShapeSubtract, 0);
+ XMapWindow(dpy, s->region_win);
+ XSelectInput(dpy, s->region_win, ExposureMask | StructureNotifyMask);
+ x11grab_draw_region_win(s);
+}
+
/**
* Initialize the x11 grab device demuxer (public device demuxer API).
*
@@ -95,6 +163,7 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
XImage *image;
int x_off = 0;
int y_off = 0;
+ int screen;
int use_shm;
char *param, *offset;
int ret = 0;
@@ -104,7 +173,7 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
offset = strchr(param, '+');
if (offset) {
sscanf(offset, "%d,%d", &x_off, &y_off);
- x11grab->nomouse= strstr(offset, "nomouse");
+ x11grab->draw_mouse = !strstr(offset, "nomouse");
*offset= 0;
}
@@ -116,14 +185,6 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
av_log(s1, AV_LOG_ERROR, "Could not parse framerate: %s.\n", x11grab->framerate);
goto out;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->width > 0)
- x11grab->width = ap->width;
- if (ap->height > 0)
- x11grab->height = ap->height;
- if (ap->time_base.num)
- framerate = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n",
s1->filename, param, x_off, y_off, x11grab->width, x11grab->height);
@@ -134,12 +195,28 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
goto out;
}
- st = av_new_stream(s1, 0);
+ st = avformat_new_stream(s1, NULL);
if (!st) {
ret = AVERROR(ENOMEM);
goto out;
}
- av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+
+ screen = DefaultScreen(dpy);
+
+ if (x11grab->follow_mouse) {
+ int screen_w, screen_h;
+ Window w;
+
+ screen_w = DisplayWidth(dpy, screen);
+ screen_h = DisplayHeight(dpy, screen);
+ XQueryPointer(dpy, RootWindow(dpy, screen), &w, &w, &x_off, &y_off, &ret, &ret, &ret);
+ x_off -= x11grab->width / 2;
+ y_off -= x11grab->height / 2;
+ x_off = FFMIN(FFMAX(x_off, 0), screen_w - x11grab->width);
+ y_off = FFMIN(FFMAX(y_off, 0), screen_h - x11grab->height);
+ av_log(s1, AV_LOG_INFO, "followmouse is enabled, resetting grabbing region to x: %d y: %d\n", x_off, y_off);
+ }
use_shm = XShmQueryExtension(dpy);
av_log(s1, AV_LOG_INFO, "shared memory extension %s found\n", use_shm ? "" : "not");
@@ -171,7 +248,7 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
goto out;
}
} else {
- image = XGetImage(dpy, RootWindow(dpy, DefaultScreen(dpy)),
+ image = XGetImage(dpy, RootWindow(dpy, screen),
x_off,y_off,
x11grab->width, x11grab->height,
AllPlanes, ZPixmap);
@@ -217,21 +294,6 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
}
break;
case 32:
-#if 0
- GetColorInfo (image, &c_info);
- if ( c_info.alpha_mask == 0xff000000 && image->green_mask == 0x0000ff00) {
- /* byte order is relevant here, not endianness
- * endianness is handled by avcodec, but atm no such thing
- * as having ABGR, instead of ARGB in a word. Since we
- * need this for Solaris/SPARC, but need to do the conversion
- * for every frame we do it outside of this loop, cf. below
- * this matches both ARGB32 and ABGR32 */
- input_pixfmt = PIX_FMT_ARGB32;
- } else {
- av_log(s1, AV_LOG_ERROR,"image depth %i not supported ... aborting\n", image->bits_per_pixel);
- return AVERROR(EIO);
- }
-#endif
input_pixfmt = PIX_FMT_RGB32;
break;
default:
@@ -389,6 +451,10 @@ x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt)
int x_off = s->x_off;
int y_off = s->y_off;
+ int screen;
+ Window root;
+ int follow_mouse = s->follow_mouse;
+
int64_t curtime, delay;
struct timespec ts;
@@ -415,17 +481,65 @@ x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt)
pkt->size = s->frame_size;
pkt->pts = curtime;
+ screen = DefaultScreen(dpy);
+ root = RootWindow(dpy, screen);
+ if (follow_mouse) {
+ int screen_w, screen_h;
+ int pointer_x, pointer_y, _;
+ Window w;
+
+ screen_w = DisplayWidth(dpy, screen);
+ screen_h = DisplayHeight(dpy, screen);
+ XQueryPointer(dpy, root, &w, &w, &pointer_x, &pointer_y, &_, &_, &_);
+ if (follow_mouse == -1) {
+ // follow the mouse, put it at center of grabbing region
+ x_off += pointer_x - s->width / 2 - x_off;
+ y_off += pointer_y - s->height / 2 - y_off;
+ } else {
+ // follow the mouse, but only move the grabbing region when mouse
+ // reaches within certain pixels to the edge.
+ if (pointer_x > x_off + s->width - follow_mouse) {
+ x_off += pointer_x - (x_off + s->width - follow_mouse);
+ } else if (pointer_x < x_off + follow_mouse)
+ x_off -= (x_off + follow_mouse) - pointer_x;
+ if (pointer_y > y_off + s->height - follow_mouse) {
+ y_off += pointer_y - (y_off + s->height - follow_mouse);
+ } else if (pointer_y < y_off + follow_mouse)
+ y_off -= (y_off + follow_mouse) - pointer_y;
+ }
+ // adjust grabbing region position if it goes out of screen.
+ s->x_off = x_off = FFMIN(FFMAX(x_off, 0), screen_w - s->width);
+ s->y_off = y_off = FFMIN(FFMAX(y_off, 0), screen_h - s->height);
+
+ if (s->show_region && s->region_win)
+ XMoveWindow(dpy, s->region_win,
+ s->x_off - REGION_WIN_BORDER,
+ s->y_off - REGION_WIN_BORDER);
+ }
+
+ if (s->show_region) {
+ if (s->region_win) {
+ XEvent evt;
+ // clean up the events, and do the initinal draw or redraw.
+ for (evt.type = NoEventMask; XCheckMaskEvent(dpy, ExposureMask | StructureNotifyMask, &evt); );
+ if (evt.type)
+ x11grab_draw_region_win(s);
+ } else {
+ x11grab_region_win_init(s);
+ }
+ }
+
if(s->use_shm) {
- if (!XShmGetImage(dpy, RootWindow(dpy, DefaultScreen(dpy)), image, x_off, y_off, AllPlanes)) {
+ if (!XShmGetImage(dpy, root, image, x_off, y_off, AllPlanes)) {
av_log (s1, AV_LOG_INFO, "XShmGetImage() failed\n");
}
} else {
- if (!xget_zpixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)), image, x_off, y_off)) {
+ if (!xget_zpixmap(dpy, root, image, x_off, y_off)) {
av_log (s1, AV_LOG_INFO, "XGetZPixmap() failed\n");
}
}
- if(!s->nomouse){
+ if (s->draw_mouse) {
paint_mouse_pointer(image, s);
}
@@ -456,6 +570,10 @@ x11grab_read_close(AVFormatContext *s1)
x11grab->image = NULL;
}
+ if (x11grab->region_win) {
+ XDestroyWindow(x11grab->dpy, x11grab->region_win);
+ }
+
/* Free X11 display */
XCloseDisplay(x11grab->dpy);
return 0;
@@ -464,8 +582,13 @@ x11grab_read_close(AVFormatContext *s1)
#define OFFSET(x) offsetof(struct x11_grab, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = "vga"}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC },
+ { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "vga"}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC },
+ { "draw_mouse", "Draw the mouse pointer.", OFFSET(draw_mouse), AV_OPT_TYPE_INT, { 1 }, 0, 1, DEC },
+ { "follow_mouse", "Move the grabbing region when the mouse pointer reaches within specified amount of pixels to the edge of region.",
+ OFFSET(follow_mouse), AV_OPT_TYPE_INT, { 0 }, -1, INT_MAX, DEC, "follow_mouse" },
+ { "centered", "Keep the mouse pointer at the center of grabbing region when following.", 0, AV_OPT_TYPE_CONST, { -1 }, INT_MIN, INT_MAX, DEC, "follow_mouse" },
+ { "show_region", "Show the grabbing region.", OFFSET(show_region), AV_OPT_TYPE_INT, { 0 }, 0, 1, DEC },
{ NULL },
};
@@ -477,15 +600,13 @@ static const AVClass x11_class = {
};
/** x11 grabber device demuxer declaration */
-AVInputFormat ff_x11_grab_device_demuxer =
-{
- "x11grab",
- NULL_IF_CONFIG_SMALL("X11grab"),
- sizeof(struct x11_grab),
- NULL,
- x11grab_read_header,
- x11grab_read_packet,
- x11grab_read_close,
- .flags = AVFMT_NOFILE,
- .priv_class = &x11_class,
+AVInputFormat ff_x11_grab_device_demuxer = {
+ .name = "x11grab",
+ .long_name = NULL_IF_CONFIG_SMALL("X11grab"),
+ .priv_data_size = sizeof(struct x11_grab),
+ .read_header = x11grab_read_header,
+ .read_packet = x11grab_read_packet,
+ .read_close = x11grab_read_close,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &x11_class,
};
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 2ed1f93..78c4692 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -1,11 +1,9 @@
-include $(SUBDIR)../config.mak
-
NAME = avfilter
FFLIBS = avutil
FFLIBS-$(CONFIG_MOVIE_FILTER) += avformat avcodec
FFLIBS-$(CONFIG_SCALE_FILTER) += swscale
-HEADERS = avfilter.h avfiltergraph.h
+HEADERS = avfilter.h avfiltergraph.h buffersrc.h vsrc_buffer.h
OBJS = allfilters.o \
avfilter.o \
@@ -14,6 +12,7 @@ OBJS = allfilters.o \
drawutils.o \
formats.o \
graphparser.o \
+ vsrc_buffer.o
OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o
@@ -22,9 +21,11 @@ OBJS-$(CONFIG_ANULLSRC_FILTER) += asrc_anullsrc.o
OBJS-$(CONFIG_ANULLSINK_FILTER) += asink_anullsink.o
OBJS-$(CONFIG_BLACKFRAME_FILTER) += vf_blackframe.o
+OBJS-$(CONFIG_BOXBLUR_FILTER) += vf_boxblur.o
OBJS-$(CONFIG_COPY_FILTER) += vf_copy.o
OBJS-$(CONFIG_CROP_FILTER) += vf_crop.o
OBJS-$(CONFIG_CROPDETECT_FILTER) += vf_cropdetect.o
+OBJS-$(CONFIG_DELOGO_FILTER) += vf_delogo.o
OBJS-$(CONFIG_DRAWBOX_FILTER) += vf_drawbox.o
OBJS-$(CONFIG_DRAWTEXT_FILTER) += vf_drawtext.o
OBJS-$(CONFIG_FADE_FILTER) += vf_fade.o
@@ -35,6 +36,10 @@ OBJS-$(CONFIG_FREI0R_FILTER) += vf_frei0r.o
OBJS-$(CONFIG_GRADFUN_FILTER) += vf_gradfun.o
OBJS-$(CONFIG_HFLIP_FILTER) += vf_hflip.o
OBJS-$(CONFIG_HQDN3D_FILTER) += vf_hqdn3d.o
+OBJS-$(CONFIG_LUT_FILTER) += vf_lut.o
+OBJS-$(CONFIG_LUTRGB_FILTER) += vf_lut.o
+OBJS-$(CONFIG_LUTYUV_FILTER) += vf_lut.o
+OBJS-$(CONFIG_NEGATE_FILTER) += vf_lut.o
OBJS-$(CONFIG_NOFORMAT_FILTER) += vf_format.o
OBJS-$(CONFIG_NULL_FILTER) += vf_null.o
OBJS-$(CONFIG_OCV_FILTER) += vf_libopencv.o
@@ -42,26 +47,30 @@ OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o
OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o
OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o
OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o
+OBJS-$(CONFIG_SELECT_FILTER) += vf_select.o
OBJS-$(CONFIG_SETDAR_FILTER) += vf_aspect.o
OBJS-$(CONFIG_SETPTS_FILTER) += vf_setpts.o
OBJS-$(CONFIG_SETSAR_FILTER) += vf_aspect.o
OBJS-$(CONFIG_SETTB_FILTER) += vf_settb.o
+OBJS-$(CONFIG_SHOWINFO_FILTER) += vf_showinfo.o
OBJS-$(CONFIG_SLICIFY_FILTER) += vf_slicify.o
+OBJS-$(CONFIG_SPLIT_FILTER) += vf_split.o
OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o
OBJS-$(CONFIG_UNSHARP_FILTER) += vf_unsharp.o
OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o
OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o
-OBJS-$(CONFIG_BUFFER_FILTER) += vsrc_buffer.o
OBJS-$(CONFIG_COLOR_FILTER) += vsrc_color.o
OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o
OBJS-$(CONFIG_MOVIE_FILTER) += vsrc_movie.o
OBJS-$(CONFIG_NULLSRC_FILTER) += vsrc_nullsrc.o
+OBJS-$(CONFIG_RGBTESTSRC_FILTER) += vsrc_testsrc.o
+OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o
OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o
--include $(SUBDIR)$(ARCH)/Makefile
+-include $(SRC_PATH)/$(SUBDIR)$(ARCH)/Makefile
DIRS = x86
-include $(SUBDIR)../subdir.mak
+TOOLS = graph2dot lavfi-showfiltfmts
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index e29b4f9..ba66941 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -41,9 +41,11 @@ void avfilter_register_all(void)
REGISTER_FILTER (ANULLSINK, anullsink, asink);
REGISTER_FILTER (BLACKFRAME, blackframe, vf);
+ REGISTER_FILTER (BOXBLUR, boxblur, vf);
REGISTER_FILTER (COPY, copy, vf);
REGISTER_FILTER (CROP, crop, vf);
REGISTER_FILTER (CROPDETECT, cropdetect, vf);
+ REGISTER_FILTER (DELOGO, delogo, vf);
REGISTER_FILTER (DRAWBOX, drawbox, vf);
REGISTER_FILTER (DRAWTEXT, drawtext, vf);
REGISTER_FILTER (FADE, fade, vf);
@@ -54,6 +56,10 @@ void avfilter_register_all(void)
REGISTER_FILTER (GRADFUN, gradfun, vf);
REGISTER_FILTER (HFLIP, hflip, vf);
REGISTER_FILTER (HQDN3D, hqdn3d, vf);
+ REGISTER_FILTER (LUT, lut, vf);
+ REGISTER_FILTER (LUTRGB, lutrgb, vf);
+ REGISTER_FILTER (LUTYUV, lutyuv, vf);
+ REGISTER_FILTER (NEGATE, negate, vf);
REGISTER_FILTER (NOFORMAT, noformat, vf);
REGISTER_FILTER (NULL, null, vf);
REGISTER_FILTER (OCV, ocv, vf);
@@ -61,21 +67,31 @@ void avfilter_register_all(void)
REGISTER_FILTER (PAD, pad, vf);
REGISTER_FILTER (PIXDESCTEST, pixdesctest, vf);
REGISTER_FILTER (SCALE, scale, vf);
+ REGISTER_FILTER (SELECT, select, vf);
REGISTER_FILTER (SETDAR, setdar, vf);
REGISTER_FILTER (SETPTS, setpts, vf);
REGISTER_FILTER (SETSAR, setsar, vf);
REGISTER_FILTER (SETTB, settb, vf);
+ REGISTER_FILTER (SHOWINFO, showinfo, vf);
REGISTER_FILTER (SLICIFY, slicify, vf);
+ REGISTER_FILTER (SPLIT, split, vf);
REGISTER_FILTER (TRANSPOSE, transpose, vf);
REGISTER_FILTER (UNSHARP, unsharp, vf);
REGISTER_FILTER (VFLIP, vflip, vf);
REGISTER_FILTER (YADIF, yadif, vf);
- REGISTER_FILTER (BUFFER, buffer, vsrc);
REGISTER_FILTER (COLOR, color, vsrc);
REGISTER_FILTER (FREI0R, frei0r_src, vsrc);
REGISTER_FILTER (MOVIE, movie, vsrc);
REGISTER_FILTER (NULLSRC, nullsrc, vsrc);
+ REGISTER_FILTER (RGBTESTSRC, rgbtestsrc, vsrc);
+ REGISTER_FILTER (TESTSRC, testsrc, vsrc);
REGISTER_FILTER (NULLSINK, nullsink, vsink);
+
+ /* vsrc_buffer is a part of public API => registered unconditionally */
+ {
+ extern AVFilter avfilter_vsrc_buffer;
+ avfilter_register(&avfilter_vsrc_buffer);
+ }
}
diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c
index dd671c5..8e99012 100644
--- a/libavfilter/asrc_anullsrc.c
+++ b/libavfilter/asrc_anullsrc.c
@@ -25,7 +25,7 @@
#include "libavutil/audioconvert.h"
typedef struct {
- int64_t channel_layout;
+ uint64_t channel_layout;
int64_t sample_rate;
} ANullContext;
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index abeae14..d426591 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -25,6 +25,7 @@
#include "libavutil/rational.h"
#include "libavutil/audioconvert.h"
#include "libavutil/imgutils.h"
+#include "libavcodec/avcodec.h"
#include "avfilter.h"
#include "internal.h"
@@ -332,8 +333,8 @@ avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int
picref->type = AVMEDIA_TYPE_VIDEO;
pic->format = picref->format = format;
- memcpy(pic->data, data, sizeof(pic->data));
- memcpy(pic->linesize, linesize, sizeof(pic->linesize));
+ memcpy(pic->data, data, 4*sizeof(data[0]));
+ memcpy(pic->linesize, linesize, 4*sizeof(linesize[0]));
memcpy(picref->data, pic->data, sizeof(picref->data));
memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
@@ -349,7 +350,7 @@ fail:
AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,
enum AVSampleFormat sample_fmt, int size,
- int64_t channel_layout, int planar)
+ uint64_t channel_layout, int planar)
{
AVFilterBufferRef *ret = NULL;
@@ -681,3 +682,21 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
return ret;
}
+int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
+{
+ if (dst->type != AVMEDIA_TYPE_VIDEO)
+ return AVERROR(EINVAL);
+
+ dst->pts = src->pts;
+ dst->format = src->format;
+
+ dst->video->w = src->width;
+ dst->video->h = src->height;
+ dst->video->pixel_aspect = src->sample_aspect_ratio;
+ dst->video->interlaced = src->interlaced_frame;
+ dst->video->top_field_first = src->top_field_first;
+ dst->video->key_frame = src->key_frame;
+ dst->video->pict_type = src->pict_type;
+
+ return 0;
+}
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 33e93e2..70efc5c 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -23,10 +23,14 @@
#define AVFILTER_AVFILTER_H
#include "libavutil/avutil.h"
+#include "libavutil/log.h"
#include "libavutil/samplefmt.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/rational.h"
+#include "libavcodec/avcodec.h"
#define LIBAVFILTER_VERSION_MAJOR 2
-#define LIBAVFILTER_VERSION_MINOR 4
+#define LIBAVFILTER_VERSION_MINOR 14
#define LIBAVFILTER_VERSION_MICRO 0
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
@@ -97,7 +101,7 @@ typedef struct AVFilterBuffer {
* per reference properties must be separated out.
*/
typedef struct AVFilterBufferRefAudioProps {
- int64_t channel_layout; ///< channel layout of audio buffer
+ uint64_t channel_layout; ///< channel layout of audio buffer
int nb_samples; ///< number of audio samples
int size; ///< audio buffer size
uint32_t sample_rate; ///< audio buffer sample rate
@@ -373,7 +377,7 @@ struct AVFilterPad {
*/
AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms,
enum AVSampleFormat sample_fmt, int size,
- int64_t channel_layout, int planar);
+ uint64_t channel_layout, int planar);
/**
* Callback called after the slices of a frame are completely sent. If
@@ -462,7 +466,7 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link,
/** default handler for get_audio_buffer() for audio inputs */
AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,
enum AVSampleFormat sample_fmt, int size,
- int64_t channel_layout, int planar);
+ uint64_t channel_layout, int planar);
/**
* A helper for query_formats() which sets all links to the same list of
@@ -493,7 +497,7 @@ AVFilterBufferRef *avfilter_null_get_video_buffer(AVFilterLink *link,
/** get_audio_buffer() handler for filters which simply pass audio along */
AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
enum AVSampleFormat sample_fmt, int size,
- int64_t channel_layout, int planar);
+ uint64_t channel_layout, int planar);
/**
* Filter definition. This defines the pads a filter contains, and all the
@@ -586,7 +590,7 @@ struct AVFilterLink {
int h; ///< agreed upon image height
AVRational sample_aspect_ratio; ///< agreed upon sample aspect ratio
/* These two parameters apply only to audio */
- int64_t channel_layout; ///< channel layout of current buffer (see libavutil/audioconvert.h)
+ uint64_t channel_layout; ///< channel layout of current buffer (see libavutil/audioconvert.h)
int64_t sample_rate; ///< samples per second
int format; ///< agreed upon media format
@@ -685,7 +689,7 @@ avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int
*/
AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,
enum AVSampleFormat sample_fmt, int size,
- int64_t channel_layout, int planar);
+ uint64_t channel_layout, int planar);
/**
* Request an input frame from the filter at the other end of the link.
@@ -705,7 +709,7 @@ int avfilter_request_frame(AVFilterLink *link);
int avfilter_poll_frame(AVFilterLink *link);
/**
- * Notifie the next filter of the start of a frame.
+ * Notify the next filter of the start of a frame.
*
* @param link the output link the frame will be sent over
* @param picref A reference to the frame about to be sent. The data for this
@@ -859,4 +863,12 @@ static inline void avfilter_insert_outpad(AVFilterContext *f, unsigned index,
&f->output_pads, &f->outputs, p);
}
+/**
+ * Copy the frame properties of src to dst, without copying the actual
+ * image data.
+ *
+ * @return 0 on success, a negative number on error.
+ */
+int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src);
+
#endif /* AVFILTER_AVFILTER_H */
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index b503c36..8c43251 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -90,7 +90,7 @@ int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
av_log(log_ctx, AV_LOG_ERROR,
"Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n",
filt->input_pads[j].name, filt->name, filt->filter->name);
- return -1;
+ return AVERROR(EINVAL);
}
}
@@ -99,7 +99,7 @@ int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
av_log(log_ctx, AV_LOG_ERROR,
"Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n",
filt->output_pads[j].name, filt->name, filt->filter->name);
- return -1;
+ return AVERROR(EINVAL);
}
}
}
@@ -178,7 +178,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
av_log(log_ctx, AV_LOG_ERROR,
"Impossible to convert between the formats supported by the filter "
"'%s' and the filter '%s'\n", link->src->name, link->dst->name);
- return -1;
+ return AVERROR(EINVAL);
}
}
}
@@ -216,9 +216,11 @@ static void pick_formats(AVFilterGraph *graph)
int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
{
+ int ret;
+
/* find supported formats from sub-filters, and merge along links */
- if (query_formats(graph, log_ctx))
- return -1;
+ if ((ret = query_formats(graph, log_ctx)) < 0)
+ return ret;
/* Once everything is merged, it's possible that we'll still have
* multiple valid media format choices. We pick the first one. */
@@ -227,7 +229,7 @@ int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
return 0;
}
-int avfilter_graph_config(AVFilterGraph *graphctx, AVClass *log_ctx)
+int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
{
int ret;
diff --git a/libavfilter/avfiltergraph.h b/libavfilter/avfiltergraph.h
index a0f6b2e..f9cf5cd 100644
--- a/libavfilter/avfiltergraph.h
+++ b/libavfilter/avfiltergraph.h
@@ -76,7 +76,7 @@ int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt,
* @param log_ctx context used for logging
* @return 0 in case of success, a negative AVERROR code otherwise
*/
-int avfilter_graph_config(AVFilterGraph *graphctx, AVClass *log_ctx);
+int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx);
/**
* Free a graph, destroy its links, and set *graph to NULL.
@@ -118,6 +118,6 @@ typedef struct AVFilterInOut {
*/
int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
AVFilterInOut *inputs, AVFilterInOut *outputs,
- AVClass *log_ctx);
+ void *log_ctx);
#endif /* AVFILTER_AVFILTERGRAPH_H */
diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h
new file mode 100644
index 0000000..bd82c06
--- /dev/null
+++ b/libavfilter/buffersrc.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFILTER_BUFFERSRC_H
+#define AVFILTER_BUFFERSRC_H
+
+/**
+ * @file
+ * Memory buffer source API.
+ */
+
+#include "avfilter.h"
+
+/**
+ * Add a buffer to the filtergraph s.
+ *
+ * @param buf buffer containing frame data to be passed down the filtergraph.
+ * This function will take ownership of buf, the user must not free it.
+ */
+int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf);
+
+#endif /* AVFILTER_BUFFERSRC_H */
diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c
index 146f1c7..4c7e878 100644
--- a/libavfilter/defaults.c
+++ b/libavfilter/defaults.c
@@ -57,7 +57,7 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per
AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,
enum AVSampleFormat sample_fmt, int size,
- int64_t channel_layout, int planar)
+ uint64_t channel_layout, int planar)
{
AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer));
AVFilterBufferRef *ref = NULL;
@@ -84,7 +84,7 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per
samples->refcount = 1;
samples->free = ff_avfilter_default_free_buffer;
- sample_size = av_get_bits_per_sample_fmt(sample_fmt) >>3;
+ sample_size = av_get_bytes_per_sample(sample_fmt);
chans_nb = av_get_channel_layout_nb_channels(channel_layout);
per_channel_size = size/chans_nb;
@@ -292,7 +292,7 @@ AVFilterBufferRef *avfilter_null_get_video_buffer(AVFilterLink *link, int perms,
AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
enum AVSampleFormat sample_fmt, int size,
- int64_t channel_layout, int packed)
+ uint64_t channel_layout, int packed)
{
return avfilter_get_audio_buffer(link->dst->outputs[0], perms, sample_fmt,
size, channel_layout, packed);
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index bb7b921..8c5041a 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -21,6 +21,7 @@
#include "libavutil/pixdesc.h"
#include "avfilter.h"
+#include "internal.h"
/**
* Add all refs from a to ret and destroy a.
@@ -42,19 +43,21 @@ static void merge_ref(AVFilterFormats *ret, AVFilterFormats *a)
AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
{
AVFilterFormats *ret;
- unsigned i, j, k = 0;
+ unsigned i, j, k = 0, m_count;
ret = av_mallocz(sizeof(AVFilterFormats));
/* merge list of formats */
- ret->formats = av_malloc(sizeof(*ret->formats) * FFMIN(a->format_count,
- b->format_count));
- for(i = 0; i < a->format_count; i ++)
- for(j = 0; j < b->format_count; j ++)
- if(a->formats[i] == b->formats[j])
- ret->formats[k++] = a->formats[i];
-
- ret->format_count = k;
+ m_count = FFMIN(a->format_count, b->format_count);
+ if (m_count) {
+ ret->formats = av_malloc(sizeof(*ret->formats) * m_count);
+ for(i = 0; i < a->format_count; i ++)
+ for(j = 0; j < b->format_count; j ++)
+ if(a->formats[i] == b->formats[j])
+ ret->formats[k++] = a->formats[i];
+
+ ret->format_count = k;
+ }
/* check that there was at least one common format */
if(!ret->format_count) {
av_free(ret->formats);
@@ -70,6 +73,17 @@ AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
return ret;
}
+int ff_fmt_is_in(int fmt, const int *fmts)
+{
+ const int *p;
+
+ for (p = fmts; *p != PIX_FMT_NONE; p++) {
+ if (fmt == *p)
+ return 1;
+ }
+ return 0;
+}
+
AVFilterFormats *avfilter_make_format_list(const int *fmts)
{
AVFilterFormats *formats;
@@ -79,7 +93,8 @@ AVFilterFormats *avfilter_make_format_list(const int *fmts)
;
formats = av_mallocz(sizeof(AVFilterFormats));
- formats->formats = av_malloc(sizeof(*formats->formats) * count);
+ if (count)
+ formats->formats = av_malloc(sizeof(*formats->formats) * count);
formats->format_count = count;
memcpy(formats->formats, fmts, sizeof(*formats->formats) * count);
@@ -94,7 +109,7 @@ int avfilter_add_format(AVFilterFormats **avff, int fmt)
return AVERROR(ENOMEM);
fmts = av_realloc((*avff)->formats,
- sizeof((*avff)->formats) * ((*avff)->format_count+1));
+ sizeof(*(*avff)->formats) * ((*avff)->format_count+1));
if (!fmts)
return AVERROR(ENOMEM);
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index 00fb57a..90f2936 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -36,7 +36,7 @@
*/
static int link_filter(AVFilterContext *src, int srcpad,
AVFilterContext *dst, int dstpad,
- AVClass *log_ctx)
+ void *log_ctx)
{
int ret;
if ((ret = avfilter_link(src, srcpad, dst, dstpad))) {
@@ -55,7 +55,7 @@ static int link_filter(AVFilterContext *src, int srcpad,
* @return a pointer (that need to be freed after use) to the name
* between parenthesis
*/
-static char *parse_link_name(const char **buf, AVClass *log_ctx)
+static char *parse_link_name(const char **buf, void *log_ctx)
{
const char *start = *buf;
char *name;
@@ -83,8 +83,8 @@ static char *parse_link_name(const char **buf, AVClass *log_ctx)
* Create an instance of a filter, initialize and insert it in the
* filtergraph in *ctx.
*
+ * @param filt_ctx put here a filter context in case of successful creation and configuration, NULL otherwise.
* @param ctx the filtergraph context
- * @param put here a filter context in case of successful creation and configuration, NULL otherwise.
* @param index an index which is supposed to be unique for each filter instance added to the filtergraph
* @param filt_name the name of the filter to create
* @param args the arguments provided to the filter during its initialization
@@ -92,7 +92,7 @@ static char *parse_link_name(const char **buf, AVClass *log_ctx)
* @return 0 in case of success, a negative AVERROR code otherwise
*/
static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int index,
- const char *filt_name, const char *args, AVClass *log_ctx)
+ const char *filt_name, const char *args, void *log_ctx)
{
AVFilter *filt;
char inst_name[30];
@@ -141,6 +141,8 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind
* corresponding filter instance which is added to graph with
* create_filter().
*
+ * @param filt_ctx Pointer that is set to the created and configured filter
+ * context on success, set to NULL on failure.
* @param filt_ctx put here a pointer to the created filter context on
* success, NULL otherwise
* @param buf pointer to the buffer to parse, *buf will be updated to
@@ -151,7 +153,7 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind
* @return 0 in case of success, a negative AVERROR code otherwise
*/
static int parse_filter(AVFilterContext **filt_ctx, const char **buf, AVFilterGraph *graph,
- int index, AVClass *log_ctx)
+ int index, void *log_ctx)
{
char *opts = NULL;
char *name = av_get_token(buf, "=,;[\n");
@@ -201,7 +203,7 @@ static void insert_inout(AVFilterInOut **inouts, AVFilterInOut *element)
static int link_filter_inouts(AVFilterContext *filt_ctx,
AVFilterInOut **curr_inputs,
- AVFilterInOut **open_inputs, AVClass *log_ctx)
+ AVFilterInOut **open_inputs, void *log_ctx)
{
int pad = filt_ctx->input_count, ret;
@@ -249,7 +251,7 @@ static int link_filter_inouts(AVFilterContext *filt_ctx,
}
static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs,
- AVFilterInOut **open_outputs, AVClass *log_ctx)
+ AVFilterInOut **open_outputs, void *log_ctx)
{
int pad = 0;
@@ -284,7 +286,7 @@ static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs,
static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs,
AVFilterInOut **open_inputs,
- AVFilterInOut **open_outputs, AVClass *log_ctx)
+ AVFilterInOut **open_outputs, void *log_ctx)
{
int ret, pad = 0;
@@ -329,7 +331,7 @@ static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs,
int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
AVFilterInOut *open_inputs,
- AVFilterInOut *open_outputs, AVClass *log_ctx)
+ AVFilterInOut *open_outputs, void *log_ctx)
{
int index = 0, ret;
char chr = 0;
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 64b3f3b..0630e9b 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -52,4 +52,7 @@ int ff_avfilter_graph_config_formats(AVFilterGraph *graphctx, AVClass *log_ctx);
/** default handler for freeing audio/video buffer when there are no references left */
void ff_avfilter_default_free_buffer(AVFilterBuffer *buf);
+/** Tell is a format is contained in the provided list terminated by -1. */
+int ff_fmt_is_in(int fmt, const int *fmts);
+
#endif /* AVFILTER_INTERNAL_H */
diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c
index 2ede0fd..b43aa86 100644
--- a/libavfilter/vf_aspect.c
+++ b/libavfilter/vf_aspect.c
@@ -23,6 +23,7 @@
* aspect ratio modification video filters
*/
+#include "libavutil/mathematics.h"
#include "avfilter.h"
typedef struct {
diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c
new file mode 100644
index 0000000..a314f5c
--- /dev/null
+++ b/libavfilter/vf_boxblur.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2002 Michael Niedermayer <michaelni at gmx.at>
+ * Copyright (c) 2011 Stefano Sabatini
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file
+ * Apply a boxblur filter to the input video.
+ * Ported from MPlayer libmpcodecs/vf_boxblur.c.
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/eval.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+
+static const char *var_names[] = {
+ "w",
+ "h",
+ "cw",
+ "ch",
+ "hsub",
+ "vsub",
+ NULL
+};
+
+enum var_name {
+ VAR_W,
+ VAR_H,
+ VAR_CW,
+ VAR_CH,
+ VAR_HSUB,
+ VAR_VSUB,
+ VARS_NB
+};
+
+typedef struct {
+ int radius;
+ int power;
+} FilterParam;
+
+typedef struct {
+ FilterParam luma_param;
+ FilterParam chroma_param;
+ FilterParam alpha_param;
+ char luma_radius_expr [256];
+ char chroma_radius_expr[256];
+ char alpha_radius_expr [256];
+
+ int hsub, vsub;
+ int radius[4];
+ int power[4];
+ uint8_t *temp[2]; ///< temporary buffer used in blur_power()
+} BoxBlurContext;
+
+#define Y 0
+#define U 1
+#define V 2
+#define A 3
+
+static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ BoxBlurContext *boxblur = ctx->priv;
+ int e;
+
+ if (!args) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Filter expects 2 or 4 or 6 arguments, none provided\n");
+ return AVERROR(EINVAL);
+ }
+
+ e = sscanf(args, "%255[^:]:%d:%255[^:]:%d:%255[^:]:%d",
+ boxblur->luma_radius_expr, &boxblur->luma_param .power,
+ boxblur->chroma_radius_expr, &boxblur->chroma_param.power,
+ boxblur->alpha_radius_expr, &boxblur->alpha_param .power);
+
+ if (e != 2 && e != 4 && e != 6) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Filter expects 2 or 4 or 6 params, provided %d\n", e);
+ return AVERROR(EINVAL);
+ }
+
+ if (e < 4) {
+ boxblur->chroma_param.power = boxblur->luma_param.power;
+ av_strlcpy(boxblur->chroma_radius_expr, boxblur->luma_radius_expr,
+ sizeof(boxblur->chroma_radius_expr));
+ }
+ if (e < 6) {
+ boxblur->alpha_param.power = boxblur->luma_param.power;
+ av_strlcpy(boxblur->alpha_radius_expr, boxblur->luma_radius_expr,
+ sizeof(boxblur->alpha_radius_expr));
+ }
+
+ return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ BoxBlurContext *boxblur = ctx->priv;
+
+ av_freep(&boxblur->temp[0]);
+ av_freep(&boxblur->temp[1]);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ enum PixelFormat pix_fmts[] = {
+ PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV420P,
+ PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_YUVA420P,
+ PIX_FMT_YUV440P, PIX_FMT_GRAY8,
+ PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P,
+ PIX_FMT_YUVJ440P,
+ PIX_FMT_NONE
+ };
+
+ avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+ const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[inlink->format];
+ AVFilterContext *ctx = inlink->dst;
+ BoxBlurContext *boxblur = ctx->priv;
+ int w = inlink->w, h = inlink->h;
+ int cw, ch;
+ double var_values[VARS_NB], res;
+ char *expr;
+ int ret;
+
+ av_freep(&boxblur->temp[0]);
+ av_freep(&boxblur->temp[1]);
+ if (!(boxblur->temp[0] = av_malloc(FFMAX(w, h))))
+ return AVERROR(ENOMEM);
+ if (!(boxblur->temp[1] = av_malloc(FFMAX(w, h)))) {
+ av_freep(&boxblur->temp[0]);
+ return AVERROR(ENOMEM);
+ }
+
+ boxblur->hsub = desc->log2_chroma_w;
+ boxblur->vsub = desc->log2_chroma_h;
+
+ var_values[VAR_W] = inlink->w;
+ var_values[VAR_H] = inlink->h;
+ var_values[VAR_CW] = cw = w>>boxblur->hsub;
+ var_values[VAR_CH] = ch = h>>boxblur->vsub;
+ var_values[VAR_HSUB] = 1<<boxblur->hsub;
+ var_values[VAR_VSUB] = 1<<boxblur->vsub;
+
+#define EVAL_RADIUS_EXPR(comp) \
+ expr = boxblur->comp##_radius_expr; \
+ ret = av_expr_parse_and_eval(&res, expr, var_names, var_values, \
+ NULL, NULL, NULL, NULL, NULL, 0, ctx); \
+ boxblur->comp##_param.radius = res; \
+ if (ret < 0) { \
+ av_log(NULL, AV_LOG_ERROR, \
+ "Error when evaluating " #comp " radius expression '%s'\n", expr); \
+ return ret; \
+ }
+ EVAL_RADIUS_EXPR(luma);
+ EVAL_RADIUS_EXPR(chroma);
+ EVAL_RADIUS_EXPR(alpha);
+
+ av_log(ctx, AV_LOG_DEBUG,
+ "luma_radius:%d luma_power:%d "
+ "chroma_radius:%d chroma_power:%d "
+ "alpha_radius:%d alpha_power:%d "
+ "w:%d chroma_w:%d h:%d chroma_h:%d\n",
+ boxblur->luma_param .radius, boxblur->luma_param .power,
+ boxblur->chroma_param.radius, boxblur->chroma_param.power,
+ boxblur->alpha_param .radius, boxblur->alpha_param .power,
+ w, cw, h, ch);
+
+#define CHECK_RADIUS_VAL(w_, h_, comp) \
+ if (boxblur->comp##_param.radius < 0 || \
+ 2*boxblur->comp##_param.radius > FFMIN(w_, h_)) { \
+ av_log(ctx, AV_LOG_ERROR, \
+ "Invalid " #comp " radius value %d, must be >= 0 and <= %d\n", \
+ boxblur->comp##_param.radius, FFMIN(w_, h_)/2); \
+ return AVERROR(EINVAL); \
+ }
+ CHECK_RADIUS_VAL(w, h, luma);
+ CHECK_RADIUS_VAL(cw, ch, chroma);
+ CHECK_RADIUS_VAL(w, h, alpha);
+
+ boxblur->radius[Y] = boxblur->luma_param.radius;
+ boxblur->radius[U] = boxblur->radius[V] = boxblur->chroma_param.radius;
+ boxblur->radius[A] = boxblur->alpha_param.radius;
+
+ boxblur->power[Y] = boxblur->luma_param.power;
+ boxblur->power[U] = boxblur->power[V] = boxblur->chroma_param.power;
+ boxblur->power[A] = boxblur->alpha_param.power;
+
+ return 0;
+}
+
+static inline void blur(uint8_t *dst, int dst_step, const uint8_t *src, int src_step,
+ int len, int radius)
+{
+ /* Naive boxblur would sum source pixels from x-radius .. x+radius
+ * for destination pixel x. That would be O(radius*width).
+ * If you now look at what source pixels represent 2 consecutive
+ * output pixels, then you see they are almost identical and only
+ * differ by 2 pixels, like:
+ * src0 111111111
+ * dst0 1
+ * src1 111111111
+ * dst1 1
+ * src0-src1 1 -1
+ * so when you know one output pixel you can find the next by just adding
+ * and subtracting 1 input pixel.
+ * The following code adopts this faster variant.
+ */
+ const int length = radius*2 + 1;
+ const int inv = ((1<<16) + length/2)/length;
+ int x, sum = 0;
+
+ for (x = 0; x < radius; x++)
+ sum += src[x*src_step]<<1;
+ sum += src[radius*src_step];
+
+ for (x = 0; x <= radius; x++) {
+ sum += src[(radius+x)*src_step] - src[(radius-x)*src_step];
+ dst[x*dst_step] = (sum*inv + (1<<15))>>16;
+ }
+
+ for (; x < len-radius; x++) {
+ sum += src[(radius+x)*src_step] - src[(x-radius-1)*src_step];
+ dst[x*dst_step] = (sum*inv + (1<<15))>>16;
+ }
+
+ for (; x < len; x++) {
+ sum += src[(2*len-radius-x-1)*src_step] - src[(x-radius-1)*src_step];
+ dst[x*dst_step] = (sum*inv + (1<<15))>>16;
+ }
+}
+
+static inline void blur_power(uint8_t *dst, int dst_step, const uint8_t *src, int src_step,
+ int len, int radius, int power, uint8_t *temp[2])
+{
+ uint8_t *a = temp[0], *b = temp[1];
+
+ if (radius && power) {
+ blur(a, 1, src, src_step, len, radius);
+ for (; power > 2; power--) {
+ uint8_t *c;
+ blur(b, 1, a, 1, len, radius);
+ c = a; a = b; b = c;
+ }
+ if (power > 1) {
+ blur(dst, dst_step, a, 1, len, radius);
+ } else {
+ int i;
+ for (i = 0; i < len; i++)
+ dst[i*dst_step] = a[i];
+ }
+ } else {
+ int i;
+ for (i = 0; i < len; i++)
+ dst[i*dst_step] = src[i*src_step];
+ }
+}
+
+static void hblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize,
+ int w, int h, int radius, int power, uint8_t *temp[2])
+{
+ int y;
+
+ if (radius == 0 && dst == src)
+ return;
+
+ for (y = 0; y < h; y++)
+ blur_power(dst + y*dst_linesize, 1, src + y*src_linesize, 1,
+ w, radius, power, temp);
+}
+
+static void vblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize,
+ int w, int h, int radius, int power, uint8_t *temp[2])
+{
+ int x;
+
+ if (radius == 0 && dst == src)
+ return;
+
+ for (x = 0; x < w; x++)
+ blur_power(dst + x, dst_linesize, src + x, src_linesize,
+ h, radius, power, temp);
+}
+
+static void draw_slice(AVFilterLink *inlink, int y0, int h0, int slice_dir)
+{
+ AVFilterContext *ctx = inlink->dst;
+ BoxBlurContext *boxblur = ctx->priv;
+ AVFilterLink *outlink = inlink->dst->outputs[0];
+ AVFilterBufferRef *inpicref = inlink ->cur_buf;
+ AVFilterBufferRef *outpicref = outlink->out_buf;
+ int plane;
+ int cw = inlink->w >> boxblur->hsub, ch = h0 >> boxblur->vsub;
+ int w[4] = { inlink->w, cw, cw, inlink->w };
+ int h[4] = { h0, ch, ch, h0 };
+
+ for (plane = 0; inpicref->data[plane] && plane < 4; plane++)
+ hblur(outpicref->data[plane], outpicref->linesize[plane],
+ inpicref ->data[plane], inpicref ->linesize[plane],
+ w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
+ boxblur->temp);
+
+ for (plane = 0; inpicref->data[plane] && plane < 4; plane++)
+ vblur(outpicref->data[plane], outpicref->linesize[plane],
+ outpicref->data[plane], outpicref->linesize[plane],
+ w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
+ boxblur->temp);
+
+ avfilter_draw_slice(outlink, y0, h0, slice_dir);
+}
+
+AVFilter avfilter_vf_boxblur = {
+ .name = "boxblur",
+ .description = NULL_IF_CONFIG_SMALL("Blur the input."),
+ .priv_size = sizeof(BoxBlurContext),
+ .init = init,
+ .uninit = uninit,
+ .query_formats = query_formats,
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .config_props = config_input,
+ .draw_slice = draw_slice,
+ .min_perms = AV_PERM_READ },
+ { .name = NULL}},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO, },
+ { .name = NULL}},
+};
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index 69e5a52..0880d4e 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -30,6 +30,7 @@
#include "libavutil/avstring.h"
#include "libavutil/libm.h"
#include "libavutil/imgutils.h"
+#include "libavutil/mathematics.h"
static const char *var_names[] = {
"E",
diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
new file mode 100644
index 0000000..ca31568
--- /dev/null
+++ b/libavfilter/vf_delogo.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2002 Jindrich Makovicka <makovick at gmail.com>
+ * Copyright (c) 2011 Stefano Sabatini
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file
+ * A very simple tv station logo remover
+ * Ported from MPlayer libmpcodecs/vf_delogo.c.
+ */
+
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+
+/**
+ * Apply a simple delogo algorithm to the image in dst and put the
+ * result in src.
+ *
+ * The algorithm is only applied to the region specified by the logo
+ * parameters.
+ *
+ * @param w width of the input image
+ * @param h height of the input image
+ * @param logo_x x coordinate of the top left corner of the logo region
+ * @param logo_y y coordinate of the top left corner of the logo region
+ * @param logo_w width of the logo
+ * @param logo_h height of the logo
+ * @param band the size of the band around the processed area
+ * @param show show a rectangle around the processed area, useful for
+ * parameters tweaking
+ * @param direct if non-zero perform in-place processing
+ */
+static void apply_delogo(uint8_t *dst, int dst_linesize,
+ uint8_t *src, int src_linesize,
+ int w, int h,
+ int logo_x, int logo_y, int logo_w, int logo_h,
+ int band, int show, int direct)
+{
+ int x, y;
+ int interp, dist;
+ uint8_t *xdst, *xsrc;
+
+ uint8_t *topleft, *botleft, *topright;
+ int xclipl, xclipr, yclipt, yclipb;
+ int logo_x1, logo_x2, logo_y1, logo_y2;
+
+ xclipl = FFMAX(-logo_x, 0);
+ xclipr = FFMAX(logo_x+logo_w-w, 0);
+ yclipt = FFMAX(-logo_y, 0);
+ yclipb = FFMAX(logo_y+logo_h-h, 0);
+
+ logo_x1 = logo_x + xclipl;
+ logo_x2 = logo_x + logo_w - xclipr;
+ logo_y1 = logo_y + yclipt;
+ logo_y2 = logo_y + logo_h - yclipb;
+
+ topleft = src+logo_y1 * src_linesize+logo_x1;
+ topright = src+logo_y1 * src_linesize+logo_x2-1;
+ botleft = src+(logo_y2-1) * src_linesize+logo_x1;
+
+ dst += (logo_y1+1)*dst_linesize;
+ src += (logo_y1+1)*src_linesize;
+
+ if (!direct)
+ av_image_copy_plane(dst, dst_linesize, src, src_linesize, w, h);
+
+ for (y = logo_y1+1; y < logo_y2-1; y++) {
+ for (x = logo_x1+1,
+ xdst = dst+logo_x1+1,
+ xsrc = src+logo_x1+1; x < logo_x2-1; x++, xdst++, xsrc++) {
+ interp = (topleft[src_linesize*(y-logo_y -yclipt)] +
+ topleft[src_linesize*(y-logo_y-1-yclipt)] +
+ topleft[src_linesize*(y-logo_y+1-yclipt)]) * (logo_w-(x-logo_x))/logo_w
+ + (topright[src_linesize*(y-logo_y-yclipt)] +
+ topright[src_linesize*(y-logo_y-1-yclipt)] +
+ topright[src_linesize*(y-logo_y+1-yclipt)]) * (x-logo_x)/logo_w
+ + (topleft[x-logo_x-xclipl] +
+ topleft[x-logo_x-1-xclipl] +
+ topleft[x-logo_x+1-xclipl]) * (logo_h-(y-logo_y))/logo_h
+ + (botleft[x-logo_x-xclipl] +
+ botleft[x-logo_x-1-xclipl] +
+ botleft[x-logo_x+1-xclipl]) * (y-logo_y)/logo_h;
+ interp /= 6;
+
+ if (y >= logo_y+band && y < logo_y+logo_h-band &&
+ x >= logo_x+band && x < logo_x+logo_w-band) {
+ *xdst = interp;
+ } else {
+ dist = 0;
+ if (x < logo_x+band)
+ dist = FFMAX(dist, logo_x-x+band);
+ else if (x >= logo_x+logo_w-band)
+ dist = FFMAX(dist, x-(logo_x+logo_w-1-band));
+
+ if (y < logo_y+band)
+ dist = FFMAX(dist, logo_y-y+band);
+ else if (y >= logo_y+logo_h-band)
+ dist = FFMAX(dist, y-(logo_y+logo_h-1-band));
+
+ *xdst = (*xsrc*dist + interp*(band-dist))/band;
+ if (show && (dist == band-1))
+ *xdst = 0;
+ }
+ }
+
+ dst += dst_linesize;
+ src += src_linesize;
+ }
+}
+
+typedef struct {
+ const AVClass *class;
+ int x, y, w, h, band, show;
+} DelogoContext;
+
+#define OFFSET(x) offsetof(DelogoContext, x)
+
+static const AVOption delogo_options[]= {
+ {"x", "set logo x position", OFFSET(x), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX },
+ {"y", "set logo y position", OFFSET(y), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX },
+ {"w", "set logo width", OFFSET(w), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX },
+ {"h", "set logo height", OFFSET(h), FF_OPT_TYPE_INT, {-1}, -1, INT_MAX },
+ {"band", "set delogo area band size", OFFSET(band), FF_OPT_TYPE_INT, { 4}, -1, INT_MAX },
+ {"t", "set delogo area band size", OFFSET(band), FF_OPT_TYPE_INT, { 4}, -1, INT_MAX },
+ {"show", "show delogo area", OFFSET(show), FF_OPT_TYPE_INT, { 0}, 0, 1 },
+ {NULL},
+};
+
+static const char *delogo_get_name(void *ctx)
+{
+ return "delogo";
+}
+
+static const AVClass delogo_class = {
+ .class_name = "DelogoContext",
+ .item_name = delogo_get_name,
+ .option = delogo_options,
+};
+
+static int query_formats(AVFilterContext *ctx)
+{
+ enum PixelFormat pix_fmts[] = {
+ PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV420P,
+ PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_YUV440P,
+ PIX_FMT_YUVA420P, PIX_FMT_GRAY8,
+ PIX_FMT_NONE
+ };
+
+ avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ return 0;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ DelogoContext *delogo = ctx->priv;
+ int ret = 0;
+
+ delogo->class = &delogo_class;
+ av_opt_set_defaults(delogo);
+
+ if (args)
+ ret = sscanf(args, "%d:%d:%d:%d:%d",
+ &delogo->x, &delogo->y, &delogo->w, &delogo->h, &delogo->band);
+ if (ret == 5) {
+ if (delogo->band < 0)
+ delogo->show = 1;
+ } else if ((ret = (av_set_options_string(delogo, args, "=", ":"))) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
+ return ret;
+ }
+
+#define CHECK_UNSET_OPT(opt) \
+ if (delogo->opt == -1) { \
+ av_log(delogo, AV_LOG_ERROR, "Option %s was not set.\n", #opt); \
+ return AVERROR(EINVAL); \
+ }
+ CHECK_UNSET_OPT(x);
+ CHECK_UNSET_OPT(y);
+ CHECK_UNSET_OPT(w);
+ CHECK_UNSET_OPT(h);
+
+ if (delogo->show)
+ delogo->band = 4;
+
+ av_log(ctx, AV_LOG_DEBUG, "x:%d y:%d, w:%d h:%d band:%d show:%d\n",
+ delogo->x, delogo->y, delogo->w, delogo->h, delogo->band, delogo->show);
+
+ delogo->w += delogo->band*2;
+ delogo->h += delogo->band*2;
+ delogo->x -= delogo->band;
+ delogo->y -= delogo->band;
+
+ return 0;
+}
+
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+{
+ AVFilterLink *outlink = inlink->dst->outputs[0];
+ AVFilterBufferRef *outpicref;
+
+ if (inpicref->perms & AV_PERM_PRESERVE) {
+ outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,
+ outlink->w, outlink->h);
+ avfilter_copy_buffer_ref_props(outpicref, inpicref);
+ outpicref->video->w = outlink->w;
+ outpicref->video->h = outlink->h;
+ } else
+ outpicref = inpicref;
+
+ outlink->out_buf = outpicref;
+ avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));
+}
+
+static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { }
+
+static void end_frame(AVFilterLink *inlink)
+{
+ DelogoContext *delogo = inlink->dst->priv;
+ AVFilterLink *outlink = inlink->dst->outputs[0];
+ AVFilterBufferRef *inpicref = inlink ->cur_buf;
+ AVFilterBufferRef *outpicref = outlink->out_buf;
+ int direct = inpicref == outpicref;
+ int hsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_w;
+ int vsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
+ int plane;
+
+ for (plane = 0; plane < 4 && inpicref->data[plane]; plane++) {
+ int hsub = plane == 1 || plane == 2 ? hsub0 : 0;
+ int vsub = plane == 1 || plane == 2 ? vsub0 : 0;
+
+ apply_delogo(outpicref->data[plane], outpicref->linesize[plane],
+ inpicref ->data[plane], inpicref ->linesize[plane],
+ inlink->w>>hsub, inlink->h>>vsub,
+ delogo->x>>hsub, delogo->y>>vsub,
+ delogo->w>>hsub, delogo->h>>vsub,
+ delogo->band>>FFMIN(hsub, vsub),
+ delogo->show, direct);
+ }
+
+ avfilter_draw_slice(outlink, 0, inlink->h, 1);
+ avfilter_end_frame(outlink);
+ avfilter_unref_buffer(inpicref);
+ if (!direct)
+ avfilter_unref_buffer(outpicref);
+}
+
+AVFilter avfilter_vf_delogo = {
+ .name = "delogo",
+ .description = NULL_IF_CONFIG_SMALL("Remove logo from input video."),
+ .priv_size = sizeof(DelogoContext),
+ .init = init,
+ .query_formats = query_formats,
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .get_video_buffer = avfilter_null_get_video_buffer,
+ .start_frame = start_frame,
+ .draw_slice = null_draw_slice,
+ .end_frame = end_frame,
+ .min_perms = AV_PERM_WRITE | AV_PERM_READ,
+ .rej_perms = AV_PERM_PRESERVE },
+ { .name = NULL}},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO, },
+ { .name = NULL}},
+};
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index 37c48c5..ab5cb03 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -34,7 +34,7 @@ enum { Y, U, V, A };
typedef struct {
int x, y, w, h;
unsigned char yuv_color[4];
- int vsub, hsub; //< chroma subsampling
+ int vsub, hsub; ///< chroma subsampling
} DrawBoxContext;
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index a3adaa7..060c3a4 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -22,7 +22,7 @@
/**
* @file
- * drawtext filter, based on the original FFmpeg vhook/drawtext.c
+ * drawtext filter, based on the original vhook/drawtext.c
* filter by Gustavo Sverzut Barbieri
*/
@@ -31,10 +31,14 @@
#include "libavutil/colorspace.h"
#include "libavutil/file.h"
+#include "libavutil/eval.h"
#include "libavutil/opt.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/random_seed.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/tree.h"
+#include "libavutil/lfg.h"
#include "avfilter.h"
#include "drawutils.h"
@@ -45,6 +49,52 @@
#include FT_FREETYPE_H
#include FT_GLYPH_H
+static const char *var_names[] = {
+ "E",
+ "PHI",
+ "PI",
+ "main_w", "W", ///< width of the main video
+ "main_h", "H", ///< height of the main video
+ "text_w", "w", ///< width of the overlay text
+ "text_h", "h", ///< height of the overlay text
+ "x",
+ "y",
+ "n", ///< number of processed frames
+ "t", ///< timestamp expressed in seconds
+ NULL
+};
+
+static const char *fun2_names[] = {
+ "rand",
+};
+
+static double drand(void *opaque, double min, double max)
+{
+ return min + (max-min) / UINT_MAX * av_lfg_get(opaque);
+}
+
+typedef double (*eval_func2)(void *, double a, double b);
+
+static const eval_func2 fun2[] = {
+ drand,
+ NULL
+};
+
+enum var_name {
+ VAR_E,
+ VAR_PHI,
+ VAR_PI,
+ VAR_MAIN_W, VAR_MW,
+ VAR_MAIN_H, VAR_MH,
+ VAR_TEXT_W, VAR_TW,
+ VAR_TEXT_H, VAR_TH,
+ VAR_X,
+ VAR_Y,
+ VAR_N,
+ VAR_T,
+ VAR_VARS_NB
+};
+
typedef struct {
const AVClass *class;
uint8_t *fontfile; ///< font to be used
@@ -55,8 +105,8 @@ typedef struct {
FT_Vector *positions; ///< positions for each element in the text
size_t nb_positions; ///< number of elements of positions array
char *textfile; ///< file with text to be drawn
- unsigned int x; ///< x position to start drawing text
- unsigned int y; ///< y position to start drawing text
+ int x, y; ///< position to start drawing text
+ int w, h; ///< dimension of the text block
int shadowx, shadowy;
unsigned int fontsize; ///< font size to use
char *fontcolor_string; ///< font color as string
@@ -81,42 +131,50 @@ typedef struct {
int pixel_step[4]; ///< distance in bytes between the component of each pixel
uint8_t rgba_map[4]; ///< map RGBA offsets to the positions in the packed RGBA format
uint8_t *box_line[4]; ///< line used for filling the box background
+ char *x_expr, *y_expr;
+ AVExpr *x_pexpr, *y_pexpr; ///< parsed expressions for x and y
+ double var_values[VAR_VARS_NB];
+ char *d_expr;
+ AVExpr *d_pexpr;
+ int draw; ///< set to zero to prevent drawing
+ AVLFG prng; ///< random
} DrawTextContext;
#define OFFSET(x) offsetof(DrawTextContext, x)
static const AVOption drawtext_options[]= {
-{"fontfile", "set font file", OFFSET(fontfile), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
-{"text", "set text", OFFSET(text), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
-{"textfile", "set text file", OFFSET(textfile), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
-{"fontcolor","set foreground color", OFFSET(fontcolor_string), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
-{"boxcolor", "set box color", OFFSET(boxcolor_string), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
-{"shadowcolor", "set shadow color", OFFSET(shadowcolor_string), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
-{"box", "set box", OFFSET(draw_box), FF_OPT_TYPE_INT, {.dbl=0}, 0, 1 },
-{"fontsize", "set font size", OFFSET(fontsize), FF_OPT_TYPE_INT, {.dbl=16}, 1, 72 },
-{"x", "set x", OFFSET(x), FF_OPT_TYPE_INT, {.dbl=0}, 0, INT_MAX },
-{"y", "set y", OFFSET(y), FF_OPT_TYPE_INT, {.dbl=0}, 0, INT_MAX },
-{"shadowx", "set x", OFFSET(shadowx), FF_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX },
-{"shadowy", "set y", OFFSET(shadowy), FF_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX },
-{"tabsize", "set tab size", OFFSET(tabsize), FF_OPT_TYPE_INT, {.dbl=4}, 0, INT_MAX },
+{"fontfile", "set font file", OFFSET(fontfile), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
+{"text", "set text", OFFSET(text), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
+{"textfile", "set text file", OFFSET(textfile), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
+{"fontcolor","set foreground color", OFFSET(fontcolor_string), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
+{"boxcolor", "set box color", OFFSET(boxcolor_string), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
+{"shadowcolor", "set shadow color", OFFSET(shadowcolor_string), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX },
+{"box", "set box", OFFSET(draw_box), AV_OPT_TYPE_INT, {.dbl=0}, 0, 1 },
+{"fontsize", "set font size", OFFSET(fontsize), AV_OPT_TYPE_INT, {.dbl=16}, 1, 72 },
+{"x", "set x", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX },
+{"y", "set y", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX },
+{"shadowx", "set x", OFFSET(shadowx), AV_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX },
+{"shadowy", "set y", OFFSET(shadowy), AV_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX },
+{"tabsize", "set tab size", OFFSET(tabsize), AV_OPT_TYPE_INT, {.dbl=4}, 0, INT_MAX },
+{"draw", "if false do not draw", OFFSET(d_expr), AV_OPT_TYPE_STRING, {.str="1"}, CHAR_MIN, CHAR_MAX },
/* FT_LOAD_* flags */
-{"ft_load_flags", "set font loading flags for libfreetype", OFFSET(ft_load_flags), FF_OPT_TYPE_FLAGS, {.dbl=FT_LOAD_DEFAULT|FT_LOAD_RENDER}, 0, INT_MAX, 0, "ft_load_flags" },
-{"default", "set default", 0, FF_OPT_TYPE_CONST, {FT_LOAD_DEFAULT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"no_scale", "set no_scale", 0, FF_OPT_TYPE_CONST, {FT_LOAD_NO_SCALE}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"no_hinting", "set no_hinting", 0, FF_OPT_TYPE_CONST, {FT_LOAD_NO_HINTING}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"render", "set render", 0, FF_OPT_TYPE_CONST, {FT_LOAD_RENDER}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"no_bitmap", "set no_bitmap", 0, FF_OPT_TYPE_CONST, {FT_LOAD_NO_BITMAP}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"vertical_layout", "set vertical_layout", 0, FF_OPT_TYPE_CONST, {FT_LOAD_VERTICAL_LAYOUT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"force_autohint", "set force_autohint", 0, FF_OPT_TYPE_CONST, {FT_LOAD_FORCE_AUTOHINT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"crop_bitmap", "set crop_bitmap", 0, FF_OPT_TYPE_CONST, {FT_LOAD_CROP_BITMAP}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"pedantic", "set pedantic", 0, FF_OPT_TYPE_CONST, {FT_LOAD_PEDANTIC}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"ignore_global_advance_width", "set ignore_global_advance_width", 0, FF_OPT_TYPE_CONST, {FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"no_recurse", "set no_recurse", 0, FF_OPT_TYPE_CONST, {FT_LOAD_NO_RECURSE}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"ignore_transform", "set ignore_transform", 0, FF_OPT_TYPE_CONST, {FT_LOAD_IGNORE_TRANSFORM}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"monochrome", "set monochrome", 0, FF_OPT_TYPE_CONST, {FT_LOAD_MONOCHROME}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"linear_design", "set linear_design", 0, FF_OPT_TYPE_CONST, {FT_LOAD_LINEAR_DESIGN}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"no_autohint", "set no_autohint", 0, FF_OPT_TYPE_CONST, {FT_LOAD_NO_AUTOHINT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"ft_load_flags", "set font loading flags for libfreetype", OFFSET(ft_load_flags), AV_OPT_TYPE_FLAGS, {.dbl=FT_LOAD_DEFAULT|FT_LOAD_RENDER}, 0, INT_MAX, 0, "ft_load_flags" },
+{"default", "set default", 0, AV_OPT_TYPE_CONST, {FT_LOAD_DEFAULT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"no_scale", "set no_scale", 0, AV_OPT_TYPE_CONST, {FT_LOAD_NO_SCALE}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"no_hinting", "set no_hinting", 0, AV_OPT_TYPE_CONST, {FT_LOAD_NO_HINTING}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"render", "set render", 0, AV_OPT_TYPE_CONST, {FT_LOAD_RENDER}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"no_bitmap", "set no_bitmap", 0, AV_OPT_TYPE_CONST, {FT_LOAD_NO_BITMAP}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"vertical_layout", "set vertical_layout", 0, AV_OPT_TYPE_CONST, {FT_LOAD_VERTICAL_LAYOUT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"force_autohint", "set force_autohint", 0, AV_OPT_TYPE_CONST, {FT_LOAD_FORCE_AUTOHINT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"crop_bitmap", "set crop_bitmap", 0, AV_OPT_TYPE_CONST, {FT_LOAD_CROP_BITMAP}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"pedantic", "set pedantic", 0, AV_OPT_TYPE_CONST, {FT_LOAD_PEDANTIC}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"ignore_global_advance_width", "set ignore_global_advance_width", 0, AV_OPT_TYPE_CONST, {FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"no_recurse", "set no_recurse", 0, AV_OPT_TYPE_CONST, {FT_LOAD_NO_RECURSE}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"ignore_transform", "set ignore_transform", 0, AV_OPT_TYPE_CONST, {FT_LOAD_IGNORE_TRANSFORM}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"monochrome", "set monochrome", 0, AV_OPT_TYPE_CONST, {FT_LOAD_MONOCHROME}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"linear_design", "set linear_design", 0, AV_OPT_TYPE_CONST, {FT_LOAD_LINEAR_DESIGN}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"no_autohint", "set no_autohint", 0, AV_OPT_TYPE_CONST, {FT_LOAD_NO_AUTOHINT}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
{NULL},
};
@@ -223,7 +281,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
Glyph *glyph;
dtext->class = &drawtext_class;
- av_opt_set_defaults2(dtext, 0, 0);
+ av_opt_set_defaults(dtext);
dtext->fontcolor_string = av_strdup("black");
dtext->boxcolor_string = av_strdup("white");
dtext->shadowcolor_string = av_strdup("black");
@@ -369,15 +427,167 @@ static av_cold void uninit(AVFilterContext *ctx)
}
+static inline int is_newline(uint32_t c)
+{
+ return (c == '\n' || c == '\r' || c == '\f' || c == '\v');
+}
+
+static int dtext_prepare_text(AVFilterContext *ctx)
+{
+ DrawTextContext *dtext = ctx->priv;
+ uint32_t code = 0, prev_code = 0;
+ int x = 0, y = 0, i = 0, ret;
+ int text_height, baseline;
+ char *text = dtext->text;
+ uint8_t *p;
+ int str_w = 0, len;
+ int y_min = 32000, y_max = -32000;
+ FT_Vector delta;
+ Glyph *glyph = NULL, *prev_glyph = NULL;
+ Glyph dummy = { 0 };
+ int width = ctx->inputs[0]->w;
+ int height = ctx->inputs[0]->h;
+
+#if HAVE_LOCALTIME_R
+ time_t now = time(0);
+ struct tm ltime;
+ uint8_t *buf = dtext->expanded_text;
+ int buf_size = dtext->expanded_text_size;
+
+ if (!buf)
+ buf_size = 2*strlen(dtext->text)+1;
+
+ localtime_r(&now, <ime);
+
+ while ((buf = av_realloc(buf, buf_size))) {
+ *buf = 1;
+ if (strftime(buf, buf_size, dtext->text, <ime) != 0 || *buf == 0)
+ break;
+ buf_size *= 2;
+ }
+
+ if (!buf)
+ return AVERROR(ENOMEM);
+ text = dtext->expanded_text = buf;
+ dtext->expanded_text_size = buf_size;
+#endif
+
+ if ((len = strlen(text)) > dtext->nb_positions) {
+ FT_Vector *p = av_realloc(dtext->positions,
+ len * sizeof(*dtext->positions));
+ if (!p) {
+ av_freep(dtext->positions);
+ dtext->nb_positions = 0;
+ return AVERROR(ENOMEM);
+ } else {
+ dtext->positions = p;
+ dtext->nb_positions = len;
+ }
+ }
+
+ /* load and cache glyphs */
+ for (i = 0, p = text; *p; i++) {
+ GET_UTF8(code, *p++, continue;);
+
+ /* get glyph */
+ dummy.code = code;
+ glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
+ if (!glyph)
+ ret = load_glyph(ctx, &glyph, code);
+ if (ret) return ret;
+
+ y_min = FFMIN(glyph->bbox.yMin, y_min);
+ y_max = FFMAX(glyph->bbox.yMax, y_max);
+ }
+ text_height = y_max - y_min;
+ baseline = y_max;
+
+ /* compute and save position for each glyph */
+ glyph = NULL;
+ for (i = 0, p = text; *p; i++) {
+ GET_UTF8(code, *p++, continue;);
+
+ /* skip the \n in the sequence \r\n */
+ if (prev_code == '\r' && code == '\n')
+ continue;
+
+ prev_code = code;
+ if (is_newline(code)) {
+ str_w = FFMAX(str_w, x - dtext->x);
+ y += text_height;
+ x = 0;
+ continue;
+ }
+
+ /* get glyph */
+ prev_glyph = glyph;
+ dummy.code = code;
+ glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
+
+ /* kerning */
+ if (dtext->use_kerning && prev_glyph && glyph->code) {
+ FT_Get_Kerning(dtext->face, prev_glyph->code, glyph->code,
+ ft_kerning_default, &delta);
+ x += delta.x >> 6;
+ }
+
+ if (x + glyph->bbox.xMax >= width) {
+ str_w = FFMAX(str_w, x);
+ y += text_height;
+ x = 0;
+ }
+
+ /* save position */
+ dtext->positions[i].x = x + glyph->bitmap_left;
+ dtext->positions[i].y = y - glyph->bitmap_top + baseline;
+ if (code == '\t') x = (x / dtext->tabsize + 1)*dtext->tabsize;
+ else x += glyph->advance;
+ }
+
+ str_w = FFMIN(width - 1, FFMAX(str_w, x));
+ y = FFMIN(y + text_height, height - 1);
+
+ dtext->w = str_w;
+ dtext->h = y;
+
+ return 0;
+}
+
+
static int config_input(AVFilterLink *inlink)
{
- DrawTextContext *dtext = inlink->dst->priv;
+ AVFilterContext *ctx = inlink->dst;
+ DrawTextContext *dtext = ctx->priv;
const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[inlink->format];
int ret;
dtext->hsub = pix_desc->log2_chroma_w;
dtext->vsub = pix_desc->log2_chroma_h;
+ dtext->var_values[VAR_E ] = M_E;
+ dtext->var_values[VAR_PHI] = M_PHI;
+ dtext->var_values[VAR_PI ] = M_PI;
+
+ dtext->var_values[VAR_MAIN_W] =
+ dtext->var_values[VAR_MW] = ctx->inputs[0]->w;
+ dtext->var_values[VAR_MAIN_H] =
+ dtext->var_values[VAR_MH] = ctx->inputs[0]->h;
+
+ dtext->var_values[VAR_X] = 0;
+ dtext->var_values[VAR_Y] = 0;
+ dtext->var_values[VAR_N] = 0;
+ dtext->var_values[VAR_T] = NAN;
+
+ av_lfg_init(&dtext->prng, av_get_random_seed());
+
+ if ((ret = av_expr_parse(&dtext->x_pexpr, dtext->x_expr, var_names,
+ NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
+ (ret = av_expr_parse(&dtext->y_pexpr, dtext->y_expr, var_names,
+ NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
+ (ret = av_expr_parse(&dtext->d_pexpr, dtext->d_expr, var_names,
+ NULL, NULL, fun2_names, fun2, 0, ctx)) < 0)
+ return AVERROR(EINVAL);
+
if ((ret =
ff_fill_line_with_color(dtext->box_line, dtext->pixel_step,
inlink->w, dtext->boxcolor,
@@ -398,7 +608,9 @@ static int config_input(AVFilterLink *inlink)
dtext->shadowcolor[3] = rgba[3];
}
- return 0;
+ dtext->draw = 1;
+
+ return dtext_prepare_text(ctx);
}
#define GET_BITMAP_VAL(r, c) \
@@ -424,15 +636,10 @@ static inline int draw_glyph_yuv(AVFilterBufferRef *picref, FT_Bitmap *bitmap, u
{
int r, c, alpha;
unsigned int luma_pos, chroma_pos1, chroma_pos2;
- uint8_t src_val, dst_pixel[4];
+ uint8_t src_val;
for (r = 0; r < bitmap->rows && r+y < height; r++) {
for (c = 0; c < bitmap->width && c+x < width; c++) {
- /* get pixel in the picref (destination) */
- dst_pixel[0] = picref->data[0][ c+x + (y+r) * picref->linesize[0]];
- dst_pixel[1] = picref->data[1][((c+x) >> hsub) + ((y+r) >> vsub) * picref->linesize[1]];
- dst_pixel[2] = picref->data[2][((c+x) >> hsub) + ((y+r) >> vsub) * picref->linesize[2]];
-
/* get intensity value in the glyph bitmap (source) */
src_val = GET_BITMAP_VAL(r, c);
if (!src_val)
@@ -460,18 +667,10 @@ static inline int draw_glyph_rgb(AVFilterBufferRef *picref, FT_Bitmap *bitmap,
{
int r, c, alpha;
uint8_t *p;
- uint8_t src_val, dst_pixel[4];
+ uint8_t src_val;
for (r = 0; r < bitmap->rows && r+y < height; r++) {
for (c = 0; c < bitmap->width && c+x < width; c++) {
- /* get pixel in the picref (destination) */
- dst_pixel[0] = picref->data[0][(c+x + rgba_map[0]) * pixel_step +
- (y+r) * picref->linesize[0]];
- dst_pixel[1] = picref->data[0][(c+x + rgba_map[1]) * pixel_step +
- (y+r) * picref->linesize[0]];
- dst_pixel[2] = picref->data[0][(c+x + rgba_map[2]) * pixel_step +
- (y+r) * picref->linesize[0]];
-
/* get intensity value in the glyph bitmap (source) */
src_val = GET_BITMAP_VAL(r, c);
if (!src_val)
@@ -512,11 +711,6 @@ static inline void drawbox(AVFilterBufferRef *picref, unsigned int x, unsigned i
}
}
-static inline int is_newline(uint32_t c)
-{
- return (c == '\n' || c == '\r' || c == '\f' || c == '\v');
-}
-
static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
int width, int height, const uint8_t rgbcolor[4], const uint8_t yuvcolor[4], int x, int y)
{
@@ -559,140 +753,104 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
int width, int height)
{
DrawTextContext *dtext = ctx->priv;
- uint32_t code = 0, prev_code = 0;
- int x = 0, y = 0, i = 0, ret;
- int text_height, baseline;
- char *text = dtext->text;
- uint8_t *p;
- int str_w = 0, len;
- int y_min = 32000, y_max = -32000;
- FT_Vector delta;
- Glyph *glyph = NULL, *prev_glyph = NULL;
- Glyph dummy = { 0 };
-
-#if HAVE_LOCALTIME_R
- time_t now = time(0);
- struct tm ltime;
- uint8_t *buf = dtext->expanded_text;
- int buf_size = dtext->expanded_text_size;
-
- if (!buf) {
- buf_size = 2*strlen(dtext->text)+1;
- buf = av_malloc(buf_size);
- }
-
- localtime_r(&now, <ime);
+ int ret;
- do {
- *buf = 1;
- if (strftime(buf, buf_size, dtext->text, <ime) != 0 || *buf == 0)
- break;
- buf_size *= 2;
- } while ((buf = av_realloc(buf, buf_size)));
+ /* draw box */
+ if (dtext->draw_box)
+ drawbox(picref, dtext->x, dtext->y, dtext->w, dtext->h,
+ dtext->box_line, dtext->pixel_step, dtext->boxcolor,
+ dtext->hsub, dtext->vsub, dtext->is_packed_rgb,
+ dtext->rgba_map);
- if (!buf)
- return AVERROR(ENOMEM);
- text = dtext->expanded_text = buf;
- dtext->expanded_text_size = buf_size;
-#endif
- if ((len = strlen(text)) > dtext->nb_positions) {
- if (!(dtext->positions =
- av_realloc(dtext->positions, len*sizeof(*dtext->positions))))
- return AVERROR(ENOMEM);
- dtext->nb_positions = len;
+ if (dtext->shadowx || dtext->shadowy) {
+ if ((ret = draw_glyphs(dtext, picref, width, height,
+ dtext->shadowcolor_rgba,
+ dtext->shadowcolor,
+ dtext->x + dtext->shadowx,
+ dtext->y + dtext->shadowy)) < 0)
+ return ret;
}
- x = dtext->x;
- y = dtext->y;
-
- /* load and cache glyphs */
- for (i = 0, p = text; *p; i++) {
- GET_UTF8(code, *p++, continue;);
+ if ((ret = draw_glyphs(dtext, picref, width, height,
+ dtext->fontcolor_rgba,
+ dtext->fontcolor,
+ dtext->x,
+ dtext->y)) < 0)
+ return ret;
- /* get glyph */
- dummy.code = code;
- glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
- if (!glyph)
- load_glyph(ctx, &glyph, code);
+ return 0;
+}
- y_min = FFMIN(glyph->bbox.yMin, y_min);
- y_max = FFMAX(glyph->bbox.yMax, y_max);
- }
- text_height = y_max - y_min;
- baseline = y_max;
+static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { }
- /* compute and save position for each glyph */
- glyph = NULL;
- for (i = 0, p = text; *p; i++) {
- GET_UTF8(code, *p++, continue;);
+static inline int normalize_double(int *n, double d)
+{
+ int ret = 0;
- /* skip the \n in the sequence \r\n */
- if (prev_code == '\r' && code == '\n')
- continue;
+ if (isnan(d)) {
+ ret = AVERROR(EINVAL);
+ } else if (d > INT_MAX || d < INT_MIN) {
+ *n = d > INT_MAX ? INT_MAX : INT_MIN;
+ ret = AVERROR(EINVAL);
+ } else
+ *n = round(d);
- prev_code = code;
- if (is_newline(code)) {
- str_w = FFMAX(str_w, x - dtext->x);
- y += text_height;
- x = dtext->x;
- continue;
- }
+ return ret;
+}
- /* get glyph */
- prev_glyph = glyph;
- dummy.code = code;
- glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+{
+ AVFilterContext *ctx = inlink->dst;
+ DrawTextContext *dtext = ctx->priv;
+ int fail = 0;
- /* kerning */
- if (dtext->use_kerning && prev_glyph && glyph->code) {
- FT_Get_Kerning(dtext->face, prev_glyph->code, glyph->code,
- ft_kerning_default, &delta);
- x += delta.x >> 6;
- }
+ if (dtext_prepare_text(ctx) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Can't draw text\n");
+ fail = 1;
+ }
- if (x + glyph->bbox.xMax >= width) {
- str_w = FFMAX(str_w, x - dtext->x);
- y += text_height;
- x = dtext->x;
- }
+ dtext->var_values[VAR_T] = inpicref->pts == AV_NOPTS_VALUE ?
+ NAN : inpicref->pts * av_q2d(inlink->time_base);
+ dtext->var_values[VAR_X] =
+ av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
+ dtext->var_values[VAR_Y] =
+ av_expr_eval(dtext->y_pexpr, dtext->var_values, &dtext->prng);
+ dtext->var_values[VAR_X] =
+ av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
- /* save position */
- dtext->positions[i].x = x + glyph->bitmap_left;
- dtext->positions[i].y = y - glyph->bitmap_top + baseline;
- if (code == '\t') x = (x / dtext->tabsize + 1)*dtext->tabsize;
- else x += glyph->advance;
- }
+ dtext->draw = fail ? 0 :
+ av_expr_eval(dtext->d_pexpr, dtext->var_values, &dtext->prng);
- str_w = FFMIN(width - dtext->x - 1, FFMAX(str_w, x - dtext->x));
- y = FFMIN(y + text_height, height - 1);
+ normalize_double(&dtext->x, dtext->var_values[VAR_X]);
+ normalize_double(&dtext->y, dtext->var_values[VAR_Y]);
- /* draw box */
- if (dtext->draw_box)
- drawbox(picref, dtext->x, dtext->y, str_w, y-dtext->y,
- dtext->box_line, dtext->pixel_step, dtext->boxcolor,
- dtext->hsub, dtext->vsub, dtext->is_packed_rgb, dtext->rgba_map);
+ if (dtext->x < 0) dtext->x = 0;
+ if (dtext->y < 0) dtext->y = 0;
+ if ((unsigned)dtext->x + (unsigned)dtext->w > inlink->w)
+ dtext->x = inlink->w - dtext->w;
+ if ((unsigned)dtext->y + (unsigned)dtext->h > inlink->h)
+ dtext->y = inlink->h - dtext->h;
- if (dtext->shadowx || dtext->shadowy) {
- if ((ret = draw_glyphs(dtext, picref, width, height, dtext->shadowcolor_rgba,
- dtext->shadowcolor, dtext->shadowx, dtext->shadowy)) < 0)
- return ret;
- }
+ dtext->x &= ~((1 << dtext->hsub) - 1);
+ dtext->y &= ~((1 << dtext->vsub) - 1);
- if ((ret = draw_glyphs(dtext, picref, width, height, dtext->fontcolor_rgba,
- dtext->fontcolor, 0, 0)) < 0)
- return ret;
+ av_dlog(ctx, "n:%d t:%f x:%d y:%d x+w:%d y+h:%d\n",
+ (int)dtext->var_values[VAR_N], dtext->var_values[VAR_T],
+ dtext->x, dtext->y, dtext->x+dtext->w, dtext->y+dtext->h);
- return 0;
+ avfilter_start_frame(inlink->dst->outputs[0], inpicref);
}
-static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { }
-
static void end_frame(AVFilterLink *inlink)
{
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFilterBufferRef *picref = inlink->cur_buf;
+ DrawTextContext *dtext = inlink->dst->priv;
+
+ if (dtext->draw)
+ draw_text(inlink->dst, picref, picref->video->w, picref->video->h);
- draw_text(inlink->dst, picref, picref->video->w, picref->video->h);
+ dtext->var_values[VAR_N] += 1.0;
avfilter_draw_slice(outlink, 0, picref->video->h, 1);
avfilter_end_frame(outlink);
@@ -709,7 +867,7 @@ AVFilter avfilter_vf_drawtext = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer = avfilter_null_get_video_buffer,
- .start_frame = avfilter_null_start_frame,
+ .start_frame = start_frame,
.draw_slice = null_draw_slice,
.end_frame = end_frame,
.config_props = config_input,
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index 48683f4..455e24a 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -28,6 +28,7 @@
#include <frei0r.h>
#include "libavutil/avstring.h"
#include "libavutil/imgutils.h"
+#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
#include "avfilter.h"
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
new file mode 100644
index 0000000..7f3e913
--- /dev/null
+++ b/libavfilter/vf_lut.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Compute a look-up table for binding the input value to the output
+ * value, and apply it to input video.
+ */
+
+#include "libavutil/eval.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "internal.h"
+
+static const char *var_names[] = {
+ "E",
+ "PHI",
+ "PI",
+ "w", ///< width of the input video
+ "h", ///< height of the input video
+ "val", ///< input value for the pixel
+ "maxval", ///< max value for the pixel
+ "minval", ///< min value for the pixel
+ "negval", ///< negated value
+ "clipval",
+ NULL
+};
+
+enum var_name {
+ VAR_E,
+ VAR_PHI,
+ VAR_PI,
+ VAR_W,
+ VAR_H,
+ VAR_VAL,
+ VAR_MAXVAL,
+ VAR_MINVAL,
+ VAR_NEGVAL,
+ VAR_CLIPVAL,
+ VAR_VARS_NB
+};
+
+typedef struct {
+ const AVClass *class;
+ uint8_t lut[4][256]; ///< lookup table for each component
+ char *comp_expr_str[4];
+ AVExpr *comp_expr[4];
+ int hsub, vsub;
+ double var_values[VAR_VARS_NB];
+ int is_rgb, is_yuv;
+ int rgba_map[4];
+ int step;
+ int negate_alpha; /* only used by negate */
+} LutContext;
+
+#define Y 0
+#define U 1
+#define V 2
+#define R 0
+#define G 1
+#define B 2
+#define A 3
+
+#define OFFSET(x) offsetof(LutContext, x)
+
+static const AVOption lut_options[] = {
+ {"c0", "set component #0 expression", OFFSET(comp_expr_str[0]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {"c1", "set component #1 expression", OFFSET(comp_expr_str[1]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {"c2", "set component #2 expression", OFFSET(comp_expr_str[2]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {"c3", "set component #3 expression", OFFSET(comp_expr_str[3]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {"y", "set Y expression", OFFSET(comp_expr_str[Y]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {"u", "set U expression", OFFSET(comp_expr_str[U]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {"v", "set V expression", OFFSET(comp_expr_str[V]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {"r", "set R expression", OFFSET(comp_expr_str[R]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {"g", "set G expression", OFFSET(comp_expr_str[G]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {"b", "set B expression", OFFSET(comp_expr_str[B]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {"a", "set A expression", OFFSET(comp_expr_str[A]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+ {NULL},
+};
+
+static const char *lut_get_name(void *ctx)
+{
+ return "lut";
+}
+
+static const AVClass lut_class = {
+ "LutContext",
+ lut_get_name,
+ lut_options
+};
+
+static int init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ LutContext *lut = ctx->priv;
+ int ret;
+
+ lut->class = &lut_class;
+ av_opt_set_defaults(lut);
+
+ lut->var_values[VAR_PHI] = M_PHI;
+ lut->var_values[VAR_PI] = M_PI;
+ lut->var_values[VAR_E ] = M_E;
+
+ lut->is_rgb = !strcmp(ctx->filter->name, "lutrgb");
+ lut->is_yuv = !strcmp(ctx->filter->name, "lutyuv");
+ if (args && (ret = av_set_options_string(lut, args, "=", ":")) < 0)
+ return ret;
+
+ return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ LutContext *lut = ctx->priv;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ av_expr_free(lut->comp_expr[i]);
+ lut->comp_expr[i] = NULL;
+ av_freep(&lut->comp_expr_str[i]);
+ }
+}
+
+#define YUV_FORMATS \
+ PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, \
+ PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_YUV440P, \
+ PIX_FMT_YUVA420P, \
+ PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P, \
+ PIX_FMT_YUVJ440P
+
+#define RGB_FORMATS \
+ PIX_FMT_ARGB, PIX_FMT_RGBA, \
+ PIX_FMT_ABGR, PIX_FMT_BGRA, \
+ PIX_FMT_RGB24, PIX_FMT_BGR24
+
+static enum PixelFormat yuv_pix_fmts[] = { YUV_FORMATS, PIX_FMT_NONE };
+static enum PixelFormat rgb_pix_fmts[] = { RGB_FORMATS, PIX_FMT_NONE };
+static enum PixelFormat all_pix_fmts[] = { RGB_FORMATS, YUV_FORMATS, PIX_FMT_NONE };
+
+static int query_formats(AVFilterContext *ctx)
+{
+ LutContext *lut = ctx->priv;
+
+ enum PixelFormat *pix_fmts = lut->is_rgb ? rgb_pix_fmts :
+ lut->is_yuv ? yuv_pix_fmts : all_pix_fmts;
+
+ avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ return 0;
+}
+
+/**
+ * Clip value val in the minval - maxval range.
+ */
+static double clip(void *opaque, double val)
+{
+ LutContext *lut = opaque;
+ double minval = lut->var_values[VAR_MINVAL];
+ double maxval = lut->var_values[VAR_MAXVAL];
+
+ return av_clip(val, minval, maxval);
+}
+
+/**
+ * Compute gamma correction for value val, assuming the minval-maxval
+ * range, val is clipped to a value contained in the same interval.
+ */
+static double compute_gammaval(void *opaque, double gamma)
+{
+ LutContext *lut = opaque;
+ double val = lut->var_values[VAR_CLIPVAL];
+ double minval = lut->var_values[VAR_MINVAL];
+ double maxval = lut->var_values[VAR_MAXVAL];
+
+ return pow((val-minval)/(maxval-minval), gamma) * (maxval-minval)+minval;
+}
+
+static double (* const funcs1[])(void *, double) = {
+ clip,
+ compute_gammaval,
+ NULL
+};
+
+static const char * const funcs1_names[] = {
+ "clip",
+ "gammaval",
+ NULL
+};
+
+static int config_props(AVFilterLink *inlink)
+{
+ AVFilterContext *ctx = inlink->dst;
+ LutContext *lut = ctx->priv;
+ const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[inlink->format];
+ int min[4], max[4];
+ int val, comp, ret;
+
+ lut->hsub = desc->log2_chroma_w;
+ lut->vsub = desc->log2_chroma_h;
+
+ lut->var_values[VAR_W] = inlink->w;
+ lut->var_values[VAR_H] = inlink->h;
+
+ switch (inlink->format) {
+ case PIX_FMT_YUV410P:
+ case PIX_FMT_YUV411P:
+ case PIX_FMT_YUV420P:
+ case PIX_FMT_YUV422P:
+ case PIX_FMT_YUV440P:
+ case PIX_FMT_YUV444P:
+ case PIX_FMT_YUVA420P:
+ min[Y] = min[U] = min[V] = 16;
+ max[Y] = 235;
+ max[U] = max[V] = 240;
+ min[A] = 0; max[A] = 255;
+ break;
+ default:
+ min[0] = min[1] = min[2] = min[3] = 0;
+ max[0] = max[1] = max[2] = max[3] = 255;
+ }
+
+ lut->is_yuv = lut->is_rgb = 0;
+ if (ff_fmt_is_in(inlink->format, yuv_pix_fmts)) lut->is_yuv = 1;
+ else if (ff_fmt_is_in(inlink->format, rgb_pix_fmts)) lut->is_rgb = 1;
+
+ if (lut->is_rgb) {
+ switch (inlink->format) {
+ case PIX_FMT_ARGB: lut->rgba_map[A] = 0; lut->rgba_map[R] = 1; lut->rgba_map[G] = 2; lut->rgba_map[B] = 3; break;
+ case PIX_FMT_ABGR: lut->rgba_map[A] = 0; lut->rgba_map[B] = 1; lut->rgba_map[G] = 2; lut->rgba_map[R] = 3; break;
+ case PIX_FMT_RGBA:
+ case PIX_FMT_RGB24: lut->rgba_map[R] = 0; lut->rgba_map[G] = 1; lut->rgba_map[B] = 2; lut->rgba_map[A] = 3; break;
+ case PIX_FMT_BGRA:
+ case PIX_FMT_BGR24: lut->rgba_map[B] = 0; lut->rgba_map[G] = 1; lut->rgba_map[R] = 2; lut->rgba_map[A] = 3; break;
+ }
+ lut->step = av_get_bits_per_pixel(desc) >> 3;
+ }
+
+ for (comp = 0; comp < desc->nb_components; comp++) {
+ double res;
+
+ /* create the parsed expression */
+ ret = av_expr_parse(&lut->comp_expr[comp], lut->comp_expr_str[comp],
+ var_names, funcs1_names, funcs1, NULL, NULL, 0, ctx);
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Error when parsing the expression '%s' for the component %d.\n",
+ lut->comp_expr_str[comp], comp);
+ return AVERROR(EINVAL);
+ }
+
+ /* compute the lut */
+ lut->var_values[VAR_MAXVAL] = max[comp];
+ lut->var_values[VAR_MINVAL] = min[comp];
+
+ for (val = 0; val < 256; val++) {
+ lut->var_values[VAR_VAL] = val;
+ lut->var_values[VAR_CLIPVAL] = av_clip(val, min[comp], max[comp]);
+ lut->var_values[VAR_NEGVAL] =
+ av_clip(min[comp] + max[comp] - lut->var_values[VAR_VAL],
+ min[comp], max[comp]);
+
+ res = av_expr_eval(lut->comp_expr[comp], lut->var_values, lut);
+ if (isnan(res)) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Error when evaluating the expression '%s' for the value %d for the component #%d.\n",
+ lut->comp_expr_str[comp], val, comp);
+ return AVERROR(EINVAL);
+ }
+ lut->lut[comp][val] = av_clip((int)res, min[comp], max[comp]);
+ av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, lut->lut[comp][val]);
+ }
+ }
+
+ return 0;
+}
+
+static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+ AVFilterContext *ctx = inlink->dst;
+ LutContext *lut = ctx->priv;
+ AVFilterLink *outlink = ctx->outputs[0];
+ AVFilterBufferRef *inpic = inlink ->cur_buf;
+ AVFilterBufferRef *outpic = outlink->out_buf;
+ uint8_t *inrow, *outrow, *inrow0, *outrow0;
+ int i, j, k, plane;
+
+ if (lut->is_rgb) {
+ /* packed */
+ inrow0 = inpic ->data[0] + y * inpic ->linesize[0];
+ outrow0 = outpic->data[0] + y * outpic->linesize[0];
+
+ for (i = 0; i < h; i ++) {
+ inrow = inrow0;
+ outrow = outrow0;
+ for (j = 0; j < inlink->w; j++) {
+ for (k = 0; k < lut->step; k++)
+ outrow[k] = lut->lut[lut->rgba_map[k]][inrow[k]];
+ outrow += lut->step;
+ inrow += lut->step;
+ }
+ inrow0 += inpic ->linesize[0];
+ outrow0 += outpic->linesize[0];
+ }
+ } else {
+ /* planar */
+ for (plane = 0; plane < 4 && inpic->data[plane]; plane++) {
+ int vsub = plane == 1 || plane == 2 ? lut->vsub : 0;
+ int hsub = plane == 1 || plane == 2 ? lut->hsub : 0;
+
+ inrow = inpic ->data[plane] + (y>>vsub) * inpic ->linesize[plane];
+ outrow = outpic->data[plane] + (y>>vsub) * outpic->linesize[plane];
+
+ for (i = 0; i < h>>vsub; i ++) {
+ for (j = 0; j < inlink->w>>hsub; j++)
+ outrow[j] = lut->lut[plane][inrow[j]];
+ inrow += inpic ->linesize[plane];
+ outrow += outpic->linesize[plane];
+ }
+ }
+ }
+
+ avfilter_draw_slice(outlink, y, h, slice_dir);
+}
+
+#define DEFINE_LUT_FILTER(name_, description_, init_) \
+ AVFilter avfilter_vf_##name_ = { \
+ .name = #name_, \
+ .description = NULL_IF_CONFIG_SMALL(description_), \
+ .priv_size = sizeof(LutContext), \
+ \
+ .init = init_, \
+ .uninit = uninit, \
+ .query_formats = query_formats, \
+ \
+ .inputs = (AVFilterPad[]) {{ .name = "default", \
+ .type = AVMEDIA_TYPE_VIDEO, \
+ .draw_slice = draw_slice, \
+ .config_props = config_props, \
+ .min_perms = AV_PERM_READ, }, \
+ { .name = NULL}}, \
+ .outputs = (AVFilterPad[]) {{ .name = "default", \
+ .type = AVMEDIA_TYPE_VIDEO, }, \
+ { .name = NULL}}, \
+ }
+
+#if CONFIG_LUT_FILTER
+DEFINE_LUT_FILTER(lut, "Compute and apply a lookup table to the RGB/YUV input video.", init);
+#endif
+#if CONFIG_LUTYUV_FILTER
+DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.", init);
+#endif
+#if CONFIG_LUTRGB_FILTER
+DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.", init);
+#endif
+
+#if CONFIG_NEGATE_FILTER
+
+static int negate_init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ LutContext *lut = ctx->priv;
+ char lut_params[64];
+
+ if (args)
+ sscanf(args, "%d", &lut->negate_alpha);
+
+ av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", lut->negate_alpha);
+
+ snprintf(lut_params, sizeof(lut_params), "c0=negval:c1=negval:c2=negval:a=%s",
+ lut->negate_alpha ? "negval" : "val");
+
+ return init(ctx, lut_params, opaque);
+}
+
+DEFINE_LUT_FILTER(negate, "Negate input video.", negate_init);
+
+#endif
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index c8bdf51..39b2375 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -30,6 +30,7 @@
#include "libavutil/avstring.h"
#include "libavutil/pixdesc.h"
#include "libavutil/imgutils.h"
+#include "libavutil/mathematics.h"
#include "internal.h"
static const char *var_names[] = {
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index 18873b8..9ba91ed 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -21,7 +21,7 @@
/**
* @file
- * video padding filter and color source
+ * video padding filter
*/
#include "avfilter.h"
@@ -32,6 +32,7 @@
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/parseutils.h"
+#include "libavutil/mathematics.h"
#include "drawutils.h"
static const char *var_names[] = {
@@ -157,7 +158,7 @@ static int config_input(AVFilterLink *inlink)
var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
var_values[VAR_A] = (float) inlink->w / inlink->h;
var_values[VAR_HSUB] = 1<<pad->hsub;
- var_values[VAR_VSUB] = 2<<pad->vsub;
+ var_values[VAR_VSUB] = 1<<pad->vsub;
/* evaluate width and height */
av_expr_parse_and_eval(&res, (expr = pad->w_expr),
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 5288d32..dd2f7e1 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -26,6 +26,7 @@
#include "avfilter.h"
#include "libavutil/avstring.h"
#include "libavutil/eval.h"
+#include "libavutil/mathematics.h"
#include "libavutil/pixdesc.h"
#include "libswscale/swscale.h"
@@ -37,7 +38,8 @@ static const char *var_names[] = {
"in_h", "ih",
"out_w", "ow",
"out_h", "oh",
- "a",
+ "a", "dar",
+ "sar",
"hsub",
"vsub",
NULL
@@ -51,7 +53,8 @@ enum var_name {
VAR_IN_H, VAR_IH,
VAR_OUT_W, VAR_OW,
VAR_OUT_H, VAR_OH,
- VAR_A,
+ VAR_A, VAR_DAR,
+ VAR_SAR,
VAR_HSUB,
VAR_VSUB,
VARS_NB
@@ -148,7 +151,9 @@ static int config_props(AVFilterLink *outlink)
var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h;
var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
- var_values[VAR_A] = (float) inlink->w / inlink->h;
+ var_values[VAR_DAR] = var_values[VAR_A] = (float) inlink->w / inlink->h;
+ var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
+ (float) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
var_values[VAR_HSUB] = 1<<av_pix_fmt_descriptors[inlink->format].log2_chroma_w;
var_values[VAR_VSUB] = 1<<av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
@@ -213,6 +218,14 @@ static int config_props(AVFilterLink *outlink)
if (!scale->sws)
return AVERROR(EINVAL);
+
+ if (inlink->sample_aspect_ratio.num)
+ outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w,
+ outlink->w*inlink->h},
+ inlink->sample_aspect_ratio);
+ else
+ outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
+
return 0;
fail:
diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c
new file mode 100644
index 0000000..0ec443a
--- /dev/null
+++ b/libavfilter/vf_select.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * filter for selecting which frame passes in the filterchain
+ */
+
+#include "libavutil/eval.h"
+#include "libavutil/fifo.h"
+#include "libavutil/mathematics.h"
+#include "avfilter.h"
+
+static const char *var_names[] = {
+ "E", ///< Euler number
+ "PHI", ///< golden ratio
+ "PI", ///< greek pi
+
+ "TB", ///< timebase
+
+ "pts", ///< original pts in the file of the frame
+ "start_pts", ///< first PTS in the stream, expressed in TB units
+ "prev_pts", ///< previous frame PTS
+ "prev_selected_pts", ///< previous selected frame PTS
+
+ "t", ///< first PTS in seconds
+ "start_t", ///< first PTS in the stream, expressed in seconds
+ "prev_t", ///< previous frame time
+ "prev_selected_t", ///< previously selected time
+
+ "pict_type", ///< the type of picture in the movie
+ "I",
+ "P",
+ "B",
+ "S",
+ "SI",
+ "SP",
+ "BI",
+
+ "interlace_type", ///< the frame interlace type
+ "PROGRESSIVE",
+ "TOPFIRST",
+ "BOTTOMFIRST",
+
+ "n", ///< frame number (starting from zero)
+ "selected_n", ///< selected frame number (starting from zero)
+ "prev_selected_n", ///< number of the last selected frame
+
+ "key", ///< tell if the frame is a key frame
+ "pos", ///< original position in the file of the frame
+
+ NULL
+};
+
+enum var_name {
+ VAR_E,
+ VAR_PHI,
+ VAR_PI,
+
+ VAR_TB,
+
+ VAR_PTS,
+ VAR_START_PTS,
+ VAR_PREV_PTS,
+ VAR_PREV_SELECTED_PTS,
+
+ VAR_T,
+ VAR_START_T,
+ VAR_PREV_T,
+ VAR_PREV_SELECTED_T,
+
+ VAR_PICT_TYPE,
+ VAR_PICT_TYPE_I,
+ VAR_PICT_TYPE_P,
+ VAR_PICT_TYPE_B,
+ VAR_PICT_TYPE_S,
+ VAR_PICT_TYPE_SI,
+ VAR_PICT_TYPE_SP,
+ VAR_PICT_TYPE_BI,
+
+ VAR_INTERLACE_TYPE,
+ VAR_INTERLACE_TYPE_P,
+ VAR_INTERLACE_TYPE_T,
+ VAR_INTERLACE_TYPE_B,
+
+ VAR_N,
+ VAR_SELECTED_N,
+ VAR_PREV_SELECTED_N,
+
+ VAR_KEY,
+ VAR_POS,
+
+ VAR_VARS_NB
+};
+
+#define FIFO_SIZE 8
+
+typedef struct {
+ AVExpr *expr;
+ double var_values[VAR_VARS_NB];
+ double select;
+ int cache_frames;
+ AVFifoBuffer *pending_frames; ///< FIFO buffer of video frames
+} SelectContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ SelectContext *select = ctx->priv;
+ int ret;
+
+ if ((ret = av_expr_parse(&select->expr, args ? args : "1",
+ var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args);
+ return ret;
+ }
+
+ select->pending_frames = av_fifo_alloc(FIFO_SIZE*sizeof(AVFilterBufferRef*));
+ if (!select->pending_frames) {
+ av_log(ctx, AV_LOG_ERROR, "Failed to allocate pending frames buffer.\n");
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
+#define INTERLACE_TYPE_P 0
+#define INTERLACE_TYPE_T 1
+#define INTERLACE_TYPE_B 2
+
+static int config_input(AVFilterLink *inlink)
+{
+ SelectContext *select = inlink->dst->priv;
+
+ select->var_values[VAR_E] = M_E;
+ select->var_values[VAR_PHI] = M_PHI;
+ select->var_values[VAR_PI] = M_PI;
+
+ select->var_values[VAR_N] = 0.0;
+ select->var_values[VAR_SELECTED_N] = 0.0;
+
+ select->var_values[VAR_TB] = av_q2d(inlink->time_base);
+
+ select->var_values[VAR_PREV_PTS] = NAN;
+ select->var_values[VAR_PREV_SELECTED_PTS] = NAN;
+ select->var_values[VAR_PREV_SELECTED_T] = NAN;
+ select->var_values[VAR_START_PTS] = NAN;
+ select->var_values[VAR_START_T] = NAN;
+
+ select->var_values[VAR_PICT_TYPE_I] = AV_PICTURE_TYPE_I;
+ select->var_values[VAR_PICT_TYPE_P] = AV_PICTURE_TYPE_P;
+ select->var_values[VAR_PICT_TYPE_B] = AV_PICTURE_TYPE_B;
+ select->var_values[VAR_PICT_TYPE_SI] = AV_PICTURE_TYPE_SI;
+ select->var_values[VAR_PICT_TYPE_SP] = AV_PICTURE_TYPE_SP;
+
+ select->var_values[VAR_INTERLACE_TYPE_P] = INTERLACE_TYPE_P;
+ select->var_values[VAR_INTERLACE_TYPE_T] = INTERLACE_TYPE_T;
+ select->var_values[VAR_INTERLACE_TYPE_B] = INTERLACE_TYPE_B;;
+
+ return 0;
+}
+
+#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
+#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
+
+static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *picref)
+{
+ SelectContext *select = ctx->priv;
+ AVFilterLink *inlink = ctx->inputs[0];
+ double res;
+
+ if (isnan(select->var_values[VAR_START_PTS]))
+ select->var_values[VAR_START_PTS] = TS2D(picref->pts);
+ if (isnan(select->var_values[VAR_START_T]))
+ select->var_values[VAR_START_T] = TS2D(picref->pts) * av_q2d(inlink->time_base);
+
+ select->var_values[VAR_PTS] = TS2D(picref->pts);
+ select->var_values[VAR_T ] = TS2D(picref->pts) * av_q2d(inlink->time_base);
+ select->var_values[VAR_POS] = picref->pos == -1 ? NAN : picref->pos;
+ select->var_values[VAR_PREV_PTS] = TS2D(picref ->pts);
+
+ select->var_values[VAR_INTERLACE_TYPE] =
+ !picref->video->interlaced ? INTERLACE_TYPE_P :
+ picref->video->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B;
+ select->var_values[VAR_PICT_TYPE] = picref->video->pict_type;
+
+ res = av_expr_eval(select->expr, select->var_values, NULL);
+ av_log(inlink->dst, AV_LOG_DEBUG,
+ "n:%d pts:%d t:%f pos:%d interlace_type:%c key:%d pict_type:%c "
+ "-> select:%f\n",
+ (int)select->var_values[VAR_N],
+ (int)select->var_values[VAR_PTS],
+ select->var_values[VAR_T],
+ (int)select->var_values[VAR_POS],
+ select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_P ? 'P' :
+ select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_T ? 'T' :
+ select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_B ? 'B' : '?',
+ (int)select->var_values[VAR_KEY],
+ av_get_picture_type_char(select->var_values[VAR_PICT_TYPE]),
+ res);
+
+ select->var_values[VAR_N] += 1.0;
+
+ if (res) {
+ select->var_values[VAR_PREV_SELECTED_N] = select->var_values[VAR_N];
+ select->var_values[VAR_PREV_SELECTED_PTS] = select->var_values[VAR_PTS];
+ select->var_values[VAR_PREV_SELECTED_T] = select->var_values[VAR_T];
+ select->var_values[VAR_SELECTED_N] += 1.0;
+ }
+ return res;
+}
+
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+ SelectContext *select = inlink->dst->priv;
+
+ select->select = select_frame(inlink->dst, picref);
+ if (select->select) {
+ /* frame was requested through poll_frame */
+ if (select->cache_frames) {
+ if (!av_fifo_space(select->pending_frames))
+ av_log(inlink->dst, AV_LOG_ERROR,
+ "Buffering limit reached, cannot cache more frames\n");
+ else
+ av_fifo_generic_write(select->pending_frames, &picref,
+ sizeof(picref), NULL);
+ return;
+ }
+ avfilter_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0));
+ }
+}
+
+static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+ SelectContext *select = inlink->dst->priv;
+
+ if (select->select && !select->cache_frames)
+ avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
+}
+
+static void end_frame(AVFilterLink *inlink)
+{
+ SelectContext *select = inlink->dst->priv;
+ AVFilterBufferRef *picref = inlink->cur_buf;
+
+ if (select->select) {
+ if (select->cache_frames)
+ return;
+ avfilter_end_frame(inlink->dst->outputs[0]);
+ }
+ avfilter_unref_buffer(picref);
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ SelectContext *select = ctx->priv;
+ AVFilterLink *inlink = outlink->src->inputs[0];
+ select->select = 0;
+
+ if (av_fifo_size(select->pending_frames)) {
+ AVFilterBufferRef *picref;
+ av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL);
+ avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
+ avfilter_draw_slice(outlink, 0, outlink->h, 1);
+ avfilter_end_frame(outlink);
+ avfilter_unref_buffer(picref);
+ return 0;
+ }
+
+ while (!select->select) {
+ int ret = avfilter_request_frame(inlink);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int poll_frame(AVFilterLink *outlink)
+{
+ SelectContext *select = outlink->src->priv;
+ AVFilterLink *inlink = outlink->src->inputs[0];
+ int count, ret;
+
+ if (!av_fifo_size(select->pending_frames)) {
+ if ((count = avfilter_poll_frame(inlink)) <= 0)
+ return count;
+ /* request frame from input, and apply select condition to it */
+ select->cache_frames = 1;
+ while (count-- && av_fifo_space(select->pending_frames)) {
+ ret = avfilter_request_frame(inlink);
+ if (ret < 0)
+ break;
+ }
+ select->cache_frames = 0;
+ }
+
+ return av_fifo_size(select->pending_frames)/sizeof(AVFilterBufferRef *);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ SelectContext *select = ctx->priv;
+ AVFilterBufferRef *picref;
+
+ av_expr_free(select->expr);
+ select->expr = NULL;
+
+ while (select->pending_frames &&
+ av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL) == sizeof(picref))
+ avfilter_unref_buffer(picref);
+ av_fifo_free(select->pending_frames);
+ select->pending_frames = NULL;
+}
+
+AVFilter avfilter_vf_select = {
+ .name = "select",
+ .description = NULL_IF_CONFIG_SMALL("Select frames to pass in output."),
+ .init = init,
+ .uninit = uninit,
+
+ .priv_size = sizeof(SelectContext),
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .get_video_buffer = avfilter_null_get_video_buffer,
+ .config_props = config_input,
+ .start_frame = start_frame,
+ .draw_slice = draw_slice,
+ .end_frame = end_frame },
+ { .name = NULL }},
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .poll_frame = poll_frame,
+ .request_frame = request_frame, },
+ { .name = NULL}},
+};
diff --git a/libavfilter/vf_setpts.c b/libavfilter/vf_setpts.c
index bece373..f265092 100644
--- a/libavfilter/vf_setpts.c
+++ b/libavfilter/vf_setpts.c
@@ -27,6 +27,7 @@
/* #define DEBUG */
#include "libavutil/eval.h"
+#include "libavutil/mathematics.h"
#include "avfilter.h"
static const char *var_names[] = {
diff --git a/libavfilter/vf_settb.c b/libavfilter/vf_settb.c
index 9575483..eeb4353 100644
--- a/libavfilter/vf_settb.c
+++ b/libavfilter/vf_settb.c
@@ -25,6 +25,7 @@
#include "libavutil/avstring.h"
#include "libavutil/eval.h"
+#include "libavutil/mathematics.h"
#include "libavutil/rational.h"
#include "avfilter.h"
#include "internal.h"
diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
new file mode 100644
index 0000000..aa2a7f1
--- /dev/null
+++ b/libavfilter/vf_showinfo.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * filter for showing textual video frame information
+ */
+
+#include "libavutil/adler32.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+
+typedef struct {
+ unsigned int frame;
+} ShowInfoContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ ShowInfoContext *showinfo = ctx->priv;
+ showinfo->frame = 0;
+ return 0;
+}
+
+static void end_frame(AVFilterLink *inlink)
+{
+ AVFilterContext *ctx = inlink->dst;
+ ShowInfoContext *showinfo = ctx->priv;
+ AVFilterBufferRef *picref = inlink->cur_buf;
+ uint32_t plane_checksum[4] = {0}, checksum = 0;
+ int i, plane, vsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
+
+ for (plane = 0; picref->data[plane] && plane < 4; plane++) {
+ size_t linesize = av_image_get_linesize(picref->format, picref->video->w, plane);
+ uint8_t *data = picref->data[plane];
+ int h = plane == 1 || plane == 2 ? inlink->h >> vsub : inlink->h;
+
+ for (i = 0; i < h; i++) {
+ plane_checksum[plane] = av_adler32_update(plane_checksum[plane], data, linesize);
+ checksum = av_adler32_update(checksum, data, linesize);
+ data += picref->linesize[plane];
+ }
+ }
+
+ av_log(ctx, AV_LOG_INFO,
+ "n:%d pts:%"PRId64" pts_time:%f pos:%"PRId64" "
+ "fmt:%s sar:%d/%d s:%dx%d i:%c iskey:%d type:%c "
+ "checksum:%u plane_checksum:[%u %u %u %u]\n",
+ showinfo->frame,
+ picref->pts, picref->pts * av_q2d(inlink->time_base), picref->pos,
+ av_pix_fmt_descriptors[picref->format].name,
+ picref->video->pixel_aspect.num, picref->video->pixel_aspect.den,
+ picref->video->w, picref->video->h,
+ !picref->video->interlaced ? 'P' : /* Progressive */
+ picref->video->top_field_first ? 'T' : 'B', /* Top / Bottom */
+ picref->video->key_frame,
+ av_get_picture_type_char(picref->video->pict_type),
+ checksum, plane_checksum[0], plane_checksum[1], plane_checksum[2], plane_checksum[3]);
+
+ showinfo->frame++;
+ avfilter_end_frame(inlink->dst->outputs[0]);
+}
+
+AVFilter avfilter_vf_showinfo = {
+ .name = "showinfo",
+ .description = NULL_IF_CONFIG_SMALL("Show textual information for each video frame."),
+
+ .priv_size = sizeof(ShowInfoContext),
+ .init = init,
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .get_video_buffer = avfilter_null_get_video_buffer,
+ .start_frame = avfilter_null_start_frame,
+ .end_frame = end_frame,
+ .min_perms = AV_PERM_READ, },
+ { .name = NULL}},
+
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO },
+ { .name = NULL}},
+};
diff --git a/libavfilter/vf_split.c b/libavfilter/vf_split.c
new file mode 100644
index 0000000..54fdd21
--- /dev/null
+++ b/libavfilter/vf_split.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2007 Bobby Bingham
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Video splitter
+ */
+
+#include "avfilter.h"
+
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+ avfilter_start_frame(inlink->dst->outputs[0],
+ avfilter_ref_buffer(picref, ~AV_PERM_WRITE));
+ avfilter_start_frame(inlink->dst->outputs[1],
+ avfilter_ref_buffer(picref, ~AV_PERM_WRITE));
+}
+
+static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+ avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
+ avfilter_draw_slice(inlink->dst->outputs[1], y, h, slice_dir);
+}
+
+static void end_frame(AVFilterLink *inlink)
+{
+ avfilter_end_frame(inlink->dst->outputs[0]);
+ avfilter_end_frame(inlink->dst->outputs[1]);
+
+ avfilter_unref_buffer(inlink->cur_buf);
+}
+
+AVFilter avfilter_vf_split = {
+ .name = "split",
+ .description = NULL_IF_CONFIG_SMALL("Pass on the input to two outputs."),
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .get_video_buffer= avfilter_null_get_video_buffer,
+ .start_frame = start_frame,
+ .draw_slice = draw_slice,
+ .end_frame = end_frame, },
+ { .name = NULL}},
+ .outputs = (AVFilterPad[]) {{ .name = "output1",
+ .type = AVMEDIA_TYPE_VIDEO, },
+ { .name = "output2",
+ .type = AVMEDIA_TYPE_VIDEO, },
+ { .name = NULL}},
+};
diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c
index 274b13c..a40df13 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -44,8 +44,8 @@
#define MIN_SIZE 3
#define MAX_SIZE 13
-#define CHROMA_WIDTH(link) -((-link->w) >> av_pix_fmt_descriptors[link->format].log2_chroma_w)
-#define CHROMA_HEIGHT(link) -((-link->h) >> av_pix_fmt_descriptors[link->format].log2_chroma_h)
+/* right-shift and round-up */
+#define SHIFTUP(x,shift) (-((-(x))>>(shift)))
typedef struct FilterParam {
int msize_x; ///< matrix width
@@ -61,15 +61,19 @@ typedef struct FilterParam {
typedef struct {
FilterParam luma; ///< luma parameters (width, height, amount)
FilterParam chroma; ///< chroma parameters (width, height, amount)
+ int hsub, vsub;
} UnsharpContext;
-static void unsharpen(uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, FilterParam *fp)
+static void apply_unsharp( uint8_t *dst, int dst_stride,
+ const uint8_t *src, int src_stride,
+ int width, int height, FilterParam *fp)
{
uint32_t **sc = fp->sc;
uint32_t sr[(MAX_SIZE * MAX_SIZE) - 1], tmp1, tmp2;
int32_t res;
int x, y, z;
+ const uint8_t *src2;
if (!fp->amount) {
if (dst_stride == src_stride)
@@ -84,9 +88,12 @@ static void unsharpen(uint8_t *dst, uint8_t *src, int dst_stride, int src_stride
memset(sc[y], 0, sizeof(sc[y][0]) * (width + 2 * fp->steps_x));
for (y = -fp->steps_y; y < height + fp->steps_y; y++) {
+ if (y < height)
+ src2 = src;
+
memset(sr, 0, sizeof(sr[0]) * (2 * fp->steps_x - 1));
for (x = -fp->steps_x; x < width + fp->steps_x; x++) {
- tmp1 = x <= 0 ? src[0] : x >= width ? src[width-1] : src[x];
+ tmp1 = x <= 0 ? src2[0] : x >= width ? src2[width-1] : src2[x];
for (z = 0; z < fp->steps_x * 2; z += 2) {
tmp2 = sr[z + 0] + tmp1; sr[z + 0] = tmp1;
tmp1 = sr[z + 1] + tmp2; sr[z + 1] = tmp2;
@@ -125,8 +132,8 @@ static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, double a
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
{
UnsharpContext *unsharp = ctx->priv;
- int lmsize_x = 5, cmsize_x = 0;
- int lmsize_y = 5, cmsize_y = 0;
+ int lmsize_x = 5, cmsize_x = 5;
+ int lmsize_y = 5, cmsize_y = 5;
double lamount = 1.0f, camount = 0.0f;
if (args)
@@ -178,8 +185,11 @@ static int config_props(AVFilterLink *link)
{
UnsharpContext *unsharp = link->dst->priv;
+ unsharp->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w;
+ unsharp->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
+
init_filter_param(link->dst, &unsharp->luma, "luma", link->w);
- init_filter_param(link->dst, &unsharp->chroma, "chroma", CHROMA_WIDTH(link));
+ init_filter_param(link->dst, &unsharp->chroma, "chroma", SHIFTUP(link->w, unsharp->hsub));
return 0;
}
@@ -205,10 +215,12 @@ static void end_frame(AVFilterLink *link)
UnsharpContext *unsharp = link->dst->priv;
AVFilterBufferRef *in = link->cur_buf;
AVFilterBufferRef *out = link->dst->outputs[0]->out_buf;
+ int cw = SHIFTUP(link->w, unsharp->hsub);
+ int ch = SHIFTUP(link->h, unsharp->vsub);
- unsharpen(out->data[0], in->data[0], out->linesize[0], in->linesize[0], link->w, link->h, &unsharp->luma);
- unsharpen(out->data[1], in->data[1], out->linesize[1], in->linesize[1], CHROMA_WIDTH(link), CHROMA_HEIGHT(link), &unsharp->chroma);
- unsharpen(out->data[2], in->data[2], out->linesize[2], in->linesize[2], CHROMA_WIDTH(link), CHROMA_HEIGHT(link), &unsharp->chroma);
+ apply_unsharp(out->data[0], out->linesize[0], in->data[0], in->linesize[0], link->w, link->h, &unsharp->luma);
+ apply_unsharp(out->data[1], out->linesize[1], in->data[1], in->linesize[1], cw, ch, &unsharp->chroma);
+ apply_unsharp(out->data[2], out->linesize[2], in->data[2], in->linesize[2], cw, ch, &unsharp->chroma);
avfilter_unref_buffer(in);
avfilter_draw_slice(link->dst->outputs[0], 0, link->h, 1);
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index 42a7219..ca2adb2 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -38,14 +38,20 @@ typedef struct {
int mode;
/**
- * 0: bottom field first
- * 1: top field first
+ * 0: top field first
+ * 1: bottom field first
* -1: auto-detection
*/
int parity;
int frame_pending;
+ /**
+ * 0: deinterlace all frames
+ * 1: only deinterlace frames marked as interlaced
+ */
+ int auto_enable;
+
AVFilterBufferRef *cur;
AVFilterBufferRef *next;
AVFilterBufferRef *prev;
@@ -139,9 +145,9 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic,
int w = dstpic->video->w;
int h = dstpic->video->h;
int refs = yadif->cur->linesize[i];
- int df = (yadif->csp->comp[i].depth_minus1+1) / 8;
+ int df = (yadif->csp->comp[i].depth_minus1 + 8) / 8;
- if (i) {
+ if (i == 1 || i == 2) {
/* Why is this not part of the per-plane description thing? */
w >>= yadif->csp->log2_chroma_w;
h >>= yadif->csp->log2_chroma_h;
@@ -197,13 +203,16 @@ static void return_frame(AVFilterContext *ctx, int is_second)
tff = yadif->parity^1;
}
- if (is_second)
+ if (is_second) {
yadif->out = avfilter_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE |
AV_PERM_REUSE, link->w, link->h);
+ avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);
+ yadif->out->video->interlaced = 0;
+ }
if (!yadif->csp)
yadif->csp = &av_pix_fmt_descriptors[link->format];
- if (yadif->csp->comp[0].depth_minus1 == 15)
+ if (yadif->csp->comp[0].depth_minus1 / 8 == 1)
yadif->filter_line = filter_line_c_16bit;
filter(ctx, yadif->out, tff ^ !is_second, tff);
@@ -242,6 +251,14 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
if (!yadif->cur)
return;
+ if (yadif->auto_enable && !yadif->cur->video->interlaced) {
+ yadif->out = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);
+ avfilter_unref_buffer(yadif->prev);
+ yadif->prev = NULL;
+ avfilter_start_frame(ctx->outputs[0], yadif->out);
+ return;
+ }
+
if (!yadif->prev)
yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);
@@ -261,6 +278,12 @@ static void end_frame(AVFilterLink *link)
if (!yadif->out)
return;
+ if (yadif->auto_enable && !yadif->cur->video->interlaced) {
+ avfilter_draw_slice(ctx->outputs[0], 0, link->h, 1);
+ avfilter_end_frame(ctx->outputs[0]);
+ return;
+ }
+
return_frame(ctx, 0);
}
@@ -301,6 +324,9 @@ static int poll_frame(AVFilterLink *link)
}
assert(yadif->next || !val);
+ if (yadif->auto_enable && yadif->next && !yadif->next->video->interlaced)
+ return val;
+
return val * ((yadif->mode&1)+1);
}
@@ -328,9 +354,13 @@ static int query_formats(AVFilterContext *ctx)
AV_NE( PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE ),
PIX_FMT_YUV440P,
PIX_FMT_YUVJ440P,
+ AV_NE( PIX_FMT_YUV420P10BE, PIX_FMT_YUV420P10LE ),
+ AV_NE( PIX_FMT_YUV422P10BE, PIX_FMT_YUV422P10LE ),
+ AV_NE( PIX_FMT_YUV444P10BE, PIX_FMT_YUV444P10LE ),
AV_NE( PIX_FMT_YUV420P16BE, PIX_FMT_YUV420P16LE ),
AV_NE( PIX_FMT_YUV422P16BE, PIX_FMT_YUV422P16LE ),
AV_NE( PIX_FMT_YUV444P16BE, PIX_FMT_YUV444P16LE ),
+ PIX_FMT_YUVA420P,
PIX_FMT_NONE
};
@@ -346,9 +376,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
yadif->mode = 0;
yadif->parity = -1;
+ yadif->auto_enable = 0;
yadif->csp = NULL;
- if (args) sscanf(args, "%d:%d", &yadif->mode, &yadif->parity);
+ if (args) sscanf(args, "%d:%d:%d", &yadif->mode, &yadif->parity, &yadif->auto_enable);
yadif->filter_line = filter_line_c;
if (HAVE_SSSE3 && cpu_flags & AV_CPU_FLAG_SSSE3)
@@ -358,7 +389,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX)
yadif->filter_line = ff_yadif_filter_line_mmx;
- av_log(ctx, AV_LOG_INFO, "mode:%d parity:%d\n", yadif->mode, yadif->parity);
+ av_log(ctx, AV_LOG_INFO, "mode:%d parity:%d auto_enable:%d\n", yadif->mode, yadif->parity, yadif->auto_enable);
return 0;
}
diff --git a/libavfilter/vsrc_buffer.c b/libavfilter/vsrc_buffer.c
index 1f0233e..7ef19a1 100644
--- a/libavfilter/vsrc_buffer.c
+++ b/libavfilter/vsrc_buffer.c
@@ -24,13 +24,12 @@
*/
#include "avfilter.h"
+#include "buffersrc.h"
#include "vsrc_buffer.h"
#include "libavutil/imgutils.h"
typedef struct {
- int64_t pts;
- AVFrame frame;
- int has_frame;
+ AVFilterBufferRef *buf;
int h, w;
enum PixelFormat pix_fmt;
AVRational time_base; ///< time_base to set in the output link
@@ -42,7 +41,7 @@ int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame,
{
BufferSourceContext *c = buffer_filter->priv;
- if (c->has_frame) {
+ if (c->buf) {
av_log(buffer_filter, AV_LOG_ERROR,
"Buffering several frames is not supported. "
"Please consume all available frames before adding a new one.\n"
@@ -50,15 +49,31 @@ int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame,
//return -1;
}
- memcpy(c->frame.data , frame->data , sizeof(frame->data));
- memcpy(c->frame.linesize, frame->linesize, sizeof(frame->linesize));
- c->frame.interlaced_frame= frame->interlaced_frame;
- c->frame.top_field_first = frame->top_field_first;
- c->frame.key_frame = frame->key_frame;
- c->frame.pict_type = frame->pict_type;
- c->pts = pts;
- c->pixel_aspect = pixel_aspect;
- c->has_frame = 1;
+ c->buf = avfilter_get_video_buffer(buffer_filter->outputs[0], AV_PERM_WRITE,
+ c->w, c->h);
+ av_image_copy(c->buf->data, c->buf->linesize, frame->data, frame->linesize,
+ c->pix_fmt, c->w, c->h);
+
+ avfilter_copy_frame_props(c->buf, frame);
+ c->buf->pts = pts;
+ c->buf->video->pixel_aspect = pixel_aspect;
+
+ return 0;
+}
+
+int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
+{
+ BufferSourceContext *c = s->priv;
+
+ if (c->buf) {
+ av_log(s, AV_LOG_ERROR,
+ "Buffering several frames is not supported. "
+ "Please consume all available frames before adding a new one.\n"
+ );
+ return AVERROR(EINVAL);
+ }
+
+ c->buf = buf;
return 0;
}
@@ -113,36 +128,18 @@ static int config_props(AVFilterLink *link)
static int request_frame(AVFilterLink *link)
{
BufferSourceContext *c = link->src->priv;
- AVFilterBufferRef *picref;
- if (!c->has_frame) {
+ if (!c->buf) {
av_log(link->src, AV_LOG_ERROR,
"request_frame() called with no available frame!\n");
//return -1;
}
- /* This picture will be needed unmodified later for decoding the next
- * frame */
- picref = avfilter_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE |
- AV_PERM_REUSE2,
- link->w, link->h);
-
- av_image_copy(picref->data, picref->linesize,
- c->frame.data, c->frame.linesize,
- picref->format, link->w, link->h);
-
- picref->pts = c->pts;
- picref->video->pixel_aspect = c->pixel_aspect;
- picref->video->interlaced = c->frame.interlaced_frame;
- picref->video->top_field_first = c->frame.top_field_first;
- picref->video->key_frame = c->frame.key_frame;
- picref->video->pict_type = c->frame.pict_type;
- avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0));
+ avfilter_start_frame(link, avfilter_ref_buffer(c->buf, ~0));
avfilter_draw_slice(link, 0, link->h, 1);
avfilter_end_frame(link);
- avfilter_unref_buffer(picref);
-
- c->has_frame = 0;
+ avfilter_unref_buffer(c->buf);
+ c->buf = NULL;
return 0;
}
@@ -150,7 +147,7 @@ static int request_frame(AVFilterLink *link)
static int poll_frame(AVFilterLink *link)
{
BufferSourceContext *c = link->src->priv;
- return !!(c->has_frame);
+ return !!(c->buf);
}
AVFilter avfilter_vsrc_buffer = {
diff --git a/libavfilter/vsrc_buffer.h b/libavfilter/vsrc_buffer.h
index cfaf791..13a209c 100644
--- a/libavfilter/vsrc_buffer.h
+++ b/libavfilter/vsrc_buffer.h
@@ -1,5 +1,4 @@
/*
- * Memory buffer source filter
* Copyright (c) 2008 Vitor Sessak
*
* This file is part of Libav.
diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c
index 6d41c8a..94b5a29 100644
--- a/libavfilter/vsrc_color.c
+++ b/libavfilter/vsrc_color.c
@@ -18,10 +18,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * color source
+ */
+
#include "avfilter.h"
#include "libavutil/pixdesc.h"
#include "libavutil/colorspace.h"
#include "libavutil/imgutils.h"
+#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
#include "drawutils.h"
@@ -124,6 +130,7 @@ static int color_config_props(AVFilterLink *inlink)
is_packed_rgba ? "rgba" : "yuva");
inlink->w = color->w;
inlink->h = color->h;
+ inlink->time_base = color->time_base;
return 0;
}
@@ -133,8 +140,8 @@ static int color_request_frame(AVFilterLink *link)
ColorContext *color = link->src->priv;
AVFilterBufferRef *picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h);
picref->video->pixel_aspect = (AVRational) {1, 1};
- picref->pts = av_rescale_q(color->pts++, color->time_base, AV_TIME_BASE_Q);
- picref->pos = 0;
+ picref->pts = color->pts++;
+ picref->pos = -1;
avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0));
ff_draw_rectangle(picref->data, picref->linesize,
diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c
index b018ba7..4ac079c 100644
--- a/libavfilter/vsrc_movie.c
+++ b/libavfilter/vsrc_movie.c
@@ -57,12 +57,12 @@ typedef struct {
#define OFFSET(x) offsetof(MovieContext, x)
static const AVOption movie_options[]= {
-{"format_name", "set format name", OFFSET(format_name), FF_OPT_TYPE_STRING, {.str = 0}, CHAR_MIN, CHAR_MAX },
-{"f", "set format name", OFFSET(format_name), FF_OPT_TYPE_STRING, {.str = 0}, CHAR_MIN, CHAR_MAX },
-{"stream_index", "set stream index", OFFSET(stream_index), FF_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX },
-{"si", "set stream index", OFFSET(stream_index), FF_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX },
-{"seek_point", "set seekpoint (seconds)", OFFSET(seek_point_d), FF_OPT_TYPE_DOUBLE, {.dbl = 0}, 0, (INT64_MAX-1) / 1000000 },
-{"sp", "set seekpoint (seconds)", OFFSET(seek_point_d), FF_OPT_TYPE_DOUBLE, {.dbl = 0}, 0, (INT64_MAX-1) / 1000000 },
+{"format_name", "set format name", OFFSET(format_name), AV_OPT_TYPE_STRING, {.str = 0}, CHAR_MIN, CHAR_MAX },
+{"f", "set format name", OFFSET(format_name), AV_OPT_TYPE_STRING, {.str = 0}, CHAR_MIN, CHAR_MAX },
+{"stream_index", "set stream index", OFFSET(stream_index), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX },
+{"si", "set stream index", OFFSET(stream_index), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX },
+{"seek_point", "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, 0, (INT64_MAX-1) / 1000000 },
+{"sp", "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, 0, (INT64_MAX-1) / 1000000 },
{NULL},
};
@@ -164,7 +164,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
MovieContext *movie = ctx->priv;
int ret;
movie->class = &movie_class;
- av_opt_set_defaults2(movie, 0, 0);
+ av_opt_set_defaults(movie);
if (args)
movie->file_name = av_get_token(&args, ":");
@@ -192,7 +192,7 @@ static av_cold void uninit(AVFilterContext *ctx)
if (movie->codec_ctx)
avcodec_close(movie->codec_ctx);
if (movie->format_ctx)
- av_close_input_file(movie->format_ctx);
+ avformat_close_input(&movie->format_ctx);
avfilter_unref_buffer(movie->picref);
av_freep(&movie->frame);
}
@@ -240,6 +240,7 @@ static int movie_get_frame(AVFilterLink *outlink)
av_image_copy(movie->picref->data, movie->picref->linesize,
movie->frame->data, movie->frame->linesize,
movie->picref->format, outlink->w, outlink->h);
+ avfilter_copy_frame_props(movie->picref, movie->frame);
/* FIXME: use a PTS correction mechanism as that in
* ffplay.c when some API will be available for that */
@@ -248,12 +249,8 @@ static int movie_get_frame(AVFilterLink *outlink)
movie->frame->pkt_dts : movie->frame->pkt_pts;
movie->picref->pos = movie->frame->reordered_opaque;
- movie->picref->video->pixel_aspect = st->sample_aspect_ratio.num ?
- st->sample_aspect_ratio : movie->codec_ctx->sample_aspect_ratio;
- movie->picref->video->interlaced = movie->frame->interlaced_frame;
- movie->picref->video->top_field_first = movie->frame->top_field_first;
- movie->picref->video->key_frame = movie->frame->key_frame;
- movie->picref->video->pict_type = movie->frame->pict_type;
+ if (!movie->frame->sample_aspect_ratio.num)
+ movie->picref->video->pixel_aspect = st->sample_aspect_ratio;
av_dlog(outlink->src,
"movie_get_frame(): file:'%s' pts:%"PRId64" time:%lf pos:%"PRId64" aspect:%d/%d\n",
movie->file_name, movie->picref->pts,
diff --git a/libavfilter/vsrc_nullsrc.c b/libavfilter/vsrc_nullsrc.c
index 629de78..dfd56fa 100644
--- a/libavfilter/vsrc_nullsrc.c
+++ b/libavfilter/vsrc_nullsrc.c
@@ -23,6 +23,7 @@
#include "libavutil/avstring.h"
#include "libavutil/eval.h"
+#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
#include "avfilter.h"
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
new file mode 100644
index 0000000..0f5596b
--- /dev/null
+++ b/libavfilter/vsrc_testsrc.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2007 Nicolas George <nicolas.george at normalesup.org>
+ * Copyright (c) 2011 Stefano Sabatini
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Misc test sources.
+ *
+ * testsrc is based on the test pattern generator demuxer by Nicolas George:
+ * http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2007-October/037845.html
+ *
+ * rgbtestsrc is ported from MPlayer libmpcodecs/vf_rgbtest.c by
+ * Michael Niedermayer.
+ */
+
+#include <float.h>
+
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/parseutils.h"
+#include "avfilter.h"
+
+typedef struct {
+ const AVClass *class;
+ int h, w;
+ unsigned int nb_frame;
+ AVRational time_base;
+ int64_t pts, max_pts;
+ char *size; ///< video frame size
+ char *rate; ///< video frame rate
+ char *duration; ///< total duration of the generated video
+ AVRational sar; ///< sample aspect ratio
+
+ void (* fill_picture_fn)(AVFilterContext *ctx, AVFilterBufferRef *picref);
+
+ /* only used by rgbtest */
+ int rgba_map[4];
+} TestSourceContext;
+
+#define OFFSET(x) offsetof(TestSourceContext, x)
+
+static const AVOption testsrc_options[] = {
+ { "size", "set video size", OFFSET(size), FF_OPT_TYPE_STRING, {.str = "320x240"}},
+ { "s", "set video size", OFFSET(size), FF_OPT_TYPE_STRING, {.str = "320x240"}},
+ { "rate", "set video rate", OFFSET(rate), FF_OPT_TYPE_STRING, {.str = "25"}, },
+ { "r", "set video rate", OFFSET(rate), FF_OPT_TYPE_STRING, {.str = "25"}, },
+ { "duration", "set video duration", OFFSET(duration), FF_OPT_TYPE_STRING, {.str = NULL}, },
+ { "sar", "set video sample aspect ratio", OFFSET(sar), FF_OPT_TYPE_RATIONAL, {1}, 0, INT_MAX },
+ { NULL },
+};
+
+static av_cold int init_common(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ TestSourceContext *test = ctx->priv;
+ AVRational frame_rate_q;
+ int64_t duration = -1;
+ int ret = 0;
+
+ av_opt_set_defaults(test);
+
+ if ((ret = (av_set_options_string(test, args, "=", ":"))) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
+ return ret;
+ }
+
+ if ((ret = av_parse_video_size(&test->w, &test->h, test->size)) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", test->size);
+ return ret;
+ }
+
+ if ((ret = av_parse_video_rate(&frame_rate_q, test->rate)) < 0 ||
+ frame_rate_q.den <= 0 || frame_rate_q.num <= 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", test->rate);
+ return ret;
+ }
+
+ if ((test->duration) && (ret = av_parse_time(&duration, test->duration, 1)) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid duration: '%s'\n", test->duration);
+ return ret;
+ }
+
+ test->time_base.num = frame_rate_q.den;
+ test->time_base.den = frame_rate_q.num;
+ test->max_pts = duration >= 0 ?
+ av_rescale_q(duration, AV_TIME_BASE_Q, test->time_base) : -1;
+ test->nb_frame = 0;
+ test->pts = 0;
+
+ av_log(ctx, AV_LOG_DEBUG, "size:%dx%d rate:%d/%d duration:%f sar:%d/%d\n",
+ test->w, test->h, frame_rate_q.num, frame_rate_q.den,
+ duration < 0 ? -1 : test->max_pts * av_q2d(test->time_base),
+ test->sar.num, test->sar.den);
+ return 0;
+}
+
+static int config_props(AVFilterLink *outlink)
+{
+ TestSourceContext *test = outlink->src->priv;
+
+ outlink->w = test->w;
+ outlink->h = test->h;
+ outlink->sample_aspect_ratio = test->sar;
+ outlink->time_base = test->time_base;
+
+ return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+ TestSourceContext *test = outlink->src->priv;
+ AVFilterBufferRef *picref;
+
+ if (test->max_pts >= 0 && test->pts > test->max_pts)
+ return AVERROR_EOF;
+ picref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,
+ test->w, test->h);
+ picref->pts = test->pts++;
+ picref->pos = -1;
+ picref->video->key_frame = 1;
+ picref->video->interlaced = 0;
+ picref->video->pict_type = AV_PICTURE_TYPE_I;
+ picref->video->pixel_aspect = test->sar;
+ test->nb_frame++;
+ test->fill_picture_fn(outlink->src, picref);
+
+ avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
+ avfilter_draw_slice(outlink, 0, picref->video->h, 1);
+ avfilter_end_frame(outlink);
+ avfilter_unref_buffer(picref);
+
+ return 0;
+}
+
+#if CONFIG_TESTSRC_FILTER
+
+static const char *testsrc_get_name(void *ctx)
+{
+ return "testsrc";
+}
+
+static const AVClass testsrc_class = {
+ .class_name = "TestSourceContext",
+ .item_name = testsrc_get_name,
+ .option = testsrc_options,
+};
+
+/**
+ * Fill a rectangle with value val.
+ *
+ * @param val the RGB value to set
+ * @param dst pointer to the destination buffer to fill
+ * @param dst_linesize linesize of destination
+ * @param segment_width width of the segment
+ * @param x horizontal coordinate where to draw the rectangle in the destination buffer
+ * @param y horizontal coordinate where to draw the rectangle in the destination buffer
+ * @param w width of the rectangle to draw, expressed as a number of segment_width units
+ * @param h height of the rectangle to draw, expressed as a number of segment_width units
+ */
+static void draw_rectangle(unsigned val, uint8_t *dst, int dst_linesize, unsigned segment_width,
+ unsigned x, unsigned y, unsigned w, unsigned h)
+{
+ int i;
+ int step = 3;
+
+ dst += segment_width * (step * x + y * dst_linesize);
+ w *= segment_width * step;
+ h *= segment_width;
+ for (i = 0; i < h; i++) {
+ memset(dst, val, w);
+ dst += dst_linesize;
+ }
+}
+
+static void draw_digit(int digit, uint8_t *dst, unsigned dst_linesize,
+ unsigned segment_width)
+{
+#define TOP_HBAR 1
+#define MID_HBAR 2
+#define BOT_HBAR 4
+#define LEFT_TOP_VBAR 8
+#define LEFT_BOT_VBAR 16
+#define RIGHT_TOP_VBAR 32
+#define RIGHT_BOT_VBAR 64
+ struct {
+ int x, y, w, h;
+ } segments[] = {
+ { 1, 0, 5, 1 }, /* TOP_HBAR */
+ { 1, 6, 5, 1 }, /* MID_HBAR */
+ { 1, 12, 5, 1 }, /* BOT_HBAR */
+ { 0, 1, 1, 5 }, /* LEFT_TOP_VBAR */
+ { 0, 7, 1, 5 }, /* LEFT_BOT_VBAR */
+ { 6, 1, 1, 5 }, /* RIGHT_TOP_VBAR */
+ { 6, 7, 1, 5 } /* RIGHT_BOT_VBAR */
+ };
+ static const unsigned char masks[10] = {
+ /* 0 */ TOP_HBAR |BOT_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
+ /* 1 */ RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
+ /* 2 */ TOP_HBAR|MID_HBAR|BOT_HBAR|LEFT_BOT_VBAR |RIGHT_TOP_VBAR,
+ /* 3 */ TOP_HBAR|MID_HBAR|BOT_HBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
+ /* 4 */ MID_HBAR |LEFT_TOP_VBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
+ /* 5 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR |RIGHT_BOT_VBAR,
+ /* 6 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR |RIGHT_BOT_VBAR,
+ /* 7 */ TOP_HBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
+ /* 8 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
+ /* 9 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,
+ };
+ unsigned mask = masks[digit];
+ int i;
+
+ draw_rectangle(0, dst, dst_linesize, segment_width, 0, 0, 8, 13);
+ for (i = 0; i < FF_ARRAY_ELEMS(segments); i++)
+ if (mask & (1<<i))
+ draw_rectangle(255, dst, dst_linesize, segment_width,
+ segments[i].x, segments[i].y, segments[i].w, segments[i].h);
+}
+
+#define GRADIENT_SIZE (6 * 256)
+
+static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
+{
+ TestSourceContext *test = ctx->priv;
+ uint8_t *p, *p0;
+ int x, y;
+ int color, color_rest;
+ int icolor;
+ int radius;
+ int quad0, quad;
+ int dquad_x, dquad_y;
+ int grad, dgrad, rgrad, drgrad;
+ int seg_size;
+ int second;
+ int i;
+ uint8_t *data = picref->data[0];
+ int width = picref->video->w;
+ int height = picref->video->h;
+
+ /* draw colored bars and circle */
+ radius = (width + height) / 4;
+ quad0 = width * width / 4 + height * height / 4 - radius * radius;
+ dquad_y = 1 - height;
+ p0 = data;
+ for (y = 0; y < height; y++) {
+ p = p0;
+ color = 0;
+ color_rest = 0;
+ quad = quad0;
+ dquad_x = 1 - width;
+ for (x = 0; x < width; x++) {
+ icolor = color;
+ if (quad < 0)
+ icolor ^= 7;
+ quad += dquad_x;
+ dquad_x += 2;
+ *(p++) = icolor & 1 ? 255 : 0;
+ *(p++) = icolor & 2 ? 255 : 0;
+ *(p++) = icolor & 4 ? 255 : 0;
+ color_rest += 8;
+ if (color_rest >= width) {
+ color_rest -= width;
+ color++;
+ }
+ }
+ quad0 += dquad_y;
+ dquad_y += 2;
+ p0 += picref->linesize[0];
+ }
+
+ /* draw sliding color line */
+ p = data + picref->linesize[0] * height * 3/4;
+ grad = (256 * test->nb_frame * test->time_base.num / test->time_base.den) %
+ GRADIENT_SIZE;
+ rgrad = 0;
+ dgrad = GRADIENT_SIZE / width;
+ drgrad = GRADIENT_SIZE % width;
+ for (x = 0; x < width; x++) {
+ *(p++) =
+ grad < 256 || grad >= 5 * 256 ? 255 :
+ grad >= 2 * 256 && grad < 4 * 256 ? 0 :
+ grad < 2 * 256 ? 2 * 256 - 1 - grad : grad - 4 * 256;
+ *(p++) =
+ grad >= 4 * 256 ? 0 :
+ grad >= 1 * 256 && grad < 3 * 256 ? 255 :
+ grad < 1 * 256 ? grad : 4 * 256 - 1 - grad;
+ *(p++) =
+ grad < 2 * 256 ? 0 :
+ grad >= 3 * 256 && grad < 5 * 256 ? 255 :
+ grad < 3 * 256 ? grad - 2 * 256 : 6 * 256 - 1 - grad;
+ grad += dgrad;
+ rgrad += drgrad;
+ if (rgrad >= GRADIENT_SIZE) {
+ grad++;
+ rgrad -= GRADIENT_SIZE;
+ }
+ if (grad >= GRADIENT_SIZE)
+ grad -= GRADIENT_SIZE;
+ }
+ for (y = height / 8; y > 0; y--) {
+ memcpy(p, p - picref->linesize[0], 3 * width);
+ p += picref->linesize[0];
+ }
+
+ /* draw digits */
+ seg_size = width / 80;
+ if (seg_size >= 1 && height >= 13 * seg_size) {
+ second = test->nb_frame * test->time_base.num / test->time_base.den;
+ x = width - (width - seg_size * 64) / 2;
+ y = (height - seg_size * 13) / 2;
+ p = data + (x*3 + y * picref->linesize[0]);
+ for (i = 0; i < 8; i++) {
+ p -= 3 * 8 * seg_size;
+ draw_digit(second % 10, p, picref->linesize[0], seg_size);
+ second /= 10;
+ if (second == 0)
+ break;
+ }
+ }
+}
+
+static av_cold int test_init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ TestSourceContext *test = ctx->priv;
+
+ test->class = &testsrc_class;
+ test->fill_picture_fn = test_fill_picture;
+ return init_common(ctx, args, opaque);
+}
+
+static int test_query_formats(AVFilterContext *ctx)
+{
+ static const enum PixelFormat pix_fmts[] = {
+ PIX_FMT_RGB24, PIX_FMT_NONE
+ };
+ avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ return 0;
+}
+
+AVFilter avfilter_vsrc_testsrc = {
+ .name = "testsrc",
+ .description = NULL_IF_CONFIG_SMALL("Generate test pattern."),
+ .priv_size = sizeof(TestSourceContext),
+ .init = test_init,
+
+ .query_formats = test_query_formats,
+
+ .inputs = (AVFilterPad[]) {{ .name = NULL}},
+
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .request_frame = request_frame,
+ .config_props = config_props, },
+ { .name = NULL }},
+};
+
+#endif /* CONFIG_TESTSRC_FILTER */
+
+#if CONFIG_RGBTESTSRC_FILTER
+
+static const char *rgbtestsrc_get_name(void *ctx)
+{
+ return "rgbtestsrc";
+}
+
+static const AVClass rgbtestsrc_class = {
+ .class_name = "RGBTestSourceContext",
+ .item_name = rgbtestsrc_get_name,
+ .option = testsrc_options,
+};
+
+#define R 0
+#define G 1
+#define B 2
+#define A 3
+
+static void rgbtest_put_pixel(uint8_t *dst, int dst_linesize,
+ int x, int y, int r, int g, int b, enum PixelFormat fmt,
+ int rgba_map[4])
+{
+ int32_t v;
+ uint8_t *p;
+
+ switch (fmt) {
+ case PIX_FMT_BGR444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4); break;
+ case PIX_FMT_RGB444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b >> 4) << 8) | ((g >> 4) << 4) | (r >> 4); break;
+ case PIX_FMT_BGR555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<10) | ((g>>3)<<5) | (b>>3); break;
+ case PIX_FMT_RGB555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<10) | ((g>>3)<<5) | (r>>3); break;
+ case PIX_FMT_BGR565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<11) | ((g>>2)<<5) | (b>>3); break;
+ case PIX_FMT_RGB565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<11) | ((g>>2)<<5) | (r>>3); break;
+ case PIX_FMT_RGB24:
+ case PIX_FMT_BGR24:
+ v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8));
+ p = dst + 3*x + y*dst_linesize;
+ AV_WL24(p, v);
+ break;
+ case PIX_FMT_RGBA:
+ case PIX_FMT_BGRA:
+ case PIX_FMT_ARGB:
+ case PIX_FMT_ABGR:
+ v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8));
+ p = dst + 4*x + y*dst_linesize;
+ AV_WL32(p, v);
+ break;
+ }
+}
+
+static void rgbtest_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
+{
+ TestSourceContext *test = ctx->priv;
+ int x, y, w = picref->video->w, h = picref->video->h;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < picref->video->w; x++) {
+ int c = 256*x/w;
+ int r = 0, g = 0, b = 0;
+
+ if (3*y < h ) r = c;
+ else if (3*y < 2*h) g = c;
+ else b = c;
+
+ rgbtest_put_pixel(picref->data[0], picref->linesize[0], x, y, r, g, b,
+ ctx->outputs[0]->format, test->rgba_map);
+ }
+ }
+}
+
+static av_cold int rgbtest_init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ TestSourceContext *test = ctx->priv;
+
+ test->class = &rgbtestsrc_class;
+ test->fill_picture_fn = rgbtest_fill_picture;
+ return init_common(ctx, args, opaque);
+}
+
+static int rgbtest_query_formats(AVFilterContext *ctx)
+{
+ static const enum PixelFormat pix_fmts[] = {
+ PIX_FMT_RGBA, PIX_FMT_ARGB, PIX_FMT_BGRA, PIX_FMT_ABGR,
+ PIX_FMT_BGR24, PIX_FMT_RGB24,
+ PIX_FMT_RGB444, PIX_FMT_BGR444,
+ PIX_FMT_RGB565, PIX_FMT_BGR565,
+ PIX_FMT_RGB555, PIX_FMT_BGR555,
+ PIX_FMT_NONE
+ };
+ avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+ return 0;
+}
+
+static int rgbtest_config_props(AVFilterLink *outlink)
+{
+ TestSourceContext *test = outlink->src->priv;
+
+ switch (outlink->format) {
+ case PIX_FMT_ARGB: test->rgba_map[A] = 0; test->rgba_map[R] = 1; test->rgba_map[G] = 2; test->rgba_map[B] = 3; break;
+ case PIX_FMT_ABGR: test->rgba_map[A] = 0; test->rgba_map[B] = 1; test->rgba_map[G] = 2; test->rgba_map[R] = 3; break;
+ case PIX_FMT_RGBA:
+ case PIX_FMT_RGB24: test->rgba_map[R] = 0; test->rgba_map[G] = 1; test->rgba_map[B] = 2; test->rgba_map[A] = 3; break;
+ case PIX_FMT_BGRA:
+ case PIX_FMT_BGR24: test->rgba_map[B] = 0; test->rgba_map[G] = 1; test->rgba_map[R] = 2; test->rgba_map[A] = 3; break;
+ }
+
+ return config_props(outlink);
+}
+
+AVFilter avfilter_vsrc_rgbtestsrc = {
+ .name = "rgbtestsrc",
+ .description = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."),
+ .priv_size = sizeof(TestSourceContext),
+ .init = rgbtest_init,
+
+ .query_formats = rgbtest_query_formats,
+
+ .inputs = (AVFilterPad[]) {{ .name = NULL}},
+
+ .outputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .request_frame = request_frame,
+ .config_props = rgbtest_config_props, },
+ { .name = NULL }},
+};
+
+#endif /* CONFIG_RGBTESTSRC_FILTER */
diff --git a/libavformat/4xm.c b/libavformat/4xm.c
index 93c90e8..ccbe3ad 100644
--- a/libavformat/4xm.c
+++ b/libavformat/4xm.c
@@ -28,7 +28,9 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
#include "avformat.h"
+#include "internal.h"
#define RIFF_TAG MKTAG('R', 'I', 'F', 'F')
#define FOURXMV_TAG MKTAG('4', 'X', 'M', 'V')
@@ -129,7 +131,7 @@ static int fourxm_read_header(AVFormatContext *s,
size = AV_RL32(&header[i + 4]);
if (fourcc_tag == std__TAG) {
- fourxm->fps = av_int2flt(AV_RL32(&header[i + 12]));
+ fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
} else if (fourcc_tag == vtrk_TAG) {
/* check that there is enough data */
if (size != vtrk_SIZE) {
@@ -140,12 +142,12 @@ static int fourxm_read_header(AVFormatContext *s,
fourxm->height = AV_RL32(&header[i + 40]);
/* allocate a new AVStream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st){
ret= AVERROR(ENOMEM);
goto fail;
}
- av_set_pts_info(st, 60, 1, fourxm->fps);
+ avpriv_set_pts_info(st, 60, 1, fourxm->fps);
fourxm->video_stream_index = st->index;
@@ -172,13 +174,15 @@ static int fourxm_read_header(AVFormatContext *s,
goto fail;
}
if (current_track + 1 > fourxm->track_count) {
- fourxm->track_count = current_track + 1;
fourxm->tracks = av_realloc(fourxm->tracks,
- fourxm->track_count * sizeof(AudioTrack));
+ (current_track + 1) * sizeof(AudioTrack));
if (!fourxm->tracks) {
- ret= AVERROR(ENOMEM);
+ ret = AVERROR(ENOMEM);
goto fail;
}
+ memset(&fourxm->tracks[fourxm->track_count], 0,
+ sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count));
+ fourxm->track_count = current_track + 1;
}
fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);
fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);
@@ -195,13 +199,14 @@ static int fourxm_read_header(AVFormatContext *s,
i += 8 + size;
/* allocate a new AVStream */
- st = av_new_stream(s, current_track);
+ st = avformat_new_stream(s, NULL);
if (!st){
ret= AVERROR(ENOMEM);
goto fail;
}
- av_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);
+ st->id = current_track;
+ avpriv_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);
fourxm->tracks[current_track].stream_index = st->index;
@@ -344,11 +349,11 @@ static int fourxm_read_close(AVFormatContext *s)
}
AVInputFormat ff_fourxm_demuxer = {
- "4xm",
- NULL_IF_CONFIG_SMALL("4X Technologies format"),
- sizeof(FourxmDemuxContext),
- fourxm_probe,
- fourxm_read_header,
- fourxm_read_packet,
- fourxm_read_close,
+ .name = "4xm",
+ .long_name = NULL_IF_CONFIG_SMALL("4X Technologies format"),
+ .priv_data_size = sizeof(FourxmDemuxContext),
+ .read_probe = fourxm_probe,
+ .read_header = fourxm_read_header,
+ .read_packet = fourxm_read_packet,
+ .read_close = fourxm_read_close,
};
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 7a8aba6..de44050 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -1,5 +1,3 @@
-include $(SUBDIR)../config.mak
-
NAME = avformat
FFLIBS = avcodec avutil
@@ -16,11 +14,14 @@ OBJS = allformats.o \
seek.o \
utils.o \
+OBJS-$(CONFIG_NETWORK) += network.o
+
# muxers/demuxers
OBJS-$(CONFIG_A64_MUXER) += a64.o
OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o rawdec.o
OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o
OBJS-$(CONFIG_AC3_MUXER) += rawenc.o
+OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o
OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o
OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o
OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o
@@ -38,16 +39,18 @@ OBJS-$(CONFIG_ASS_DEMUXER) += assdec.o
OBJS-$(CONFIG_ASS_MUXER) += assenc.o
OBJS-$(CONFIG_AU_DEMUXER) += au.o pcm.o
OBJS-$(CONFIG_AU_MUXER) += au.o
-OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o avi.o
-OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o avi.o
+OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o
+OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o
OBJS-$(CONFIG_AVISYNTH) += avisynth.o
OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o
OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o
OBJS-$(CONFIG_BETHSOFTVID_DEMUXER) += bethsoftvid.o
OBJS-$(CONFIG_BFI_DEMUXER) += bfi.o
OBJS-$(CONFIG_BINK_DEMUXER) += bink.o
+OBJS-$(CONFIG_BMV_DEMUXER) += bmv.o
OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o
-OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o riff.o isom.o
+OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o mov_chan.o \
+ riff.o isom.o
OBJS-$(CONFIG_CAVSVIDEO_DEMUXER) += cavsvideodec.o rawdec.o
OBJS-$(CONFIG_CAVSVIDEO_MUXER) += rawenc.o
OBJS-$(CONFIG_CDG_DEMUXER) += cdg.o
@@ -87,7 +90,7 @@ OBJS-$(CONFIG_FOURXM_DEMUXER) += 4xm.o
OBJS-$(CONFIG_FRAMECRC_MUXER) += framecrcenc.o
OBJS-$(CONFIG_FRAMEMD5_MUXER) += md5enc.o
OBJS-$(CONFIG_GIF_MUXER) += gif.o
-OBJS-$(CONFIG_GSM_DEMUXER) += rawdec.o
+OBJS-$(CONFIG_GSM_DEMUXER) += gsmdec.o
OBJS-$(CONFIG_GXF_DEMUXER) += gxf.o
OBJS-$(CONFIG_GXF_MUXER) += gxfenc.o audiointerleave.o
OBJS-$(CONFIG_G722_DEMUXER) += rawdec.o
@@ -111,6 +114,8 @@ OBJS-$(CONFIG_IV8_DEMUXER) += iv8.o
OBJS-$(CONFIG_IVF_DEMUXER) += ivfdec.o riff.o
OBJS-$(CONFIG_IVF_MUXER) += ivfenc.o
OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o
+OBJS-$(CONFIG_LATM_DEMUXER) += rawdec.o
+OBJS-$(CONFIG_LATM_MUXER) += latmenc.o
OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o
OBJS-$(CONFIG_LXF_DEMUXER) += lxfdec.o
OBJS-$(CONFIG_M4V_DEMUXER) += m4vdec.o rawdec.o
@@ -128,12 +133,13 @@ OBJS-$(CONFIG_MLP_MUXER) += rawenc.o
OBJS-$(CONFIG_MM_DEMUXER) += mm.o
OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o pcm.o
OBJS-$(CONFIG_MMF_MUXER) += mmf.o riff.o
-OBJS-$(CONFIG_MOV_DEMUXER) += mov.o riff.o isom.o
+OBJS-$(CONFIG_MOV_DEMUXER) += mov.o riff.o isom.o mov_chan.o
OBJS-$(CONFIG_MOV_MUXER) += movenc.o riff.o isom.o avc.o \
- movenchint.o rtpenc_chain.o
+ movenchint.o rtpenc_chain.o \
+ mov_chan.o
OBJS-$(CONFIG_MP2_MUXER) += mp3enc.o rawenc.o
OBJS-$(CONFIG_MP3_DEMUXER) += mp3dec.o
-OBJS-$(CONFIG_MP3_MUXER) += mp3enc.o rawenc.o
+OBJS-$(CONFIG_MP3_MUXER) += mp3enc.o rawenc.o id3v2enc.o
OBJS-$(CONFIG_MPC_DEMUXER) += mpc.o apetag.o
OBJS-$(CONFIG_MPC8_DEMUXER) += mpc8.o
OBJS-$(CONFIG_MPEG1SYSTEM_MUXER) += mpegenc.o
@@ -161,6 +167,7 @@ OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o riff.o
OBJS-$(CONFIG_NUT_MUXER) += nutenc.o nut.o riff.o
OBJS-$(CONFIG_NUV_DEMUXER) += nuv.o riff.o
OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \
+ oggparsecelt.o \
oggparsedirac.o \
oggparseflac.o \
oggparseogm.o \
@@ -172,7 +179,8 @@ OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \
vorbiscomment.o
OBJS-$(CONFIG_OGG_MUXER) += oggenc.o \
vorbiscomment.o
-OBJS-$(CONFIG_OMA_DEMUXER) += oma.o pcm.o
+OBJS-$(CONFIG_OMA_DEMUXER) += omadec.o pcm.o oma.o
+OBJS-$(CONFIG_OMA_MUXER) += omaenc.o rawenc.o oma.o id3v2enc.o
OBJS-$(CONFIG_PCM_ALAW_DEMUXER) += pcmdec.o pcm.o rawdec.o
OBJS-$(CONFIG_PCM_ALAW_MUXER) += pcmenc.o rawenc.o
OBJS-$(CONFIG_PCM_F32BE_DEMUXER) += pcmdec.o pcm.o rawdec.o
@@ -213,6 +221,7 @@ OBJS-$(CONFIG_PCM_U32LE_DEMUXER) += pcmdec.o pcm.o rawdec.o
OBJS-$(CONFIG_PCM_U32LE_MUXER) += pcmenc.o rawenc.o
OBJS-$(CONFIG_PCM_U8_DEMUXER) += pcmdec.o pcm.o rawdec.o
OBJS-$(CONFIG_PCM_U8_MUXER) += pcmenc.o rawenc.o
+OBJS-$(CONFIG_PMP_DEMUXER) += pmpdec.o
OBJS-$(CONFIG_PVA_DEMUXER) += pva.o
OBJS-$(CONFIG_QCP_DEMUXER) += qcp.o
OBJS-$(CONFIG_R3D_DEMUXER) += r3d.o
@@ -242,6 +251,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \
rtpdec.o \
rtpdec_amr.o \
rtpdec_asf.o \
+ rtpdec_g726.o \
rtpdec_h263.o \
rtpdec_h264.o \
rtpdec_latm.o \
@@ -259,9 +269,11 @@ OBJS-$(CONFIG_SAP_DEMUXER) += sapdec.o
OBJS-$(CONFIG_SAP_MUXER) += sapenc.o rtpenc_chain.o
OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o
OBJS-$(CONFIG_SEGAFILM_DEMUXER) += segafilm.o
+OBJS-$(CONFIG_SEGMENT_MUXER) += segment.o
OBJS-$(CONFIG_SHORTEN_DEMUXER) += rawdec.o
OBJS-$(CONFIG_SIFF_DEMUXER) += siff.o
OBJS-$(CONFIG_SMACKER_DEMUXER) += smacker.o
+OBJS-$(CONFIG_SMJPEG_DEMUXER) += smjpeg.o
OBJS-$(CONFIG_SOL_DEMUXER) += sol.o pcm.o
OBJS-$(CONFIG_SOX_DEMUXER) += soxdec.o pcm.o
OBJS-$(CONFIG_SOX_MUXER) += soxenc.o
@@ -300,6 +312,7 @@ OBJS-$(CONFIG_WTV_DEMUXER) += wtv.o asfdec.o asf.o asfcrypt.o \
avlanguage.o mpegts.o isom.o riff.o
OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o
OBJS-$(CONFIG_XA_DEMUXER) += xa.o
+OBJS-$(CONFIG_XMV_DEMUXER) += xmv.o riff.o
OBJS-$(CONFIG_XWMA_DEMUXER) += xwma.o riff.o
OBJS-$(CONFIG_YOP_DEMUXER) += yop.o
OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpeg.o
@@ -318,6 +331,8 @@ OBJS-$(CONFIG_CRYPTO_PROTOCOL) += crypto.o
OBJS-$(CONFIG_FILE_PROTOCOL) += file.o
OBJS-$(CONFIG_GOPHER_PROTOCOL) += gopher.o
OBJS-$(CONFIG_HTTP_PROTOCOL) += http.o httpauth.o
+OBJS-$(CONFIG_HTTPPROXY_PROTOCOL) += http.o httpauth.o
+OBJS-$(CONFIG_HTTPS_PROTOCOL) += http.o httpauth.o
OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o
OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
OBJS-$(CONFIG_MD5_PROTOCOL) += md5proto.o
@@ -330,14 +345,11 @@ OBJS-$(CONFIG_RTMP_PROTOCOL) += $(RTMP-OBJS-yes)
OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o
OBJS-$(CONFIG_TCP_PROTOCOL) += tcp.o
+OBJS-$(CONFIG_TLS_PROTOCOL) += tls.o
OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o
-# libavdevice dependencies
-OBJS-$(CONFIG_JACK_INDEV) += timefilter.o
-
EXAMPLES = metadata output
-TESTPROGS = timefilter
-
-include $(SUBDIR)../subdir.mak
+TESTPROGS = seek
+TOOLS = pktdumper probetest
$(SUBDIR)output-example$(EXESUF): ELIBS = -lswscale
diff --git a/libavformat/a64.c b/libavformat/a64.c
index 0e5576b..3cea50b 100644
--- a/libavformat/a64.c
+++ b/libavformat/a64.c
@@ -55,7 +55,6 @@ static int a64_write_header(struct AVFormatContext *s)
break;
default:
return AVERROR(EINVAL);
- break;
}
avio_write(s->pb, header, 2);
c->prev_pkt.size = 0;
@@ -167,11 +166,10 @@ static int a64_write_trailer(struct AVFormatContext *s)
AVOutputFormat ff_a64_muxer = {
.name = "a64",
.long_name = NULL_IF_CONFIG_SMALL("a64 - video for Commodore 64"),
- .mime_type = NULL,
.extensions = "a64, A64",
.priv_data_size = sizeof (A64Context),
.video_codec = CODEC_ID_A64_MULTI,
- a64_write_header,
- a64_write_packet,
- a64_write_trailer
+ .write_header = a64_write_header,
+ .write_packet = a64_write_packet,
+ .write_trailer = a64_write_trailer
};
diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c
index 6a184c7..25c5910 100644
--- a/libavformat/aacdec.c
+++ b/libavformat/aacdec.c
@@ -22,6 +22,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#include "rawdec.h"
#include "id3v1.h"
@@ -65,7 +66,7 @@ static int adts_aac_read_header(AVFormatContext *s,
{
AVStream *st;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -76,18 +77,17 @@ static int adts_aac_read_header(AVFormatContext *s,
ff_id3v1_read(s);
//LCM of all possible ADTS sample rates
- av_set_pts_info(st, 64, 1, 28224000);
+ avpriv_set_pts_info(st, 64, 1, 28224000);
return 0;
}
AVInputFormat ff_aac_demuxer = {
- "aac",
- NULL_IF_CONFIG_SMALL("raw ADTS AAC"),
- 0,
- adts_aac_probe,
- adts_aac_read_header,
- ff_raw_read_partial_packet,
+ .name = "aac",
+ .long_name = NULL_IF_CONFIG_SMALL("raw ADTS AAC"),
+ .read_probe = adts_aac_probe,
+ .read_header = adts_aac_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "aac",
.value = CODEC_ID_AAC,
diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c
index 7ed0102..ca6aee3 100644
--- a/libavformat/ac3dec.c
+++ b/libavformat/ac3dec.c
@@ -41,7 +41,7 @@ static int ac3_eac3_probe(AVProbeData *p, enum CodecID expected_codec_id)
for(frames = 0; buf2 < end; frames++) {
init_get_bits(&gbc, buf2, 54);
- if(ff_ac3_parse_header(&gbc, &hdr) < 0)
+ if(avpriv_ac3_parse_header(&gbc, &hdr) < 0)
break;
if(buf2 + hdr.frame_size > end ||
av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf2 + 2, hdr.frame_size - 2))
@@ -71,12 +71,11 @@ static int ac3_probe(AVProbeData *p)
}
AVInputFormat ff_ac3_demuxer = {
- "ac3",
- NULL_IF_CONFIG_SMALL("raw AC-3"),
- 0,
- ac3_probe,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "ac3",
+ .long_name = NULL_IF_CONFIG_SMALL("raw AC-3"),
+ .read_probe = ac3_probe,
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "ac3",
.value = CODEC_ID_AC3,
@@ -90,12 +89,11 @@ static int eac3_probe(AVProbeData *p)
}
AVInputFormat ff_eac3_demuxer = {
- "eac3",
- NULL_IF_CONFIG_SMALL("raw E-AC-3"),
- 0,
- eac3_probe,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "eac3",
+ .long_name = NULL_IF_CONFIG_SMALL("raw E-AC-3"),
+ .read_probe = eac3_probe,
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "eac3",
.value = CODEC_ID_EAC3,
diff --git a/libavformat/adtsenc.c b/libavformat/adtsenc.c
index 75649e2..ef3d8e2 100644
--- a/libavformat/adtsenc.c
+++ b/libavformat/adtsenc.c
@@ -27,6 +27,8 @@
#include "avformat.h"
#include "adts.h"
+#define ADTS_MAX_FRAME_BYTES ((1 << 13) - 1)
+
int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf, int size)
{
GetBitContext gb;
@@ -35,7 +37,7 @@ int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf
int off;
init_get_bits(&gb, buf, size * 8);
- off = ff_mpeg4audio_get_config(&m4ac, buf, size);
+ off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1);
if (off < 0)
return off;
skip_bits_long(&gb, off);
@@ -67,7 +69,7 @@ int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf
init_put_bits(&pb, adts->pce_data, MAX_PCE_SIZE);
put_bits(&pb, 3, 5); //ID_PCE
- adts->pce_size = (ff_copy_pce_data(&pb, &gb) + 3) / 8;
+ adts->pce_size = (avpriv_copy_pce_data(&pb, &gb) + 3) / 8;
flush_put_bits(&pb);
}
@@ -93,6 +95,13 @@ int ff_adts_write_frame_header(ADTSContext *ctx,
{
PutBitContext pb;
+ unsigned full_frame_size = (unsigned)ADTS_HEADER_SIZE + size + pce_size;
+ if (full_frame_size > ADTS_MAX_FRAME_BYTES) {
+ av_log(NULL, AV_LOG_ERROR, "ADTS frame size too large: %u (max %d)\n",
+ full_frame_size, ADTS_MAX_FRAME_BYTES);
+ return AVERROR_INVALIDDATA;
+ }
+
init_put_bits(&pb, buf, ADTS_HEADER_SIZE);
/* adts_fixed_header */
@@ -110,7 +119,7 @@ int ff_adts_write_frame_header(ADTSContext *ctx,
/* adts_variable_header */
put_bits(&pb, 1, 0); /* copyright_identification_bit */
put_bits(&pb, 1, 0); /* copyright_identification_start */
- put_bits(&pb, 13, ADTS_HEADER_SIZE + size + pce_size); /* aac_frame_length */
+ put_bits(&pb, 13, full_frame_size); /* aac_frame_length */
put_bits(&pb, 11, 0x7ff); /* adts_buffer_fullness */
put_bits(&pb, 2, 0); /* number_of_raw_data_blocks_in_frame */
@@ -128,7 +137,10 @@ static int adts_write_packet(AVFormatContext *s, AVPacket *pkt)
if (!pkt->size)
return 0;
if (adts->write_adts) {
- ff_adts_write_frame_header(adts, buf, pkt->size, adts->pce_size);
+ int err = ff_adts_write_frame_header(adts, buf, pkt->size,
+ adts->pce_size);
+ if (err < 0)
+ return err;
avio_write(pb, buf, ADTS_HEADER_SIZE);
if (adts->pce_size) {
avio_write(pb, adts->pce_data, adts->pce_size);
@@ -142,13 +154,13 @@ static int adts_write_packet(AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_adts_muxer = {
- "adts",
- NULL_IF_CONFIG_SMALL("ADTS AAC"),
- "audio/aac",
- "aac,adts",
- sizeof(ADTSContext),
- CODEC_ID_AAC,
- CODEC_ID_NONE,
- adts_write_header,
- adts_write_packet,
+ .name = "adts",
+ .long_name = NULL_IF_CONFIG_SMALL("ADTS AAC"),
+ .mime_type = "audio/aac",
+ .extensions = "aac,adts",
+ .priv_data_size = sizeof(ADTSContext),
+ .audio_codec = CODEC_ID_AAC,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = adts_write_header,
+ .write_packet = adts_write_packet,
};
diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c
new file mode 100644
index 0000000..dca9748
--- /dev/null
+++ b/libavformat/adxdec.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2011 Justin Ruggles
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * CRI ADX demuxer
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "libavcodec/adx.h"
+#include "avformat.h"
+#include "internal.h"
+
+#define BLOCK_SIZE 18
+#define BLOCK_SAMPLES 32
+
+typedef struct ADXDemuxerContext {
+ int header_size;
+} ADXDemuxerContext;
+
+static int adx_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ ADXDemuxerContext *c = s->priv_data;
+ AVCodecContext *avctx = s->streams[0]->codec;
+ int ret, size;
+
+ size = BLOCK_SIZE * avctx->channels;
+
+ pkt->pos = avio_tell(s->pb);
+ pkt->stream_index = 0;
+
+ ret = av_get_packet(s->pb, pkt, size);
+ if (ret != size) {
+ av_free_packet(pkt);
+ return ret < 0 ? ret : AVERROR(EIO);
+ }
+ if (AV_RB16(pkt->data) & 0x8000) {
+ av_free_packet(pkt);
+ return AVERROR_EOF;
+ }
+ pkt->size = size;
+ pkt->duration = 1;
+ pkt->pts = (pkt->pos - c->header_size) / size;
+
+ return 0;
+}
+
+static int adx_read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ ADXDemuxerContext *c = s->priv_data;
+ AVCodecContext *avctx;
+ int ret;
+
+ AVStream *st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ avctx = s->streams[0]->codec;
+
+ if (avio_rb16(s->pb) != 0x8000)
+ return AVERROR_INVALIDDATA;
+ c->header_size = avio_rb16(s->pb) + 4;
+ avio_seek(s->pb, -4, SEEK_CUR);
+
+ avctx->extradata = av_mallocz(c->header_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!avctx->extradata)
+ return AVERROR(ENOMEM);
+ if (avio_read(s->pb, avctx->extradata, c->header_size) < c->header_size) {
+ av_freep(&avctx->extradata);
+ return AVERROR(EIO);
+ }
+ avctx->extradata_size = c->header_size;
+
+ ret = avpriv_adx_decode_header(avctx, avctx->extradata,
+ avctx->extradata_size, &c->header_size,
+ NULL);
+ if (ret)
+ return ret;
+
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = s->iformat->value;
+
+ avpriv_set_pts_info(st, 64, BLOCK_SAMPLES, avctx->sample_rate);
+
+ return 0;
+}
+
+AVInputFormat ff_adx_demuxer = {
+ .name = "adx",
+ .long_name = NULL_IF_CONFIG_SMALL("CRI ADX"),
+ .priv_data_size = sizeof(ADXDemuxerContext),
+ .read_header = adx_read_header,
+ .read_packet = adx_read_packet,
+ .extensions = "adx",
+ .value = CODEC_ID_ADPCM_ADX,
+};
diff --git a/libavformat/aea.c b/libavformat/aea.c
index c6dfbb1..b33b45f 100644
--- a/libavformat/aea.c
+++ b/libavformat/aea.c
@@ -57,7 +57,7 @@ static int aea_read_probe(AVProbeData *p)
static int aea_read_header(AVFormatContext *s,
AVFormatParameters *ap)
{
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -95,14 +95,12 @@ static int aea_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_aea_demuxer = {
- "aea",
- NULL_IF_CONFIG_SMALL("MD STUDIO audio"),
- 0,
- aea_read_probe,
- aea_read_header,
- aea_read_packet,
- 0,
- pcm_read_seek,
+ .name = "aea",
+ .long_name = NULL_IF_CONFIG_SMALL("MD STUDIO audio"),
+ .read_probe = aea_read_probe,
+ .read_header = aea_read_header,
+ .read_packet = aea_read_packet,
+ .read_seek = pcm_read_seek,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "aea",
};
diff --git a/libavformat/aiff.h b/libavformat/aiff.h
index cd2bd25..3190a22 100644
--- a/libavformat/aiff.h
+++ b/libavformat/aiff.h
@@ -43,6 +43,7 @@ static const AVCodecTag ff_codec_aiff_tags[] = {
{ 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_S16BE, MKTAG('t','w','o','s') },
{ 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') },
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index 0e81542..0e69d02 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -19,9 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/intfloat_readwrite.h"
+#include "libavutil/mathematics.h"
#include "libavutil/dict.h"
#include "avformat.h"
+#include "internal.h"
#include "pcm.h"
#include "aiff.h"
@@ -87,7 +88,8 @@ static void get_meta(AVFormatContext *s, const char *key, int size)
static unsigned int get_aiff_header(AVIOContext *pb, AVCodecContext *codec,
int size, unsigned version)
{
- AVExtFloat ext;
+ int exp;
+ uint64_t val;
double sample_rate;
unsigned int num_frames;
@@ -98,8 +100,9 @@ static unsigned int get_aiff_header(AVIOContext *pb, AVCodecContext *codec,
num_frames = avio_rb32(pb);
codec->bits_per_coded_sample = avio_rb16(pb);
- avio_read(pb, (uint8_t*)&ext, sizeof(ext));/* Sample rate is in */
- sample_rate = av_ext2dbl(ext); /* 80 bits BE IEEE extended float */
+ exp = avio_rb16(pb);
+ val = avio_rb64(pb);
+ sample_rate = ldexp(val, exp - 16383 - 63);
codec->sample_rate = sample_rate;
size -= 18;
@@ -196,7 +199,7 @@ static int aiff_read_header(AVFormatContext *s,
filesize -= 4;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -268,10 +271,7 @@ static int aiff_read_header(AVFormatContext *s,
got_sound:
/* Now positioned, get the sound data start and end */
- if (st->nb_frames)
- s->file_size = st->nb_frames * st->codec->block_align;
-
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
st->start_time = 0;
st->duration = st->codec->frame_size ?
st->nb_frames * st->codec->frame_size : st->nb_frames;
@@ -313,13 +313,12 @@ static int aiff_read_packet(AVFormatContext *s,
}
AVInputFormat ff_aiff_demuxer = {
- "aiff",
- NULL_IF_CONFIG_SMALL("Audio IFF"),
- sizeof(AIFFInputContext),
- aiff_probe,
- aiff_read_header,
- aiff_read_packet,
- NULL,
- pcm_read_seek,
+ .name = "aiff",
+ .long_name = NULL_IF_CONFIG_SMALL("Audio IFF"),
+ .priv_data_size = sizeof(AIFFInputContext),
+ .read_probe = aiff_probe,
+ .read_header = aiff_read_header,
+ .read_packet = aiff_read_packet,
+ .read_seek = pcm_read_seek,
.codec_tag= (const AVCodecTag* const []){ff_codec_aiff_tags, 0},
};
diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
index 3bdb4f4..2916d26 100644
--- a/libavformat/aiffenc.c
+++ b/libavformat/aiffenc.c
@@ -19,7 +19,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/intfloat.h"
#include "avformat.h"
+#include "internal.h"
#include "aiff.h"
#include "avio_internal.h"
@@ -34,7 +36,7 @@ static int aiff_write_header(AVFormatContext *s)
AIFFOutputContext *aiff = s->priv_data;
AVIOContext *pb = s->pb;
AVCodecContext *enc = s->streams[0]->codec;
- AVExtFloat sample_rate;
+ uint64_t sample_rate;
int aifc = 0;
/* First verify if format is ok */
@@ -80,8 +82,9 @@ static int aiff_write_header(AVFormatContext *s)
avio_wb16(pb, enc->bits_per_coded_sample); /* Sample size */
- sample_rate = av_dbl2ext((double)enc->sample_rate);
- avio_write(pb, (uint8_t*)&sample_rate, sizeof(sample_rate));
+ sample_rate = av_double2int(enc->sample_rate);
+ avio_wb16(pb, (sample_rate >> 52) + (16383 - 1023));
+ avio_wb64(pb, UINT64_C(1) << 63 | sample_rate << 11);
if (aifc) {
avio_wl32(pb, enc->codec_tag);
@@ -95,7 +98,7 @@ static int aiff_write_header(AVFormatContext *s)
avio_wb32(pb, 0); /* Data offset */
avio_wb32(pb, 0); /* Block-size (block align) */
- av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
+ avpriv_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
/* Data is starting here */
avio_flush(pb);
@@ -147,15 +150,15 @@ static int aiff_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_aiff_muxer = {
- "aiff",
- NULL_IF_CONFIG_SMALL("Audio IFF"),
- "audio/aiff",
- "aif,aiff,afc,aifc",
- sizeof(AIFFOutputContext),
- CODEC_ID_PCM_S16BE,
- CODEC_ID_NONE,
- aiff_write_header,
- aiff_write_packet,
- aiff_write_trailer,
+ .name = "aiff",
+ .long_name = NULL_IF_CONFIG_SMALL("Audio IFF"),
+ .mime_type = "audio/aiff",
+ .extensions = "aif,aiff,afc,aifc",
+ .priv_data_size = sizeof(AIFFOutputContext),
+ .audio_codec = CODEC_ID_PCM_S16BE,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = aiff_write_header,
+ .write_packet = aiff_write_packet,
+ .write_trailer = aiff_write_trailer,
.codec_tag= (const AVCodecTag* const []){ff_codec_aiff_tags, 0},
};
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index f1c3d3b..1debddb 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -52,6 +52,7 @@ void av_register_all(void)
REGISTER_DEMUXER (AAC, aac);
REGISTER_MUXDEMUX (AC3, ac3);
REGISTER_MUXER (ADTS, adts);
+ REGISTER_DEMUXER (ADX, adx);
REGISTER_DEMUXER (AEA, aea);
REGISTER_MUXDEMUX (AIFF, aiff);
REGISTER_MUXDEMUX (AMR, amr);
@@ -70,6 +71,7 @@ void av_register_all(void)
REGISTER_DEMUXER (BETHSOFTVID, bethsoftvid);
REGISTER_DEMUXER (BFI, bfi);
REGISTER_DEMUXER (BINK, bink);
+ REGISTER_DEMUXER (BMV, bmv);
REGISTER_DEMUXER (C93, c93);
REGISTER_DEMUXER (CAF, caf);
REGISTER_MUXDEMUX (CAVSVIDEO, cavsvideo);
@@ -113,6 +115,7 @@ void av_register_all(void)
REGISTER_DEMUXER (IV8, iv8);
REGISTER_MUXDEMUX (IVF, ivf);
REGISTER_DEMUXER (JV, jv);
+ REGISTER_MUXDEMUX (LATM, latm);
REGISTER_DEMUXER (LMLM4, lmlm4);
REGISTER_DEMUXER (LXF, lxf);
REGISTER_MUXDEMUX (M4V, m4v);
@@ -153,7 +156,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX (NUT, nut);
REGISTER_DEMUXER (NUV, nuv);
REGISTER_MUXDEMUX (OGG, ogg);
- REGISTER_DEMUXER (OMA, oma);
+ REGISTER_MUXDEMUX (OMA, oma);
REGISTER_MUXDEMUX (PCM_ALAW, pcm_alaw);
REGISTER_MUXDEMUX (PCM_MULAW, pcm_mulaw);
REGISTER_MUXDEMUX (PCM_F64BE, pcm_f64be);
@@ -174,6 +177,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX (PCM_U16BE, pcm_u16be);
REGISTER_MUXDEMUX (PCM_U16LE, pcm_u16le);
REGISTER_MUXDEMUX (PCM_U8, pcm_u8);
+ REGISTER_DEMUXER (PMP, pmp);
REGISTER_MUXER (PSP, psp);
REGISTER_DEMUXER (PVA, pva);
REGISTER_DEMUXER (QCP, qcp);
@@ -193,9 +197,11 @@ void av_register_all(void)
av_register_rdt_dynamic_payload_handlers();
#endif
REGISTER_DEMUXER (SEGAFILM, segafilm);
+ REGISTER_MUXER (SEGMENT, segment);
REGISTER_DEMUXER (SHORTEN, shorten);
REGISTER_DEMUXER (SIFF, siff);
REGISTER_DEMUXER (SMACKER, smacker);
+ REGISTER_DEMUXER (SMJPEG, smjpeg);
REGISTER_DEMUXER (SOL, sol);
REGISTER_MUXDEMUX (SOX, sox);
REGISTER_MUXDEMUX (SPDIF, spdif);
@@ -225,6 +231,7 @@ void av_register_all(void)
REGISTER_DEMUXER (WTV, wtv);
REGISTER_DEMUXER (WV, wv);
REGISTER_DEMUXER (XA, xa);
+ REGISTER_DEMUXER (XMV, xmv);
REGISTER_DEMUXER (XWMA, xwma);
REGISTER_DEMUXER (YOP, yop);
REGISTER_MUXDEMUX (YUV4MPEGPIPE, yuv4mpegpipe);
@@ -239,6 +246,8 @@ void av_register_all(void)
REGISTER_PROTOCOL (FILE, file);
REGISTER_PROTOCOL (GOPHER, gopher);
REGISTER_PROTOCOL (HTTP, http);
+ REGISTER_PROTOCOL (HTTPPROXY, httpproxy);
+ REGISTER_PROTOCOL (HTTPS, https);
REGISTER_PROTOCOL (MMSH, mmsh);
REGISTER_PROTOCOL (MMST, mmst);
REGISTER_PROTOCOL (MD5, md5);
@@ -252,5 +261,6 @@ void av_register_all(void)
#endif
REGISTER_PROTOCOL (RTP, rtp);
REGISTER_PROTOCOL (TCP, tcp);
+ REGISTER_PROTOCOL (TLS, tls);
REGISTER_PROTOCOL (UDP, udp);
}
diff --git a/libavformat/amr.c b/libavformat/amr.c
index 260bd6a..b52ac49 100644
--- a/libavformat/amr.c
+++ b/libavformat/amr.c
@@ -26,6 +26,7 @@ Only mono files are supported.
*/
#include "avformat.h"
+#include "internal.h"
static const char AMR_header [] = "#!AMR\n";
static const char AMRWB_header [] = "#!AMR-WB\n";
@@ -84,7 +85,7 @@ static int amr_read_header(AVFormatContext *s,
avio_read(pb, header, 6);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
{
return AVERROR(ENOMEM);
@@ -111,7 +112,7 @@ static int amr_read_header(AVFormatContext *s,
}
st->codec->channels = 1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
return 0;
}
@@ -174,27 +175,24 @@ static int amr_read_packet(AVFormatContext *s,
#if CONFIG_AMR_DEMUXER
AVInputFormat ff_amr_demuxer = {
- "amr",
- NULL_IF_CONFIG_SMALL("3GPP AMR file format"),
- 0, /*priv_data_size*/
- amr_probe,
- amr_read_header,
- amr_read_packet,
- NULL,
+ .name = "amr",
+ .long_name = NULL_IF_CONFIG_SMALL("3GPP AMR file format"),
+ .read_probe = amr_probe,
+ .read_header = amr_read_header,
+ .read_packet = amr_read_packet,
.flags = AVFMT_GENERIC_INDEX,
};
#endif
#if CONFIG_AMR_MUXER
AVOutputFormat ff_amr_muxer = {
- "amr",
- NULL_IF_CONFIG_SMALL("3GPP AMR file format"),
- "audio/amr",
- "amr",
- 0,
- CODEC_ID_AMR_NB,
- CODEC_ID_NONE,
- amr_write_header,
- amr_write_packet,
+ .name = "amr",
+ .long_name = NULL_IF_CONFIG_SMALL("3GPP AMR file format"),
+ .mime_type = "audio/amr",
+ .extensions = "amr",
+ .audio_codec = CODEC_ID_AMR_NB,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = amr_write_header,
+ .write_packet = amr_write_packet,
};
#endif
diff --git a/libavformat/anm.c b/libavformat/anm.c
index 4d1b5f7..7ceb2d8 100644
--- a/libavformat/anm.c
+++ b/libavformat/anm.c
@@ -26,6 +26,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
typedef struct {
int base_record;
@@ -97,7 +98,7 @@ static int read_header(AVFormatContext *s,
return AVERROR_INVALIDDATA;
/* video stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -128,7 +129,7 @@ static int read_header(AVFormatContext *s,
avio_skip(pb, 32); /* record_types */
st->nb_frames = avio_rl32(pb);
- av_set_pts_info(st, 64, 1, avio_rl16(pb));
+ avpriv_set_pts_info(st, 64, 1, avio_rl16(pb));
avio_skip(pb, 58);
/* color cycling and palette data */
@@ -136,16 +137,16 @@ static int read_header(AVFormatContext *s,
st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata) {
ret = AVERROR(ENOMEM);
- goto close_and_return;
+ goto fail;
}
ret = avio_read(pb, st->codec->extradata, st->codec->extradata_size);
if (ret < 0)
- goto close_and_return;
+ goto fail;
/* read page table */
ret = avio_seek(pb, anm->page_table_offset, SEEK_SET);
if (ret < 0)
- goto close_and_return;
+ goto fail;
for (i = 0; i < MAX_PAGES; i++) {
Page *p = &anm->pt[i];
@@ -158,7 +159,7 @@ static int read_header(AVFormatContext *s,
anm->page = find_record(anm, 0);
if (anm->page < 0) {
ret = anm->page;
- goto close_and_return;
+ goto fail;
}
anm->record = -1;
@@ -168,8 +169,7 @@ invalid:
av_log_ask_for_sample(s, NULL);
ret = AVERROR_INVALIDDATA;
-close_and_return:
- av_close_input_stream(s);
+fail:
return ret;
}
@@ -226,10 +226,10 @@ repeat:
}
AVInputFormat ff_anm_demuxer = {
- "anm",
- NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
- sizeof(AnmDemuxContext),
- probe,
- read_header,
- read_packet,
+ .name = "anm",
+ .long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
+ .priv_data_size = sizeof(AnmDemuxContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
};
diff --git a/libavformat/apc.c b/libavformat/apc.c
index 40c6f0c..2383950 100644
--- a/libavformat/apc.c
+++ b/libavformat/apc.c
@@ -39,7 +39,7 @@ static int apc_read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_rl32(pb); /* _APC */
avio_rl32(pb); /* 1.20 */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -81,10 +81,9 @@ static int apc_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_apc_demuxer = {
- "apc",
- NULL_IF_CONFIG_SMALL("CRYO APC format"),
- 0,
- apc_probe,
- apc_read_header,
- apc_read_packet,
+ .name = "apc",
+ .long_name = NULL_IF_CONFIG_SMALL("CRYO APC format"),
+ .read_probe = apc_probe,
+ .read_header = apc_read_header,
+ .read_packet = apc_read_packet,
};
diff --git a/libavformat/ape.c b/libavformat/ape.c
index b084100..a60626e 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -24,6 +24,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#include "apetag.h"
/* The earliest and latest file formats supported by this library */
@@ -129,9 +130,11 @@ static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx)
} else {
for (i = 0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++) {
if (i < ape_ctx->totalframes - 1) {
- av_log(s, AV_LOG_DEBUG, "%8d %d (%d bytes)\n", i, ape_ctx->seektable[i], ape_ctx->seektable[i + 1] - ape_ctx->seektable[i]);
+ av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32" (%"PRIu32" bytes)\n",
+ i, ape_ctx->seektable[i],
+ ape_ctx->seektable[i + 1] - ape_ctx->seektable[i]);
} else {
- av_log(s, AV_LOG_DEBUG, "%8d %d\n", i, ape_ctx->seektable[i]);
+ av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32"\n", i, ape_ctx->seektable[i]);
}
}
}
@@ -169,7 +172,7 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
ape->fileversion = avio_rl16(pb);
if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) {
- av_log(s, AV_LOG_ERROR, "Unsupported file version - %"PRId16".%02"PRId16"\n",
+ av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n",
ape->fileversion / 1000, (ape->fileversion % 1000) / 10);
return -1;
}
@@ -253,7 +256,8 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
return -1;
}
if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) {
- av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %ld vs. %"PRIu32"\n",
+ av_log(s, AV_LOG_ERROR,
+ "Number of seek entries is less than number of frames: %zu vs. %"PRIu32"\n",
ape->seektablelength / sizeof(*ape->seektable), ape->totalframes);
return AVERROR_INVALIDDATA;
}
@@ -310,7 +314,7 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
ape->compressiontype);
/* now we are ready: build format streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
@@ -327,7 +331,7 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
st->nb_frames = ape->totalframes;
st->start_time = 0;
st->duration = total_blocks / MAC_SUBFRAME_SIZE;
- av_set_pts_info(st, 64, MAC_SUBFRAME_SIZE, ape->samplerate);
+ avpriv_set_pts_info(st, 64, MAC_SUBFRAME_SIZE, ape->samplerate);
st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE);
st->codec->extradata_size = APE_EXTRADATA_SIZE;
@@ -407,13 +411,13 @@ static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
}
AVInputFormat ff_ape_demuxer = {
- "ape",
- NULL_IF_CONFIG_SMALL("Monkey's Audio"),
- sizeof(APEContext),
- ape_probe,
- ape_read_header,
- ape_read_packet,
- ape_read_close,
- ape_read_seek,
+ .name = "ape",
+ .long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
+ .priv_data_size = sizeof(APEContext),
+ .read_probe = ape_probe,
+ .read_header = ape_read_header,
+ .read_packet = ape_read_packet,
+ .read_close = ape_read_close,
+ .read_seek = ape_read_seek,
.extensions = "ape,apl,mac"
};
diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c
index 38f33a2..f62e2d0 100644
--- a/libavformat/applehttp.c
+++ b/libavformat/applehttp.c
@@ -27,6 +27,7 @@
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
#include "avformat.h"
@@ -98,6 +99,8 @@ typedef struct AppleHTTPContext {
int cur_seq_no;
int end_of_segment;
int first_packet;
+ int64_t first_timestamp;
+ AVIOInterruptCB *interrupt_callback;
} AppleHTTPContext;
static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -129,7 +132,7 @@ static void free_variant_list(AppleHTTPContext *c)
ffurl_close(var->input);
if (var->ctx) {
var->ctx->pb = NULL;
- av_close_input_file(var->ctx);
+ avformat_close_input(&var->ctx);
}
av_free(var);
}
@@ -201,14 +204,15 @@ static int parse_playlist(AppleHTTPContext *c, const char *url,
enum KeyType key_type = KEY_NONE;
uint8_t iv[16] = "";
int has_iv = 0;
- char key[MAX_URL_SIZE];
+ char key[MAX_URL_SIZE] = "";
char line[1024];
const char *ptr;
int close_in = 0;
if (!in) {
close_in = 1;
- if ((ret = avio_open(&in, url, AVIO_FLAG_READ)) < 0)
+ if ((ret = avio_open2(&in, url, AVIO_FLAG_READ,
+ c->interrupt_callback, NULL)) < 0)
return ret;
}
@@ -321,13 +325,15 @@ static int open_input(struct variant *var)
{
struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];
if (seg->key_type == KEY_NONE) {
- return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ);
+ return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ,
+ &var->parent->interrupt_callback, NULL);
} else if (seg->key_type == KEY_AES_128) {
char iv[33], key[33], url[MAX_URL_SIZE];
int ret;
if (strcmp(seg->key, var->key_url)) {
URLContext *uc;
- if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ) == 0) {
+ if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ,
+ &var->parent->interrupt_callback, NULL) == 0) {
if (ffurl_read_complete(uc, var->key, sizeof(var->key))
!= sizeof(var->key)) {
av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
@@ -347,11 +353,12 @@ static int open_input(struct variant *var)
snprintf(url, sizeof(url), "crypto+%s", seg->url);
else
snprintf(url, sizeof(url), "crypto:%s", seg->url);
- if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ)) < 0)
+ if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ,
+ &var->parent->interrupt_callback)) < 0)
return ret;
- av_set_string3(var->input->priv_data, "key", key, 0, NULL);
- av_set_string3(var->input->priv_data, "iv", iv, 0, NULL);
- if ((ret = ffurl_connect(var->input)) < 0) {
+ av_opt_set(var->input->priv_data, "key", key, 0);
+ av_opt_set(var->input->priv_data, "iv", iv, 0);
+ if ((ret = ffurl_connect(var->input, NULL)) < 0) {
ffurl_close(var->input);
var->input = NULL;
return ret;
@@ -369,13 +376,23 @@ static int read_data(void *opaque, uint8_t *buf, int buf_size)
restart:
if (!v->input) {
-reload:
- /* If this is a live stream and target_duration has elapsed since
+ /* If this is a live stream and the reload interval has elapsed since
* the last playlist reload, reload the variant playlists now. */
+ int64_t reload_interval = v->n_segments > 0 ?
+ v->segments[v->n_segments - 1]->duration :
+ v->target_duration;
+ reload_interval *= 1000000;
+
+reload:
if (!v->finished &&
- av_gettime() - v->last_load_time >= v->target_duration*1000000 &&
- (ret = parse_playlist(c, v->url, v, NULL)) < 0)
+ av_gettime() - v->last_load_time >= reload_interval) {
+ if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
return ret;
+ /* If we need to reload the playlist again below (if
+ * there's still no more segments), switch to a reload
+ * interval of half the target duration. */
+ reload_interval = v->target_duration * 500000;
+ }
if (v->cur_seq_no < v->start_seq_no) {
av_log(NULL, AV_LOG_WARNING,
"skipping %d segments ahead, expired from playlists\n",
@@ -385,9 +402,8 @@ reload:
if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
if (v->finished)
return AVERROR_EOF;
- while (av_gettime() - v->last_load_time <
- v->target_duration*1000000) {
- if (url_interrupt_cb())
+ while (av_gettime() - v->last_load_time < reload_interval) {
+ if (ff_check_interrupt(c->interrupt_callback))
return AVERROR_EXIT;
usleep(100*1000);
}
@@ -411,7 +427,7 @@ reload:
c->end_of_segment = 1;
c->cur_seq_no = v->cur_seq_no;
- if (v->ctx) {
+ if (v->ctx && v->ctx->nb_streams) {
v->needed = 0;
for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
i++) {
@@ -432,6 +448,8 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
AppleHTTPContext *c = s->priv_data;
int ret = 0, i, j, stream_offset = 0;
+ c->interrupt_callback = &s->interrupt_callback;
+
if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
goto fail;
@@ -494,8 +512,15 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
v->pb.seekable = 0;
ret = av_probe_input_buffer(&v->pb, &in_fmt, v->segments[0]->url,
NULL, 0, 0);
- if (ret < 0)
+ if (ret < 0) {
+ /* Free the ctx - it isn't initialized properly at this point,
+ * so avformat_close_input shouldn't be called. If
+ * avformat_open_input fails below, it frees and zeros the
+ * context, so it doesn't need any special treatment like this. */
+ avformat_free_context(v->ctx);
+ v->ctx = NULL;
goto fail;
+ }
v->ctx->pb = &v->pb;
ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL);
if (ret < 0)
@@ -504,11 +529,12 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
/* Create new AVStreams for each stream in this variant */
for (j = 0; j < v->ctx->nb_streams; j++) {
- AVStream *st = av_new_stream(s, i);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st) {
ret = AVERROR(ENOMEM);
goto fail;
}
+ st->id = i;
avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
if (v->bandwidth)
av_dict_set(&st->metadata, "variant_bitrate", bitrate_str,
@@ -518,6 +544,7 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
c->first_packet = 1;
+ c->first_timestamp = AV_NOPTS_VALUE;
return 0;
fail:
@@ -582,6 +609,9 @@ start:
if (!var->pb.eof_reached)
return ret;
reset_packet(&var->pkt);
+ } else {
+ if (c->first_timestamp == AV_NOPTS_VALUE)
+ c->first_timestamp = var->pkt.dts;
}
}
/* Check if this stream has the packet with the lowest dts */
@@ -630,7 +660,10 @@ static int applehttp_read_seek(AVFormatContext *s, int stream_index,
for (i = 0; i < c->n_variants; i++) {
/* Reset reading */
struct variant *var = c->variants[i];
- int64_t pos = 0;
+ int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
+ av_rescale_rnd(c->first_timestamp, 1,
+ stream_index >= 0 ? s->streams[stream_index]->time_base.den : AV_TIME_BASE,
+ flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
if (var->input) {
ffurl_close(var->input);
var->input = NULL;
@@ -667,12 +700,12 @@ static int applehttp_probe(AVProbeData *p)
}
AVInputFormat ff_applehttp_demuxer = {
- "applehttp",
- NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming format"),
- sizeof(AppleHTTPContext),
- applehttp_probe,
- applehttp_read_header,
- applehttp_read_packet,
- applehttp_close,
- applehttp_read_seek,
+ .name = "applehttp",
+ .long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming format"),
+ .priv_data_size = sizeof(AppleHTTPContext),
+ .read_probe = applehttp_probe,
+ .read_header = applehttp_read_header,
+ .read_packet = applehttp_read_packet,
+ .read_close = applehttp_close,
+ .read_seek = applehttp_read_seek,
};
diff --git a/libavformat/applehttpproto.c b/libavformat/applehttpproto.c
index 85f3cfc..46758ba 100644
--- a/libavformat/applehttpproto.c
+++ b/libavformat/applehttpproto.c
@@ -114,7 +114,8 @@ static int parse_playlist(URLContext *h, const char *url)
char line[1024];
const char *ptr;
- if ((ret = avio_open(&in, url, AVIO_FLAG_READ)) < 0)
+ if ((ret = avio_open2(&in, url, AVIO_FLAG_READ,
+ &h->interrupt_callback, NULL)) < 0)
return ret;
read_chomp_line(in, line, sizeof(line));
@@ -173,19 +174,25 @@ fail:
return ret;
}
+static int applehttp_close(URLContext *h)
+{
+ AppleHTTPContext *s = h->priv_data;
+
+ free_segment_list(s);
+ free_variant_list(s);
+ ffurl_close(s->seg_hd);
+ return 0;
+}
+
static int applehttp_open(URLContext *h, const char *uri, int flags)
{
- AppleHTTPContext *s;
+ AppleHTTPContext *s = h->priv_data;
int ret, i;
const char *nested_url;
if (flags & AVIO_FLAG_WRITE)
return AVERROR(ENOSYS);
- s = av_mallocz(sizeof(AppleHTTPContext));
- if (!s)
- return AVERROR(ENOMEM);
- h->priv_data = s;
h->is_streamed = 1;
if (av_strstart(uri, "applehttp+", &nested_url)) {
@@ -228,7 +235,7 @@ static int applehttp_open(URLContext *h, const char *uri, int flags)
return 0;
fail:
- av_free(s);
+ applehttp_close(h);
return ret;
}
@@ -237,6 +244,7 @@ static int applehttp_read(URLContext *h, uint8_t *buf, int size)
AppleHTTPContext *s = h->priv_data;
const char *url;
int ret;
+ int64_t reload_interval;
start:
if (s->seg_hd) {
@@ -249,12 +257,21 @@ start:
s->seg_hd = NULL;
s->cur_seq_no++;
}
+ reload_interval = s->n_segments > 0 ?
+ s->segments[s->n_segments - 1]->duration :
+ s->target_duration;
+ reload_interval *= 1000000;
retry:
if (!s->finished) {
int64_t now = av_gettime();
- if (now - s->last_load_time >= s->target_duration*1000000)
+ if (now - s->last_load_time >= reload_interval) {
if ((ret = parse_playlist(h, s->playlisturl)) < 0)
return ret;
+ /* If we need to reload the playlist again below (if
+ * there's still no more segments), switch to a reload
+ * interval of half the target duration. */
+ reload_interval = s->target_duration * 500000;
+ }
}
if (s->cur_seq_no < s->start_seq_no) {
av_log(h, AV_LOG_WARNING,
@@ -265,8 +282,8 @@ retry:
if (s->cur_seq_no - s->start_seq_no >= s->n_segments) {
if (s->finished)
return AVERROR_EOF;
- while (av_gettime() - s->last_load_time < s->target_duration*1000000) {
- if (url_interrupt_cb())
+ while (av_gettime() - s->last_load_time < reload_interval) {
+ if (ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT;
usleep(100*1000);
}
@@ -274,9 +291,10 @@ retry:
}
url = s->segments[s->cur_seq_no - s->start_seq_no]->url,
av_log(h, AV_LOG_DEBUG, "opening %s\n", url);
- ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ);
+ ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ,
+ &h->interrupt_callback, NULL);
if (ret < 0) {
- if (url_interrupt_cb())
+ if (ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT;
av_log(h, AV_LOG_WARNING, "Unable to open %s\n", url);
s->cur_seq_no++;
@@ -285,21 +303,11 @@ retry:
goto start;
}
-static int applehttp_close(URLContext *h)
-{
- AppleHTTPContext *s = h->priv_data;
-
- free_segment_list(s);
- free_variant_list(s);
- ffurl_close(s->seg_hd);
- av_free(s);
- return 0;
-}
-
URLProtocol ff_applehttp_protocol = {
- .name = "applehttp",
- .url_open = applehttp_open,
- .url_read = applehttp_read,
- .url_close = applehttp_close,
- .flags = URL_PROTOCOL_FLAG_NESTED_SCHEME,
+ .name = "applehttp",
+ .url_open = applehttp_open,
+ .url_read = applehttp_read,
+ .url_close = applehttp_close,
+ .flags = URL_PROTOCOL_FLAG_NESTED_SCHEME,
+ .priv_data_size = sizeof(AppleHTTPContext),
};
diff --git a/libavformat/asfcrypt.c b/libavformat/asfcrypt.c
index 52cfc17..aea3d4f 100644
--- a/libavformat/asfcrypt.c
+++ b/libavformat/asfcrypt.c
@@ -28,9 +28,9 @@
#include "asfcrypt.h"
/**
- * \brief find multiplicative inverse modulo 2 ^ 32
- * \param v number to invert, must be odd!
- * \return number so that result * v = 1 (mod 2^32)
+ * @brief find multiplicative inverse modulo 2 ^ 32
+ * @param v number to invert, must be odd!
+ * @return number so that result * v = 1 (mod 2^32)
*/
static uint32_t inverse(uint32_t v) {
// v ^ 3 gives the inverse (mod 16), could also be implemented
@@ -45,9 +45,9 @@ static uint32_t inverse(uint32_t v) {
}
/**
- * \brief read keys from keybuf into keys
- * \param keybuf buffer containing the keys
- * \param keys output key array containing the keys for encryption in
+ * @brief read keys from keybuf into keys
+ * @param keybuf buffer containing the keys
+ * @param keys output key array containing the keys for encryption in
* native endianness
*/
static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12]) {
@@ -57,9 +57,9 @@ static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12]) {
}
/**
- * \brief invert the keys so that encryption become decryption keys and
+ * @brief invert the keys so that encryption become decryption keys and
* the other way round.
- * \param keys key array of ints to invert
+ * @param keys key array of ints to invert
*/
static void multiswap_invert_keys(uint32_t keys[12]) {
int i;
@@ -92,12 +92,12 @@ static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v) {
}
/**
- * \brief "MultiSwap" encryption
- * \param keys 32 bit numbers in machine endianness,
+ * @brief "MultiSwap" encryption
+ * @param keys 32 bit numbers in machine endianness,
* 0-4 and 6-10 must be inverted from decryption
- * \param key another key, this one must be the same for the decryption
- * \param data data to encrypt
- * \return encrypted data
+ * @param key another key, this one must be the same for the decryption
+ * @param data data to encrypt
+ * @return encrypted data
*/
static uint64_t multiswap_enc(const uint32_t keys[12], uint64_t key, uint64_t data) {
uint32_t a = data;
@@ -114,12 +114,12 @@ static uint64_t multiswap_enc(const uint32_t keys[12], uint64_t key, uint64_t da
}
/**
- * \brief "MultiSwap" decryption
- * \param keys 32 bit numbers in machine endianness,
+ * @brief "MultiSwap" decryption
+ * @param keys 32 bit numbers in machine endianness,
* 0-4 and 6-10 must be inverted from encryption
- * \param key another key, this one must be the same as for the encryption
- * \param data data to decrypt
- * \return decrypted data
+ * @param key another key, this one must be the same as for the encryption
+ * @param data data to decrypt
+ * @return decrypted data
*/
static uint64_t multiswap_dec(const uint32_t keys[12], uint64_t key, uint64_t data) {
uint32_t a;
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 16bba93..91d285e 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -25,8 +25,10 @@
#include "libavutil/common.h"
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
#include "libavcodec/mpegaudio.h"
#include "avformat.h"
+#include "internal.h"
#include "avio_internal.h"
#include "riff.h"
#include "asf.h"
@@ -84,13 +86,11 @@ static const ff_asf_guid index_guid = {
0x90, 0x08, 0x00, 0x33, 0xb1, 0xe5, 0xcf, 0x11, 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb
};
+#ifdef DEBUG
static const ff_asf_guid stream_bitrate_guid = { /* (http://get.to/sdp) */
0xce, 0x75, 0xf8, 0x7b, 0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2
};
-/**********************************/
-/* decoding */
-#ifdef DEBUG
#define PRINT_IF_GUID(g,cmp) \
if (!ff_guidcmp(g, &cmp)) \
av_dlog(NULL, "(GUID: %s) ", #cmp)
@@ -228,10 +228,10 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
pos1 = avio_tell(pb);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
+ avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
asf_st = av_mallocz(sizeof(ASFStream));
if (!asf_st)
return AVERROR(ENOMEM);
@@ -363,7 +363,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
/* 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 */
+ /* This is true for all paletted codecs implemented in libavcodec */
if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
int av_unused i;
#if HAVE_BIGENDIAN
@@ -574,7 +574,7 @@ static int asf_read_marker(AVFormatContext *s, int64_t size)
name_len = avio_rl32(pb); // name length
if ((ret = avio_get_str16le(pb, name_len * 2, name, sizeof(name))) < name_len)
avio_skip(pb, name_len - ret);
- ff_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name );
+ avpriv_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name );
}
return 0;
@@ -979,7 +979,7 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
asf_st->packet_pos= asf->packet_pos;
if (asf_st->pkt.data && asf_st->palette_changed) {
uint8_t *pal;
- pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
+ pal = av_packet_new_side_data(&asf_st->pkt, AV_PKT_DATA_PALETTE,
AVPALETTE_SIZE);
if (!pal) {
av_log(s, AV_LOG_ERROR, "Cannot append palette to packet\n");
@@ -1101,8 +1101,6 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1);
asf->packet_time_start = 0;
}
-
- return 0;
}
// Added to support seeking after packets have been read
@@ -1170,12 +1168,12 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos,
//printf("asf_read_pts\n");
asf_reset_header(s);
for(;;){
- if (av_read_frame(s, pkt) < 0){
+ if (asf_read_packet(s, pkt) < 0){
av_log(s, AV_LOG_INFO, "asf_read_pts failed\n");
return AV_NOPTS_VALUE;
}
- pts= pkt->pts;
+ pts = pkt->dts;
av_free_packet(pkt);
if(pkt->flags&AV_PKT_FLAG_KEY){
@@ -1285,21 +1283,21 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int
}
}
/* no index or seeking by index failed */
- if(av_seek_frame_binary(s, stream_index, pts, flags)<0)
+ if (ff_seek_frame_binary(s, stream_index, pts, flags) < 0)
return -1;
asf_reset_header(s);
return 0;
}
AVInputFormat ff_asf_demuxer = {
- "asf",
- NULL_IF_CONFIG_SMALL("ASF format"),
- sizeof(ASFContext),
- asf_probe,
- asf_read_header,
- asf_read_packet,
- asf_read_close,
- asf_read_seek,
- asf_read_pts,
+ .name = "asf",
+ .long_name = NULL_IF_CONFIG_SMALL("ASF format"),
+ .priv_data_size = sizeof(ASFContext),
+ .read_probe = asf_probe,
+ .read_header = asf_read_header,
+ .read_packet = asf_read_packet,
+ .read_close = asf_read_close,
+ .read_seek = asf_read_seek,
+ .read_timestamp = asf_read_pts,
.flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH,
};
diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c
index f9b9b3c..1cfc857 100644
--- a/libavformat/asfenc.c
+++ b/libavformat/asfenc.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
#include "asf.h"
#include "avio_internal.h"
@@ -321,7 +322,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
for(n=0;n<s->nb_streams;n++) {
enc = s->streams[n]->codec;
- av_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */
+ avpriv_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */
bit_rate += enc->bit_rate;
}
@@ -434,10 +435,6 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
/* WAVEFORMATEX header */
int wavsize = ff_put_wav_header(pb, enc);
- if ((enc->codec_id != CODEC_ID_MP3) && (enc->codec_id != CODEC_ID_MP2) && (enc->codec_id != CODEC_ID_ADPCM_IMA_WAV) && (enc->extradata_size==0)) {
- wavsize += 2;
- avio_wl16(pb, 0);
- }
if (wavsize < 0)
return -1;
@@ -882,20 +879,20 @@ static int asf_write_trailer(AVFormatContext *s)
#if CONFIG_ASF_MUXER
AVOutputFormat ff_asf_muxer = {
- "asf",
- NULL_IF_CONFIG_SMALL("ASF format"),
- "video/x-ms-asf",
- "asf,wmv,wma",
- sizeof(ASFContext),
+ .name = "asf",
+ .long_name = NULL_IF_CONFIG_SMALL("ASF format"),
+ .mime_type = "video/x-ms-asf",
+ .extensions = "asf,wmv,wma",
+ .priv_data_size = sizeof(ASFContext),
#if CONFIG_LIBMP3LAME
- CODEC_ID_MP3,
+ .audio_codec = CODEC_ID_MP3,
#else
- CODEC_ID_MP2,
+ .audio_codec = CODEC_ID_MP2,
#endif
- CODEC_ID_MSMPEG4V3,
- asf_write_header,
- asf_write_packet,
- asf_write_trailer,
+ .video_codec = CODEC_ID_MSMPEG4V3,
+ .write_header = asf_write_header,
+ .write_packet = asf_write_packet,
+ .write_trailer = asf_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0},
};
@@ -903,20 +900,20 @@ AVOutputFormat ff_asf_muxer = {
#if CONFIG_ASF_STREAM_MUXER
AVOutputFormat ff_asf_stream_muxer = {
- "asf_stream",
- NULL_IF_CONFIG_SMALL("ASF format"),
- "video/x-ms-asf",
- "asf,wmv,wma",
- sizeof(ASFContext),
+ .name = "asf_stream",
+ .long_name = NULL_IF_CONFIG_SMALL("ASF format"),
+ .mime_type = "video/x-ms-asf",
+ .extensions = "asf,wmv,wma",
+ .priv_data_size = sizeof(ASFContext),
#if CONFIG_LIBMP3LAME
- CODEC_ID_MP3,
+ .audio_codec = CODEC_ID_MP3,
#else
- CODEC_ID_MP2,
+ .audio_codec = CODEC_ID_MP2,
#endif
- CODEC_ID_MSMPEG4V3,
- asf_write_stream_header,
- asf_write_packet,
- asf_write_trailer,
+ .video_codec = CODEC_ID_MSMPEG4V3,
+ .write_header = asf_write_stream_header,
+ .write_packet = asf_write_packet,
+ .write_trailer = asf_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0},
};
diff --git a/libavformat/assdec.c b/libavformat/assdec.c
index b270200..b100f2c 100644
--- a/libavformat/assdec.c
+++ b/libavformat/assdec.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/mathematics.h"
#include "avformat.h"
#include "internal.h"
@@ -82,10 +83,10 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
uint8_t *p, **dst[2]={0};
int pos[2]={0};
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
- av_set_pts_info(st, 64, 1, 100);
+ avpriv_set_pts_info(st, 64, 1, 100);
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codec->codec_id= CODEC_ID_SSA;
diff --git a/libavformat/au.c b/libavformat/au.c
index 6cffe1c..c6fb8db 100644
--- a/libavformat/au.c
+++ b/libavformat/au.c
@@ -28,6 +28,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "avio_internal.h"
#include "pcm.h"
#include "riff.h"
@@ -35,7 +36,7 @@
/* if we don't know the size in advance */
#define AU_UNKNOWN_SIZE ((uint32_t)(~0))
-/* The ffmpeg codecs we support, and the IDs they have in the file */
+/* The libavcodec codecs we support, and the IDs they have in the file */
static const AVCodecTag codec_au_tags[] = {
{ CODEC_ID_PCM_MULAW, 1 },
{ CODEC_ID_PCM_S8, 2 },
@@ -151,7 +152,7 @@ static int au_read_header(AVFormatContext *s,
}
/* now we are ready: build format streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -159,7 +160,7 @@ static int au_read_header(AVFormatContext *s,
st->codec->codec_id = codec;
st->codec->channels = channels;
st->codec->sample_rate = rate;
- av_set_pts_info(st, 64, 1, rate);
+ avpriv_set_pts_info(st, 64, 1, rate);
return 0;
}
@@ -185,30 +186,27 @@ static int au_read_packet(AVFormatContext *s,
#if CONFIG_AU_DEMUXER
AVInputFormat ff_au_demuxer = {
- "au",
- NULL_IF_CONFIG_SMALL("SUN AU format"),
- 0,
- au_probe,
- au_read_header,
- au_read_packet,
- NULL,
- pcm_read_seek,
+ .name = "au",
+ .long_name = NULL_IF_CONFIG_SMALL("SUN AU format"),
+ .read_probe = au_probe,
+ .read_header = au_read_header,
+ .read_packet = au_read_packet,
+ .read_seek = pcm_read_seek,
.codec_tag= (const AVCodecTag* const []){codec_au_tags, 0},
};
#endif
#if CONFIG_AU_MUXER
AVOutputFormat ff_au_muxer = {
- "au",
- NULL_IF_CONFIG_SMALL("SUN AU format"),
- "audio/basic",
- "au",
- 0,
- CODEC_ID_PCM_S16BE,
- CODEC_ID_NONE,
- au_write_header,
- au_write_packet,
- au_write_trailer,
+ .name = "au",
+ .long_name = NULL_IF_CONFIG_SMALL("SUN AU format"),
+ .mime_type = "audio/basic",
+ .extensions = "au",
+ .audio_codec = CODEC_ID_PCM_S16BE,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = au_write_header,
+ .write_packet = au_write_packet,
+ .write_trailer = au_write_trailer,
.codec_tag= (const AVCodecTag* const []){codec_au_tags, 0},
};
#endif //CONFIG_AU_MUXER
diff --git a/libavformat/audiointerleave.c b/libavformat/audiointerleave.c
index e4cb1b8..e48f826 100644
--- a/libavformat/audiointerleave.c
+++ b/libavformat/audiointerleave.c
@@ -21,6 +21,7 @@
*/
#include "libavutil/fifo.h"
+#include "libavutil/mathematics.h"
#include "avformat.h"
#include "audiointerleave.h"
#include "internal.h"
diff --git a/libavformat/avc.c b/libavformat/avc.c
index 70a05ec..b0c511e 100644
--- a/libavformat/avc.c
+++ b/libavformat/avc.c
@@ -75,8 +75,11 @@ int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
size = 0;
nal_start = ff_avc_find_startcode(p, end);
- while (nal_start < end) {
- while(!*(nal_start++));
+ for (;;) {
+ while (nal_start < end && !*(nal_start++));
+ if (nal_start == end)
+ break;
+
nal_end = ff_avc_find_startcode(nal_start, end);
avio_wb32(pb, nal_end - nal_start);
avio_write(pb, nal_start, nal_end - nal_start);
@@ -117,22 +120,26 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
end = buf + len;
/* look for sps and pps */
- while (buf < end) {
- unsigned int size;
+ while (end - buf > 4) {
+ uint32_t size;
uint8_t nal_type;
- size = AV_RB32(buf);
- nal_type = buf[4] & 0x1f;
+ size = FFMIN(AV_RB32(buf), end - buf - 4);
+ buf += 4;
+ nal_type = buf[0] & 0x1f;
+
if (nal_type == 7) { /* SPS */
- sps = buf + 4;
+ sps = buf;
sps_size = size;
} else if (nal_type == 8) { /* PPS */
- pps = buf + 4;
+ pps = buf;
pps_size = size;
}
- buf += size + 4;
+
+ buf += size;
}
- assert(sps);
- assert(pps);
+
+ if (!sps || !pps || sps_size < 4 || sps_size > UINT16_MAX || pps_size > UINT16_MAX)
+ return AVERROR_INVALIDDATA;
avio_w8(pb, 1); /* version */
avio_w8(pb, sps[1]); /* profile */
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index c11d650..89b9eda 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -21,26 +21,125 @@
#ifndef AVFORMAT_AVFORMAT_H
#define AVFORMAT_AVFORMAT_H
-
-/**
- * Return the LIBAVFORMAT_VERSION_INT constant.
- */
-unsigned avformat_version(void);
-
/**
- * Return the libavformat build-time configuration.
+ * @file
+ * @ingroup libavf
+ * Main libavformat public API header
*/
-const char *avformat_configuration(void);
/**
- * Return the libavformat license.
+ * @defgroup libavf I/O and Muxing/Demuxing Library
+ * @{
+ *
+ * Libavformat (lavf) is a library for dealing with various media container
+ * formats. Its main two purposes are demuxing - i.e. splitting a media file
+ * into component streams, and the reverse process of muxing - writing supplied
+ * data in a specified container format. It also has an @ref lavf_io
+ * "I/O module" which supports a number of protocols for accessing the data (e.g.
+ * file, tcp, http and others). Before using lavf, you need to call
+ * av_register_all() to register all compiled muxers, demuxers and protocols.
+ * Unless you are absolutely sure you won't use libavformat's network
+ * capabilities, you should also call avformat_network_init().
+ *
+ * A supported input format is described by an AVInputFormat struct, conversely
+ * an output format is described by AVOutputFormat. You can iterate over all
+ * registered input/output formats using the av_iformat_next() /
+ * av_oformat_next() functions. The protocols layer is not part of the public
+ * API, so you can only get the names of supported protocols with the
+ * avio_enum_protocols() function.
+ *
+ * Main lavf structure used for both muxing and demuxing is AVFormatContext,
+ * which exports all information about the file being read or written. As with
+ * most Libav structures, its size is not part of public ABI, so it cannot be
+ * allocated on stack or directly with av_malloc(). To create an
+ * AVFormatContext, use avformat_alloc_context() (some functions, like
+ * avformat_open_input() might do that for you).
+ *
+ * Most importantly an AVFormatContext contains:
+ * @li the @ref AVFormatContext.iformat "input" or @ref AVFormatContext.oformat
+ * "output" format. It is either autodetected or set by user for input;
+ * always set by user for output.
+ * @li an @ref AVFormatContext.streams "array" of AVStreams, which describe all
+ * elementary streams stored in the file. AVStreams are typically referred to
+ * using their index in this array.
+ * @li an @ref AVFormatContext.pb "I/O context". It is either opened by lavf or
+ * set by user for input, always set by user for output (unless you are dealing
+ * with an AVFMT_NOFILE format).
+ *
+ * @defgroup lavf_decoding Demuxing
+ * @{
+ * Demuxers read a media file and split it into chunks of data (@em packets). A
+ * @ref AVPacket "packet" contains one or more frames which belong a single
+ * elementary stream. In lavf API this process is represented by the
+ * avformat_open_input() function for opening a file, av_read_frame() for
+ * reading a single packet and finally avformat_close_input(), which does the
+ * cleanup.
+ *
+ * @section lavf_decoding_open Opening a media file
+ * The minimum information required to open a file is its URL or filename, which
+ * is passed to avformat_open_input(), as in the following code:
+ * @code
+ * const char *url = "in.mp3";
+ * AVFormatContext *s = NULL;
+ * int ret = avformat_open_input(&s, url, NULL, NULL);
+ * if (ret < 0)
+ * abort();
+ * @endcode
+ * The above code attempts to allocate an AVFormatContext, open the
+ * specified file (autodetecting the format) and read the header, exporting the
+ * information stored there into s. Some formats do not have a header or do not
+ * store enough information there, so it is recommended that you call the
+ * avformat_find_stream_info() function which tries to read and decode a few
+ * frames to find missing information.
+ *
+ * In some cases you might want to preallocate an AVFormatContext yourself with
+ * avformat_alloc_context() and do some tweaking on it before passing it to
+ * avformat_open_input(). One such case is when you want to use custom functions
+ * for reading input data instead of lavf internal I/O layer.
+ * To do that, create your own AVIOContext with avio_alloc_context(), passing
+ * your reading callbacks to it. Then set the @em pb field of your
+ * AVFormatContext to newly created AVIOContext.
+ *
+ * After you have finished reading the file, you must close it with
+ * avformat_close_input(). It will free everything associated with the file.
+ *
+ * @section lavf_decoding_read Reading from an opened file
+ *
+ * @section lavf_decoding_seek Seeking
+ * @}
+ *
+ * @defgroup lavf_encoding Muxing
+ * @{
+ * @}
+ *
+ * @defgroup lavf_io I/O Read/Write
+ * @{
+ * @}
+ *
+ * @defgroup lavf_codec Demuxers
+ * @{
+ * @defgroup lavf_codec_native Native Demuxers
+ * @{
+ * @}
+ * @defgroup lavf_codec_wrappers External library wrappers
+ * @{
+ * @}
+ * @}
+ * @defgroup lavf_protos I/O Protocols
+ * @{
+ * @}
+ * @defgroup lavf_internal Internal
+ * @{
+ * @}
+ * @}
+ *
*/
-const char *avformat_license(void);
#include <time.h>
#include <stdio.h> /* FILE */
#include "libavcodec/avcodec.h"
#include "libavutil/dict.h"
+#include "libavutil/log.h"
#include "avio.h"
#include "libavformat/version.h"
@@ -51,10 +150,17 @@ struct AVFormatContext;
/**
* @defgroup metadata_api Public Metadata API
* @{
+ * @ingroup libavf
* The metadata API allows libavformat to export metadata tags to a client
- * application using a sequence of key/value pairs. Like all strings in Libav,
- * metadata must be stored as UTF-8 encoded Unicode. Note that metadata
+ * application when demuxing. Conversely it allows a client application to
+ * set metadata when muxing.
+ *
+ * Metadata is exported or set as pairs of key/value strings in the 'metadata'
+ * fields of the AVFormatContext, AVStream, AVChapter and AVProgram structs
+ * using the @ref lavu_dict "AVDictionary" API. Like all strings in Libav,
+ * metadata is assumed to be UTF-8 encoded Unicode. Note that metadata
* exported by demuxers isn't checked to be valid UTF-8 in most cases.
+ *
* Important concepts to keep in mind:
* - Keys are unique; there can never be 2 tags with the same key. This is
* also meant semantically, i.e., a demuxer should not knowingly produce
@@ -258,7 +364,7 @@ typedef struct AVFormatParameters {
#endif
} AVFormatParameters;
-//! Demuxer will use avio_open, no opened file should be provided by the caller.
+/// Demuxer will use avio_open, no opened file should be provided by the caller.
#define AVFMT_NOFILE 0x0001
#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */
#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */
@@ -273,7 +379,12 @@ typedef struct AVFormatParameters {
#define AVFMT_NOSTREAMS 0x1000 /**< Format does not require any streams */
#define AVFMT_NOBINSEARCH 0x2000 /**< Format does not allow to fallback to binary search via read_timestamp */
#define AVFMT_NOGENSEARCH 0x4000 /**< Format does not allow to fallback to generic search */
+#define AVFMT_NO_BYTE_SEEK 0x8000 /**< Format does not allow seeking by bytes */
+/**
+ * @addtogroup lavf_encoding
+ * @{
+ */
typedef struct AVOutputFormat {
const char *name;
/**
@@ -321,10 +432,25 @@ typedef struct AVOutputFormat {
const AVClass *priv_class; ///< AVClass for the private context
+ /**
+ * Test if the given codec can be stored in this container.
+ *
+ * @return 1 if the codec is supported, 0 if it is not.
+ * A negative number if unknown.
+ */
+ int (*query_codec)(enum CodecID id, int std_compliance);
+
/* private fields */
struct AVOutputFormat *next;
} AVOutputFormat;
+/**
+ * @}
+ */
+/**
+ * @addtogroup lavf_decoding
+ * @{
+ */
typedef struct AVInputFormat {
/**
* A comma separated list of short names for the format. New names
@@ -390,14 +516,16 @@ typedef struct AVInputFormat {
int stream_index, int64_t timestamp, int flags);
#endif
/**
- * Gets the next timestamp in stream[stream_index].time_base units.
+ * Get the next timestamp in stream[stream_index].time_base units.
* @return the timestamp or AV_NOPTS_VALUE if an error occurred
*/
int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index,
int64_t *pos, int64_t pos_limit);
/**
- * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER.
+ * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS,
+ * AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH,
+ * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK.
*/
int flags;
@@ -444,6 +572,9 @@ typedef struct AVInputFormat {
/* private fields */
struct AVInputFormat *next;
} AVInputFormat;
+/**
+ * @}
+ */
enum AVStreamParseType {
AVSTREAM_PARSE_NONE,
@@ -501,8 +632,10 @@ typedef struct AVStream {
AVRational r_frame_rate;
void *priv_data;
+#if FF_API_REORDER_PRIVATE
/* internal data used in av_find_stream_info() */
int64_t first_dts;
+#endif
/**
* encoding: pts generation when outputting stream
@@ -517,17 +650,23 @@ typedef struct AVStream {
* encoding: set by libavformat in av_write_header
*/
AVRational time_base;
+#if FF_API_REORDER_PRIVATE
int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */
+#endif
+#if FF_API_STREAM_COPY
/* ffmpeg.c private use */
- int stream_copy; /**< If set, just copy stream. */
+ attribute_deprecated int stream_copy; /**< If set, just copy stream. */
+#endif
enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed.
+#if FF_API_AVSTREAM_QUALITY
//FIXME move stuff to a flags field?
/**
* Quality, as it has been removed from AVCodecContext and put in AVVideoFrame.
* MN: dunno if that is the right place for it
*/
- float quality;
+ attribute_deprecated float quality;
+#endif
/**
* Decoding: pts of the first frame of the stream, in stream time base.
@@ -544,6 +683,7 @@ typedef struct AVStream {
*/
int64_t duration;
+#if FF_API_REORDER_PRIVATE
/* av_read_frame() support */
enum AVStreamParseType need_parsing;
struct AVCodecParserContext *parser;
@@ -556,14 +696,17 @@ typedef struct AVStream {
support seeking natively. */
int nb_index_entries;
unsigned int index_entries_allocated_size;
+#endif
int64_t nb_frames; ///< number of frames in this stream if known or 0
int disposition; /**< AV_DISPOSITION_* bit field */
+#if FF_API_REORDER_PRIVATE
AVProbeData probe_data;
#define MAX_REORDER_DELAY 16
int64_t pts_buffer[MAX_REORDER_DELAY+1];
+#endif
/**
* sample aspect ratio (0 if unknown)
@@ -574,6 +717,7 @@ typedef struct AVStream {
AVDictionary *metadata;
+#if FF_API_REORDER_PRIVATE
/* Intended mostly for av_read_frame() support. Not supposed to be used by */
/* external applications; try to use something else if at all possible. */
const uint8_t *cur_ptr;
@@ -599,22 +743,32 @@ typedef struct AVStream {
/**
* last packet in packet_buffer for this stream when muxing.
- * used internally, NOT PART OF PUBLIC API, dont read or write from outside of libav*
+ * Used internally, NOT PART OF PUBLIC API, do not read or
+ * write from outside of libav*
*/
struct AVPacketList *last_in_packet_buffer;
+#endif
/**
* Average framerate
*/
AVRational avg_frame_rate;
+ /*****************************************************************
+ * All fields below this line are not part of the public API. They
+ * may not be used outside of libavformat and can be changed and
+ * removed at will.
+ * New public fields should be added right above.
+ *****************************************************************
+ */
+
/**
* Number of frames that have been demuxed during av_find_stream_info()
*/
int codec_info_nb_frames;
/**
- * Stream informations used internally by av_find_stream_info()
+ * Stream information used internally by av_find_stream_info()
*/
#define MAX_STD_TIMEBASES (60*12+5)
struct {
@@ -623,7 +777,51 @@ typedef struct AVStream {
int duration_count;
double duration_error[MAX_STD_TIMEBASES];
int64_t codec_info_duration;
+ int nb_decoded_frames;
} *info;
+#if !FF_API_REORDER_PRIVATE
+ const uint8_t *cur_ptr;
+ int cur_len;
+ AVPacket cur_pkt;
+
+ // Timestamp generation support:
+ /**
+ * Timestamp corresponding to the last dts sync point.
+ *
+ * Initialized when AVCodecParserContext.dts_sync_point >= 0 and
+ * a DTS is received from the underlying container. Otherwise set to
+ * AV_NOPTS_VALUE by default.
+ */
+ int64_t reference_dts;
+ int64_t first_dts;
+ int64_t cur_dts;
+ int last_IP_duration;
+ int64_t last_IP_pts;
+
+ /**
+ * Number of packets to buffer for codec probing
+ */
+#define MAX_PROBE_PACKETS 2500
+ int probe_packets;
+
+ /**
+ * last packet in packet_buffer for this stream when muxing.
+ */
+ struct AVPacketList *last_in_packet_buffer;
+ AVProbeData probe_data;
+#define MAX_REORDER_DELAY 16
+ int64_t pts_buffer[MAX_REORDER_DELAY+1];
+ /* av_read_frame() support */
+ enum AVStreamParseType need_parsing;
+ struct AVCodecParserContext *parser;
+
+ AVIndexEntry *index_entries; /**< Only used if the format does not
+ support seeking natively. */
+ int nb_index_entries;
+ unsigned int index_entries_allocated_size;
+
+ int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */
+#endif
} AVStream;
#define AV_PROGRAM_RUNNING 1
@@ -658,22 +856,67 @@ typedef struct AVChapter {
* New fields can be added to the end with minor version bumps.
* Removal, reordering and changes to existing fields require a major
* version bump.
- * sizeof(AVFormatContext) must not be used outside libav*.
+ * sizeof(AVFormatContext) must not be used outside libav*, use
+ * avformat_alloc_context() to create an AVFormatContext.
*/
typedef struct AVFormatContext {
- const AVClass *av_class; /**< Set by avformat_alloc_context. */
- /* Can only be iformat or oformat, not both at the same time. */
+ /**
+ * A class for logging and AVOptions. Set by avformat_alloc_context().
+ * Exports (de)muxer private options if they exist.
+ */
+ const AVClass *av_class;
+
+ /**
+ * Can only be iformat or oformat, not both at the same time.
+ *
+ * decoding: set by avformat_open_input().
+ * encoding: set by the user.
+ */
struct AVInputFormat *iformat;
struct AVOutputFormat *oformat;
+
+ /**
+ * Format private data. This is an AVOptions-enabled struct
+ * if and only if iformat/oformat.priv_class is not NULL.
+ */
void *priv_data;
+
+ /*
+ * I/O context.
+ *
+ * decoding: either set by the user before avformat_open_input() (then
+ * the user must close it manually) or set by avformat_open_input().
+ * encoding: set by the user.
+ *
+ * Do NOT set this field if AVFMT_NOFILE flag is set in
+ * iformat/oformat.flags. In such a case, the (de)muxer will handle
+ * I/O in some other way and this field will be NULL.
+ */
AVIOContext *pb;
+
+ /**
+ * A list of all streams in the file. New streams are created with
+ * avformat_new_stream().
+ *
+ * decoding: streams are created by libavformat in avformat_open_input().
+ * If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also
+ * appear in av_read_frame().
+ * encoding: streams are created by the user before avformat_write_header().
+ */
unsigned int nb_streams;
AVStream **streams;
+
char filename[1024]; /**< input or output filename */
/* stream info */
- int64_t timestamp;
+#if FF_API_TIMESTAMP
+ /**
+ * @deprecated use 'creation_time' metadata tag instead
+ */
+ attribute_deprecated int64_t timestamp;
+#endif
int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */
+#if FF_API_REORDER_PRIVATE
/* private data for pts handling (do not modify directly). */
/**
* This buffer is only needed when packets were already buffered but
@@ -681,6 +924,7 @@ typedef struct AVFormatContext {
* streams.
*/
struct AVPacketList *packet_buffer;
+#endif
/**
* Decoding: position of the first frame of the component, in
@@ -692,15 +936,17 @@ typedef struct AVFormatContext {
/**
* Decoding: duration of the stream, in AV_TIME_BASE fractional
* seconds. Only set this value if you know none of the individual stream
- * durations and also dont set any of them. This is deduced from the
+ * durations and also do not set any of them. This is deduced from the
* AVStream values if not set.
*/
int64_t duration;
+#if FF_API_FILESIZE
/**
* decoding: total file size, 0 if unknown
*/
- int64_t file_size;
+ attribute_deprecated int64_t file_size;
+#endif
/**
* Decoding: total stream bitrate in bit/s, 0 if not
@@ -709,23 +955,36 @@ typedef struct AVFormatContext {
*/
int bit_rate;
+#if FF_API_REORDER_PRIVATE
/* av_read_frame() support */
AVStream *cur_st;
/* av_seek_frame() support */
int64_t data_offset; /**< offset of the first packet */
+#endif
- int mux_rate;
+#if FF_API_MUXRATE
+ /**
+ * use mpeg muxer private options instead
+ */
+ attribute_deprecated int mux_rate;
+#endif
unsigned int packet_size;
- int preload;
+#if FF_API_PRELOAD
+ attribute_deprecated int preload;
+#endif
int max_delay;
+#if FF_API_LOOP_OUTPUT
#define AVFMT_NOOUTPUTLOOP -1
#define AVFMT_INFINITEOUTPUTLOOP 0
/**
* number of times to loop output in formats that support it
+ *
+ * @deprecated use the 'loop' private option in the gif muxer.
*/
- int loop_output;
+ attribute_deprecated int loop_output;
+#endif
int flags;
#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames.
@@ -738,8 +997,14 @@ typedef struct AVFormatContext {
#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Deprecated, use the -movflags rtphint muxer specific AVOption instead
#endif
#define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
+#define AVFMT_FLAG_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted
- int loop_input;
+#if FF_API_LOOP_INPUT
+ /**
+ * @deprecated, use the 'loop' img2 demuxer private option.
+ */
+ attribute_deprecated int loop_input;
+#endif
/**
* decoding: size of data to probe; encoding: unused.
@@ -747,8 +1012,8 @@ typedef struct AVFormatContext {
unsigned int probesize;
/**
- * Maximum time (in AV_TIME_BASE units) during which the input should
- * be analyzed in av_find_stream_info().
+ * decoding: maximum time (in AV_TIME_BASE units) during which the input should
+ * be analyzed in avformat_find_stream_info().
*/
int max_analyze_duration;
@@ -803,6 +1068,7 @@ typedef struct AVFormatContext {
int debug;
#define FF_FDEBUG_TS 0x0001
+#if FF_API_REORDER_PRIVATE
/**
* Raw packets from the demuxer, prior to parsing and decoding.
* This buffer is used for buffering packets until the codec can
@@ -813,15 +1079,18 @@ typedef struct AVFormatContext {
struct AVPacketList *raw_packet_buffer_end;
struct AVPacketList *packet_buffer_end;
+#endif
AVDictionary *metadata;
+#if FF_API_REORDER_PRIVATE
/**
* Remaining size available for raw_packet_buffer, in bytes.
* NOT PART OF PUBLIC API
*/
#define RAW_PACKET_BUFFER_SIZE 2500000
int raw_packet_buffer_remaining_size;
+#endif
/**
* Start time of the stream in real world time, in microseconds
@@ -836,6 +1105,62 @@ typedef struct AVFormatContext {
* decoding: number of frames used to probe fps
*/
int fps_probe_size;
+
+ /**
+ * Error recognition; higher values will detect more errors but may
+ * misdetect some more or less valid parts as errors.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int error_recognition;
+
+ /**
+ * Custom interrupt callbacks for the I/O layer.
+ *
+ * decoding: set by the user before avformat_open_input().
+ * encoding: set by the user before avformat_write_header()
+ * (mainly useful for AVFMT_NOFILE formats). The callback
+ * should also be passed to avio_open2() if it's used to
+ * open the file.
+ */
+ AVIOInterruptCB interrupt_callback;
+
+ /*****************************************************************
+ * All fields below this line are not part of the public API. They
+ * may not be used outside of libavformat and can be changed and
+ * removed at will.
+ * New public fields should be added right above.
+ *****************************************************************
+ */
+#if !FF_API_REORDER_PRIVATE
+ /**
+ * 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;
+ struct AVPacketList *raw_packet_buffer_end;
+ /**
+ * Remaining size available for raw_packet_buffer, in bytes.
+ */
+#define RAW_PACKET_BUFFER_SIZE 2500000
+ int raw_packet_buffer_remaining_size;
+
+ /**
+ * This buffer is only needed when packets were already buffered but
+ * not decoded, for example to get the codec parameters in MPEG
+ * streams.
+ */
+ struct AVPacketList *packet_buffer;
+ struct AVPacketList *packet_buffer_end;
+
+ /* av_read_frame() support */
+ AVStream *cur_st;
+
+ /* av_seek_frame() support */
+ int64_t data_offset; /**< offset of the first packet */
+#endif
} AVFormatContext;
typedef struct AVPacketList {
@@ -843,140 +1168,134 @@ typedef struct AVPacketList {
struct AVPacketList *next;
} AVPacketList;
+
/**
- * If f is NULL, returns the first registered input format,
- * if f is non-NULL, returns the next registered input format after f
- * or NULL if f is the last one.
+ * @defgroup lavf_core Core functions
+ * @ingroup libavf
+ *
+ * Functions for querying libavformat capabilities, allocating core structures,
+ * etc.
+ * @{
*/
-AVInputFormat *av_iformat_next(AVInputFormat *f);
/**
- * If f is NULL, returns the first registered output format,
- * if f is non-NULL, returns the next registered output format after f
- * or NULL if f is the last one.
+ * Return the LIBAVFORMAT_VERSION_INT constant.
*/
-AVOutputFormat *av_oformat_next(AVOutputFormat *f);
-
-#if FF_API_GUESS_IMG2_CODEC
-attribute_deprecated enum CodecID av_guess_image2_codec(const char *filename);
-#endif
-
-/* XXX: Use automatic init with either ELF sections or C file parser */
-/* modules. */
-
-/* utils.c */
-void av_register_input_format(AVInputFormat *format);
-void av_register_output_format(AVOutputFormat *format);
+unsigned avformat_version(void);
/**
- * Return the output format in the list of registered output formats
- * which best matches the provided parameters, or return NULL if
- * there is no match.
- *
- * @param short_name if non-NULL checks if short_name matches with the
- * names of the registered formats
- * @param filename if non-NULL checks if filename terminates with the
- * extensions of the registered formats
- * @param mime_type if non-NULL checks if mime_type matches with the
- * MIME type of the registered formats
+ * Return the libavformat build-time configuration.
*/
-AVOutputFormat *av_guess_format(const char *short_name,
- const char *filename,
- const char *mime_type);
+const char *avformat_configuration(void);
/**
- * Guess the codec ID based upon muxer and filename.
+ * Return the libavformat license.
*/
-enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
- const char *filename, const char *mime_type,
- enum AVMediaType type);
+const char *avformat_license(void);
/**
- * Send a nice hexadecimal dump of a buffer to the specified file stream.
- *
- * @param f The file stream pointer where the dump should be sent to.
- * @param buf buffer
- * @param size buffer size
+ * Initialize libavformat and register all the muxers, demuxers and
+ * protocols. If you do not call this function, then you can select
+ * exactly which formats you want to support.
*
- * @see av_hex_dump_log, av_pkt_dump2, av_pkt_dump_log2
+ * @see av_register_input_format()
+ * @see av_register_output_format()
+ * @see av_register_protocol()
*/
-void av_hex_dump(FILE *f, uint8_t *buf, int size);
+void av_register_all(void);
+
+void av_register_input_format(AVInputFormat *format);
+void av_register_output_format(AVOutputFormat *format);
/**
- * Send a nice hexadecimal dump of a buffer to the log.
- *
- * @param avcl A pointer to an arbitrary struct of which the first field is a
- * pointer to an AVClass struct.
- * @param level The importance level of the message, lower values signifying
- * higher importance.
- * @param buf buffer
- * @param size buffer size
+ * Do global initialization of network components. This is optional,
+ * but recommended, since it avoids the overhead of implicitly
+ * doing the setup for each session.
*
- * @see av_hex_dump, av_pkt_dump2, av_pkt_dump_log2
+ * Calling this function will become mandatory if using network
+ * protocols at some major version bump.
*/
-void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size);
+int avformat_network_init(void);
/**
- * Send a nice dump of a packet to the specified file stream.
- *
- * @param f The file stream pointer where the dump should be sent to.
- * @param pkt packet to dump
- * @param dump_payload True if the payload must be displayed, too.
- * @param st AVStream that the packet belongs to
+ * Undo the initialization done by avformat_network_init.
*/
-void av_pkt_dump2(FILE *f, AVPacket *pkt, int dump_payload, AVStream *st);
+int avformat_network_deinit(void);
+/**
+ * If f is NULL, returns the first registered input format,
+ * if f is non-NULL, returns the next registered input format after f
+ * or NULL if f is the last one.
+ */
+AVInputFormat *av_iformat_next(AVInputFormat *f);
/**
- * Send a nice dump of a packet to the log.
- *
- * @param avcl A pointer to an arbitrary struct of which the first field is a
- * pointer to an AVClass struct.
- * @param level The importance level of the message, lower values signifying
- * higher importance.
- * @param pkt packet to dump
- * @param dump_payload True if the payload must be displayed, too.
- * @param st AVStream that the packet belongs to
+ * If f is NULL, returns the first registered output format,
+ * if f is non-NULL, returns the next registered output format after f
+ * or NULL if f is the last one.
*/
-void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload,
- AVStream *st);
+AVOutputFormat *av_oformat_next(AVOutputFormat *f);
-#if FF_API_PKT_DUMP
-attribute_deprecated void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
-attribute_deprecated void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt,
- int dump_payload);
-#endif
+/**
+ * Allocate an AVFormatContext.
+ * avformat_free_context() can be used to free the context and everything
+ * allocated by the framework within it.
+ */
+AVFormatContext *avformat_alloc_context(void);
/**
- * Initialize libavformat and register all the muxers, demuxers and
- * protocols. If you do not call this function, then you can select
- * exactly which formats you want to support.
- *
- * @see av_register_input_format()
- * @see av_register_output_format()
- * @see av_register_protocol()
+ * Free an AVFormatContext and all its streams.
+ * @param s context to free
*/
-void av_register_all(void);
+void avformat_free_context(AVFormatContext *s);
/**
- * Get the CodecID for the given codec tag tag.
- * If no codec id is found returns CODEC_ID_NONE.
+ * Get the AVClass for AVFormatContext. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
*
- * @param tags list of supported codec_id-codec_tag pairs, as stored
- * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ * @see av_opt_find().
*/
-enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag);
+const AVClass *avformat_get_class(void);
/**
- * Get the codec tag for the given codec id id.
- * If no codec tag is found returns 0.
+ * Add a new stream to a media file.
*
- * @param tags list of supported codec_id-codec_tag pairs, as stored
- * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ * When demuxing, it is called by the demuxer in read_header(). If the
+ * flag AVFMTCTX_NOHEADER is set in s.ctx_flags, then it may also
+ * be called in read_packet().
+ *
+ * When muxing, should be called by the user before avformat_write_header().
+ *
+ * @param c If non-NULL, the AVCodecContext corresponding to the new stream
+ * will be initialized to use this codec. This is needed for e.g. codec-specific
+ * defaults to be set, so codec should be provided if it is known.
+ *
+ * @return newly created stream or NULL on error.
*/
-unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id);
+AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c);
-/* media file input */
+AVProgram *av_new_program(AVFormatContext *s, int id);
+
+/**
+ * @}
+ */
+
+
+#if FF_API_GUESS_IMG2_CODEC
+attribute_deprecated enum CodecID av_guess_image2_codec(const char *filename);
+#endif
+
+#if FF_API_PKT_DUMP
+attribute_deprecated void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
+attribute_deprecated void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt,
+ int dump_payload);
+#endif
+
+
+/**
+ * @addtogroup lavf_decoding
+ * @{
+ */
/**
* Find AVInputFormat based on the short name of the input format.
@@ -1074,13 +1393,6 @@ attribute_deprecated int av_open_input_file(AVFormatContext **ic_ptr, const char
*/
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
-/**
- * Allocate an AVFormatContext.
- * avformat_free_context() can be used to free the context and everything
- * allocated by the framework within it.
- */
-AVFormatContext *avformat_alloc_context(void);
-
#if FF_API_FORMAT_PARAMETERS
/**
* Read packets of a media file to get stream information. This
@@ -1097,6 +1409,7 @@ AVFormatContext *avformat_alloc_context(void);
*
* @deprecated use avformat_find_stream_info.
*/
+attribute_deprecated
int av_find_stream_info(AVFormatContext *ic);
#endif
@@ -1247,25 +1560,37 @@ int av_read_play(AVFormatContext *s);
*/
int av_read_pause(AVFormatContext *s);
+#if FF_API_FORMAT_PARAMETERS
/**
* Free a AVFormatContext allocated by av_open_input_stream.
* @param s context to free
+ * @deprecated use av_close_input_file()
*/
+attribute_deprecated
void av_close_input_stream(AVFormatContext *s);
+#endif
+#if FF_API_CLOSE_INPUT_FILE
/**
+ * @deprecated use avformat_close_input()
* Close a media file (but not its codecs).
*
* @param s media file handle
*/
+attribute_deprecated
void av_close_input_file(AVFormatContext *s);
+#endif
/**
- * Free an AVFormatContext and all its streams.
- * @param s context to free
+ * Close an opened input AVFormatContext. Free it and all its contents
+ * and set *s to NULL.
+ */
+void avformat_close_input(AVFormatContext **s);
+/**
+ * @}
*/
-void avformat_free_context(AVFormatContext *s);
+#if FF_API_NEW_STREAM
/**
* Add a new stream to a media file.
*
@@ -1276,86 +1601,39 @@ void avformat_free_context(AVFormatContext *s);
* @param s media file handle
* @param id file-format-dependent stream ID
*/
+attribute_deprecated
AVStream *av_new_stream(AVFormatContext *s, int id);
-AVProgram *av_new_program(AVFormatContext *s, int id);
+#endif
+#if FF_API_SET_PTS_INFO
/**
- * Set the pts for a given stream. If the new values would be invalid
- * (<= 0), it leaves the AVStream unchanged.
- *
- * @param s stream
- * @param pts_wrap_bits number of bits effectively used by the pts
- * (used for wrap control, 33 is the value for MPEG)
- * @param pts_num numerator to convert to seconds (MPEG: 1)
- * @param pts_den denominator to convert to seconds (MPEG: 90000)
+ * @deprecated this function is not supposed to be called outside of lavf
*/
+attribute_deprecated
void av_set_pts_info(AVStream *s, int pts_wrap_bits,
unsigned int pts_num, unsigned int pts_den);
+#endif
#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward
#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes
#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes
#define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number
-int av_find_default_stream_index(AVFormatContext *s);
-
-/**
- * Get the index for a specific timestamp.
- * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond
- * to the timestamp which is <= the requested one, if backward
- * is 0, then it will be >=
- * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise
- * @return < 0 if no such timestamp could be found
- */
-int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
-
-/**
- * Add an index entry into a sorted list. Update the entry if the list
- * already contains it.
- *
- * @param timestamp timestamp in the time base of the given stream
- */
-int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
- int size, int distance, int flags);
-
-/**
- * Perform a binary search using av_index_search_timestamp() and
- * AVInputFormat.read_timestamp().
- * This is not supposed to be called directly by a user application,
- * but by demuxers.
- * @param target_ts target timestamp in the time base of the given stream
- * @param stream_index stream number
- */
+#if FF_API_SEEK_PUBLIC
+attribute_deprecated
int av_seek_frame_binary(AVFormatContext *s, int stream_index,
int64_t target_ts, int flags);
-
-/**
- * Update cur_dts of all streams based on the given timestamp and AVStream.
- *
- * Stream ref_st unchanged, others set cur_dts in their native time base.
- * Only needed for timestamp wrapping or if (dts not set and pts!=dts).
- * @param timestamp new dts expressed in time_base of param ref_st
- * @param ref_st reference stream giving time_base of param timestamp
- */
+attribute_deprecated
void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
-
-/**
- * Perform a binary search using read_timestamp().
- * This is not supposed to be called directly by a user application,
- * but by demuxers.
- * @param target_ts target timestamp in the time base of the given stream
- * @param stream_index stream number
- */
+attribute_deprecated
int64_t av_gen_search(AVFormatContext *s, int stream_index,
int64_t target_ts, int64_t pos_min,
int64_t pos_max, int64_t pos_limit,
int64_t ts_min, int64_t ts_max,
int flags, int64_t *ts_ret,
int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
+#endif
-/**
- * media file output
- */
#if FF_API_FORMAT_PARAMETERS
/**
* @deprecated pass the options to avformat_write_header directly.
@@ -1364,31 +1642,9 @@ attribute_deprecated int av_set_parameters(AVFormatContext *s, AVFormatParameter
#endif
/**
- * Split a URL string into components.
- *
- * The pointers to buffers for storing individual components may be null,
- * in order to ignore that component. Buffers for components not found are
- * set to empty strings. If the port is not found, it is set to a negative
- * value.
- *
- * @param proto the buffer for the protocol
- * @param proto_size the size of the proto buffer
- * @param authorization the buffer for the authorization
- * @param authorization_size the size of the authorization buffer
- * @param hostname the buffer for the host name
- * @param hostname_size the size of the hostname buffer
- * @param port_ptr a pointer to store the port number in
- * @param path the buffer for the path
- * @param path_size the size of the path buffer
- * @param url the URL to split
+ * @addtogroup lavf_encoding
+ * @{
*/
-void av_url_split(char *proto, int proto_size,
- char *authorization, int authorization_size,
- char *hostname, int hostname_size,
- int *port_ptr,
- char *path, int path_size,
- const char *url);
-
/**
* Allocate the stream private data and write the stream header to
* an output media file.
@@ -1481,6 +1737,159 @@ int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
*/
int av_write_trailer(AVFormatContext *s);
+/**
+ * Return the output format in the list of registered output formats
+ * which best matches the provided parameters, or return NULL if
+ * there is no match.
+ *
+ * @param short_name if non-NULL checks if short_name matches with the
+ * names of the registered formats
+ * @param filename if non-NULL checks if filename terminates with the
+ * extensions of the registered formats
+ * @param mime_type if non-NULL checks if mime_type matches with the
+ * MIME type of the registered formats
+ */
+AVOutputFormat *av_guess_format(const char *short_name,
+ const char *filename,
+ const char *mime_type);
+
+/**
+ * Guess the codec ID based upon muxer and filename.
+ */
+enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
+ const char *filename, const char *mime_type,
+ enum AVMediaType type);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup lavf_misc Utility functions
+ * @ingroup libavf
+ * @{
+ *
+ * Miscelaneous utility functions related to both muxing and demuxing
+ * (or neither).
+ */
+
+/**
+ * Send a nice hexadecimal dump of a buffer to the specified file stream.
+ *
+ * @param f The file stream pointer where the dump should be sent to.
+ * @param buf buffer
+ * @param size buffer size
+ *
+ * @see av_hex_dump_log, av_pkt_dump2, av_pkt_dump_log2
+ */
+void av_hex_dump(FILE *f, uint8_t *buf, int size);
+
+/**
+ * Send a nice hexadecimal dump of a buffer to the log.
+ *
+ * @param avcl A pointer to an arbitrary struct of which the first field is a
+ * pointer to an AVClass struct.
+ * @param level The importance level of the message, lower values signifying
+ * higher importance.
+ * @param buf buffer
+ * @param size buffer size
+ *
+ * @see av_hex_dump, av_pkt_dump2, av_pkt_dump_log2
+ */
+void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size);
+
+/**
+ * Send a nice dump of a packet to the specified file stream.
+ *
+ * @param f The file stream pointer where the dump should be sent to.
+ * @param pkt packet to dump
+ * @param dump_payload True if the payload must be displayed, too.
+ * @param st AVStream that the packet belongs to
+ */
+void av_pkt_dump2(FILE *f, AVPacket *pkt, int dump_payload, AVStream *st);
+
+
+/**
+ * Send a nice dump of a packet to the log.
+ *
+ * @param avcl A pointer to an arbitrary struct of which the first field is a
+ * pointer to an AVClass struct.
+ * @param level The importance level of the message, lower values signifying
+ * higher importance.
+ * @param pkt packet to dump
+ * @param dump_payload True if the payload must be displayed, too.
+ * @param st AVStream that the packet belongs to
+ */
+void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload,
+ AVStream *st);
+
+/**
+ * Get the CodecID for the given codec tag tag.
+ * If no codec id is found returns CODEC_ID_NONE.
+ *
+ * @param tags list of supported codec_id-codec_tag pairs, as stored
+ * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ */
+enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag);
+
+/**
+ * Get the codec tag for the given codec id id.
+ * If no codec tag is found returns 0.
+ *
+ * @param tags list of supported codec_id-codec_tag pairs, as stored
+ * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ */
+unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id);
+
+int av_find_default_stream_index(AVFormatContext *s);
+
+/**
+ * Get the index for a specific timestamp.
+ * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond
+ * to the timestamp which is <= the requested one, if backward
+ * is 0, then it will be >=
+ * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise
+ * @return < 0 if no such timestamp could be found
+ */
+int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
+
+/**
+ * Add an index entry into a sorted list. Update the entry if the list
+ * already contains it.
+ *
+ * @param timestamp timestamp in the time base of the given stream
+ */
+int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
+ int size, int distance, int flags);
+
+
+/**
+ * Split a URL string into components.
+ *
+ * The pointers to buffers for storing individual components may be null,
+ * in order to ignore that component. Buffers for components not found are
+ * set to empty strings. If the port is not found, it is set to a negative
+ * value.
+ *
+ * @param proto the buffer for the protocol
+ * @param proto_size the size of the proto buffer
+ * @param authorization the buffer for the authorization
+ * @param authorization_size the size of the authorization buffer
+ * @param hostname the buffer for the host name
+ * @param hostname_size the size of the hostname buffer
+ * @param port_ptr a pointer to store the port number in
+ * @param path the buffer for the path
+ * @param path_size the size of the path buffer
+ * @param url the URL to split
+ */
+void av_url_split(char *proto, int proto_size,
+ char *authorization, int authorization_size,
+ char *hostname, int hostname_size,
+ int *port_ptr,
+ char *path, int path_size,
+ const char *url);
+
#if FF_API_DUMP_FORMAT
attribute_deprecated void dump_format(AVFormatContext *ic,
int index,
@@ -1568,4 +1977,18 @@ attribute_deprecated int avf_sdp_create(AVFormatContext *ac[], int n_files, char
*/
int av_match_ext(const char *filename, const char *extensions);
+/**
+ * Test if the given container can store a codec.
+ *
+ * @param std_compliance standards compliance level, one of FF_COMPLIANCE_*
+ *
+ * @return 1 if codec with ID codec_id can be stored in ofmt, 0 if it cannot.
+ * A negative number if this information is not available.
+ */
+int avformat_query_codec(AVOutputFormat *ofmt, enum CodecID codec_id, int std_compliance);
+
+/**
+ * @}
+ */
+
#endif /* AVFORMAT_AVFORMAT_H */
diff --git a/libavformat/avi.c b/libavformat/avi.c
deleted file mode 100644
index 9f36b27..0000000
--- a/libavformat/avi.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * AVI common data
- * Copyright (c) 2010 Anton Khirnov
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "avi.h"
-
-const AVMetadataConv ff_avi_metadata_conv[] = {
- { "IART", "artist" },
- { "ICMT", "comment" },
- { "ICOP", "copyright" },
- { "ICRD", "date" },
- { "IGNR", "genre" },
- { "ILNG", "language" },
- { "INAM", "title" },
- { "IPRD", "album" },
- { "IPRT", "track" },
- { "ISFT", "encoder" },
- { "ITCH", "encoded_by"},
- { "strn", "title" },
- { 0 },
-};
-
-const char ff_avi_tags[][5] = {
- "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
- "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
- "IPRT", "ISBJ", "ISFT", "ISHP", "ISRC", "ISRF", "ITCH",
- {0}
-};
diff --git a/libavformat/avi.h b/libavformat/avi.h
index 05e0297..e05db9c 100644
--- a/libavformat/avi.h
+++ b/libavformat/avi.h
@@ -21,8 +21,6 @@
#ifndef AVFORMAT_AVI_H
#define AVFORMAT_AVI_H
-#include "metadata.h"
-
#define AVIF_HASINDEX 0x00000010 // Index at end of file?
#define AVIF_MUSTUSEINDEX 0x00000020
#define AVIF_ISINTERLEAVED 0x00000100
@@ -37,11 +35,4 @@
/* index flags */
#define AVIIF_INDEX 0x10
-extern const AVMetadataConv ff_avi_metadata_conv[];
-
-/**
- * A list of AVI info tags.
- */
-extern const char ff_avi_tags[][5];
-
#endif /* AVFORMAT_AVI_H */
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 85fc794..b45224f 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -19,11 +19,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <strings.h>
#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
#include "libavutil/bswap.h"
#include "libavutil/dict.h"
+#include "libavutil/avstring.h"
#include "avformat.h"
+#include "internal.h"
#include "avi.h"
#include "dv.h"
#include "riff.h"
@@ -78,6 +80,11 @@ static const char avi_headers[][8] = {
{ 0 }
};
+static const AVMetadataConv avi_metadata_conv[] = {
+ { "strn", "title" },
+ { 0 },
+};
+
static int avi_load_index(AVFormatContext *s);
static int guess_ni_flag(AVFormatContext *s);
@@ -260,15 +267,6 @@ static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t
AV_DICT_DONT_STRDUP_VAL);
}
-static void avi_read_info(AVFormatContext *s, uint64_t end)
-{
- while (avio_tell(s->pb) < end) {
- uint32_t tag = avio_rl32(s->pb);
- uint32_t size = avio_rl32(s->pb);
- avi_read_tag(s, NULL, tag, size);
- }
-}
-
static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
@@ -280,7 +278,7 @@ static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
month, &day, time, &year) == 4) {
for (i=0; i<12; i++)
- if (!strcasecmp(month, months[i])) {
+ if (!av_strcasecmp(month, months[i])) {
snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
year, i+1, day, time);
av_dict_set(metadata, "creation_time", buffer, 0);
@@ -379,7 +377,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
goto end_of_header;
}
else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
- avi_read_info(s, list_end);
+ ff_read_riff_info(s, size - 4);
else if (tag1 == MKTAG('n', 'c', 'd', 't'))
avi_read_nikon(s, list_end);
@@ -425,10 +423,11 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
break;
}else{
stream_index++;
- st = av_new_stream(s, stream_index);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
+ st->id = stream_index;
ast = av_mallocz(sizeof(AVIStream));
if (!ast)
goto fail;
@@ -460,7 +459,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
av_freep(&s->streams[0]);
s->nb_streams = 0;
if (CONFIG_DV_DEMUXER) {
- avi->dv_demux = dv_init_demux(s);
+ avi->dv_demux = avpriv_dv_init_demux(s);
if (!avi->dv_demux)
goto fail;
}
@@ -504,7 +503,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
ast->scale = 1;
}
}
- av_set_pts_info(st, 64, ast->scale, ast->rate);
+ avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
ast->cum_len=avio_rl32(pb); /* start */
st->nb_frames = avio_rl32(pb);
@@ -666,8 +665,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
break;
case MKTAG('i', 'n', 'd', 'x'):
i= avio_tell(pb);
- if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX)){
- read_braindead_odml_indx(s, 0);
+ if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
+ read_braindead_odml_indx(s, 0) < 0 && s->error_recognition >= FF_ER_EXPLODE){
+ goto fail;
}
avio_seek(pb, i+size, SEEK_SET);
break;
@@ -705,6 +705,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
if(size > 1000000){
av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, "
"I will ignore it and try to continue anyway.\n");
+ if (s->error_recognition >= FF_ER_EXPLODE) goto fail;
avi->movi_list = avio_tell(pb) - 4;
avi->movi_end = avio_size(pb);
goto end_of_header;
@@ -741,7 +742,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
clean_index(s);
}
- ff_metadata_conv_ctx(s, NULL, ff_avi_metadata_conv);
+ ff_metadata_conv_ctx(s, NULL, avi_metadata_conv);
+ ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
return 0;
}
@@ -783,7 +785,7 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
*st->codec = *ast->sub_ctx->streams[0]->codec;
ast->sub_ctx->streams[0]->codec->extradata = NULL;
time_base = ast->sub_ctx->streams[0]->time_base;
- av_set_pts_info(st, 64, time_base.num, time_base.den);
+ avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
}
ast->sub_buffer = pkt->data;
memset(pkt, 0, sizeof(*pkt));
@@ -836,17 +838,146 @@ static int get_stream_idx(int *d){
}
}
-static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
+static int avi_sync(AVFormatContext *s, int exit_early)
{
AVIContext *avi = s->priv_data;
AVIOContext *pb = s->pb;
- int n, d[8];
+ int n;
+ unsigned int d[8];
unsigned int size;
int64_t i, sync;
+
+start_sync:
+ memset(d, -1, sizeof(d));
+ for(i=sync=avio_tell(pb); !pb->eof_reached; i++) {
+ int j;
+
+ for(j=0; j<7; j++)
+ d[j]= d[j+1];
+ d[7]= avio_r8(pb);
+
+ size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);
+
+ n= get_stream_idx(d+2);
+//av_log(s, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
+ if(i + (uint64_t)size > avi->fsize || d[0] > 127)
+ continue;
+
+ //parse ix##
+ if( (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams)
+ //parse JUNK
+ ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K')
+ ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){
+ avio_skip(pb, size);
+//av_log(s, AV_LOG_DEBUG, "SKIP\n");
+ goto start_sync;
+ }
+
+ //parse stray LIST
+ if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){
+ avio_skip(pb, 4);
+ goto start_sync;
+ }
+
+ n= get_stream_idx(d);
+
+ if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams)
+ continue;
+
+ //detect ##ix chunk and skip
+ if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){
+ avio_skip(pb, size);
+ goto start_sync;
+ }
+
+ //parse ##dc/##wb
+ if(n < s->nb_streams){
+ AVStream *st;
+ AVIStream *ast;
+ st = s->streams[n];
+ ast = st->priv_data;
+
+ if(s->nb_streams>=2){
+ AVStream *st1 = s->streams[1];
+ AVIStream *ast1= st1->priv_data;
+ //workaround for broken small-file-bug402.avi
+ if( d[2] == 'w' && d[3] == 'b'
+ && n==0
+ && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
+ && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
+ && ast->prefix == 'd'*256+'c'
+ && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
+ ){
+ n=1;
+ st = st1;
+ ast = ast1;
+ av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n");
+ }
+ }
+
+
+ if( (st->discard >= AVDISCARD_DEFAULT && size==0)
+ /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
+ || st->discard >= AVDISCARD_ALL){
+ if (!exit_early) {
+ ast->frame_offset += get_duration(ast, size);
+ }
+ avio_skip(pb, size);
+ goto start_sync;
+ }
+
+ if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) {
+ int k = avio_r8(pb);
+ int last = (k + avio_r8(pb) - 1) & 0xFF;
+
+ avio_rl16(pb); //flags
+
+ for (; k <= last; k++)
+ ast->pal[k] = avio_rb32(pb)>>8;// b + (g << 8) + (r << 16);
+ ast->has_pal= 1;
+ goto start_sync;
+ } else if( ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
+ d[2]*256+d[3] == ast->prefix /*||
+ (d[2] == 'd' && d[3] == 'c') ||
+ (d[2] == 'w' && d[3] == 'b')*/) {
+
+ if (exit_early)
+ return 0;
+//av_log(s, AV_LOG_DEBUG, "OK\n");
+ if(d[2]*256+d[3] == ast->prefix)
+ ast->prefix_count++;
+ else{
+ ast->prefix= d[2]*256+d[3];
+ ast->prefix_count= 0;
+ }
+
+ avi->stream_index= n;
+ ast->packet_size= size + 8;
+ ast->remaining= size;
+
+ if(size || !ast->sample_size){
+ uint64_t pos= avio_tell(pb) - 8;
+ if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){
+ av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME);
+ }
+ }
+ return 0;
+ }
+ }
+ }
+
+ return AVERROR_EOF;
+}
+
+static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ AVIContext *avi = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int err;
void* dstr;
if (CONFIG_DV_DEMUXER && avi->dv_demux) {
- int size = dv_get_packet(avi->dv_demux, pkt);
+ int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
if (size >= 0)
return size;
}
@@ -946,7 +1077,7 @@ resync:
if (CONFIG_DV_DEMUXER && avi->dv_demux) {
dstr = pkt->destruct;
- size = dv_produce_packet(avi->dv_demux, pkt,
+ size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
pkt->data, pkt->size);
pkt->destruct = dstr;
pkt->flags |= AV_PKT_FLAG_KEY;
@@ -993,121 +1124,9 @@ resync:
return size;
}
- memset(d, -1, sizeof(int)*8);
- for(i=sync=avio_tell(pb); !pb->eof_reached; i++) {
- int j;
-
- for(j=0; j<7; j++)
- d[j]= d[j+1];
- d[7]= avio_r8(pb);
-
- size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);
-
- n= get_stream_idx(d+2);
-//av_log(s, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
- if(i + (uint64_t)size > avi->fsize || d[0]<0)
- continue;
-
- //parse ix##
- if( (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams)
- //parse JUNK
- ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K')
- ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){
- avio_skip(pb, size);
-//av_log(s, AV_LOG_DEBUG, "SKIP\n");
- goto resync;
- }
-
- //parse stray LIST
- if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){
- avio_skip(pb, 4);
- goto resync;
- }
-
- n= get_stream_idx(d);
-
- if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams)
- continue;
-
- //detect ##ix chunk and skip
- if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){
- avio_skip(pb, size);
- goto resync;
- }
-
- //parse ##dc/##wb
- if(n < s->nb_streams){
- AVStream *st;
- AVIStream *ast;
- st = s->streams[n];
- ast = st->priv_data;
-
- if(s->nb_streams>=2){
- AVStream *st1 = s->streams[1];
- AVIStream *ast1= st1->priv_data;
- //workaround for broken small-file-bug402.avi
- if( d[2] == 'w' && d[3] == 'b'
- && n==0
- && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
- && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
- && ast->prefix == 'd'*256+'c'
- && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
- ){
- n=1;
- st = st1;
- ast = ast1;
- av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n");
- }
- }
-
-
- if( (st->discard >= AVDISCARD_DEFAULT && size==0)
- /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
- || st->discard >= AVDISCARD_ALL){
- ast->frame_offset += get_duration(ast, size);
- avio_skip(pb, size);
- goto resync;
- }
-
- if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) {
- int k = avio_r8(pb);
- int last = (k + avio_r8(pb) - 1) & 0xFF;
-
- avio_rl16(pb); //flags
-
- for (; k <= last; k++)
- ast->pal[k] = avio_rb32(pb)>>8;// b + (g << 8) + (r << 16);
- ast->has_pal= 1;
- goto resync;
- } else if( ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
- d[2]*256+d[3] == ast->prefix /*||
- (d[2] == 'd' && d[3] == 'c') ||
- (d[2] == 'w' && d[3] == 'b')*/) {
-
-//av_log(s, AV_LOG_DEBUG, "OK\n");
- if(d[2]*256+d[3] == ast->prefix)
- ast->prefix_count++;
- else{
- ast->prefix= d[2]*256+d[3];
- ast->prefix_count= 0;
- }
-
- avi->stream_index= n;
- ast->packet_size= size + 8;
- ast->remaining= size;
-
- if(size || !ast->sample_size){
- uint64_t pos= avio_tell(pb) - 8;
- if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){
- av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME);
- }
- }
- goto resync;
- }
- }
- }
-
- return AVERROR_EOF;
+ if ((err = avi_sync(s, 0)) < 0)
+ return err;
+ goto resync;
}
/* XXX: We make the implicit supposition that the positions are sorted
@@ -1119,13 +1138,22 @@ static int avi_read_idx1(AVFormatContext *s, int size)
int nb_index_entries, i;
AVStream *st;
AVIStream *ast;
- unsigned int index, tag, flags, pos, len;
+ unsigned int index, tag, flags, pos, len, first_packet = 1;
unsigned last_pos= -1;
+ int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
nb_index_entries = size / 16;
if (nb_index_entries <= 0)
return -1;
+ idx1_pos = avio_tell(pb);
+ avio_seek(pb, avi->movi_list+4, SEEK_SET);
+ if (avi_sync(s, 1) == 0) {
+ first_packet_pos = avio_tell(pb) - 8;
+ }
+ avi->stream_index = -1;
+ avio_seek(pb, idx1_pos, SEEK_SET);
+
/* Read the entries and sort them in each stream component. */
for(i = 0; i < nb_index_entries; i++) {
tag = avio_rl32(pb);
@@ -1134,9 +1162,6 @@ static int avi_read_idx1(AVFormatContext *s, int size)
len = avio_rl32(pb);
av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
i, tag, flags, pos, len);
- if(i==0 && pos > avi->movi_list)
- avi->movi_list= 0; //FIXME better check
- pos += avi->movi_list;
index = ((tag & 0xff) - '0') * 10;
index += ((tag >> 8) & 0xff) - '0';
@@ -1145,6 +1170,12 @@ static int avi_read_idx1(AVFormatContext *s, int size)
st = s->streams[index];
ast = st->priv_data;
+ if(first_packet && first_packet_pos && len) {
+ data_offset = first_packet_pos - pos;
+ first_packet = 0;
+ }
+ pos += data_offset;
+
av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
if(pb->eof_reached)
@@ -1213,20 +1244,16 @@ static int avi_load_index(AVFormatContext *s)
(tag >> 16) & 0xff,
(tag >> 24) & 0xff,
size);
- switch(tag) {
- case MKTAG('i', 'd', 'x', '1'):
- if (avi_read_idx1(s, size) < 0)
- goto skip;
+
+ if (tag == MKTAG('i', 'd', 'x', '1') &&
+ avi_read_idx1(s, size) >= 0) {
ret = 0;
- goto the_end;
- break;
- default:
- skip:
- size += (size & 1);
- if (avio_skip(pb, size) < 0)
- goto the_end; // something is wrong here
break;
}
+
+ size += (size & 1);
+ if (avio_skip(pb, size) < 0)
+ break; // something is wrong here
}
the_end:
avio_seek(pb, pos, SEEK_SET);
@@ -1338,7 +1365,7 @@ static int avi_read_close(AVFormatContext *s)
if (ast) {
if (ast->sub_ctx) {
av_freep(&ast->sub_ctx->pb);
- av_close_input_file(ast->sub_ctx);
+ avformat_close_input(&ast->sub_ctx);
}
av_free(ast->sub_buffer);
av_free_packet(&ast->sub_pkt);
@@ -1364,12 +1391,12 @@ static int avi_probe(AVProbeData *p)
}
AVInputFormat ff_avi_demuxer = {
- "avi",
- NULL_IF_CONFIG_SMALL("AVI format"),
- sizeof(AVIContext),
- avi_probe,
- avi_read_header,
- avi_read_packet,
- avi_read_close,
- avi_read_seek,
+ .name = "avi",
+ .long_name = NULL_IF_CONFIG_SMALL("AVI format"),
+ .priv_data_size = sizeof(AVIContext),
+ .read_probe = avi_probe,
+ .read_header = avi_read_header,
+ .read_packet = avi_read_packet,
+ .read_close = avi_read_close,
+ .read_seek = avi_read_seek,
};
diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index 343396c..2a23c21 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
+#include "internal.h"
#include "avi.h"
#include "avio_internal.h"
#include "riff.h"
@@ -256,7 +257,7 @@ static int avi_write_header(AVFormatContext *s)
avio_wl32(pb, au_scale); /* scale */
avio_wl32(pb, au_byterate); /* rate */
- av_set_pts_info(s->streams[i], 64, au_scale, au_byterate);
+ avpriv_set_pts_info(s->streams[i], 64, au_scale, au_byterate);
avio_wl32(pb, 0); /* start */
avist->frames_hdr_strm = avio_tell(pb); /* remember this offset to fill later */
@@ -378,9 +379,9 @@ static int avi_write_header(AVFormatContext *s)
list2 = ff_start_tag(pb, "LIST");
ffio_wfourcc(pb, "INFO");
- ff_metadata_conv(&s->metadata, ff_avi_metadata_conv, NULL);
- for (i = 0; *ff_avi_tags[i]; i++) {
- if ((t = av_dict_get(s->metadata, ff_avi_tags[i], NULL, AV_DICT_MATCH_CASE)))
+ ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
+ for (i = 0; *ff_riff_tags[i]; i++) {
+ if ((t = av_dict_get(s->metadata, ff_riff_tags[i], NULL, AV_DICT_MATCH_CASE)))
avi_write_info_tag(s->pb, t->key, t->value);
}
ff_end_tag(pb, list2);
@@ -639,16 +640,20 @@ static int avi_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_avi_muxer = {
- "avi",
- NULL_IF_CONFIG_SMALL("AVI format"),
- "video/x-msvideo",
- "avi",
- sizeof(AVIContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG4,
- avi_write_header,
- avi_write_packet,
- avi_write_trailer,
+ .name = "avi",
+ .long_name = NULL_IF_CONFIG_SMALL("AVI format"),
+ .mime_type = "video/x-msvideo",
+ .extensions = "avi",
+ .priv_data_size = sizeof(AVIContext),
+#if CONFIG_LIBMP3LAME_ENCODER
+ .audio_codec = CODEC_ID_MP3,
+#else
+ .audio_codec = CODEC_ID_AC3,
+#endif
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = avi_write_header,
+ .write_packet = avi_write_packet,
+ .write_trailer = avi_write_trailer,
.codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
.flags= AVFMT_VARIABLE_FPS,
};
diff --git a/libavformat/avio.c b/libavformat/avio.c
index ac15407..4750a9d 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -1,5 +1,5 @@
/*
- * Unbuffered io for ffmpeg system
+ * unbuffered I/O
* Copyright (c) 2001 Fabrice Bellard
*
* This file is part of Libav.
@@ -22,6 +22,7 @@
#include <unistd.h>
#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
#include "libavutil/opt.h"
#include "os_support.h"
#include "avformat.h"
@@ -30,6 +31,13 @@
#endif
#include "url.h"
+static URLProtocol *first_protocol = NULL;
+
+URLProtocol *ffurl_protocol_next(URLProtocol *prev)
+{
+ return prev ? prev->next : first_protocol;
+}
+
/** @name Logging context. */
/*@{*/
static const char *urlcontext_to_name(void *ptr)
@@ -38,32 +46,60 @@ static const char *urlcontext_to_name(void *ptr)
if(h->prot) return h->prot->name;
else return "NULL";
}
+
+static void *urlcontext_child_next(void *obj, void *prev)
+{
+ URLContext *h = obj;
+ if (!prev && h->priv_data && h->prot->priv_data_class)
+ return h->priv_data;
+ return NULL;
+}
+
+static const AVClass *urlcontext_child_class_next(const AVClass *prev)
+{
+ URLProtocol *p = NULL;
+
+ /* find the protocol that corresponds to prev */
+ while (prev && (p = ffurl_protocol_next(p)))
+ if (p->priv_data_class == prev)
+ break;
+
+ /* find next protocol with priv options */
+ while (p = ffurl_protocol_next(p))
+ if (p->priv_data_class)
+ return p->priv_data_class;
+ return NULL;
+
+}
+
static const AVOption options[] = {{NULL}};
-static const AVClass urlcontext_class = {
+const AVClass ffurl_context_class = {
.class_name = "URLContext",
.item_name = urlcontext_to_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
+ .child_next = urlcontext_child_next,
+ .child_class_next = urlcontext_child_class_next,
};
/*@}*/
-static int default_interrupt_cb(void);
-URLProtocol *first_protocol = NULL;
+#if FF_API_OLD_INTERRUPT_CB
+static int default_interrupt_cb(void);
int (*url_interrupt_cb)(void) = default_interrupt_cb;
+#endif
#if FF_API_OLD_AVIO
URLProtocol *av_protocol_next(URLProtocol *p)
{
- if(p) return p->next;
- else return first_protocol;
+ return ffurl_protocol_next(p);
}
#endif
const char *avio_enum_protocols(void **opaque, int output)
{
URLProtocol **p = opaque;
- *p = *p ? (*p)->next : first_protocol;
+ *p = ffurl_protocol_next(*p);
if (!*p) return NULL;
if ((output && (*p)->url_write) || (!output && (*p)->url_read))
return (*p)->name;
@@ -86,7 +122,8 @@ int ffurl_register_protocol(URLProtocol *protocol, int size)
}
static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
- const char *filename, int flags)
+ const char *filename, int flags,
+ const AVIOInterruptCB *int_cb)
{
URLContext *uc;
int err;
@@ -100,7 +137,7 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
err = AVERROR(ENOMEM);
goto fail;
}
- uc->av_class = &urlcontext_class;
+ uc->av_class = &ffurl_context_class;
uc->filename = (char *) &uc[1];
strcpy(uc->filename, filename);
uc->prot = up;
@@ -114,6 +151,8 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
av_opt_set_defaults(uc->priv_data);
}
}
+ if (int_cb)
+ uc->interrupt_callback = *int_cb;
*puc = uc;
return 0;
@@ -125,9 +164,13 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
return err;
}
-int ffurl_connect(URLContext* uc)
+int ffurl_connect(URLContext* uc, AVDictionary **options)
{
- int err = uc->prot->url_open(uc, uc->filename, uc->flags);
+ int err =
+#if !FF_API_OLD_AVIO
+ uc->prot->url_open2 ? uc->prot->url_open2(uc, uc->filename, uc->flags, options) :
+#endif
+ uc->prot->url_open(uc, uc->filename, uc->flags);
if (err)
return err;
uc->is_connected = 1;
@@ -145,10 +188,10 @@ int url_open_protocol (URLContext **puc, struct URLProtocol *up,
{
int ret;
- ret = url_alloc_for_protocol(puc, up, filename, flags);
+ ret = url_alloc_for_protocol(puc, up, filename, flags, NULL);
if (ret)
goto fail;
- ret = ffurl_connect(*puc);
+ ret = ffurl_connect(*puc, NULL);
if (!ret)
return 0;
fail:
@@ -158,15 +201,15 @@ int url_open_protocol (URLContext **puc, struct URLProtocol *up,
}
int url_alloc(URLContext **puc, const char *filename, int flags)
{
- return ffurl_alloc(puc, filename, flags);
+ return ffurl_alloc(puc, filename, flags, NULL);
}
int url_connect(URLContext* uc)
{
- return ffurl_connect(uc);
+ return ffurl_connect(uc, NULL);
}
int url_open(URLContext **puc, const char *filename, int flags)
{
- return ffurl_open(puc, filename, flags);
+ return ffurl_open(puc, filename, flags, NULL, NULL);
}
int url_read(URLContext *h, unsigned char *buf, int size)
{
@@ -219,9 +262,10 @@ int av_register_protocol2(URLProtocol *protocol, int size)
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"0123456789+-."
-int ffurl_alloc(URLContext **puc, const char *filename, int flags)
+int ffurl_alloc(URLContext **puc, const char *filename, int flags,
+ const AVIOInterruptCB *int_cb)
{
- URLProtocol *up;
+ URLProtocol *up = NULL;
char proto_str[128], proto_nested[128], *ptr;
size_t proto_len = strspn(filename, URL_SCHEME_CHARS);
@@ -234,27 +278,30 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags)
if ((ptr = strchr(proto_nested, '+')))
*ptr = '\0';
- up = first_protocol;
- while (up != NULL) {
+ while (up = ffurl_protocol_next(up)) {
if (!strcmp(proto_str, up->name))
- return url_alloc_for_protocol (puc, up, filename, flags);
+ return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
if (up->flags & URL_PROTOCOL_FLAG_NESTED_SCHEME &&
!strcmp(proto_nested, up->name))
- return url_alloc_for_protocol (puc, up, filename, flags);
- up = up->next;
+ return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
}
*puc = NULL;
return AVERROR(ENOENT);
}
-int ffurl_open(URLContext **puc, const char *filename, int flags)
+int ffurl_open(URLContext **puc, const char *filename, int flags,
+ const AVIOInterruptCB *int_cb, AVDictionary **options)
{
- int ret = ffurl_alloc(puc, filename, flags);
+ int ret = ffurl_alloc(puc, filename, flags, int_cb);
if (ret)
return ret;
- ret = ffurl_connect(*puc);
+ if (options && (*puc)->prot->priv_data_class &&
+ (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0)
+ goto fail;
+ ret = ffurl_connect(*puc, options);
if (!ret)
return 0;
+fail:
ffurl_close(*puc);
*puc = NULL;
return ret;
@@ -284,7 +331,7 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int
if (ret)
fast_retries = FFMAX(fast_retries, 2);
len += ret;
- if (url_interrupt_cb())
+ if (ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT;
}
return len;
@@ -335,8 +382,11 @@ int ffurl_close(URLContext *h)
#if CONFIG_NETWORK
ff_network_close();
#endif
- if (h->prot->priv_data_size)
+ if (h->prot->priv_data_size) {
+ if (h->prot->priv_data_class)
+ av_opt_free(h->priv_data);
av_free(h->priv_data);
+ }
av_free(h);
return ret;
}
@@ -345,7 +395,7 @@ int ffurl_close(URLContext *h)
int url_exist(const char *filename)
{
URLContext *h;
- if (ffurl_open(&h, filename, AVIO_FLAG_READ) < 0)
+ if (ffurl_open(&h, filename, AVIO_FLAG_READ, NULL, NULL) < 0)
return 0;
ffurl_close(h);
return 1;
@@ -355,14 +405,14 @@ int url_exist(const char *filename)
int avio_check(const char *url, int flags)
{
URLContext *h;
- int ret = ffurl_alloc(&h, url, flags);
+ int ret = ffurl_alloc(&h, url, flags, NULL);
if (ret)
return ret;
if (h->prot->url_check) {
ret = h->prot->url_check(h, flags);
} else {
- ret = ffurl_connect(h);
+ ret = ffurl_connect(h, NULL);
if (ret >= 0)
ret = flags;
}
@@ -393,6 +443,7 @@ int ffurl_get_file_handle(URLContext *h)
return h->prot->url_get_file_handle(h);
}
+#if FF_API_OLD_INTERRUPT_CB
static int default_interrupt_cb(void)
{
return 0;
@@ -404,6 +455,19 @@ void avio_set_interrupt_cb(int (*interrupt_cb)(void))
interrupt_cb = default_interrupt_cb;
url_interrupt_cb = interrupt_cb;
}
+#endif
+
+int ff_check_interrupt(AVIOInterruptCB *cb)
+{
+ int ret;
+ if (cb && cb->callback && (ret = cb->callback(cb->opaque)))
+ return ret;
+#if FF_API_OLD_INTERRUPT_CB
+ return url_interrupt_cb();
+#else
+ return 0;
+#endif
+}
#if FF_API_OLD_AVIO
int av_url_read_pause(URLContext *h, int pause)
diff --git a/libavformat/avio.h b/libavformat/avio.h
index 211fe93..dec2a5e 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -22,12 +22,14 @@
/**
* @file
+ * @ingroup lavf_io
* Buffered I/O operations
*/
#include <stdint.h>
#include "libavutil/common.h"
+#include "libavutil/dict.h"
#include "libavutil/log.h"
#include "libavformat/version.h"
@@ -36,6 +38,22 @@
#define AVIO_SEEKABLE_NORMAL 0x0001 /**< Seeking works like for a local file */
/**
+ * Callback for checking whether to abort blocking functions.
+ * AVERROR_EXIT is returned in this case by the interrupted
+ * function. During blocking operations, callback is called with
+ * opaque as parameter. If the callback returns 1, the
+ * blocking operation will be aborted.
+ *
+ * No members can be added to this struct without a major bump, if
+ * new elements have been added after this struct in AVFormatContext
+ * or AVIOContext.
+ */
+typedef struct {
+ int (*callback)(void*);
+ void *opaque;
+} AVIOInterruptCB;
+
+/**
* Bytestream IO Context.
* New fields can be added to the end with minor version bumps.
* Removal, reordering and changes to existing fields require a major
@@ -48,6 +66,21 @@
* function pointers specified in avio_alloc_context()
*/
typedef struct {
+#if !FF_API_OLD_AVIO
+ /**
+ * A class for private options.
+ *
+ * If this AVIOContext is created by avio_open2(), av_class is set and
+ * passes the options down to protocols.
+ *
+ * If this AVIOContext is manually allocated, then av_class may be set by
+ * the caller.
+ *
+ * warning -- this field can be NULL, be sure to not pass this AVIOContext
+ * to any av_opt_* functions in that case.
+ */
+ AVClass *av_class;
+#endif
unsigned char *buffer; /**< Start of the buffer. */
int buffer_size; /**< Maximum buffer size */
unsigned char *buf_ptr; /**< Current position in the buffer */
@@ -109,6 +142,7 @@ typedef struct URLContext {
void *priv_data;
char *filename; /**< specified URL */
int is_connected;
+ AVIOInterruptCB interrupt_callback;
} URLContext;
#define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */
@@ -178,6 +212,7 @@ extern URLInterruptCB *url_interrupt_cb;
* @defgroup old_url_funcs Old url_* functions
* The following functions are deprecated. Use the buffered API based on #AVIOContext instead.
* @{
+ * @ingroup lavf_io
*/
attribute_deprecated int url_open_protocol (URLContext **puc, struct URLProtocol *up,
const char *url, int flags);
@@ -237,6 +272,7 @@ attribute_deprecated AVIOContext *av_alloc_put_byte(
* @defgroup old_avio_funcs Old put_/get_*() functions
* The following functions are deprecated. Use the "avio_"-prefixed functions instead.
* @{
+ * @ingroup lavf_io
*/
attribute_deprecated int get_buffer(AVIOContext *s, unsigned char *buf, int size);
attribute_deprecated int get_partial_buffer(AVIOContext *s, unsigned char *buf, int size);
@@ -274,6 +310,7 @@ attribute_deprecated int64_t av_url_read_fseek (AVIOContext *h, int stream_in
* @defgroup old_url_f_funcs Old url_f* functions
* The following functions are deprecated, use the "avio_"-prefixed functions instead.
* @{
+ * @ingroup lavf_io
*/
attribute_deprecated int url_fopen( AVIOContext **s, const char *url, int flags);
attribute_deprecated int url_fclose(AVIOContext *s);
@@ -284,11 +321,7 @@ attribute_deprecated int64_t url_fsize(AVIOContext *s);
#define URL_EOF (-1)
attribute_deprecated int url_fgetc(AVIOContext *s);
attribute_deprecated int url_setbufsize(AVIOContext *s, int buf_size);
-#ifdef __GNUC__
-attribute_deprecated int url_fprintf(AVIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
-#else
-attribute_deprecated int url_fprintf(AVIOContext *s, const char *fmt, ...);
-#endif
+attribute_deprecated int url_fprintf(AVIOContext *s, const char *fmt, ...) av_printf_format(2, 3);
attribute_deprecated void put_flush_packet(AVIOContext *s);
attribute_deprecated int url_open_dyn_buf(AVIOContext **s);
attribute_deprecated int url_open_dyn_packet_buf(AVIOContext **s, int max_packet_size);
@@ -360,13 +393,17 @@ attribute_deprecated int url_exist(const char *url);
*/
int avio_check(const char *url, int flags);
+#if FF_API_OLD_INTERRUPT_CB
/**
* The callback is called in blocking functions to test regulary if
* asynchronous interruption is needed. AVERROR_EXIT is returned
* in this case by the interrupted function. 'NULL' means no interrupt
* callback is given.
+ * @deprecated Use interrupt_callback in AVFormatContext/avio_open2
+ * instead.
*/
-void avio_set_interrupt_cb(int (*interrupt_cb)(void));
+attribute_deprecated void avio_set_interrupt_cb(int (*interrupt_cb)(void));
+#endif
/**
* Allocate and initialize an AVIOContext for buffered I/O. It must be later
@@ -463,11 +500,7 @@ static av_always_inline int64_t avio_tell(AVIOContext *s)
int64_t avio_size(AVIOContext *s);
/** @warning currently size is limited */
-#ifdef __GNUC__
-int avio_printf(AVIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
-#else
-int avio_printf(AVIOContext *s, const char *fmt, ...);
-#endif
+int avio_printf(AVIOContext *s, const char *fmt, ...) av_printf_format(2, 3);
void avio_flush(AVIOContext *s);
@@ -565,6 +598,26 @@ int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen);
int avio_open(AVIOContext **s, const char *url, int flags);
/**
+ * Create and initialize a AVIOContext for accessing the
+ * resource indicated by url.
+ * @note When the resource indicated by url has been opened in
+ * read+write mode, the AVIOContext can be used only for writing.
+ *
+ * @param s Used to return the pointer to the created AVIOContext.
+ * In case of failure the pointed to value is set to NULL.
+ * @param flags flags which control how the resource indicated by url
+ * is to be opened
+ * @param int_cb an interrupt callback to be used at the protocols level
+ * @param options A dictionary filled with protocol-private options. On return
+ * this parameter will be destroyed and replaced with a dict containing options
+ * that were not found. May be NULL.
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code in case of failure
+ */
+int avio_open2(AVIOContext **s, const char *url, int flags,
+ const AVIOInterruptCB *int_cb, AVDictionary **options);
+
+/**
* Close the resource accessed by the AVIOContext s and free it.
* This function can only be used if s was opened by avio_open().
*
diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index 1369c43..f2ccc36 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -23,6 +23,10 @@
#include "avio.h"
#include "url.h"
+#include "libavutil/log.h"
+
+extern const AVClass ffio_url_class;
+
int ffio_init_context(AVIOContext *s,
unsigned char *buffer,
int buffer_size,
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index fa63ddf..898f35d 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -1,5 +1,5 @@
/*
- * Buffered I/O for ffmpeg system
+ * buffered I/O
* Copyright (c) 2000,2001 Fabrice Bellard
*
* This file is part of Libav.
@@ -20,7 +20,10 @@
*/
#include "libavutil/crc.h"
+#include "libavutil/dict.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "avio.h"
#include "avio_internal.h"
@@ -37,6 +40,31 @@
*/
#define SHORT_SEEK_THRESHOLD 4096
+#if !FF_API_OLD_AVIO
+static void *ffio_url_child_next(void *obj, void *prev)
+{
+ AVIOContext *s = obj;
+ return prev ? NULL : s->opaque;
+}
+
+static const AVClass *ffio_url_child_class_next(const AVClass *prev)
+{
+ return prev ? NULL : &ffurl_context_class;
+}
+
+static const AVOption ffio_url_options[] = {
+ { NULL },
+};
+
+const AVClass ffio_url_class = {
+ .class_name = "AVIOContext",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = ffio_url_options,
+ .child_next = ffio_url_child_next,
+ .child_class_next = ffio_url_child_class_next,
+};
+#endif
static void fill_buffer(AVIOContext *s);
static int url_resetbuf(AVIOContext *s, int flags);
@@ -769,13 +797,14 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
{
int i;
+ if (buflen <= 0)
+ return AVERROR(EINVAL);
// reserve 1 byte for terminating 0
buflen = FFMIN(buflen - 1, maxlen);
for (i = 0; i < buflen; i++)
if (!(buf[i] = avio_r8(s)))
return i + 1;
- if (buflen)
- buf[i] = 0;
+ buf[i] = 0;
for (; i < maxlen; i++)
if (!avio_r8(s))
return i + 1;
@@ -787,6 +816,8 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
{\
char* q = buf;\
int ret = 0;\
+ if (buflen <= 0) \
+ return AVERROR(EINVAL); \
while (ret + 1 < maxlen) {\
uint8_t tmp;\
uint32_t ch;\
@@ -838,19 +869,12 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
if (!buffer)
return AVERROR(ENOMEM);
- *s = av_mallocz(sizeof(AVIOContext));
- if(!*s) {
+ *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
+ ffurl_read, ffurl_write, ffurl_seek);
+ if (!*s) {
av_free(buffer);
return AVERROR(ENOMEM);
}
-
- if (ffio_init_context(*s, buffer, buffer_size,
- h->flags & AVIO_FLAG_WRITE, h,
- ffurl_read, ffurl_write, ffurl_seek) < 0) {
- av_free(buffer);
- av_freep(s);
- return AVERROR(EIO);
- }
#if FF_API_OLD_AVIO
(*s)->is_streamed = h->is_streamed;
#endif
@@ -860,6 +884,9 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
(*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause;
(*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek;
}
+#if !FF_API_OLD_AVIO
+ (*s)->av_class = &ffio_url_class;
+#endif
return 0;
}
@@ -933,10 +960,16 @@ int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size
int avio_open(AVIOContext **s, const char *filename, int flags)
{
+ return avio_open2(s, filename, flags, NULL, NULL);
+}
+
+int avio_open2(AVIOContext **s, const char *filename, int flags,
+ const AVIOInterruptCB *int_cb, AVDictionary **options)
+{
URLContext *h;
int err;
- err = ffurl_open(&h, filename, flags);
+ err = ffurl_open(&h, filename, flags, int_cb, options);
if (err < 0)
return err;
err = ffio_fdopen(s, h);
diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index 5e6f6bf..9449c1b 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -1,5 +1,5 @@
/*
- * AVISynth support for ffmpeg system
+ * AVISynth support
* Copyright (c) 2006 DivX, Inc.
*
* This file is part of Libav.
@@ -20,6 +20,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
#include <windows.h>
@@ -84,7 +85,8 @@ static int avisynth_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (AVIStreamReadFormat(stream->handle, 0, &wvfmt, &struct_size) != S_OK)
continue;
- st = av_new_stream(s, id);
+ st = avformat_new_stream(s, NULL);
+ st->id = id;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->block_align = wvfmt.nBlockAlign;
@@ -110,7 +112,8 @@ static int avisynth_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (AVIStreamReadFormat(stream->handle, 0, &imgfmt, &struct_size) != S_OK)
continue;
- st = av_new_stream(s, id);
+ st = avformat_new_stream(s, NULL);
+ st->id = id;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->r_frame_rate.num = stream->info.dwRate;
st->r_frame_rate.den = stream->info.dwScale;
@@ -135,7 +138,7 @@ static int avisynth_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->stream_codec_tag = stream->info.fccHandler;
- av_set_pts_info(st, 64, info.dwScale, info.dwRate);
+ avpriv_set_pts_info(st, 64, info.dwScale, info.dwRate);
st->start_time = stream->info.dwStart;
}
}
@@ -208,15 +211,12 @@ static int avisynth_read_seek(AVFormatContext *s, int stream_index, int64_t pts,
}
AVInputFormat ff_avisynth_demuxer = {
- "avs",
- NULL_IF_CONFIG_SMALL("AVISynth"),
- sizeof(AVISynthContext),
- NULL,
- avisynth_read_header,
- avisynth_read_packet,
- avisynth_read_close,
- avisynth_read_seek,
- NULL,
- 0,
- "avs",
+ .name = "avs",
+ .long_name = NULL_IF_CONFIG_SMALL("AVISynth"),
+ .priv_data_size = sizeof(AVISynthContext),
+ .read_header = avisynth_read_header,
+ .read_packet = avisynth_read_packet,
+ .read_close = avisynth_read_close,
+ .read_seek = avisynth_read_seek,
+ .extensions = "avs",
};
diff --git a/libavformat/avlanguage.c b/libavformat/avlanguage.c
index 787382e..e606ef2 100644
--- a/libavformat/avlanguage.c
+++ b/libavformat/avlanguage.c
@@ -20,6 +20,7 @@
#include "avlanguage.h"
#include "libavutil/avstring.h"
+#include "libavutil/common.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
@@ -736,7 +737,7 @@ const char *av_convert_lang_to(const char *lang, enum AVLangCodespace target_cod
{
int i;
const LangEntry *entry = NULL;
- const int NB_CODESPACES = sizeof(lang_table_counts)/sizeof(*lang_table_counts);
+ const int NB_CODESPACES = FF_ARRAY_ELEMS(lang_table_counts);
if (target_codespace >= NB_CODESPACES)
return NULL;
diff --git a/libavformat/avs.c b/libavformat/avs.c
index bd9b31d..c6ccbb2 100644
--- a/libavformat/avs.c
+++ b/libavformat/avs.c
@@ -163,10 +163,14 @@ static int avs_read_packet(AVFormatContext * s, AVPacket * pkt)
sub_type = avio_r8(s->pb);
type = avio_r8(s->pb);
size = avio_rl16(s->pb);
+ if (size < 4)
+ return AVERROR_INVALIDDATA;
avs->remaining_frame_size -= size;
switch (type) {
case AVS_PALETTE:
+ if (size - 4 > sizeof(palette))
+ return AVERROR_INVALIDDATA;
ret = avio_read(s->pb, palette, size - 4);
if (ret < size - 4)
return AVERROR(EIO);
@@ -175,7 +179,7 @@ static int avs_read_packet(AVFormatContext * s, AVPacket * pkt)
case AVS_VIDEO:
if (!avs->st_video) {
- avs->st_video = av_new_stream(s, AVS_VIDEO);
+ avs->st_video = avformat_new_stream(s, NULL);
if (avs->st_video == NULL)
return AVERROR(ENOMEM);
avs->st_video->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -192,7 +196,7 @@ static int avs_read_packet(AVFormatContext * s, AVPacket * pkt)
case AVS_AUDIO:
if (!avs->st_audio) {
- avs->st_audio = av_new_stream(s, AVS_AUDIO);
+ avs->st_audio = avformat_new_stream(s, NULL);
if (avs->st_audio == NULL)
return AVERROR(ENOMEM);
avs->st_audio->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -216,11 +220,11 @@ static int avs_read_close(AVFormatContext * s)
}
AVInputFormat ff_avs_demuxer = {
- "avs",
- NULL_IF_CONFIG_SMALL("AVS format"),
- sizeof(AvsFormat),
- avs_probe,
- avs_read_header,
- avs_read_packet,
- avs_read_close,
+ .name = "avs",
+ .long_name = NULL_IF_CONFIG_SMALL("AVS format"),
+ .priv_data_size = sizeof(AvsFormat),
+ .read_probe = avs_probe,
+ .read_header = avs_read_header,
+ .read_packet = avs_read_packet,
+ .read_close = avs_read_close,
};
diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c
index 01e6f55..7705fcb 100644
--- a/libavformat/bethsoftvid.c
+++ b/libavformat/bethsoftvid.c
@@ -23,12 +23,13 @@
* @file
* @brief Bethesda Softworks VID (.vid) file demuxer
* @author Nicholas Tung [ntung (at. ntung com] (2007-03)
- * @sa http://wiki.multimedia.cx/index.php?title=Bethsoft_VID
- * @sa http://www.svatopluk.com/andux/docs/dfvid.html
+ * @see http://wiki.multimedia.cx/index.php?title=Bethsoft_VID
+ * @see http://www.svatopluk.com/andux/docs/dfvid.html
*/
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#include "libavcodec/bethsoftvideo.h"
typedef struct BVID_DemuxContext
@@ -70,10 +71,10 @@ static int vid_read_header(AVFormatContext *s,
avio_skip(pb, 5);
vid->nframes = avio_rl16(pb);
- stream = av_new_stream(s, 0);
+ stream = avformat_new_stream(s, NULL);
if (!stream)
return AVERROR(ENOMEM);
- av_set_pts_info(stream, 32, 1, 60); // 16 ms increments, i.e. 60 fps
+ avpriv_set_pts_info(stream, 32, 1, 60); // 16 ms increments, i.e. 60 fps
stream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
stream->codec->codec_id = CODEC_ID_BETHSOFTVID;
stream->codec->width = avio_rl16(pb);
@@ -83,7 +84,7 @@ static int vid_read_header(AVFormatContext *s,
avio_rl16(pb);
// done with video codec, set up audio codec
- stream = av_new_stream(s, 0);
+ stream = avformat_new_stream(s, NULL);
if (!stream)
return AVERROR(ENOMEM);
stream->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -220,15 +221,13 @@ static int vid_read_packet(AVFormatContext *s,
av_log(s, AV_LOG_ERROR, "unknown block (character = %c, decimal = %d, hex = %x)!!!\n",
block_type, block_type, block_type); return -1;
}
-
- return 0;
}
AVInputFormat ff_bethsoftvid_demuxer = {
- "bethsoftvid",
- NULL_IF_CONFIG_SMALL("Bethesda Softworks VID format"),
- sizeof(BVID_DemuxContext),
- vid_probe,
- vid_read_header,
- vid_read_packet,
+ .name = "bethsoftvid",
+ .long_name = NULL_IF_CONFIG_SMALL("Bethesda Softworks VID format"),
+ .priv_data_size = sizeof(BVID_DemuxContext),
+ .read_probe = vid_probe,
+ .read_header = vid_read_header,
+ .read_packet = vid_read_packet,
};
diff --git a/libavformat/bfi.c b/libavformat/bfi.c
index bc26d47..bb02e85 100644
--- a/libavformat/bfi.c
+++ b/libavformat/bfi.c
@@ -23,11 +23,12 @@
* @file
* @brief Brute Force & Ignorance (.bfi) file demuxer
* @author Sisir Koppaka ( sisir.koppaka at gmail dot com )
- * @sa http://wiki.multimedia.cx/index.php?title=BFI
+ * @see http://wiki.multimedia.cx/index.php?title=BFI
*/
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
typedef struct BFIContext {
int nframes;
@@ -55,12 +56,12 @@ static int bfi_read_header(AVFormatContext * s, AVFormatParameters * ap)
int fps, chunk_header;
/* Initialize the video codec... */
- vstream = av_new_stream(s, 0);
+ vstream = avformat_new_stream(s, NULL);
if (!vstream)
return AVERROR(ENOMEM);
/* Initialize the audio codec... */
- astream = av_new_stream(s, 0);
+ astream = avformat_new_stream(s, NULL);
if (!astream)
return AVERROR(ENOMEM);
@@ -86,7 +87,7 @@ static int bfi_read_header(AVFormatContext * s, AVFormatParameters * ap)
astream->codec->sample_rate = avio_rl32(pb);
/* Set up the video codec... */
- av_set_pts_info(vstream, 32, 1, fps);
+ avpriv_set_pts_info(vstream, 32, 1, fps);
vstream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vstream->codec->codec_id = CODEC_ID_BFI;
vstream->codec->pix_fmt = PIX_FMT_PAL8;
@@ -99,7 +100,7 @@ static int bfi_read_header(AVFormatContext * s, AVFormatParameters * ap)
astream->codec->bit_rate =
astream->codec->sample_rate * astream->codec->bits_per_coded_sample;
avio_seek(pb, chunk_header - 3, SEEK_SET);
- av_set_pts_info(astream, 64, 1, astream->codec->sample_rate);
+ avpriv_set_pts_info(astream, 64, 1, astream->codec->sample_rate);
return 0;
}
@@ -159,10 +160,10 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt)
}
AVInputFormat ff_bfi_demuxer = {
- "bfi",
- NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
- sizeof(BFIContext),
- bfi_probe,
- bfi_read_header,
- bfi_read_packet,
+ .name = "bfi",
+ .long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
+ .priv_data_size = sizeof(BFIContext),
+ .read_probe = bfi_probe,
+ .read_header = bfi_read_header,
+ .read_packet = bfi_read_packet,
};
diff --git a/libavformat/bink.c b/libavformat/bink.c
index 76b457c..ecf6905 100644
--- a/libavformat/bink.c
+++ b/libavformat/bink.c
@@ -30,6 +30,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
enum BinkAudFlags {
BINK_AUD_16BITS = 0x4000, ///< prefer 16-bit output
@@ -78,7 +79,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
uint16_t flags;
int keyframe;
- vst = av_new_stream(s, 0);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
@@ -109,7 +110,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num, fps_den);
return AVERROR(EIO);
}
- av_set_pts_info(vst, 64, fps_den, fps_num);
+ avpriv_set_pts_info(vst, 64, fps_den, fps_num);
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vst->codec->codec_id = CODEC_ID_BINKVIDEO;
@@ -130,17 +131,22 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_skip(pb, 4 * bink->num_audio_tracks);
for (i = 0; i < bink->num_audio_tracks; i++) {
- ast = av_new_stream(s, 1);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- ast->codec->codec_tag = vst->codec->codec_tag;
+ ast->codec->codec_tag = 0;
ast->codec->sample_rate = avio_rl16(pb);
- av_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
+ avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
flags = avio_rl16(pb);
ast->codec->codec_id = flags & BINK_AUD_USEDCT ?
CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_RDFT;
ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1;
+ ast->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!ast->codec->extradata)
+ return AVERROR(ENOMEM);
+ ast->codec->extradata_size = 4;
+ AV_WL32(ast->codec->extradata, vst->codec->codec_tag);
}
for (i = 0; i < bink->num_audio_tracks; i++)
@@ -259,12 +265,11 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in
}
AVInputFormat ff_bink_demuxer = {
- "bink",
- NULL_IF_CONFIG_SMALL("Bink"),
- sizeof(BinkDemuxContext),
- probe,
- read_header,
- read_packet,
- NULL,
- read_seek,
+ .name = "bink",
+ .long_name = NULL_IF_CONFIG_SMALL("Bink"),
+ .priv_data_size = sizeof(BinkDemuxContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .read_seek = read_seek,
};
diff --git a/libavformat/bmv.c b/libavformat/bmv.c
new file mode 100644
index 0000000..1077efa
--- /dev/null
+++ b/libavformat/bmv.c
@@ -0,0 +1,137 @@
+/*
+ * Discworld II BMV demuxer
+ * Copyright (c) 2011 Konstantin Shishkov.
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "internal.h"
+
+enum BMVFlags {
+ BMV_NOP = 0,
+ BMV_END,
+ BMV_DELTA,
+ BMV_INTRA,
+
+ BMV_AUDIO = 0x20,
+};
+
+typedef struct BMVContext {
+ uint8_t *packet;
+ int size;
+ int get_next;
+ int64_t audio_pos;
+} BMVContext;
+
+static int bmv_read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ AVStream *st, *ast;
+ BMVContext *c = s->priv_data;
+
+ st = avformat_new_stream(s, 0);
+ if (!st)
+ return AVERROR(ENOMEM);
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = CODEC_ID_BMV_VIDEO;
+ st->codec->width = 640;
+ st->codec->height = 429;
+ st->codec->pix_fmt = PIX_FMT_PAL8;
+ avpriv_set_pts_info(st, 16, 1, 12);
+ ast = avformat_new_stream(s, 0);
+ if (!ast)
+ return AVERROR(ENOMEM);
+ ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ ast->codec->codec_id = CODEC_ID_BMV_AUDIO;
+ ast->codec->channels = 2;
+ ast->codec->sample_rate = 22050;
+ avpriv_set_pts_info(ast, 16, 1, 22050);
+
+ c->get_next = 1;
+ c->audio_pos = 0;
+ return 0;
+}
+
+static int bmv_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ BMVContext *c = s->priv_data;
+ int type;
+ void *tmp;
+
+ while (c->get_next) {
+ if (s->pb->eof_reached)
+ return AVERROR_EOF;
+ type = avio_r8(s->pb);
+ if (type == BMV_NOP)
+ continue;
+ if (type == BMV_END)
+ return AVERROR_EOF;
+ c->size = avio_rl24(s->pb);
+ if (!c->size)
+ return AVERROR_INVALIDDATA;
+ tmp = av_realloc(c->packet, c->size + 1);
+ if (!tmp)
+ return AVERROR(ENOMEM);
+ c->packet = tmp;
+ c->packet[0] = type;
+ if (avio_read(s->pb, c->packet + 1, c->size) != c->size)
+ return AVERROR(EIO);
+ if (type & BMV_AUDIO) {
+ int audio_size = c->packet[1] * 65 + 1;
+ if (audio_size >= c->size) {
+ av_log(s, AV_LOG_ERROR, "Reported audio size %d is bigger than packet size (%d)\n",
+ audio_size, c->size);
+ return AVERROR_INVALIDDATA;
+ }
+ if (av_new_packet(pkt, audio_size) < 0)
+ return AVERROR(ENOMEM);
+ memcpy(pkt->data, c->packet + 1, pkt->size);
+ pkt->stream_index = 1;
+ pkt->pts = c->audio_pos;
+ pkt->duration = c->packet[1] * 32;
+ c->audio_pos += pkt->duration;
+ c->get_next = 0;
+ return pkt->size;
+ } else
+ break;
+ }
+ if (av_new_packet(pkt, c->size + 1) < 0)
+ return AVERROR(ENOMEM);
+ pkt->stream_index = 0;
+ c->get_next = 1;
+ memcpy(pkt->data, c->packet, pkt->size);
+ return pkt->size;
+}
+
+static int bmv_read_close(AVFormatContext *s)
+{
+ BMVContext *c = s->priv_data;
+
+ av_freep(&c->packet);
+
+ return 0;
+}
+
+AVInputFormat ff_bmv_demuxer = {
+ .name = "bmv",
+ .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV"),
+ .priv_data_size = sizeof(BMVContext),
+ .read_header = bmv_read_header,
+ .read_packet = bmv_read_packet,
+ .read_close = bmv_read_close,
+ .extensions = "bmv"
+};
diff --git a/libavformat/c93.c b/libavformat/c93.c
index 097565a..d82086d 100644
--- a/libavformat/c93.c
+++ b/libavformat/c93.c
@@ -20,6 +20,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "voc.h"
#include "libavutil/intreadwrite.h"
@@ -79,7 +80,7 @@ static int read_header(AVFormatContext *s,
/* Audio streams are added if audio packets are found */
s->ctx_flags |= AVFMTCTX_NOHEADER;
- video = av_new_stream(s, 0);
+ video = avformat_new_stream(s, NULL);
if (!video)
return AVERROR(ENOMEM);
@@ -89,7 +90,7 @@ static int read_header(AVFormatContext *s,
video->codec->height = 192;
/* 4:3 320x200 with 8 empty lines */
video->sample_aspect_ratio = (AVRational) { 5, 6 };
- av_set_pts_info(video, 64, 2, 25);
+ avpriv_set_pts_info(video, 64, 2, 25);
video->nb_frames = framecount;
video->duration = framecount;
video->start_time = 0;
@@ -117,7 +118,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
datasize = avio_rl16(pb);
if (datasize > 42) {
if (!c93->audio) {
- c93->audio = av_new_stream(s, 1);
+ c93->audio = avformat_new_stream(s, NULL);
if (!c93->audio)
return AVERROR(ENOMEM);
c93->audio->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -193,10 +194,10 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_c93_demuxer = {
- "c93",
- NULL_IF_CONFIG_SMALL("Interplay C93"),
- sizeof(C93DemuxContext),
- probe,
- read_header,
- read_packet,
+ .name = "c93",
+ .long_name = NULL_IF_CONFIG_SMALL("Interplay C93"),
+ .priv_data_size = sizeof(C93DemuxContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
};
diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c
index dff3b41..4efc40f 100644
--- a/libavformat/cafdec.c
+++ b/libavformat/cafdec.c
@@ -26,9 +26,11 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
#include "isom.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
#include "libavutil/dict.h"
#include "caf.h"
@@ -60,13 +62,13 @@ static int read_desc_chunk(AVFormatContext *s)
int flags;
/* new audio stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
/* parse format description */
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->sample_rate = av_int2dbl(avio_rb64(pb));
+ st->codec->sample_rate = av_int2double(avio_rb64(pb));
st->codec->codec_tag = avio_rb32(pb);
flags = avio_rb32(pb);
caf->bytes_per_packet = avio_rb32(pb);
@@ -285,10 +287,8 @@ static int read_header(AVFormatContext *s,
"block size or frame size are variable.\n");
return AVERROR_INVALIDDATA;
}
- s->file_size = avio_size(pb);
- s->file_size = FFMAX(0, s->file_size);
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
st->start_time = 0;
/* position the stream at the start of data */
@@ -383,13 +383,12 @@ static int read_seek(AVFormatContext *s, int stream_index,
}
AVInputFormat ff_caf_demuxer = {
- "caf",
- NULL_IF_CONFIG_SMALL("Apple Core Audio Format"),
- sizeof(CaffContext),
- probe,
- read_header,
- read_packet,
- NULL,
- read_seek,
+ .name = "caf",
+ .long_name = NULL_IF_CONFIG_SMALL("Apple Core Audio Format"),
+ .priv_data_size = sizeof(CaffContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .read_seek = read_seek,
.codec_tag = (const AVCodecTag*[]){ff_codec_caf_tags, 0},
};
diff --git a/libavformat/cdg.c b/libavformat/cdg.c
index b47a20e..0980df7 100644
--- a/libavformat/cdg.c
+++ b/libavformat/cdg.c
@@ -20,15 +20,18 @@
*/
#include "avformat.h"
+#include "internal.h"
#define CDG_PACKET_SIZE 24
+#define CDG_COMMAND 0x09
+#define CDG_MASK 0x3F
static int read_header(AVFormatContext *s, AVFormatParameters *ap)
{
AVStream *vst;
int ret;
- vst = av_new_stream(s, 0);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
@@ -36,7 +39,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
vst->codec->codec_id = CODEC_ID_CDGRAPHICS;
/// 75 sectors/sec * 4 packets/sector = 300 packets/sec
- av_set_pts_info(vst, 32, 1, 300);
+ avpriv_set_pts_info(vst, 32, 1, 300);
ret = avio_size(s->pb);
if (ret > 0)
@@ -49,18 +52,21 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
int ret;
- ret = av_get_packet(s->pb, pkt, CDG_PACKET_SIZE);
+ while (1) {
+ ret = av_get_packet(s->pb, pkt, CDG_PACKET_SIZE);
+ if (ret < 1 || (pkt->data[0] & CDG_MASK) == CDG_COMMAND)
+ break;
+ av_free_packet(pkt);
+ }
pkt->stream_index = 0;
return ret;
}
AVInputFormat ff_cdg_demuxer = {
- "cdg",
- NULL_IF_CONFIG_SMALL("CD Graphics Format"),
- 0,
- NULL,
- read_header,
- read_packet,
+ .name = "cdg",
+ .long_name = NULL_IF_CONFIG_SMALL("CD Graphics Format"),
+ .read_header = read_header,
+ .read_packet = read_packet,
.extensions = "cdg"
};
diff --git a/libavformat/concat.c b/libavformat/concat.c
index da9bee2..24c50c1 100644
--- a/libavformat/concat.c
+++ b/libavformat/concat.c
@@ -50,7 +50,6 @@ static av_cold int concat_close(URLContext *h)
err |= ffurl_close(nodes[i].uc);
av_freep(&data->nodes);
- av_freep(&h->priv_data);
return err < 0 ? -1 : 0;
}
@@ -62,16 +61,11 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags)
int64_t size;
size_t len, i;
URLContext *uc;
- struct concat_data *data;
+ struct concat_data *data = h->priv_data;
struct concat_nodes *nodes;
av_strstart(uri, "concat:", &uri);
- /* creating data */
- if (!(data = av_mallocz(sizeof(*data))))
- return AVERROR(ENOMEM);
- h->priv_data = data;
-
for (i = 0, len = 1; uri[i]; i++)
if (uri[i] == *AV_CAT_SEPARATOR)
/* integer overflow */
@@ -81,7 +75,6 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags)
}
if (!(nodes = av_malloc(sizeof(*nodes) * len))) {
- av_freep(&h->priv_data);
return AVERROR(ENOMEM);
} else
data->nodes = nodes;
@@ -101,7 +94,8 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags)
uri += len + strspn(uri+len, AV_CAT_SEPARATOR);
/* creating URLContext */
- if ((err = ffurl_open(&uc, node_uri, flags)) < 0)
+ if ((err = ffurl_open(&uc, node_uri, flags,
+ &h->interrupt_callback, NULL)) < 0)
break;
/* creating size */
@@ -190,9 +184,10 @@ static int64_t concat_seek(URLContext *h, int64_t pos, int whence)
}
URLProtocol ff_concat_protocol = {
- .name = "concat",
- .url_open = concat_open,
- .url_read = concat_read,
- .url_seek = concat_seek,
- .url_close = concat_close,
+ .name = "concat",
+ .url_open = concat_open,
+ .url_read = concat_read,
+ .url_seek = concat_seek,
+ .url_close = concat_close,
+ .priv_data_size = sizeof(struct concat_data),
};
diff --git a/libavformat/crcenc.c b/libavformat/crcenc.c
index 55c99d9..c67fd09 100644
--- a/libavformat/crcenc.c
+++ b/libavformat/crcenc.c
@@ -55,14 +55,14 @@ static int crc_write_trailer(struct AVFormatContext *s)
}
AVOutputFormat ff_crc_muxer = {
- "crc",
- NULL_IF_CONFIG_SMALL("CRC testing format"),
- NULL,
- "",
- sizeof(CRCState),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_RAWVIDEO,
- crc_write_header,
- crc_write_packet,
- crc_write_trailer,
+ .name = "crc",
+ .long_name = NULL_IF_CONFIG_SMALL("CRC testing format"),
+ .extensions = "",
+ .priv_data_size = sizeof(CRCState),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_header = crc_write_header,
+ .write_packet = crc_write_packet,
+ .write_trailer = crc_write_trailer,
+ .flags = AVFMT_NOTIMESTAMPS,
};
diff --git a/libavformat/crypto.c b/libavformat/crypto.c
index 5e7ee1e..7095360 100644
--- a/libavformat/crypto.c
+++ b/libavformat/crypto.c
@@ -45,9 +45,10 @@ typedef struct {
} CryptoContext;
#define OFFSET(x) offsetof(CryptoContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- {"key", "AES decryption key", OFFSET(key), FF_OPT_TYPE_BINARY },
- {"iv", "AES decryption initialization vector", OFFSET(iv), FF_OPT_TYPE_BINARY },
+ {"key", "AES decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, .flags = D },
+ {"iv", "AES decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY, .flags = D },
{ NULL }
};
@@ -61,7 +62,7 @@ static const AVClass crypto_class = {
static int crypto_open(URLContext *h, const char *uri, int flags)
{
const char *nested_url;
- int ret;
+ int ret = 0;
CryptoContext *c = h->priv_data;
if (!av_strstart(uri, "crypto+", &nested_url) &&
@@ -81,7 +82,8 @@ static int crypto_open(URLContext *h, const char *uri, int flags)
ret = AVERROR(ENOSYS);
goto err;
}
- if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ)) < 0) {
+ if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ,
+ &h->interrupt_callback, NULL)) < 0) {
av_log(h, AV_LOG_ERROR, "Unable to open input\n");
goto err;
}
@@ -95,10 +97,7 @@ static int crypto_open(URLContext *h, const char *uri, int flags)
h->is_streamed = 1;
- return 0;
err:
- av_freep(&c->key);
- av_freep(&c->iv);
return ret;
}
@@ -157,8 +156,6 @@ static int crypto_close(URLContext *h)
if (c->hd)
ffurl_close(c->hd);
av_freep(&c->aes);
- av_freep(&c->key);
- av_freep(&c->iv);
return 0;
}
diff --git a/libavformat/cutils.c b/libavformat/cutils.c
index 092aa8a..9955244 100644
--- a/libavformat/cutils.c
+++ b/libavformat/cutils.c
@@ -1,5 +1,5 @@
/*
- * Various simple utilities for ffmpeg system
+ * various simple utilities for libavformat
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
* This file is part of Libav.
@@ -24,7 +24,7 @@
/* add one element to a dynamic array */
void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem)
{
- /* see similar ffmpeg.c:grow_array() */
+ /* see similar avconv.c:grow_array() */
int nb, nb_alloc;
intptr_t *tab;
diff --git a/libavformat/daud.c b/libavformat/daud.c
index 1b3cfcf..9deca33 100644
--- a/libavformat/daud.c
+++ b/libavformat/daud.c
@@ -21,7 +21,7 @@
#include "avformat.h"
static int daud_header(AVFormatContext *s, AVFormatParameters *ap) {
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -71,30 +71,23 @@ static int daud_write_packet(struct AVFormatContext *s, AVPacket *pkt)
#if CONFIG_DAUD_DEMUXER
AVInputFormat ff_daud_demuxer = {
- "daud",
- NULL_IF_CONFIG_SMALL("D-Cinema audio format"),
- 0,
- NULL,
- daud_header,
- daud_packet,
- NULL,
- NULL,
+ .name = "daud",
+ .long_name = NULL_IF_CONFIG_SMALL("D-Cinema audio format"),
+ .read_header = daud_header,
+ .read_packet = daud_packet,
.extensions = "302",
};
#endif
#if CONFIG_DAUD_MUXER
-AVOutputFormat ff_daud_muxer =
-{
- "daud",
- NULL_IF_CONFIG_SMALL("D-Cinema audio format"),
- NULL,
- "302",
- 0,
- CODEC_ID_PCM_S24DAUD,
- CODEC_ID_NONE,
- daud_write_header,
- daud_write_packet,
- .flags= AVFMT_NOTIMESTAMPS,
+AVOutputFormat ff_daud_muxer = {
+ .name = "daud",
+ .long_name = NULL_IF_CONFIG_SMALL("D-Cinema audio format"),
+ .extensions = "302",
+ .audio_codec = CODEC_ID_PCM_S24DAUD,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = daud_write_header,
+ .write_packet = daud_write_packet,
+ .flags = AVFMT_NOTIMESTAMPS,
};
#endif
diff --git a/libavformat/dfa.c b/libavformat/dfa.c
index 8108535..ac49b61 100644
--- a/libavformat/dfa.c
+++ b/libavformat/dfa.c
@@ -21,6 +21,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
static int dfa_probe(AVProbeData *p)
{
@@ -45,7 +46,7 @@ static int dfa_read_header(AVFormatContext *s,
avio_skip(pb, 2); // unused
frames = avio_rl16(pb);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -58,7 +59,7 @@ static int dfa_read_header(AVFormatContext *s,
av_log(s, AV_LOG_WARNING, "Zero FPS reported, defaulting to 10\n");
mspf = 100;
}
- av_set_pts_info(st, 24, mspf, 1000);
+ avpriv_set_pts_info(st, 24, mspf, 1000);
avio_skip(pb, 128 - 16); // padding
st->duration = frames;
@@ -109,11 +110,10 @@ static int dfa_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_dfa_demuxer = {
- "dfa",
- NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
- 0,
- dfa_probe,
- dfa_read_header,
- dfa_read_packet,
+ .name = "dfa",
+ .long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
+ .read_probe = dfa_probe,
+ .read_header = dfa_read_header,
+ .read_packet = dfa_read_packet,
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/dsicin.c b/libavformat/dsicin.c
index d02de46..801ca6a 100644
--- a/libavformat/dsicin.c
+++ b/libavformat/dsicin.c
@@ -26,6 +26,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
typedef struct CinFileHeader {
@@ -107,11 +108,11 @@ static int cin_read_header(AVFormatContext *s, AVFormatParameters *ap)
cin->audio_buffer_size = 0;
/* initialize the video decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 32, 1, 12);
+ avpriv_set_pts_info(st, 32, 1, 12);
cin->video_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_DSICINVIDEO;
@@ -120,20 +121,19 @@ static int cin_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->height = hdr->video_frame_height;
/* initialize the audio decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 32, 1, 22050);
+ avpriv_set_pts_info(st, 32, 1, 22050);
cin->audio_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_DSICINAUDIO;
st->codec->codec_tag = 0; /* no tag */
st->codec->channels = 1;
st->codec->sample_rate = 22050;
- st->codec->bits_per_coded_sample = 16;
+ st->codec->bits_per_coded_sample = 8;
st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels;
- st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
return 0;
}
@@ -211,16 +211,17 @@ static int cin_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->stream_index = cin->audio_stream_index;
pkt->pts = cin->audio_stream_pts;
- cin->audio_stream_pts += cin->audio_buffer_size * 2 / cin->file_header.audio_frame_size;
+ pkt->duration = cin->audio_buffer_size - (pkt->pts == 0);
+ cin->audio_stream_pts += pkt->duration;
cin->audio_buffer_size = 0;
return 0;
}
AVInputFormat ff_dsicin_demuxer = {
- "dsicin",
- NULL_IF_CONFIG_SMALL("Delphine Software International CIN format"),
- sizeof(CinDemuxContext),
- cin_probe,
- cin_read_header,
- cin_read_packet,
+ .name = "dsicin",
+ .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN format"),
+ .priv_data_size = sizeof(CinDemuxContext),
+ .read_probe = cin_probe,
+ .read_header = cin_read_header,
+ .read_packet = cin_read_packet,
};
diff --git a/libavformat/dtsdec.c b/libavformat/dtsdec.c
index 943f6a5..d61855d 100644
--- a/libavformat/dtsdec.c
+++ b/libavformat/dtsdec.c
@@ -66,12 +66,11 @@ static int dts_probe(AVProbeData *p)
}
AVInputFormat ff_dts_demuxer = {
- "dts",
- NULL_IF_CONFIG_SMALL("raw DTS"),
- 0,
- dts_probe,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "dts",
+ .long_name = NULL_IF_CONFIG_SMALL("raw DTS"),
+ .read_probe = dts_probe,
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "dts",
.value = CODEC_ID_DTS,
diff --git a/libavformat/dv.c b/libavformat/dv.c
index 4b41e0a..805f252 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -30,8 +30,10 @@
*/
#include <time.h>
#include "avformat.h"
+#include "internal.h"
#include "libavcodec/dvdata.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
#include "dv.h"
struct DVDemuxContext {
@@ -95,7 +97,7 @@ static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t)
/*
* There's a couple of assumptions being made here:
* 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples.
- * We can pass them upwards when ffmpeg will be ready to deal with them.
+ * We can pass them upwards when libavcodec will be ready to deal with them.
* 2. We don't do software emphasis.
* 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples
* are converted into 16bit linear ones.
@@ -210,10 +212,10 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
/* Dynamic handling of the audio streams in DV */
for (i = 0; i < ach; i++) {
if (!c->ast[i]) {
- c->ast[i] = av_new_stream(c->fctx, 0);
+ c->ast[i] = avformat_new_stream(c->fctx, NULL);
if (!c->ast[i])
break;
- av_set_pts_info(c->ast[i], 64, 1, 30000);
+ avpriv_set_pts_info(c->ast[i], 64, 1, 30000);
c->ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
c->ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE;
@@ -243,7 +245,7 @@ static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
if (c->sys) {
avctx = c->vst->codec;
- av_set_pts_info(c->vst, 64, c->sys->time_base.num,
+ avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num,
c->sys->time_base.den);
avctx->time_base= c->sys->time_base;
if (!avctx->width){
@@ -269,7 +271,7 @@ static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
* The following 3 functions constitute our interface to the world
*/
-DVDemuxContext* dv_init_demux(AVFormatContext *s)
+DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s)
{
DVDemuxContext *c;
@@ -277,7 +279,7 @@ DVDemuxContext* dv_init_demux(AVFormatContext *s)
if (!c)
return NULL;
- c->vst = av_new_stream(s, 0);
+ c->vst = avformat_new_stream(s, NULL);
if (!c->vst) {
av_free(c);
return NULL;
@@ -298,7 +300,7 @@ DVDemuxContext* dv_init_demux(AVFormatContext *s)
return c;
}
-int dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
+int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
{
int size = -1;
int i;
@@ -315,14 +317,14 @@ int dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
return size;
}
-int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
+int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
uint8_t* buf, int buf_size)
{
int size, i;
uint8_t *ppcm[4] = {0};
if (buf_size < DV_PROFILE_BYTES ||
- !(c->sys = ff_dv_frame_profile(c->sys, buf, buf_size)) ||
+ !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||
buf_size < c->sys->frame_size) {
return -1; /* Broken frame, or not enough data */
}
@@ -368,7 +370,7 @@ static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
int64_t timestamp, int flags)
{
// FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk)
- const DVprofile* sys = ff_dv_codec_profile(c->vst->codec);
+ const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec);
int64_t offset;
int64_t size = avio_size(s->pb) - s->data_offset;
int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
@@ -406,7 +408,7 @@ static int dv_read_header(AVFormatContext *s,
unsigned state, marker_pos = 0;
RawDVContext *c = s->priv_data;
- c->dv_demux = dv_init_demux(s);
+ c->dv_demux = avpriv_dv_init_demux(s);
if (!c->dv_demux)
return -1;
@@ -431,7 +433,7 @@ static int dv_read_header(AVFormatContext *s,
avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
return AVERROR(EIO);
- c->dv_demux->sys = ff_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
+ c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
if (!c->dv_demux->sys) {
av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n");
return -1;
@@ -449,7 +451,7 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
int size;
RawDVContext *c = s->priv_data;
- size = dv_get_packet(c->dv_demux, pkt);
+ size = avpriv_dv_get_packet(c->dv_demux, pkt);
if (size < 0) {
if (!c->dv_demux->sys)
@@ -458,7 +460,7 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
if (avio_read(s->pb, c->buf, size) <= 0)
return AVERROR(EIO);
- size = dv_produce_packet(c->dv_demux, pkt, c->buf, size);
+ size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size);
}
return size;
@@ -519,14 +521,14 @@ static int dv_probe(AVProbeData *p)
#if CONFIG_DV_DEMUXER
AVInputFormat ff_dv_demuxer = {
- "dv",
- NULL_IF_CONFIG_SMALL("DV video format"),
- sizeof(RawDVContext),
- dv_probe,
- dv_read_header,
- dv_read_packet,
- dv_read_close,
- dv_read_seek,
+ .name = "dv",
+ .long_name = NULL_IF_CONFIG_SMALL("DV video format"),
+ .priv_data_size = sizeof(RawDVContext),
+ .read_probe = dv_probe,
+ .read_header = dv_read_header,
+ .read_packet = dv_read_packet,
+ .read_close = dv_read_close,
+ .read_seek = dv_read_seek,
.extensions = "dv,dif",
};
#endif
diff --git a/libavformat/dv.h b/libavformat/dv.h
index 650699d..b4bb10d 100644
--- a/libavformat/dv.h
+++ b/libavformat/dv.h
@@ -31,9 +31,9 @@
#include "avformat.h"
typedef struct DVDemuxContext DVDemuxContext;
-DVDemuxContext* dv_init_demux(AVFormatContext* s);
-int dv_get_packet(DVDemuxContext*, AVPacket *);
-int dv_produce_packet(DVDemuxContext*, AVPacket*, uint8_t*, int);
+DVDemuxContext* avpriv_dv_init_demux(AVFormatContext* s);
+int avpriv_dv_get_packet(DVDemuxContext*, AVPacket *);
+int avpriv_dv_produce_packet(DVDemuxContext*, AVPacket*, uint8_t*, int);
void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset);
typedef struct DVMuxContext DVMuxContext;
diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index 537581a..bffad44 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -35,6 +35,7 @@
#include "libavcodec/dvdata.h"
#include "dv.h"
#include "libavutil/fifo.h"
+#include "libavutil/mathematics.h"
struct DVMuxContext {
const DVprofile* sys; /* current DV profile, e.g.: 525/60, 625/50 */
@@ -42,7 +43,7 @@ struct DVMuxContext {
AVStream *ast[2]; /* stereo audio streams */
AVFifoBuffer *audio_data[2]; /* FIFO for storing excessive amounts of PCM */
int frames; /* current frame number */
- time_t start_time; /* recording start time */
+ int64_t start_time; /* recording start time */
int has_audio; /* frame under contruction has audio */
int has_video; /* frame under contruction has video */
uint8_t frame_buf[DV_MAX_FRAME_SIZE]; /* frame under contruction */
@@ -191,8 +192,8 @@ static void dv_inject_audio(DVMuxContext *c, int channel, uint8_t* frame_ptr)
if (of*2 >= size)
continue;
- frame_ptr[d] = av_fifo_peek(c->audio_data[channel], of*2+1); // FIXME: maybe we have to admit
- frame_ptr[d+1] = av_fifo_peek(c->audio_data[channel], of*2); // that DV is a big-endian PCM
+ frame_ptr[d] = *av_fifo_peek2(c->audio_data[channel], of*2+1); // FIXME: maybe we have to admit
+ frame_ptr[d+1] = *av_fifo_peek2(c->audio_data[channel], of*2); // that DV is a big-endian PCM
}
frame_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
}
@@ -289,6 +290,7 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s)
{
DVMuxContext *c = s->priv_data;
AVStream *vst = NULL;
+ AVDictionaryEntry *t;
int i;
/* we support at most 1 video and 2 audio streams */
@@ -323,7 +325,7 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s)
c->ast[i]->codec->channels != 2))
goto bail_out;
}
- c->sys = ff_dv_codec_profile(vst->codec);
+ c->sys = avpriv_dv_codec_profile(vst->codec);
if (!c->sys)
goto bail_out;
@@ -336,7 +338,13 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s)
c->frames = 0;
c->has_audio = 0;
c->has_video = 0;
- c->start_time = (time_t)s->timestamp;
+#if FF_API_TIMESTAMP
+ if (s->timestamp)
+ c->start_time = s->timestamp;
+ else
+#endif
+ if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+ c->start_time = ff_iso8601_to_unix_time(t->value);
for (i=0; i < c->n_ast; i++) {
if (c->ast[i] && !(c->audio_data[i]=av_fifo_alloc(100*AVCODEC_MAX_AUDIO_FRAME_SIZE))) {
@@ -400,14 +408,13 @@ static int dv_write_trailer(struct AVFormatContext *s)
}
AVOutputFormat ff_dv_muxer = {
- "dv",
- NULL_IF_CONFIG_SMALL("DV video format"),
- NULL,
- "dv",
- sizeof(DVMuxContext),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_DVVIDEO,
- dv_write_header,
- dv_write_packet,
- dv_write_trailer,
+ .name = "dv",
+ .long_name = NULL_IF_CONFIG_SMALL("DV video format"),
+ .extensions = "dv",
+ .priv_data_size = sizeof(DVMuxContext),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_DVVIDEO,
+ .write_header = dv_write_header,
+ .write_packet = dv_write_packet,
+ .write_trailer = dv_write_trailer,
};
diff --git a/libavformat/dxa.c b/libavformat/dxa.c
index 1e1d505..0cc803d 100644
--- a/libavformat/dxa.c
+++ b/libavformat/dxa.c
@@ -21,6 +21,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
#define DXA_EXTRA_SIZE 9
@@ -87,7 +88,7 @@ static int dxa_read_header(AVFormatContext *s, AVFormatParameters *ap)
h = avio_rb16(pb);
c->has_sound = 0;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
@@ -100,7 +101,7 @@ static int dxa_read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_skip(pb, 16);
fsize = avio_rl32(pb);
- ast = av_new_stream(s, 0);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return -1;
ret = ff_get_wav_header(pb, ast->codec, fsize);
@@ -127,7 +128,7 @@ static int dxa_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->width = w;
st->codec->height = h;
av_reduce(&den, &num, den, num, (1UL<<31)-1);
- av_set_pts_info(st, 33, num, den);
+ avpriv_set_pts_info(st, 33, num, den);
/* flags & 0x80 means that image is interlaced,
* flags & 0x40 means that image has double height
* either way set true height
@@ -213,10 +214,10 @@ static int dxa_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_dxa_demuxer = {
- "dxa",
- NULL_IF_CONFIG_SMALL("DXA"),
- sizeof(DXAContext),
- dxa_probe,
- dxa_read_header,
- dxa_read_packet,
+ .name = "dxa",
+ .long_name = NULL_IF_CONFIG_SMALL("DXA"),
+ .priv_data_size = sizeof(DXAContext),
+ .read_probe = dxa_probe,
+ .read_header = dxa_read_header,
+ .read_packet = dxa_read_packet,
};
diff --git a/libavformat/eacdata.c b/libavformat/eacdata.c
index 5c89559..8fe144e 100644
--- a/libavformat/eacdata.c
+++ b/libavformat/eacdata.c
@@ -29,6 +29,7 @@
*/
#include "avformat.h"
+#include "internal.h"
typedef struct {
unsigned int channels;
@@ -64,7 +65,7 @@ static int cdata_read_header(AVFormatContext *s, AVFormatParameters *ap)
sample_rate = avio_rb16(pb);
avio_skip(pb, 12);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -72,7 +73,7 @@ static int cdata_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->codec_id = CODEC_ID_ADPCM_EA_XAS;
st->codec->channels = cdata->channels;
st->codec->sample_rate = sample_rate;
- av_set_pts_info(st, 64, 1, sample_rate);
+ avpriv_set_pts_info(st, 64, 1, sample_rate);
cdata->audio_pts = 0;
return 0;
@@ -91,11 +92,11 @@ static int cdata_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_ea_cdata_demuxer = {
- "ea_cdata",
- NULL_IF_CONFIG_SMALL("Electronic Arts cdata"),
- sizeof(CdataDemuxContext),
- cdata_probe,
- cdata_read_header,
- cdata_read_packet,
+ .name = "ea_cdata",
+ .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts cdata"),
+ .priv_data_size = sizeof(CdataDemuxContext),
+ .read_probe = cdata_probe,
+ .read_header = cdata_read_header,
+ .read_packet = cdata_read_packet,
.extensions = "cdata",
};
diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index 06689dd..0facc8a 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -27,6 +27,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define SCHl_TAG MKTAG('S', 'C', 'H', 'l')
#define SEAD_TAG MKTAG('S', 'E', 'A', 'D') /* Sxxx header */
@@ -410,7 +411,7 @@ static int ea_read_header(AVFormatContext *s,
if (ea->video_codec) {
/* initialize the video decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
ea->video_stream_index = st->index;
@@ -435,10 +436,10 @@ static int ea_read_header(AVFormatContext *s,
}
/* initialize the audio decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 33, 1, ea->sample_rate);
+ avpriv_set_pts_info(st, 33, 1, ea->sample_rate);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = ea->audio_codec;
st->codec->codec_tag = 0; /* no tag */
@@ -569,10 +570,10 @@ get_video_packet:
}
AVInputFormat ff_ea_demuxer = {
- "ea",
- NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia Format"),
- sizeof(EaDemuxContext),
- ea_probe,
- ea_read_header,
- ea_read_packet,
+ .name = "ea",
+ .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia Format"),
+ .priv_data_size = sizeof(EaDemuxContext),
+ .read_probe = ea_probe,
+ .read_header = ea_read_header,
+ .read_packet = ea_read_packet,
};
diff --git a/libavformat/ffm.h b/libavformat/ffm.h
index 89a14a5..6ce5e04 100644
--- a/libavformat/ffm.h
+++ b/libavformat/ffm.h
@@ -1,5 +1,5 @@
/*
- * FFM (ffserver live feed) common header
+ * FFM (avserver live feed) common header
* Copyright (c) 2001 Fabrice Bellard
*
* This file is part of Libav.
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c
index dfd86cb..9cee3ad 100644
--- a/libavformat/ffmdec.c
+++ b/libavformat/ffmdec.c
@@ -1,5 +1,5 @@
/*
- * FFM (ffserver live feed) demuxer
+ * FFM (avserver live feed) demuxer
* Copyright (c) 2001 Fabrice Bellard
*
* This file is part of Libav.
@@ -20,9 +20,11 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
#include "avformat.h"
+#include "internal.h"
#include "ffm.h"
-#if CONFIG_FFSERVER
+#if CONFIG_AVSERVER
#include <unistd.h>
int64_t ffm_read_write_index(int fd)
@@ -54,7 +56,7 @@ void ffm_set_write_index(AVFormatContext *s, int64_t pos, int64_t file_size)
ffm->write_index = pos;
ffm->file_size = file_size;
}
-#endif // CONFIG_FFSERVER
+#endif // CONFIG_AVSERVER
static int ffm_is_avail_data(AVFormatContext *s, int size)
{
@@ -289,18 +291,17 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
for(i=0;i<nb_streams;i++) {
char rc_eq_buf[128];
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
- av_set_pts_info(st, 64, 1, 1000000);
+ avpriv_set_pts_info(st, 64, 1, 1000000);
codec = st->codec;
/* generic info */
codec->codec_id = avio_rb32(pb);
codec->codec_type = avio_r8(pb); /* codec_type */
codec->bit_rate = avio_rb32(pb);
- st->quality = avio_rb32(pb);
codec->flags = avio_rb32(pb);
codec->flags2 = avio_rb32(pb);
codec->debug = avio_rb32(pb);
@@ -324,10 +325,10 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
codec->rc_max_rate = avio_rb32(pb);
codec->rc_min_rate = avio_rb32(pb);
codec->rc_buffer_size = avio_rb32(pb);
- codec->i_quant_factor = av_int2dbl(avio_rb64(pb));
- codec->b_quant_factor = av_int2dbl(avio_rb64(pb));
- codec->i_quant_offset = av_int2dbl(avio_rb64(pb));
- codec->b_quant_offset = av_int2dbl(avio_rb64(pb));
+ codec->i_quant_factor = av_int2double(avio_rb64(pb));
+ codec->b_quant_factor = av_int2double(avio_rb64(pb));
+ codec->i_quant_offset = av_int2double(avio_rb64(pb));
+ codec->b_quant_offset = av_int2double(avio_rb64(pb));
codec->dct_algo = avio_rb32(pb);
codec->strict_std_compliance = avio_rb32(pb);
codec->max_b_frames = avio_rb32(pb);
@@ -339,22 +340,20 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
codec->mb_decision = avio_rb32(pb);
codec->nsse_weight = avio_rb32(pb);
codec->frame_skip_cmp = avio_rb32(pb);
- codec->rc_buffer_aggressivity = av_int2dbl(avio_rb64(pb));
+ codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb));
codec->codec_tag = avio_rb32(pb);
codec->thread_count = avio_r8(pb);
codec->coder_type = avio_rb32(pb);
codec->me_cmp = avio_rb32(pb);
- codec->partitions = avio_rb32(pb);
codec->me_subpel_quality = avio_rb32(pb);
codec->me_range = avio_rb32(pb);
codec->keyint_min = avio_rb32(pb);
codec->scenechange_threshold = avio_rb32(pb);
codec->b_frame_strategy = avio_rb32(pb);
- codec->qcompress = av_int2dbl(avio_rb64(pb));
- codec->qblur = av_int2dbl(avio_rb64(pb));
+ codec->qcompress = av_int2double(avio_rb64(pb));
+ codec->qblur = av_int2double(avio_rb64(pb));
codec->max_qdiff = avio_rb32(pb);
codec->refs = avio_rb32(pb);
- codec->directpred = avio_rb32(pb);
break;
case AVMEDIA_TYPE_AUDIO:
codec->sample_rate = avio_rb32(pb);
@@ -509,12 +508,12 @@ static int ffm_probe(AVProbeData *p)
}
AVInputFormat ff_ffm_demuxer = {
- "ffm",
- NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"),
- sizeof(FFMContext),
- ffm_probe,
- ffm_read_header,
- ffm_read_packet,
- ffm_close,
- ffm_seek,
+ .name = "ffm",
+ .long_name = NULL_IF_CONFIG_SMALL("FFM (AVserver live feed) format"),
+ .priv_data_size = sizeof(FFMContext),
+ .read_probe = ffm_probe,
+ .read_header = ffm_read_header,
+ .read_packet = ffm_read_packet,
+ .read_close = ffm_close,
+ .read_seek = ffm_seek,
};
diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c
index 71d93e5..d304f57 100644
--- a/libavformat/ffmenc.c
+++ b/libavformat/ffmenc.c
@@ -1,5 +1,5 @@
/*
- * FFM (ffserver live feed) muxer
+ * FFM (avserver live feed) muxer
* Copyright (c) 2001 Fabrice Bellard
*
* This file is part of Libav.
@@ -20,7 +20,9 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
#include "avformat.h"
+#include "internal.h"
#include "ffm.h"
static void flush_packet(AVFormatContext *s)
@@ -106,14 +108,13 @@ static int ffm_write_header(AVFormatContext *s)
/* list of streams */
for(i=0;i<s->nb_streams;i++) {
st = s->streams[i];
- av_set_pts_info(st, 64, 1, 1000000);
+ avpriv_set_pts_info(st, 64, 1, 1000000);
codec = st->codec;
/* generic info */
avio_wb32(pb, codec->codec_id);
avio_w8(pb, codec->codec_type);
avio_wb32(pb, codec->bit_rate);
- avio_wb32(pb, st->quality);
avio_wb32(pb, codec->flags);
avio_wb32(pb, codec->flags2);
avio_wb32(pb, codec->debug);
@@ -136,10 +137,10 @@ static int ffm_write_header(AVFormatContext *s)
avio_wb32(pb, codec->rc_max_rate);
avio_wb32(pb, codec->rc_min_rate);
avio_wb32(pb, codec->rc_buffer_size);
- avio_wb64(pb, av_dbl2int(codec->i_quant_factor));
- avio_wb64(pb, av_dbl2int(codec->b_quant_factor));
- avio_wb64(pb, av_dbl2int(codec->i_quant_offset));
- avio_wb64(pb, av_dbl2int(codec->b_quant_offset));
+ avio_wb64(pb, av_double2int(codec->i_quant_factor));
+ avio_wb64(pb, av_double2int(codec->b_quant_factor));
+ avio_wb64(pb, av_double2int(codec->i_quant_offset));
+ avio_wb64(pb, av_double2int(codec->b_quant_offset));
avio_wb32(pb, codec->dct_algo);
avio_wb32(pb, codec->strict_std_compliance);
avio_wb32(pb, codec->max_b_frames);
@@ -151,22 +152,20 @@ static int ffm_write_header(AVFormatContext *s)
avio_wb32(pb, codec->mb_decision);
avio_wb32(pb, codec->nsse_weight);
avio_wb32(pb, codec->frame_skip_cmp);
- avio_wb64(pb, av_dbl2int(codec->rc_buffer_aggressivity));
+ avio_wb64(pb, av_double2int(codec->rc_buffer_aggressivity));
avio_wb32(pb, codec->codec_tag);
avio_w8(pb, codec->thread_count);
avio_wb32(pb, codec->coder_type);
avio_wb32(pb, codec->me_cmp);
- avio_wb32(pb, codec->partitions);
avio_wb32(pb, codec->me_subpel_quality);
avio_wb32(pb, codec->me_range);
avio_wb32(pb, codec->keyint_min);
avio_wb32(pb, codec->scenechange_threshold);
avio_wb32(pb, codec->b_frame_strategy);
- avio_wb64(pb, av_dbl2int(codec->qcompress));
- avio_wb64(pb, av_dbl2int(codec->qblur));
+ avio_wb64(pb, av_double2int(codec->qcompress));
+ avio_wb64(pb, av_double2int(codec->qblur));
avio_wb32(pb, codec->max_qdiff);
avio_wb32(pb, codec->refs);
- avio_wb32(pb, codec->directpred);
break;
case AVMEDIA_TYPE_AUDIO:
avio_wb32(pb, codec->sample_rate);
@@ -241,15 +240,14 @@ static int ffm_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_ffm_muxer = {
- "ffm",
- NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"),
- "",
- "ffm",
- sizeof(FFMContext),
- /* not really used */
- CODEC_ID_MP2,
- CODEC_ID_MPEG1VIDEO,
- ffm_write_header,
- ffm_write_packet,
- ffm_write_trailer,
+ .name = "ffm",
+ .long_name = NULL_IF_CONFIG_SMALL("FFM (AVserver live feed) format"),
+ .mime_type = "",
+ .extensions = "ffm",
+ .priv_data_size = sizeof(FFMContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG1VIDEO,
+ .write_header = ffm_write_header,
+ .write_packet = ffm_write_packet,
+ .write_trailer = ffm_write_trailer,
};
diff --git a/libavformat/ffmetadec.c b/libavformat/ffmetadec.c
index e3d800d..21e5ee9 100644
--- a/libavformat/ffmetadec.c
+++ b/libavformat/ffmetadec.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/mathematics.h"
#include "avformat.h"
#include "ffmeta.h"
#include "internal.h"
@@ -74,7 +75,7 @@ static AVChapter *read_chapter(AVFormatContext *s)
end = AV_NOPTS_VALUE;
}
- return ff_new_chapter(s, s->nb_chapters, tb, start, end, NULL);
+ return avpriv_new_chapter(s, s->nb_chapters, tb, start, end, NULL);
}
static uint8_t *unescape(uint8_t *buf, int size)
@@ -131,7 +132,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
get_line(s->pb, line, sizeof(line));
if (!memcmp(line, ID_STREAM, strlen(ID_STREAM))) {
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return -1;
diff --git a/libavformat/file.c b/libavformat/file.c
index 649640a..cca9ec1 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -1,5 +1,5 @@
/*
- * Buffered file io for ffmpeg system
+ * buffered file I/O
* Copyright (c) 2001 Fabrice Bellard
*
* This file is part of Libav.
diff --git a/libavformat/filmstripdec.c b/libavformat/filmstripdec.c
index 095bf9e..648fb4f 100644
--- a/libavformat/filmstripdec.c
+++ b/libavformat/filmstripdec.c
@@ -26,6 +26,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define RAND_TAG MKBETAG('R','a','n','d')
@@ -49,7 +50,7 @@ static int read_header(AVFormatContext *s,
return AVERROR_INVALIDDATA;
}
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -67,7 +68,7 @@ static int read_header(AVFormatContext *s,
st->codec->width = avio_rb16(pb);
st->codec->height = avio_rb16(pb);
film->leading = avio_rb16(pb);
- av_set_pts_info(st, 64, 1, avio_rb16(pb));
+ avpriv_set_pts_info(st, 64, 1, avio_rb16(pb));
avio_seek(pb, 0, SEEK_SET);
@@ -99,13 +100,11 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in
}
AVInputFormat ff_filmstrip_demuxer = {
- "filmstrip",
- NULL_IF_CONFIG_SMALL("Adobe Filmstrip"),
- sizeof(FilmstripDemuxContext),
- NULL,
- read_header,
- read_packet,
- NULL,
- read_seek,
+ .name = "filmstrip",
+ .long_name = NULL_IF_CONFIG_SMALL("Adobe Filmstrip"),
+ .priv_data_size = sizeof(FilmstripDemuxContext),
+ .read_header = read_header,
+ .read_packet = read_packet,
+ .read_seek = read_seek,
.extensions = "flm",
};
diff --git a/libavformat/filmstripenc.c b/libavformat/filmstripenc.c
index 21f4755..0e55408 100644
--- a/libavformat/filmstripenc.c
+++ b/libavformat/filmstripenc.c
@@ -72,14 +72,13 @@ static int write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_filmstrip_muxer = {
- "filmstrip",
- NULL_IF_CONFIG_SMALL("Adobe Filmstrip"),
- NULL,
- "flm",
- sizeof(FilmstripMuxContext),
- CODEC_ID_NONE,
- CODEC_ID_RAWVIDEO,
- write_header,
- write_packet,
- write_trailer,
+ .name = "filmstrip",
+ .long_name = NULL_IF_CONFIG_SMALL("Adobe Filmstrip"),
+ .extensions = "flm",
+ .priv_data_size = sizeof(FilmstripMuxContext),
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_header = write_header,
+ .write_packet = write_packet,
+ .write_trailer = write_trailer,
};
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
index 02452b4..9e083d1 100644
--- a/libavformat/flacdec.c
+++ b/libavformat/flacdec.c
@@ -21,9 +21,11 @@
#include "libavcodec/flac.h"
#include "avformat.h"
+#include "internal.h"
#include "rawdec.h"
#include "oggdec.h"
#include "vorbiscomment.h"
+#include "libavcodec/bytestream.h"
static int flac_read_header(AVFormatContext *s,
AVFormatParameters *ap)
@@ -31,7 +33,7 @@ static int flac_read_header(AVFormatContext *s,
int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
uint8_t header[4];
uint8_t *buffer=NULL;
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -48,11 +50,12 @@ static int flac_read_header(AVFormatContext *s,
/* process metadata blocks */
while (!s->pb->eof_reached && !metadata_last) {
avio_read(s->pb, header, 4);
- ff_flac_parse_block_header(header, &metadata_last, &metadata_type,
+ avpriv_flac_parse_block_header(header, &metadata_last, &metadata_type,
&metadata_size);
switch (metadata_type) {
/* allocate and read metadata block for supported types */
case FLAC_METADATA_TYPE_STREAMINFO:
+ case FLAC_METADATA_TYPE_CUESHEET:
case FLAC_METADATA_TYPE_VORBIS_COMMENT:
buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!buffer) {
@@ -87,14 +90,38 @@ static int flac_read_header(AVFormatContext *s,
buffer = NULL;
/* get codec params from STREAMINFO header */
- ff_flac_parse_streaminfo(st->codec, &si, st->codec->extradata);
+ avpriv_flac_parse_streaminfo(st->codec, &si, st->codec->extradata);
/* set time base and duration */
if (si.samplerate > 0) {
- av_set_pts_info(st, 64, 1, si.samplerate);
+ avpriv_set_pts_info(st, 64, 1, si.samplerate);
if (si.samples > 0)
st->duration = si.samples;
}
+ } else if (metadata_type == FLAC_METADATA_TYPE_CUESHEET) {
+ uint8_t isrc[13];
+ uint64_t start;
+ const uint8_t *offset;
+ int i, chapters, track, ti;
+ if (metadata_size < 431)
+ return AVERROR_INVALIDDATA;
+ offset = buffer + 395;
+ chapters = bytestream_get_byte(&offset) - 1;
+ if (chapters <= 0)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < chapters; i++) {
+ if (offset + 36 - buffer > metadata_size)
+ return AVERROR_INVALIDDATA;
+ start = bytestream_get_be64(&offset);
+ track = bytestream_get_byte(&offset);
+ bytestream_get_buffer(&offset, isrc, 12);
+ isrc[12] = 0;
+ offset += 14;
+ ti = bytestream_get_byte(&offset);
+ if (ti <= 0) return AVERROR_INVALIDDATA;
+ offset += ti * 12;
+ avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc);
+ }
} else {
/* STREAMINFO must be the first block */
if (!found_streaminfo) {
@@ -124,12 +151,11 @@ static int flac_probe(AVProbeData *p)
}
AVInputFormat ff_flac_demuxer = {
- "flac",
- NULL_IF_CONFIG_SMALL("raw FLAC"),
- 0,
- flac_probe,
- flac_read_header,
- ff_raw_read_partial_packet,
+ .name = "flac",
+ .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"),
+ .read_probe = flac_probe,
+ .read_header = flac_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "flac",
.value = CODEC_ID_FLAC,
diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index fb28a6e..725dc71 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -41,7 +41,7 @@ static int flac_write_block_padding(AVIOContext *pb, unsigned int n_padding_byte
static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m,
int last_block, int bitexact)
{
- const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
+ const char *vendor = bitexact ? "Libav" : LIBAVFORMAT_IDENT;
unsigned int len, count;
uint8_t *p, *p0;
@@ -94,7 +94,7 @@ static int flac_write_trailer(struct AVFormatContext *s)
enum FLACExtradataFormat format;
int64_t file_size;
- if (!ff_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo))
+ if (!avpriv_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo))
return -1;
if (pb->seekable) {
@@ -118,15 +118,14 @@ static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_flac_muxer = {
- "flac",
- NULL_IF_CONFIG_SMALL("raw FLAC"),
- "audio/x-flac",
- "flac",
- 0,
- CODEC_ID_FLAC,
- CODEC_ID_NONE,
- flac_write_header,
- flac_write_packet,
- flac_write_trailer,
+ .name = "flac",
+ .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"),
+ .mime_type = "audio/x-flac",
+ .extensions = "flac",
+ .audio_codec = CODEC_ID_FLAC,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = flac_write_header,
+ .write_packet = flac_write_packet,
+ .write_trailer = flac_write_trailer,
.flags= AVFMT_NOTIMESTAMPS,
};
diff --git a/libavformat/flacenc_header.c b/libavformat/flacenc_header.c
index 90c5a77..c1f7c86 100644
--- a/libavformat/flacenc_header.c
+++ b/libavformat/flacenc_header.c
@@ -34,16 +34,14 @@ int ff_flac_write_header(AVIOContext *pb, AVCodecContext *codec,
enum FLACExtradataFormat format;
header[4] = last_block ? 0x80 : 0x00;
- if (!ff_flac_is_extradata_valid(codec, &format, &streaminfo))
+ if (!avpriv_flac_is_extradata_valid(codec, &format, &streaminfo))
return -1;
- /* write "fLaC" stream marker and first metadata block header if needed */
- if (format == FLAC_EXTRADATA_FORMAT_STREAMINFO) {
- avio_write(pb, header, 8);
- }
+ /* write "fLaC" stream marker and first metadata block header */
+ avio_write(pb, header, 8);
- /* write STREAMINFO or full header */
- avio_write(pb, codec->extradata, codec->extradata_size);
+ /* write STREAMINFO */
+ avio_write(pb, streaminfo, FLAC_STREAMINFO_SIZE);
return 0;
}
diff --git a/libavformat/flic.c b/libavformat/flic.c
index fcdf4c8..7edc46e 100644
--- a/libavformat/flic.c
+++ b/libavformat/flic.c
@@ -34,6 +34,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/audioconvert.h"
#include "avformat.h"
+#include "internal.h"
#define FLIC_FILE_MAGIC_1 0xAF11
#define FLIC_FILE_MAGIC_2 0xAF12
@@ -105,7 +106,7 @@ static int flic_read_header(AVFormatContext *s,
speed = FLIC_DEFAULT_SPEED;
/* initialize the decoder streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
flic->video_stream_index = st->index;
@@ -145,7 +146,7 @@ static int flic_read_header(AVFormatContext *s,
*/
if (AV_RL16(&preamble[4]) == FLIC_TFTD_CHUNK_AUDIO) {
/* TFTD videos have an extra 22050 Hz 8-bit mono audio stream */
- ast = av_new_stream(s, 1);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
@@ -167,10 +168,10 @@ static int flic_read_header(AVFormatContext *s,
/* Since the header information is incorrect we have to figure out the
* framerate using block_align and the fact that the audio is 22050 Hz.
* We usually have two cases: 2205 -> 10 fps and 1470 -> 15 fps */
- av_set_pts_info(st, 64, ast->codec->block_align, FLIC_TFTD_SAMPLE_RATE);
- av_set_pts_info(ast, 64, 1, FLIC_TFTD_SAMPLE_RATE);
+ avpriv_set_pts_info(st, 64, ast->codec->block_align, FLIC_TFTD_SAMPLE_RATE);
+ avpriv_set_pts_info(ast, 64, 1, FLIC_TFTD_SAMPLE_RATE);
} else if (AV_RL16(&header[0x10]) == FLIC_CHUNK_MAGIC_1) {
- av_set_pts_info(st, 64, FLIC_MC_SPEED, 70);
+ avpriv_set_pts_info(st, 64, FLIC_MC_SPEED, 70);
/* rewind the stream since the first chunk is at offset 12 */
avio_seek(pb, 12, SEEK_SET);
@@ -182,10 +183,10 @@ static int flic_read_header(AVFormatContext *s,
memcpy(st->codec->extradata, header, 12);
} else if (magic_number == FLIC_FILE_MAGIC_1) {
- av_set_pts_info(st, 64, speed, 70);
+ avpriv_set_pts_info(st, 64, speed, 70);
} else if ((magic_number == FLIC_FILE_MAGIC_2) ||
(magic_number == FLIC_FILE_MAGIC_3)) {
- av_set_pts_info(st, 64, speed, 1000);
+ avpriv_set_pts_info(st, 64, speed, 1000);
} else {
av_log(s, AV_LOG_INFO, "Invalid or unsupported magic chunk in file\n");
return AVERROR_INVALIDDATA;
@@ -261,10 +262,10 @@ static int flic_read_packet(AVFormatContext *s,
}
AVInputFormat ff_flic_demuxer = {
- "flic",
- NULL_IF_CONFIG_SMALL("FLI/FLC/FLX animation format"),
- sizeof(FlicDemuxContext),
- flic_probe,
- flic_read_header,
- flic_read_packet,
+ .name = "flic",
+ .long_name = NULL_IF_CONFIG_SMALL("FLI/FLC/FLX animation format"),
+ .priv_data_size = sizeof(FlicDemuxContext),
+ .read_probe = flic_probe,
+ .read_header = flic_read_header,
+ .read_packet = flic_read_packet,
};
diff --git a/libavformat/flv.h b/libavformat/flv.h
index c86e20a..6418b27 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -1,5 +1,4 @@
-/**
- * @file
+/*
* FLV common header
*
* Copyright (c) 2006 The Libav Project
@@ -21,6 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * FLV common header
+ */
+
#ifndef AVFORMAT_FLV_H
#define AVFORMAT_FLV_H
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 5f442f7..4f1c805 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -26,9 +26,12 @@
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
+#include "libavutil/intfloat.h"
+#include "libavutil/mathematics.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/mpeg4audio.h"
#include "avformat.h"
+#include "internal.h"
#include "avio_internal.h"
#include "flv.h"
@@ -38,6 +41,10 @@
typedef struct {
int wrong_dts; ///< wrong dts due to negative cts
+ uint8_t *new_extradata[2];
+ int new_extradata_size[2];
+ int last_sample_rate;
+ int last_channels;
} FLVContext;
static int flv_probe(AVProbeData *p)
@@ -51,8 +58,7 @@ static int flv_probe(AVProbeData *p)
return 0;
}
-static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, int flv_codecid) {
- AVCodecContext *acodec = astream->codec;
+static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, AVCodecContext *acodec, int flv_codecid) {
switch(flv_codecid) {
//no distinction between S16 and S8 PCM codec flags
case FLV_CODECID_PCM:
@@ -138,6 +144,18 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
int64_t *filepositions = NULL;
int ret = AVERROR(ENOSYS);
int64_t initial_pos = avio_tell(ioc);
+ AVDictionaryEntry *creator = av_dict_get(s->metadata, "metadatacreator",
+ NULL, 0);
+
+ if (creator && !strcmp(creator->value, "MEGA")) {
+ /* Files with this metadatacreator tag seem to have filepositions
+ * pointing at the 4 trailer bytes of the previous packet,
+ * which isn't the norm (nor what we expect here, nor what
+ * jwplayer + lighttpd expect, nor what flvtool2 produces).
+ * Just ignore the index in this case, instead of risking trying
+ * to adjust it to something that might or might not work. */
+ return 0;
+ }
while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
int64_t* current_array;
@@ -174,7 +192,7 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) {
if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER)
goto finish;
- num_val = av_int2dbl(avio_rb64(ioc));
+ num_val = av_int2double(avio_rb64(ioc));
current_array[i] = num_val;
}
if (times && filepositions) {
@@ -185,8 +203,8 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
}
}
- if (timeslen == fileposlen)
- for(i = 0; i < arraylen; i++)
+ if (!ret && timeslen == fileposlen)
+ for (i = 0; i < fileposlen; i++)
av_add_index_entry(vstream, filepositions[i], times[i]*1000, 0, 0, AVINDEX_KEYFRAME);
else
av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n");
@@ -215,7 +233,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
switch(amf_type) {
case AMF_DATA_TYPE_NUMBER:
- num_val = av_int2dbl(avio_rb64(ioc)); break;
+ num_val = av_int2double(avio_rb64(ioc)); break;
case AMF_DATA_TYPE_BOOL:
num_val = avio_r8(ioc); break;
case AMF_DATA_TYPE_STRING:
@@ -225,8 +243,9 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
case AMF_DATA_TYPE_OBJECT: {
unsigned int keylen;
- if (key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
- if (parse_keyframes_index(s, ioc, vstream, max_pos) < 0)
+ if ((vstream || astream) && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
+ if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,
+ max_pos) < 0)
return -1;
while(avio_tell(ioc) < max_pos - 2 && (keylen = avio_rb16(ioc))) {
@@ -273,17 +292,35 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
acodec = astream ? astream->codec : NULL;
vcodec = vstream ? vstream->codec : NULL;
+ if (amf_type == AMF_DATA_TYPE_NUMBER) {
+ if (!strcmp(key, "duration"))
+ s->duration = num_val * AV_TIME_BASE;
+ else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
+ vcodec->bit_rate = num_val * 1024.0;
+ else if (!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
+ acodec->bit_rate = num_val * 1024.0;
+ }
+
+ if (!strcmp(key, "duration") ||
+ !strcmp(key, "filesize") ||
+ !strcmp(key, "width") ||
+ !strcmp(key, "height") ||
+ !strcmp(key, "videodatarate") ||
+ !strcmp(key, "framerate") ||
+ !strcmp(key, "videocodecid") ||
+ !strcmp(key, "audiodatarate") ||
+ !strcmp(key, "audiosamplerate") ||
+ !strcmp(key, "audiosamplesize") ||
+ !strcmp(key, "stereo") ||
+ !strcmp(key, "audiocodecid"))
+ return 0;
+
if(amf_type == AMF_DATA_TYPE_BOOL) {
av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val));
av_dict_set(&s->metadata, key, str_val, 0);
} else if(amf_type == AMF_DATA_TYPE_NUMBER) {
snprintf(str_val, sizeof(str_val), "%.f", num_val);
av_dict_set(&s->metadata, key, str_val, 0);
- if(!strcmp(key, "duration")) s->duration = num_val * AV_TIME_BASE;
- else if(!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
- vcodec->bit_rate = num_val * 1024.0;
- else if(!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
- acodec->bit_rate = num_val * 1024.0;
} else if (amf_type == AMF_DATA_TYPE_STRING)
av_dict_set(&s->metadata, key, str_val, 0);
}
@@ -322,11 +359,12 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
}
static AVStream *create_stream(AVFormatContext *s, int is_audio){
- AVStream *st = av_new_stream(s, is_audio);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return NULL;
+ st->id = is_audio;
st->codec->codec_type = is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO;
- av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
+ avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
return st;
}
@@ -366,6 +404,14 @@ static int flv_read_header(AVFormatContext *s,
return 0;
}
+static int flv_read_close(AVFormatContext *s)
+{
+ FLVContext *flv = s->priv_data;
+ av_freep(&flv->new_extradata[0]);
+ av_freep(&flv->new_extradata[1]);
+ return 0;
+}
+
static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size)
{
av_free(st->codec->extradata);
@@ -377,12 +423,25 @@ static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size)
return 0;
}
+static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream,
+ int size)
+{
+ av_free(flv->new_extradata[stream]);
+ flv->new_extradata[stream] = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!flv->new_extradata[stream])
+ return AVERROR(ENOMEM);
+ flv->new_extradata_size[stream] = size;
+ avio_read(pb, flv->new_extradata[stream], size);
+ return 0;
+}
+
static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
{
FLVContext *flv = s->priv_data;
int ret, i, type, size, flags, is_audio;
int64_t next, pos;
int64_t dts, pts = AV_NOPTS_VALUE;
+ int sample_rate, channels;
AVStream *st = NULL;
for(;;avio_skip(s->pb, 4)){ /* pkt size is repeated at end. skip it */
@@ -467,13 +526,24 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
}
if(is_audio){
+ int bits_per_coded_sample;
+ channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
+ sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);
+ bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) {
- st->codec->channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
- st->codec->sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);
- st->codec->bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
+ st->codec->channels = channels;
+ st->codec->sample_rate = sample_rate;
+ st->codec->bits_per_coded_sample = bits_per_coded_sample;
}
if(!st->codec->codec_id){
- flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK);
+ flv_set_audio_codec(s, st, st->codec, flags & FLV_AUDIO_CODECID_MASK);
+ flv->last_sample_rate = st->codec->sample_rate;
+ flv->last_channels = st->codec->channels;
+ } else {
+ AVCodecContext ctx;
+ ctx.sample_rate = sample_rate;
+ flv_set_audio_codec(s, st, &ctx, flags & FLV_AUDIO_CODECID_MASK);
+ sample_rate = ctx.sample_rate;
}
}else{
size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK);
@@ -494,12 +564,18 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
dts = AV_NOPTS_VALUE;
}
if (type == 0) {
+ if (st->codec->extradata) {
+ if ((ret = flv_queue_extradata(flv, s->pb, is_audio, size)) < 0)
+ return ret;
+ ret = AVERROR(EAGAIN);
+ goto leave;
+ }
if ((ret = flv_get_extradata(s, st, size)) < 0)
return ret;
if (st->codec->codec_id == CODEC_ID_AAC) {
MPEG4AudioConfig cfg;
- ff_mpeg4audio_get_config(&cfg, st->codec->extradata,
- st->codec->extradata_size);
+ avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
+ st->codec->extradata_size * 8, 1);
st->codec->channels = cfg.channels;
if (cfg.ext_sample_rate)
st->codec->sample_rate = cfg.ext_sample_rate;
@@ -530,6 +606,22 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->dts = dts;
pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
pkt->stream_index = st->index;
+ if (flv->new_extradata[is_audio]) {
+ uint8_t *side = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
+ flv->new_extradata_size[is_audio]);
+ if (side) {
+ memcpy(side, flv->new_extradata[is_audio],
+ flv->new_extradata_size[is_audio]);
+ av_freep(&flv->new_extradata[is_audio]);
+ flv->new_extradata_size[is_audio] = 0;
+ }
+ }
+ if (is_audio && (sample_rate != flv->last_sample_rate ||
+ channels != flv->last_channels)) {
+ flv->last_sample_rate = sample_rate;
+ flv->last_channels = channels;
+ ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0);
+ }
if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY))
pkt->flags |= AV_PKT_FLAG_KEY;
@@ -573,16 +665,17 @@ static int flv_read_seek2(AVFormatContext *s, int stream_index,
#endif
AVInputFormat ff_flv_demuxer = {
- "flv",
- NULL_IF_CONFIG_SMALL("FLV format"),
- sizeof(FLVContext),
- flv_probe,
- flv_read_header,
- flv_read_packet,
+ .name = "flv",
+ .long_name = NULL_IF_CONFIG_SMALL("FLV format"),
+ .priv_data_size = sizeof(FLVContext),
+ .read_probe = flv_probe,
+ .read_header = flv_read_header,
+ .read_packet = flv_read_packet,
.read_seek = flv_read_seek,
#if 0
.read_seek2 = flv_read_seek2,
#endif
+ .read_close = flv_read_close,
.extensions = "flv",
.value = CODEC_ID_FLV1,
};
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index bd1a1f4..623bea7 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -18,6 +18,8 @@
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
+#include "libavutil/intfloat.h"
#include "avformat.h"
#include "flv.h"
#include "internal.h"
@@ -55,10 +57,13 @@ typedef struct FLVContext {
int64_t duration_offset;
int64_t filesize_offset;
int64_t duration;
- int delay; ///< first dts delay for AVC
- int64_t last_video_ts;
+ int64_t delay; ///< first dts delay (needed for AVC & Speex)
} FLVContext;
+typedef struct FLVStreamContext {
+ int64_t last_ts; ///< last timestamp for each stream
+} FLVStreamContext;
+
static int get_audio_flags(AVCodecContext *enc){
int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT;
@@ -73,11 +78,6 @@ static int get_audio_flags(AVCodecContext *enc){
av_log(enc, AV_LOG_ERROR, "flv only supports mono Speex audio\n");
return -1;
}
- if (enc->frame_size / 320 > 8) {
- av_log(enc, AV_LOG_WARNING, "Warning: Speex stream has more than "
- "8 frames per packet. Adobe Flash "
- "Player cannot handle this!\n");
- }
return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT;
} else {
switch (enc->sample_rate) {
@@ -90,6 +90,7 @@ static int get_audio_flags(AVCodecContext *enc){
case 11025:
flags |= FLV_SAMPLERATE_11025HZ;
break;
+ case 16000: //nellymoser only
case 8000: //nellymoser only
case 5512: //not mp3
if(enc->codec_id != CODEC_ID_MP3){
@@ -125,6 +126,8 @@ static int get_audio_flags(AVCodecContext *enc){
case CODEC_ID_NELLYMOSER:
if (enc->sample_rate == 8000) {
flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT;
+ } else if (enc->sample_rate == 16000) {
+ flags |= FLV_CODECID_NELLYMOSER_16KHZ_MONO | FLV_SAMPLESSIZE_16BIT;
} else {
flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT;
}
@@ -162,7 +165,7 @@ static void put_avc_eos_tag(AVIOContext *pb, unsigned ts) {
static void put_amf_double(AVIOContext *pb, double d)
{
avio_w8(pb, AMF_DATA_TYPE_NUMBER);
- avio_wb64(pb, av_dbl2int(d));
+ avio_wb64(pb, av_double2int(d));
}
static void put_amf_bool(AVIOContext *pb, int b) {
@@ -175,13 +178,14 @@ static int flv_write_header(AVFormatContext *s)
AVIOContext *pb = s->pb;
FLVContext *flv = s->priv_data;
AVCodecContext *audio_enc = NULL, *video_enc = NULL;
- int i;
+ int i, metadata_count = 0;
double framerate = 0.0;
- int64_t metadata_size_pos, data_size;
+ int64_t metadata_size_pos, data_size, metadata_count_pos;
AVDictionaryEntry *tag = NULL;
for(i=0; i<s->nb_streams; i++){
AVCodecContext *enc = s->streams[i]->codec;
+ FLVStreamContext *sc;
if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) {
framerate = av_q2d(s->streams[i]->r_frame_rate);
@@ -198,8 +202,16 @@ static int flv_write_header(AVFormatContext *s)
if(get_audio_flags(enc)<0)
return -1;
}
- av_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
+ avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
+
+ sc = av_mallocz(sizeof(FLVStreamContext));
+ if (!sc)
+ return AVERROR(ENOMEM);
+ s->streams[i]->priv_data = sc;
+ sc->last_ts = -1;
}
+ flv->delay = AV_NOPTS_VALUE;
+
avio_write(pb, "FLV", 3);
avio_w8(pb,1);
avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc
@@ -218,8 +230,6 @@ static int flv_write_header(AVFormatContext *s)
}
}
- flv->last_video_ts = -1;
-
/* write meta_tag */
avio_w8(pb, 18); // tag type META
metadata_size_pos= avio_tell(pb);
@@ -235,7 +245,9 @@ static int flv_write_header(AVFormatContext *s)
/* mixed array (hash) with size and string/type/data tuples */
avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
- avio_wb32(pb, 5*!!video_enc + 5*!!audio_enc + 2); // +2 for duration and file size
+ metadata_count_pos = avio_tell(pb);
+ metadata_count = 5*!!video_enc + 5*!!audio_enc + 2; // +2 for duration and file size
+ avio_wb32(pb, metadata_count);
put_amf_string(pb, "duration");
flv->duration_offset= avio_tell(pb);
@@ -279,6 +291,7 @@ static int flv_write_header(AVFormatContext *s)
put_amf_string(pb, tag->key);
avio_w8(pb, AMF_DATA_TYPE_STRING);
put_amf_string(pb, tag->value);
+ metadata_count++;
}
put_amf_string(pb, "filesize");
@@ -290,6 +303,10 @@ static int flv_write_header(AVFormatContext *s)
/* write total size of tag */
data_size= avio_tell(pb) - metadata_size_pos - 10;
+
+ avio_seek(pb, metadata_count_pos, SEEK_SET);
+ avio_wb32(pb, metadata_count);
+
avio_seek(pb, metadata_size_pos, SEEK_SET);
avio_wb24(pb, data_size);
avio_skip(pb, data_size + 10 - 3);
@@ -338,15 +355,16 @@ static int flv_write_trailer(AVFormatContext *s)
/* Add EOS tag */
for (i = 0; i < s->nb_streams; i++) {
AVCodecContext *enc = s->streams[i]->codec;
+ FLVStreamContext *sc = s->streams[i]->priv_data;
if (enc->codec_type == AVMEDIA_TYPE_VIDEO &&
enc->codec_id == CODEC_ID_H264) {
- put_avc_eos_tag(pb, flv->last_video_ts);
+ put_avc_eos_tag(pb, sc->last_ts);
}
}
file_size = avio_tell(pb);
- /* update informations */
+ /* update information */
avio_seek(pb, flv->duration_offset, SEEK_SET);
put_amf_double(pb, flv->duration / (double)1000);
avio_seek(pb, flv->filesize_offset, SEEK_SET);
@@ -361,6 +379,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
AVIOContext *pb = s->pb;
AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
FLVContext *flv = s->priv_data;
+ FLVStreamContext *sc = s->streams[pkt->stream_index]->priv_data;
unsigned ts;
int size= pkt->size;
uint8_t *data= NULL;
@@ -396,20 +415,32 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
}
if (enc->codec_id == CODEC_ID_H264) {
- /* check if extradata looks like mp4 formated */
+ /* check if extradata looks like MP4 */
if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) {
if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0)
return -1;
}
- if (!flv->delay && pkt->dts < 0)
- flv->delay = -pkt->dts;
+ }
+ if (flv->delay == AV_NOPTS_VALUE)
+ flv->delay = -pkt->dts;
+ if (pkt->dts < -flv->delay) {
+ av_log(s, AV_LOG_WARNING, "Packets are not in the proper order with "
+ "respect to DTS\n");
+ return AVERROR(EINVAL);
}
ts = pkt->dts + flv->delay; // add delay to force positive dts
- if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (flv->last_video_ts < ts)
- flv->last_video_ts = ts;
+
+ /* check Speex packet duration */
+ if (enc->codec_id == CODEC_ID_SPEEX && ts - sc->last_ts > 160) {
+ av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than "
+ "8 frames per packet. Adobe Flash "
+ "Player cannot handle this!\n");
}
+
+ if (sc->last_ts < ts)
+ sc->last_ts = ts;
+
avio_wb24(pb,size + flags_size);
avio_wb24(pb,ts);
avio_w8(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_
@@ -439,20 +470,20 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_flv_muxer = {
- "flv",
- NULL_IF_CONFIG_SMALL("FLV format"),
- "video/x-flv",
- "flv",
- sizeof(FLVContext),
+ .name = "flv",
+ .long_name = NULL_IF_CONFIG_SMALL("FLV format"),
+ .mime_type = "video/x-flv",
+ .extensions = "flv",
+ .priv_data_size = sizeof(FLVContext),
#if CONFIG_LIBMP3LAME
- CODEC_ID_MP3,
+ .audio_codec = CODEC_ID_MP3,
#else // CONFIG_LIBMP3LAME
- CODEC_ID_ADPCM_SWF,
+ .audio_codec = CODEC_ID_ADPCM_SWF,
#endif // CONFIG_LIBMP3LAME
- CODEC_ID_FLV1,
- flv_write_header,
- flv_write_packet,
- flv_write_trailer,
+ .video_codec = CODEC_ID_FLV1,
+ .write_header = flv_write_header,
+ .write_packet = flv_write_packet,
+ .write_trailer = flv_write_trailer,
.codec_tag= (const AVCodecTag* const []){flv_video_codec_ids, flv_audio_codec_ids, 0},
.flags= AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
};
diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c
index 2bd3f54..d845e79 100644
--- a/libavformat/framecrcenc.c
+++ b/libavformat/framecrcenc.c
@@ -34,14 +34,11 @@ static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_framecrc_muxer = {
- "framecrc",
- NULL_IF_CONFIG_SMALL("framecrc testing format"),
- NULL,
- "",
- 0,
- CODEC_ID_PCM_S16LE,
- CODEC_ID_RAWVIDEO,
- NULL,
- framecrc_write_packet,
- NULL,
+ .name = "framecrc",
+ .long_name = NULL_IF_CONFIG_SMALL("framecrc testing format"),
+ .extensions = "",
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_packet = framecrc_write_packet,
+ .flags = AVFMT_VARIABLE_FPS,
};
diff --git a/libavformat/gif.c b/libavformat/gif.c
index 55deb4d..3ef7ebe 100644
--- a/libavformat/gif.c
+++ b/libavformat/gif.c
@@ -40,6 +40,8 @@
*/
#include "avformat.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
/* The GIF format uses reversed order for bitstreams... */
/* at least they don't use PDP_ENDIAN :) */
@@ -245,8 +247,10 @@ static int gif_image_write_image(AVIOContext *pb,
}
typedef struct {
+ AVClass *class; /** Class for private options. */
int64_t time, file_time;
uint8_t buffer[100]; /* data chunks */
+ int loop;
} GIFContext;
static int gif_write_header(AVFormatContext *s)
@@ -254,7 +258,7 @@ static int gif_write_header(AVFormatContext *s)
GIFContext *gif = s->priv_data;
AVIOContext *pb = s->pb;
AVCodecContext *enc, *video_enc;
- int i, width, height, loop_count /*, rate*/;
+ int i, width, height /*, rate*/;
/* XXX: do we reject audio streams or just ignore them ?
if(s->nb_streams > 1)
@@ -276,7 +280,6 @@ static int gif_write_header(AVFormatContext *s)
} else {
width = video_enc->width;
height = video_enc->height;
- loop_count = s->loop_output;
// rate = video_enc->time_base.den;
}
@@ -285,7 +288,12 @@ static int gif_write_header(AVFormatContext *s)
return AVERROR(EIO);
}
- gif_image_write_header(pb, width, height, loop_count, NULL);
+#if FF_API_LOOP_OUTPUT
+ if (s->loop_output)
+ gif->loop = s->loop_output;
+#endif
+
+ gif_image_write_header(pb, width, height, gif->loop, NULL);
avio_flush(s->pb);
return 0;
@@ -340,15 +348,30 @@ static int gif_write_trailer(AVFormatContext *s)
return 0;
}
+#define OFFSET(x) offsetof(GIFContext, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "loop", "Number of times to loop the output.", OFFSET(loop), AV_OPT_TYPE_INT, {0}, 0, 65535, ENC },
+ { NULL },
+};
+
+static const AVClass gif_muxer_class = {
+ .class_name = "GIF muxer",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = options,
+};
+
AVOutputFormat ff_gif_muxer = {
- "gif",
- NULL_IF_CONFIG_SMALL("GIF Animation"),
- "image/gif",
- "gif",
- sizeof(GIFContext),
- CODEC_ID_NONE,
- CODEC_ID_RAWVIDEO,
- gif_write_header,
- gif_write_packet,
- gif_write_trailer,
+ .name = "gif",
+ .long_name = NULL_IF_CONFIG_SMALL("GIF Animation"),
+ .mime_type = "image/gif",
+ .extensions = "gif",
+ .priv_data_size = sizeof(GIFContext),
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_header = gif_write_header,
+ .write_packet = gif_write_packet,
+ .write_trailer = gif_write_trailer,
+ .priv_class = &gif_muxer_class,
};
diff --git a/libavformat/gopher.c b/libavformat/gopher.c
index 79d1feb..c033861 100644
--- a/libavformat/gopher.c
+++ b/libavformat/gopher.c
@@ -72,24 +72,17 @@ static int gopher_close(URLContext *h)
ffurl_close(s->hd);
s->hd = NULL;
}
- av_freep(&h->priv_data);
return 0;
}
static int gopher_open(URLContext *h, const char *uri, int flags)
{
- GopherContext *s;
+ GopherContext *s = h->priv_data;
char hostname[1024], auth[1024], path[1024], buf[1024];
int port, err;
h->is_streamed = 1;
- s = av_malloc(sizeof(GopherContext));
- if (!s) {
- return AVERROR(ENOMEM);
- }
- h->priv_data = s;
-
/* needed in any case to build the host string */
av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
path, sizeof(path), uri);
@@ -100,7 +93,8 @@ static int gopher_open(URLContext *h, const char *uri, int flags)
ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
s->hd = NULL;
- err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE);
+ err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE,
+ &h->interrupt_callback, NULL);
if (err < 0)
goto fail;
@@ -121,9 +115,10 @@ static int gopher_read(URLContext *h, uint8_t *buf, int size)
URLProtocol ff_gopher_protocol = {
- .name = "gopher",
- .url_open = gopher_open,
- .url_read = gopher_read,
- .url_write = gopher_write,
- .url_close = gopher_close,
+ .name = "gopher",
+ .url_open = gopher_open,
+ .url_read = gopher_read,
+ .url_write = gopher_write,
+ .url_close = gopher_close,
+ .priv_data_size = sizeof(GopherContext),
};
diff --git a/libavformat/gsmdec.c b/libavformat/gsmdec.c
new file mode 100644
index 0000000..2360887
--- /dev/null
+++ b/libavformat/gsmdec.c
@@ -0,0 +1,133 @@
+/*
+ * RAW GSM demuxer
+ * Copyright (c) 2011 Justin Ruggles
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+#include "internal.h"
+
+#define GSM_BLOCK_SIZE 33
+#define GSM_BLOCK_SAMPLES 160
+#define GSM_SAMPLE_RATE 8000
+
+typedef struct {
+ AVClass *class;
+ int sample_rate;
+} GSMDemuxerContext;
+
+static int gsm_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ int ret, size;
+
+ size = GSM_BLOCK_SIZE * 32;
+
+ pkt->pos = avio_tell(s->pb);
+ pkt->stream_index = 0;
+
+ ret = av_get_packet(s->pb, pkt, size);
+ if (ret < GSM_BLOCK_SIZE) {
+ av_free_packet(pkt);
+ return ret < 0 ? ret : AVERROR(EIO);
+ }
+ pkt->size = ret;
+ pkt->duration = ret / GSM_BLOCK_SIZE;
+ pkt->pts = pkt->pos / GSM_BLOCK_SIZE;
+
+ return 0;
+}
+
+static int gsm_read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ GSMDemuxerContext *c = s->priv_data;
+ AVStream *st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = s->iformat->value;
+ st->codec->channels = 1;
+ st->codec->sample_rate = c->sample_rate;
+ st->codec->block_align = GSM_BLOCK_SIZE;
+ st->codec->bit_rate = GSM_BLOCK_SIZE * 8 * c->sample_rate / GSM_BLOCK_SAMPLES;
+
+ avpriv_set_pts_info(st, 64, GSM_BLOCK_SAMPLES, GSM_SAMPLE_RATE);
+
+ return 0;
+}
+
+static int gsm_read_seek2(AVFormatContext *s, int stream_index, int64_t min_ts,
+ int64_t ts, int64_t max_ts, int flags)
+{
+ GSMDemuxerContext *c = s->priv_data;
+
+ /* convert timestamps to file positions */
+ if (!(flags & AVSEEK_FLAG_BYTE)) {
+ if (stream_index < 0) {
+ AVRational bitrate_q = { GSM_BLOCK_SAMPLES, c->sample_rate * GSM_BLOCK_SIZE };
+ ts = av_rescale_q(ts, AV_TIME_BASE_Q, bitrate_q);
+ min_ts = av_rescale_q(min_ts, AV_TIME_BASE_Q, bitrate_q);
+ max_ts = av_rescale_q(max_ts, AV_TIME_BASE_Q, bitrate_q);
+ } else {
+ ts *= GSM_BLOCK_SIZE;
+ min_ts *= GSM_BLOCK_SIZE;
+ max_ts *= GSM_BLOCK_SIZE;
+ }
+ }
+ /* round to nearest block boundary */
+ ts = (ts + GSM_BLOCK_SIZE / 2) / GSM_BLOCK_SIZE * GSM_BLOCK_SIZE;
+ ts = FFMAX(0, ts);
+
+ /* handle min/max */
+ while (ts < min_ts)
+ ts += GSM_BLOCK_SIZE;
+ while (ts > max_ts)
+ ts -= GSM_BLOCK_SIZE;
+ if (ts < min_ts || ts > max_ts)
+ return -1;
+
+ return avio_seek(s->pb, ts, SEEK_SET);
+}
+
+static const AVOption options[] = {
+ { "sample_rate", "", offsetof(GSMDemuxerContext, sample_rate),
+ AV_OPT_TYPE_INT, {.dbl = GSM_SAMPLE_RATE}, 1, INT_MAX / GSM_BLOCK_SIZE,
+ AV_OPT_FLAG_DECODING_PARAM },
+ { NULL },
+};
+
+static const AVClass class = {
+ .class_name = "gsm demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_gsm_demuxer = {
+ .name = "gsm",
+ .long_name = NULL_IF_CONFIG_SMALL("raw GSM"),
+ .priv_data_size = sizeof(GSMDemuxerContext),
+ .read_header = gsm_read_header,
+ .read_packet = gsm_read_packet,
+ .read_seek2 = gsm_read_seek2,
+ .extensions = "gsm",
+ .value = CODEC_ID_GSM,
+ .priv_class = &class,
+};
diff --git a/libavformat/gxf.c b/libavformat/gxf.c
index d77fd18..ebc4eea 100644
--- a/libavformat/gxf.c
+++ b/libavformat/gxf.c
@@ -32,11 +32,11 @@ struct gxf_stream_info {
};
/**
- * \brief parses a packet header, extracting type and length
- * \param pb AVIOContext to read header from
- * \param type detected packet type is stored here
- * \param length detected packet length, excluding header is stored here
- * \return 0 if header not found or contains invalid data, 1 otherwise
+ * @brief parses a packet header, extracting type and length
+ * @param pb AVIOContext to read header from
+ * @param type detected packet type is stored here
+ * @param length detected packet length, excluding header is stored here
+ * @return 0 if header not found or contains invalid data, 1 otherwise
*/
static int parse_packet_header(AVIOContext *pb, GXFPktType *type, int *length) {
if (avio_rb32(pb))
@@ -58,7 +58,7 @@ static int parse_packet_header(AVIOContext *pb, GXFPktType *type, int *length) {
}
/**
- * \brief check if file starts with a PKT_MAP header
+ * @brief check if file starts with a PKT_MAP header
*/
static int gxf_probe(AVProbeData *p) {
static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet
@@ -70,10 +70,10 @@ static int gxf_probe(AVProbeData *p) {
}
/**
- * \brief gets the stream index for the track with the specified id, creates new
+ * @brief gets the stream index for the track with the specified id, creates new
* stream if not found
- * \param id id of stream to find / add
- * \param format stream format identifier
+ * @param id id of stream to find / add
+ * @param format stream format identifier
*/
static int get_sindex(AVFormatContext *s, int id, int format) {
int i;
@@ -81,9 +81,10 @@ static int get_sindex(AVFormatContext *s, int id, int format) {
i = ff_find_stream_index(s, id);
if (i >= 0)
return i;
- st = av_new_stream(s, id);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
+ st->id = id;
switch (format) {
case 3:
case 4:
@@ -153,9 +154,9 @@ static int get_sindex(AVFormatContext *s, int id, int format) {
}
/**
- * \brief filters out interesting tags from material information.
- * \param len length of tag section, will be adjusted to contain remaining bytes
- * \param si struct to store collected information into
+ * @brief filters out interesting tags from material information.
+ * @param len length of tag section, will be adjusted to contain remaining bytes
+ * @param si struct to store collected information into
*/
static void gxf_material_tags(AVIOContext *pb, int *len, struct gxf_stream_info *si) {
si->first_field = AV_NOPTS_VALUE;
@@ -179,20 +180,20 @@ static void gxf_material_tags(AVIOContext *pb, int *len, struct gxf_stream_info
}
/**
- * \brief convert fps tag value to AVRational fps
- * \param fps fps value from tag
- * \return fps as AVRational, or 0 / 0 if unknown
+ * @brief convert fps tag value to AVRational fps
+ * @param fps fps value from tag
+ * @return fps as AVRational, or 0 / 0 if unknown
*/
static AVRational fps_tag2avr(int32_t fps) {
- extern const AVRational ff_frame_rate_tab[];
+ extern const AVRational avpriv_frame_rate_tab[];
if (fps < 1 || fps > 9) fps = 9;
- return ff_frame_rate_tab[9 - fps]; // values have opposite order
+ return avpriv_frame_rate_tab[9 - fps]; // values have opposite order
}
/**
- * \brief convert UMF attributes flags to AVRational fps
- * \param flags UMF flags to convert
- * \return fps as AVRational, or 0 / 0 if unknown
+ * @brief convert UMF attributes flags to AVRational fps
+ * @param flags UMF flags to convert
+ * @return fps as AVRational, or 0 / 0 if unknown
*/
static AVRational fps_umf2avr(uint32_t flags) {
static const AVRational map[] = {{50, 1}, {60000, 1001}, {24, 1},
@@ -202,9 +203,9 @@ static AVRational fps_umf2avr(uint32_t flags) {
}
/**
- * \brief filters out interesting tags from track information.
- * \param len length of tag section, will be adjusted to contain remaining bytes
- * \param si struct to store collected information into
+ * @brief filters out interesting tags from track information.
+ * @param len length of tag section, will be adjusted to contain remaining bytes
+ * @param si struct to store collected information into
*/
static void gxf_track_tags(AVIOContext *pb, int *len, struct gxf_stream_info *si) {
si->frames_per_second = (AVRational){0, 0};
@@ -228,7 +229,7 @@ static void gxf_track_tags(AVIOContext *pb, int *len, struct gxf_stream_info *si
}
/**
- * \brief read index from FLT packet into stream 0 av_index
+ * @brief read index from FLT packet into stream 0 av_index
*/
static void gxf_read_index(AVFormatContext *s, int pkt_len) {
AVIOContext *pb = s->pb;
@@ -361,7 +362,7 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
main_timebase = (AVRational){1001, 60000};
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- av_set_pts_info(st, 32, main_timebase.num, main_timebase.den);
+ avpriv_set_pts_info(st, 32, main_timebase.num, main_timebase.den);
}
return 0;
}
@@ -374,11 +375,11 @@ static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
}
/**
- * \brief resync the stream on the next media packet with specified properties
- * \param max_interval how many bytes to search for matching packet at most
- * \param track track id the media packet must belong to, -1 for any
- * \param timestamp minimum timestamp (== field number) the packet must have, -1 for any
- * \return timestamp of packet found
+ * @brief resync the stream on the next media packet with specified properties
+ * @param max_interval how many bytes to search for matching packet at most
+ * @param track track id the media packet must belong to, -1 for any
+ * @param timestamp minimum timestamp (== field number) the packet must have, -1 for any
+ * @return timestamp of packet found
*/
static int64_t gxf_resync_media(AVFormatContext *s, uint64_t max_interval, int track, int timestamp) {
uint32_t tmp;
@@ -523,13 +524,12 @@ static int64_t gxf_read_timestamp(AVFormatContext *s, int stream_index,
}
AVInputFormat ff_gxf_demuxer = {
- "gxf",
- NULL_IF_CONFIG_SMALL("GXF format"),
- sizeof(struct gxf_stream_info),
- gxf_probe,
- gxf_header,
- gxf_packet,
- NULL,
- gxf_seek,
- gxf_read_timestamp,
+ .name = "gxf",
+ .long_name = NULL_IF_CONFIG_SMALL("GXF format"),
+ .priv_data_size = sizeof(struct gxf_stream_info),
+ .read_probe = gxf_probe,
+ .read_header = gxf_header,
+ .read_packet = gxf_packet,
+ .read_seek = gxf_seek,
+ .read_timestamp = gxf_read_timestamp,
};
diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c
index 98126fa..124064f 100644
--- a/libavformat/gxfenc.c
+++ b/libavformat/gxfenc.c
@@ -19,7 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/intfloat.h"
+#include "libavutil/mathematics.h"
#include "avformat.h"
+#include "internal.h"
#include "gxf.h"
#include "riff.h"
#include "audiointerleave.h"
@@ -392,9 +395,20 @@ static int gxf_write_umf_material_description(AVFormatContext *s)
GXFContext *gxf = s->priv_data;
AVIOContext *pb = s->pb;
int timecode_base = gxf->time_base.den == 60000 ? 60 : 50;
+ int64_t timestamp = 0;
+ AVDictionaryEntry *t;
+ uint32_t timecode;
+
+#if FF_API_TIMESTAMP
+ if (s->timestamp)
+ timestamp = s->timestamp;
+ else
+#endif
+ if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+ timestamp = ff_iso8601_to_unix_time(t->value);
// XXX drop frame
- uint32_t timecode =
+ timecode =
gxf->nb_fields / (timecode_base * 3600) % 24 << 24 | // hours
gxf->nb_fields / (timecode_base * 60) % 60 << 16 | // minutes
gxf->nb_fields / timecode_base % 60 << 8 | // seconds
@@ -407,8 +421,8 @@ static int gxf_write_umf_material_description(AVFormatContext *s)
avio_wl32(pb, gxf->nb_fields); /* mark out */
avio_wl32(pb, 0); /* timecode mark in */
avio_wl32(pb, timecode); /* timecode mark out */
- avio_wl64(pb, s->timestamp); /* modification time */
- avio_wl64(pb, s->timestamp); /* creation time */
+ avio_wl64(pb, timestamp); /* modification time */
+ avio_wl64(pb, timestamp); /* creation time */
avio_wl16(pb, 0); /* reserved */
avio_wl16(pb, 0); /* reserved */
avio_wl16(pb, gxf->audio_tracks);
@@ -506,8 +520,8 @@ static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc)
static int gxf_write_umf_media_audio(AVIOContext *pb, GXFStreamContext *sc)
{
- avio_wl64(pb, av_dbl2int(1)); /* sound level to begin to */
- avio_wl64(pb, av_dbl2int(1)); /* sound level to begin to */
+ avio_wl64(pb, av_double2int(1)); /* sound level to begin to */
+ avio_wl64(pb, av_double2int(1)); /* sound level to begin to */
avio_wl32(pb, 0); /* number of fields over which to ramp up sound level */
avio_wl32(pb, 0); /* number of fields over which to ramp down sound level */
avio_wl32(pb, 0); /* reserved */
@@ -663,7 +677,7 @@ static int gxf_write_header(AVFormatContext *s)
}
sc->track_type = 2;
sc->sample_rate = st->codec->sample_rate;
- av_set_pts_info(st, 64, 1, sc->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, sc->sample_rate);
sc->sample_size = 16;
sc->frame_rate_index = -2;
sc->lines_index = -2;
@@ -693,7 +707,7 @@ static int gxf_write_header(AVFormatContext *s)
"gxf muxer only accepts PAL or NTSC resolutions currently\n");
return -1;
}
- av_set_pts_info(st, 64, gxf->time_base.num, gxf->time_base.den);
+ avpriv_set_pts_info(st, 64, gxf->time_base.num, gxf->time_base.den);
if (gxf_find_lines_index(st) < 0)
sc->lines_index = -1;
sc->sample_size = st->codec->bit_rate;
@@ -931,17 +945,14 @@ static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pk
}
AVOutputFormat ff_gxf_muxer = {
- "gxf",
- NULL_IF_CONFIG_SMALL("GXF format"),
- NULL,
- "gxf",
- sizeof(GXFContext),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_MPEG2VIDEO,
- gxf_write_header,
- gxf_write_packet,
- gxf_write_trailer,
- 0,
- NULL,
- gxf_interleave_packet,
+ .name = "gxf",
+ .long_name = NULL_IF_CONFIG_SMALL("GXF format"),
+ .extensions = "gxf",
+ .priv_data_size = sizeof(GXFContext),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = gxf_write_header,
+ .write_packet = gxf_write_packet,
+ .write_trailer = gxf_write_trailer,
+ .interleave_packet = gxf_interleave_packet,
};
diff --git a/libavformat/http.c b/libavformat/http.c
index aa8c665..7badf72 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1,5 +1,5 @@
/*
- * HTTP protocol for ffmpeg client
+ * HTTP protocol for avconv client
* Copyright (c) 2000, 2001 Fabrice Bellard
*
* This file is part of Libav.
@@ -22,7 +22,6 @@
#include "libavutil/avstring.h"
#include "avformat.h"
#include <unistd.h>
-#include <strings.h>
#include "internal.h"
#include "network.h"
#include "http.h"
@@ -31,7 +30,7 @@
#include "url.h"
#include "libavutil/opt.h"
-/* XXX: POST protocol is not completely implemented because ffmpeg uses
+/* XXX: POST protocol is not completely implemented because avconv uses
only a subset of it. */
/* used for protocol handling */
@@ -48,57 +47,54 @@ typedef struct {
int64_t off, filesize;
char location[MAX_URL_SIZE];
HTTPAuthState auth_state;
- unsigned char headers[BUFFER_SIZE];
+ HTTPAuthState proxy_auth_state;
+ char *headers;
int willclose; /**< Set if the server correctly handles Connection: close and will close the connection after feeding us the content. */
+ int chunked_post;
} HTTPContext;
#define OFFSET(x) offsetof(HTTPContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
-{"chunksize", "use chunked transfer-encoding for posts, -1 disables it, 0 enables it", OFFSET(chunksize), FF_OPT_TYPE_INT64, {.dbl = 0}, -1, 0 }, /* Default to 0, for chunked POSTs */
+{"chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, {.dbl = 1}, 0, 1, E },
+{"headers", "custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
{NULL}
};
-static const AVClass httpcontext_class = {
- .class_name = "HTTP",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-static int http_connect(URLContext *h, const char *path, const char *hoststr,
- const char *auth, int *new_location);
-
-void ff_http_set_headers(URLContext *h, const char *headers)
-{
- HTTPContext *s = h->priv_data;
- int len = strlen(headers);
-
- if (len && strcmp("\r\n", headers + len - 2))
- av_log(h, AV_LOG_ERROR, "No trailing CRLF found in HTTP header.\n");
-
- av_strlcpy(s->headers, headers, sizeof(s->headers));
+#define HTTP_CLASS(flavor)\
+static const AVClass flavor ## _context_class = {\
+ .class_name = #flavor,\
+ .item_name = av_default_item_name,\
+ .option = options,\
+ .version = LIBAVUTIL_VERSION_INT,\
}
-void ff_http_set_chunked_transfer_encoding(URLContext *h, int is_chunked)
-{
- ((HTTPContext*)h->priv_data)->chunksize = is_chunked ? 0 : -1;
-}
+HTTP_CLASS(http);
+HTTP_CLASS(https);
+
+static int http_connect(URLContext *h, const char *path, const char *local_path,
+ const char *hoststr, const char *auth,
+ const char *proxyauth, int *new_location);
void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
{
memcpy(&((HTTPContext*)dest->priv_data)->auth_state,
&((HTTPContext*)src->priv_data)->auth_state, sizeof(HTTPAuthState));
+ memcpy(&((HTTPContext*)dest->priv_data)->proxy_auth_state,
+ &((HTTPContext*)src->priv_data)->proxy_auth_state,
+ sizeof(HTTPAuthState));
}
/* return non zero if error */
static int http_open_cnx(URLContext *h)
{
- const char *path, *proxy_path;
- char hostname[1024], hoststr[1024];
- char auth[1024];
+ const char *path, *proxy_path, *lower_proto = "tcp", *local_path;
+ char hostname[1024], hoststr[1024], proto[10];
+ char auth[1024], proxyauth[1024] = "";
char path1[1024];
- char buf[1024];
+ char buf[1024], urlbuf[1024];
int port, use_proxy, err, location_changed = 0, redirects = 0;
- HTTPAuthType cur_auth_type;
+ HTTPAuthType cur_auth_type, cur_proxy_auth_type;
HTTPContext *s = h->priv_data;
URLContext *hd = NULL;
@@ -109,31 +105,45 @@ static int http_open_cnx(URLContext *h)
/* fill the dest addr */
redo:
/* needed in any case to build the host string */
- av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
+ av_url_split(proto, sizeof(proto), auth, sizeof(auth),
+ hostname, sizeof(hostname), &port,
path1, sizeof(path1), s->location);
ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
- if (use_proxy) {
- av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
- NULL, 0, proxy_path);
- path = s->location;
- } else {
- if (path1[0] == '\0')
- path = "/";
- else
- path = path1;
+ if (!strcmp(proto, "https")) {
+ lower_proto = "tls";
+ use_proxy = 0;
+ if (port < 0)
+ port = 443;
}
if (port < 0)
port = 80;
- ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
- err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE);
+ if (path1[0] == '\0')
+ path = "/";
+ else
+ path = path1;
+ local_path = path;
+ if (use_proxy) {
+ /* Reassemble the request URL without auth string - we don't
+ * want to leak the auth to the proxy. */
+ ff_url_join(urlbuf, sizeof(urlbuf), proto, NULL, hostname, port, "%s",
+ path1);
+ path = urlbuf;
+ av_url_split(NULL, 0, proxyauth, sizeof(proxyauth),
+ hostname, sizeof(hostname), &port, NULL, 0, proxy_path);
+ }
+
+ ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL);
+ err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE,
+ &h->interrupt_callback, NULL);
if (err < 0)
goto fail;
s->hd = hd;
cur_auth_type = s->auth_state.auth_type;
- if (http_connect(h, path, hoststr, auth, &location_changed) < 0)
+ cur_proxy_auth_type = s->auth_state.auth_type;
+ if (http_connect(h, path, local_path, hoststr, auth, proxyauth, &location_changed) < 0)
goto fail;
if (s->http_code == 401) {
if (cur_auth_type == HTTP_AUTH_NONE && s->auth_state.auth_type != HTTP_AUTH_NONE) {
@@ -142,6 +152,14 @@ static int http_open_cnx(URLContext *h)
} else
goto fail;
}
+ if (s->http_code == 407) {
+ if (cur_proxy_auth_type == HTTP_AUTH_NONE &&
+ s->proxy_auth_state.auth_type != HTTP_AUTH_NONE) {
+ ffurl_close(hd);
+ goto redo;
+ } else
+ goto fail;
+ }
if ((s->http_code == 301 || s->http_code == 302 || s->http_code == 303 || s->http_code == 307)
&& location_changed == 1) {
/* url moved, get next */
@@ -168,6 +186,12 @@ static int http_open(URLContext *h, const char *uri, int flags)
s->filesize = -1;
av_strlcpy(s->location, uri, sizeof(s->location));
+ if (s->headers) {
+ int len = strlen(s->headers);
+ if (len < 2 || strcmp("\r\n", s->headers + len - 2))
+ av_log(h, AV_LOG_WARNING, "No trailing CRLF found in HTTP header.\n");
+ }
+
return http_open_cnx(h);
}
static int http_getc(HTTPContext *s)
@@ -233,7 +257,9 @@ static int process_line(URLContext *h, char *line, int line_count,
/* error codes are 4xx and 5xx, but regard 401 as a success, so we
* don't abort until all headers have been parsed. */
- if (s->http_code >= 400 && s->http_code < 600 && s->http_code != 401) {
+ if (s->http_code >= 400 && s->http_code < 600 && (s->http_code != 401
+ || s->auth_state.auth_type != HTTP_AUTH_NONE) &&
+ (s->http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) {
end += strspn(end, SPACE_CHARS);
av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n",
s->http_code, end);
@@ -250,12 +276,12 @@ static int process_line(URLContext *h, char *line, int line_count,
p++;
while (isspace(*p))
p++;
- if (!strcasecmp(tag, "Location")) {
+ if (!av_strcasecmp(tag, "Location")) {
strcpy(s->location, p);
*new_location = 1;
- } else if (!strcasecmp (tag, "Content-Length") && s->filesize == -1) {
+ } else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {
s->filesize = atoll(p);
- } else if (!strcasecmp (tag, "Content-Range")) {
+ } else if (!av_strcasecmp (tag, "Content-Range")) {
/* "bytes $from-$to/$document_size" */
const char *slash;
if (!strncmp (p, "bytes ", 6)) {
@@ -265,14 +291,18 @@ static int process_line(URLContext *h, char *line, int line_count,
s->filesize = atoll(slash+1);
}
h->is_streamed = 0; /* we _can_ in fact seek */
- } else if (!strcasecmp (tag, "Transfer-Encoding") && !strncasecmp(p, "chunked", 7)) {
+ } else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) {
+ h->is_streamed = 0;
+ } else if (!av_strcasecmp (tag, "Transfer-Encoding") && !av_strncasecmp(p, "chunked", 7)) {
s->filesize = -1;
s->chunksize = 0;
- } else if (!strcasecmp (tag, "WWW-Authenticate")) {
+ } else if (!av_strcasecmp (tag, "WWW-Authenticate")) {
ff_http_auth_handle_header(&s->auth_state, tag, p);
- } else if (!strcasecmp (tag, "Authentication-Info")) {
+ } else if (!av_strcasecmp (tag, "Authentication-Info")) {
ff_http_auth_handle_header(&s->auth_state, tag, p);
- } else if (!strcasecmp (tag, "Connection")) {
+ } else if (!av_strcasecmp (tag, "Proxy-Authenticate")) {
+ ff_http_auth_handle_header(&s->proxy_auth_state, tag, p);
+ } else if (!av_strcasecmp (tag, "Connection")) {
if (!strcmp(p, "close"))
s->willclose = 1;
}
@@ -283,25 +313,32 @@ static int process_line(URLContext *h, char *line, int line_count,
static inline int has_header(const char *str, const char *header)
{
/* header + 2 to skip over CRLF prefix. (make sure you have one!) */
+ if (!str)
+ return 0;
return av_stristart(str, header + 2, NULL) || av_stristr(str, header);
}
-static int http_connect(URLContext *h, const char *path, const char *hoststr,
- const char *auth, int *new_location)
+static int http_connect(URLContext *h, const char *path, const char *local_path,
+ const char *hoststr, const char *auth,
+ const char *proxyauth, int *new_location)
{
HTTPContext *s = h->priv_data;
int post, err;
char line[1024];
char headers[1024] = "";
- char *authstr = NULL;
+ char *authstr = NULL, *proxyauthstr = NULL;
int64_t off = s->off;
int len = 0;
+ const char *method;
/* send http header */
post = h->flags & AVIO_FLAG_WRITE;
- authstr = ff_http_auth_create_response(&s->auth_state, auth, path,
- post ? "POST" : "GET");
+ method = post ? "POST" : "GET";
+ authstr = ff_http_auth_create_response(&s->auth_state, auth, local_path,
+ method);
+ proxyauthstr = ff_http_auth_create_response(&s->proxy_auth_state, proxyauth,
+ local_path, method);
/* set default headers if needed */
if (!has_header(s->headers, "\r\nUser-Agent: "))
@@ -310,7 +347,7 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
if (!has_header(s->headers, "\r\nAccept: "))
len += av_strlcpy(headers + len, "Accept: */*\r\n",
sizeof(headers) - len);
- if (!has_header(s->headers, "\r\nRange: "))
+ if (!has_header(s->headers, "\r\nRange: ") && !post)
len += av_strlcatf(headers + len, sizeof(headers) - len,
"Range: bytes=%"PRId64"-\r\n", s->off);
if (!has_header(s->headers, "\r\nConnection: "))
@@ -321,21 +358,25 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
"Host: %s\r\n", hoststr);
/* now add in custom headers */
- av_strlcpy(headers+len, s->headers, sizeof(headers)-len);
+ if (s->headers)
+ av_strlcpy(headers + len, s->headers, sizeof(headers) - len);
snprintf(s->buffer, sizeof(s->buffer),
"%s %s HTTP/1.1\r\n"
"%s"
"%s"
"%s"
+ "%s%s"
"\r\n",
- post ? "POST" : "GET",
+ method,
path,
- post && s->chunksize >= 0 ? "Transfer-Encoding: chunked\r\n" : "",
+ post && s->chunked_post ? "Transfer-Encoding: chunked\r\n" : "",
headers,
- authstr ? authstr : "");
+ authstr ? authstr : "",
+ proxyauthstr ? "Proxy-" : "", proxyauthstr ? proxyauthstr : "");
av_freep(&authstr);
+ av_freep(&proxyauthstr);
if (ffurl_write(s->hd, s->buffer, strlen(s->buffer)) < 0)
return AVERROR(EIO);
@@ -374,10 +415,33 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr,
}
-static int http_read(URLContext *h, uint8_t *buf, int size)
+static int http_buf_read(URLContext *h, uint8_t *buf, int size)
{
HTTPContext *s = h->priv_data;
int len;
+ /* read bytes from input buffer first */
+ len = s->buf_end - s->buf_ptr;
+ if (len > 0) {
+ if (len > size)
+ len = size;
+ memcpy(buf, s->buf_ptr, len);
+ s->buf_ptr += len;
+ } else {
+ if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize)
+ return AVERROR_EOF;
+ len = ffurl_read(s->hd, buf, size);
+ }
+ if (len > 0) {
+ s->off += len;
+ if (s->chunksize > 0)
+ s->chunksize -= len;
+ }
+ return len;
+}
+
+static int http_read(URLContext *h, uint8_t *buf, int size)
+{
+ HTTPContext *s = h->priv_data;
if (s->chunksize >= 0) {
if (!s->chunksize) {
@@ -400,24 +464,7 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
}
size = FFMIN(size, s->chunksize);
}
- /* read bytes from input buffer first */
- len = s->buf_end - s->buf_ptr;
- if (len > 0) {
- if (len > size)
- len = size;
- memcpy(buf, s->buf_ptr, len);
- s->buf_ptr += len;
- } else {
- if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize)
- return AVERROR_EOF;
- len = ffurl_read(s->hd, buf, size);
- }
- if (len > 0) {
- s->off += len;
- if (s->chunksize > 0)
- s->chunksize -= len;
- }
- return len;
+ return http_buf_read(h, buf, size);
}
/* used only when posting data */
@@ -428,7 +475,7 @@ static int http_write(URLContext *h, const uint8_t *buf, int size)
char crlf[] = "\r\n";
HTTPContext *s = h->priv_data;
- if (s->chunksize == -1) {
+ if (!s->chunked_post) {
/* non-chunked data is sent without any special encoding */
return ffurl_write(s->hd, buf, size);
}
@@ -454,7 +501,7 @@ static int http_close(URLContext *h)
HTTPContext *s = h->priv_data;
/* signal end of chunked encoding if used */
- if ((h->flags & AVIO_FLAG_WRITE) && s->chunksize != -1) {
+ if ((h->flags & AVIO_FLAG_WRITE) && s->chunked_post) {
ret = ffurl_write(s->hd, footer, sizeof(footer) - 1);
ret = ret > 0 ? 0 : ret;
}
@@ -507,6 +554,7 @@ http_get_file_handle(URLContext *h)
return ffurl_get_file_handle(s->hd);
}
+#if CONFIG_HTTP_PROTOCOL
URLProtocol ff_http_protocol = {
.name = "http",
.url_open = http_open,
@@ -516,5 +564,134 @@ URLProtocol ff_http_protocol = {
.url_close = http_close,
.url_get_file_handle = http_get_file_handle,
.priv_data_size = sizeof(HTTPContext),
- .priv_data_class = &httpcontext_class,
+ .priv_data_class = &http_context_class,
+};
+#endif
+#if CONFIG_HTTPS_PROTOCOL
+URLProtocol ff_https_protocol = {
+ .name = "https",
+ .url_open = http_open,
+ .url_read = http_read,
+ .url_write = http_write,
+ .url_seek = http_seek,
+ .url_close = http_close,
+ .url_get_file_handle = http_get_file_handle,
+ .priv_data_size = sizeof(HTTPContext),
+ .priv_data_class = &https_context_class,
+};
+#endif
+
+#if CONFIG_HTTPPROXY_PROTOCOL
+static int http_proxy_close(URLContext *h)
+{
+ HTTPContext *s = h->priv_data;
+ if (s->hd)
+ ffurl_close(s->hd);
+ return 0;
+}
+
+static int http_proxy_open(URLContext *h, const char *uri, int flags)
+{
+ HTTPContext *s = h->priv_data;
+ char hostname[1024], hoststr[1024];
+ char auth[1024], pathbuf[1024], *path;
+ char line[1024], lower_url[100];
+ int port, ret = 0;
+ HTTPAuthType cur_auth_type;
+ char *authstr;
+
+ h->is_streamed = 1;
+
+ av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
+ pathbuf, sizeof(pathbuf), uri);
+ ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
+ path = pathbuf;
+ if (*path == '/')
+ path++;
+
+ ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port,
+ NULL);
+redo:
+ ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,
+ &h->interrupt_callback, NULL);
+ if (ret < 0)
+ return ret;
+
+ authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth,
+ path, "CONNECT");
+ snprintf(s->buffer, sizeof(s->buffer),
+ "CONNECT %s HTTP/1.1\r\n"
+ "Host: %s\r\n"
+ "Connection: close\r\n"
+ "%s%s"
+ "\r\n",
+ path,
+ hoststr,
+ authstr ? "Proxy-" : "", authstr ? authstr : "");
+ av_freep(&authstr);
+
+ if ((ret = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)
+ goto fail;
+
+ s->buf_ptr = s->buffer;
+ s->buf_end = s->buffer;
+ s->line_count = 0;
+ s->filesize = -1;
+ cur_auth_type = s->proxy_auth_state.auth_type;
+
+ for (;;) {
+ int new_loc;
+ // Note: This uses buffering, potentially reading more than the
+ // HTTP header. If tunneling a protocol where the server starts
+ // the conversation, we might buffer part of that here, too.
+ // Reading that requires using the proper ffurl_read() function
+ // on this URLContext, not using the fd directly (as the tls
+ // protocol does). This shouldn't be an issue for tls though,
+ // since the client starts the conversation there, so there
+ // is no extra data that we might buffer up here.
+ if (http_get_line(s, line, sizeof(line)) < 0) {
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+
+ av_dlog(h, "header='%s'\n", line);
+
+ ret = process_line(h, line, s->line_count, &new_loc);
+ if (ret < 0)
+ goto fail;
+ if (ret == 0)
+ break;
+ s->line_count++;
+ }
+ if (s->http_code == 407 && cur_auth_type == HTTP_AUTH_NONE &&
+ s->proxy_auth_state.auth_type != HTTP_AUTH_NONE) {
+ ffurl_close(s->hd);
+ s->hd = NULL;
+ goto redo;
+ }
+
+ if (s->http_code < 400)
+ return 0;
+ ret = AVERROR(EIO);
+
+fail:
+ http_proxy_close(h);
+ return ret;
+}
+
+static int http_proxy_write(URLContext *h, const uint8_t *buf, int size)
+{
+ HTTPContext *s = h->priv_data;
+ return ffurl_write(s->hd, buf, size);
+}
+
+URLProtocol ff_httpproxy_protocol = {
+ .name = "httpproxy",
+ .url_open = http_proxy_open,
+ .url_read = http_buf_read,
+ .url_write = http_proxy_write,
+ .url_close = http_proxy_close,
+ .url_get_file_handle = http_get_file_handle,
+ .priv_data_size = sizeof(HTTPContext),
};
+#endif
diff --git a/libavformat/http.h b/libavformat/http.h
index c5ff5e1..8dfb192 100644
--- a/libavformat/http.h
+++ b/libavformat/http.h
@@ -25,32 +25,6 @@
#include "url.h"
/**
- * Set custom HTTP headers.
- * A trailing CRLF ("\r\n") is required for custom headers.
- * Passing in an empty header string ("\0") will reset to defaults.
- *
- * The following headers can be overriden by custom values,
- * otherwise they will be set to their defaults.
- * -User-Agent
- * -Accept
- * -Range
- * -Host
- * -Connection
- *
- * @param h URL context for this HTTP connection
- * @param headers the custom headers to set
- */
-void ff_http_set_headers(URLContext *h, const char *headers);
-
-/**
- * Enable or disable chunked transfer encoding. (default is enabled)
- *
- * @param h URL context for this HTTP connection
- * @param is_chunked 0 to disable chunking, nonzero otherwise.
- */
-void ff_http_set_chunked_transfer_encoding(URLContext *h, int is_chunked);
-
-/**
* Initialize the authentication state based on another HTTP URLContext.
* This can be used to pre-initialize the authentication parameters if
* they are known beforehand, to avoid having to do an initial failing
diff --git a/libavformat/httpauth.c b/libavformat/httpauth.c
index 1dda1ac..c8b8ace 100644
--- a/libavformat/httpauth.c
+++ b/libavformat/httpauth.c
@@ -87,7 +87,7 @@ static void choose_qop(char *qop, int size)
void ff_http_auth_handle_header(HTTPAuthState *state, const char *key,
const char *value)
{
- if (!strcmp(key, "WWW-Authenticate")) {
+ if (!strcmp(key, "WWW-Authenticate") || !strcmp(key, "Proxy-Authenticate")) {
const char *p;
if (av_stristart(value, "Basic ", &p) &&
state->auth_type <= HTTP_AUTH_BASIC) {
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index be6c03b..deb652d 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -26,6 +26,66 @@
#include "libavutil/dict.h"
#include "avio_internal.h"
+const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
+ { "TALB", "album"},
+ { "TCOM", "composer"},
+ { "TCON", "genre"},
+ { "TCOP", "copyright"},
+ { "TENC", "encoded_by"},
+ { "TIT2", "title"},
+ { "TLAN", "language"},
+ { "TPE1", "artist"},
+ { "TPE2", "album_artist"},
+ { "TPE3", "performer"},
+ { "TPOS", "disc"},
+ { "TPUB", "publisher"},
+ { "TRCK", "track"},
+ { "TSSE", "encoder"},
+ { 0 }
+};
+
+const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
+ { "TDRL", "date"},
+ { "TDRC", "date"},
+ { "TDEN", "creation_time"},
+ { "TSOA", "album-sort"},
+ { "TSOP", "artist-sort"},
+ { "TSOT", "title-sort"},
+ { 0 }
+};
+
+static const AVMetadataConv id3v2_2_metadata_conv[] = {
+ { "TAL", "album"},
+ { "TCO", "genre"},
+ { "TT2", "title"},
+ { "TEN", "encoded_by"},
+ { "TP1", "artist"},
+ { "TP2", "album_artist"},
+ { "TP3", "performer"},
+ { "TRK", "track"},
+ { 0 }
+};
+
+
+const char ff_id3v2_tags[][4] = {
+ "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
+ "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
+ "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
+ "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
+ { 0 },
+};
+
+const char ff_id3v2_4_tags[][4] = {
+ "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
+ "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
+ { 0 },
+};
+
+const char ff_id3v2_3_tags[][4] = {
+ "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
+ { 0 },
+};
+
int ff_id3v2_match(const uint8_t *buf, const char * magic)
{
return buf[0] == magic[0] &&
@@ -59,81 +119,220 @@ static unsigned int get_size(AVIOContext *s, int len)
return v;
}
-static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key)
+/**
+ * Free GEOB type extra metadata.
+ */
+static void free_geobtag(void *obj)
{
- char *q, dst[512];
- const char *val = NULL;
- int len, dstlen = sizeof(dst) - 1;
- unsigned genre;
- unsigned int (*get)(AVIOContext*) = avio_rb16;
+ ID3v2ExtraMetaGEOB *geob = obj;
+ av_free(geob->mime_type);
+ av_free(geob->file_name);
+ av_free(geob->description);
+ av_free(geob->data);
+ av_free(geob);
+}
- dst[0] = 0;
- if (taglen < 1)
- return;
+/**
+ * Decode characters to UTF-8 according to encoding type. The decoded buffer is
+ * always null terminated. Stop reading when either *maxread bytes are read from
+ * pb or U+0000 character is found.
+ *
+ * @param dst Pointer where the address of the buffer with the decoded bytes is
+ * stored. Buffer must be freed by caller.
+ * @param maxread Pointer to maximum number of characters to read from the
+ * AVIOContext. After execution the value is decremented by the number of bytes
+ * actually read.
+ * @returns 0 if no error occurred, dst is uninitialized on error
+ */
+static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
+ uint8_t **dst, int *maxread)
+{
+ int ret;
+ uint8_t tmp;
+ uint32_t ch = 1;
+ int left = *maxread;
+ unsigned int (*get)(AVIOContext*) = avio_rb16;
+ AVIOContext *dynbuf;
- taglen--; /* account for encoding type byte */
+ if ((ret = avio_open_dyn_buf(&dynbuf)) < 0) {
+ av_log(s, AV_LOG_ERROR, "Error opening memory stream\n");
+ return ret;
+ }
- switch (avio_r8(pb)) { /* encoding type */
+ switch (encoding) {
case ID3v2_ENCODING_ISO8859:
- q = dst;
- while (taglen-- && q - dst < dstlen - 7) {
- uint8_t tmp;
- PUT_UTF8(avio_r8(pb), tmp, *q++ = tmp;)
+ while (left && ch) {
+ ch = avio_r8(pb);
+ PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
+ left--;
}
- *q = 0;
break;
case ID3v2_ENCODING_UTF16BOM:
- taglen -= 2;
+ if ((left -= 2) < 0) {
+ av_log(s, AV_LOG_ERROR, "Cannot read BOM value, input too short\n");
+ avio_close_dyn_buf(dynbuf, dst);
+ av_freep(dst);
+ return AVERROR_INVALIDDATA;
+ }
switch (avio_rb16(pb)) {
case 0xfffe:
get = avio_rl16;
case 0xfeff:
break;
default:
- av_log(s, AV_LOG_ERROR, "Incorrect BOM value in tag %s.\n", key);
- return;
+ av_log(s, AV_LOG_ERROR, "Incorrect BOM value\n");
+ avio_close_dyn_buf(dynbuf, dst);
+ av_freep(dst);
+ *maxread = left;
+ return AVERROR_INVALIDDATA;
}
// fall-through
case ID3v2_ENCODING_UTF16BE:
- q = dst;
- while (taglen > 1 && q - dst < dstlen - 7) {
- uint32_t ch;
- uint8_t tmp;
-
- GET_UTF16(ch, ((taglen -= 2) >= 0 ? get(pb) : 0), break;)
- PUT_UTF8(ch, tmp, *q++ = tmp;)
+ while ((left > 1) && ch) {
+ GET_UTF16(ch, ((left -= 2) >= 0 ? get(pb) : 0), break;)
+ PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
}
- *q = 0;
+ if (left < 0)
+ left += 2; /* did not read last char from pb */
break;
case ID3v2_ENCODING_UTF8:
- len = FFMIN(taglen, dstlen);
- avio_read(pb, dst, len);
- dst[len] = 0;
+ while (left && ch) {
+ ch = avio_r8(pb);
+ avio_w8(dynbuf, ch);
+ left--;
+ }
break;
default:
- av_log(s, AV_LOG_WARNING, "Unknown encoding in tag %s.\n", key);
+ av_log(s, AV_LOG_WARNING, "Unknown encoding\n");
+ }
+
+ if (ch)
+ avio_w8(dynbuf, 0);
+
+ avio_close_dyn_buf(dynbuf, dst);
+ *maxread = left;
+
+ return 0;
+}
+
+/**
+ * Parse a text tag.
+ */
+static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key)
+{
+ uint8_t *dst;
+ int encoding, dict_flags = AV_DICT_DONT_OVERWRITE;
+ unsigned genre;
+
+ if (taglen < 1)
+ return;
+
+ encoding = avio_r8(pb);
+ taglen--; /* account for encoding type byte */
+
+ if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
+ av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key);
+ return;
}
if (!(strcmp(key, "TCON") && strcmp(key, "TCO"))
&& (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1)
- && genre <= ID3v1_GENRE_MAX)
- val = ff_id3v1_genre_str[genre];
- else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
- /* dst now contains two 0-terminated strings */
- dst[dstlen] = 0;
- len = strlen(dst);
+ && genre <= ID3v1_GENRE_MAX) {
+ av_freep(&dst);
+ dst = ff_id3v1_genre_str[genre];
+ } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
+ /* dst now contains the key, need to get value */
key = dst;
- val = dst + FFMIN(len + 1, dstlen);
+ if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
+ av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key);
+ av_freep(&key);
+ return;
+ }
+ dict_flags |= AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_STRDUP_KEY;
}
else if (*dst)
- val = dst;
+ dict_flags |= AV_DICT_DONT_STRDUP_VAL;
- if (val)
- av_dict_set(&s->metadata, key, val, AV_DICT_DONT_OVERWRITE);
+ if (dst)
+ av_dict_set(&s->metadata, key, dst, dict_flags);
+}
+
+/**
+ * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
+ */
+static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+{
+ ID3v2ExtraMetaGEOB *geob_data = NULL;
+ ID3v2ExtraMeta *new_extra = NULL;
+ char encoding;
+ unsigned int len;
+
+ if (taglen < 1)
+ return;
+
+ geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB));
+ if (!geob_data) {
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMetaGEOB));
+ return;
+ }
+
+ new_extra = av_mallocz(sizeof(ID3v2ExtraMeta));
+ if (!new_extra) {
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMeta));
+ goto fail;
+ }
+
+ /* read encoding type byte */
+ encoding = avio_r8(pb);
+ taglen--;
+
+ /* read MIME type (always ISO-8859) */
+ if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type, &taglen) < 0
+ || taglen <= 0)
+ goto fail;
+
+ /* read file name */
+ if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0
+ || taglen <= 0)
+ goto fail;
+
+ /* read content description */
+ if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0
+ || taglen < 0)
+ goto fail;
+
+ if (taglen) {
+ /* save encapsulated binary data */
+ geob_data->data = av_malloc(taglen);
+ if (!geob_data->data) {
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", taglen);
+ goto fail;
+ }
+ if ((len = avio_read(pb, geob_data->data, taglen)) < taglen)
+ av_log(s, AV_LOG_WARNING, "Error reading GEOB frame, data truncated.\n");
+ geob_data->datasize = len;
+ } else {
+ geob_data->data = NULL;
+ geob_data->datasize = 0;
+ }
+
+ /* add data to the list */
+ new_extra->tag = "GEOB";
+ new_extra->data = geob_data;
+ new_extra->next = *extra_meta;
+ *extra_meta = new_extra;
+
+ return;
+
+fail:
+ av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", tag);
+ free_geobtag(geob_data);
+ av_free(new_extra);
+ return;
}
static int is_number(const char *str)
@@ -182,7 +381,38 @@ finish:
av_dict_set(m, "date", date, 0);
}
-static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags)
+typedef struct ID3v2EMFunc {
+ const char *tag3;
+ const char *tag4;
+ void (*read)(AVFormatContext*, AVIOContext*, int, char*, ID3v2ExtraMeta **);
+ void (*free)(void *obj);
+} ID3v2EMFunc;
+
+static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
+ { "GEO", "GEOB", read_geobtag, free_geobtag },
+ { NULL }
+};
+
+/**
+ * Get the corresponding ID3v2EMFunc struct for a tag.
+ * @param isv34 Determines if v2.2 or v2.3/4 strings are used
+ * @return A pointer to the ID3v2EMFunc struct if found, NULL otherwise.
+ */
+static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34)
+{
+ int i = 0;
+ while (id3v2_extra_meta_funcs[i].tag3) {
+ if (!memcmp(tag,
+ (isv34 ? id3v2_extra_meta_funcs[i].tag4 :
+ id3v2_extra_meta_funcs[i].tag3),
+ (isv34 ? 4 : 3)))
+ return &id3v2_extra_meta_funcs[i];
+ i++;
+ }
+ return NULL;
+}
+
+static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags, ID3v2ExtraMeta **extra_meta)
{
int isv34, tlen, unsync;
char tag[5];
@@ -190,8 +420,10 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
int taghdrlen;
const char *reason = NULL;
AVIOContext pb;
+ AVIOContext *pbx;
unsigned char *buffer = NULL;
int buffer_size = 0;
+ const ID3v2EMFunc *extra_func;
switch (version) {
case 2:
@@ -237,13 +469,19 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
tag[3] = 0;
tlen = avio_rb24(s->pb);
}
- if (tlen <= 0 || tlen > len - taghdrlen) {
+ if (tlen < 0 || tlen > len - taghdrlen) {
av_log(s, AV_LOG_WARNING, "Invalid size in frame %s, skipping the rest of tag.\n", tag);
break;
}
len -= taghdrlen + tlen;
next = avio_tell(s->pb) + tlen;
+ if (!tlen) {
+ if (tag[0])
+ av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n", tag);
+ continue;
+ }
+
if (tflags & ID3v2_FLAG_DATALEN) {
avio_rb32(s->pb);
tlen -= 4;
@@ -252,7 +490,8 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
if (tflags & (ID3v2_FLAG_ENCRYPTION | ID3v2_FLAG_COMPRESSION)) {
av_log(s, AV_LOG_WARNING, "Skipping encrypted/compressed ID3v2 frame %s.\n", tag);
avio_skip(s->pb, tlen);
- } else if (tag[0] == 'T') {
+ /* check for text tag or supported special meta tag */
+ } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) {
if (unsync || tunsync) {
int i, j;
av_fast_malloc(&buffer, &buffer_size, tlen);
@@ -268,10 +507,17 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
}
}
ffio_init_context(&pb, buffer, j, 0, NULL, NULL, NULL, NULL);
- read_ttag(s, &pb, j, tag);
+ tlen = j;
+ pbx = &pb; // read from sync buffer
} else {
- read_ttag(s, s->pb, tlen, tag);
+ pbx = s->pb; // read straight from input
}
+ if (tag[0] == 'T')
+ /* parse text tag */
+ read_ttag(s, pbx, tlen, tag);
+ else
+ /* parse special meta tag */
+ extra_func->read(s, pbx, tlen, tag, extra_meta);
}
else if (!tag[0]) {
if (tag[1])
@@ -295,7 +541,7 @@ seek:
return;
}
-void ff_id3v2_read(AVFormatContext *s, const char *magic)
+void ff_id3v2_read_all(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta)
{
int len, ret;
uint8_t buf[ID3v2_HEADER_SIZE];
@@ -315,73 +561,32 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic)
((buf[7] & 0x7f) << 14) |
((buf[8] & 0x7f) << 7) |
(buf[9] & 0x7f);
- ff_id3v2_parse(s, len, buf[3], buf[5]);
+ ff_id3v2_parse(s, len, buf[3], buf[5], extra_meta);
} else {
avio_seek(s->pb, off, SEEK_SET);
}
} while (found_header);
ff_metadata_conv(&s->metadata, NULL, ff_id3v2_34_metadata_conv);
- ff_metadata_conv(&s->metadata, NULL, ff_id3v2_2_metadata_conv);
+ ff_metadata_conv(&s->metadata, NULL, id3v2_2_metadata_conv);
ff_metadata_conv(&s->metadata, NULL, ff_id3v2_4_metadata_conv);
merge_date(&s->metadata);
}
-const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
- { "TALB", "album"},
- { "TCOM", "composer"},
- { "TCON", "genre"},
- { "TCOP", "copyright"},
- { "TENC", "encoded_by"},
- { "TIT2", "title"},
- { "TLAN", "language"},
- { "TPE1", "artist"},
- { "TPE2", "album_artist"},
- { "TPE3", "performer"},
- { "TPOS", "disc"},
- { "TPUB", "publisher"},
- { "TRCK", "track"},
- { "TSSE", "encoder"},
- { 0 }
-};
-
-const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
- { "TDRL", "date"},
- { "TDRC", "date"},
- { "TDEN", "creation_time"},
- { "TSOA", "album-sort"},
- { "TSOP", "artist-sort"},
- { "TSOT", "title-sort"},
- { 0 }
-};
-
-const AVMetadataConv ff_id3v2_2_metadata_conv[] = {
- { "TAL", "album"},
- { "TCO", "genre"},
- { "TT2", "title"},
- { "TEN", "encoded_by"},
- { "TP1", "artist"},
- { "TP2", "album_artist"},
- { "TP3", "performer"},
- { "TRK", "track"},
- { 0 }
-};
-
-
-const char ff_id3v2_tags[][4] = {
- "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
- "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
- "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
- "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
- { 0 },
-};
-
-const char ff_id3v2_4_tags[][4] = {
- "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
- "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
- { 0 },
-};
+void ff_id3v2_read(AVFormatContext *s, const char *magic)
+{
+ ff_id3v2_read_all(s, magic, NULL);
+}
-const char ff_id3v2_3_tags[][4] = {
- "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
- { 0 },
-};
+void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
+{
+ ID3v2ExtraMeta *current = *extra_meta, *next;
+ const ID3v2EMFunc *extra_func;
+
+ while (current) {
+ if ((extra_func = get_extra_meta_func(current->tag, 1)))
+ extra_func->free(current->data);
+ next = current->next;
+ av_freep(¤t);
+ current = next;
+ }
+}
diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h
index 3e0e65a..a296e03 100644
--- a/libavformat/id3v2.h
+++ b/libavformat/id3v2.h
@@ -45,10 +45,24 @@ enum ID3v2Encoding {
ID3v2_ENCODING_UTF8 = 3,
};
+typedef struct ID3v2ExtraMeta {
+ const char *tag;
+ void *data;
+ struct ID3v2ExtraMeta *next;
+} ID3v2ExtraMeta;
+
+typedef struct ID3v2ExtraMetaGEOB {
+ uint32_t datasize;
+ uint8_t *mime_type;
+ uint8_t *file_name;
+ uint8_t *description;
+ uint8_t *data;
+} ID3v2ExtraMetaGEOB;
+
/**
* Detect ID3v2 Header.
* @param buf must be ID3v2_HEADER_SIZE byte long
- * @param magic magic bytes to identify the header, machine byte order.
+ * @param magic magic bytes to identify the header.
* If in doubt, use ID3v2_DEFAULT_MAGIC.
*/
int ff_id3v2_match(const uint8_t *buf, const char *magic);
@@ -61,13 +75,33 @@ int ff_id3v2_match(const uint8_t *buf, const char *magic);
int ff_id3v2_tag_len(const uint8_t *buf);
/**
- * Read an ID3v2 tag
+ * Read an ID3v2 tag (text tags only)
*/
void ff_id3v2_read(AVFormatContext *s, const char *magic);
+/**
+ * Read an ID3v2 tag, including supported extra metadata (currently only GEOB)
+ * @param extra_meta If not NULL, extra metadata is parsed into a list of
+ * ID3v2ExtraMeta structs and *extra_meta points to the head of the list
+ */
+void ff_id3v2_read_all(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta);
+
+/**
+ * Write an ID3v2 tag.
+ * @param id3v2_version Subversion of ID3v2; supported values are 3 and 4
+ * @param magic magic bytes to identify the header
+ * If in doubt, use ID3v2_DEFAULT_MAGIC.
+ */
+int ff_id3v2_write(struct AVFormatContext *s, int id3v2_version, const char *magic);
+
+/**
+ * Free memory allocated parsing special (non-text) metadata.
+ * @param extra_meta Pointer to a pointer to the head of a ID3v2ExtraMeta list, *extra_meta is set to NULL.
+ */
+void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta);
+
extern const AVMetadataConv ff_id3v2_34_metadata_conv[];
extern const AVMetadataConv ff_id3v2_4_metadata_conv[];
-extern const AVMetadataConv ff_id3v2_2_metadata_conv[];
/**
* A list of text information frames allowed in both ID3 v2.3 and v2.4
diff --git a/libavformat/id3v2enc.c b/libavformat/id3v2enc.c
new file mode 100644
index 0000000..36c73bf
--- /dev/null
+++ b/libavformat/id3v2enc.c
@@ -0,0 +1,146 @@
+/*
+ * ID3v2 header writer
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "avio.h"
+#include "id3v2.h"
+
+static void id3v2_put_size(AVFormatContext *s, int size)
+{
+ avio_w8(s->pb, size >> 21 & 0x7f);
+ avio_w8(s->pb, size >> 14 & 0x7f);
+ avio_w8(s->pb, size >> 7 & 0x7f);
+ avio_w8(s->pb, size & 0x7f);
+}
+
+static int string_is_ascii(const uint8_t *str)
+{
+ while (*str && *str < 128) str++;
+ return !*str;
+}
+
+/**
+ * Write a text frame with one (normal frames) or two (TXXX frames) strings
+ * according to encoding (only UTF-8 or UTF-16+BOM supported).
+ * @return number of bytes written or a negative error code.
+ */
+static int id3v2_put_ttag(AVFormatContext *s, const char *str1, const char *str2,
+ uint32_t tag, enum ID3v2Encoding enc)
+{
+ int len;
+ uint8_t *pb;
+ int (*put)(AVIOContext*, const char*);
+ AVIOContext *dyn_buf;
+ if (avio_open_dyn_buf(&dyn_buf) < 0)
+ return AVERROR(ENOMEM);
+
+ /* check if the strings are ASCII-only and use UTF16 only if
+ * they're not */
+ if (enc == ID3v2_ENCODING_UTF16BOM && string_is_ascii(str1) &&
+ (!str2 || string_is_ascii(str2)))
+ enc = ID3v2_ENCODING_ISO8859;
+
+ avio_w8(dyn_buf, enc);
+ if (enc == ID3v2_ENCODING_UTF16BOM) {
+ avio_wl16(dyn_buf, 0xFEFF); /* BOM */
+ put = avio_put_str16le;
+ } else
+ put = avio_put_str;
+
+ put(dyn_buf, str1);
+ if (str2)
+ put(dyn_buf, str2);
+ len = avio_close_dyn_buf(dyn_buf, &pb);
+
+ avio_wb32(s->pb, tag);
+ id3v2_put_size(s, len);
+ avio_wb16(s->pb, 0);
+ avio_write(s->pb, pb, len);
+
+ av_freep(&pb);
+ return len + ID3v2_HEADER_SIZE;
+}
+
+static int id3v2_check_write_tag(AVFormatContext *s, AVDictionaryEntry *t, const char table[][4],
+ enum ID3v2Encoding enc)
+{
+ uint32_t tag;
+ int i;
+
+ if (t->key[0] != 'T' || strlen(t->key) != 4)
+ return -1;
+ tag = AV_RB32(t->key);
+ for (i = 0; *table[i]; i++)
+ if (tag == AV_RB32(table[i]))
+ return id3v2_put_ttag(s, t->value, NULL, tag, enc);
+ return -1;
+}
+
+int ff_id3v2_write(struct AVFormatContext *s, int id3v2_version,
+ const char *magic)
+{
+ int64_t size_pos, cur_pos;
+ AVDictionaryEntry *t = NULL;
+
+ int totlen = 0, enc = id3v2_version == 3 ? ID3v2_ENCODING_UTF16BOM :
+ ID3v2_ENCODING_UTF8;
+
+
+ avio_wb32(s->pb, MKBETAG(magic[0], magic[1], magic[2], id3v2_version));
+ avio_w8(s->pb, 0);
+ avio_w8(s->pb, 0); /* flags */
+
+ /* reserve space for size */
+ size_pos = avio_tell(s->pb);
+ avio_wb32(s->pb, 0);
+
+ ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL);
+ if (id3v2_version == 4)
+ ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
+
+ while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
+ int ret;
+
+ if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags, enc)) > 0) {
+ totlen += ret;
+ continue;
+ }
+ if ((ret = id3v2_check_write_tag(s, t, id3v2_version == 3 ?
+ ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
+ totlen += ret;
+ continue;
+ }
+
+ /* unknown tag, write as TXXX frame */
+ if ((ret = id3v2_put_ttag(s, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
+ return ret;
+ totlen += ret;
+ }
+
+ cur_pos = avio_tell(s->pb);
+ avio_seek(s->pb, size_pos, SEEK_SET);
+ id3v2_put_size(s, totlen);
+ avio_seek(s->pb, cur_pos, SEEK_SET);
+ return 0;
+}
diff --git a/libavformat/idcin.c b/libavformat/idcin.c
index 04ae687..b26f2aa 100644
--- a/libavformat/idcin.c
+++ b/libavformat/idcin.c
@@ -70,6 +70,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define HUFFMAN_TABLE_SIZE (64 * 1024)
#define IDCIN_FPS 14
@@ -153,10 +154,10 @@ static int idcin_read_header(AVFormatContext *s,
bytes_per_sample = avio_rl32(pb);
channels = avio_rl32(pb);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 33, 1, IDCIN_FPS);
+ avpriv_set_pts_info(st, 33, 1, IDCIN_FPS);
idcin->video_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_IDCIN;
@@ -174,10 +175,10 @@ static int idcin_read_header(AVFormatContext *s,
/* if sample rate is 0, assume no audio */
if (sample_rate) {
idcin->audio_present = 1;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 33, 1, IDCIN_FPS);
+ avpriv_set_pts_info(st, 33, 1, IDCIN_FPS);
idcin->audio_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_tag = 1;
@@ -292,10 +293,10 @@ static int idcin_read_packet(AVFormatContext *s,
}
AVInputFormat ff_idcin_demuxer = {
- "idcin",
- NULL_IF_CONFIG_SMALL("id Cinematic format"),
- sizeof(IdcinDemuxContext),
- idcin_probe,
- idcin_read_header,
- idcin_read_packet,
+ .name = "idcin",
+ .long_name = NULL_IF_CONFIG_SMALL("id Cinematic format"),
+ .priv_data_size = sizeof(IdcinDemuxContext),
+ .read_probe = idcin_probe,
+ .read_header = idcin_read_header,
+ .read_packet = idcin_read_packet,
};
diff --git a/libavformat/idroqdec.c b/libavformat/idroqdec.c
index 8e991c5..d63c395 100644
--- a/libavformat/idroqdec.c
+++ b/libavformat/idroqdec.c
@@ -29,6 +29,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define RoQ_MAGIC_NUMBER 0x1084
#define RoQ_CHUNK_PREAMBLE_SIZE 8
@@ -43,6 +44,7 @@
typedef struct RoqDemuxContext {
+ int frame_rate;
int width;
int height;
int audio_channels;
@@ -69,29 +71,21 @@ static int roq_read_header(AVFormatContext *s,
{
RoqDemuxContext *roq = s->priv_data;
AVIOContext *pb = s->pb;
- int framerate;
- AVStream *st;
unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
/* get the main header */
if (avio_read(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
RoQ_CHUNK_PREAMBLE_SIZE)
return AVERROR(EIO);
- framerate = AV_RL16(&preamble[6]);
+ roq->frame_rate = AV_RL16(&preamble[6]);
/* init private context parameters */
roq->width = roq->height = roq->audio_channels = roq->video_pts =
roq->audio_frame_count = 0;
roq->audio_stream_index = -1;
+ roq->video_stream_index = -1;
- st = av_new_stream(s, 0);
- if (!st)
- return AVERROR(ENOMEM);
- av_set_pts_info(st, 63, 1, framerate);
- roq->video_stream_index = st->index;
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = CODEC_ID_ROQ;
- st->codec->codec_tag = 0; /* no fourcc */
+ s->ctx_flags |= AVFMTCTX_NOHEADER;
return 0;
}
@@ -127,8 +121,16 @@ static int roq_read_packet(AVFormatContext *s,
switch (chunk_type) {
case RoQ_INFO:
- if (!roq->width || !roq->height) {
- AVStream *st = s->streams[roq->video_stream_index];
+ if (roq->video_stream_index == -1) {
+ AVStream *st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ avpriv_set_pts_info(st, 63, 1, roq->frame_rate);
+ roq->video_stream_index = st->index;
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = CODEC_ID_ROQ;
+ st->codec->codec_tag = 0; /* no fourcc */
+
if (avio_read(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE)
return AVERROR(EIO);
st->codec->width = roq->width = AV_RL16(preamble);
@@ -166,10 +168,10 @@ static int roq_read_packet(AVFormatContext *s,
case RoQ_SOUND_MONO:
case RoQ_SOUND_STEREO:
if (roq->audio_stream_index == -1) {
- AVStream *st = av_new_stream(s, 1);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 32, 1, RoQ_AUDIO_SAMPLE_RATE);
+ avpriv_set_pts_info(st, 32, 1, RoQ_AUDIO_SAMPLE_RATE);
roq->audio_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_ROQ_DPCM;
@@ -209,7 +211,6 @@ static int roq_read_packet(AVFormatContext *s,
default:
av_log(s, AV_LOG_ERROR, " unknown RoQ chunk (%04X)\n", chunk_type);
return AVERROR_INVALIDDATA;
- break;
}
}
@@ -217,10 +218,10 @@ static int roq_read_packet(AVFormatContext *s,
}
AVInputFormat ff_roq_demuxer = {
- "RoQ",
- NULL_IF_CONFIG_SMALL("id RoQ format"),
- sizeof(RoqDemuxContext),
- roq_probe,
- roq_read_header,
- roq_read_packet,
+ .name = "RoQ",
+ .long_name = NULL_IF_CONFIG_SMALL("id RoQ format"),
+ .priv_data_size = sizeof(RoqDemuxContext),
+ .read_probe = roq_probe,
+ .read_header = roq_read_header,
+ .read_packet = roq_read_packet,
};
diff --git a/libavformat/idroqenc.c b/libavformat/idroqenc.c
index 688d58d..266a731 100644
--- a/libavformat/idroqenc.c
+++ b/libavformat/idroqenc.c
@@ -35,15 +35,12 @@ static int roq_write_header(struct AVFormatContext *s)
return 0;
}
-AVOutputFormat ff_roq_muxer =
-{
- "RoQ",
- NULL_IF_CONFIG_SMALL("raw id RoQ format"),
- NULL,
- "roq",
- 0,
- CODEC_ID_ROQ_DPCM,
- CODEC_ID_ROQ,
- roq_write_header,
- ff_raw_write_packet,
+AVOutputFormat ff_roq_muxer = {
+ .name = "RoQ",
+ .long_name = NULL_IF_CONFIG_SMALL("raw id RoQ format"),
+ .extensions = "roq",
+ .audio_codec = CODEC_ID_ROQ_DPCM,
+ .video_codec = CODEC_ID_ROQ,
+ .write_header = roq_write_header,
+ .write_packet = ff_raw_write_packet,
};
diff --git a/libavformat/iff.c b/libavformat/iff.c
index 2b84986..b895cf2 100644
--- a/libavformat/iff.c
+++ b/libavformat/iff.c
@@ -32,6 +32,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "avformat.h"
+#include "internal.h"
#define ID_8SVX MKTAG('8','S','V','X')
#define ID_VHDR MKTAG('V','H','D','R')
@@ -59,8 +60,6 @@
#define RIGHT 4
#define STEREO 6
-#define PACKET_SIZE 1024
-
typedef enum {
COMP_NONE,
COMP_FIB,
@@ -76,22 +75,9 @@ typedef struct {
uint64_t body_pos;
uint32_t body_size;
uint32_t sent_bytes;
- uint32_t audio_frame_count;
} IffDemuxContext;
-static void interleave_stereo(const uint8_t *src, uint8_t *dest, int size)
-{
- uint8_t *end = dest + size;
- size = size>>1;
-
- while(dest < end) {
- *dest++ = *src;
- *dest++ = *(src+size);
- src++;
- }
-}
-
/* Metadata string read */
static int get_metadata(AVFormatContext *s,
const char *const tag,
@@ -130,7 +116,7 @@ static int iff_read_header(AVFormatContext *s,
uint32_t chunk_id, data_size;
int compression = -1;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -231,11 +217,11 @@ static int iff_read_header(AVFormatContext *s,
switch(st->codec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- av_set_pts_info(st, 32, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);
switch(compression) {
case COMP_NONE:
- st->codec->codec_id = CODEC_ID_PCM_S8;
+ st->codec->codec_id = CODEC_ID_PCM_S8_PLANAR;
break;
case COMP_FIB:
st->codec->codec_id = CODEC_ID_8SVX_FIB;
@@ -278,48 +264,28 @@ static int iff_read_packet(AVFormatContext *s,
{
IffDemuxContext *iff = s->priv_data;
AVIOContext *pb = s->pb;
- AVStream *st = s->streams[0];
int ret;
if(iff->sent_bytes >= iff->body_size)
- return AVERROR(EIO);
-
- if(st->codec->channels == 2) {
- uint8_t sample_buffer[PACKET_SIZE];
+ return AVERROR_EOF;
- ret = avio_read(pb, sample_buffer, PACKET_SIZE);
- if(av_new_packet(pkt, PACKET_SIZE) < 0) {
- av_log(s, AV_LOG_ERROR, "cannot allocate packet\n");
- return AVERROR(ENOMEM);
- }
- interleave_stereo(sample_buffer, pkt->data, PACKET_SIZE);
- } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- ret = av_get_packet(pb, pkt, iff->body_size);
- } else {
- ret = av_get_packet(pb, pkt, PACKET_SIZE);
- }
+ ret = av_get_packet(pb, pkt, iff->body_size);
+ if (ret < 0)
+ return ret;
if(iff->sent_bytes == 0)
pkt->flags |= AV_PKT_FLAG_KEY;
+ iff->sent_bytes = iff->body_size;
- if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- iff->sent_bytes += PACKET_SIZE;
- } else {
- iff->sent_bytes = iff->body_size;
- }
pkt->stream_index = 0;
- if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- pkt->pts = iff->audio_frame_count;
- iff->audio_frame_count += ret / st->codec->channels;
- }
return ret;
}
AVInputFormat ff_iff_demuxer = {
- "IFF",
- NULL_IF_CONFIG_SMALL("IFF format"),
- sizeof(IffDemuxContext),
- iff_probe,
- iff_read_header,
- iff_read_packet,
+ .name = "IFF",
+ .long_name = NULL_IF_CONFIG_SMALL("IFF format"),
+ .priv_data_size = sizeof(IffDemuxContext),
+ .read_probe = iff_probe,
+ .read_header = iff_read_header,
+ .read_packet = iff_read_packet,
};
diff --git a/libavformat/img2.c b/libavformat/img2.c
index 4eef623..2af561c 100644
--- a/libavformat/img2.c
+++ b/libavformat/img2.c
@@ -29,7 +29,6 @@
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
-#include <strings.h>
typedef struct {
const AVClass *class; /**< Class for private options. */
@@ -42,6 +41,7 @@ typedef struct {
char *pixel_format; /**< Set by a private option. */
char *video_size; /**< Set by a private option. */
char *framerate; /**< Set by a private option. */
+ int loop;
} VideoData;
typedef struct {
@@ -120,7 +120,7 @@ static enum CodecID av_str2id(const IdStrMap *tags, const char *str)
str++;
while (tags->id) {
- if (!strcasecmp(str, tags->str))
+ if (!av_strcasecmp(str, tags->str))
return tags->id;
tags++;
@@ -215,7 +215,7 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
s1->ctx_flags |= AVFMTCTX_NOHEADER;
- st = av_new_stream(s1, 0);
+ st = avformat_new_stream(s1, NULL);
if (!st) {
return AVERROR(ENOMEM);
}
@@ -232,15 +232,10 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s->framerate);
return ret;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->pix_fmt != PIX_FMT_NONE)
- pix_fmt = ap->pix_fmt;
- if (ap->width > 0)
- width = ap->width;
- if (ap->height > 0)
- height = ap->height;
- if (ap->time_base.num)
- framerate = (AVRational){ap->time_base.den, ap->time_base.num};
+
+#if FF_API_LOOP_INPUT
+ if (s1->loop_input)
+ s->loop = s1->loop_input;
#endif
av_strlcpy(s->path, s1->filename, sizeof(s->path));
@@ -255,7 +250,7 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
st->need_parsing = AVSTREAM_PARSE_FULL;
}
- av_set_pts_info(st, 60, framerate.den, framerate.num);
+ avpriv_set_pts_info(st, 60, framerate.den, framerate.num);
if (width && height) {
st->codec->width = width;
@@ -300,7 +295,7 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt)
if (!s->is_pipe) {
/* loop over input */
- if (s1->loop_input && s->img_number > s->img_last) {
+ if (s->loop && s->img_number > s->img_last) {
s->img_number = s->img_first;
}
if (s->img_number > s->img_last)
@@ -309,7 +304,8 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt)
s->path, s->img_number)<0 && s->img_number > 1)
return AVERROR(EIO);
for(i=0; i<3; i++){
- if (avio_open(&f[i], filename, AVIO_FLAG_READ) < 0) {
+ if (avio_open2(&f[i], filename, AVIO_FLAG_READ,
+ &s1->interrupt_callback, NULL) < 0) {
if(i==1)
break;
av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n",filename);
@@ -393,7 +389,8 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EIO);
}
for(i=0; i<3; i++){
- if (avio_open(&pb[i], filename, AVIO_FLAG_WRITE) < 0) {
+ if (avio_open2(&pb[i], filename, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, NULL) < 0) {
av_log(s, AV_LOG_ERROR, "Could not open file : %s\n",filename);
return AVERROR(EIO);
}
@@ -435,7 +432,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
(!st->codec->extradata_size &&
AV_RL32(pkt->data+4) != MKTAG('j','P',' ',' '))){ // signature
error:
- av_log(s, AV_LOG_ERROR, "malformated jpeg2000 codestream\n");
+ av_log(s, AV_LOG_ERROR, "malformed JPEG 2000 codestream\n");
return -1;
}
}
@@ -455,21 +452,21 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
#define OFFSET(x) offsetof(VideoData, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "pixel_format", "", OFFSET(pixel_format), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "video_size", "", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+ { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "video_size", "", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+ { "loop", "", OFFSET(loop), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, DEC },
{ NULL },
};
+/* input */
+#if CONFIG_IMAGE2_DEMUXER
static const AVClass img2_class = {
.class_name = "image2 demuxer",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};
-
-/* input */
-#if CONFIG_IMAGE2_DEMUXER
AVInputFormat ff_image2_demuxer = {
.name = "image2",
.long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
@@ -482,13 +479,19 @@ AVInputFormat ff_image2_demuxer = {
};
#endif
#if CONFIG_IMAGE2PIPE_DEMUXER
+static const AVClass img2pipe_class = {
+ .class_name = "image2pipe demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
AVInputFormat ff_image2pipe_demuxer = {
.name = "image2pipe",
.long_name = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
.priv_data_size = sizeof(VideoData),
.read_header = read_header,
.read_packet = read_packet,
- .priv_class = &img2_class,
+ .priv_class = &img2pipe_class,
};
#endif
diff --git a/libavformat/ingenientdec.c b/libavformat/ingenientdec.c
index febeb2e..35ac649 100644
--- a/libavformat/ingenientdec.c
+++ b/libavformat/ingenientdec.c
@@ -58,15 +58,16 @@ static int ingenient_read_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
}
+FF_RAWVIDEO_DEMUXER_CLASS(ingenient)
+
AVInputFormat ff_ingenient_demuxer = {
- "ingenient",
- NULL_IF_CONFIG_SMALL("raw Ingenient MJPEG"),
- sizeof(FFRawVideoDemuxerContext),
- NULL,
- ff_raw_video_read_header,
- ingenient_read_packet,
+ .name = "ingenient",
+ .long_name = NULL_IF_CONFIG_SMALL("raw Ingenient MJPEG"),
+ .priv_data_size = sizeof(FFRawVideoDemuxerContext),
+ .read_header = ff_raw_video_read_header,
+ .read_packet = ingenient_read_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "cgi", // FIXME
.value = CODEC_ID_MJPEG,
- .priv_class = &ff_rawvideo_demuxer_class,
+ .priv_class = &ingenient_demuxer_class,
};
diff --git a/libavformat/internal.h b/libavformat/internal.h
index c1a4b4f..559e710 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -108,7 +108,7 @@ uint64_t ff_ntp_time(void);
*/
int ff_url_join(char *str, int size, const char *proto,
const char *authorization, const char *hostname,
- int port, const char *fmt, ...);
+ int port, const char *fmt, ...) av_printf_format(7, 8);
/**
* Append the media-specific SDP fragment for the media stream c
@@ -225,8 +225,8 @@ int ff_add_index_entry(AVIndexEntry **index_entries,
*
* @return AVChapter or NULL on error
*/
-AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base,
- int64_t start, int64_t end, const char *title);
+AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base,
+ int64_t start, int64_t end, const char *title);
/**
* Ensure the index uses less memory than the maximum specified in
@@ -248,4 +248,63 @@ void ff_make_absolute_url(char *buf, int size, const char *base,
enum CodecID ff_guess_image2_codec(const char *filename);
+/**
+ * Convert a date string in ISO8601 format to Unix timestamp.
+ */
+int64_t ff_iso8601_to_unix_time(const char *datestr);
+
+/**
+ * Perform a binary search using av_index_search_timestamp() and
+ * AVInputFormat.read_timestamp().
+ *
+ * @param target_ts target timestamp in the time base of the given stream
+ * @param stream_index stream number
+ */
+int ff_seek_frame_binary(AVFormatContext *s, int stream_index,
+ int64_t target_ts, int flags);
+
+/**
+ * Update cur_dts of all streams based on the given timestamp and AVStream.
+ *
+ * Stream ref_st unchanged, others set cur_dts in their native time base.
+ * Only needed for timestamp wrapping or if (dts not set and pts!=dts).
+ * @param timestamp new dts expressed in time_base of param ref_st
+ * @param ref_st reference stream giving time_base of param timestamp
+ */
+void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
+
+/**
+ * Perform a binary search using read_timestamp().
+ *
+ * @param target_ts target timestamp in the time base of the given stream
+ * @param stream_index stream number
+ */
+int64_t ff_gen_search(AVFormatContext *s, int stream_index,
+ int64_t target_ts, int64_t pos_min,
+ int64_t pos_max, int64_t pos_limit,
+ int64_t ts_min, int64_t ts_max,
+ int flags, int64_t *ts_ret,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
+
+/**
+ * Set the pts for a given stream. If the new values would be invalid
+ * (<= 0), it leaves the AVStream unchanged.
+ *
+ * @param s stream
+ * @param pts_wrap_bits number of bits effectively used by the pts
+ * (used for wrap control, 33 is the value for MPEG)
+ * @param pts_num numerator to convert to seconds (MPEG: 1)
+ * @param pts_den denominator to convert to seconds (MPEG: 90000)
+ */
+void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits,
+ unsigned int pts_num, unsigned int pts_den);
+
+/**
+ * Add side data to a packet for changing parameters to the given values.
+ * Parameters set to 0 aren't included in the change.
+ */
+int ff_add_param_change(AVPacket *pkt, int32_t channels,
+ uint64_t channel_layout, int32_t sample_rate,
+ int32_t width, int32_t height);
+
#endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c
index e8ba064..4bd3580 100644
--- a/libavformat/ipmovie.c
+++ b/libavformat/ipmovie.c
@@ -34,6 +34,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define CHUNK_PREAMBLE_SIZE 4
#define OPCODE_PREAMBLE_SIZE 4
@@ -559,10 +560,10 @@ static int ipmovie_read_header(AVFormatContext *s,
return AVERROR_INVALIDDATA;
/* initialize the stream decoders */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 63, 1, 1000000);
+ avpriv_set_pts_info(st, 63, 1, 1000000);
ipmovie->video_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_INTERPLAY_VIDEO;
@@ -572,10 +573,10 @@ static int ipmovie_read_header(AVFormatContext *s,
st->codec->bits_per_coded_sample = ipmovie->video_bpp;
if (ipmovie->audio_type) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate);
+ avpriv_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate);
ipmovie->audio_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = ipmovie->audio_type;
@@ -616,10 +617,10 @@ static int ipmovie_read_packet(AVFormatContext *s,
}
AVInputFormat ff_ipmovie_demuxer = {
- "ipmovie",
- NULL_IF_CONFIG_SMALL("Interplay MVE format"),
- sizeof(IPMVEContext),
- ipmovie_probe,
- ipmovie_read_header,
- ipmovie_read_packet,
+ .name = "ipmovie",
+ .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE format"),
+ .priv_data_size = sizeof(IPMVEContext),
+ .read_probe = ipmovie_probe,
+ .read_header = ipmovie_read_header,
+ .read_packet = ipmovie_read_packet,
};
diff --git a/libavformat/isom.c b/libavformat/isom.c
index eb17e25..eab304c 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -61,6 +61,8 @@ const AVCodecTag ff_mp4_obj_type[] = {
{ CODEC_ID_VORBIS , 0xDD }, /* non standard, gpac uses it */
{ CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* non standard, see unsupported-embedded-subs-2.mp4 */
{ CODEC_ID_QCELP , 0xE1 },
+ { CODEC_ID_MPEG4SYSTEMS, 0x01 },
+ { CODEC_ID_MPEG4SYSTEMS, 0x02 },
{ CODEC_ID_NONE , 0 },
};
@@ -88,6 +90,7 @@ const AVCodecTag codec_movvideo_tags[] = {
{ CODEC_ID_R10K, MKTAG('R', '1', '0', 'g') }, /* UNCOMPRESSED 10BIT RGB */
{ CODEC_ID_R210, MKTAG('r', '2', '1', '0') }, /* UNCOMPRESSED 10BIT RGB */
{ CODEC_ID_V210, MKTAG('v', '2', '1', '0') }, /* UNCOMPRESSED 10BIT 4:2:2 */
+ { CODEC_ID_V410, MKTAG('v', '4', '1', '0') }, /* UNCOMPRESSED 10BIT 4:4:4 */
{ CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */
{ CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */
@@ -137,11 +140,18 @@ const AVCodecTag codec_movvideo_tags[] = {
{ CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') },
{ CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */
- { CODEC_ID_H264, MKTAG('a', 'i', '5', '5') }, /* AVC Intra 50 / 1080 interlace */
- { CODEC_ID_H264, MKTAG('a', 'i', '5', 'q') }, /* AVC Intra 50 / 720 */
- { CODEC_ID_H264, MKTAG('a', 'i', '1', '5') }, /* AVC Intra 100 / 1080 interlace */
- { CODEC_ID_H264, MKTAG('a', 'i', '1', 'q') }, /* AVC Intra 100 / 720 */
- { CODEC_ID_H264, MKTAG('a', 'i', '1', '2') }, /* AVC Intra 100 / 1080 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', 'p') }, /* AVC-Intra 50M 720p24/30/60 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', 'q') }, /* AVC-Intra 50M 720p25/50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', '2') }, /* AVC-Intra 50M 1080p25/50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', '3') }, /* AVC-Intra 50M 1080p24/30/60 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', '5') }, /* AVC-Intra 50M 1080i50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '5', '6') }, /* AVC-Intra 50M 1080i60 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', 'p') }, /* AVC-Intra 100M 720p24/30/60 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', 'q') }, /* AVC-Intra 100M 720p25/50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', '2') }, /* AVC-Intra 100M 1080p25/50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', '3') }, /* AVC-Intra 100M 1080p24/30/60 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', '5') }, /* AVC-Intra 100M 1080i50 */
+ { CODEC_ID_H264, MKTAG('a', 'i', '1', '6') }, /* AVC-Intra 100M 1080i60 */
{ CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') }, /* Apple MPEG-1 Camcorder */
{ CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */
@@ -197,6 +207,8 @@ const AVCodecTag codec_movvideo_tags[] = {
{ CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
{ CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'n') }, /* AVID DNxHD */
+ { CODEC_ID_FLV1, MKTAG('H', '2', '6', '3') }, /* Flash Media Server */
+ { CODEC_ID_MSMPEG4V3, MKTAG('3', 'I', 'V', 'D') }, /* 3ivx DivX Doctor */
{ CODEC_ID_RAWVIDEO, MKTAG('A', 'V', '1', 'x') }, /* AVID 1:1x */
{ CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'u', 'p') },
{ CODEC_ID_SGI, MKTAG('s', 'g', 'i', ' ') }, /* SGI */
@@ -212,60 +224,48 @@ const AVCodecTag codec_movvideo_tags[] = {
};
const AVCodecTag codec_movaudio_tags[] = {
- { CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') },
- { CODEC_ID_PCM_S32LE, MKTAG('i', 'n', '3', '2') },
- { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') },
- { CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') },
- { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */
- { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /* */
- { CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') },
- { CODEC_ID_PCM_F32BE, MKTAG('f', 'l', '3', '2') },
- { CODEC_ID_PCM_F32LE, MKTAG('f', 'l', '3', '2') },
- { CODEC_ID_PCM_F64BE, MKTAG('f', 'l', '6', '4') },
- { CODEC_ID_PCM_F64LE, MKTAG('f', 'l', '6', '4') },
- { CODEC_ID_PCM_S8, MKTAG('s', 'o', 'w', 't') },
- { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, /* 8 bits unsigned */
- { CODEC_ID_PCM_U8, MKTAG('N', 'O', 'N', 'E') }, /* uncompressed */
- { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /* */
- { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /* */
-
- { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, /* IMA-4 ADPCM */
-
- { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, /* Macintosh Audio Compression and Expansion 3:1 */
- { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, /* Macintosh Audio Compression and Expansion 6:1 */
-
- { CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') }, /* MPEG layer 1 */
- { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '2') }, /* MPEG layer 2 */
-
- { CODEC_ID_MP3, MKTAG('.', 'm', 'p', '3') }, /* MPEG layer 3 */ /* sample files at http://www.3ivx.com/showcase.html use this tag */
- { CODEC_ID_MP3, 0x6D730055 }, /* MPEG layer 3 */
-
-/* { CODEC_ID_OGG_VORBIS, MKTAG('O', 'g', 'g', 'S') }, *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
-
- { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, /* MPEG-4 AAC */
- { CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F */
- { CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') }, /* Nero Recode */
- { CODEC_ID_DTS, MKTAG('d', 't', 's', 'c') }, /* mp4ra.org */
- { CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') }, /* non-standard */
-
- { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */
- { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */
-
- { CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') },
- { CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */
-
- { CODEC_ID_QCELP, MKTAG('Q','c','l','p') },
- { CODEC_ID_QCELP, MKTAG('Q','c','l','q') },
- { CODEC_ID_QCELP, MKTAG('s','q','c','p') }, /* ISO Media fourcc */
-
- { CODEC_ID_QDMC, MKTAG('Q', 'D', 'M', 'C') }, /* QDMC */
- { CODEC_ID_QDM2, MKTAG('Q', 'D', 'M', '2') }, /* QDM2 */
-
- { CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') },
- { CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') },
-
- { CODEC_ID_WMAV2, MKTAG('W', 'M', 'A', '2') },
-
+ { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
+ { CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F */
+ { CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') }, /* Nero Recode */
+ { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') },
+ { CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
+ { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */
+ { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */
+ { CODEC_ID_DTS, MKTAG('d', 't', 's', 'c') }, /* mp4ra.org */
+ { CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') }, /* non-standard */
+ { CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') },
+ { CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') },
+ { CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') },
+ { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') },
+ { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') },
+ { CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') },
+ { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '2') },
+ { CODEC_ID_MP3, MKTAG('.', 'm', 'p', '3') },
+ { CODEC_ID_MP3, 0x6D730055 },
+ { CODEC_ID_NELLYMOSER, MKTAG('n', 'm', 'o', 's') }, /* Flash Media Server */
+ { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') },
+ { CODEC_ID_PCM_F32BE, MKTAG('f', 'l', '3', '2') },
+ { CODEC_ID_PCM_F32LE, MKTAG('f', 'l', '3', '2') },
+ { CODEC_ID_PCM_F64BE, MKTAG('f', 'l', '6', '4') },
+ { CODEC_ID_PCM_F64LE, MKTAG('f', 'l', '6', '4') },
+ { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') },
+ { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') },
+ { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') },
+ { CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') },
+ { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') },
+ { CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') },
+ { CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') },
+ { CODEC_ID_PCM_S32LE, MKTAG('i', 'n', '3', '2') },
+ { CODEC_ID_PCM_S8, MKTAG('s', 'o', 'w', 't') },
+ { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') },
+ { CODEC_ID_PCM_U8, MKTAG('N', 'O', 'N', 'E') },
+ { CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'p') },
+ { CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'q') },
+ { CODEC_ID_QCELP, MKTAG('s', 'q', 'c', 'p') }, /* ISO Media fourcc */
+ { CODEC_ID_QDM2, MKTAG('Q', 'D', 'M', '2') },
+ { CODEC_ID_QDMC, MKTAG('Q', 'D', 'M', 'C') },
+ { CODEC_ID_SPEEX, MKTAG('s', 'p', 'e', 'x') }, /* Flash Media Server */
+ { CODEC_ID_WMAV2, MKTAG('W', 'M', 'A', '2') },
{ CODEC_ID_NONE, 0 },
};
@@ -372,6 +372,22 @@ int ff_mp4_read_descr(AVFormatContext *fc, AVIOContext *pb, int *tag)
return len;
}
+void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id)
+{
+ int flags;
+ if (es_id) *es_id = avio_rb16(pb);
+ else avio_rb16(pb);
+ flags = avio_r8(pb);
+ if (flags & 0x80) //streamDependenceFlag
+ avio_rb16(pb);
+ if (flags & 0x40) { //URL_Flag
+ int len = avio_r8(pb);
+ avio_skip(pb, len);
+ }
+ if (flags & 0x20) //OCRstreamFlag
+ avio_rb16(pb);
+}
+
static const AVCodecTag mp4_audio_types[] = {
{ CODEC_ID_MP3ON4, AOT_PS }, /* old mp3on4 draft */
{ CODEC_ID_MP3ON4, AOT_L1 }, /* layer 1 */
@@ -395,7 +411,7 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext
len = ff_mp4_read_descr(fc, pb, &tag);
if (tag == MP4DecSpecificDescrTag) {
av_dlog(fc, "Specific MPEG4 header len=%d\n", len);
- if((uint64_t)len > (1<<30))
+ if (!len || (uint64_t)len > (1<<30))
return -1;
av_free(st->codec->extradata);
st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -405,11 +421,11 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext
st->codec->extradata_size = len;
if (st->codec->codec_id == CODEC_ID_AAC) {
MPEG4AudioConfig cfg;
- ff_mpeg4audio_get_config(&cfg, st->codec->extradata,
- st->codec->extradata_size);
+ avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
+ st->codec->extradata_size * 8, 1);
st->codec->channels = cfg.channels;
if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4
- st->codec->sample_rate = ff_mpa_freq_tab[cfg.sampling_index];
+ st->codec->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index];
else if (cfg.ext_sample_rate)
st->codec->sample_rate = cfg.ext_sample_rate;
else
diff --git a/libavformat/isom.h b/libavformat/isom.h
index ef3fe14..e6d04dc 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -146,11 +146,14 @@ typedef struct MOVContext {
int ff_mp4_read_descr_len(AVIOContext *pb);
int ff_mp4_read_descr(AVFormatContext *fc, AVIOContext *pb, int *tag);
int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb);
+void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id);
+#define MP4ODescrTag 0x01
#define MP4IODescrTag 0x02
#define MP4ESDescrTag 0x03
#define MP4DecConfigDescrTag 0x04
#define MP4DecSpecificDescrTag 0x05
+#define MP4SLDescrTag 0x06
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom);
enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags);
diff --git a/libavformat/iss.c b/libavformat/iss.c
index fe5203d..ec6509c 100644
--- a/libavformat/iss.c
+++ b/libavformat/iss.c
@@ -23,11 +23,11 @@
* @file
* Funcom ISS file demuxer
* @author Jaikrishnan Menon
- * for more information on the .iss file format, visit:
- * http://wiki.multimedia.cx/index.php?title=FunCom_ISS
+ * @see http://wiki.multimedia.cx/index.php?title=FunCom_ISS
*/
#include "avformat.h"
+#include "internal.h"
#include "libavutil/avstring.h"
#define ISS_SIG "IMA_ADPCM_Sound"
@@ -89,7 +89,7 @@ static av_cold int iss_read_header(AVFormatContext *s, AVFormatParameters *ap)
iss->sample_start_pos = avio_tell(pb);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -102,7 +102,7 @@ static av_cold int iss_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->bit_rate = st->codec->channels * st->codec->sample_rate
* st->codec->bits_per_coded_sample;
st->codec->block_align = iss->packet_size;
- av_set_pts_info(st, 32, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);
return 0;
}
@@ -123,11 +123,11 @@ static int iss_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_iss_demuxer = {
- "ISS",
- NULL_IF_CONFIG_SMALL("Funcom ISS format"),
- sizeof(IssDemuxContext),
- iss_probe,
- iss_read_header,
- iss_read_packet,
+ .name = "ISS",
+ .long_name = NULL_IF_CONFIG_SMALL("Funcom ISS format"),
+ .priv_data_size = sizeof(IssDemuxContext),
+ .read_probe = iss_probe,
+ .read_header = iss_read_header,
+ .read_packet = iss_read_packet,
};
diff --git a/libavformat/iv8.c b/libavformat/iv8.c
index 22e60cf..4f25441 100644
--- a/libavformat/iv8.c
+++ b/libavformat/iv8.c
@@ -19,11 +19,12 @@
*/
#include "avformat.h"
+#include "internal.h"
static int probe(AVProbeData *p)
{
- // the single file i have starts with that, i dont know if others do too
+ // the single file I have starts with that, I do not know if others do, too
if( p->buf[0] == 1
&& p->buf[1] == 1
&& p->buf[2] == 3
@@ -40,14 +41,14 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
{
AVStream *st;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_MPEG4;
st->need_parsing = AVSTREAM_PARSE_FULL;
- av_set_pts_info(st, 64, 1, 90000);
+ avpriv_set_pts_info(st, 64, 1, 90000);
return 0;
@@ -55,42 +56,64 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
- int ret, size, pts, type;
-retry:
- type= avio_rb16(s->pb); // 257 or 258
- size= avio_rb16(s->pb);
-
- avio_rb16(s->pb); //some flags, 0x80 indicates end of frame
- avio_rb16(s->pb); //packet number
- pts=avio_rb32(s->pb);
- avio_rb32(s->pb); //6A 13 E3 88
-
- size -= 12;
- if(size<1)
- return -1;
-
- if(type==258){
- avio_skip(s->pb, size);
- goto retry;
+ int ret, size, pts, type, flags;
+ int first_pkt = 0;
+ int frame_complete = 0;
+
+ while (!frame_complete) {
+
+ type = avio_rb16(s->pb); // 257 or 258
+ size = avio_rb16(s->pb);
+ flags = avio_rb16(s->pb); //some flags, 0x80 indicates end of frame
+ avio_rb16(s->pb); //packet number
+ pts = avio_rb32(s->pb);
+ avio_rb32(s->pb); //6A 13 E3 88
+
+ frame_complete = flags & 0x80;
+
+ size -= 12;
+ if (size < 1)
+ return -1;
+
+ if (type == 258) {
+ avio_skip(s->pb, size);
+ frame_complete = 0;
+ continue;
+ }
+
+ if (!first_pkt) {
+ ret = av_get_packet(s->pb, pkt, size);
+ if (ret < 0)
+ return ret;
+ first_pkt = 1;
+ pkt->pts = pts;
+ pkt->pos -= 16;
+ } else {
+ ret = av_append_packet(s->pb, pkt, size);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "failed to grow packet\n");
+ av_free_packet(pkt);
+ return ret;
+ }
+ }
+ if (ret < size) {
+ av_log(s, AV_LOG_ERROR, "Truncated packet! Read %d of %d bytes\n",
+ ret, size);
+ pkt->flags |= AV_PKT_FLAG_CORRUPT;
+ break;
+ }
}
-
- ret= av_get_packet(s->pb, pkt, size);
-
- pkt->pts= pts;
- pkt->pos-=16;
-
pkt->stream_index = 0;
- return ret;
+ return 0;
}
AVInputFormat ff_iv8_demuxer = {
- "iv8",
- NULL_IF_CONFIG_SMALL("A format generated by IndigoVision 8000 video server"),
- 0,
- probe,
- read_header,
- read_packet,
+ .name = "iv8",
+ .long_name = NULL_IF_CONFIG_SMALL("A format generated by IndigoVision 8000 video server"),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
.flags= AVFMT_GENERIC_INDEX,
.value = CODEC_ID_MPEG4,
};
diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c
index 3901731..03f7995 100644
--- a/libavformat/ivfdec.c
+++ b/libavformat/ivfdec.c
@@ -19,6 +19,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
#include "libavutil/intreadwrite.h"
@@ -40,7 +41,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_rl16(s->pb); // version
avio_rl16(s->pb); // header size
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -61,7 +62,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
return AVERROR_INVALIDDATA;
}
- av_set_pts_info(st, 64, time_base.num, time_base.den);
+ avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
return 0;
}
@@ -80,12 +81,11 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_ivf_demuxer = {
- "ivf",
- NULL_IF_CONFIG_SMALL("On2 IVF"),
- 0,
- probe,
- read_header,
- read_packet,
+ .name = "ivf",
+ .long_name = NULL_IF_CONFIG_SMALL("On2 IVF"),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
.flags= AVFMT_GENERIC_INDEX,
.codec_tag = (const AVCodecTag*[]){ff_codec_bmp_tags, 0},
};
diff --git a/libavformat/jvdec.c b/libavformat/jvdec.c
index d4008f7..c24b0c2 100644
--- a/libavformat/jvdec.c
+++ b/libavformat/jvdec.c
@@ -27,6 +27,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define JV_PREAMBLE_SIZE 5
@@ -69,8 +70,8 @@ static int read_header(AVFormatContext *s,
avio_skip(pb, 80);
- ast = av_new_stream(s, 0);
- vst = av_new_stream(s, 1);
+ ast = avformat_new_stream(s, NULL);
+ vst = avformat_new_stream(s, NULL);
if (!ast || !vst)
return AVERROR(ENOMEM);
@@ -81,7 +82,7 @@ static int read_header(AVFormatContext *s,
vst->codec->height = avio_rl16(pb);
vst->nb_frames =
ast->nb_index_entries = avio_rl16(pb);
- av_set_pts_info(vst, 64, avio_rl16(pb), 1000);
+ avpriv_set_pts_info(vst, 64, avio_rl16(pb), 1000);
avio_skip(pb, 4);
@@ -90,7 +91,7 @@ static int read_header(AVFormatContext *s,
ast->codec->codec_tag = 0; /* no fourcc */
ast->codec->sample_rate = avio_rl16(pb);
ast->codec->channels = 1;
- av_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
+ avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
avio_skip(pb, 10);
diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c
new file mode 100644
index 0000000..423710d
--- /dev/null
+++ b/libavformat/latmenc.c
@@ -0,0 +1,191 @@
+/*
+ * LATM/LOAS muxer
+ * Copyright (c) 2011 Kieran Kunhya <kieran at kunhya.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavcodec/get_bits.h"
+#include "libavcodec/put_bits.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/mpeg4audio.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+
+typedef struct {
+ AVClass *av_class;
+ int off;
+ int channel_conf;
+ int object_type;
+ int counter;
+ int mod;
+} LATMContext;
+
+static const AVOption options[] = {
+ {"smc-interval", "StreamMuxConfig interval.",
+ offsetof(LATMContext, mod), AV_OPT_TYPE_INT, {.dbl = 0x0014}, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
+ {NULL},
+};
+
+static const AVClass latm_muxer_class = {
+ .class_name = "LATM/LOAS muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static int latm_decode_extradata(LATMContext *ctx, uint8_t *buf, int size)
+{
+ GetBitContext gb;
+ MPEG4AudioConfig m4ac;
+
+ init_get_bits(&gb, buf, size * 8);
+ ctx->off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1);
+ if (ctx->off < 0)
+ return ctx->off;
+ skip_bits_long(&gb, ctx->off);
+
+ /* FIXME: are any formats not allowed in LATM? */
+
+ if (m4ac.object_type > AOT_SBR && m4ac.object_type != AOT_ALS) {
+ av_log(ctx, AV_LOG_ERROR, "Muxing MPEG-4 AOT %d in LATM is not supported\n", m4ac.object_type);
+ return AVERROR_INVALIDDATA;
+ }
+ ctx->channel_conf = m4ac.chan_config;
+ ctx->object_type = m4ac.object_type;
+
+ return 0;
+}
+
+static int latm_write_header(AVFormatContext *s)
+{
+ LATMContext *ctx = s->priv_data;
+ AVCodecContext *avctx = s->streams[0]->codec;
+
+ if (avctx->extradata_size > 0 &&
+ latm_decode_extradata(ctx, avctx->extradata, avctx->extradata_size) < 0)
+ return AVERROR_INVALIDDATA;
+
+ return 0;
+}
+
+static int latm_write_frame_header(AVFormatContext *s, PutBitContext *bs)
+{
+ LATMContext *ctx = s->priv_data;
+ AVCodecContext *avctx = s->streams[0]->codec;
+ GetBitContext gb;
+ int header_size;
+
+ /* AudioMuxElement */
+ put_bits(bs, 1, !!ctx->counter);
+
+ if (!ctx->counter) {
+ init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
+
+ /* StreamMuxConfig */
+ put_bits(bs, 1, 0); /* audioMuxVersion */
+ put_bits(bs, 1, 1); /* allStreamsSameTimeFraming */
+ put_bits(bs, 6, 0); /* numSubFrames */
+ put_bits(bs, 4, 0); /* numProgram */
+ put_bits(bs, 3, 0); /* numLayer */
+
+ /* AudioSpecificConfig */
+ if (ctx->object_type == AOT_ALS) {
+ header_size = avctx->extradata_size-(ctx->off + 7) >> 3;
+ avpriv_copy_bits(bs, &avctx->extradata[ctx->off], header_size);
+ } else {
+ avpriv_copy_bits(bs, avctx->extradata, ctx->off + 3);
+
+ if (!ctx->channel_conf) {
+ avpriv_copy_pce_data(bs, &gb);
+ }
+ }
+
+ put_bits(bs, 3, 0); /* frameLengthType */
+ put_bits(bs, 8, 0xff); /* latmBufferFullness */
+
+ put_bits(bs, 1, 0); /* otherDataPresent */
+ put_bits(bs, 1, 0); /* crcCheckPresent */
+ }
+
+ ctx->counter++;
+ ctx->counter %= ctx->mod;
+
+ return 0;
+}
+
+static int latm_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ AVIOContext *pb = s->pb;
+ PutBitContext bs;
+ int i, len;
+ uint8_t loas_header[] = "\x56\xe0\x00";
+ uint8_t *buf;
+
+ if (pkt->size > 2 && pkt->data[0] == 0xff && (pkt->data[1] >> 4) == 0xf) {
+ av_log(s, AV_LOG_ERROR, "ADTS header detected - ADTS will not be incorrectly muxed into LATM\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ buf = av_malloc(pkt->size+1024);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ init_put_bits(&bs, buf, pkt->size+1024);
+
+ latm_write_frame_header(s, &bs);
+
+ /* PayloadLengthInfo() */
+ for (i = 0; i <= pkt->size-255; i+=255)
+ put_bits(&bs, 8, 255);
+
+ put_bits(&bs, 8, pkt->size-i);
+
+ /* The LATM payload is written unaligned */
+
+ /* PayloadMux() */
+ for (i = 0; i < pkt->size; i++)
+ put_bits(&bs, 8, pkt->data[i]);
+
+ avpriv_align_put_bits(&bs);
+ flush_put_bits(&bs);
+
+ len = put_bits_count(&bs) >> 3;
+
+ loas_header[1] |= (len >> 8) & 0x1f;
+ loas_header[2] |= len & 0xff;
+
+ avio_write(pb, loas_header, 3);
+ avio_write(pb, buf, len);
+
+ av_free(buf);
+
+ return 0;
+}
+
+AVOutputFormat ff_latm_muxer = {
+ .name = "latm",
+ .long_name = NULL_IF_CONFIG_SMALL("LOAS/LATM"),
+ .mime_type = "audio/MP4A-LATM",
+ .extensions = "latm",
+ .priv_data_size = sizeof(LATMContext),
+ .audio_codec = CODEC_ID_AAC,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = latm_write_header,
+ .write_packet = latm_write_packet,
+ .priv_class = &latm_muxer_class,
+};
diff --git a/libavformat/libavformat.v b/libavformat/libavformat.v
index 0ec1c3c..c5dc982 100644
--- a/libavformat/libavformat.v
+++ b/libavformat/libavformat.v
@@ -1,7 +1,29 @@
LIBAVFORMAT_$MAJOR {
- global: *;
- local:
- ff_*_demuxer;
- ff_*_muxer;
- ff_*_protocol;
+ global: av*;
+ #FIXME those are for avserver
+ ff_inet_aton;
+ ff_socket_nonblock;
+ ffm_set_write_index;
+ ffm_read_write_index;
+ ffm_write_write_index;
+ ff_rtsp_parse_line;
+ ff_rtp_get_local_rtp_port;
+ ff_rtp_get_local_rtcp_port;
+ ffio_open_dyn_packet_buf;
+ url_open;
+ url_close;
+ url_write;
+ url_get_max_packet_size;
+ #those are deprecated, remove on next bump
+ find_info_tag;
+ parse_date;
+ dump_format;
+ url_*;
+ get_*;
+ put_*;
+ udp_set_remote_url;
+ udp_get_local_port;
+ init_checksum;
+ init_put_byte;
+ local: *;
};
diff --git a/libavformat/libnut.c b/libavformat/libnut.c
index 76a621a..56e8bfc 100644
--- a/libavformat/libnut.c
+++ b/libavformat/libnut.c
@@ -26,6 +26,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
#include <libnut.h>
@@ -92,7 +93,7 @@ static int nut_write_header(AVFormatContext * avf) {
for (j = 0; j < s[i].fourcc_len; j++) s[i].fourcc[j] = (fourcc >> (j*8)) & 0xFF;
ff_parse_specific_params(codec, &num, &ssize, &denom);
- av_set_pts_info(avf->streams[i], 60, denom, num);
+ avpriv_set_pts_info(avf->streams[i], 60, denom, num);
s[i].time_base.num = denom;
s[i].time_base.den = num;
@@ -151,16 +152,16 @@ static int nut_write_trailer(AVFormatContext * avf) {
}
AVOutputFormat ff_libnut_muxer = {
- "libnut",
- "nut format",
- "video/x-nut",
- "nut",
- sizeof(NUTContext),
- CODEC_ID_VORBIS,
- CODEC_ID_MPEG4,
- nut_write_header,
- nut_write_packet,
- nut_write_trailer,
+ .name = "libnut",
+ .long_name = "nut format",
+ .mime_type = "video/x-nut",
+ .extensions = "nut",
+ .priv_data_size = sizeof(NUTContext),
+ .audio_codec = CODEC_ID_VORBIS,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = nut_write_header,
+ .write_packet = nut_write_packet,
+ .write_trailer = nut_write_trailer,
.flags = AVFMT_GLOBALHEADER,
};
#endif /* CONFIG_LIBNUT_MUXER */
@@ -213,7 +214,7 @@ static int nut_read_header(AVFormatContext * avf, AVFormatParameters * ap) {
priv->s = s;
for (i = 0; s[i].type != -1 && i < 2; i++) {
- AVStream * st = av_new_stream(avf, i);
+ AVStream * st = avformat_new_stream(avf, NULL);
int j;
for (j = 0; j < s[i].fourcc_len && j < 8; j++) st->codec->codec_tag |= s[i].fourcc[j]<<(j*8);
@@ -226,7 +227,7 @@ static int nut_read_header(AVFormatContext * avf, AVFormatParameters * ap) {
memcpy(st->codec->extradata, s[i].codec_specific, st->codec->extradata_size);
}
- av_set_pts_info(avf->streams[i], 60, s[i].time_base.num, s[i].time_base.den);
+ avpriv_set_pts_info(avf->streams[i], 60, s[i].time_base.num, s[i].time_base.den);
st->start_time = 0;
st->duration = s[i].max_pts;
@@ -298,13 +299,13 @@ static int nut_read_close(AVFormatContext *s) {
}
AVInputFormat ff_libnut_demuxer = {
- "libnut",
- NULL_IF_CONFIG_SMALL("NUT format"),
- sizeof(NUTContext),
- nut_probe,
- nut_read_header,
- nut_read_packet,
- nut_read_close,
- nut_read_seek,
+ .name = "libnut",
+ .long_name = NULL_IF_CONFIG_SMALL("NUT format"),
+ .priv_data_size = sizeof(NUTContext),
+ .read_probe = nut_probe,
+ .read_header = nut_read_header,
+ .read_packet = nut_read_packet,
+ .read_close = nut_read_close,
+ .read_seek = nut_read_seek,
.extensions = "nut",
};
diff --git a/libavformat/librtmp.c b/libavformat/librtmp.c
index 30fe8a1..c04c833 100644
--- a/libavformat/librtmp.c
+++ b/libavformat/librtmp.c
@@ -24,6 +24,7 @@
* RTMP protocol based on http://rtmpdump.mplayerhq.hu/ librtmp
*/
+#include "libavutil/mathematics.h"
#include "avformat.h"
#include "url.h"
@@ -51,7 +52,6 @@ static int rtmp_close(URLContext *s)
RTMP *r = s->priv_data;
RTMP_Close(r);
- av_free(r);
return 0;
}
@@ -69,13 +69,9 @@ static int rtmp_close(URLContext *s)
*/
static int rtmp_open(URLContext *s, const char *uri, int flags)
{
- RTMP *r;
+ RTMP *r = s->priv_data;
int rc;
- r = av_mallocz(sizeof(RTMP));
- if (!r)
- return AVERROR(ENOMEM);
-
switch (av_log_get_level()) {
default:
case AV_LOG_FATAL: rc = RTMP_LOGCRIT; break;
@@ -102,11 +98,9 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
goto fail;
}
- s->priv_data = r;
s->is_streamed = 1;
return 0;
fail:
- av_free(r);
return rc;
}
@@ -166,7 +160,8 @@ URLProtocol ff_rtmp_protocol = {
.url_close = rtmp_close,
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
- .url_get_file_handle = rtmp_get_file_handle
+ .url_get_file_handle = rtmp_get_file_handle,
+ .priv_data_size = sizeof(RTMP),
};
URLProtocol ff_rtmpt_protocol = {
@@ -177,7 +172,8 @@ URLProtocol ff_rtmpt_protocol = {
.url_close = rtmp_close,
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
- .url_get_file_handle = rtmp_get_file_handle
+ .url_get_file_handle = rtmp_get_file_handle,
+ .priv_data_size = sizeof(RTMP),
};
URLProtocol ff_rtmpe_protocol = {
@@ -188,7 +184,8 @@ URLProtocol ff_rtmpe_protocol = {
.url_close = rtmp_close,
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
- .url_get_file_handle = rtmp_get_file_handle
+ .url_get_file_handle = rtmp_get_file_handle,
+ .priv_data_size = sizeof(RTMP),
};
URLProtocol ff_rtmpte_protocol = {
@@ -199,7 +196,8 @@ URLProtocol ff_rtmpte_protocol = {
.url_close = rtmp_close,
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
- .url_get_file_handle = rtmp_get_file_handle
+ .url_get_file_handle = rtmp_get_file_handle,
+ .priv_data_size = sizeof(RTMP),
};
URLProtocol ff_rtmps_protocol = {
@@ -210,5 +208,6 @@ URLProtocol ff_rtmps_protocol = {
.url_close = rtmp_close,
.url_read_pause = rtmp_read_pause,
.url_read_seek = rtmp_read_seek,
- .url_get_file_handle = rtmp_get_file_handle
+ .url_get_file_handle = rtmp_get_file_handle,
+ .priv_data_size = sizeof(RTMP),
};
diff --git a/libavformat/lmlm4.c b/libavformat/lmlm4.c
index eafc1b6..5f26c4b 100644
--- a/libavformat/lmlm4.c
+++ b/libavformat/lmlm4.c
@@ -24,6 +24,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define LMLM4_I_FRAME 0x00
#define LMLM4_P_FRAME 0x01
@@ -60,14 +61,14 @@ static int lmlm4_probe(AVProbeData * pd) {
static int lmlm4_read_header(AVFormatContext *s, AVFormatParameters *ap) {
AVStream *st;
- if (!(st = av_new_stream(s, 0)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_MPEG4;
st->need_parsing = AVSTREAM_PARSE_HEADERS;
- av_set_pts_info(st, 64, 1001, 30000);
+ avpriv_set_pts_info(st, 64, 1001, 30000);
- if (!(st = av_new_stream(s, 1)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_MP2;
@@ -118,10 +119,9 @@ static int lmlm4_read_packet(AVFormatContext *s, AVPacket *pkt) {
}
AVInputFormat ff_lmlm4_demuxer = {
- "lmlm4",
- NULL_IF_CONFIG_SMALL("lmlm4 raw format"),
- 0,
- lmlm4_probe,
- lmlm4_read_header,
- lmlm4_read_packet,
+ .name = "lmlm4",
+ .long_name = NULL_IF_CONFIG_SMALL("lmlm4 raw format"),
+ .read_probe = lmlm4_probe,
+ .read_header = lmlm4_read_header,
+ .read_packet = lmlm4_read_packet,
};
diff --git a/libavformat/lxfdec.c b/libavformat/lxfdec.c
index 0f7e426..b3afa7e 100644
--- a/libavformat/lxfdec.c
+++ b/libavformat/lxfdec.c
@@ -21,6 +21,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
#define LXF_PACKET_HEADER_SIZE 60
@@ -174,14 +175,14 @@ static int get_packet_header(AVFormatContext *s, uint8_t *header, uint32_t *form
//use audio packet size to determine video standard
//for NTSC we have one 8008-sample audio frame per five video frames
if (samples == LXF_SAMPLERATE * 5005 / 30000) {
- av_set_pts_info(s->streams[0], 64, 1001, 30000);
+ avpriv_set_pts_info(s->streams[0], 64, 1001, 30000);
} else {
//assume PAL, but warn if we don't have 1920 samples
if (samples != LXF_SAMPLERATE / 25)
av_log(s, AV_LOG_WARNING,
"video doesn't seem to be PAL or NTSC. guessing PAL\n");
- av_set_pts_info(s->streams[0], 64, 1, 25);
+ avpriv_set_pts_info(s->streams[0], 64, 1, 25);
}
//TODO: warning if track mask != (1 << channels) - 1?
@@ -217,7 +218,7 @@ static int lxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
if ((ret = avio_read(pb, header_data, LXF_HEADER_DATA_SIZE)) != LXF_HEADER_DATA_SIZE)
return ret < 0 ? ret : AVERROR_EOF;
- if (!(st = av_new_stream(s, 0)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->duration = AV_RL32(&header_data[32]);
@@ -243,14 +244,14 @@ static int lxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
av_log(s, AV_LOG_WARNING, "VBI data not yet supported\n");
if ((lxf->channels = (disk_params >> 2) & 0xF)) {
- if (!(st = av_new_stream(s, 1)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->sample_rate = LXF_SAMPLERATE;
st->codec->channels = lxf->channels;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
}
if (format == 1) {
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 59dce4f..2684d6e 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -22,10 +22,10 @@
/**
* @file
* Matroska file demuxer
- * by Ronald Bultje <rbultje at ronald.bitfreak.net>
- * with a little help from Moritz Bunkus <moritz at bunkus.org>
- * totally reworked by Aurelien Jacobs <aurel at gnuage.org>
- * Specs available on the Matroska project page: http://www.matroska.org/.
+ * @author Ronald Bultje <rbultje at ronald.bitfreak.net>
+ * @author with a little help from Moritz Bunkus <moritz at bunkus.org>
+ * @author totally reworked by Aurelien Jacobs <aurel at gnuage.org>
+ * @see specs available on the Matroska project page: http://www.matroska.org/
*/
#include <stdio.h>
@@ -38,7 +38,7 @@
#include "rm.h"
#include "matroska.h"
#include "libavcodec/mpeg4audio.h"
-#include "libavutil/intfloat_readwrite.h"
+#include "libavutil/intfloat.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
#include "libavutil/lzo.h"
@@ -244,6 +244,9 @@ typedef struct {
/* What to skip before effectively reading a packet. */
int skip_to_keyframe;
uint64_t skip_to_timecode;
+
+ /* File has a CUES element, but we defer parsing until it is needed. */
+ int cues_parsing_deferred;
} MatroskaDemuxContext;
typedef struct {
@@ -621,9 +624,9 @@ static int ebml_read_float(AVIOContext *pb, int size, double *num)
if (size == 0) {
*num = 0;
} else if (size == 4) {
- *num= av_int2flt(avio_rb32(pb));
- } else if(size==8){
- *num= av_int2dbl(avio_rb64(pb));
+ *num = av_int2float(avio_rb32(pb));
+ } else if (size == 8){
+ *num = av_int2double(avio_rb64(pb));
} else
return AVERROR_INVALIDDATA;
@@ -1131,7 +1134,7 @@ static void matroska_convert_tags(AVFormatContext *s)
}
}
-static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
+static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, int idx)
{
EbmlList *seekhead_list = &matroska->seekhead;
MatroskaSeekhead *seekhead = seekhead_list->elem;
@@ -1139,6 +1142,54 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
int64_t before_pos = avio_tell(matroska->ctx->pb);
uint32_t saved_id = matroska->current_id;
MatroskaLevel level;
+ int64_t offset;
+ int ret = 0;
+
+ if (idx >= seekhead_list->nb_elem
+ || seekhead[idx].id == MATROSKA_ID_SEEKHEAD
+ || seekhead[idx].id == MATROSKA_ID_CLUSTER)
+ return 0;
+
+ /* seek */
+ offset = seekhead[idx].pos + matroska->segment_start;
+ if (avio_seek(matroska->ctx->pb, offset, SEEK_SET) == offset) {
+ /* We don't want to lose our seekhead level, so we add
+ * a dummy. This is a crude hack. */
+ if (matroska->num_levels == EBML_MAX_DEPTH) {
+ av_log(matroska->ctx, AV_LOG_INFO,
+ "Max EBML element depth (%d) reached, "
+ "cannot parse further.\n", EBML_MAX_DEPTH);
+ ret = AVERROR_INVALIDDATA;
+ } else {
+ level.start = 0;
+ level.length = (uint64_t)-1;
+ matroska->levels[matroska->num_levels] = level;
+ matroska->num_levels++;
+ matroska->current_id = 0;
+
+ ret = ebml_parse(matroska, matroska_segment, matroska);
+
+ /* remove dummy level */
+ while (matroska->num_levels) {
+ uint64_t length = matroska->levels[--matroska->num_levels].length;
+ if (length == (uint64_t)-1)
+ break;
+ }
+ }
+ }
+ /* seek back */
+ avio_seek(matroska->ctx->pb, before_pos, SEEK_SET);
+ matroska->level_up = level_up;
+ matroska->current_id = saved_id;
+
+ return ret;
+}
+
+static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
+{
+ EbmlList *seekhead_list = &matroska->seekhead;
+ MatroskaSeekhead *seekhead = seekhead_list->elem;
+ int64_t before_pos = avio_tell(matroska->ctx->pb);
int i;
// we should not do any seeking in the streaming case
@@ -1146,47 +1197,55 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
(matroska->ctx->flags & AVFMT_FLAG_IGNIDX))
return;
- for (i=0; i<seekhead_list->nb_elem; i++) {
- int64_t offset = seekhead[i].pos + matroska->segment_start;
-
- if (seekhead[i].pos <= before_pos
- || seekhead[i].id == MATROSKA_ID_SEEKHEAD
- || seekhead[i].id == MATROSKA_ID_CLUSTER)
+ for (i = 0; i < seekhead_list->nb_elem; i++) {
+ if (seekhead[i].pos <= before_pos)
continue;
- /* seek */
- if (avio_seek(matroska->ctx->pb, offset, SEEK_SET) != offset)
+ // defer cues parsing until we actually need cue data.
+ if (seekhead[i].id == MATROSKA_ID_CUES) {
+ matroska->cues_parsing_deferred = 1;
continue;
+ }
- /* We don't want to lose our seekhead level, so we add
- * a dummy. This is a crude hack. */
- if (matroska->num_levels == EBML_MAX_DEPTH) {
- av_log(matroska->ctx, AV_LOG_INFO,
- "Max EBML element depth (%d) reached, "
- "cannot parse further.\n", EBML_MAX_DEPTH);
+ if (matroska_parse_seekhead_entry(matroska, i) < 0)
break;
- }
+ }
+}
- level.start = 0;
- level.length = (uint64_t)-1;
- matroska->levels[matroska->num_levels] = level;
- matroska->num_levels++;
- matroska->current_id = 0;
+static void matroska_parse_cues(MatroskaDemuxContext *matroska) {
+ EbmlList *seekhead_list = &matroska->seekhead;
+ MatroskaSeekhead *seekhead = seekhead_list->elem;
+ EbmlList *index_list;
+ MatroskaIndex *index;
+ int index_scale = 1;
+ int i, j;
- ebml_parse(matroska, matroska_segment, matroska);
+ for (i = 0; i < seekhead_list->nb_elem; i++)
+ if (seekhead[i].id == MATROSKA_ID_CUES)
+ break;
+ assert(i <= seekhead_list->nb_elem);
- /* remove dummy level */
- while (matroska->num_levels) {
- uint64_t length = matroska->levels[--matroska->num_levels].length;
- if (length == (uint64_t)-1)
- break;
+ matroska_parse_seekhead_entry(matroska, i);
+
+ index_list = &matroska->index;
+ index = index_list->elem;
+ if (index_list->nb_elem
+ && index[0].time > 1E14/matroska->time_scale) {
+ av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n");
+ index_scale = matroska->time_scale;
+ }
+ for (i = 0; i < index_list->nb_elem; i++) {
+ EbmlList *pos_list = &index[i].pos;
+ MatroskaIndexPos *pos = pos_list->elem;
+ for (j = 0; j < pos_list->nb_elem; j++) {
+ MatroskaTrack *track = matroska_find_track_by_num(matroska, pos[j].track);
+ if (track && track->stream)
+ av_add_index_entry(track->stream,
+ pos[j].pos + matroska->segment_start,
+ index[i].time/index_scale, 0, 0,
+ AVINDEX_KEYFRAME);
}
}
-
- /* seek back */
- avio_seek(matroska->ctx->pb, before_pos, SEEK_SET);
- matroska->level_up = level_up;
- matroska->current_id = saved_id;
}
static int matroska_aac_profile(char *codec_id)
@@ -1204,8 +1263,8 @@ static int matroska_aac_sri(int samplerate)
{
int sri;
- for (sri=0; sri<FF_ARRAY_ELEMS(ff_mpeg4audio_sample_rates); sri++)
- if (ff_mpeg4audio_sample_rates[sri] == samplerate)
+ for (sri=0; sri<FF_ARRAY_ELEMS(avpriv_mpeg4audio_sample_rates); sri++)
+ if (avpriv_mpeg4audio_sample_rates[sri] == samplerate)
break;
return sri;
}
@@ -1218,9 +1277,6 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
EbmlList *chapters_list = &matroska->chapters;
MatroskaChapter *chapters;
MatroskaTrack *tracks;
- EbmlList *index_list;
- MatroskaIndex *index;
- int index_scale = 1;
uint64_t max_start = 0;
Ebml ebml = { 0 };
AVStream *st;
@@ -1295,7 +1351,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
if (encodings_list->nb_elem > 1) {
av_log(matroska->ctx, AV_LOG_ERROR,
- "Multiple combined encodings no supported");
+ "Multiple combined encodings not supported");
} else if (encodings_list->nb_elem == 1) {
if (encodings[0].type ||
(encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP &&
@@ -1340,7 +1396,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
}
- st = track->stream = av_new_stream(s, 0);
+ st = track->stream = avformat_new_stream(s, NULL);
if (st == NULL)
return AVERROR(ENOMEM);
@@ -1450,7 +1506,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (track->time_scale < 0.01)
track->time_scale = 1.0;
- av_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */
+ avpriv_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */
st->codec->codec_id = codec_id;
st->start_time = 0;
@@ -1463,10 +1519,6 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (track->flag_forced)
st->disposition |= AV_DISPOSITION_FORCED;
- if (track->default_duration)
- av_reduce(&st->codec->time_base.num, &st->codec->time_base.den,
- track->default_duration, 1000000000, 30000);
-
if (!st->codec->extradata) {
if(extradata){
st->codec->extradata = extradata;
@@ -1514,10 +1566,11 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
attachements[j].bin.data && attachements[j].bin.size > 0)) {
av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n");
} else {
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (st == NULL)
break;
av_dict_set(&st->metadata, "filename",attachements[j].filename, 0);
+ av_dict_set(&st->metadata, "mimetype", attachements[j].mime, 0);
st->codec->codec_id = CODEC_ID_NONE;
st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
st->codec->extradata = av_malloc(attachements[j].bin.size);
@@ -1542,7 +1595,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid
&& (max_start==0 || chapters[i].start > max_start)) {
chapters[i].chapter =
- ff_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000},
+ avpriv_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000},
chapters[i].start, chapters[i].end,
chapters[i].title);
av_dict_set(&chapters[i].chapter->metadata,
@@ -1550,27 +1603,6 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
max_start = chapters[i].start;
}
- index_list = &matroska->index;
- index = index_list->elem;
- if (index_list->nb_elem
- && index[0].time > 100000000000000/matroska->time_scale) {
- av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n");
- index_scale = matroska->time_scale;
- }
- for (i=0; i<index_list->nb_elem; i++) {
- EbmlList *pos_list = &index[i].pos;
- MatroskaIndexPos *pos = pos_list->elem;
- for (j=0; j<pos_list->nb_elem; j++) {
- MatroskaTrack *track = matroska_find_track_by_num(matroska,
- pos[j].track);
- if (track && track->stream)
- av_add_index_entry(track->stream,
- pos[j].pos + matroska->segment_start,
- index[i].time/index_scale, 0, 0,
- AVINDEX_KEYFRAME);
- }
- }
-
matroska_convert_tags(s);
return 0;
@@ -1643,11 +1675,12 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
size -= n;
track = matroska_find_track_by_num(matroska, num);
- if (size <= 3 || !track || !track->stream) {
+ if (!track || !track->stream) {
av_log(matroska->ctx, AV_LOG_INFO,
"Invalid stream %"PRIu64" or size %u\n", num, size);
- return res;
- }
+ return AVERROR_INVALIDDATA;
+ } else if (size <= 3)
+ return 0;
st = track->stream;
if (st->discard >= AVDISCARD_ALL)
return res;
@@ -1747,7 +1780,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
lace_size[n] = lace_size[n - 1] + snum;
total += lace_size[n];
}
- lace_size[n] = size - total;
+ lace_size[laces - 1] = size - total;
break;
}
}
@@ -1883,7 +1916,7 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
res = ebml_parse(matroska, matroska_clusters, &cluster);
blocks_list = &cluster.blocks;
blocks = blocks_list->elem;
- for (i=0; i<blocks_list->nb_elem; i++)
+ for (i=0; i<blocks_list->nb_elem && !res; i++)
if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
if (!blocks[i].non_simple)
@@ -1902,14 +1935,15 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
{
MatroskaDemuxContext *matroska = s->priv_data;
+ int ret = 0;
- while (matroska_deliver_packet(matroska, pkt)) {
+ while (!ret && matroska_deliver_packet(matroska, pkt)) {
if (matroska->done)
return AVERROR_EOF;
- matroska_parse_cluster(matroska);
+ ret = matroska_parse_cluster(matroska);
}
- return 0;
+ return ret;
}
static int matroska_read_seek(AVFormatContext *s, int stream_index,
@@ -1920,6 +1954,12 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
AVStream *st = s->streams[stream_index];
int i, index, index_sub, index_min;
+ /* Parse the CUES now since we need the index data to seek. */
+ if (matroska->cues_parsing_deferred) {
+ matroska_parse_cues(matroska);
+ matroska->cues_parsing_deferred = 0;
+ }
+
if (!st->nb_index_entries)
return 0;
timestamp = FFMAX(timestamp, st->index_entries[0].timestamp);
@@ -1959,7 +1999,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
matroska->skip_to_keyframe = !(flags & AVSEEK_FLAG_ANY);
matroska->skip_to_timecode = st->index_entries[index].timestamp;
matroska->done = 0;
- av_update_cur_dts(s, st, st->index_entries[index].timestamp);
+ ff_update_cur_dts(s, st, st->index_entries[index].timestamp);
return 0;
}
@@ -1980,12 +2020,12 @@ static int matroska_read_close(AVFormatContext *s)
}
AVInputFormat ff_matroska_demuxer = {
- "matroska,webm",
- NULL_IF_CONFIG_SMALL("Matroska/WebM file format"),
- sizeof(MatroskaDemuxContext),
- matroska_probe,
- matroska_read_header,
- matroska_read_packet,
- matroska_read_close,
- matroska_read_seek,
+ .name = "matroska,webm",
+ .long_name = NULL_IF_CONFIG_SMALL("Matroska/WebM file format"),
+ .priv_data_size = sizeof(MatroskaDemuxContext),
+ .read_probe = matroska_probe,
+ .read_header = matroska_read_header,
+ .read_packet = matroska_read_packet,
+ .read_close = matroska_read_close,
+ .read_seek = matroska_read_seek,
};
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index fde1470..e93dd65 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -20,6 +20,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
#include "isom.h"
#include "matroska.h"
@@ -28,12 +29,14 @@
#include "avlanguage.h"
#include "libavutil/samplefmt.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
+#include "libavutil/mathematics.h"
#include "libavutil/random_seed.h"
#include "libavutil/lfg.h"
#include "libavutil/dict.h"
+#include "libavutil/avstring.h"
#include "libavcodec/xiph.h"
#include "libavcodec/mpeg4audio.h"
-#include <strings.h>
typedef struct ebml_master {
int64_t pos; ///< absolute offset in the file where the master's elements start
@@ -89,6 +92,8 @@ typedef struct MatroskaMuxContext {
unsigned int audio_buffer_size;
AVPacket cur_audio_pkt;
+
+ int have_attachments;
} MatroskaMuxContext;
@@ -180,7 +185,7 @@ static void put_ebml_float(AVIOContext *pb, unsigned int elementid, double val)
{
put_ebml_id(pb, elementid);
put_ebml_num(pb, 8, 0);
- avio_wb64(pb, av_dbl2int(val));
+ avio_wb64(pb, av_double2int(val));
}
static void put_ebml_binary(AVIOContext *pb, unsigned int elementid,
@@ -313,9 +318,12 @@ static int64_t mkv_write_seekhead(AVIOContext *pb, mkv_seekhead *seekhead)
currentpos = avio_tell(pb);
- if (seekhead->reserved_size > 0)
- if (avio_seek(pb, seekhead->filepos, SEEK_SET) < 0)
- return -1;
+ if (seekhead->reserved_size > 0) {
+ if (avio_seek(pb, seekhead->filepos, SEEK_SET) < 0) {
+ currentpos = -1;
+ goto fail;
+ }
+ }
metaseek = start_ebml_master(pb, MATROSKA_ID_SEEKHEAD, seekhead->reserved_size);
for (i = 0; i < seekhead->num_entries; i++) {
@@ -339,6 +347,7 @@ static int64_t mkv_write_seekhead(AVIOContext *pb, mkv_seekhead *seekhead)
currentpos = seekhead->filepos;
}
+fail:
av_free(seekhead->entries);
av_free(seekhead);
@@ -419,7 +428,7 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, AVCodecContex
else
first_header_size = 42;
- if (ff_split_xiph_headers(codec->extradata, codec->extradata_size,
+ if (avpriv_split_xiph_headers(codec->extradata, codec->extradata_size,
first_header_size, header_start, header_len) < 0) {
av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
return -1;
@@ -439,7 +448,8 @@ static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec, int
{
MPEG4AudioConfig mp4ac;
- if (ff_mpeg4audio_get_config(&mp4ac, codec->extradata, codec->extradata_size) < 0) {
+ if (avpriv_mpeg4audio_get_config(&mp4ac, codec->extradata,
+ codec->extradata_size * 8, 1) < 0) {
av_log(s, AV_LOG_WARNING, "Error parsing AAC extradata, unable to determine samplerate.\n");
return;
}
@@ -526,8 +536,13 @@ static int mkv_write_tracks(AVFormatContext *s)
int output_sample_rate = 0;
AVDictionaryEntry *tag;
+ if (codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
+ mkv->have_attachments = 1;
+ continue;
+ }
+
if (!bit_depth)
- bit_depth = av_get_bits_per_sample_fmt(codec->sample_fmt);
+ bit_depth = av_get_bytes_per_sample(codec->sample_fmt) << 3;
if (codec->codec_id == CODEC_ID_AAC)
get_aac_sample_rates(s, codec, &sample_rate, &output_sample_rate);
@@ -649,7 +664,7 @@ static int mkv_write_tracks(AVFormatContext *s)
end_ebml_master(pb, track);
// ms precision is the de-facto standard timescale for mkv files
- av_set_pts_info(st, 64, 1, 1000);
+ avpriv_set_pts_info(st, 64, 1, 1000);
}
end_ebml_master(pb, tracks);
return 0;
@@ -751,7 +766,7 @@ static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme
end_ebml_master(s->pb, targets);
while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
- if (strcasecmp(t->key, "title"))
+ if (av_strcasecmp(t->key, "title"))
mkv_write_simpletag(s->pb, t);
end_ebml_master(s->pb, tag);
@@ -795,6 +810,68 @@ static int mkv_write_tags(AVFormatContext *s)
return 0;
}
+static int mkv_write_attachments(AVFormatContext *s)
+{
+ MatroskaMuxContext *mkv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ ebml_master attachments;
+ AVLFG c;
+ int i, ret;
+
+ if (!mkv->have_attachments)
+ return 0;
+
+ av_lfg_init(&c, av_get_random_seed());
+
+ ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_ATTACHMENTS, avio_tell(pb));
+ if (ret < 0) return ret;
+
+ attachments = start_ebml_master(pb, MATROSKA_ID_ATTACHMENTS, 0);
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ ebml_master attached_file;
+ AVDictionaryEntry *t;
+ const char *mimetype = NULL;
+
+ if (st->codec->codec_type != AVMEDIA_TYPE_ATTACHMENT)
+ continue;
+
+ attached_file = start_ebml_master(pb, MATROSKA_ID_ATTACHEDFILE, 0);
+
+ if (t = av_dict_get(st->metadata, "title", NULL, 0))
+ put_ebml_string(pb, MATROSKA_ID_FILEDESC, t->value);
+ if (!(t = av_dict_get(st->metadata, "filename", NULL, 0))) {
+ av_log(s, AV_LOG_ERROR, "Attachment stream %d has no filename tag.\n", i);
+ return AVERROR(EINVAL);
+ }
+ put_ebml_string(pb, MATROSKA_ID_FILENAME, t->value);
+ if (t = av_dict_get(st->metadata, "mimetype", NULL, 0))
+ mimetype = t->value;
+ else if (st->codec->codec_id != CODEC_ID_NONE ) {
+ int i;
+ for (i = 0; ff_mkv_mime_tags[i].id != CODEC_ID_NONE; i++)
+ if (ff_mkv_mime_tags[i].id == st->codec->codec_id) {
+ mimetype = ff_mkv_mime_tags[i].str;
+ break;
+ }
+ }
+ if (!mimetype) {
+ av_log(s, AV_LOG_ERROR, "Attachment stream %d has no mimetype tag and "
+ "it cannot be deduced from the codec id.\n", i);
+ return AVERROR(EINVAL);
+ }
+
+ put_ebml_string(pb, MATROSKA_ID_FILEMIMETYPE, mimetype);
+ put_ebml_binary(pb, MATROSKA_ID_FILEDATA, st->codec->extradata, st->codec->extradata_size);
+ put_ebml_uint(pb, MATROSKA_ID_FILEUID, av_lfg_get(&c));
+ end_ebml_master(pb, attached_file);
+ }
+ end_ebml_master(pb, attachments);
+
+ return 0;
+}
+
static int mkv_write_header(AVFormatContext *s)
{
MatroskaMuxContext *mkv = s->priv_data;
@@ -868,6 +945,9 @@ static int mkv_write_header(AVFormatContext *s)
ret = mkv_write_tags(s);
if (ret < 0) return ret;
+
+ ret = mkv_write_attachments(s);
+ if (ret < 0) return ret;
}
if (!s->pb->seekable)
@@ -930,7 +1010,7 @@ static int mkv_write_ass_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *p
size -= start - data;
sscanf(data, "Dialogue: %d,", &layer);
i = snprintf(buffer, sizeof(buffer), "%"PRId64",%d,",
- s->streams[pkt->stream_index]->nb_frames++, layer);
+ s->streams[pkt->stream_index]->nb_frames, layer);
size = FFMIN(i+size, sizeof(buffer));
memcpy(buffer+i, start, size-i);
@@ -1189,52 +1269,81 @@ static int mkv_write_trailer(AVFormatContext *s)
return 0;
}
+static int mkv_query_codec(enum CodecID codec_id, int std_compliance)
+{
+ int i;
+ for (i = 0; ff_mkv_codec_tags[i].id != CODEC_ID_NONE; i++)
+ if (ff_mkv_codec_tags[i].id == codec_id)
+ return 1;
+
+ if (std_compliance < FF_COMPLIANCE_NORMAL) { // mkv theoretically supports any
+ enum AVMediaType type = avcodec_get_type(codec_id); // video/audio through VFW/ACM
+ if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)
+ return 1;
+ }
+
+ return 0;
+}
+
#if CONFIG_MATROSKA_MUXER
AVOutputFormat ff_matroska_muxer = {
- "matroska",
- NULL_IF_CONFIG_SMALL("Matroska file format"),
- "video/x-matroska",
- "mkv",
- sizeof(MatroskaMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG4,
- mkv_write_header,
- mkv_write_packet,
- mkv_write_trailer,
- .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
- .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
- .subtitle_codec = CODEC_ID_TEXT,
+ .name = "matroska",
+ .long_name = NULL_IF_CONFIG_SMALL("Matroska file format"),
+ .mime_type = "video/x-matroska",
+ .extensions = "mkv",
+ .priv_data_size = sizeof(MatroskaMuxContext),
+#if CONFIG_LIBVORBIS_ENCODER
+ .audio_codec = CODEC_ID_VORBIS,
+#else
+ .audio_codec = CODEC_ID_AC3,
+#endif
+#if CONFIG_LIBX264_ENCODER
+ .video_codec = CODEC_ID_H264,
+#else
+ .video_codec = CODEC_ID_MPEG4,
+#endif
+ .write_header = mkv_write_header,
+ .write_packet = mkv_write_packet,
+ .write_trailer = mkv_write_trailer,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
+ .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
+ .subtitle_codec = CODEC_ID_SSA,
+ .query_codec = mkv_query_codec,
};
#endif
#if CONFIG_WEBM_MUXER
AVOutputFormat ff_webm_muxer = {
- "webm",
- NULL_IF_CONFIG_SMALL("WebM file format"),
- "video/webm",
- "webm",
- sizeof(MatroskaMuxContext),
- CODEC_ID_VORBIS,
- CODEC_ID_VP8,
- mkv_write_header,
- mkv_write_packet,
- mkv_write_trailer,
+ .name = "webm",
+ .long_name = NULL_IF_CONFIG_SMALL("WebM file format"),
+ .mime_type = "video/webm",
+ .extensions = "webm",
+ .priv_data_size = sizeof(MatroskaMuxContext),
+ .audio_codec = CODEC_ID_VORBIS,
+ .video_codec = CODEC_ID_VP8,
+ .write_header = mkv_write_header,
+ .write_packet = mkv_write_packet,
+ .write_trailer = mkv_write_trailer,
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
};
#endif
#if CONFIG_MATROSKA_AUDIO_MUXER
AVOutputFormat ff_matroska_audio_muxer = {
- "matroska",
- NULL_IF_CONFIG_SMALL("Matroska file format"),
- "audio/x-matroska",
- "mka",
- sizeof(MatroskaMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_NONE,
- mkv_write_header,
- mkv_write_packet,
- mkv_write_trailer,
+ .name = "matroska",
+ .long_name = NULL_IF_CONFIG_SMALL("Matroska file format"),
+ .mime_type = "audio/x-matroska",
+ .extensions = "mka",
+ .priv_data_size = sizeof(MatroskaMuxContext),
+#if CONFIG_LIBVORBIS_ENCODER
+ .audio_codec = CODEC_ID_VORBIS,
+#else
+ .audio_codec = CODEC_ID_AC3,
+#endif
+ .video_codec = CODEC_ID_NONE,
+ .write_header = mkv_write_header,
+ .write_packet = mkv_write_packet,
+ .write_trailer = mkv_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
};
diff --git a/libavformat/md5enc.c b/libavformat/md5enc.c
index 3b7d0ea..4509c18 100644
--- a/libavformat/md5enc.c
+++ b/libavformat/md5enc.c
@@ -66,16 +66,16 @@ static int write_trailer(struct AVFormatContext *s)
}
AVOutputFormat ff_md5_muxer = {
- "md5",
- NULL_IF_CONFIG_SMALL("MD5 testing format"),
- NULL,
- "",
- PRIVSIZE,
- CODEC_ID_PCM_S16LE,
- CODEC_ID_RAWVIDEO,
- write_header,
- write_packet,
- write_trailer,
+ .name = "md5",
+ .long_name = NULL_IF_CONFIG_SMALL("MD5 testing format"),
+ .extensions = "",
+ .priv_data_size = PRIVSIZE,
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_header = write_header,
+ .write_packet = write_packet,
+ .write_trailer = write_trailer,
+ .flags = AVFMT_NOTIMESTAMPS,
};
#endif
@@ -96,15 +96,13 @@ static int framemd5_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_framemd5_muxer = {
- "framemd5",
- NULL_IF_CONFIG_SMALL("Per-frame MD5 testing format"),
- NULL,
- "",
- PRIVSIZE,
- CODEC_ID_PCM_S16LE,
- CODEC_ID_RAWVIDEO,
- NULL,
- framemd5_write_packet,
- NULL,
+ .name = "framemd5",
+ .long_name = NULL_IF_CONFIG_SMALL("Per-frame MD5 testing format"),
+ .extensions = "",
+ .priv_data_size = PRIVSIZE,
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_packet = framemd5_write_packet,
+ .flags = AVFMT_VARIABLE_FPS,
};
#endif
diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c
index 4630c49..796b4ea 100644
--- a/libavformat/md5proto.c
+++ b/libavformat/md5proto.c
@@ -36,7 +36,7 @@ static int md5_open(URLContext *h, const char *filename, int flags)
return -1;
}
- if (!flags & AVIO_FLAG_WRITE)
+ if (!(flags & AVIO_FLAG_WRITE))
return AVERROR(EINVAL);
av_md5_init(h->priv_data);
@@ -65,7 +65,8 @@ static int md5_close(URLContext *h)
av_strstart(filename, "md5:", &filename);
if (*filename) {
- err = ffurl_open(&out, filename, AVIO_FLAG_WRITE);
+ err = ffurl_open(&out, filename, AVIO_FLAG_WRITE,
+ &h->interrupt_callback, NULL);
if (err)
return err;
err = ffurl_write(out, buf, i*2+1);
@@ -78,16 +79,11 @@ static int md5_close(URLContext *h)
return err;
}
-static int md5_get_handle(URLContext *h)
-{
- return (intptr_t)h->priv_data;
-}
URLProtocol ff_md5_protocol = {
.name = "md5",
.url_open = md5_open,
.url_write = md5_write,
.url_close = md5_close,
- .url_get_file_handle = md5_get_handle,
.priv_data_size = PRIV_SIZE,
};
diff --git a/libavformat/metadata.c b/libavformat/metadata.c
index d8957df..7d85363 100644
--- a/libavformat/metadata.c
+++ b/libavformat/metadata.c
@@ -18,10 +18,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <strings.h>
#include "avformat.h"
#include "metadata.h"
#include "libavutil/dict.h"
+#include "libavutil/avstring.h"
#if FF_API_OLD_METADATA2
AVDictionaryEntry *
@@ -69,13 +69,13 @@ void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv,
key = mtag->key;
if (s_conv)
for (sc=s_conv; sc->native; sc++)
- if (!strcasecmp(key, sc->native)) {
+ if (!av_strcasecmp(key, sc->native)) {
key = sc->generic;
break;
}
if (d_conv)
for (dc=d_conv; dc->native; dc++)
- if (!strcasecmp(key, dc->generic)) {
+ if (!av_strcasecmp(key, dc->generic)) {
key = dc->native;
break;
}
diff --git a/libavformat/mm.c b/libavformat/mm.c
index bea6161..341cf26 100644
--- a/libavformat/mm.c
+++ b/libavformat/mm.c
@@ -33,6 +33,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define MM_PREAMBLE_SIZE 6
@@ -105,7 +106,7 @@ static int read_header(AVFormatContext *s,
avio_skip(pb, length - 10); /* unknown data */
/* video stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -113,11 +114,11 @@ static int read_header(AVFormatContext *s,
st->codec->codec_tag = 0; /* no fourcc */
st->codec->width = width;
st->codec->height = height;
- av_set_pts_info(st, 64, 1, frame_rate);
+ avpriv_set_pts_info(st, 64, 1, frame_rate);
/* audio stream */
if (length == MM_HEADER_LEN_AV) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -125,7 +126,7 @@ static int read_header(AVFormatContext *s,
st->codec->codec_id = CODEC_ID_PCM_U8;
st->codec->channels = 1;
st->codec->sample_rate = 8000;
- av_set_pts_info(st, 64, 1, 8000); /* 8000 hz */
+ avpriv_set_pts_info(st, 64, 1, 8000); /* 8000 hz */
}
mm->audio_pts = 0;
@@ -184,15 +185,13 @@ static int read_packet(AVFormatContext *s,
avio_skip(pb, length);
}
}
-
- return 0;
}
AVInputFormat ff_mm_demuxer = {
- "mm",
- NULL_IF_CONFIG_SMALL("American Laser Games MM format"),
- sizeof(MmDemuxContext),
- probe,
- read_header,
- read_packet,
+ .name = "mm",
+ .long_name = NULL_IF_CONFIG_SMALL("American Laser Games MM format"),
+ .priv_data_size = sizeof(MmDemuxContext),
+ .read_probe = probe,
+ .read_header = read_header,
+ .read_packet = read_packet,
};
diff --git a/libavformat/mmf.c b/libavformat/mmf.c
index 3848d5c..8e4f2de 100644
--- a/libavformat/mmf.c
+++ b/libavformat/mmf.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
+#include "internal.h"
#include "avio_internal.h"
#include "pcm.h"
#include "riff.h"
@@ -100,7 +101,7 @@ static int mmf_write_header(AVFormatContext *s)
mmf->awapos = ff_start_tag(pb, "Awa\x01");
- av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
+ avpriv_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
avio_flush(pb);
@@ -241,7 +242,7 @@ static int mmf_read_header(AVFormatContext *s,
}
mmf->data_size = size;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -252,7 +253,7 @@ static int mmf_read_header(AVFormatContext *s,
st->codec->bits_per_coded_sample = 4;
st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
return 0;
}
@@ -291,27 +292,26 @@ static int mmf_read_packet(AVFormatContext *s,
#if CONFIG_MMF_DEMUXER
AVInputFormat ff_mmf_demuxer = {
- "mmf",
- NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
- sizeof(MMFContext),
- mmf_probe,
- mmf_read_header,
- mmf_read_packet,
- NULL,
- pcm_read_seek,
+ .name = "mmf",
+ .long_name = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
+ .priv_data_size = sizeof(MMFContext),
+ .read_probe = mmf_probe,
+ .read_header = mmf_read_header,
+ .read_packet = mmf_read_packet,
+ .read_seek = pcm_read_seek,
};
#endif
#if CONFIG_MMF_MUXER
AVOutputFormat ff_mmf_muxer = {
- "mmf",
- NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
- "application/vnd.smaf",
- "mmf",
- sizeof(MMFContext),
- CODEC_ID_ADPCM_YAMAHA,
- CODEC_ID_NONE,
- mmf_write_header,
- mmf_write_packet,
- mmf_write_trailer,
+ .name = "mmf",
+ .long_name = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
+ .mime_type = "application/vnd.smaf",
+ .extensions = "mmf",
+ .priv_data_size = sizeof(MMFContext),
+ .audio_codec = CODEC_ID_ADPCM_YAMAHA,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = mmf_write_header,
+ .write_packet = mmf_write_packet,
+ .write_trailer = mmf_write_trailer,
};
#endif
diff --git a/libavformat/mms.h b/libavformat/mms.h
index 36e772c..5235581 100644
--- a/libavformat/mms.h
+++ b/libavformat/mms.h
@@ -33,7 +33,7 @@ typedef struct {
/** Buffer for outgoing packets. */
/*@{*/
- uint8_t *write_out_ptr; ///< Pointer for writting the buffer.
+ uint8_t *write_out_ptr; ///< Pointer for writing the buffer.
uint8_t out_buffer[512]; ///< Buffer for outgoing packet.
/*@}*/
diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c
index af040e2..fa1a467 100644
--- a/libavformat/mmsh.c
+++ b/libavformat/mmsh.c
@@ -28,6 +28,7 @@
#include <string.h>
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
#include "internal.h"
#include "mms.h"
#include "asf.h"
@@ -67,7 +68,6 @@ static int mmsh_close(URLContext *h)
ffurl_close(mms->mms_hd);
av_free(mms->streams);
av_free(mms->asf_header);
- av_freep(&h->priv_data);
return 0;
}
@@ -208,7 +208,6 @@ static int get_http_header_data(MMSHContext *mmsh)
}
}
}
- return 0;
}
static int mmsh_open(URLContext *h, const char *uri, int flags)
@@ -217,12 +216,9 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
char httpname[256], path[256], host[128], location[1024];
char *stream_selection = NULL;
char headers[1024];
- MMSHContext *mmsh;
+ MMSHContext *mmsh = h->priv_data;
MMSContext *mms;
- mmsh = h->priv_data = av_mallocz(sizeof(MMSHContext));
- if (!h->priv_data)
- return AVERROR(ENOMEM);
mmsh->request_seq = h->is_streamed = 1;
mms = &mmsh->mms;
av_strlcpy(location, uri, sizeof(location));
@@ -233,7 +229,8 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
port = 80; // default mmsh protocol port
ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, "%s", path);
- if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ) < 0) {
+ if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ,
+ &h->interrupt_callback) < 0) {
return AVERROR(EIO);
}
@@ -246,9 +243,9 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
CLIENTGUID
"Connection: Close\r\n\r\n",
host, port, mmsh->request_seq++);
- ff_http_set_headers(mms->mms_hd, headers);
+ av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0);
- err = ffurl_connect(mms->mms_hd);
+ err = ffurl_connect(mms->mms_hd, NULL);
if (err) {
goto fail;
}
@@ -261,8 +258,9 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
// close the socket and then reopen it for sending the second play request.
ffurl_close(mms->mms_hd);
memset(headers, 0, sizeof(headers));
- if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ) < 0) {
- return AVERROR(EIO);
+ if ((err = ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ,
+ &h->interrupt_callback)) < 0) {
+ goto fail;
}
stream_selection = av_mallocz(mms->stream_num * 19 + 1);
if (!stream_selection)
@@ -292,9 +290,9 @@ static int mmsh_open(URLContext *h, const char *uri, int flags)
goto fail;
}
av_dlog(NULL, "out_buffer is %s", headers);
- ff_http_set_headers(mms->mms_hd, headers);
+ av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0);
- err = ffurl_connect(mms->mms_hd);
+ err = ffurl_connect(mms->mms_hd, NULL);
if (err) {
goto fail;
}
@@ -361,10 +359,9 @@ static int mmsh_read(URLContext *h, uint8_t *buf, int size)
}
URLProtocol ff_mmsh_protocol = {
- .name = "mmsh",
- .url_open = mmsh_open,
- .url_read = mmsh_read,
- .url_write = NULL,
- .url_seek = NULL,
- .url_close = mmsh_close,
+ .name = "mmsh",
+ .url_open = mmsh_open,
+ .url_read = mmsh_read,
+ .url_close = mmsh_close,
+ .priv_data_size = sizeof(MMSHContext),
};
diff --git a/libavformat/mmst.c b/libavformat/mmst.c
index e1904de..753b05c 100644
--- a/libavformat/mmst.c
+++ b/libavformat/mmst.c
@@ -470,7 +470,6 @@ static int mms_close(URLContext *h)
/* free all separately allocated pointers in mms */
av_free(mms->streams);
av_free(mms->asf_header);
- av_freep(&h->priv_data);
return 0;
}
@@ -502,15 +501,12 @@ static void clear_stream_buffers(MMSContext *mms)
static int mms_open(URLContext *h, const char *uri, int flags)
{
- MMSTContext *mmst;
+ MMSTContext *mmst = h->priv_data;
MMSContext *mms;
int port, err;
char tcpname[256];
h->is_streamed = 1;
- mmst = h->priv_data = av_mallocz(sizeof(MMSTContext));
- if (!h->priv_data)
- return AVERROR(ENOMEM);
mms = &mmst->mms;
// only for MMS over TCP, so set proto = NULL
@@ -523,7 +519,8 @@ static int mms_open(URLContext *h, const char *uri, int flags)
// establish tcp connection.
ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL);
- err = ffurl_open(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE);
+ err = ffurl_open(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE,
+ &h->interrupt_callback, NULL);
if (err)
goto fail;
@@ -623,8 +620,9 @@ static int mms_read(URLContext *h, uint8_t *buf, int size)
}
URLProtocol ff_mmst_protocol = {
- .name = "mmst",
- .url_open = mms_open,
- .url_read = mms_read,
- .url_close = mms_close,
+ .name = "mmst",
+ .url_open = mms_open,
+ .url_read = mms_read,
+ .url_close = mms_close,
+ .priv_data_size = sizeof(MMSTContext),
};
diff --git a/libavformat/mov.c b/libavformat/mov.c
index c720440..d3674d9 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -26,13 +26,18 @@
//#define MOV_EXPORT_ALL_METADATA
#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
+#include "libavutil/mathematics.h"
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
#include "avformat.h"
+#include "internal.h"
#include "avio_internal.h"
#include "riff.h"
#include "isom.h"
#include "libavcodec/get_bits.h"
+#include "id3v1.h"
+#include "mov_chan.h"
#if CONFIG_ZLIB
#include <zlib.h>
@@ -41,21 +46,6 @@
/*
* First version by Francois Revol revol at free.fr
* Seek function by Gael Chardon gael.dev at 4now.net
- *
- * Features and limitations:
- * - reads most of the QT files I have (at least the structure),
- * Sample QuickTime files with mp3 audio can be found at: http://www.3ivx.com/showcase.html
- * - the code is quite ugly... maybe I won't do it recursive next time :-)
- *
- * Funny I didn't know about http://sourceforge.net/projects/qt-ffmpeg/
- * when coding this :) (it's a writer anyway)
- *
- * Reference documents:
- * http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
- * Apple:
- * http://developer.apple.com/documentation/QuickTime/QTFF/
- * http://developer.apple.com/documentation/QuickTime/QTFF/qtff.pdf
- * QuickTime is a trademark of Apple (AFAIK :))
*/
#include "qtpalette.h"
@@ -64,13 +54,7 @@
#undef NDEBUG
#include <assert.h>
-/* XXX: it's the first time I make a recursive parser I think... sorry if it's ugly :P */
-
/* those functions parse an atom */
-/* return code:
- 0: continue to parse next atom
- <0: error occurred, exit
-*/
/* links atom IDs to parse functions */
typedef struct MOVParseTableEntry {
uint32_t type;
@@ -79,15 +63,64 @@ typedef struct MOVParseTableEntry {
static const MOVParseTableEntry mov_default_parse_table[];
-static int mov_metadata_trkn(MOVContext *c, AVIOContext *pb, unsigned len)
+static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
+ unsigned len, const char *key)
{
char buf[16];
+ short current, total;
avio_rb16(pb); // unknown
- snprintf(buf, sizeof(buf), "%d", avio_rb16(pb));
- av_dict_set(&c->fc->metadata, "track", buf, 0);
+ current = avio_rb16(pb);
+ total = avio_rb16(pb);
+ if (!total)
+ snprintf(buf, sizeof(buf), "%d", current);
+ else
+ snprintf(buf, sizeof(buf), "%d/%d", current, total);
+ av_dict_set(&c->fc->metadata, key, buf, 0);
+
+ return 0;
+}
+
+static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
+ unsigned len, const char *key)
+{
+ char buf[16];
+
+ /* bypass padding bytes */
+ avio_r8(pb);
+ avio_r8(pb);
+ avio_r8(pb);
+
+ snprintf(buf, sizeof(buf), "%d", avio_r8(pb));
+ av_dict_set(&c->fc->metadata, key, buf, 0);
+
+ return 0;
+}
+
+static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
+ unsigned len, const char *key)
+{
+ char buf[16];
+
+ snprintf(buf, sizeof(buf), "%d", avio_r8(pb));
+ av_dict_set(&c->fc->metadata, key, buf, 0);
+
+ return 0;
+}
+
+static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
+ unsigned len, const char *key)
+{
+ short genre;
+ char buf[20];
+
+ avio_r8(pb); // unknown
- avio_rb16(pb); // total tracks
+ genre = avio_r8(pb);
+ if (genre < 1 || genre > ID3v1_GENRE_MAX)
+ return 0;
+ snprintf(buf, sizeof(buf), "%s", ff_id3v1_genre_str[genre-1]);
+ av_dict_set(&c->fc->metadata, key, buf, 0);
return 0;
}
@@ -138,12 +171,13 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
const char *key = NULL;
uint16_t str_size, langcode = 0;
uint32_t data_type = 0;
- int (*parse)(MOVContext*, AVIOContext*, unsigned) = NULL;
+ int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
switch (atom.type) {
case MKTAG(0xa9,'n','a','m'): key = "title"; break;
case MKTAG(0xa9,'a','u','t'):
case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
+ case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
case MKTAG( 'c','p','r','t'):
case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
@@ -152,6 +186,8 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
case MKTAG(0xa9,'a','l','b'): key = "album"; break;
case MKTAG(0xa9,'d','a','y'): key = "date"; break;
case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
+ case MKTAG( 'g','n','r','e'): key = "genre";
+ parse = mov_metadata_gnre; break;
case MKTAG(0xa9,'t','o','o'):
case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
@@ -161,7 +197,19 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
case MKTAG( 't','v','e','n'): key = "episode_id";break;
case MKTAG( 't','v','n','n'): key = "network"; break;
case MKTAG( 't','r','k','n'): key = "track";
- parse = mov_metadata_trkn; break;
+ parse = mov_metadata_track_or_disc_number; break;
+ case MKTAG( 'd','i','s','k'): key = "disc";
+ parse = mov_metadata_track_or_disc_number; break;
+ case MKTAG( 't','v','e','s'): key = "episode_sort";
+ parse = mov_metadata_int8_bypass_padding; break;
+ case MKTAG( 't','v','s','n'): key = "season_number";
+ parse = mov_metadata_int8_bypass_padding; break;
+ case MKTAG( 's','t','i','k'): key = "media_type";
+ parse = mov_metadata_int8_no_padding; break;
+ case MKTAG( 'h','d','v','d'): key = "hd_video";
+ parse = mov_metadata_int8_no_padding; break;
+ case MKTAG( 'p','g','a','p'): key = "gapless_playback";
+ parse = mov_metadata_int8_no_padding; break;
}
if (c->itunes_metadata && atom.size > 8) {
@@ -196,7 +244,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
str_size = FFMIN3(sizeof(str)-1, str_size, atom.size);
if (parse)
- parse(c, pb, str_size);
+ parse(c, pb, str_size, key);
else {
if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Encoded
mov_read_mac_string(c, pb, str_size, str, sizeof(str));
@@ -244,7 +292,7 @@ static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_read(pb, str, str_len);
str[str_len] = 0;
- ff_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
+ avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
}
return 0;
}
@@ -261,7 +309,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
a.size = atom.size;
a.type=0;
- if(atom.size >= 8) {
+ if (atom.size >= 8) {
a.size = avio_rb32(pb);
a.type = avio_rl32(pb);
}
@@ -278,7 +326,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
break;
}
a.size -= 8;
- if(a.size < 0)
+ if (a.size < 0)
break;
a.size = FFMIN(a.size, atom.size - total_size);
@@ -445,11 +493,11 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (type == MKTAG('v','i','d','e'))
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- else if(type == MKTAG('s','o','u','n'))
+ else if (type == MKTAG('s','o','u','n'))
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- else if(type == MKTAG('m','1','a',' '))
+ else if (type == MKTAG('m','1','a',' '))
st->codec->codec_id = CODEC_ID_MP2;
- else if(type == MKTAG('s','u','b','p'))
+ else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
avio_rb32(pb); /* component manufacture */
@@ -471,8 +519,7 @@ int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom)
avio_rb32(pb); /* version + flags */
ff_mp4_read_descr(fc, pb, &tag);
if (tag == MP4ESDescrTag) {
- avio_rb16(pb); /* ID */
- avio_r8(pb); /* priority */
+ ff_mp4_parse_es_descr(pb, NULL);
} else
avio_rb16(pb); /* ID */
@@ -508,6 +555,51 @@ static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ AVStream *st;
+ uint8_t version;
+ uint32_t flags, layout_tag, bitmap, num_descr;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams-1];
+
+ if (atom.size < 16)
+ return 0;
+
+ version = avio_r8(pb);
+ flags = avio_rb24(pb);
+
+ layout_tag = avio_rb32(pb);
+ bitmap = avio_rb32(pb);
+ num_descr = avio_rb32(pb);
+
+ if (atom.size < 16ULL + num_descr * 20ULL)
+ return 0;
+
+ av_dlog(c->fc, "chan: size=%ld version=%u flags=%u layout=%u bitmap=%u num_descr=%u\n",
+ atom.size, version, flags, layout_tag, bitmap, num_descr);
+
+#if 0
+ /* TODO: use the channel descriptions if the layout tag is 0 */
+ int i;
+ for (i = 0; i < num_descr; i++) {
+ uint32_t label, cflags;
+ float coords[3];
+ label = avio_rb32(pb); // mChannelLabel
+ cflags = avio_rb32(pb); // mChannelFlags
+ AV_WN32(&coords[0], avio_rl32(pb)); // mCoordinates[0]
+ AV_WN32(&coords[1], avio_rl32(pb)); // mCoordinates[1]
+ AV_WN32(&coords[2], avio_rl32(pb)); // mCoordinates[2]
+ }
+#endif
+
+ st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap);
+
+ return 0;
+}
+
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
@@ -547,7 +639,7 @@ static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
/* this atom contains actual media data */
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- if(atom.size == 0) /* wrong one (MP4) */
+ if (atom.size == 0) /* wrong one (MP4) */
return 0;
c->found_mdat=1;
return 0; /* now go for moov */
@@ -701,7 +793,7 @@ static int mov_read_smi(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if((uint64_t)atom.size > (1<<30))
+ if ((uint64_t)atom.size > (1<<30))
return -1;
// currently SVQ3 decoder expect full STSD header - so let's fake it
@@ -749,6 +841,40 @@ static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ AVStream *st;
+ unsigned mov_field_order;
+ enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
+
+ if (c->fc->nb_streams < 1) // will happen with jp2 files
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams-1];
+ if (atom.size < 2)
+ return AVERROR_INVALIDDATA;
+ mov_field_order = avio_rb16(pb);
+ if ((mov_field_order & 0xFF00) == 0x0100)
+ decoded_field_order = AV_FIELD_PROGRESSIVE;
+ else if ((mov_field_order & 0xFF00) == 0x0200) {
+ switch (mov_field_order & 0xFF) {
+ case 0x01: decoded_field_order = AV_FIELD_TT;
+ break;
+ case 0x06: decoded_field_order = AV_FIELD_BB;
+ break;
+ case 0x09: decoded_field_order = AV_FIELD_TB;
+ break;
+ case 0x0E: decoded_field_order = AV_FIELD_BT;
+ break;
+ }
+ }
+ if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
+ av_log(NULL, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
+ }
+ st->codec->field_order = decoded_field_order;
+
+ return 0;
+}
+
/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
@@ -760,10 +886,10 @@ static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st= c->fc->streams[c->fc->nb_streams-1];
size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;
- if(size > INT_MAX || (uint64_t)atom.size > INT_MAX)
+ if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
return -1;
buf= av_realloc(st->codec->extradata, size);
- if(!buf)
+ if (!buf)
return -1;
st->codec->extradata= buf;
buf+= st->codec->extradata_size;
@@ -782,7 +908,7 @@ static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if((uint64_t)atom.size > (1<<30))
+ if ((uint64_t)atom.size > (1<<30))
return -1;
if (st->codec->codec_id == CODEC_ID_QDM2 || st->codec->codec_id == CODEC_ID_QDMC) {
@@ -813,9 +939,18 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if((uint64_t)atom.size > (1<<30))
+ if ((uint64_t)atom.size > (1<<30))
return -1;
+ if (atom.size >= 10) {
+ // Broken files created by legacy versions of Libav and FFmpeg will
+ // wrap a whole fiel atom inside of a glbl atom.
+ unsigned size = avio_rb32(pb);
+ unsigned type = avio_rl32(pb);
+ avio_seek(pb, -8, SEEK_CUR);
+ if (type == MKTAG('f','i','e','l') && size == atom.size)
+ return mov_read_default(c, pb, atom);
+ }
av_free(st->codec->extradata);
st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
@@ -840,7 +975,7 @@ static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if((uint64_t)atom.size > (1<<30))
+ if ((uint64_t)atom.size > (1<<30))
return -1;
av_free(st->codec->extradata);
@@ -869,7 +1004,9 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
entries = avio_rb32(pb);
- if(entries >= UINT_MAX/sizeof(int64_t))
+ if (!entries)
+ return 0;
+ if (entries >= UINT_MAX/sizeof(int64_t))
return -1;
sc->chunk_offsets = av_malloc(entries * sizeof(int64_t));
@@ -878,10 +1015,10 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->chunk_count = entries;
if (atom.type == MKTAG('s','t','c','o'))
- for(i=0; i<entries; i++)
+ for (i=0; i<entries; i++)
sc->chunk_offsets[i] = avio_rb32(pb);
else if (atom.type == MKTAG('c','o','6','4'))
- for(i=0; i<entries; i++)
+ for (i=0; i<entries; i++)
sc->chunk_offsets[i] = avio_rb64(pb);
else
return -1;
@@ -935,7 +1072,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
st = c->fc->streams[c->fc->nb_streams-1];
sc = st->priv_data;
- for(pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) {
+ for (pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) {
//Parsing Sample description table
enum CodecID id;
int dref_id = 1;
@@ -983,9 +1120,9 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
id = ff_codec_get_id(ff_codec_bmp_tags, format);
if (id > 0)
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- else if(st->codec->codec_type == AVMEDIA_TYPE_DATA){
+ else if (st->codec->codec_type == AVMEDIA_TYPE_DATA){
id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
- if(id > 0)
+ if (id > 0)
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
}
}
@@ -994,7 +1131,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
(format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff,
(format >> 24) & 0xff, st->codec->codec_type);
- if(st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
+ if (st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
unsigned int color_depth, len;
int color_greyscale;
@@ -1097,7 +1234,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
}
sc->has_palette = 1;
}
- } else if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
+ } else if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
int bits_per_sample, flags;
uint16_t version = avio_rb16(pb);
@@ -1116,15 +1253,15 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
//Read QT version 1 fields. In version 0 these do not exist.
av_dlog(c->fc, "version =%d, isom =%d\n",version,c->isom);
- if(!c->isom) {
- if(version==1) {
+ if (!c->isom) {
+ if (version==1) {
sc->samples_per_frame = avio_rb32(pb);
avio_rb32(pb); /* bytes per packet */
sc->bytes_per_frame = avio_rb32(pb);
avio_rb32(pb); /* bytes per sample */
- } else if(version==2) {
+ } else if (version==2) {
avio_rb32(pb); /* sizeof struct only */
- st->codec->sample_rate = av_int2dbl(avio_rb64(pb)); /* float 64 */
+ st->codec->sample_rate = av_int2double(avio_rb64(pb)); /* float 64 */
st->codec->channels = avio_rb32(pb);
avio_rb32(pb); /* always 0x7F000000 */
st->codec->bits_per_coded_sample = avio_rb32(pb); /* bits per channel if sound is uncompressed */
@@ -1177,7 +1314,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
st->codec->bits_per_coded_sample = bits_per_sample;
sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
}
- } else if(st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){
+ } else if (st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){
// ttxt stsd contains display flags, justification, background
// color, fonts, and default styles, so fake an atom to read it
MOVAtom fake_atom = { .size = size - (avio_tell(pb) - start_pos) };
@@ -1199,7 +1336,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
avio_skip(pb, a.size);
}
- if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
+ if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
st->codec->sample_rate= sc->time_scale;
/* special codec parameters handling */
@@ -1207,7 +1344,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
#if CONFIG_DV_DEMUXER
case CODEC_ID_DVAUDIO:
c->dv_fctx = avformat_alloc_context();
- c->dv_demux = dv_init_demux(c->dv_fctx);
+ c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
if (!c->dv_demux) {
av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
return -1;
@@ -1225,14 +1362,16 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
st->codec->channels= 1; /* really needed */
break;
case CODEC_ID_AMR_NB:
- case CODEC_ID_AMR_WB:
- st->codec->frame_size= sc->samples_per_frame;
st->codec->channels= 1; /* really needed */
/* force sample rate for amr, stsd in 3gp does not store sample rate */
- if (st->codec->codec_id == CODEC_ID_AMR_NB)
- st->codec->sample_rate = 8000;
- else if (st->codec->codec_id == CODEC_ID_AMR_WB)
- st->codec->sample_rate = 16000;
+ st->codec->sample_rate = 8000;
+ /* force frame_size, too, samples_per_frame isn't always set properly */
+ st->codec->frame_size = 160;
+ break;
+ case CODEC_ID_AMR_WB:
+ st->codec->channels = 1;
+ st->codec->sample_rate = 16000;
+ st->codec->frame_size = 320;
break;
case CODEC_ID_MP2:
case CODEC_ID_MP3:
@@ -1288,14 +1427,16 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_dlog(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
- if(entries >= UINT_MAX / sizeof(*sc->stsc_data))
+ if (!entries)
+ return 0;
+ if (entries >= UINT_MAX / sizeof(*sc->stsc_data))
return -1;
sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
if (!sc->stsc_data)
return AVERROR(ENOMEM);
sc->stsc_count = entries;
- for(i=0; i<entries; i++) {
+ for (i=0; i<entries; i++) {
sc->stsc_data[i].first = avio_rb32(pb);
sc->stsc_data[i].count = avio_rb32(pb);
sc->stsc_data[i].id = avio_rb32(pb);
@@ -1350,14 +1491,14 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_dlog(c->fc, "keyframe_count = %d\n", entries);
- if(entries >= UINT_MAX / sizeof(int))
+ if (entries >= UINT_MAX / sizeof(int))
return -1;
sc->keyframes = av_malloc(entries * sizeof(int));
if (!sc->keyframes)
return AVERROR(ENOMEM);
sc->keyframe_count = entries;
- for(i=0; i<entries; i++) {
+ for (i=0; i<entries; i++) {
sc->keyframes[i] = avio_rb32(pb);
//av_dlog(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);
}
@@ -1403,6 +1544,8 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return -1;
}
+ if (!entries)
+ return 0;
if (entries >= UINT_MAX / sizeof(int) || entries >= (UINT_MAX - 4) / field_size)
return -1;
sc->sample_sizes = av_malloc(entries * sizeof(int));
@@ -1425,7 +1568,7 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
init_get_bits(&gb, buf, 8*num_bytes);
- for(i=0; i<entries; i++)
+ for (i=0; i<entries; i++)
sc->sample_sizes[i] = get_bits_long(&gb, field_size);
av_free(buf);
@@ -1449,16 +1592,21 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_rb24(pb); /* flags */
entries = avio_rb32(pb);
- av_dlog(c->fc, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
+ av_dlog(c->fc, "track[%i].stts.entries = %i\n",
+ c->fc->nb_streams-1, entries);
+
+ if (!entries)
+ return 0;
+ if (entries >= UINT_MAX / sizeof(*sc->stts_data))
+ return AVERROR(EINVAL);
- if(entries >= UINT_MAX / sizeof(*sc->stts_data))
- return -1;
sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data));
if (!sc->stts_data)
return AVERROR(ENOMEM);
+
sc->stts_count = entries;
- for(i=0; i<entries; i++) {
+ for (i=0; i<entries; i++) {
int sample_duration;
int sample_count;
@@ -1467,14 +1615,15 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->stts_data[i].count= sample_count;
sc->stts_data[i].duration= sample_duration;
- av_dlog(c->fc, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
+ av_dlog(c->fc, "sample_count=%d, sample_duration=%d\n",
+ sample_count, sample_duration);
duration+=(int64_t)sample_duration*sample_count;
total_sample_count+=sample_count;
}
st->nb_frames= total_sample_count;
- if(duration)
+ if (duration)
st->duration= duration;
return 0;
}
@@ -1496,14 +1645,16 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_dlog(c->fc, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);
- if(entries >= UINT_MAX / sizeof(*sc->ctts_data))
+ if (!entries)
+ return 0;
+ if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
return -1;
sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data));
if (!sc->ctts_data)
return AVERROR(ENOMEM);
sc->ctts_count = entries;
- for(i=0; i<entries; i++) {
+ for (i=0; i<entries; i++) {
int count =avio_rb32(pb);
int duration =avio_rb32(pb);
@@ -1535,7 +1686,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
if (sc->time_offset < 0)
sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale);
current_dts = -sc->time_offset;
- if (sc->ctts_data && sc->stts_data &&
+ if (sc->ctts_data && sc->stts_data && sc->stts_data[0].duration &&
sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) {
/* more than 16 frames delay, dts are likely wrong
this happens with files created by iMovie */
@@ -1555,6 +1706,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
current_dts -= sc->dts_shift;
+ if (!sc->sample_count)
+ return;
if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries))
return;
st->index_entries = av_malloc(sc->sample_count*sizeof(*st->index_entries));
@@ -1586,7 +1739,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
if (keyframe)
distance = 0;
sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
- if(sc->pseudo_stream_id == -1 ||
+ if (sc->pseudo_stream_id == -1 ||
sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
AVIndexEntry *e = &st->index_entries[st->nb_index_entries++];
e->pos = current_offset;
@@ -1698,7 +1851,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
}
}
-static int mov_open_dref(AVIOContext **pb, char *src, MOVDref *ref)
+static int mov_open_dref(AVIOContext **pb, char *src, MOVDref *ref,
+ AVIOInterruptCB *int_cb)
{
/* try relative path, we do not try the absolute because it can leak information about our
system to an attacker */
@@ -1733,7 +1887,7 @@ static int mov_open_dref(AVIOContext **pb, char *src, MOVDref *ref)
av_strlcat(filename, ref->path + l + 1, 1024);
- if (!avio_open(pb, filename, AVIO_FLAG_READ))
+ if (!avio_open2(pb, filename, AVIO_FLAG_READ, int_cb, NULL))
return 0;
}
}
@@ -1747,8 +1901,9 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
MOVStreamContext *sc;
int ret;
- st = av_new_stream(c->fc, c->fc->nb_streams);
+ st = avformat_new_stream(c->fc, NULL);
if (!st) return AVERROR(ENOMEM);
+ st->id = c->fc->nb_streams;
sc = av_mallocz(sizeof(MOVStreamContext));
if (!sc) return AVERROR(ENOMEM);
@@ -1774,7 +1929,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->time_scale = 1;
}
- av_set_pts_info(st, 64, 1, sc->time_scale);
+ avpriv_set_pts_info(st, 64, 1, sc->time_scale);
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
!st->codec->frame_size && sc->stts_count == 1) {
@@ -1787,7 +1942,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
MOVDref *dref = &sc->drefs[sc->dref_id - 1];
- if (mov_open_dref(&sc->pb, c->fc->filename, dref) < 0)
+ if (mov_open_dref(&sc->pb, c->fc->filename, dref, &c->fc->interrupt_callback) < 0)
av_log(c->fc, AV_LOG_ERROR,
"stream %d, error opening alias: path='%s', dir='%s', "
"filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
@@ -2151,9 +2306,9 @@ static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return AVERROR(ENOMEM);
}
avio_read(pb, cmov_data, cmov_len);
- if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
+ if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
goto free_and_return;
- if(ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
+ if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
goto free_and_return;
atom.type = MKTAG('m','o','o','v');
atom.size = moov_len;
@@ -2182,10 +2337,10 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_rb24(pb); /* flags */
edit_count = avio_rb32(pb); /* entries */
- if((uint64_t)edit_count*12+8 > atom.size)
+ if ((uint64_t)edit_count*12+8 > atom.size)
return -1;
- for(i=0; i<edit_count; i++){
+ for (i=0; i<edit_count; i++){
int64_t time;
int64_t duration;
if (version == 1) {
@@ -2201,7 +2356,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
}
}
- if(edit_count > 1)
+ if (edit_count > 1)
av_log(c->fc, AV_LOG_WARNING, "multiple edit list entries, "
"a/v desync might occur, patch welcome\n");
@@ -2219,7 +2374,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('e','d','t','s'), mov_read_default },
{ MKTAG('e','l','s','t'), mov_read_elst },
{ MKTAG('e','n','d','a'), mov_read_enda },
-{ MKTAG('f','i','e','l'), mov_read_extradata },
+{ MKTAG('f','i','e','l'), mov_read_fiel },
{ MKTAG('f','t','y','p'), mov_read_ftyp },
{ MKTAG('g','l','b','l'), mov_read_glbl },
{ MKTAG('h','d','l','r'), mov_read_hdlr },
@@ -2263,6 +2418,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
{ MKTAG('w','f','e','x'), mov_read_wfex },
{ MKTAG('c','m','o','v'), mov_read_cmov },
+{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
{ 0, NULL }
};
@@ -2274,7 +2430,7 @@ static int mov_probe(AVProbeData *p)
/* check file header */
offset = 0;
- for(;;) {
+ for (;;) {
/* ignore invalid offset */
if ((offset + 8) > (unsigned int)p->buf_size)
return score;
@@ -2308,7 +2464,6 @@ static int mov_probe(AVProbeData *p)
return score;
}
}
- return score;
}
// must be done after parsing all trak because there's no order requirement
@@ -2357,17 +2512,24 @@ static void mov_read_chapters(AVFormatContext *s)
// The samples could theoretically be in any encoding if there's an encd
// atom following, but in practice are only utf-8 or utf-16, distinguished
// instead by the presence of a BOM
- ch = avio_rb16(sc->pb);
- if (ch == 0xfeff)
- avio_get_str16be(sc->pb, len, title, title_len);
- else if (ch == 0xfffe)
- avio_get_str16le(sc->pb, len, title, title_len);
- else {
- AV_WB16(title, ch);
- avio_get_str(sc->pb, len - 2, title + 2, title_len - 2);
+ if (!len) {
+ title[0] = 0;
+ } else {
+ ch = avio_rb16(sc->pb);
+ if (ch == 0xfeff)
+ avio_get_str16be(sc->pb, len, title, title_len);
+ else if (ch == 0xfffe)
+ avio_get_str16le(sc->pb, len, title, title_len);
+ else {
+ AV_WB16(title, ch);
+ if (len == 1 || len == 2)
+ title[len] = 0;
+ else
+ avio_get_str(sc->pb, len - 2, title + 2, title_len - 2);
+ }
}
- ff_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
+ avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
av_freep(&title);
}
finish:
@@ -2383,7 +2545,7 @@ static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
mov->fc = s;
/* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
- if(pb->seekable)
+ if (pb->seekable)
atom.size = avio_size(pb);
else
atom.size = INT64_MAX;
@@ -2475,10 +2637,10 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
}
#if CONFIG_DV_DEMUXER
if (mov->dv_demux && sc->dv_audio_container) {
- dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size);
+ avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size);
av_free(pkt->data);
pkt->size = 0;
- ret = dv_get_packet(mov->dv_demux, pkt);
+ ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
if (ret < 0)
return ret;
}
@@ -2591,12 +2753,10 @@ static int mov_read_close(AVFormatContext *s)
av_freep(&sc->drefs);
if (sc->pb && sc->pb != s->pb)
avio_close(sc->pb);
-
- av_freep(&st->codec->palctrl);
}
if (mov->dv_demux) {
- for(i = 0; i < mov->dv_fctx->nb_streams; i++) {
+ for (i = 0; i < mov->dv_fctx->nb_streams; i++) {
av_freep(&mov->dv_fctx->streams[i]->codec);
av_freep(&mov->dv_fctx->streams[i]);
}
@@ -2610,12 +2770,12 @@ static int mov_read_close(AVFormatContext *s)
}
AVInputFormat ff_mov_demuxer = {
- "mov,mp4,m4a,3gp,3g2,mj2",
- NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"),
- sizeof(MOVContext),
- mov_probe,
- mov_read_header,
- mov_read_packet,
- mov_read_close,
- mov_read_seek,
+ .name = "mov,mp4,m4a,3gp,3g2,mj2",
+ .long_name = NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"),
+ .priv_data_size = sizeof(MOVContext),
+ .read_probe = mov_probe,
+ .read_header = mov_read_header,
+ .read_packet = mov_read_packet,
+ .read_close = mov_read_close,
+ .read_seek = mov_read_seek,
};
diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c
new file mode 100644
index 0000000..3c1ced6
--- /dev/null
+++ b/libavformat/mov_chan.c
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 2011 Justin Ruggles
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * mov 'chan' tag reading/writing.
+ * @author Justin Ruggles
+ */
+
+#include <stdint.h>
+
+#include "libavutil/audioconvert.h"
+#include "libavcodec/avcodec.h"
+#include "mov_chan.h"
+
+/**
+ * Channel Layout Tag
+ * This tells which channels are present in the audio stream and the order in
+ * which they appear.
+ *
+ * @note We're using the channel layout tag to indicate channel order
+ * when the value is greater than 0x10000. The Apple documentation has
+ * some contradictions as to how this is actually supposed to be handled.
+ *
+ * Core Audio File Format Spec:
+ * "The high 16 bits indicates a specific ordering of the channels."
+ * Core Audio Data Types Reference:
+ * "These identifiers specify the channels included in a layout but
+ * do not specify a particular ordering of those channels."
+ */
+enum MovChannelLayoutTag {
+ MOV_CH_LAYOUT_UNKNOWN = 0xFFFF0000,
+ MOV_CH_LAYOUT_USE_DESCRIPTIONS = ( 0 << 16) | 0,
+ MOV_CH_LAYOUT_USE_BITMAP = ( 1 << 16) | 0,
+ MOV_CH_LAYOUT_DISCRETEINORDER = (147 << 16) | 0,
+ MOV_CH_LAYOUT_MONO = (100 << 16) | 1,
+ MOV_CH_LAYOUT_STEREO = (101 << 16) | 2,
+ MOV_CH_LAYOUT_STEREOHEADPHONES = (102 << 16) | 2,
+ MOV_CH_LAYOUT_MATRIXSTEREO = (103 << 16) | 2,
+ MOV_CH_LAYOUT_MIDSIDE = (104 << 16) | 2,
+ MOV_CH_LAYOUT_XY = (105 << 16) | 2,
+ MOV_CH_LAYOUT_BINAURAL = (106 << 16) | 2,
+ MOV_CH_LAYOUT_AMBISONIC_B_FORMAT = (107 << 16) | 4,
+ MOV_CH_LAYOUT_QUADRAPHONIC = (108 << 16) | 4,
+ MOV_CH_LAYOUT_PENTAGONAL = (109 << 16) | 5,
+ MOV_CH_LAYOUT_HEXAGONAL = (110 << 16) | 6,
+ MOV_CH_LAYOUT_OCTAGONAL = (111 << 16) | 8,
+ MOV_CH_LAYOUT_CUBE = (112 << 16) | 8,
+ MOV_CH_LAYOUT_MPEG_3_0_A = (113 << 16) | 3,
+ MOV_CH_LAYOUT_MPEG_3_0_B = (114 << 16) | 3,
+ MOV_CH_LAYOUT_MPEG_4_0_A = (115 << 16) | 4,
+ MOV_CH_LAYOUT_MPEG_4_0_B = (116 << 16) | 4,
+ MOV_CH_LAYOUT_MPEG_5_0_A = (117 << 16) | 5,
+ MOV_CH_LAYOUT_MPEG_5_0_B = (118 << 16) | 5,
+ MOV_CH_LAYOUT_MPEG_5_0_C = (119 << 16) | 5,
+ MOV_CH_LAYOUT_MPEG_5_0_D = (120 << 16) | 5,
+ MOV_CH_LAYOUT_MPEG_5_1_A = (121 << 16) | 6,
+ MOV_CH_LAYOUT_MPEG_5_1_B = (122 << 16) | 6,
+ MOV_CH_LAYOUT_MPEG_5_1_C = (123 << 16) | 6,
+ MOV_CH_LAYOUT_MPEG_5_1_D = (124 << 16) | 6,
+ MOV_CH_LAYOUT_MPEG_6_1_A = (125 << 16) | 7,
+ MOV_CH_LAYOUT_MPEG_7_1_A = (126 << 16) | 8,
+ MOV_CH_LAYOUT_MPEG_7_1_B = (127 << 16) | 8,
+ MOV_CH_LAYOUT_MPEG_7_1_C = (128 << 16) | 8,
+ MOV_CH_LAYOUT_EMAGIC_DEFAULT_7_1 = (129 << 16) | 8,
+ MOV_CH_LAYOUT_SMPTE_DTV = (130 << 16) | 8,
+ MOV_CH_LAYOUT_ITU_2_1 = (131 << 16) | 3,
+ MOV_CH_LAYOUT_ITU_2_2 = (132 << 16) | 4,
+ MOV_CH_LAYOUT_DVD_4 = (133 << 16) | 3,
+ MOV_CH_LAYOUT_DVD_5 = (134 << 16) | 4,
+ MOV_CH_LAYOUT_DVD_6 = (135 << 16) | 5,
+ MOV_CH_LAYOUT_DVD_10 = (136 << 16) | 4,
+ MOV_CH_LAYOUT_DVD_11 = (137 << 16) | 5,
+ MOV_CH_LAYOUT_DVD_18 = (138 << 16) | 5,
+ MOV_CH_LAYOUT_AUDIOUNIT_6_0 = (139 << 16) | 6,
+ MOV_CH_LAYOUT_AUDIOUNIT_7_0 = (140 << 16) | 7,
+ MOV_CH_LAYOUT_AUDIOUNIT_7_0_FRONT = (148 << 16) | 7,
+ MOV_CH_LAYOUT_AAC_6_0 = (141 << 16) | 6,
+ MOV_CH_LAYOUT_AAC_6_1 = (142 << 16) | 7,
+ MOV_CH_LAYOUT_AAC_7_0 = (143 << 16) | 7,
+ MOV_CH_LAYOUT_AAC_OCTAGONAL = (144 << 16) | 8,
+ MOV_CH_LAYOUT_TMH_10_2_STD = (145 << 16) | 16,
+ MOV_CH_LAYOUT_TMH_10_2_FULL = (146 << 16) | 21,
+ MOV_CH_LAYOUT_AC3_1_0_1 = (149 << 16) | 2,
+ MOV_CH_LAYOUT_AC3_3_0 = (150 << 16) | 3,
+ MOV_CH_LAYOUT_AC3_3_1 = (151 << 16) | 4,
+ MOV_CH_LAYOUT_AC3_3_0_1 = (152 << 16) | 4,
+ MOV_CH_LAYOUT_AC3_2_1_1 = (153 << 16) | 4,
+ MOV_CH_LAYOUT_AC3_3_1_1 = (154 << 16) | 5,
+ MOV_CH_LAYOUT_EAC3_6_0_A = (155 << 16) | 6,
+ MOV_CH_LAYOUT_EAC3_7_0_A = (156 << 16) | 7,
+ MOV_CH_LAYOUT_EAC3_6_1_A = (157 << 16) | 7,
+ MOV_CH_LAYOUT_EAC3_6_1_B = (158 << 16) | 7,
+ MOV_CH_LAYOUT_EAC3_6_1_C = (159 << 16) | 7,
+ MOV_CH_LAYOUT_EAC3_7_1_A = (160 << 16) | 8,
+ MOV_CH_LAYOUT_EAC3_7_1_B = (161 << 16) | 8,
+ MOV_CH_LAYOUT_EAC3_7_1_C = (162 << 16) | 8,
+ MOV_CH_LAYOUT_EAC3_7_1_D = (163 << 16) | 8,
+ MOV_CH_LAYOUT_EAC3_7_1_E = (164 << 16) | 8,
+ MOV_CH_LAYOUT_EAC3_7_1_F = (165 << 16) | 8,
+ MOV_CH_LAYOUT_EAC3_7_1_G = (166 << 16) | 8,
+ MOV_CH_LAYOUT_EAC3_7_1_H = (167 << 16) | 8,
+ MOV_CH_LAYOUT_DTS_3_1 = (168 << 16) | 4,
+ MOV_CH_LAYOUT_DTS_4_1 = (169 << 16) | 5,
+ MOV_CH_LAYOUT_DTS_6_0_A = (170 << 16) | 6,
+ MOV_CH_LAYOUT_DTS_6_0_B = (171 << 16) | 6,
+ MOV_CH_LAYOUT_DTS_6_0_C = (172 << 16) | 6,
+ MOV_CH_LAYOUT_DTS_6_1_A = (173 << 16) | 7,
+ MOV_CH_LAYOUT_DTS_6_1_B = (174 << 16) | 7,
+ MOV_CH_LAYOUT_DTS_6_1_C = (175 << 16) | 7,
+ MOV_CH_LAYOUT_DTS_6_1_D = (182 << 16) | 7,
+ MOV_CH_LAYOUT_DTS_7_0 = (176 << 16) | 7,
+ MOV_CH_LAYOUT_DTS_7_1 = (177 << 16) | 8,
+ MOV_CH_LAYOUT_DTS_8_0_A = (178 << 16) | 8,
+ MOV_CH_LAYOUT_DTS_8_0_B = (179 << 16) | 8,
+ MOV_CH_LAYOUT_DTS_8_1_A = (180 << 16) | 9,
+ MOV_CH_LAYOUT_DTS_8_1_B = (181 << 16) | 9,
+};
+
+struct MovChannelLayoutMap {
+ uint32_t tag;
+ uint64_t layout;
+};
+
+static const struct MovChannelLayoutMap mov_ch_layout_map_misc[] = {
+ { MOV_CH_LAYOUT_USE_DESCRIPTIONS, 0 },
+ { MOV_CH_LAYOUT_USE_BITMAP, 0 },
+ { MOV_CH_LAYOUT_DISCRETEINORDER, 0 },
+ { MOV_CH_LAYOUT_UNKNOWN, 0 },
+ { MOV_CH_LAYOUT_TMH_10_2_STD, 0 }, // L, R, C, Vhc, Lsd, Rsd,
+ // Ls, Rs, Vhl, Vhr, Lw, Rw,
+ // Csd, Cs, LFE1, LFE2
+ { MOV_CH_LAYOUT_TMH_10_2_FULL, 0 }, // L, R, C, Vhc, Lsd, Rsd,
+ // Ls, Rs, Vhl, Vhr, Lw, Rw,
+ // Csd, Cs, LFE1, LFE2, Lc, Rc,
+ // HI, VI, Haptic
+ { 0, 0 },
+};
+
+static const struct MovChannelLayoutMap mov_ch_layout_map_1ch[] = {
+ { MOV_CH_LAYOUT_MONO, AV_CH_LAYOUT_MONO }, // C
+};
+
+static const struct MovChannelLayoutMap mov_ch_layout_map_2ch[] = {
+ { MOV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO }, // L, R
+ { MOV_CH_LAYOUT_STEREOHEADPHONES, AV_CH_LAYOUT_STEREO }, // L, R
+ { MOV_CH_LAYOUT_BINAURAL, AV_CH_LAYOUT_STEREO }, // L, R
+ { MOV_CH_LAYOUT_MIDSIDE, AV_CH_LAYOUT_STEREO }, // C, sides
+ { MOV_CH_LAYOUT_XY, AV_CH_LAYOUT_STEREO }, // X (left), Y (right)
+
+ { MOV_CH_LAYOUT_MATRIXSTEREO, AV_CH_LAYOUT_STEREO_DOWNMIX }, // Lt, Rt
+
+ { MOV_CH_LAYOUT_AC3_1_0_1, AV_CH_LAYOUT_MONO | // C, LFE
+ AV_CH_LOW_FREQUENCY },
+ { 0, 0 },
+};
+
+static const struct MovChannelLayoutMap mov_ch_layout_map_3ch[] = {
+ { MOV_CH_LAYOUT_MPEG_3_0_A, AV_CH_LAYOUT_SURROUND }, // L, R, C
+ { MOV_CH_LAYOUT_MPEG_3_0_B, AV_CH_LAYOUT_SURROUND }, // C, L, R
+ { MOV_CH_LAYOUT_AC3_3_0, AV_CH_LAYOUT_SURROUND }, // L, C, R
+
+ { MOV_CH_LAYOUT_ITU_2_1, AV_CH_LAYOUT_2_1 }, // L, R, Cs
+
+ { MOV_CH_LAYOUT_DVD_4, AV_CH_LAYOUT_2POINT1 }, // L, R, LFE
+ { 0, 0 },
+};
+
+static const struct MovChannelLayoutMap mov_ch_layout_map_4ch[] = {
+ { MOV_CH_LAYOUT_AMBISONIC_B_FORMAT, 0 }, // W, X, Y, Z
+
+ { MOV_CH_LAYOUT_QUADRAPHONIC, AV_CH_LAYOUT_QUAD }, // L, R, Rls, Rrs
+
+ { MOV_CH_LAYOUT_MPEG_4_0_A, AV_CH_LAYOUT_4POINT0 }, // L, R, C, Cs
+ { MOV_CH_LAYOUT_MPEG_4_0_B, AV_CH_LAYOUT_4POINT0 }, // C, L, R, Cs
+ { MOV_CH_LAYOUT_AC3_3_1, AV_CH_LAYOUT_4POINT0 }, // L, C, R, Cs
+
+ { MOV_CH_LAYOUT_ITU_2_2, AV_CH_LAYOUT_2_2 }, // L, R, Ls, Rs
+
+ { MOV_CH_LAYOUT_DVD_5, AV_CH_LAYOUT_2_1 | // L, R, LFE, Cs
+ AV_CH_LOW_FREQUENCY },
+ { MOV_CH_LAYOUT_AC3_2_1_1, AV_CH_LAYOUT_2_1 | // L, R, Cs, LFE
+ AV_CH_LOW_FREQUENCY },
+
+ { MOV_CH_LAYOUT_DVD_10, AV_CH_LAYOUT_3POINT1 }, // L, R, C, LFE
+ { MOV_CH_LAYOUT_AC3_3_0_1, AV_CH_LAYOUT_3POINT1 }, // L, C, R, LFE
+ { MOV_CH_LAYOUT_DTS_3_1, AV_CH_LAYOUT_3POINT1 }, // C, L, R, LFE
+ { 0, 0 },
+};
+
+static const struct MovChannelLayoutMap mov_ch_layout_map_5ch[] = {
+ { MOV_CH_LAYOUT_PENTAGONAL, AV_CH_LAYOUT_5POINT0_BACK }, // L, R, Rls, Rrs, C
+
+ { MOV_CH_LAYOUT_MPEG_5_0_A, AV_CH_LAYOUT_5POINT0 }, // L, R, C, Ls, Rs
+ { MOV_CH_LAYOUT_MPEG_5_0_B, AV_CH_LAYOUT_5POINT0 }, // L, R, Ls, Rs, C
+ { MOV_CH_LAYOUT_MPEG_5_0_C, AV_CH_LAYOUT_5POINT0 }, // L, C, R, Ls, Rs
+ { MOV_CH_LAYOUT_MPEG_5_0_D, AV_CH_LAYOUT_5POINT0 }, // C, L, R, Ls, Rs
+
+ { MOV_CH_LAYOUT_DVD_6, AV_CH_LAYOUT_2_2 | // L, R, LFE, Ls, Rs
+ AV_CH_LOW_FREQUENCY },
+ { MOV_CH_LAYOUT_DVD_18, AV_CH_LAYOUT_2_2 | // L, R, Ls, Rs, LFE
+ AV_CH_LOW_FREQUENCY },
+
+ { MOV_CH_LAYOUT_DVD_11, AV_CH_LAYOUT_4POINT1 }, // L, R, C, LFE, Cs
+ { MOV_CH_LAYOUT_AC3_3_1_1, AV_CH_LAYOUT_4POINT1 }, // L, C, R, Cs, LFE
+ { MOV_CH_LAYOUT_DTS_4_1, AV_CH_LAYOUT_4POINT1 }, // C, L, R, Cs, LFE
+ { 0, 0 },
+};
+
+static const struct MovChannelLayoutMap mov_ch_layout_map_6ch[] = {
+ { MOV_CH_LAYOUT_HEXAGONAL, AV_CH_LAYOUT_HEXAGONAL }, // L, R, Rls, Rrs, C, Cs
+ { MOV_CH_LAYOUT_DTS_6_0_C, AV_CH_LAYOUT_HEXAGONAL }, // C, Cs, L, R, Rls, Rrs
+
+ { MOV_CH_LAYOUT_MPEG_5_1_A, AV_CH_LAYOUT_5POINT1 }, // L, R, C, LFE, Ls, Rs
+ { MOV_CH_LAYOUT_MPEG_5_1_B, AV_CH_LAYOUT_5POINT1 }, // L, R, Ls, Rs, C, LFE
+ { MOV_CH_LAYOUT_MPEG_5_1_C, AV_CH_LAYOUT_5POINT1 }, // L, C, R, Ls, Rs, LFE
+ { MOV_CH_LAYOUT_MPEG_5_1_D, AV_CH_LAYOUT_5POINT1 }, // C, L, R, Ls, Rs, LFE
+
+ { MOV_CH_LAYOUT_AUDIOUNIT_6_0, AV_CH_LAYOUT_6POINT0 }, // L, R, Ls, Rs, C, Cs
+ { MOV_CH_LAYOUT_AAC_6_0, AV_CH_LAYOUT_6POINT0 }, // C, L, R, Ls, Rs, Cs
+ { MOV_CH_LAYOUT_EAC3_6_0_A, AV_CH_LAYOUT_6POINT0 }, // L, C, R, Ls, Rs, Cs
+
+ { MOV_CH_LAYOUT_DTS_6_0_A, AV_CH_LAYOUT_6POINT0_FRONT }, // Lc, Rc, L, R, Ls, Rs
+
+ { MOV_CH_LAYOUT_DTS_6_0_B, AV_CH_LAYOUT_5POINT0_BACK | // C, L, R, Rls, Rrs, Ts
+ AV_CH_TOP_CENTER },
+ { 0, 0 },
+};
+
+static const struct MovChannelLayoutMap mov_ch_layout_map_7ch[] = {
+ { MOV_CH_LAYOUT_MPEG_6_1_A, AV_CH_LAYOUT_6POINT1 }, // L, R, C, LFE, Ls, Rs, Cs
+ { MOV_CH_LAYOUT_AAC_6_1, AV_CH_LAYOUT_6POINT1 }, // C, L, R, Ls, Rs, Cs, LFE
+ { MOV_CH_LAYOUT_EAC3_6_1_A, AV_CH_LAYOUT_6POINT1 }, // L, C, R, Ls, Rs, LFE, Cs
+ { MOV_CH_LAYOUT_DTS_6_1_D, AV_CH_LAYOUT_6POINT1 }, // C, L, R, Ls, Rs, LFE, Cs
+
+ { MOV_CH_LAYOUT_AUDIOUNIT_7_0, AV_CH_LAYOUT_7POINT0 }, // L, R, Ls, Rs, C, Rls, Rrs
+ { MOV_CH_LAYOUT_AAC_7_0, AV_CH_LAYOUT_7POINT0 }, // C, L, R, Ls, Rs, Rls, Rrs
+ { MOV_CH_LAYOUT_EAC3_7_0_A, AV_CH_LAYOUT_7POINT0 }, // L, C, R, Ls, Rs, Rls, Rrs
+
+ { MOV_CH_LAYOUT_AUDIOUNIT_7_0_FRONT, AV_CH_LAYOUT_7POINT0_FRONT }, // L, R, Ls, Rs, C, Lc, Rc
+ { MOV_CH_LAYOUT_DTS_7_0, AV_CH_LAYOUT_7POINT0_FRONT }, // Lc, C, Rc, L, R, Ls, Rs
+
+ { MOV_CH_LAYOUT_EAC3_6_1_B, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Ts
+ AV_CH_TOP_CENTER },
+
+ { MOV_CH_LAYOUT_EAC3_6_1_C, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Vhc
+ AV_CH_TOP_FRONT_CENTER },
+
+ { MOV_CH_LAYOUT_DTS_6_1_A, AV_CH_LAYOUT_6POINT1_FRONT }, // Lc, Rc, L, R, Ls, Rs, LFE
+
+ { MOV_CH_LAYOUT_DTS_6_1_B, AV_CH_LAYOUT_5POINT1_BACK | // C, L, R, Rls, Rrs, Ts, LFE
+ AV_CH_TOP_CENTER },
+
+ { MOV_CH_LAYOUT_DTS_6_1_C, AV_CH_LAYOUT_6POINT1_BACK }, // C, Cs, L, R, Rls, Rrs, LFE
+ { 0, 0 },
+};
+
+static const struct MovChannelLayoutMap mov_ch_layout_map_8ch[] = {
+ { MOV_CH_LAYOUT_OCTAGONAL, AV_CH_LAYOUT_OCTAGONAL }, // L, R, Rls, Rrs, C, Cs, Ls, Rs
+ { MOV_CH_LAYOUT_AAC_OCTAGONAL, AV_CH_LAYOUT_OCTAGONAL }, // C, L, R, Ls, Rs, Rls, Rrs, Cs
+
+ { MOV_CH_LAYOUT_CUBE, AV_CH_LAYOUT_QUAD | // L, R, Rls, Rrs, Vhl, Vhr, Rlt, Rrt
+ AV_CH_TOP_FRONT_LEFT |
+ AV_CH_TOP_FRONT_RIGHT |
+ AV_CH_TOP_BACK_LEFT |
+ AV_CH_TOP_BACK_RIGHT },
+
+ { MOV_CH_LAYOUT_MPEG_7_1_A, AV_CH_LAYOUT_7POINT1_WIDE }, // L, R, C, LFE, Ls, Rs, Lc, Rc
+ { MOV_CH_LAYOUT_MPEG_7_1_B, AV_CH_LAYOUT_7POINT1_WIDE }, // C, Lc, Rc, L, R, Ls, Rs, LFE
+ { MOV_CH_LAYOUT_EMAGIC_DEFAULT_7_1, AV_CH_LAYOUT_7POINT1_WIDE }, // L, R, Ls, Rs, C, LFE, Lc, Rc
+ { MOV_CH_LAYOUT_EAC3_7_1_B, AV_CH_LAYOUT_7POINT1_WIDE }, // L, C, R, Ls, Rs, LFE, Lc, Rc
+ { MOV_CH_LAYOUT_DTS_7_1, AV_CH_LAYOUT_7POINT1_WIDE }, // Lc, C, Rc, L, R, Ls, Rs, LFE
+
+ { MOV_CH_LAYOUT_MPEG_7_1_C, AV_CH_LAYOUT_7POINT1 }, // L, R, C, LFE, Ls, Rs, Rls, Rrs
+ { MOV_CH_LAYOUT_EAC3_7_1_A, AV_CH_LAYOUT_7POINT1 }, // L, C, R, Ls, Rs, LFE, Rls, Rrs
+
+ { MOV_CH_LAYOUT_SMPTE_DTV, AV_CH_LAYOUT_5POINT1 | // L, R, C, LFE, Ls, Rs, Lt, Rt
+ AV_CH_LAYOUT_STEREO_DOWNMIX },
+
+ { MOV_CH_LAYOUT_EAC3_7_1_C, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Lsd, Rsd
+ AV_CH_SURROUND_DIRECT_LEFT |
+ AV_CH_SURROUND_DIRECT_RIGHT },
+
+ { MOV_CH_LAYOUT_EAC3_7_1_D, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Lw, Rw
+ AV_CH_WIDE_LEFT |
+ AV_CH_WIDE_RIGHT },
+
+ { MOV_CH_LAYOUT_EAC3_7_1_E, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Vhl, Vhr
+ AV_CH_TOP_FRONT_LEFT |
+ AV_CH_TOP_FRONT_RIGHT },
+
+ { MOV_CH_LAYOUT_EAC3_7_1_F, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Cs, Ts
+ AV_CH_BACK_CENTER |
+ AV_CH_TOP_CENTER },
+
+ { MOV_CH_LAYOUT_EAC3_7_1_G, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Cs, Vhc
+ AV_CH_BACK_CENTER |
+ AV_CH_TOP_FRONT_CENTER },
+
+ { MOV_CH_LAYOUT_EAC3_7_1_H, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Ts, Vhc
+ AV_CH_TOP_CENTER |
+ AV_CH_TOP_FRONT_CENTER },
+
+ { MOV_CH_LAYOUT_DTS_8_0_A, AV_CH_LAYOUT_2_2 | // Lc, Rc, L, R, Ls, Rs, Rls, Rrs
+ AV_CH_BACK_LEFT |
+ AV_CH_BACK_RIGHT |
+ AV_CH_FRONT_LEFT_OF_CENTER |
+ AV_CH_FRONT_RIGHT_OF_CENTER },
+
+ { MOV_CH_LAYOUT_DTS_8_0_B, AV_CH_LAYOUT_5POINT0 | // Lc, C, Rc, L, R, Ls, Cs, Rs
+ AV_CH_FRONT_LEFT_OF_CENTER |
+ AV_CH_FRONT_RIGHT_OF_CENTER |
+ AV_CH_BACK_CENTER },
+ { 0, 0 },
+};
+
+static const struct MovChannelLayoutMap mov_ch_layout_map_9ch[] = {
+ { MOV_CH_LAYOUT_DTS_8_1_A, AV_CH_LAYOUT_2_2 | // Lc, Rc, L, R, Ls, Rs, Rls, Rrs, LFE
+ AV_CH_BACK_LEFT |
+ AV_CH_BACK_RIGHT |
+ AV_CH_FRONT_LEFT_OF_CENTER |
+ AV_CH_FRONT_RIGHT_OF_CENTER |
+ AV_CH_LOW_FREQUENCY },
+
+ { MOV_CH_LAYOUT_DTS_8_1_B, AV_CH_LAYOUT_7POINT1_WIDE | // Lc, C, Rc, L, R, Ls, Cs, Rs, LFE
+ AV_CH_BACK_CENTER },
+ { 0, 0 },
+};
+
+static const struct MovChannelLayoutMap *mov_ch_layout_map[] = {
+ mov_ch_layout_map_misc,
+ mov_ch_layout_map_1ch,
+ mov_ch_layout_map_2ch,
+ mov_ch_layout_map_3ch,
+ mov_ch_layout_map_4ch,
+ mov_ch_layout_map_5ch,
+ mov_ch_layout_map_6ch,
+ mov_ch_layout_map_7ch,
+ mov_ch_layout_map_8ch,
+ mov_ch_layout_map_9ch,
+};
+
+static const enum MovChannelLayoutTag mov_ch_layouts_aac[] = {
+ MOV_CH_LAYOUT_MONO,
+ MOV_CH_LAYOUT_STEREO,
+ MOV_CH_LAYOUT_AC3_1_0_1,
+ MOV_CH_LAYOUT_MPEG_3_0_B,
+ MOV_CH_LAYOUT_ITU_2_1,
+ MOV_CH_LAYOUT_DVD_4,
+ MOV_CH_LAYOUT_QUADRAPHONIC,
+ MOV_CH_LAYOUT_MPEG_4_0_B,
+ MOV_CH_LAYOUT_ITU_2_2,
+ MOV_CH_LAYOUT_AC3_2_1_1,
+ MOV_CH_LAYOUT_DTS_3_1,
+ MOV_CH_LAYOUT_MPEG_5_0_D,
+ MOV_CH_LAYOUT_DVD_18,
+ MOV_CH_LAYOUT_DTS_4_1,
+ MOV_CH_LAYOUT_MPEG_5_1_D,
+ MOV_CH_LAYOUT_AAC_6_0,
+ MOV_CH_LAYOUT_DTS_6_0_A,
+ MOV_CH_LAYOUT_AAC_6_1,
+ MOV_CH_LAYOUT_AAC_7_0,
+ MOV_CH_LAYOUT_DTS_6_1_A,
+ MOV_CH_LAYOUT_AAC_OCTAGONAL,
+ MOV_CH_LAYOUT_MPEG_7_1_B,
+ MOV_CH_LAYOUT_DTS_8_0_A,
+ 0,
+};
+
+static const enum MovChannelLayoutTag mov_ch_layouts_ac3[] = {
+ MOV_CH_LAYOUT_MONO,
+ MOV_CH_LAYOUT_STEREO,
+ MOV_CH_LAYOUT_AC3_1_0_1,
+ MOV_CH_LAYOUT_AC3_3_0,
+ MOV_CH_LAYOUT_ITU_2_1,
+ MOV_CH_LAYOUT_DVD_4,
+ MOV_CH_LAYOUT_AC3_3_1,
+ MOV_CH_LAYOUT_ITU_2_2,
+ MOV_CH_LAYOUT_AC3_2_1_1,
+ MOV_CH_LAYOUT_AC3_3_0_1,
+ MOV_CH_LAYOUT_MPEG_5_0_C,
+ MOV_CH_LAYOUT_DVD_18,
+ MOV_CH_LAYOUT_AC3_3_1_1,
+ MOV_CH_LAYOUT_MPEG_5_1_C,
+ 0,
+};
+
+static const enum MovChannelLayoutTag mov_ch_layouts_alac[] = {
+ MOV_CH_LAYOUT_MONO,
+ MOV_CH_LAYOUT_STEREO,
+ MOV_CH_LAYOUT_MPEG_3_0_B,
+ MOV_CH_LAYOUT_MPEG_4_0_B,
+ MOV_CH_LAYOUT_MPEG_5_0_D,
+ MOV_CH_LAYOUT_MPEG_5_1_D,
+ MOV_CH_LAYOUT_AAC_6_1,
+ MOV_CH_LAYOUT_MPEG_7_1_B,
+ 0,
+};
+
+static const struct {
+ enum CodecID codec_id;
+ const enum MovChannelLayoutTag *layouts;
+} mov_codec_ch_layouts[] = {
+ { CODEC_ID_AAC, mov_ch_layouts_aac },
+ { CODEC_ID_AC3, mov_ch_layouts_ac3 },
+ { CODEC_ID_ALAC, mov_ch_layouts_alac },
+ { CODEC_ID_NONE, NULL },
+};
+
+uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap)
+{
+ int i, channels;
+ const struct MovChannelLayoutMap *layout_map;
+
+ /* handle the use of the channel descriptions */
+ /* TODO: map MOV channel labels to Libav channels */
+ if (tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS)
+ return 0;
+
+ /* handle the use of the channel bitmap */
+ if (tag == MOV_CH_LAYOUT_USE_BITMAP)
+ return bitmap < 0x40000 ? bitmap : 0;
+
+ /* get the layout map based on the channel count for the specified layout tag */
+ channels = tag & 0xFFFF;
+ if (channels > 9)
+ channels = 0;
+ layout_map = mov_ch_layout_map[channels];
+
+ /* find the channel layout for the specified layout tag */
+ for (i = 0; layout_map[i].tag != 0; i++) {
+ if (layout_map[i].tag == tag)
+ break;
+ }
+ return layout_map[i].layout;
+}
+
+uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id,
+ uint64_t channel_layout,
+ uint32_t *bitmap)
+{
+ int i, j;
+ uint32_t tag = 0;
+ const enum MovChannelLayoutTag *layouts = NULL;
+
+ /* find the layout list for the specified codec */
+ for (i = 0; mov_codec_ch_layouts[i].codec_id != CODEC_ID_NONE; i++) {
+ if (mov_codec_ch_layouts[i].codec_id == codec_id)
+ break;
+ }
+ if (mov_codec_ch_layouts[i].codec_id != CODEC_ID_NONE)
+ layouts = mov_codec_ch_layouts[i].layouts;
+
+ if (layouts) {
+ int channels;
+ const struct MovChannelLayoutMap *layout_map;
+
+ /* get the layout map based on the channel count */
+ channels = av_get_channel_layout_nb_channels(channel_layout);
+ if (channels > 9)
+ channels = 0;
+ layout_map = mov_ch_layout_map[channels];
+
+ /* find the layout tag for the specified channel layout */
+ for (i = 0; layouts[i] != 0; i++) {
+ if (layouts[i] & 0xFFFF != channels)
+ continue;
+ for (j = 0; layout_map[j].tag != 0; j++) {
+ if (layout_map[j].tag == layouts[i] &&
+ layout_map[j].layout == channel_layout)
+ break;
+ }
+ if (layout_map[j].tag)
+ break;
+ }
+ tag = layouts[i];
+ }
+
+ /* if no tag was found, use channel bitmap as a backup if possible */
+ if (tag == 0 && channel_layout > 0 && channel_layout < 0x40000) {
+ tag = MOV_CH_LAYOUT_USE_BITMAP;
+ *bitmap = (uint32_t)channel_layout;
+ } else
+ *bitmap = 0;
+
+ /* TODO: set channel descriptions as a secondary backup */
+
+ return tag;
+}
diff --git a/libavformat/mov_chan.h b/libavformat/mov_chan.h
new file mode 100644
index 0000000..9723340
--- /dev/null
+++ b/libavformat/mov_chan.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011 Justin Ruggles
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * mov 'chan' tag reading/writing.
+ * @author Justin Ruggles
+ */
+
+#ifndef AVFORMAT_MOV_CHAN_H
+#define AVFORMAT_MOV_CHAN_H
+
+#include <stdint.h>
+
+#include "libavcodec/avcodec.h"
+
+/**
+ * Get the channel layout for the specified channel layout tag.
+ *
+ * @param[in] tag channel layout tag
+ * @param[out] bitmap channel bitmap (only used if needed)
+ * @return channel layout
+ */
+uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap);
+
+/**
+ * Get the channel layout tag for the specified codec id and channel layout.
+ * If the layout tag was not found, use a channel bitmap if possible.
+ *
+ * @param[in] codec_id codec id
+ * @param[in] channel_layout channel layout
+ * @param[out] bitmap channel bitmap
+ * @return channel layout tag
+ */
+uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id,
+ uint64_t channel_layout,
+ uint32_t *bitmap);
+
+#endif /* AVFORMAT_MOV_CHAN_H */
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index b171c2d..e11eb50 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -32,25 +32,32 @@
#include "libavcodec/put_bits.h"
#include "internal.h"
#include "libavutil/avstring.h"
+#include "libavutil/intfloat.h"
+#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
#include "rtpenc.h"
+#include "mov_chan.h"
#undef NDEBUG
#include <assert.h>
static const AVOption options[] = {
- { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), FF_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
- { "rtphint", "Add RTP hint tracks", 0, FF_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+ { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+ { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
+ { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
+ { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.dbl = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
+ { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.dbl = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
{ NULL },
};
-static const AVClass mov_muxer_class = {
- .class_name = "MOV/3GP/MP4/3G2 muxer",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
+#define MOV_CLASS(flavor)\
+static const AVClass flavor ## _muxer_class = {\
+ .class_name = #flavor " muxer",\
+ .item_name = av_default_item_name,\
+ .option = options,\
+ .version = LIBAVUTIL_VERSION_INT,\
};
//FIXME support 64 bit variant with wide placeholders
@@ -239,7 +246,7 @@ static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track)
/**
* This function writes extradata "as is".
- * Extradata must be formated like a valid atom (with size and tag)
+ * Extradata must be formatted like a valid atom (with size and tag).
*/
static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
{
@@ -335,6 +342,31 @@ static int mov_write_ms_tag(AVIOContext *pb, MOVTrack *track)
return updateSize(pb, pos);
}
+static int mov_write_chan_tag(AVIOContext *pb, MOVTrack *track)
+{
+ uint32_t layout_tag, bitmap;
+ int64_t pos = avio_tell(pb);
+
+ layout_tag = ff_mov_get_channel_layout_tag(track->enc->codec_id,
+ track->enc->channel_layout,
+ &bitmap);
+ if (!layout_tag) {
+ av_log(track->enc, AV_LOG_WARNING, "not writing 'chan' tag due to "
+ "lack of channel information\n");
+ return 0;
+ }
+
+ avio_wb32(pb, 0); // Size
+ ffio_wfourcc(pb, "chan"); // Type
+ avio_w8(pb, 0); // Version
+ avio_wb24(pb, 0); // Flags
+ avio_wb32(pb, layout_tag); // mChannelLayoutTag
+ avio_wb32(pb, bitmap); // mChannelBitmap
+ avio_wb32(pb, 0); // mNumberChannelDescriptions
+
+ return updateSize(pb, pos);
+}
+
static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track)
{
int64_t pos = avio_tell(pb);
@@ -357,6 +389,7 @@ static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track)
} else if (track->enc->codec_id == CODEC_ID_AMR_NB) {
mov_write_amr_tag(pb, track);
} else if (track->enc->codec_id == CODEC_ID_AC3) {
+ mov_write_chan_tag(pb, track);
mov_write_ac3_tag(pb, track);
} else if (track->enc->codec_id == CODEC_ID_ALAC) {
mov_write_extradata_tag(pb, track);
@@ -415,15 +448,9 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
uint32_t tag = track->tag;
if (track->mode == MODE_MOV) {
- if (track->timescale > UINT16_MAX) {
- if (mov_get_lpcm_flags(track->enc->codec_id))
- tag = AV_RL32("lpcm");
- version = 2;
- } else if (track->audio_vbr || mov_pcm_le_gt16(track->enc->codec_id) ||
- track->enc->codec_id == CODEC_ID_ADPCM_MS ||
- track->enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) {
- version = 1;
- }
+ if (mov_get_lpcm_flags(track->enc->codec_id))
+ tag = AV_RL32("lpcm");
+ version = 2;
}
avio_wb32(pb, 0); /* size */
@@ -444,40 +471,24 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
avio_wb16(pb, 0);
avio_wb32(pb, 0x00010000);
avio_wb32(pb, 72);
- avio_wb64(pb, av_dbl2int(track->timescale));
+ avio_wb64(pb, av_double2int(track->timescale));
avio_wb32(pb, track->enc->channels);
avio_wb32(pb, 0x7F000000);
avio_wb32(pb, av_get_bits_per_sample(track->enc->codec_id));
avio_wb32(pb, mov_get_lpcm_flags(track->enc->codec_id));
avio_wb32(pb, track->sampleSize);
- avio_wb32(pb, track->enc->frame_size);
+ avio_wb32(pb, track->audio_vbr ? track->enc->frame_size : 1);
} else {
- if (track->mode == MODE_MOV) {
- avio_wb16(pb, track->enc->channels);
- if (track->enc->codec_id == CODEC_ID_PCM_U8 ||
- track->enc->codec_id == CODEC_ID_PCM_S8)
- avio_wb16(pb, 8); /* bits per sample */
- else
- avio_wb16(pb, 16);
- avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
- } else { /* reserved for mp4/3gp */
- avio_wb16(pb, 2);
- avio_wb16(pb, 16);
- avio_wb16(pb, 0);
- }
+ /* reserved for mp4/3gp */
+ avio_wb16(pb, 2);
+ avio_wb16(pb, 16);
+ avio_wb16(pb, 0);
avio_wb16(pb, 0); /* packet size (= 0) */
avio_wb16(pb, track->timescale); /* Time scale */
avio_wb16(pb, 0); /* Reserved */
}
- if(version == 1) { /* SoundDescription V1 extended info */
- avio_wb32(pb, track->enc->frame_size); /* Samples per packet */
- avio_wb32(pb, track->sampleSize / track->enc->channels); /* Bytes per packet */
- avio_wb32(pb, track->sampleSize); /* Bytes per frame */
- avio_wb32(pb, 2); /* Bytes per sample */
- }
-
if(track->mode == MODE_MOV &&
(track->enc->codec_id == CODEC_ID_AAC ||
track->enc->codec_id == CODEC_ID_AC3 ||
@@ -709,7 +720,7 @@ static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
if (!tag) { // if no mac fcc found, try with Microsoft tags
tag = ff_codec_get_tag(ff_codec_bmp_tags, track->enc->codec_id);
if (tag)
- av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, "
+ av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
"the file may be unplayable!\n");
}
} else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -718,7 +729,7 @@ static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->enc->codec_id);
if (ms_tag) {
tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
- av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, "
+ av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
"the file may be unplayable!\n");
}
}
@@ -772,6 +783,23 @@ static int mov_write_uuid_tag_ipod(AVIOContext *pb)
return 28;
}
+static const uint16_t fiel_data[] = {
+ 0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
+};
+
+static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track)
+{
+ unsigned mov_field_order = 0;
+ if (track->enc->field_order < FF_ARRAY_ELEMS(fiel_data))
+ mov_field_order = fiel_data[track->enc->field_order];
+ else
+ return 0;
+ avio_wb32(pb, 10);
+ ffio_wfourcc(pb, "fiel");
+ avio_wb16(pb, mov_field_order);
+ return 10;
+}
+
static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track)
{
int64_t pos = avio_tell(pb);
@@ -858,7 +886,9 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
mov_write_avcc_tag(pb, track);
if(track->mode == MODE_IPOD)
mov_write_uuid_tag_ipod(pb);
- } else if(track->vosLen > 0)
+ } else if (track->enc->field_order != AV_FIELD_UNKNOWN)
+ mov_write_fiel_tag(pb, track);
+ else if(track->vosLen > 0)
mov_write_glbl_tag(pb, track);
if (track->enc->sample_aspect_ratio.den && track->enc->sample_aspect_ratio.num &&
@@ -1278,7 +1308,7 @@ static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
avio_wb32(pb, track->enc->height << 16);
return updateSize(pb, pos);
-};
+}
// This box seems important for the psp playback ... without it the movie seems to hang
static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track)
@@ -1399,21 +1429,34 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
return updateSize(pb, pos);
}
-#if 0
-/* TODO: Not sorted out, but not necessary either */
static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
{
- avio_wb32(pb, 0x15); /* size */
+ int i, has_audio = 0, has_video = 0;
+ int64_t pos = avio_tell(pb);
+ int audio_profile = mov->iods_audio_profile;
+ int video_profile = mov->iods_video_profile;
+ for (i = 0; i < mov->nb_streams; i++) {
+ if(mov->tracks[i].entry > 0) {
+ has_audio |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_AUDIO;
+ has_video |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_VIDEO;
+ }
+ }
+ if (audio_profile < 0)
+ audio_profile = 0xFF - has_audio;
+ if (video_profile < 0)
+ video_profile = 0xFF - has_video;
+ avio_wb32(pb, 0x0); /* size */
ffio_wfourcc(pb, "iods");
avio_wb32(pb, 0); /* version & flags */
- avio_wb16(pb, 0x1007);
- avio_w8(pb, 0);
- avio_wb16(pb, 0x4fff);
- avio_wb16(pb, 0xfffe);
- avio_wb16(pb, 0x01ff);
- return 0x15;
+ putDescr(pb, 0x10, 7);
+ avio_wb16(pb, 0x004f);
+ avio_w8(pb, 0xff);
+ avio_w8(pb, 0xff);
+ avio_w8(pb, audio_profile);
+ avio_w8(pb, video_profile);
+ avio_w8(pb, 0xff);
+ return updateSize(pb, pos);
}
-#endif
static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
{
@@ -1821,7 +1864,8 @@ static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
}
mov_write_mvhd_tag(pb, mov);
- //mov_write_iods_tag(pb, mov);
+ if (mov->mode != MODE_MOV && !mov->iods_skip)
+ mov_write_iods_tag(pb, mov);
for (i=0; i<mov->nb_streams; i++) {
if(mov->tracks[i].entry > 0) {
mov_write_trak_tag(pb, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL);
@@ -1994,6 +2038,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
AVCodecContext *enc = trk->enc;
unsigned int samplesInChunk = 0;
int size= pkt->size;
+ uint8_t *reformatted_data = NULL;
if (!s->pb->seekable) return 0; /* Can't handle that */
if (!size) return 0; /* Discard 0 sized packets */
@@ -2001,7 +2046,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
if (enc->codec_id == CODEC_ID_AMR_NB) {
/* We must find out how many AMR blocks there are in one packet */
static uint16_t packed_size[16] =
- {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0};
+ {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
int len = 0;
while (len < size && samplesInChunk < 100) {
@@ -2012,9 +2057,6 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
return -1;
}
- } else if (enc->codec_id == CODEC_ID_ADPCM_MS ||
- enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) {
- samplesInChunk = enc->frame_size;
} else if (trk->sampleSize)
samplesInChunk = size/trk->sampleSize;
else
@@ -2030,7 +2072,13 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
if (enc->codec_id == CODEC_ID_H264 && trk->vosLen > 0 && *(uint8_t *)trk->vosData != 1) {
/* from x264 or from bytestream h264 */
/* nal reformating needed */
- size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
+ if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
+ ff_avc_parse_nal_units_buf(pkt->data, &reformatted_data,
+ &size);
+ avio_write(pb, reformatted_data, size);
+ } else {
+ size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
+ }
} else {
avio_write(pb, pkt->data, size);
}
@@ -2085,7 +2133,9 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
avio_flush(pb);
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams)
- ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry);
+ ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry,
+ reformatted_data, size);
+ av_free(reformatted_data);
return 0;
}
@@ -2101,7 +2151,7 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
track->mode = mov->mode;
track->tag = MKTAG('t','e','x','t');
track->timescale = MOV_TIMESCALE;
- track->enc = avcodec_alloc_context();
+ track->enc = avcodec_alloc_context3(NULL);
track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
for (i = 0; i < s->nb_chapters; i++) {
@@ -2128,6 +2178,7 @@ static int mov_write_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
MOVMuxContext *mov = s->priv_data;
+ AVDictionaryEntry *t;
int i, hint_track = 0;
if (!s->pb->seekable) {
@@ -2220,21 +2271,21 @@ static int mov_write_header(AVFormatContext *s)
"or choose different container.\n");
}else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){
track->timescale = st->codec->sample_rate;
- if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
- av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i);
- goto error;
- }else if(st->codec->codec_id == CODEC_ID_ADPCM_MS ||
- st->codec->codec_id == CODEC_ID_ADPCM_IMA_WAV){
+ /* set sampleSize for PCM and ADPCM */
+ if (av_get_bits_per_sample(st->codec->codec_id)) {
if (!st->codec->block_align) {
- av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
+ av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set\n", i);
goto error;
}
track->sampleSize = st->codec->block_align;
- }else if(st->codec->frame_size > 1){ /* assume compressed audio */
+ }
+ /* set audio_vbr for compressed audio */
+ if (av_get_bits_per_sample(st->codec->codec_id) < 8) {
+ if (!st->codec->frame_size) {
+ av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i);
+ goto error;
+ }
track->audio_vbr = 1;
- }else{
- st->codec->frame_size = 1;
- track->sampleSize = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
}
if (track->mode != MODE_MOV) {
if (track->timescale > UINT16_MAX) {
@@ -2254,11 +2305,19 @@ static int mov_write_header(AVFormatContext *s)
if (!track->height)
track->height = st->codec->height;
- av_set_pts_info(st, 64, 1, track->timescale);
+ avpriv_set_pts_info(st, 64, 1, track->timescale);
}
mov_write_mdat_tag(pb, mov);
- mov->time = s->timestamp + 0x7C25B080; //1970 based -> 1904 based
+
+#if FF_API_TIMESTAMP
+ if (s->timestamp)
+ mov->time = s->timestamp;
+ else
+#endif
+ if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+ mov->time = ff_iso8601_to_unix_time(t->value);
+ mov->time += 0x7C25B080; //1970 based -> 1904 based
if (mov->chapter_track)
mov_create_chapter_track(s, mov->chapter_track);
@@ -2327,104 +2386,118 @@ static int mov_write_trailer(AVFormatContext *s)
}
#if CONFIG_MOV_MUXER
+MOV_CLASS(mov)
AVOutputFormat ff_mov_muxer = {
- "mov",
- NULL_IF_CONFIG_SMALL("MOV format"),
- NULL,
- "mov",
- sizeof(MOVMuxContext),
- CODEC_ID_AAC,
- CODEC_ID_MPEG4,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "mov",
+ .long_name = NULL_IF_CONFIG_SMALL("MOV format"),
+ .extensions = "mov",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AAC,
+#if CONFIG_LIBX264_ENCODER
+ .video_codec = CODEC_ID_H264,
+#else
+ .video_codec = CODEC_ID_MPEG4,
+#endif
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_movvideo_tags, codec_movaudio_tags, 0},
.priv_class = &mov_muxer_class,
};
#endif
#if CONFIG_TGP_MUXER
+MOV_CLASS(tgp)
AVOutputFormat ff_tgp_muxer = {
- "3gp",
- NULL_IF_CONFIG_SMALL("3GP format"),
- NULL,
- "3gp",
- sizeof(MOVMuxContext),
- CODEC_ID_AMR_NB,
- CODEC_ID_H263,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "3gp",
+ .long_name = NULL_IF_CONFIG_SMALL("3GP format"),
+ .extensions = "3gp",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AMR_NB,
+ .video_codec = CODEC_ID_H263,
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
- .priv_class = &mov_muxer_class,
+ .priv_class = &tgp_muxer_class,
};
#endif
#if CONFIG_MP4_MUXER
+MOV_CLASS(mp4)
AVOutputFormat ff_mp4_muxer = {
- "mp4",
- NULL_IF_CONFIG_SMALL("MP4 format"),
- "application/mp4",
- "mp4",
- sizeof(MOVMuxContext),
- CODEC_ID_AAC,
- CODEC_ID_MPEG4,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "mp4",
+ .long_name = NULL_IF_CONFIG_SMALL("MP4 format"),
+ .mime_type = "application/mp4",
+ .extensions = "mp4",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AAC,
+#if CONFIG_LIBX264_ENCODER
+ .video_codec = CODEC_ID_H264,
+#else
+ .video_codec = CODEC_ID_MPEG4,
+#endif
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
- .priv_class = &mov_muxer_class,
+ .priv_class = &mp4_muxer_class,
};
#endif
#if CONFIG_PSP_MUXER
+MOV_CLASS(psp)
AVOutputFormat ff_psp_muxer = {
- "psp",
- NULL_IF_CONFIG_SMALL("PSP MP4 format"),
- NULL,
- "mp4,psp",
- sizeof(MOVMuxContext),
- CODEC_ID_AAC,
- CODEC_ID_MPEG4,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "psp",
+ .long_name = NULL_IF_CONFIG_SMALL("PSP MP4 format"),
+ .extensions = "mp4,psp",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AAC,
+#if CONFIG_LIBX264_ENCODER
+ .video_codec = CODEC_ID_H264,
+#else
+ .video_codec = CODEC_ID_MPEG4,
+#endif
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
- .priv_class = &mov_muxer_class,
+ .priv_class = &psp_muxer_class,
};
#endif
#if CONFIG_TG2_MUXER
+MOV_CLASS(tg2)
AVOutputFormat ff_tg2_muxer = {
- "3g2",
- NULL_IF_CONFIG_SMALL("3GP2 format"),
- NULL,
- "3g2",
- sizeof(MOVMuxContext),
- CODEC_ID_AMR_NB,
- CODEC_ID_H263,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "3g2",
+ .long_name = NULL_IF_CONFIG_SMALL("3GP2 format"),
+ .extensions = "3g2",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AMR_NB,
+ .video_codec = CODEC_ID_H263,
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
- .priv_class = &mov_muxer_class,
+ .priv_class = &tg2_muxer_class,
};
#endif
#if CONFIG_IPOD_MUXER
+MOV_CLASS(ipod)
AVOutputFormat ff_ipod_muxer = {
- "ipod",
- NULL_IF_CONFIG_SMALL("iPod H.264 MP4 format"),
- "application/mp4",
- "m4v,m4a",
- sizeof(MOVMuxContext),
- CODEC_ID_AAC,
- CODEC_ID_H264,
- mov_write_header,
- ff_mov_write_packet,
- mov_write_trailer,
+ .name = "ipod",
+ .long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 format"),
+ .mime_type = "application/mp4",
+ .extensions = "m4v,m4a",
+ .priv_data_size = sizeof(MOVMuxContext),
+ .audio_codec = CODEC_ID_AAC,
+ .video_codec = CODEC_ID_H264,
+ .write_header = mov_write_header,
+ .write_packet = ff_mov_write_packet,
+ .write_trailer = mov_write_trailer,
.flags = AVFMT_GLOBALHEADER,
.codec_tag = (const AVCodecTag* const []){codec_ipod_tags, 0},
- .priv_class = &mov_muxer_class,
+ .priv_class = &ipod_muxer_class,
};
#endif
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 39cdb39..5ca5631 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -35,7 +35,7 @@
#define MODE_MOV 0x02
#define MODE_3GP 0x04
#define MODE_PSP 0x08 // example working PSP command line:
-// ffmpeg -i testinput.avi -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
+// avconv -i testinput.avi -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
#define MODE_3G2 0x10
#define MODE_IPOD 0x20
@@ -112,6 +112,9 @@ typedef struct MOVMuxContext {
int flags;
int rtp_flags;
+ int iods_skip;
+ int iods_video_profile;
+ int iods_audio_profile;
} MOVMuxContext;
#define FF_MOV_FLAG_RTP_HINT 1
@@ -120,7 +123,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index);
int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt,
- int track_index, int sample);
+ int track_index, int sample,
+ uint8_t *sample_data, int sample_size);
void ff_mov_close_hinting(MOVTrack *track);
#endif /* AVFORMAT_MOVENC_H */
diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
index 6157146..9f5e621 100644
--- a/libavformat/movenchint.c
+++ b/libavformat/movenchint.c
@@ -36,7 +36,7 @@ int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
track->tag = MKTAG('r','t','p',' ');
track->src_track = src_index;
- track->enc = avcodec_alloc_context();
+ track->enc = avcodec_alloc_context3(NULL);
if (!track->enc)
goto fail;
track->enc->codec_type = AVMEDIA_TYPE_DATA;
@@ -95,11 +95,12 @@ static void sample_queue_free(HintSampleQueue *queue)
* not copied. sample_queue_retain should be called before pkt->data
* is reused/freed.
*/
-static void sample_queue_push(HintSampleQueue *queue, AVPacket *pkt, int sample)
+static void sample_queue_push(HintSampleQueue *queue, uint8_t *data, int size,
+ int sample)
{
/* No need to keep track of smaller samples, since describing them
* with immediates is more efficient. */
- if (pkt->size <= 14)
+ if (size <= 14)
return;
if (!queue->samples || queue->len >= queue->size) {
HintSample* samples;
@@ -109,8 +110,8 @@ static void sample_queue_push(HintSampleQueue *queue, AVPacket *pkt, int sample)
return;
queue->samples = samples;
}
- queue->samples[queue->len].data = pkt->data;
- queue->samples[queue->len].size = pkt->size;
+ queue->samples[queue->len].data = data;
+ queue->samples[queue->len].size = size;
queue->samples[queue->len].sample_number = sample;
queue->samples[queue->len].offset = 0;
queue->samples[queue->len].own_data = 0;
@@ -386,7 +387,8 @@ static int write_hint_packets(AVIOContext *out, const uint8_t *data,
}
int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt,
- int track_index, int sample)
+ int track_index, int sample,
+ uint8_t *sample_data, int sample_size)
{
MOVMuxContext *mov = s->priv_data;
MOVTrack *trk = &mov->tracks[track_index];
@@ -402,7 +404,10 @@ int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt,
if (!rtp_ctx->pb)
return AVERROR(ENOMEM);
- sample_queue_push(&trk->sample_queue, pkt, sample);
+ if (sample_data)
+ sample_queue_push(&trk->sample_queue, sample_data, sample_size, sample);
+ else
+ sample_queue_push(&trk->sample_queue, pkt->data, pkt->size, sample);
/* Feed the packet to the RTP muxer */
ff_write_chained(rtp_ctx, 0, pkt, s);
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index a1db232..185d7b8 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -22,7 +22,9 @@
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
#include "avformat.h"
+#include "internal.h"
#include "id3v2.h"
#include "id3v1.h"
#include "libavcodec/mpegaudiodecheader.h"
@@ -50,7 +52,7 @@ static int mp3_read_probe(AVProbeData *p)
for(frames = 0; buf2 < end; frames++) {
header = AV_RB32(buf2);
- fsize = ff_mpa_decode_header(&avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate);
+ fsize = avpriv_mpa_decode_header(&avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate);
if(fsize < 0)
break;
buf2 += fsize;
@@ -85,7 +87,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
if(ff_mpa_check_header(v) < 0)
return -1;
- if (ff_mpegaudio_decode_header(&c, v) == 0)
+ if (avpriv_mpegaudio_decode_header(&c, v) == 0)
vbrtag_size = c.frame_size;
if(c.layer != 3)
return -1;
@@ -136,7 +138,7 @@ static int mp3_read_header(AVFormatContext *s,
AVStream *st;
int64_t off;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -146,7 +148,7 @@ static int mp3_read_header(AVFormatContext *s,
st->start_time = 0;
// lcm of all mp3 sample rates
- av_set_pts_info(st, 64, 1, 14112000);
+ avpriv_set_pts_info(st, 64, 1, 14112000);
off = avio_tell(s->pb);
@@ -187,12 +189,11 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_mp3_demuxer = {
- "mp3",
- NULL_IF_CONFIG_SMALL("MPEG audio layer 2/3"),
- 0,
- mp3_read_probe,
- mp3_read_header,
- mp3_read_packet,
+ .name = "mp3",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG audio layer 2/3"),
+ .read_probe = mp3_read_probe,
+ .read_header = mp3_read_header,
+ .read_packet = mp3_read_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "mp2,mp3,m2a", /* XXX: use probe */
};
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index 092d16e..ce547ea 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -19,12 +19,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <strings.h>
#include "avformat.h"
+#include "avio_internal.h"
#include "id3v1.h"
#include "id3v2.h"
#include "rawenc.h"
#include "libavutil/avstring.h"
+#include "libavcodec/mpegaudio.h"
+#include "libavcodec/mpegaudiodata.h"
+#include "libavcodec/mpegaudiodecheader.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
@@ -60,7 +63,7 @@ static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
buf[127] = 0xFF; /* default to unknown genre */
if ((tag = av_dict_get(s->metadata, "TCON", NULL, 0))) { //genre
for(i = 0; i <= ID3v1_GENRE_MAX; i++) {
- if (!strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
+ if (!av_strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
buf[127] = i;
count++;
break;
@@ -70,100 +73,55 @@ static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
return count;
}
-/* simple formats */
-
-static void id3v2_put_size(AVFormatContext *s, int size)
-{
- avio_w8(s->pb, size >> 21 & 0x7f);
- avio_w8(s->pb, size >> 14 & 0x7f);
- avio_w8(s->pb, size >> 7 & 0x7f);
- avio_w8(s->pb, size & 0x7f);
-}
-
-static int string_is_ascii(const uint8_t *str)
-{
- while (*str && *str < 128) str++;
- return !*str;
-}
-
-/**
- * Write a text frame with one (normal frames) or two (TXXX frames) strings
- * according to encoding (only UTF-8 or UTF-16+BOM supported).
- * @return number of bytes written or a negative error code.
- */
-static int id3v2_put_ttag(AVFormatContext *s, const char *str1, const char *str2,
- uint32_t tag, enum ID3v2Encoding enc)
-{
- int len;
- uint8_t *pb;
- int (*put)(AVIOContext*, const char*);
- AVIOContext *dyn_buf;
- if (avio_open_dyn_buf(&dyn_buf) < 0)
- return AVERROR(ENOMEM);
-
- /* check if the strings are ASCII-only and use UTF16 only if
- * they're not */
- if (enc == ID3v2_ENCODING_UTF16BOM && string_is_ascii(str1) &&
- (!str2 || string_is_ascii(str2)))
- enc = ID3v2_ENCODING_ISO8859;
-
- avio_w8(dyn_buf, enc);
- if (enc == ID3v2_ENCODING_UTF16BOM) {
- avio_wl16(dyn_buf, 0xFEFF); /* BOM */
- put = avio_put_str16le;
- } else
- put = avio_put_str;
-
- put(dyn_buf, str1);
- if (str2)
- put(dyn_buf, str2);
- len = avio_close_dyn_buf(dyn_buf, &pb);
-
- avio_wb32(s->pb, tag);
- id3v2_put_size(s, len);
- avio_wb16(s->pb, 0);
- avio_write(s->pb, pb, len);
-
- av_freep(&pb);
- return len + ID3v2_HEADER_SIZE;
-}
+typedef struct MP3Context {
+ const AVClass *class;
+ int id3v2_version;
+ int write_id3v1;
+ int64_t nb_frames_offset;
+} MP3Context;
static int mp3_write_trailer(struct AVFormatContext *s)
{
uint8_t buf[ID3v1_TAG_SIZE];
+ MP3Context *mp3 = s->priv_data;
/* write the id3v1 tag */
- if (id3v1_create_tag(s, buf) > 0) {
+ if (mp3 && mp3->write_id3v1 && id3v1_create_tag(s, buf) > 0) {
avio_write(s->pb, buf, ID3v1_TAG_SIZE);
- avio_flush(s->pb);
}
+
+ /* write number of frames */
+ if (mp3 && mp3->nb_frames_offset) {
+ avio_seek(s->pb, mp3->nb_frames_offset, SEEK_SET);
+ avio_wb32(s->pb, s->streams[0]->nb_frames);
+ avio_seek(s->pb, 0, SEEK_END);
+ }
+
+ avio_flush(s->pb);
+
return 0;
}
#if CONFIG_MP2_MUXER
AVOutputFormat ff_mp2_muxer = {
- "mp2",
- NULL_IF_CONFIG_SMALL("MPEG audio layer 2"),
- "audio/x-mpeg",
- "mp2,m2a",
- 0,
- CODEC_ID_MP2,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
- mp3_write_trailer,
+ .name = "mp2",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG audio layer 2"),
+ .mime_type = "audio/x-mpeg",
+ .extensions = "mp2,m2a",
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
+ .write_trailer = mp3_write_trailer,
};
#endif
#if CONFIG_MP3_MUXER
-typedef struct MP3Context {
- const AVClass *class;
- int id3v2_version;
-} MP3Context;
static const AVOption options[] = {
{ "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.",
- offsetof(MP3Context, id3v2_version), FF_OPT_TYPE_INT, {.dbl = 4}, 3, 4, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MP3Context, id3v2_version), AV_OPT_TYPE_INT, {.dbl = 4}, 3, 4, AV_OPT_FLAG_ENCODING_PARAM},
+ { "write_id3v1", "Enable ID3v1 writing. ID3v1 tags are written in UTF-8 which may not be supported by most software.",
+ offsetof(MP3Context, write_id3v1), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
{ NULL },
};
@@ -174,19 +132,50 @@ static const AVClass mp3_muxer_class = {
.version = LIBAVUTIL_VERSION_INT,
};
-static int id3v2_check_write_tag(AVFormatContext *s, AVDictionaryEntry *t, const char table[][4],
- enum ID3v2Encoding enc)
+/* insert a dummy frame containing number of frames */
+static void mp3_write_xing(AVFormatContext *s)
{
- uint32_t tag;
- int i;
+ AVCodecContext *codec = s->streams[0]->codec;
+ MP3Context *mp3 = s->priv_data;
+ int bitrate_idx = 1; // 32 kbps
+ int64_t xing_offset = (codec->channels == 2) ? 32 : 17;
+ int32_t header;
+ MPADecodeHeader mpah;
+ int srate_idx, i, channels;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++)
+ if (avpriv_mpa_freq_tab[i] == codec->sample_rate) {
+ srate_idx = i;
+ break;
+ }
+ if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) {
+ av_log(s, AV_LOG_ERROR, "Unsupported sample rate.\n");
+ return;
+ }
+
+ switch (codec->channels) {
+ case 1: channels = MPA_MONO; break;
+ case 2: channels = MPA_STEREO; break;
+ default: av_log(s, AV_LOG_ERROR, "Unsupported number of channels.\n"); return;
+ }
+
+ /* dummy MPEG audio header */
+ header = 0xff << 24; // sync
+ header |= (0x7 << 5 | 0x3 << 3 | 0x1 << 1 | 0x1) << 16; // sync/mpeg-1/layer 3/no crc*/
+ header |= (bitrate_idx << 4 | srate_idx << 2) << 8;
+ header |= channels << 6;
+ avio_wb32(s->pb, header);
+
+ avpriv_mpegaudio_decode_header(&mpah, header);
- if (t->key[0] != 'T' || strlen(t->key) != 4)
- return -1;
- tag = AV_RB32(t->key);
- for (i = 0; *table[i]; i++)
- if (tag == AV_RB32(table[i]))
- return id3v2_put_ttag(s, t->value, NULL, tag, enc);
- return -1;
+ ffio_fill(s->pb, 0, xing_offset);
+ ffio_wfourcc(s->pb, "Xing");
+ avio_wb32(s->pb, 0x1); // only number of frames
+ mp3->nb_frames_offset = avio_tell(s->pb);
+ avio_wb32(s->pb, 0);
+
+ mpah.frame_size -= 4 + xing_offset + 4 + 4 + 4;
+ ffio_fill(s->pb, 0, mpah.frame_size);
}
/**
@@ -196,62 +185,30 @@ static int id3v2_check_write_tag(AVFormatContext *s, AVDictionaryEntry *t, const
static int mp3_write_header(struct AVFormatContext *s)
{
MP3Context *mp3 = s->priv_data;
- AVDictionaryEntry *t = NULL;
- int totlen = 0, enc = mp3->id3v2_version == 3 ? ID3v2_ENCODING_UTF16BOM :
- ID3v2_ENCODING_UTF8;
- int64_t size_pos, cur_pos;
-
- avio_wb32(s->pb, MKBETAG('I', 'D', '3', mp3->id3v2_version));
- avio_w8(s->pb, 0);
- avio_w8(s->pb, 0); /* flags */
-
- /* reserve space for size */
- size_pos = avio_tell(s->pb);
- avio_wb32(s->pb, 0);
-
- ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL);
- if (mp3->id3v2_version == 4)
- ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
+ int ret;
- while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
- int ret;
-
- if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags, enc)) > 0) {
- totlen += ret;
- continue;
- }
- if ((ret = id3v2_check_write_tag(s, t, mp3->id3v2_version == 3 ?
- ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
- totlen += ret;
- continue;
- }
-
- /* unknown tag, write as TXXX frame */
- if ((ret = id3v2_put_ttag(s, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
- return ret;
- totlen += ret;
- }
+ ret = ff_id3v2_write(s, mp3->id3v2_version, ID3v2_DEFAULT_MAGIC);
+ if (ret < 0)
+ return ret;
- cur_pos = avio_tell(s->pb);
- avio_seek(s->pb, size_pos, SEEK_SET);
- id3v2_put_size(s, totlen);
- avio_seek(s->pb, cur_pos, SEEK_SET);
+ if (s->pb->seekable)
+ mp3_write_xing(s);
return 0;
}
AVOutputFormat ff_mp3_muxer = {
- "mp3",
- NULL_IF_CONFIG_SMALL("MPEG audio layer 3"),
- "audio/x-mpeg",
- "mp3",
- sizeof(MP3Context),
- CODEC_ID_MP3,
- CODEC_ID_NONE,
- mp3_write_header,
- ff_raw_write_packet,
- mp3_write_trailer,
- AVFMT_NOTIMESTAMPS,
+ .name = "mp3",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG audio layer 3"),
+ .mime_type = "audio/x-mpeg",
+ .extensions = "mp3",
+ .priv_data_size = sizeof(MP3Context),
+ .audio_codec = CODEC_ID_MP3,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = mp3_write_header,
+ .write_packet = ff_raw_write_packet,
+ .write_trailer = mp3_write_trailer,
+ .flags = AVFMT_NOTIMESTAMPS,
.priv_class = &mp3_muxer_class,
};
#endif
diff --git a/libavformat/mpc.c b/libavformat/mpc.c
index 0aec1e8..943121e 100644
--- a/libavformat/mpc.c
+++ b/libavformat/mpc.c
@@ -21,6 +21,7 @@
#include "libavcodec/get_bits.h"
#include "avformat.h"
+#include "internal.h"
#include "apetag.h"
#include "id3v1.h"
#include "libavutil/dict.h"
@@ -70,13 +71,21 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap)
av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n");
return -1;
}
- c->frames = av_malloc(c->fcount * sizeof(MPCFrame));
+ if(c->fcount){
+ c->frames = av_malloc(c->fcount * sizeof(MPCFrame));
+ if(!c->frames){
+ av_log(s, AV_LOG_ERROR, "Cannot allocate seektable\n");
+ return AVERROR(ENOMEM);
+ }
+ }else{
+ av_log(s, AV_LOG_WARNING, "Container reports no frames\n");
+ }
c->curframe = 0;
c->lastframe = -1;
c->curbits = 8;
c->frames_noted = 0;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -88,7 +97,7 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
avio_read(s->pb, st->codec->extradata, 16);
st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3];
- av_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate);
/* scan for seekpoints */
st->start_time = 0;
st->duration = c->fcount;
@@ -109,9 +118,10 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt)
{
MPCContext *c = s->priv_data;
int ret, size, size2, curbits, cur = c->curframe;
- int64_t tmp, pos;
+ unsigned tmp;
+ int64_t pos;
- if (c->curframe >= c->fcount)
+ if (c->curframe >= c->fcount && c->fcount)
return -1;
if(c->curframe != c->lastframe + 1){
@@ -126,14 +136,13 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt)
if(curbits <= 12){
size2 = (tmp >> (12 - curbits)) & 0xFFFFF;
}else{
- tmp = (tmp << 32) | avio_rl32(s->pb);
- size2 = (tmp >> (44 - curbits)) & 0xFFFFF;
+ size2 = (tmp << (curbits - 12) | avio_rl32(s->pb) >> (44 - curbits)) & 0xFFFFF;
}
curbits += 20;
avio_seek(s->pb, pos, SEEK_SET);
size = ((size2 + curbits + 31) & ~31) >> 3;
- if(cur == c->frames_noted){
+ if(cur == c->frames_noted && c->fcount){
c->frames[cur].pos = pos;
c->frames[cur].size = size;
c->frames[cur].skip = curbits - 20;
@@ -146,7 +155,7 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EIO);
pkt->data[0] = curbits;
- pkt->data[1] = (c->curframe > c->fcount);
+ pkt->data[1] = (c->curframe > c->fcount) && c->fcount;
pkt->data[2] = 0;
pkt->data[3] = 0;
@@ -214,13 +223,13 @@ static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
AVInputFormat ff_mpc_demuxer = {
- "mpc",
- NULL_IF_CONFIG_SMALL("Musepack"),
- sizeof(MPCContext),
- mpc_probe,
- mpc_read_header,
- mpc_read_packet,
- mpc_read_close,
- mpc_read_seek,
+ .name = "mpc",
+ .long_name = NULL_IF_CONFIG_SMALL("Musepack"),
+ .priv_data_size = sizeof(MPCContext),
+ .read_probe = mpc_probe,
+ .read_header = mpc_read_header,
+ .read_packet = mpc_read_packet,
+ .read_close = mpc_read_close,
+ .read_seek = mpc_read_seek,
.extensions = "mpc",
};
diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c
index c4810f6..d956049 100644
--- a/libavformat/mpc8.c
+++ b/libavformat/mpc8.c
@@ -22,6 +22,7 @@
#include "libavcodec/get_bits.h"
#include "libavcodec/unary.h"
#include "avformat.h"
+#include "internal.h"
#include "avio_internal.h"
/// Two-byte MPC tag
@@ -222,7 +223,7 @@ static int mpc8_read_header(AVFormatContext *s, AVFormatParameters *ap)
c->samples = ffio_read_varlen(pb);
ffio_read_varlen(pb); //silence samples at the beginning
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -235,7 +236,7 @@ static int mpc8_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->channels = (st->codec->extradata[1] >> 4) + 1;
st->codec->sample_rate = mpc8_rate[st->codec->extradata[0] >> 5];
- av_set_pts_info(st, 32, 1152 << (st->codec->extradata[1]&3)*2, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 32, 1152 << (st->codec->extradata[1]&3)*2, st->codec->sample_rate);
st->duration = c->samples / (1152 << (st->codec->extradata[1]&3)*2);
size -= avio_tell(pb) - pos;
@@ -264,7 +265,7 @@ static int mpc8_read_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(EIO);
mpc8_handle_chunk(s, tag, pos, size);
}
- return 0;
+ return AVERROR_EOF;
}
static int mpc8_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
@@ -281,12 +282,11 @@ static int mpc8_read_seek(AVFormatContext *s, int stream_index, int64_t timestam
AVInputFormat ff_mpc8_demuxer = {
- "mpc8",
- NULL_IF_CONFIG_SMALL("Musepack SV8"),
- sizeof(MPCContext),
- mpc8_probe,
- mpc8_read_header,
- mpc8_read_packet,
- NULL,
- mpc8_read_seek,
+ .name = "mpc8",
+ .long_name = NULL_IF_CONFIG_SMALL("Musepack SV8"),
+ .priv_data_size = sizeof(MPCContext),
+ .read_probe = mpc8_probe,
+ .read_header = mpc8_read_header,
+ .read_packet = mpc8_read_packet,
+ .read_seek = mpc8_read_seek,
};
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 496b9d4..f740a25 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -49,6 +49,10 @@ static int check_pes(uint8_t *p, uint8_t *end){
return pes1||pes2;
}
+static int check_pack_header(const uint8_t *buf) {
+ return (buf[1] & 0xC0) == 0x40 || (buf[1] & 0xF0) == 0x20;
+}
+
static int mpegps_probe(AVProbeData *p)
{
uint32_t code= -1;
@@ -61,9 +65,10 @@ static int mpegps_probe(AVProbeData *p)
if ((code & 0xffffff00) == 0x100) {
int len= p->buf[i+1] << 8 | p->buf[i+2];
int pes= check_pes(p->buf+i, p->buf+p->buf_size);
+ int pack = check_pack_header(p->buf+i);
if(code == SYSTEM_HEADER_START_CODE) sys++;
- else if(code == PACK_START_CODE) pspack++;
+ else if(code == PACK_START_CODE && pack) pspack++;
else if((code & 0xf0) == VIDEO_ID && pes) vid++;
// skip pes payload to avoid start code emulation for private
// and audio streams
@@ -418,7 +423,7 @@ static int mpegps_read_packet(AVFormatContext *s,
{
MpegDemuxContext *m = s->priv_data;
AVStream *st;
- int len, startcode, i, es_type;
+ int len, startcode, i, es_type, ret;
enum CodecID codec_id = CODEC_ID_NONE;
enum AVMediaType type;
int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
@@ -527,9 +532,10 @@ static int mpegps_read_packet(AVFormatContext *s,
goto redo;
}
/* no stream found: add a new stream */
- st = av_new_stream(s, startcode);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto skip;
+ st->id = startcode;
st->codec->codec_type = type;
st->codec->codec_id = codec_id;
if (codec_id != CODEC_ID_PCM_S16BE)
@@ -561,8 +567,7 @@ static int mpegps_read_packet(AVFormatContext *s,
else if (st->codec->bits_per_coded_sample == 28)
return AVERROR(EINVAL);
}
- av_new_packet(pkt, len);
- avio_read(s->pb, pkt->data, pkt->size);
+ ret = av_get_packet(s->pb, pkt, len);
pkt->pts = pts;
pkt->dts = dts;
pkt->pos = dummy_pos;
@@ -571,7 +576,7 @@ static int mpegps_read_packet(AVFormatContext *s,
pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0,
pkt->size);
- return 0;
+ return (ret < 0) ? ret : 0;
}
static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
@@ -603,14 +608,12 @@ static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
}
AVInputFormat ff_mpegps_demuxer = {
- "mpeg",
- NULL_IF_CONFIG_SMALL("MPEG-PS format"),
- sizeof(MpegDemuxContext),
- mpegps_probe,
- mpegps_read_header,
- mpegps_read_packet,
- NULL,
- NULL, //mpegps_read_seek,
- mpegps_read_dts,
+ .name = "mpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-PS format"),
+ .priv_data_size = sizeof(MpegDemuxContext),
+ .read_probe = mpegps_probe,
+ .read_header = mpegps_read_header,
+ .read_packet = mpegps_read_packet,
+ .read_timestamp = mpegps_read_dts,
.flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
};
diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index 820c5bd..d537af6 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -20,8 +20,12 @@
*/
#include "libavutil/fifo.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "libavcodec/put_bits.h"
#include "avformat.h"
+#include "internal.h"
#include "mpeg.h"
#define MAX_PAYLOAD_SIZE 4096
@@ -55,6 +59,7 @@ typedef struct {
} StreamInfo;
typedef struct {
+ const AVClass *class;
int packet_size; /* required packet size */
int packet_number;
int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */
@@ -73,6 +78,7 @@ typedef struct {
double vcd_padding_bitrate; //FIXME floats
int64_t vcd_padding_bytes_written;
+ int preload;
} MpegMuxContext;
extern AVOutputFormat ff_mpeg1vcd_muxer;
@@ -331,7 +337,7 @@ static int mpeg_mux_init(AVFormatContext *ctx)
goto fail;
st->priv_data = stream;
- av_set_pts_info(st, 64, 1, 90000);
+ avpriv_set_pts_info(st, 64, 1, 90000);
switch(st->codec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
@@ -415,9 +421,12 @@ static int mpeg_mux_init(AVFormatContext *ctx)
video_bitrate += codec_rate;
}
+#if FF_API_MUXRATE
if(ctx->mux_rate){
s->mux_rate= (ctx->mux_rate + (8 * 50) - 1) / (8 * 50);
- } else {
+ } else
+#endif
+ if (!s->mux_rate) {
/* we increase slightly the bitrate to take into account the
headers. XXX: compute it exactly */
bitrate += bitrate*5/100;
@@ -1151,9 +1160,15 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
StreamInfo *stream = st->priv_data;
int64_t pts, dts;
PacketDesc *pkt_desc;
- const int preload= av_rescale(ctx->preload, 90000, AV_TIME_BASE);
+ int preload;
const int is_iframe = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (pkt->flags & AV_PKT_FLAG_KEY);
+#if FF_API_PRELOAD
+ if (ctx->preload)
+ s->preload = ctx->preload;
+#endif
+ preload = av_rescale(s->preload, 90000, AV_TIME_BASE);
+
pts= pkt->pts;
dts= pkt->dts;
@@ -1226,77 +1241,102 @@ static int mpeg_mux_end(AVFormatContext *ctx)
return 0;
}
+#define OFFSET(x) offsetof(MpegMuxContext, x)
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "muxrate", NULL, OFFSET(mux_rate), AV_OPT_TYPE_INT, {0}, 0, INT_MAX, E },
+ { "preload", "Initial demux-decode delay in microseconds.", OFFSET(preload), AV_OPT_TYPE_INT, {500000}, 0, INT_MAX, E},
+ { NULL },
+};
+
+#define MPEGENC_CLASS(flavor)\
+static const AVClass flavor ## _class = {\
+ .class_name = #flavor " muxer",\
+ .item_name = av_default_item_name,\
+ .version = LIBAVUTIL_VERSION_INT,\
+ .option = options,\
+};
+
#if CONFIG_MPEG1SYSTEM_MUXER
+MPEGENC_CLASS(mpeg)
AVOutputFormat ff_mpeg1system_muxer = {
- "mpeg",
- NULL_IF_CONFIG_SMALL("MPEG-1 System format"),
- "video/mpeg",
- "mpg,mpeg",
- sizeof(MpegMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG1VIDEO,
- mpeg_mux_init,
- mpeg_mux_write_packet,
- mpeg_mux_end,
+ .name = "mpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format"),
+ .mime_type = "video/mpeg",
+ .extensions = "mpg,mpeg",
+ .priv_data_size = sizeof(MpegMuxContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG1VIDEO,
+ .write_header = mpeg_mux_init,
+ .write_packet = mpeg_mux_write_packet,
+ .write_trailer = mpeg_mux_end,
+ .priv_class = &mpeg_class,
};
#endif
#if CONFIG_MPEG1VCD_MUXER
+MPEGENC_CLASS(vcd)
AVOutputFormat ff_mpeg1vcd_muxer = {
- "vcd",
- NULL_IF_CONFIG_SMALL("MPEG-1 System format (VCD)"),
- "video/mpeg",
- NULL,
- sizeof(MpegMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG1VIDEO,
- mpeg_mux_init,
- mpeg_mux_write_packet,
- mpeg_mux_end,
+ .name = "vcd",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 System format (VCD)"),
+ .mime_type = "video/mpeg",
+ .priv_data_size = sizeof(MpegMuxContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG1VIDEO,
+ .write_header = mpeg_mux_init,
+ .write_packet = mpeg_mux_write_packet,
+ .write_trailer = mpeg_mux_end,
+ .priv_class = &vcd_class,
};
#endif
#if CONFIG_MPEG2VOB_MUXER
+MPEGENC_CLASS(vob)
AVOutputFormat ff_mpeg2vob_muxer = {
- "vob",
- NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"),
- "video/mpeg",
- "vob",
- sizeof(MpegMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG2VIDEO,
- mpeg_mux_init,
- mpeg_mux_write_packet,
- mpeg_mux_end,
+ .name = "vob",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"),
+ .mime_type = "video/mpeg",
+ .extensions = "vob",
+ .priv_data_size = sizeof(MpegMuxContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mpeg_mux_init,
+ .write_packet = mpeg_mux_write_packet,
+ .write_trailer = mpeg_mux_end,
+ .priv_class = &vob_class,
};
#endif
/* Same as mpeg2vob_mux except that the pack size is 2324 */
#if CONFIG_MPEG2SVCD_MUXER
+MPEGENC_CLASS(svcd)
AVOutputFormat ff_mpeg2svcd_muxer = {
- "svcd",
- NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"),
- "video/mpeg",
- "vob",
- sizeof(MpegMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG2VIDEO,
- mpeg_mux_init,
- mpeg_mux_write_packet,
- mpeg_mux_end,
+ .name = "svcd",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"),
+ .mime_type = "video/mpeg",
+ .extensions = "vob",
+ .priv_data_size = sizeof(MpegMuxContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mpeg_mux_init,
+ .write_packet = mpeg_mux_write_packet,
+ .write_trailer = mpeg_mux_end,
+ .priv_class = &svcd_class,
};
#endif
/* Same as mpeg2vob_mux except the 'is_dvd' flag is set to produce NAV pkts */
#if CONFIG_MPEG2DVD_MUXER
+MPEGENC_CLASS(dvd)
AVOutputFormat ff_mpeg2dvd_muxer = {
- "dvd",
- NULL_IF_CONFIG_SMALL("MPEG-2 PS format (DVD VOB)"),
- "video/mpeg",
- "dvd",
- sizeof(MpegMuxContext),
- CODEC_ID_MP2,
- CODEC_ID_MPEG2VIDEO,
- mpeg_mux_init,
- mpeg_mux_write_packet,
- mpeg_mux_end,
+ .name = "dvd",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS format (DVD VOB)"),
+ .mime_type = "video/mpeg",
+ .extensions = "dvd",
+ .priv_data_size = sizeof(MpegMuxContext),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mpeg_mux_init,
+ .write_packet = mpeg_mux_write_packet,
+ .write_trailer = mpeg_mux_end,
+ .priv_class = &dvd_class,
};
#endif
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 608cbe7..15688a9 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -25,8 +25,10 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavcodec/bytestream.h"
+#include "libavcodec/get_bits.h"
#include "avformat.h"
#include "mpegts.h"
#include "internal.h"
@@ -41,6 +43,8 @@
#define MAX_PES_PAYLOAD 200*1024
+#define MAX_MP4_DESCR_COUNT 16
+
enum MpegTSFilterType {
MPEGTS_PES,
MPEGTS_SECTION,
@@ -71,6 +75,7 @@ typedef struct MpegTSSectionFilter {
struct MpegTSFilter {
int pid;
+ int es_id;
int last_cc; /* last cc code (-1 if first packet) */
enum MpegTSFilterType type;
union {
@@ -125,7 +130,7 @@ struct MpegTSContext {
};
static const AVOption options[] = {
- {"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), FF_OPT_TYPE_INT,
+ {"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT,
{.dbl = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
};
@@ -163,6 +168,7 @@ typedef struct PESContext {
enum MpegTSState state;
/* used to get the format */
int data_index;
+ int flags; /**< copied to the AVPacket flags */
int total_size;
int pes_header_size;
int extended_stream_id;
@@ -170,6 +176,7 @@ typedef struct PESContext {
int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */
uint8_t header[MAX_PES_HEADER_SIZE];
uint8_t *buffer;
+ SLConfigDescr sl;
} PESContext;
extern AVInputFormat ff_mpegts_demuxer;
@@ -221,11 +228,11 @@ static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, unsigned i
}
/**
- * \brief discard_pid() decides if the pid is to be discarded according
+ * @brief discard_pid() decides if the pid is to be discarded according
* to caller's programs selection
- * \param ts : - TS context
- * \param pid : - pid
- * \return 1 if the pid is only comprised in programs that have .discard=AVDISCARD_ALL
+ * @param ts : - TS context
+ * @param pid : - pid
+ * @return 1 if the pid is only comprised in programs that have .discard=AVDISCARD_ALL
* 0 otherwise
*/
static int discard_pid(MpegTSContext *ts, unsigned int pid)
@@ -313,6 +320,7 @@ static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int
ts->pids[pid] = filter;
filter->type = MPEGTS_SECTION;
filter->pid = pid;
+ filter->es_id = -1;
filter->last_cc = -1;
sec = &filter->u.section_filter;
sec->section_cb = section_cb;
@@ -341,6 +349,7 @@ static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid,
ts->pids[pid] = filter;
filter->type = MPEGTS_PES;
filter->pid = pid;
+ filter->es_id = -1;
filter->last_cc = -1;
pes = &filter->u.pes_filter;
pes->pes_cb = pes_cb;
@@ -359,7 +368,7 @@ static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
PESContext *pes = filter->u.pes_filter.opaque;
av_freep(&pes->buffer);
/* referenced private data will be freed later in
- * av_close_input_stream */
+ * avformat_close_input */
if (!((PESContext *)filter->u.pes_filter.opaque)->st) {
av_freep(&filter->u.pes_filter.opaque);
}
@@ -447,7 +456,7 @@ static inline int get16(const uint8_t **pp, const uint8_t *p_end)
return c;
}
-/* read and allocate a DVB string preceeded by its length */
+/* read and allocate a DVB string preceded by its length */
static char *getstr8(const uint8_t **pp, const uint8_t *p_end)
{
int len;
@@ -568,7 +577,7 @@ static void mpegts_find_stream_type(AVStream *st,
static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
uint32_t stream_type, uint32_t prog_reg_desc)
{
- av_set_pts_info(st, 33, 1, 90000);
+ avpriv_set_pts_info(st, 33, 1, 90000);
st->priv_data = pes;
st->codec->codec_type = AVMEDIA_TYPE_DATA;
st->codec->codec_id = CODEC_ID_NONE;
@@ -596,13 +605,14 @@ static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
return AVERROR(ENOMEM);
memcpy(sub_pes, pes, sizeof(*sub_pes));
- sub_st = av_new_stream(pes->stream, pes->pid);
+ sub_st = avformat_new_stream(pes->stream, NULL);
if (!sub_st) {
av_free(sub_pes);
return AVERROR(ENOMEM);
}
- av_set_pts_info(sub_st, 33, 1, 90000);
+ sub_st->id = pes->pid;
+ avpriv_set_pts_info(sub_st, 33, 1, 90000);
sub_st->priv_data = sub_pes;
sub_st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
sub_st->codec->codec_id = CODEC_ID_AC3;
@@ -623,6 +633,12 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
pkt->destruct = av_destruct_packet;
pkt->data = pes->buffer;
pkt->size = pes->data_index;
+
+ if(pes->total_size != MAX_PES_PAYLOAD &&
+ pes->pes_header_size + pes->data_index != pes->total_size + PES_START_SIZE) {
+ av_log(pes->stream, AV_LOG_WARNING, "PES packet size mismatch\n");
+ pes->flags |= AV_PKT_FLAG_CORRUPT;
+ }
memset(pkt->data+pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
// Separate out the AC3 substream from an HDMV combined TrueHD/AC3 PID
@@ -634,12 +650,92 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
pkt->dts = pes->dts;
/* store position of first TS packet of this PES packet */
pkt->pos = pes->ts_packet_pos;
+ pkt->flags = pes->flags;
/* reset pts values */
pes->pts = AV_NOPTS_VALUE;
pes->dts = AV_NOPTS_VALUE;
pes->buffer = NULL;
pes->data_index = 0;
+ pes->flags = 0;
+}
+
+static uint64_t get_bits64(GetBitContext *gb, int bits)
+{
+ uint64_t ret = 0;
+ while (bits > 17) {
+ ret <<= 17;
+ ret |= get_bits(gb, 17);
+ bits -= 17;
+ }
+ ret <<= bits;
+ ret |= get_bits(gb, bits);
+ return ret;
+}
+
+static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf, int buf_size)
+{
+ GetBitContext gb;
+ int au_start_flag = 0, au_end_flag = 0, ocr_flag = 0, idle_flag = 0;
+ int padding_flag = 0, padding_bits = 0, inst_bitrate_flag = 0;
+ int dts_flag = -1, cts_flag = -1;
+ int64_t dts = AV_NOPTS_VALUE, cts = AV_NOPTS_VALUE;
+ init_get_bits(&gb, buf, buf_size*8);
+
+ if (sl->use_au_start)
+ au_start_flag = get_bits1(&gb);
+ if (sl->use_au_end)
+ au_end_flag = get_bits1(&gb);
+ if (!sl->use_au_start && !sl->use_au_end)
+ au_start_flag = au_end_flag = 1;
+ if (sl->ocr_len > 0)
+ ocr_flag = get_bits1(&gb);
+ if (sl->use_idle)
+ idle_flag = get_bits1(&gb);
+ if (sl->use_padding)
+ padding_flag = get_bits1(&gb);
+ if (padding_flag)
+ padding_bits = get_bits(&gb, 3);
+
+ if (!idle_flag && (!padding_flag || padding_bits != 0)) {
+ if (sl->packet_seq_num_len)
+ skip_bits_long(&gb, sl->packet_seq_num_len);
+ if (sl->degr_prior_len)
+ if (get_bits1(&gb))
+ skip_bits(&gb, sl->degr_prior_len);
+ if (ocr_flag)
+ skip_bits_long(&gb, sl->ocr_len);
+ if (au_start_flag) {
+ if (sl->use_rand_acc_pt)
+ get_bits1(&gb);
+ if (sl->au_seq_num_len > 0)
+ skip_bits_long(&gb, sl->au_seq_num_len);
+ if (sl->use_timestamps) {
+ dts_flag = get_bits1(&gb);
+ cts_flag = get_bits1(&gb);
+ }
+ }
+ if (sl->inst_bitrate_len)
+ inst_bitrate_flag = get_bits1(&gb);
+ if (dts_flag == 1)
+ dts = get_bits64(&gb, sl->timestamp_len);
+ if (cts_flag == 1)
+ cts = get_bits64(&gb, sl->timestamp_len);
+ if (sl->au_len > 0)
+ skip_bits_long(&gb, sl->au_len);
+ if (inst_bitrate_flag)
+ skip_bits_long(&gb, sl->inst_bitrate_len);
+ }
+
+ if (dts != AV_NOPTS_VALUE)
+ pes->dts = dts;
+ if (cts != AV_NOPTS_VALUE)
+ pes->pts = cts;
+
+ if (sl->timestamp_len && sl->timestamp_res)
+ avpriv_set_pts_info(pes->st, sl->timestamp_len, 1, sl->timestamp_res);
+
+ return (get_bits_count(&gb) + 7) >> 3;
}
/* return non zero if a packet could be constructed */
@@ -690,9 +786,10 @@ static int mpegts_push_data(MpegTSFilter *filter,
/* stream not present in PMT */
if (!pes->st) {
- pes->st = av_new_stream(ts->stream, pes->pid);
+ pes->st = avformat_new_stream(ts->stream, NULL);
if (!pes->st)
return AVERROR(ENOMEM);
+ pes->st->id = pes->pid;
mpegts_set_stream_info(pes->st, pes, 0, 0);
}
@@ -792,6 +889,12 @@ static int mpegts_push_data(MpegTSFilter *filter,
/* we got the full header. We parse it and get the payload */
pes->state = MPEGTS_PAYLOAD;
pes->data_index = 0;
+ if (pes->stream_type == 0x12) {
+ int sl_header_bytes = read_sl_header(pes, &pes->sl, p, buf_size);
+ pes->pes_header_size += sl_header_bytes;
+ p += sl_header_bytes;
+ buf_size -= sl_header_bytes;
+ }
}
break;
case MPEGTS_PAYLOAD:
@@ -816,9 +919,9 @@ static int mpegts_push_data(MpegTSFilter *filter,
* decreases demuxer delay for infrequent packets like subtitles from
* a couple of seconds to milliseconds for properly muxed files.
* total_size is the number of bytes following pes_packet_length
- * in the pes header, i.e. not counting the first 6 bytes */
+ * in the pes header, i.e. not counting the first PES_START_SIZE bytes */
if (!ts->stop_parse && pes->total_size < MAX_PES_PAYLOAD &&
- pes->pes_header_size + pes->data_index == pes->total_size + 6) {
+ pes->pes_header_size + pes->data_index == pes->total_size + PES_START_SIZE) {
ts->stop_parse = 1;
new_pes_packet(pes, ts->pkt);
}
@@ -856,49 +959,289 @@ static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid)
return pes;
}
+#define MAX_LEVEL 4
+typedef struct {
+ AVFormatContext *s;
+ AVIOContext pb;
+ Mp4Descr *descr;
+ Mp4Descr *active_descr;
+ int descr_count;
+ int max_descr_count;
+ int level;
+} MP4DescrParseContext;
+
+static int init_MP4DescrParseContext(
+ MP4DescrParseContext *d, AVFormatContext *s, const uint8_t *buf,
+ unsigned size, Mp4Descr *descr, int max_descr_count)
+{
+ int ret;
+ if (size > (1<<30))
+ return AVERROR_INVALIDDATA;
+
+ if ((ret = ffio_init_context(&d->pb, (unsigned char*)buf, size, 0,
+ NULL, NULL, NULL, NULL)) < 0)
+ return ret;
+
+ d->s = s;
+ d->level = 0;
+ d->descr_count = 0;
+ d->descr = descr;
+ d->active_descr = NULL;
+ d->max_descr_count = max_descr_count;
+
+ return 0;
+}
+
+static void update_offsets(AVIOContext *pb, int64_t *off, int *len) {
+ int64_t new_off = avio_tell(pb);
+ (*len) -= new_off - *off;
+ *off = new_off;
+}
+
+static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len,
+ int target_tag);
+
+static int parse_mp4_descr_arr(MP4DescrParseContext *d, int64_t off, int len)
+{
+ while (len > 0) {
+ if (parse_mp4_descr(d, off, len, 0) < 0)
+ return -1;
+ update_offsets(&d->pb, &off, &len);
+ }
+ return 0;
+}
+
+static int parse_MP4IODescrTag(MP4DescrParseContext *d, int64_t off, int len)
+{
+ avio_rb16(&d->pb); // ID
+ avio_r8(&d->pb);
+ avio_r8(&d->pb);
+ avio_r8(&d->pb);
+ avio_r8(&d->pb);
+ avio_r8(&d->pb);
+ update_offsets(&d->pb, &off, &len);
+ return parse_mp4_descr_arr(d, off, len);
+}
+
+static int parse_MP4ODescrTag(MP4DescrParseContext *d, int64_t off, int len)
+{
+ int id_flags;
+ if (len < 2)
+ return 0;
+ id_flags = avio_rb16(&d->pb);
+ if (!(id_flags & 0x0020)) { //URL_Flag
+ update_offsets(&d->pb, &off, &len);
+ return parse_mp4_descr_arr(d, off, len); //ES_Descriptor[]
+ } else {
+ return 0;
+ }
+}
+
+static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len)
+{
+ int es_id = 0;
+ if (d->descr_count >= d->max_descr_count)
+ return -1;
+ ff_mp4_parse_es_descr(&d->pb, &es_id);
+ d->active_descr = d->descr + (d->descr_count++);
+
+ d->active_descr->es_id = es_id;
+ update_offsets(&d->pb, &off, &len);
+ parse_mp4_descr(d, off, len, MP4DecConfigDescrTag);
+ update_offsets(&d->pb, &off, &len);
+ if (len > 0)
+ parse_mp4_descr(d, off, len, MP4SLDescrTag);
+ d->active_descr = NULL;
+ return 0;
+}
+
+static int parse_MP4DecConfigDescrTag(MP4DescrParseContext *d, int64_t off, int len)
+{
+ Mp4Descr *descr = d->active_descr;
+ if (!descr)
+ return -1;
+ d->active_descr->dec_config_descr = av_malloc(len);
+ if (!descr->dec_config_descr)
+ return AVERROR(ENOMEM);
+ descr->dec_config_descr_len = len;
+ avio_read(&d->pb, descr->dec_config_descr, len);
+ return 0;
+}
+
+static int parse_MP4SLDescrTag(MP4DescrParseContext *d, int64_t off, int len)
+{
+ Mp4Descr *descr = d->active_descr;
+ int predefined;
+ if (!descr)
+ return -1;
+
+ predefined = avio_r8(&d->pb);
+ if (!predefined) {
+ int lengths;
+ int flags = avio_r8(&d->pb);
+ descr->sl.use_au_start = !!(flags & 0x80);
+ descr->sl.use_au_end = !!(flags & 0x40);
+ descr->sl.use_rand_acc_pt = !!(flags & 0x20);
+ descr->sl.use_padding = !!(flags & 0x08);
+ descr->sl.use_timestamps = !!(flags & 0x04);
+ descr->sl.use_idle = !!(flags & 0x02);
+ descr->sl.timestamp_res = avio_rb32(&d->pb);
+ avio_rb32(&d->pb);
+ descr->sl.timestamp_len = avio_r8(&d->pb);
+ descr->sl.ocr_len = avio_r8(&d->pb);
+ descr->sl.au_len = avio_r8(&d->pb);
+ descr->sl.inst_bitrate_len = avio_r8(&d->pb);
+ lengths = avio_rb16(&d->pb);
+ descr->sl.degr_prior_len = lengths >> 12;
+ descr->sl.au_seq_num_len = (lengths >> 7) & 0x1f;
+ descr->sl.packet_seq_num_len = (lengths >> 2) & 0x1f;
+ } else {
+ av_log_missing_feature(d->s, "Predefined SLConfigDescriptor\n", 0);
+ }
+ return 0;
+}
+
+static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len,
+ int target_tag) {
+ int tag;
+ int len1 = ff_mp4_read_descr(d->s, &d->pb, &tag);
+ update_offsets(&d->pb, &off, &len);
+ if (len < 0 || len1 > len || len1 <= 0) {
+ av_log(d->s, AV_LOG_ERROR, "Tag %x length violation new length %d bytes remaining %d\n", tag, len1, len);
+ return -1;
+ }
+
+ if (d->level++ >= MAX_LEVEL) {
+ av_log(d->s, AV_LOG_ERROR, "Maximum MP4 descriptor level exceeded\n");
+ goto done;
+ }
+
+ if (target_tag && tag != target_tag) {
+ av_log(d->s, AV_LOG_ERROR, "Found tag %x expected %x\n", tag, target_tag);
+ goto done;
+ }
+
+ switch (tag) {
+ case MP4IODescrTag:
+ parse_MP4IODescrTag(d, off, len1);
+ break;
+ case MP4ODescrTag:
+ parse_MP4ODescrTag(d, off, len1);
+ break;
+ case MP4ESDescrTag:
+ parse_MP4ESDescrTag(d, off, len1);
+ break;
+ case MP4DecConfigDescrTag:
+ parse_MP4DecConfigDescrTag(d, off, len1);
+ break;
+ case MP4SLDescrTag:
+ parse_MP4SLDescrTag(d, off, len1);
+ break;
+ }
+
+done:
+ d->level--;
+ avio_seek(&d->pb, off + len1, SEEK_SET);
+ return 0;
+}
+
static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size,
- int *es_id, uint8_t **dec_config_descr,
- int *dec_config_descr_size)
+ Mp4Descr *descr, int *descr_count, int max_descr_count)
+{
+ MP4DescrParseContext d;
+ if (init_MP4DescrParseContext(&d, s, buf, size, descr, max_descr_count) < 0)
+ return -1;
+
+ parse_mp4_descr(&d, avio_tell(&d.pb), size, MP4IODescrTag);
+
+ *descr_count = d.descr_count;
+ return 0;
+}
+
+static int mp4_read_od(AVFormatContext *s, const uint8_t *buf, unsigned size,
+ Mp4Descr *descr, int *descr_count, int max_descr_count)
{
+ MP4DescrParseContext d;
+ if (init_MP4DescrParseContext(&d, s, buf, size, descr, max_descr_count) < 0)
+ return -1;
+
+ parse_mp4_descr_arr(&d, avio_tell(&d.pb), size);
+
+ *descr_count = d.descr_count;
+ return 0;
+}
+
+static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
+{
+ MpegTSContext *ts = filter->u.section_filter.opaque;
+ SectionHeader h;
+ const uint8_t *p, *p_end;
AVIOContext pb;
- int tag;
- unsigned len;
-
- ffio_init_context(&pb, buf, size, 0, NULL, NULL, NULL, NULL);
-
- len = ff_mp4_read_descr(s, &pb, &tag);
- if (tag == MP4IODescrTag) {
- avio_rb16(&pb); // ID
- avio_r8(&pb);
- avio_r8(&pb);
- avio_r8(&pb);
- avio_r8(&pb);
- avio_r8(&pb);
- len = ff_mp4_read_descr(s, &pb, &tag);
- if (tag == MP4ESDescrTag) {
- *es_id = avio_rb16(&pb); /* ES_ID */
- av_dlog(s, "ES_ID %#x\n", *es_id);
- avio_r8(&pb); /* priority */
- len = ff_mp4_read_descr(s, &pb, &tag);
- if (tag == MP4DecConfigDescrTag) {
- *dec_config_descr = av_malloc(len);
- if (!*dec_config_descr)
- return AVERROR(ENOMEM);
- *dec_config_descr_size = len;
- avio_read(&pb, *dec_config_descr, len);
+ Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = {{ 0 }};
+ int mp4_descr_count = 0;
+ int i, pid;
+ AVFormatContext *s = ts->stream;
+
+ p_end = section + section_len - 4;
+ p = section;
+ if (parse_section_header(&h, &p, p_end) < 0)
+ return;
+ if (h.tid != M4OD_TID)
+ return;
+
+ mp4_read_od(s, p, (unsigned)(p_end - p), mp4_descr, &mp4_descr_count, MAX_MP4_DESCR_COUNT);
+
+ for (pid = 0; pid < NB_PID_MAX; pid++) {
+ if (!ts->pids[pid])
+ continue;
+ for (i = 0; i < mp4_descr_count; i++) {
+ PESContext *pes;
+ AVStream *st;
+ if (ts->pids[pid]->es_id != mp4_descr[i].es_id)
+ continue;
+ if (!(ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES)) {
+ av_log(s, AV_LOG_ERROR, "pid %x is not PES\n", pid);
+ continue;
+ }
+ pes = ts->pids[pid]->u.pes_filter.opaque;
+ st = pes->st;
+ if (!st) {
+ continue;
+ }
+
+ pes->sl = mp4_descr[i].sl;
+
+ ffio_init_context(&pb, mp4_descr[i].dec_config_descr,
+ mp4_descr[i].dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
+ ff_mp4_read_dec_config_descr(s, st, &pb);
+ if (st->codec->codec_id == CODEC_ID_AAC &&
+ st->codec->extradata_size > 0)
+ st->need_parsing = 0;
+ if (st->codec->codec_id == CODEC_ID_H264 &&
+ st->codec->extradata_size > 0)
+ st->need_parsing = 0;
+
+ if (st->codec->codec_id <= CODEC_ID_NONE) {
+ } else if (st->codec->codec_id < CODEC_ID_FIRST_AUDIO) {
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ } else if (st->codec->codec_id < CODEC_ID_FIRST_SUBTITLE) {
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ } else if (st->codec->codec_id < CODEC_ID_FIRST_UNKNOWN) {
+ st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
}
}
}
- return 0;
+ for (i = 0; i < mp4_descr_count; i++)
+ av_free(mp4_descr[i].dec_config_descr);
}
int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
const uint8_t **pp, const uint8_t *desc_list_end,
- int mp4_dec_config_descr_len, int mp4_es_id, int pid,
- uint8_t *mp4_dec_config_descr)
+ Mp4Descr *mp4_descr, int mp4_descr_count, int pid,
+ MpegTSContext *ts)
{
const uint8_t *desc_end;
- int desc_len, desc_tag;
+ int desc_len, desc_tag, desc_es_id;
char language[252];
int i;
@@ -919,13 +1262,31 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
mpegts_find_stream_type(st, desc_tag, DESC_types);
switch(desc_tag) {
+ case 0x1E: /* SL descriptor */
+ desc_es_id = get16(pp, desc_end);
+ if (ts && ts->pids[pid])
+ ts->pids[pid]->es_id = desc_es_id;
+ for (i = 0; i < mp4_descr_count; i++)
+ if (mp4_descr[i].dec_config_descr_len &&
+ mp4_descr[i].es_id == desc_es_id) {
+ AVIOContext pb;
+ ffio_init_context(&pb, mp4_descr[i].dec_config_descr,
+ mp4_descr[i].dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
+ ff_mp4_read_dec_config_descr(fc, st, &pb);
+ if (st->codec->codec_id == CODEC_ID_AAC &&
+ st->codec->extradata_size > 0)
+ st->need_parsing = 0;
+ if (st->codec->codec_id == CODEC_ID_MPEG4SYSTEMS)
+ mpegts_open_section_filter(ts, pid, m4sl_cb, ts, 1);
+ }
+ break;
case 0x1F: /* FMC descriptor */
get16(pp, desc_end);
- if (st->codec->codec_id == CODEC_ID_AAC_LATM &&
- mp4_dec_config_descr_len && mp4_es_id == pid) {
+ if (mp4_descr_count > 0 && st->codec->codec_id == CODEC_ID_AAC_LATM &&
+ mp4_descr->dec_config_descr_len && mp4_descr->es_id == pid) {
AVIOContext pb;
- ffio_init_context(&pb, mp4_dec_config_descr,
- mp4_dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
+ ffio_init_context(&pb, mp4_descr->dec_config_descr,
+ mp4_descr->dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
ff_mp4_read_dec_config_descr(fc, st, &pb);
if (st->codec->codec_id == CODEC_ID_AAC &&
st->codec->extradata_size > 0)
@@ -1009,9 +1370,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
int program_info_length, pcr_pid, pid, stream_type;
int desc_list_len;
uint32_t prog_reg_desc = 0; /* registration descriptor */
- uint8_t *mp4_dec_config_descr = NULL;
- int mp4_dec_config_descr_len = 0;
- int mp4_es_id = 0;
+
+ Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = {{ 0 }};
+ int mp4_descr_count = 0;
+ int i;
av_dlog(ts->stream, "PMT: len %i\n", section_len);
hex_dump_debug(ts->stream, (uint8_t *)section, section_len);
@@ -1053,8 +1415,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
get8(&p, p_end); // scope
get8(&p, p_end); // label
len -= 2;
- mp4_read_iods(ts->stream, p, len, &mp4_es_id,
- &mp4_dec_config_descr, &mp4_dec_config_descr_len);
+ mp4_read_iods(ts->stream, p, len, mp4_descr + mp4_descr_count,
+ &mp4_descr_count, MAX_MP4_DESCR_COUNT);
} else if (tag == 0x05 && len >= 4) { // registration descriptor
prog_reg_desc = bytestream_get_le32(&p);
len -= 4;
@@ -1071,6 +1433,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
for(;;) {
st = 0;
+ pes = NULL;
stream_type = get8(&p, p_end);
if (stream_type < 0)
break;
@@ -1078,23 +1441,36 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
if (pid < 0)
break;
- /* now create ffmpeg stream */
+ /* now create stream */
if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) {
pes = ts->pids[pid]->u.pes_filter.opaque;
- if (!pes->st)
- pes->st = av_new_stream(pes->stream, pes->pid);
+ if (!pes->st) {
+ pes->st = avformat_new_stream(pes->stream, NULL);
+ pes->st->id = pes->pid;
+ }
st = pes->st;
- } else {
+ } else if (stream_type != 0x13) {
if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably
pes = add_pes_stream(ts, pid, pcr_pid);
- if (pes)
- st = av_new_stream(pes->stream, pes->pid);
+ if (pes) {
+ st = avformat_new_stream(pes->stream, NULL);
+ st->id = pes->pid;
+ }
+ } else {
+ int idx = ff_find_stream_index(ts->stream, pid);
+ if (idx >= 0) {
+ st = ts->stream->streams[idx];
+ } else {
+ st = avformat_new_stream(ts->stream, NULL);
+ st->id = pid;
+ st->codec->codec_type = AVMEDIA_TYPE_DATA;
+ }
}
if (!st)
goto out;
- if (!pes->stream_type)
+ if (pes && !pes->stream_type)
mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc);
add_pid_to_pmt(ts, h->id, pid);
@@ -1109,10 +1485,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
break;
for(;;) {
if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p, desc_list_end,
- mp4_dec_config_descr_len, mp4_es_id, pid, mp4_dec_config_descr) < 0)
+ mp4_descr, mp4_descr_count, pid, ts) < 0)
break;
- if (prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) {
+ if (pes && prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) {
ff_program_add_stream_index(ts->stream, h->id, pes->sub_st->index);
pes->sub_st->codec->codec_tag = st->codec->codec_tag;
}
@@ -1121,7 +1497,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
}
out:
- av_free(mp4_dec_config_descr);
+ for (i = 0; i < mp4_descr_count; i++)
+ av_free(mp4_descr[i].dec_config_descr);
}
static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
@@ -1247,7 +1624,8 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
{
AVFormatContext *s = ts->stream;
MpegTSFilter *tss;
- int len, pid, cc, expected_cc, cc_ok, afc, is_start;
+ int len, pid, cc, expected_cc, cc_ok, afc, is_start, is_discontinuity,
+ has_adaptation, has_payload;
const uint8_t *p, *p_end;
int64_t pos;
@@ -1263,21 +1641,39 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
if (!tss)
return 0;
+ afc = (packet[3] >> 4) & 3;
+ if (afc == 0) /* reserved value */
+ return 0;
+ has_adaptation = afc & 2;
+ has_payload = afc & 1;
+ is_discontinuity = has_adaptation
+ && packet[4] != 0 /* with length > 0 */
+ && (packet[5] & 0x80); /* and discontinuity indicated */
+
/* continuity check (currently not used) */
cc = (packet[3] & 0xf);
- expected_cc = (packet[3] & 0x10) ? (tss->last_cc + 1) & 0x0f : tss->last_cc;
- cc_ok = (tss->last_cc < 0) || (expected_cc == cc);
+ expected_cc = has_payload ? (tss->last_cc + 1) & 0x0f : tss->last_cc;
+ cc_ok = pid == 0x1FFF // null packet PID
+ || is_discontinuity
+ || tss->last_cc < 0
+ || expected_cc == cc;
+
tss->last_cc = cc;
+ if (!cc_ok) {
+ av_log(ts->stream, AV_LOG_WARNING,
+ "Continuity check failed for pid %d expected %d got %d\n",
+ pid, expected_cc, cc);
+ if(tss->type == MPEGTS_PES) {
+ PESContext *pc = tss->u.pes_filter.opaque;
+ pc->flags |= AV_PKT_FLAG_CORRUPT;
+ }
+ }
- /* skip adaptation field */
- afc = (packet[3] >> 4) & 3;
- p = packet + 4;
- if (afc == 0) /* reserved value */
+ if (!has_payload)
return 0;
- if (afc == 2) /* adaptation field only */
- return 0;
- if (afc == 3) {
- /* skip adapation field */
+ p = packet + 4;
+ if (has_adaptation) {
+ /* skip adaptation field */
p += p[0] + 1;
}
/* if past the end of packet, ignore */
@@ -1355,7 +1751,7 @@ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size)
len = avio_read(pb, buf, TS_PACKET_SIZE);
if (len != TS_PACKET_SIZE)
return len < 0 ? len : AVERROR_EOF;
- /* check paquet sync byte */
+ /* check packet sync byte */
if (buf[0] != 0x47) {
/* find a new packet start */
avio_seek(pb, -TS_PACKET_SIZE, SEEK_CUR);
@@ -1377,7 +1773,24 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
{
AVFormatContext *s = ts->stream;
uint8_t packet[TS_PACKET_SIZE];
- int packet_num, ret;
+ int packet_num, ret = 0;
+
+ if (avio_tell(s->pb) != ts->last_pos) {
+ int i;
+ av_dlog(ts->stream, "Skipping after seek\n");
+ /* seek detected, flush pes buffer */
+ for (i = 0; i < NB_PID_MAX; i++) {
+ if (ts->pids[i]) {
+ if (ts->pids[i]->type == MPEGTS_PES) {
+ PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
+ av_freep(&pes->buffer);
+ pes->data_index = 0;
+ pes->state = MPEGTS_SKIP; /* skip until pes header */
+ }
+ ts->pids[i]->last_cc = -1;
+ }
+ }
+ }
ts->stop_parse = 0;
packet_num = 0;
@@ -1389,12 +1802,13 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
break;
ret = read_packet(s, packet, ts->raw_packet_size);
if (ret != 0)
- return ret;
+ break;
ret = handle_packet(ts, packet);
if (ret != 0)
- return ret;
+ break;
}
- return 0;
+ ts->last_pos = avio_tell(s->pb);
+ return ret;
}
static int mpegts_probe(AVProbeData *p)
@@ -1465,17 +1879,6 @@ static int mpegts_read_header(AVFormatContext *s,
int len;
int64_t pos;
-#if FF_API_FORMAT_PARAMETERS
- if (ap) {
- if (ap->mpeg2ts_compute_pcr)
- ts->mpeg2ts_compute_pcr = ap->mpeg2ts_compute_pcr;
- if(ap->mpeg2ts_raw){
- av_log(s, AV_LOG_ERROR, "use mpegtsraw_demuxer!\n");
- return -1;
- }
- }
-#endif
-
/* read the first 1024 bytes to get packet size */
pos = avio_tell(pb);
len = avio_read(pb, buf, sizeof(buf));
@@ -1490,8 +1893,8 @@ static int mpegts_read_header(AVFormatContext *s,
if (s->iformat == &ff_mpegts_demuxer) {
/* normal demux */
- /* first do a scaning to get all the services */
- if (avio_seek(pb, pos, SEEK_SET) < 0)
+ /* first do a scan to get all the services */
+ if (pb->seekable && avio_seek(pb, pos, SEEK_SET) < 0)
av_log(s, AV_LOG_ERROR, "Unable to seek back to the start\n");
mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
@@ -1515,10 +1918,10 @@ static int mpegts_read_header(AVFormatContext *s,
/* only read packets */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
- av_set_pts_info(st, 60, 1, 27000000);
+ avpriv_set_pts_info(st, 60, 1, 27000000);
st->codec->codec_type = AVMEDIA_TYPE_DATA;
st->codec->codec_id = CODEC_ID_MPEG2TS;
@@ -1612,18 +2015,6 @@ static int mpegts_read_packet(AVFormatContext *s,
MpegTSContext *ts = s->priv_data;
int ret, i;
- if (avio_tell(s->pb) != ts->last_pos) {
- /* seek detected, flush pes buffer */
- for (i = 0; i < NB_PID_MAX; i++) {
- if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {
- PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
- av_freep(&pes->buffer);
- pes->data_index = 0;
- pes->state = MPEGTS_SKIP; /* skip until pes header */
- }
- }
- }
-
ts->pkt = pkt;
ret = handle_packets(ts, 0);
if (ret < 0) {
@@ -1641,8 +2032,6 @@ static int mpegts_read_packet(AVFormatContext *s,
}
}
- ts->last_pos = avio_tell(s->pb);
-
return ret;
}
@@ -1741,7 +2130,7 @@ static int read_seek2(AVFormatContext *s,
ts_adj = target_ts;
stream_index_gen_search = stream_index;
}
- pos = av_gen_search(s, stream_index_gen_search, ts_adj,
+ pos = ff_gen_search(s, stream_index_gen_search, ts_adj,
0, INT64_MAX, -1,
AV_NOPTS_VALUE,
AV_NOPTS_VALUE,
@@ -1789,7 +2178,7 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, in
uint8_t buf[TS_PACKET_SIZE];
int64_t pos;
- if(av_seek_frame_binary(s, stream_index, target_ts, flags) < 0)
+ if (ff_seek_frame_binary(s, stream_index, target_ts, flags) < 0)
return -1;
pos= avio_tell(s->pb);
@@ -1863,15 +2252,15 @@ void ff_mpegts_parse_close(MpegTSContext *ts)
}
AVInputFormat ff_mpegts_demuxer = {
- "mpegts",
- NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
- sizeof(MpegTSContext),
- mpegts_probe,
- mpegts_read_header,
- mpegts_read_packet,
- mpegts_read_close,
- read_seek,
- mpegts_get_pcr,
+ .name = "mpegts",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
+ .priv_data_size = sizeof(MpegTSContext),
+ .read_probe = mpegts_probe,
+ .read_header = mpegts_read_header,
+ .read_packet = mpegts_read_packet,
+ .read_close = mpegts_read_close,
+ .read_seek = read_seek,
+ .read_timestamp = mpegts_get_pcr,
.flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
#ifdef USE_SYNCPOINT_SEARCH
.read_seek2 = read_seek2,
@@ -1879,15 +2268,14 @@ AVInputFormat ff_mpegts_demuxer = {
};
AVInputFormat ff_mpegtsraw_demuxer = {
- "mpegtsraw",
- NULL_IF_CONFIG_SMALL("MPEG-2 raw transport stream format"),
- sizeof(MpegTSContext),
- NULL,
- mpegts_read_header,
- mpegts_raw_read_packet,
- mpegts_read_close,
- read_seek,
- mpegts_get_pcr,
+ .name = "mpegtsraw",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 raw transport stream format"),
+ .priv_data_size = sizeof(MpegTSContext),
+ .read_header = mpegts_read_header,
+ .read_packet = mpegts_raw_read_packet,
+ .read_close = mpegts_read_close,
+ .read_seek = read_seek,
+ .read_timestamp = mpegts_get_pcr,
.flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
#ifdef USE_SYNCPOINT_SEARCH
.read_seek2 = read_seek2,
diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 73ef2ed..e38f2e0 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -39,6 +39,7 @@
/* table ids */
#define PAT_TID 0x00
#define PMT_TID 0x02
+#define M4OD_TID 0x05
#define SDT_TID 0x42
#define STREAM_TYPE_VIDEO_MPEG1 0x01
@@ -64,6 +65,30 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
const uint8_t *buf, int len);
void ff_mpegts_parse_close(MpegTSContext *ts);
+typedef struct {
+ int use_au_start;
+ int use_au_end;
+ int use_rand_acc_pt;
+ int use_padding;
+ int use_timestamps;
+ int use_idle;
+ int timestamp_res;
+ int timestamp_len;
+ int ocr_len;
+ int au_len;
+ int inst_bitrate_len;
+ int degr_prior_len;
+ int au_seq_num_len;
+ int packet_seq_num_len;
+} SLConfigDescr;
+
+typedef struct {
+ int es_id;
+ int dec_config_descr_len;
+ uint8_t *dec_config_descr;
+ SLConfigDescr sl;
+} Mp4Descr;
+
/**
* Parse an MPEG-2 descriptor
* @param[in] fc Format context (used for logging only)
@@ -79,7 +104,7 @@ void ff_mpegts_parse_close(MpegTSContext *ts);
*/
int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
const uint8_t **pp, const uint8_t *desc_list_end,
- int mp4_dec_config_descr_len, int mp4_es_id, int pid,
- uint8_t *mp4_dec_config_descr);
+ Mp4Descr *mp4_descr, int mp4_descr_count, int pid,
+ MpegTSContext *ts);
#endif /* AVFORMAT_MPEGTS_H */
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 26d2cb2..90f2232 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -22,6 +22,7 @@
#include "libavutil/bswap.h"
#include "libavutil/crc.h"
#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavcodec/mpegvideo.h"
#include "avformat.h"
@@ -67,6 +68,7 @@ typedef struct MpegTSWrite {
int tsid;
int64_t first_pcr;
int mux_rate; ///< set to 1 when VBR
+ int pes_payload_size;
int transport_stream_id;
int original_network_id;
@@ -76,17 +78,24 @@ typedef struct MpegTSWrite {
int start_pid;
} MpegTSWrite;
+/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
+#define DEFAULT_PES_HEADER_FREQ 16
+#define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)
+
static const AVOption options[] = {
{ "mpegts_transport_stream_id", "Set transport_stream_id field.",
- offsetof(MpegTSWrite, transport_stream_id), FF_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MpegTSWrite, transport_stream_id), AV_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
{ "mpegts_original_network_id", "Set original_network_id field.",
- offsetof(MpegTSWrite, original_network_id), FF_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MpegTSWrite, original_network_id), AV_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
{ "mpegts_service_id", "Set service_id field.",
- offsetof(MpegTSWrite, service_id), FF_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MpegTSWrite, service_id), AV_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
{ "mpegts_pmt_start_pid", "Set the first pid of the PMT.",
- offsetof(MpegTSWrite, pmt_start_pid), FF_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM},
{ "mpegts_start_pid", "Set the first pid.",
- offsetof(MpegTSWrite, start_pid), FF_OPT_TYPE_INT, {.dbl = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM},
+ offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT, {.dbl = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM},
+ { "muxrate", NULL, offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, {1}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+ { "pes_payload_size", "Minimum PES packet payload in bytes",
+ offsetof(MpegTSWrite, pes_payload_size), AV_OPT_TYPE_INT, {DEFAULT_PES_PAYLOAD_SIZE}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ NULL },
};
@@ -186,10 +195,6 @@ static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
#define DEFAULT_PROVIDER_NAME "Libav"
#define DEFAULT_SERVICE_NAME "Service01"
-/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
-#define DEFAULT_PES_HEADER_FREQ 16
-#define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)
-
/* we retransmit the SI info at this rate */
#define SDT_RETRANS_TIME 500
#define PAT_RETRANS_TIME 100
@@ -199,11 +204,12 @@ typedef struct MpegTSWriteStream {
struct MpegTSService *service;
int pid; /* stream associated pid */
int cc;
- int payload_index;
+ int payload_size;
int first_pts_check; ///< first pts check needed
int64_t payload_pts;
int64_t payload_dts;
- uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE];
+ int payload_flags;
+ uint8_t *payload;
ADTSContext *adts;
} MpegTSWriteStream;
@@ -450,6 +456,9 @@ static int mpegts_write_header(AVFormatContext *s)
const char *provider_name;
int *pids;
+ // round up to a whole number of TS packets
+ ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;
+
ts->tsid = ts->transport_stream_id;
ts->onid = ts->original_network_id;
/* allocate a single DVB service */
@@ -481,11 +490,14 @@ static int mpegts_write_header(AVFormatContext *s)
/* assign pids to each stream */
for(i = 0;i < s->nb_streams; i++) {
st = s->streams[i];
- av_set_pts_info(st, 33, 1, 90000);
+ avpriv_set_pts_info(st, 33, 1, 90000);
ts_st = av_mallocz(sizeof(MpegTSWriteStream));
if (!ts_st)
goto fail;
st->priv_data = ts_st;
+ ts_st->payload = av_mallocz(ts->pes_payload_size);
+ if (!ts_st->payload)
+ goto fail;
ts_st->service = service;
/* MPEG pid values < 16 are reserved. Applications which set st->id in
* this range are assigned a calculated pid. */
@@ -521,10 +533,10 @@ static int mpegts_write_header(AVFormatContext *s)
st->codec->extradata_size > 0) {
ts_st->adts = av_mallocz(sizeof(*ts_st->adts));
if (!ts_st->adts)
- return AVERROR(ENOMEM);
+ goto fail;
if (ff_adts_decode_extradata(s, ts_st->adts, st->codec->extradata,
st->codec->extradata_size) < 0)
- return -1;
+ goto fail;
}
}
@@ -537,7 +549,10 @@ static int mpegts_write_header(AVFormatContext *s)
service->pcr_pid = ts_st->pid;
}
- ts->mux_rate = s->mux_rate ? s->mux_rate : 1;
+#if FF_API_MUXRATE
+ if (s->mux_rate)
+ ts->mux_rate = s->mux_rate;
+#endif
if (ts->mux_rate > 1) {
service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) /
@@ -589,7 +604,13 @@ static int mpegts_write_header(AVFormatContext *s)
fail:
av_free(pids);
for(i = 0;i < s->nb_streams; i++) {
+ MpegTSWriteStream *ts_st;
st = s->streams[i];
+ ts_st = st->priv_data;
+ if (ts_st) {
+ av_freep(&ts_st->payload);
+ av_freep(&ts_st->adts);
+ }
av_freep(&st->priv_data);
}
return -1;
@@ -620,7 +641,7 @@ static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
ts->first_pcr;
}
-static uint8_t* write_pcr_bits(uint8_t *buf, int64_t pcr)
+static int write_pcr_bits(uint8_t *buf, int64_t pcr)
{
int64_t pcr_low = pcr % 300, pcr_high = pcr / 300;
@@ -631,7 +652,7 @@ static uint8_t* write_pcr_bits(uint8_t *buf, int64_t pcr)
*buf++ = pcr_high << 7 | pcr_low >> 8 | 0x7e;
*buf++ = pcr_low;
- return buf;
+ return 6;
}
/* Write a single null transport stream packet */
@@ -667,7 +688,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
*q++ = 0x10; /* Adaptation flags: PCR present */
/* PCR coded into 6 bytes */
- q = write_pcr_bits(q, get_pcr(ts, s->pb));
+ q += write_pcr_bits(q, get_pcr(ts, s->pb));
/* stuffing bytes */
memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
@@ -688,6 +709,39 @@ static void write_pts(uint8_t *q, int fourbits, int64_t pts)
*q++ = val;
}
+/* Set an adaptation field flag in an MPEG-TS packet*/
+static void set_af_flag(uint8_t *pkt, int flag)
+{
+ // expect at least one flag to set
+ assert(flag);
+
+ if ((pkt[3] & 0x20) == 0) {
+ // no AF yet, set adaptation field flag
+ pkt[3] |= 0x20;
+ // 1 byte length, no flags
+ pkt[4] = 1;
+ pkt[5] = 0;
+ }
+ pkt[5] |= flag;
+}
+
+/* Extend the adaptation field by size bytes */
+static void extend_af(uint8_t *pkt, int size)
+{
+ // expect already existing adaptation field
+ assert(pkt[3] & 0x20);
+ pkt[4] += size;
+}
+
+/* Get a pointer to MPEG-TS payload (right after TS packet header) */
+static uint8_t *get_ts_payload_start(uint8_t *pkt)
+{
+ if (pkt[3] & 0x20)
+ return pkt + 5 + pkt[4];
+ else
+ return pkt + 4;
+}
+
/* Add a pes header to the front of payload, and segment into an integer number of
* ts packets. The final ts packet is padded using an over-sized adaptation header
* to exactly fill the last ts packet.
@@ -695,7 +749,7 @@ static void write_pts(uint8_t *q, int fourbits, int64_t pts)
*/
static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
const uint8_t *payload, int payload_size,
- int64_t pts, int64_t dts)
+ int64_t pts, int64_t dts, int key)
{
MpegTSWriteStream *ts_st = st->priv_data;
MpegTSWrite *ts = s->priv_data;
@@ -740,8 +794,17 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
*q++ = val;
*q++ = ts_st->pid;
ts_st->cc = (ts_st->cc + 1) & 0xf;
- *q++ = 0x10 | ts_st->cc | (write_pcr ? 0x20 : 0);
+ *q++ = 0x10 | ts_st->cc; // payload indicator + CC
+ if (key && is_start && pts != AV_NOPTS_VALUE) {
+ // set Random Access for key frames
+ if (ts_st->pid == ts_st->service->pcr_pid)
+ write_pcr = 1;
+ set_af_flag(buf, 0x40);
+ q = get_ts_payload_start(buf);
+ }
if (write_pcr) {
+ set_af_flag(buf, 0x10);
+ q = get_ts_payload_start(buf);
// add 11, pcr references the last byte of program clock reference base
if (ts->mux_rate > 1)
pcr = get_pcr(ts, s->pb);
@@ -749,9 +812,8 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
pcr = (dts - delay)*300;
if (dts != AV_NOPTS_VALUE && dts < pcr / 300)
av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");
- *q++ = 7; /* AFC length */
- *q++ = 0x10; /* flags: PCR present */
- q = write_pcr_bits(q, pcr);
+ extend_af(buf, write_pcr_bits(q, pcr));
+ q = get_ts_payload_start(buf);
}
if (is_start) {
int pes_extension = 0;
@@ -877,6 +939,7 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
int size = pkt->size;
uint8_t *buf= pkt->data;
uint8_t *data= NULL;
+ MpegTSWrite *ts = s->priv_data;
MpegTSWriteStream *ts_st = st->priv_data;
const uint64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE)*2;
int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE;
@@ -897,13 +960,13 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
uint32_t state = -1;
if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001) {
- av_log(s, AV_LOG_ERROR, "h264 bitstream malformated, "
+ av_log(s, AV_LOG_ERROR, "H.264 bitstream malformed, "
"no startcode found, use -vbsf h264_mp4toannexb\n");
return -1;
}
do {
- p = ff_find_start_code(p, buf_end, &state);
+ p = avpriv_mpv_find_start_code(p, buf_end, &state);
//av_log(s, AV_LOG_INFO, "nal %d\n", state & 0x1f);
} while (p < buf_end && (state & 0x1f) != 9 &&
(state & 0x1f) != 5 && (state & 0x1f) != 1);
@@ -924,7 +987,7 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
return -1;
if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) {
ADTSContext *adts = ts_st->adts;
- int new_size;
+ int new_size, err;
if (!adts) {
av_log(s, AV_LOG_ERROR, "aac bitstream not in adts format "
"and extradata missing\n");
@@ -936,7 +999,12 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
data = av_malloc(new_size);
if (!data)
return AVERROR(ENOMEM);
- ff_adts_write_frame_header(adts, data, pkt->size, adts->pce_size);
+ err = ff_adts_write_frame_header(adts, data, pkt->size,
+ adts->pce_size);
+ if (err < 0) {
+ av_free(data);
+ return err;
+ }
if (adts->pce_size) {
memcpy(data+ADTS_HEADER_SIZE, adts->pce_data, adts->pce_size);
adts->pce_size = 0;
@@ -949,24 +1017,34 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
// for video and subtitle, write a single pes packet
- mpegts_write_pes(s, st, buf, size, pts, dts);
+ mpegts_write_pes(s, st, buf, size, pts, dts, pkt->flags & AV_PKT_FLAG_KEY);
av_free(data);
return 0;
}
- if (ts_st->payload_index + size > DEFAULT_PES_PAYLOAD_SIZE) {
- mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
- ts_st->payload_pts, ts_st->payload_dts);
- ts_st->payload_index = 0;
+ if (ts_st->payload_size + size > ts->pes_payload_size) {
+ if (ts_st->payload_size) {
+ mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size,
+ ts_st->payload_pts, ts_st->payload_dts,
+ ts_st->payload_flags & AV_PKT_FLAG_KEY);
+ ts_st->payload_size = 0;
+ }
+ if (size > ts->pes_payload_size) {
+ mpegts_write_pes(s, st, buf, size, pts, dts,
+ pkt->flags & AV_PKT_FLAG_KEY);
+ av_free(data);
+ return 0;
+ }
}
- if (!ts_st->payload_index) {
+ if (!ts_st->payload_size) {
ts_st->payload_pts = pts;
ts_st->payload_dts = dts;
+ ts_st->payload_flags = pkt->flags;
}
- memcpy(ts_st->payload + ts_st->payload_index, buf, size);
- ts_st->payload_index += size;
+ memcpy(ts_st->payload + ts_st->payload_size, buf, size);
+ ts_st->payload_size += size;
av_free(data);
@@ -985,10 +1063,12 @@ static int mpegts_write_end(AVFormatContext *s)
for(i = 0; i < s->nb_streams; i++) {
st = s->streams[i];
ts_st = st->priv_data;
- if (ts_st->payload_index > 0) {
- mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
- ts_st->payload_pts, ts_st->payload_dts);
+ if (ts_st->payload_size > 0) {
+ mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size,
+ ts_st->payload_pts, ts_st->payload_dts,
+ ts_st->payload_flags & AV_PKT_FLAG_KEY);
}
+ av_freep(&ts_st->payload);
av_freep(&ts_st->adts);
}
avio_flush(s->pb);
@@ -1005,15 +1085,15 @@ static int mpegts_write_end(AVFormatContext *s)
}
AVOutputFormat ff_mpegts_muxer = {
- "mpegts",
- NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
- "video/x-mpegts",
- "ts,m2t",
- sizeof(MpegTSWrite),
- CODEC_ID_MP2,
- CODEC_ID_MPEG2VIDEO,
- mpegts_write_header,
- mpegts_write_packet,
- mpegts_write_end,
+ .name = "mpegts",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
+ .mime_type = "video/x-mpegts",
+ .extensions = "ts,m2t",
+ .priv_data_size = sizeof(MpegTSWrite),
+ .audio_codec = CODEC_ID_MP2,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mpegts_write_header,
+ .write_packet = mpegts_write_packet,
+ .write_trailer = mpegts_write_end,
.priv_class = &mpegts_muxer_class,
};
diff --git a/libavformat/mpjpeg.c b/libavformat/mpjpeg.c
index ebb57bf..79cc272 100644
--- a/libavformat/mpjpeg.c
+++ b/libavformat/mpjpeg.c
@@ -22,7 +22,7 @@
/* Multipart JPEG */
-#define BOUNDARY_TAG "ffserver"
+#define BOUNDARY_TAG "avserver"
static int mpjpeg_write_header(AVFormatContext *s)
{
@@ -54,14 +54,13 @@ static int mpjpeg_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_mpjpeg_muxer = {
- "mpjpeg",
- NULL_IF_CONFIG_SMALL("MIME multipart JPEG format"),
- "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG,
- "mjpg",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_MJPEG,
- mpjpeg_write_header,
- mpjpeg_write_packet,
- mpjpeg_write_trailer,
+ .name = "mpjpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("MIME multipart JPEG format"),
+ .mime_type = "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG,
+ .extensions = "mjpg",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_MJPEG,
+ .write_header = mpjpeg_write_header,
+ .write_packet = mpjpeg_write_packet,
+ .write_trailer = mpjpeg_write_trailer,
};
diff --git a/libavformat/msnwc_tcp.c b/libavformat/msnwc_tcp.c
index d9d8000..7e76c07 100644
--- a/libavformat/msnwc_tcp.c
+++ b/libavformat/msnwc_tcp.c
@@ -20,6 +20,7 @@
#include "libavcodec/bytestream.h"
#include "avformat.h"
+#include "internal.h"
#define HEADER_SIZE 24
@@ -75,7 +76,7 @@ static int msnwc_tcp_read_header(AVFormatContext *ctx, AVFormatParameters *ap)
AVCodecContext *codec;
AVStream *st;
- st = av_new_stream(ctx, 0);
+ st = avformat_new_stream(ctx, NULL);
if(!st)
return AVERROR(ENOMEM);
@@ -84,7 +85,7 @@ static int msnwc_tcp_read_header(AVFormatContext *ctx, AVFormatParameters *ap)
codec->codec_id = CODEC_ID_MIMIC;
codec->codec_tag = MKTAG('M', 'L', '2', '0');
- av_set_pts_info(st, 32, 1, 1000);
+ avpriv_set_pts_info(st, 32, 1, 1000);
/* Some files start with "connected\r\n\r\n".
* So skip until we find the first byte of struct size */
@@ -131,10 +132,9 @@ static int msnwc_tcp_read_packet(AVFormatContext *ctx, AVPacket *pkt)
}
AVInputFormat ff_msnwc_tcp_demuxer = {
- "msnwctcp",
- NULL_IF_CONFIG_SMALL("MSN TCP Webcam stream"),
- 0,
- msnwc_tcp_probe,
- msnwc_tcp_read_header,
- msnwc_tcp_read_packet,
+ .name = "msnwctcp",
+ .long_name = NULL_IF_CONFIG_SMALL("MSN TCP Webcam stream"),
+ .read_probe = msnwc_tcp_probe,
+ .read_header = msnwc_tcp_read_header,
+ .read_packet = msnwc_tcp_read_packet,
};
diff --git a/libavformat/mtv.c b/libavformat/mtv.c
index 92d38e1..c3fb15c 100644
--- a/libavformat/mtv.c
+++ b/libavformat/mtv.c
@@ -27,13 +27,12 @@
#include "libavutil/bswap.h"
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define MTV_ASUBCHUNK_DATA_SIZE 500
#define MTV_HEADER_SIZE 512
#define MTV_AUDIO_PADDING_SIZE 12
#define AUDIO_SAMPLING_RATE 44100
-#define VIDEO_SID 0
-#define AUDIO_SID 1
typedef struct MTVDemuxContext {
@@ -118,11 +117,11 @@ static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap)
// video - raw rgb565
- st = av_new_stream(s, VIDEO_SID);
+ st = avformat_new_stream(s, NULL);
if(!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 64, 1, mtv->video_fps);
+ avpriv_set_pts_info(st, 64, 1, mtv->video_fps);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_RAWVIDEO;
st->codec->pix_fmt = PIX_FMT_RGB565;
@@ -134,11 +133,11 @@ static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap)
// audio - mp3
- st = av_new_stream(s, AUDIO_SID);
+ st = avformat_new_stream(s, NULL);
if(!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 64, 1, AUDIO_SAMPLING_RATE);
+ avpriv_set_pts_info(st, 64, 1, AUDIO_SAMPLING_RATE);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_MP3;
st->codec->bit_rate = mtv->audio_br;
@@ -171,7 +170,7 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
pkt->pos -= MTV_AUDIO_PADDING_SIZE;
- pkt->stream_index = AUDIO_SID;
+ pkt->stream_index = 1;
}else
{
@@ -190,17 +189,17 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
for(i=0;i<mtv->img_segment_size/2;i++)
*((uint16_t *)pkt->data+i) = av_bswap16(*((uint16_t *)pkt->data+i));
#endif
- pkt->stream_index = VIDEO_SID;
+ pkt->stream_index = 0;
}
return ret;
}
AVInputFormat ff_mtv_demuxer = {
- "MTV",
- NULL_IF_CONFIG_SMALL("MTV format"),
- sizeof(MTVDemuxContext),
- mtv_probe,
- mtv_read_header,
- mtv_read_packet,
+ .name = "MTV",
+ .long_name = NULL_IF_CONFIG_SMALL("MTV format"),
+ .priv_data_size = sizeof(MTVDemuxContext),
+ .read_probe = mtv_probe,
+ .read_header = mtv_read_header,
+ .read_packet = mtv_read_packet,
};
diff --git a/libavformat/mvi.c b/libavformat/mvi.c
index 809cdf5..4782aad 100644
--- a/libavformat/mvi.c
+++ b/libavformat/mvi.c
@@ -20,6 +20,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#define MVI_FRAC_BITS 10
@@ -42,11 +43,11 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
AVStream *ast, *vst;
unsigned int version, frames_count, msecs_per_frame, player_version;
- ast = av_new_stream(s, 0);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
- vst = av_new_stream(s, 0);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
@@ -76,14 +77,14 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
return AVERROR_INVALIDDATA;
}
- av_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
+ avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
ast->codec->codec_id = CODEC_ID_PCM_U8;
ast->codec->channels = 1;
ast->codec->bits_per_coded_sample = 8;
ast->codec->bit_rate = ast->codec->sample_rate * 8;
- av_set_pts_info(vst, 64, msecs_per_frame, 1000000);
+ avpriv_set_pts_info(vst, 64, msecs_per_frame, 1000000);
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vst->codec->codec_id = CODEC_ID_MOTIONPIXELS;
@@ -124,11 +125,10 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_mvi_demuxer = {
- "mvi",
- NULL_IF_CONFIG_SMALL("Motion Pixels MVI format"),
- sizeof(MviDemuxContext),
- NULL,
- read_header,
- read_packet,
+ .name = "mvi",
+ .long_name = NULL_IF_CONFIG_SMALL("Motion Pixels MVI format"),
+ .priv_data_size = sizeof(MviDemuxContext),
+ .read_header = read_header,
+ .read_packet = read_packet,
.extensions = "mvi"
};
diff --git a/libavformat/mxf.c b/libavformat/mxf.c
index 6192368..e4d9fbd 100644
--- a/libavformat/mxf.c
+++ b/libavformat/mxf.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/common.h"
#include "mxf.h"
/**
@@ -41,6 +42,8 @@ const MXFCodecUL ff_mxf_codec_uls[] = {
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14, CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, CODEC_ID_RAWVIDEO }, /* Uncompressed */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x03,0x02,0x00,0x00 }, 14, CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x00,0x00 }, 14, CODEC_ID_H264 }, /* H.264/MPEG-4 AVC Intra */
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x02,0x00 }, 15, CODEC_ID_V210 }, /* V210 */
/* SoundEssenceCompression */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16LE }, /* Uncompressed */
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16LE },
@@ -80,7 +83,7 @@ static const struct {
{PIX_FMT_PAL8, {'P', 8 }},
};
-static const int num_pixel_layouts = sizeof(ff_mxf_pixel_layouts) / sizeof(*ff_mxf_pixel_layouts);
+static const int num_pixel_layouts = FF_ARRAY_ELEMS(ff_mxf_pixel_layouts);
int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum PixelFormat *pix_fmt)
{
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index fcee7a7..c4c3f59 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -46,8 +46,10 @@
//#define DEBUG
#include "libavutil/aes.h"
+#include "libavutil/mathematics.h"
#include "libavcodec/bytestream.h"
#include "avformat.h"
+#include "internal.h"
#include "mxf.h"
typedef struct {
@@ -223,12 +225,13 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt,
if (length > 61444) /* worst case PAL 1920 samples 8 channels */
return -1;
- av_new_packet(pkt, length);
- avio_read(pb, pkt->data, length);
+ length = av_get_packet(pb, pkt, length);
+ if (length < 0)
+ return length;
data_ptr = pkt->data;
end_ptr = pkt->data + length;
buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */
- for (; buf_ptr < end_ptr; ) {
+ for (; buf_ptr + st->codec->channels*4 < end_ptr; ) {
for (i = 0; i < st->codec->channels; i++) {
uint32_t sample = bytestream_get_le32(&buf_ptr);
if (st->codec->bits_per_coded_sample == 24)
@@ -238,7 +241,7 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt,
}
buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M
}
- pkt->size = data_ptr - pkt->data;
+ av_shrink_packet(pkt, data_ptr - pkt->data);
return 0;
}
@@ -248,7 +251,7 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv
MXFContext *mxf = s->priv_data;
AVIOContext *pb = s->pb;
int64_t end = avio_tell(pb) + klv->length;
- uint64_t size;
+ int64_t size;
uint64_t orig_size;
uint64_t plaintext_size;
uint8_t ivec[16];
@@ -290,12 +293,16 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv
if (memcmp(tmpbuf, checkv, 16))
av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
size -= 32;
- av_get_packet(pb, pkt, size);
+ size = av_get_packet(pb, pkt, size);
+ if (size < 0)
+ return size;
+ else if (size < plaintext_size)
+ return AVERROR_INVALIDDATA;
size -= plaintext_size;
if (mxf->aesc)
av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
&pkt->data[plaintext_size], size >> 4, ivec, 1);
- pkt->size = orig_size;
+ av_shrink_packet(pkt, orig_size);
pkt->stream_index = index;
avio_skip(pb, end - avio_tell(pb));
return 0;
@@ -332,8 +339,11 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
return -1;
}
- } else
- av_get_packet(s->pb, pkt, klv.length);
+ } else {
+ int ret = av_get_packet(s->pb, pkt, klv.length);
+ if (ret < 0)
+ return ret;
+ }
pkt->stream_index = index;
pkt->pos = klv.offset;
return 0;
@@ -737,17 +747,18 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
if (!source_track)
continue;
- st = av_new_stream(mxf->fc, source_track->track_id);
+ st = avformat_new_stream(mxf->fc, NULL);
if (!st) {
av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n");
return -1;
}
+ st->id = source_track->track_id;
st->priv_data = source_track;
st->duration = component->duration;
if (st->duration == -1)
st->duration = AV_NOPTS_VALUE;
st->start_time = component->start_position;
- av_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den);
+ avpriv_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den);
if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
@@ -820,12 +831,12 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
/* TODO: implement CODEC_ID_RAWAUDIO */
if (st->codec->codec_id == CODEC_ID_PCM_S16LE) {
- if (descriptor->bits_per_sample == 24)
+ if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
st->codec->codec_id = CODEC_ID_PCM_S24LE;
else if (descriptor->bits_per_sample == 32)
st->codec->codec_id = CODEC_ID_PCM_S32LE;
} else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
- if (descriptor->bits_per_sample == 24)
+ if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
st->codec->codec_id = CODEC_ID_PCM_S24BE;
else if (descriptor->bits_per_sample == 32)
st->codec->codec_id = CODEC_ID_PCM_S32BE;
@@ -1010,17 +1021,17 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
sample_time = 0;
seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
- av_update_cur_dts(s, st, sample_time);
+ ff_update_cur_dts(s, st, sample_time);
return 0;
}
AVInputFormat ff_mxf_demuxer = {
- "mxf",
- NULL_IF_CONFIG_SMALL("Material eXchange Format"),
- sizeof(MXFContext),
- mxf_probe,
- mxf_read_header,
- mxf_read_packet,
- mxf_read_close,
- mxf_read_seek,
+ .name = "mxf",
+ .long_name = NULL_IF_CONFIG_SMALL("Material eXchange Format"),
+ .priv_data_size = sizeof(MXFContext),
+ .read_probe = mxf_probe,
+ .read_header = mxf_read_header,
+ .read_packet = mxf_read_packet,
+ .read_close = mxf_read_close,
+ .read_seek = mxf_read_seek,
};
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 387263e..65935ab 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -39,6 +39,7 @@
#include "libavcodec/bytestream.h"
#include "audiointerleave.h"
#include "avformat.h"
+#include "internal.h"
#include "mxf.h"
static const int NTSC_samples_per_frame[] = { 1602, 1601, 1602, 1601, 1602, 0 };
@@ -67,7 +68,7 @@ typedef struct {
int index; ///< index in mxf_essence_container_uls table
const UID *codec_ul;
int order; ///< interleaving order if dts are equal
- int interlaced; ///< wether picture is interlaced
+ int interlaced; ///< whether picture is interlaced
int temporal_reordering;
AVRational aspect_ratio; ///< display aspect ratio
int closed_gop; ///< gop is closed, used in mpeg-2 frame parsing
@@ -1284,6 +1285,8 @@ static const UID mxf_mpeg2_codec_uls[] = {
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, // MP-HL Long GOP
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, // 422P-HL I-Frame
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, // 422P-HL Long GOP
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x02,0x00 }, // MP at H-14 I-Frame
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x03,0x00 }, // MP at H-14 Long GOP
};
static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx)
@@ -1295,6 +1298,8 @@ static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx)
return &mxf_mpeg2_codec_uls[0+long_gop];
else if (avctx->level == 4) // High
return &mxf_mpeg2_codec_uls[4+long_gop];
+ else if (avctx->level == 6) // High 14
+ return &mxf_mpeg2_codec_uls[8+long_gop];
} else if (avctx->profile == 0) { // 422
if (avctx->level == 5) // Main
return &mxf_mpeg2_codec_uls[2+long_gop];
@@ -1407,6 +1412,8 @@ static int mxf_write_header(AVFormatContext *s)
int i;
uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};
const int *samples_per_frame = NULL;
+ AVDictionaryEntry *t;
+ int64_t timestamp = 0;
if (!s->nb_streams)
return -1;
@@ -1435,7 +1442,7 @@ static int mxf_write_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "unsupported video frame rate\n");
return -1;
}
- av_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);
+ avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);
if (s->oformat == &ff_mxf_d10_muxer) {
if (st->codec->bit_rate == 50000000)
if (mxf->time_base.den == 25) sc->index = 3;
@@ -1463,7 +1470,7 @@ static int mxf_write_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");
return -1;
}
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
if (s->oformat == &ff_mxf_d10_muxer) {
if (st->index != 1) {
av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");
@@ -1512,8 +1519,15 @@ static int mxf_write_header(AVFormatContext *s)
sc->order = AV_RB32(sc->track_essence_element_key+12);
}
+#if FF_API_TIMESTAMP
if (s->timestamp)
- mxf->timestamp = mxf_parse_timestamp(s->timestamp);
+ timestamp = s->timestamp;
+ else
+#endif
+ if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
+ timestamp = ff_iso8601_to_unix_time(t->value);
+ if (timestamp)
+ mxf->timestamp = mxf_parse_timestamp(timestamp);
mxf->duration = -1;
mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));
@@ -1549,7 +1563,7 @@ static uint32_t ff_framenum_to_12m_time_code(unsigned frame, int drop, int fps)
((((frame / (fps * 60)) % 60) / 10) << 12) | // tens of minutes
((((frame / (fps * 60)) % 60) % 10) << 8) | // units of minutes
(0 << 7) | // b1
- (0 << 6) | // b2 (NSC), field phase (PAL)
+ (0 << 6) | // b2 (NTSC), field phase (PAL)
((((frame / (fps * 3600) % 24)) / 10) << 4) | // tens of hours
( (frame / (fps * 3600) % 24)) % 10; // units of hours
}
@@ -1880,33 +1894,30 @@ static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int
}
AVOutputFormat ff_mxf_muxer = {
- "mxf",
- NULL_IF_CONFIG_SMALL("Material eXchange Format"),
- "application/mxf",
- "mxf",
- sizeof(MXFContext),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_MPEG2VIDEO,
- mxf_write_header,
- mxf_write_packet,
- mxf_write_footer,
- AVFMT_NOTIMESTAMPS,
- NULL,
- mxf_interleave,
+ .name = "mxf",
+ .long_name = NULL_IF_CONFIG_SMALL("Material eXchange Format"),
+ .mime_type = "application/mxf",
+ .extensions = "mxf",
+ .priv_data_size = sizeof(MXFContext),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mxf_write_header,
+ .write_packet = mxf_write_packet,
+ .write_trailer = mxf_write_footer,
+ .flags = AVFMT_NOTIMESTAMPS,
+ .interleave_packet = mxf_interleave,
};
AVOutputFormat ff_mxf_d10_muxer = {
- "mxf_d10",
- NULL_IF_CONFIG_SMALL("Material eXchange Format, D-10 Mapping"),
- "application/mxf",
- NULL,
- sizeof(MXFContext),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_MPEG2VIDEO,
- mxf_write_header,
- mxf_write_packet,
- mxf_write_footer,
- AVFMT_NOTIMESTAMPS,
- NULL,
- mxf_interleave,
+ .name = "mxf_d10",
+ .long_name = NULL_IF_CONFIG_SMALL("Material eXchange Format, D-10 Mapping"),
+ .mime_type = "application/mxf",
+ .priv_data_size = sizeof(MXFContext),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_header = mxf_write_header,
+ .write_packet = mxf_write_packet,
+ .write_trailer = mxf_write_footer,
+ .flags = AVFMT_NOTIMESTAMPS,
+ .interleave_packet = mxf_interleave,
};
diff --git a/libavformat/mxg.c b/libavformat/mxg.c
index 5caa68a..a740364 100644
--- a/libavformat/mxg.c
+++ b/libavformat/mxg.c
@@ -22,10 +22,9 @@
#include "libavutil/intreadwrite.h"
#include "libavcodec/mjpeg.h"
#include "avformat.h"
+#include "internal.h"
#include "avio.h"
-#define VIDEO_STREAM_INDEX 0
-#define AUDIO_STREAM_INDEX 1
#define DEFAULT_PACKET_SIZE 1024
#define OVERREAD_SIZE 3
@@ -44,14 +43,14 @@ static int mxg_read_header(AVFormatContext *s, AVFormatParameters *ap)
MXGContext *mxg = s->priv_data;
/* video parameters will be extracted from the compressed bitstream */
- video_st = av_new_stream(s, VIDEO_STREAM_INDEX);
+ video_st = avformat_new_stream(s, NULL);
if (!video_st)
return AVERROR(ENOMEM);
video_st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
video_st->codec->codec_id = CODEC_ID_MXPEG;
- av_set_pts_info(video_st, 64, 1, 1000000);
+ avpriv_set_pts_info(video_st, 64, 1, 1000000);
- audio_st = av_new_stream(s, AUDIO_STREAM_INDEX);
+ audio_st = avformat_new_stream(s, NULL);
if (!audio_st)
return AVERROR(ENOMEM);
audio_st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -60,7 +59,7 @@ static int mxg_read_header(AVFormatContext *s, AVFormatParameters *ap)
audio_st->codec->sample_rate = 8000;
audio_st->codec->bits_per_coded_sample = 8;
audio_st->codec->block_align = 1;
- av_set_pts_info(audio_st, 64, 1, 1000000);
+ avpriv_set_pts_info(audio_st, 64, 1, 1000000);
mxg->soi_ptr = mxg->buffer_ptr = mxg->buffer = 0;
mxg->buffer_size = 0;
@@ -166,7 +165,7 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
}
pkt->pts = pkt->dts = mxg->dts;
- pkt->stream_index = VIDEO_STREAM_INDEX;
+ pkt->stream_index = 0;
pkt->destruct = NULL;
pkt->size = mxg->buffer_ptr - mxg->soi_ptr;
pkt->data = mxg->soi_ptr;
@@ -204,7 +203,7 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
if (marker == APP13 && size >= 16) { /* audio data */
/* time (GMT) of first sample in usec since 1970, little-endian */
pkt->pts = pkt->dts = AV_RL64(startmarker_ptr + 8);
- pkt->stream_index = AUDIO_STREAM_INDEX;
+ pkt->stream_index = 1;
pkt->destruct = NULL;
pkt->size = size - 14;
pkt->data = startmarker_ptr + 16;
diff --git a/libavformat/ncdec.c b/libavformat/ncdec.c
index 7e43adc..ab1d302 100644
--- a/libavformat/ncdec.c
+++ b/libavformat/ncdec.c
@@ -22,6 +22,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define NC_VIDEO_FLAG 0x1A5
@@ -45,7 +46,7 @@ static int nc_probe(AVProbeData *probe_packet)
static int nc_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -54,7 +55,7 @@ static int nc_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->codec_id = CODEC_ID_MPEG4;
st->need_parsing = AVSTREAM_PARSE_FULL;
- av_set_pts_info(st, 64, 1, 100);
+ avpriv_set_pts_info(st, 64, 1, 100);
return 0;
}
@@ -91,11 +92,10 @@ static int nc_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_nc_demuxer = {
- "nc",
- NULL_IF_CONFIG_SMALL("NC camera feed format"),
- 0,
- nc_probe,
- nc_read_header,
- nc_read_packet,
+ .name = "nc",
+ .long_name = NULL_IF_CONFIG_SMALL("NC camera feed format"),
+ .read_probe = nc_probe,
+ .read_header = nc_read_header,
+ .read_packet = nc_read_packet,
.extensions = "v",
};
diff --git a/libavformat/network.c b/libavformat/network.c
new file mode 100644
index 0000000..bfc34c7
--- /dev/null
+++ b/libavformat/network.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2007 The Libav Project
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "network.h"
+#include "libavcodec/internal.h"
+
+#define THREADS (HAVE_PTHREADS || (defined(WIN32) && !defined(__MINGW32CE__)))
+
+#if THREADS
+#if HAVE_PTHREADS
+#include <pthread.h>
+#else
+#include "libavcodec/w32pthreads.h"
+#endif
+#endif
+
+#if CONFIG_OPENSSL
+#include <openssl/ssl.h>
+static int openssl_init;
+#if THREADS
+#include <openssl/crypto.h>
+#include "libavutil/avutil.h"
+pthread_mutex_t *openssl_mutexes;
+static void openssl_lock(int mode, int type, const char *file, int line)
+{
+ if (mode & CRYPTO_LOCK)
+ pthread_mutex_lock(&openssl_mutexes[type]);
+ else
+ pthread_mutex_unlock(&openssl_mutexes[type]);
+}
+#if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
+static unsigned long openssl_thread_id(void)
+{
+ return (intptr_t) pthread_self();
+}
+#endif
+#endif
+#endif
+#if CONFIG_GNUTLS
+#include <gnutls/gnutls.h>
+#if THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00
+#include <gcrypt.h>
+#include <errno.h>
+#undef malloc
+#undef free
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+#endif
+#endif
+
+void ff_tls_init(void)
+{
+ avpriv_lock_avformat();
+#if CONFIG_OPENSSL
+ if (!openssl_init) {
+ SSL_library_init();
+ SSL_load_error_strings();
+#if THREADS
+ if (!CRYPTO_get_locking_callback()) {
+ int i;
+ openssl_mutexes = av_malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
+ for (i = 0; i < CRYPTO_num_locks(); i++)
+ pthread_mutex_init(&openssl_mutexes[i], NULL);
+ CRYPTO_set_locking_callback(openssl_lock);
+#if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
+ CRYPTO_set_id_callback(openssl_thread_id);
+#endif
+ }
+#endif
+ }
+ openssl_init++;
+#endif
+#if CONFIG_GNUTLS
+#if THREADS && GNUTLS_VERSION_NUMBER < 0x020b00
+ if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
+ gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+#endif
+ gnutls_global_init();
+#endif
+ avpriv_unlock_avformat();
+}
+
+void ff_tls_deinit(void)
+{
+ avpriv_lock_avformat();
+#if CONFIG_OPENSSL
+ openssl_init--;
+ if (!openssl_init) {
+#if THREADS
+ if (CRYPTO_get_locking_callback() == openssl_lock) {
+ int i;
+ CRYPTO_set_locking_callback(NULL);
+ for (i = 0; i < CRYPTO_num_locks(); i++)
+ pthread_mutex_destroy(&openssl_mutexes[i]);
+ av_free(openssl_mutexes);
+ }
+#endif
+ }
+#endif
+#if CONFIG_GNUTLS
+ gnutls_global_deinit();
+#endif
+ avpriv_unlock_avformat();
+}
+
+int ff_network_inited_globally;
+
+int ff_network_init(void)
+{
+#if HAVE_WINSOCK2_H
+ WSADATA wsaData;
+#endif
+
+ if (!ff_network_inited_globally)
+ av_log(NULL, AV_LOG_WARNING, "Using network protocols without global "
+ "network initialization. Please use "
+ "avformat_network_init(), this will "
+ "become mandatory later.\n");
+#if HAVE_WINSOCK2_H
+ if (WSAStartup(MAKEWORD(1,1), &wsaData))
+ return 0;
+#endif
+ return 1;
+}
+
+int ff_network_wait_fd(int fd, int write)
+{
+ int ev = write ? POLLOUT : POLLIN;
+ struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
+ int ret;
+ ret = poll(&p, 1, 100);
+ return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN);
+}
+
+void ff_network_close(void)
+{
+#if HAVE_WINSOCK2_H
+ WSACleanup();
+#endif
+}
+
+#if HAVE_WINSOCK2_H
+int ff_neterrno(void)
+{
+ int err = WSAGetLastError();
+ switch (err) {
+ case WSAEWOULDBLOCK:
+ return AVERROR(EAGAIN);
+ case WSAEINTR:
+ return AVERROR(EINTR);
+ }
+ return -err;
+}
+#endif
+
+int ff_is_multicast_address(struct sockaddr *addr)
+{
+ if (addr->sa_family == AF_INET) {
+ return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr));
+ }
+#if HAVE_STRUCT_SOCKADDR_IN6
+ if (addr->sa_family == AF_INET6) {
+ return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr);
+ }
+#endif
+
+ return 0;
+}
+
diff --git a/libavformat/network.h b/libavformat/network.h
index 80d094a..72d01d2 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -36,17 +36,7 @@
#define ECONNREFUSED WSAECONNREFUSED
#define EINPROGRESS WSAEINPROGRESS
-static inline int ff_neterrno(void)
-{
- int err = WSAGetLastError();
- switch (err) {
- case WSAEWOULDBLOCK:
- return AVERROR(EAGAIN);
- case WSAEINTR:
- return AVERROR(EINTR);
- }
- return -err;
-}
+int ff_neterrno(void);
#else
#include <sys/types.h>
#include <sys/socket.h>
@@ -66,31 +56,14 @@ static inline int ff_neterrno(void)
int ff_socket_nonblock(int socket, int enable);
-static inline int ff_network_init(void)
-{
-#if HAVE_WINSOCK2_H
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(1,1), &wsaData))
- return 0;
-#endif
- return 1;
-}
-
-static inline int ff_network_wait_fd(int fd, int write)
-{
- int ev = write ? POLLOUT : POLLIN;
- struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
- int ret;
- ret = poll(&p, 1, 100);
- return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN);
-}
-
-static inline void ff_network_close(void)
-{
-#if HAVE_WINSOCK2_H
- WSACleanup();
-#endif
-}
+extern int ff_network_inited_globally;
+int ff_network_init(void);
+void ff_network_close(void);
+
+void ff_tls_init(void);
+void ff_tls_deinit(void);
+
+int ff_network_wait_fd(int fd, int write);
int ff_inet_aton (const char * str, struct in_addr * add);
@@ -191,18 +164,6 @@ const char *ff_gai_strerror(int ecode);
#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff)
#endif
-static inline int ff_is_multicast_address(struct sockaddr *addr)
-{
- if (addr->sa_family == AF_INET) {
- return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr));
- }
-#if HAVE_STRUCT_SOCKADDR_IN6
- if (addr->sa_family == AF_INET6) {
- return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr);
- }
-#endif
-
- return 0;
-}
+int ff_is_multicast_address(struct sockaddr *addr);
#endif /* AVFORMAT_NETWORK_H */
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index 9adb2f4..18dfde2 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -18,7 +18,10 @@
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
+#include "libavutil/mathematics.h"
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
#include "libavutil/dict.h"
@@ -69,7 +72,11 @@
* so the header seems to not be mandatory. (for streaming).
*
* index slice duration check (excepts nsvtrailer.nsv):
- * for f in [^n]*.nsv; do DUR="$(ffmpeg -i "$f" 2>/dev/null | grep 'NSVf duration' | cut -d ' ' -f 4)"; IC="$(ffmpeg -i "$f" 2>/dev/null | grep 'INDEX ENTRIES' | cut -d ' ' -f 2)"; echo "duration $DUR, slite time $(($DUR/$IC))"; done
+ * for f in [^n]*.nsv; do
+ * DUR="$(avconv -i "$f" 2> /dev/null | grep 'NSVf duration' | cut -d ' ' -f 4)"
+ * IC="$(avconv -i "$f" 2> /dev/null | grep 'INDEX ENTRIES' | cut -d ' ' -f 2)"
+ * echo "duration $DUR, slite time $(($DUR/$IC))"
+ * done
*/
/*
@@ -435,10 +442,11 @@ static int nsv_parse_NSVs_header(AVFormatContext *s, AVFormatParameters *ap)
nsv->vheight = vwidth;
if (vtag != T_NONE) {
int i;
- st = av_new_stream(s, NSV_ST_VIDEO);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
+ st->id = NSV_ST_VIDEO;
nst = av_mallocz(sizeof(NSVStream));
if (!nst)
goto fail;
@@ -450,7 +458,7 @@ static int nsv_parse_NSVs_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->height = vheight;
st->codec->bits_per_coded_sample = 24; /* depth XXX */
- av_set_pts_info(st, 64, framerate.den, framerate.num);
+ avpriv_set_pts_info(st, 64, framerate.den, framerate.num);
st->start_time = 0;
st->duration = av_rescale(nsv->duration, framerate.num, 1000*framerate.den);
@@ -466,10 +474,11 @@ static int nsv_parse_NSVs_header(AVFormatContext *s, AVFormatParameters *ap)
}
if (atag != T_NONE) {
#ifndef DISABLE_AUDIO
- st = av_new_stream(s, NSV_ST_AUDIO);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto fail;
+ st->id = NSV_ST_AUDIO;
nst = av_mallocz(sizeof(NSVStream));
if (!nst)
goto fail;
@@ -481,7 +490,7 @@ static int nsv_parse_NSVs_header(AVFormatContext *s, AVFormatParameters *ap)
st->need_parsing = AVSTREAM_PARSE_FULL; /* for PCM we will read a chunk later and put correct info */
/* set timebase to common denominator of ms and framerate */
- av_set_pts_info(st, 64, 1, framerate.num*1000);
+ avpriv_set_pts_info(st, 64, 1, framerate.num*1000);
st->start_time = 0;
st->duration = (int64_t)nsv->duration * framerate.num;
#endif
@@ -531,7 +540,7 @@ static int nsv_read_header(AVFormatContext *s, AVFormatParameters *ap)
err = nsv_read_chunk(s, 1);
av_dlog(s, "parsed header\n");
- return 0;
+ return err;
}
static int nsv_read_chunk(AVFormatContext *s, int fill_header)
@@ -774,12 +783,12 @@ static int nsv_probe(AVProbeData *p)
}
AVInputFormat ff_nsv_demuxer = {
- "nsv",
- NULL_IF_CONFIG_SMALL("Nullsoft Streaming Video"),
- sizeof(NSVContext),
- nsv_probe,
- nsv_read_header,
- nsv_read_packet,
- nsv_read_close,
- nsv_read_seek,
+ .name = "nsv",
+ .long_name = NULL_IF_CONFIG_SMALL("Nullsoft Streaming Video"),
+ .priv_data_size = sizeof(NSVContext),
+ .read_probe = nsv_probe,
+ .read_header = nsv_read_header,
+ .read_packet = nsv_read_packet,
+ .read_close = nsv_read_close,
+ .read_seek = nsv_read_seek,
};
diff --git a/libavformat/nullenc.c b/libavformat/nullenc.c
index 8e38b27..9849f46 100644
--- a/libavformat/nullenc.c
+++ b/libavformat/nullenc.c
@@ -27,14 +27,10 @@ static int null_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_null_muxer = {
- "null",
- NULL_IF_CONFIG_SMALL("raw null video format"),
- NULL,
- NULL,
- 0,
- AV_NE(CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE),
- CODEC_ID_RAWVIDEO,
- NULL,
- null_write_packet,
- .flags = AVFMT_NOFILE | AVFMT_RAWPICTURE | AVFMT_NOTIMESTAMPS,
+ .name = "null",
+ .long_name = NULL_IF_CONFIG_SMALL("raw null video format"),
+ .audio_codec = AV_NE(CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE),
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_packet = null_write_packet,
+ .flags = AVFMT_NOFILE | AVFMT_NOTIMESTAMPS | AVFMT_RAWPICTURE,
};
diff --git a/libavformat/nut.c b/libavformat/nut.c
index 9a2ee6b..ac62d4f 100644
--- a/libavformat/nut.c
+++ b/libavformat/nut.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/mathematics.h"
#include "libavutil/tree.h"
#include "nut.h"
#include "internal.h"
@@ -69,6 +70,12 @@ const AVCodecTag ff_nut_video_tags[] = {
{ CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 48 ) },
{ CODEC_ID_RAWVIDEO, MKTAG(48 , 'B', 'G', 'R') },
{ CODEC_ID_RAWVIDEO, MKTAG(48 , 'R', 'G', 'B') },
+ { CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 10 ) },
+ { CODEC_ID_RAWVIDEO, MKTAG(10 , 11 , '3', 'Y') },
+ { CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 10 ) },
+ { CODEC_ID_RAWVIDEO, MKTAG(10 , 10 , '3', 'Y') },
+ { CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 10 ) },
+ { CODEC_ID_RAWVIDEO, MKTAG(10 , 0 , '3', 'Y') },
{ CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0 , 16 ) },
{ CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '1', 'Y') },
{ CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 16 ) },
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index db1b999..9cec89e 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -20,10 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <strings.h>
#include "libavutil/avstring.h"
#include "libavutil/bswap.h"
#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
#include "libavutil/tree.h"
#include "avio_internal.h"
#include "nut.h"
@@ -287,7 +287,7 @@ static int decode_main_header(NUTContext *nut){
nut->stream = av_mallocz(sizeof(StreamContext)*stream_count);
for(i=0; i<stream_count; i++){
- av_new_stream(s, i);
+ avformat_new_stream(s, NULL);
}
return 0;
@@ -374,7 +374,7 @@ static int decode_stream_header(NUTContext *nut){
return -1;
}
stc->time_base= &nut->time_base[stc->time_base_id];
- av_set_pts_info(s->streams[stream_id], 63, stc->time_base->num, stc->time_base->den);
+ avpriv_set_pts_info(s->streams[stream_id], 63, stc->time_base->num, stc->time_base->den);
return 0;
}
@@ -415,7 +415,7 @@ static int decode_info_header(NUTContext *nut){
if(chapter_id && !stream_id_plus1){
int64_t start= chapter_start / nut->time_base_count;
- chapter= ff_new_chapter(s, chapter_id,
+ chapter= avpriv_new_chapter(s, chapter_id,
nut->time_base[chapter_start % nut->time_base_count],
start, start + chapter_len, NULL);
metadata = &chapter->metadata;
@@ -458,8 +458,8 @@ static int decode_info_header(NUTContext *nut){
set_disposition_bits(s, str_value, stream_id_plus1 - 1);
continue;
}
- if(metadata && strcasecmp(name,"Uses")
- && strcasecmp(name,"Depends") && strcasecmp(name,"Replaces"))
+ if(metadata && av_strcasecmp(name,"Uses")
+ && av_strcasecmp(name,"Depends") && av_strcasecmp(name,"Replaces"))
av_dict_set(metadata, name, str_value, 0);
}
}
@@ -873,16 +873,16 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flag
(void **) next_node);
av_log(s, AV_LOG_DEBUG, "%"PRIu64"-%"PRIu64" %"PRId64"-%"PRId64"\n", next_node[0]->pos, next_node[1]->pos,
next_node[0]->ts , next_node[1]->ts);
- pos= av_gen_search(s, -1, dummy.ts, next_node[0]->pos, next_node[1]->pos, next_node[1]->pos,
- next_node[0]->ts , next_node[1]->ts, AVSEEK_FLAG_BACKWARD, &ts, nut_read_timestamp);
+ pos = ff_gen_search(s, -1, dummy.ts, next_node[0]->pos, next_node[1]->pos, next_node[1]->pos,
+ next_node[0]->ts , next_node[1]->ts, AVSEEK_FLAG_BACKWARD, &ts, nut_read_timestamp);
if(!(flags & AVSEEK_FLAG_BACKWARD)){
dummy.pos= pos+16;
next_node[1]= &nopts_sp;
av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp,
(void **) next_node);
- pos2= av_gen_search(s, -2, dummy.pos, next_node[0]->pos , next_node[1]->pos, next_node[1]->pos,
- next_node[0]->back_ptr, next_node[1]->back_ptr, flags, &ts, nut_read_timestamp);
+ pos2 = ff_gen_search(s, -2, dummy.pos, next_node[0]->pos , next_node[1]->pos, next_node[1]->pos,
+ next_node[0]->back_ptr, next_node[1]->back_ptr, flags, &ts, nut_read_timestamp);
if(pos2>=0)
pos= pos2;
//FIXME dir but I think it does not matter
@@ -923,14 +923,14 @@ static int nut_read_close(AVFormatContext *s)
#if CONFIG_NUT_DEMUXER
AVInputFormat ff_nut_demuxer = {
- "nut",
- NULL_IF_CONFIG_SMALL("NUT format"),
- sizeof(NUTContext),
- nut_probe,
- nut_read_header,
- nut_read_packet,
- nut_read_close,
- read_seek,
+ .name = "nut",
+ .long_name = NULL_IF_CONFIG_SMALL("NUT format"),
+ .priv_data_size = sizeof(NUTContext),
+ .read_probe = nut_probe,
+ .read_header = nut_read_header,
+ .read_packet = nut_read_packet,
+ .read_close = nut_read_close,
+ .read_seek = read_seek,
.extensions = "nut",
.codec_tag = (const AVCodecTag * const []) { ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0 },
};
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
index 260a760..ae1c2f1 100644
--- a/libavformat/nutenc.c
+++ b/libavformat/nutenc.c
@@ -20,6 +20,7 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
#include "libavutil/tree.h"
#include "libavutil/dict.h"
#include "libavcodec/mpegaudiodata.h"
@@ -58,10 +59,10 @@ static int find_expected_header(AVCodecContext *c, int size, int key_frame, uint
else if(sample_rate < (44100 + 48000)/2) sample_rate_index=0;
else sample_rate_index=1;
- sample_rate= ff_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25);
+ sample_rate= avpriv_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25);
for(bitrate_index=2; bitrate_index<30; bitrate_index++){
- frame_size = ff_mpa_bitrate_tab[lsf][layer-1][bitrate_index>>1];
+ frame_size = avpriv_mpa_bitrate_tab[lsf][layer-1][bitrate_index>>1];
frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1);
if(frame_size == size)
@@ -577,7 +578,7 @@ static int write_headers(AVFormatContext *avctx, AVIOContext *bc){
return 0;
}
-static int write_header(AVFormatContext *s){
+static int nut_write_header(AVFormatContext *s){
NUTContext *nut = s->priv_data;
AVIOContext *bc = s->pb;
int i, j, ret;
@@ -602,7 +603,7 @@ static int write_header(AVFormatContext *s){
AVRational time_base;
ff_parse_specific_params(st->codec, &time_base.den, &ssize, &time_base.num);
- av_set_pts_info(st, 64, time_base.num, time_base.den);
+ avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
for(j=0; j<nut->time_base_count; j++){
if(!memcmp(&time_base, &nut->time_base[j], sizeof(AVRational))){
@@ -690,7 +691,7 @@ static int find_best_header_idx(NUTContext *nut, AVPacket *pkt){
return best_i;
}
-static int write_packet(AVFormatContext *s, AVPacket *pkt){
+static int nut_write_packet(AVFormatContext *s, AVPacket *pkt){
NUTContext *nut = s->priv_data;
StreamContext *nus= &nut->stream[pkt->stream_index];
AVIOContext *bc = s->pb, *dyn_bc;
@@ -844,7 +845,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt){
return 0;
}
-static int write_trailer(AVFormatContext *s){
+static int nut_write_trailer(AVFormatContext *s){
NUTContext *nut= s->priv_data;
AVIOContext *bc= s->pb;
@@ -860,22 +861,22 @@ static int write_trailer(AVFormatContext *s){
}
AVOutputFormat ff_nut_muxer = {
- "nut",
- NULL_IF_CONFIG_SMALL("NUT format"),
- "video/x-nut",
- "nut",
- sizeof(NUTContext),
+ .name = "nut",
+ .long_name = NULL_IF_CONFIG_SMALL("NUT format"),
+ .mime_type = "video/x-nut",
+ .extensions = "nut",
+ .priv_data_size = sizeof(NUTContext),
#if CONFIG_LIBVORBIS
- CODEC_ID_VORBIS,
+ .audio_codec = CODEC_ID_VORBIS,
#elif CONFIG_LIBMP3LAME
- CODEC_ID_MP3,
+ .audio_codec = CODEC_ID_MP3,
#else
- CODEC_ID_MP2,
+ .audio_codec = CODEC_ID_MP2,
#endif
- CODEC_ID_MPEG4,
- write_header,
- write_packet,
- write_trailer,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = nut_write_header,
+ .write_packet = nut_write_packet,
+ .write_trailer = nut_write_trailer,
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
.codec_tag = (const AVCodecTag * const []){ ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0 },
};
diff --git a/libavformat/nuv.c b/libavformat/nuv.c
index bf59610..262c4c5 100644
--- a/libavformat/nuv.c
+++ b/libavformat/nuv.c
@@ -20,7 +20,9 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
typedef struct {
@@ -45,15 +47,15 @@ static int nuv_probe(AVProbeData *p) {
return 0;
}
-//! little macro to sanitize packet size
+/// little macro to sanitize packet size
#define PKTSIZE(s) (s & 0xffffff)
/**
- * \brief read until we found all data needed for decoding
- * \param vst video stream of which to change parameters
- * \param ast video stream of which to change parameters
- * \param myth set if this is a MythTVVideo format file
- * \return 1 if all required codec data was found
+ * @brief read until we found all data needed for decoding
+ * @param vst video stream of which to change parameters
+ * @param ast video stream of which to change parameters
+ * @param myth set if this is a MythTVVideo format file
+ * @return 1 if all required codec data was found
*/
static int get_codec_data(AVIOContext *pb, AVStream *vst,
AVStream *ast, int myth) {
@@ -138,10 +140,10 @@ static int nuv_header(AVFormatContext *s, AVFormatParameters *ap) {
avio_rl32(pb); // unused, "desiredheight"
avio_r8(pb); // 'P' == progressive, 'I' == interlaced
avio_skip(pb, 3); // padding
- aspect = av_int2dbl(avio_rl64(pb));
+ aspect = av_int2double(avio_rl64(pb));
if (aspect > 0.9999 && aspect < 1.0001)
aspect = 4.0 / 3.0;
- fps = av_int2dbl(avio_rl64(pb));
+ fps = av_int2double(avio_rl64(pb));
// number of packets per stream type, -1 means unknown, e.g. streaming
v_packs = avio_rl32(pb);
@@ -152,7 +154,7 @@ static int nuv_header(AVFormatContext *s, AVFormatParameters *ap) {
if (v_packs) {
ctx->v_id = stream_nr++;
- vst = av_new_stream(s, ctx->v_id);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -162,13 +164,13 @@ static int nuv_header(AVFormatContext *s, AVFormatParameters *ap) {
vst->codec->bits_per_coded_sample = 10;
vst->sample_aspect_ratio = av_d2q(aspect * height / width, 10000);
vst->r_frame_rate = av_d2q(fps, 60000);
- av_set_pts_info(vst, 32, 1, 1000);
+ avpriv_set_pts_info(vst, 32, 1, 1000);
} else
ctx->v_id = -1;
if (a_packs) {
ctx->a_id = stream_nr++;
- ast = av_new_stream(s, ctx->a_id);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -178,7 +180,7 @@ static int nuv_header(AVFormatContext *s, AVFormatParameters *ap) {
ast->codec->bit_rate = 2 * 2 * 44100 * 8;
ast->codec->block_align = 2 * 2;
ast->codec->bits_per_coded_sample = 16;
- av_set_pts_info(ast, 32, 1, 1000);
+ avpriv_set_pts_info(ast, 32, 1, 1000);
} else
ctx->a_id = -1;
@@ -258,13 +260,11 @@ static int nuv_packet(AVFormatContext *s, AVPacket *pkt) {
}
AVInputFormat ff_nuv_demuxer = {
- "nuv",
- NULL_IF_CONFIG_SMALL("NuppelVideo format"),
- sizeof(NUVContext),
- nuv_probe,
- nuv_header,
- nuv_packet,
- NULL,
- NULL,
+ .name = "nuv",
+ .long_name = NULL_IF_CONFIG_SMALL("NuppelVideo format"),
+ .priv_data_size = sizeof(NUVContext),
+ .read_probe = nuv_probe,
+ .read_header = nuv_header,
+ .read_packet = nuv_packet,
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 1820167..36e2c45 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -2,10 +2,9 @@
* Ogg bitstream support
* Luca Barbato <lu_zero at gentoo.org>
* Based on tcvp implementation
- *
*/
-/**
+/*
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
Permission is hereby granted, free of charge, to any person
@@ -27,12 +26,13 @@
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
-**/
+ */
#include <stdio.h>
#include "oggdec.h"
#include "avformat.h"
+#include "internal.h"
#include "vorbiscomment.h"
#define MAX_PAGE_SIZE 65307
@@ -45,6 +45,7 @@ static const struct ogg_codec * const ogg_codecs[] = {
&ff_vorbis_codec,
&ff_theora_codec,
&ff_flac_codec,
+ &ff_celt_codec,
&ff_old_dirac_codec,
&ff_old_flac_codec,
&ff_ogm_video_codec,
@@ -171,11 +172,12 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
os->header = -1;
if (new_avstream) {
- st = av_new_stream(s, idx);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 64, 1, 1000000);
+ st->id = idx;
+ avpriv_set_pts_info(st, 64, 1, 1000000);
}
return idx;
@@ -202,7 +204,7 @@ static int ogg_read_page(AVFormatContext *s, int *str)
AVIOContext *bc = s->pb;
struct ogg *ogg = s->priv_data;
struct ogg_stream *os;
- int i = 0;
+ int ret, i = 0;
int flags, nsegs;
uint64_t gp;
uint32_t serial;
@@ -210,8 +212,9 @@ static int ogg_read_page(AVFormatContext *s, int *str)
uint8_t sync[4];
int sp = 0;
- if (avio_read (bc, sync, 4) < 4)
- return -1;
+ ret = avio_read(bc, sync, 4);
+ if (ret < 4)
+ return ret < 0 ? ret : AVERROR_EOF;
do{
int c;
@@ -223,17 +226,17 @@ static int ogg_read_page(AVFormatContext *s, int *str)
c = avio_r8(bc);
if (bc->eof_reached)
- return -1;
+ return AVERROR_EOF;
sync[sp++ & 3] = c;
}while (i++ < MAX_PAGE_SIZE);
if (i >= MAX_PAGE_SIZE){
av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (avio_r8(bc) != 0) /* version */
- return -1;
+ return AVERROR_INVALIDDATA;
flags = avio_r8(bc);
gp = avio_rl64 (bc);
@@ -258,7 +261,7 @@ static int ogg_read_page(AVFormatContext *s, int *str)
idx = ogg_new_stream(s, serial, 1);
}
if (idx < 0)
- return -1;
+ return idx;
}
os = ogg->streams + idx;
@@ -267,8 +270,9 @@ static int ogg_read_page(AVFormatContext *s, int *str)
if(os->psize > 0)
ogg_new_buf(ogg, idx);
- if (avio_read (bc, os->segments, nsegs) < nsegs)
- return -1;
+ ret = avio_read(bc, os->segments, nsegs);
+ if (ret < nsegs)
+ return ret < 0 ? ret : AVERROR_EOF;
os->nsegs = nsegs;
os->segp = 0;
@@ -299,8 +303,9 @@ static int ogg_read_page(AVFormatContext *s, int *str)
os->buf = nb;
}
- if (avio_read (bc, os->buf + os->bufpos, size) < size)
- return -1;
+ ret = avio_read(bc, os->buf + os->bufpos, size);
+ if (ret < size)
+ return ret < 0 ? ret : AVERROR_EOF;
os->bufpos += size;
os->granule = gp;
@@ -316,7 +321,7 @@ static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
int64_t *fpos)
{
struct ogg *ogg = s->priv_data;
- int idx, i;
+ int idx, i, ret;
struct ogg_stream *os;
int complete = 0;
int segp = 0, psize = 0;
@@ -327,8 +332,9 @@ static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
idx = ogg->curidx;
while (idx < 0){
- if (ogg_read_page (s, &idx) < 0)
- return -1;
+ ret = ogg_read_page(s, &idx);
+ if (ret < 0)
+ return ret;
}
os = ogg->streams + idx;
@@ -340,6 +346,7 @@ static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
if (os->header < 0){
os->codec = ogg_find_codec (os->buf, os->bufpos);
if (!os->codec){
+ av_log(s, AV_LOG_WARNING, "Codec not found\n");
os->header = 0;
return 0;
}
@@ -438,10 +445,12 @@ static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
static int ogg_get_headers(AVFormatContext *s)
{
struct ogg *ogg = s->priv_data;
+ int ret;
do{
- if (ogg_packet (s, NULL, NULL, NULL, NULL) < 0)
- return -1;
+ ret = ogg_packet(s, NULL, NULL, NULL, NULL);
+ if (ret < 0)
+ return ret;
}while (!ogg->headers);
av_dlog(s, "found headers\n");
@@ -488,12 +497,12 @@ static int ogg_get_length(AVFormatContext *s)
static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
struct ogg *ogg = s->priv_data;
- int i;
+ int ret, i;
ogg->curidx = -1;
//linear headers seek from start
- if (ogg_get_headers (s) < 0){
- return -1;
- }
+ ret = ogg_get_headers(s);
+ if (ret < 0)
+ return ret;
for (i = 0; i < ogg->nstreams; i++)
if (ogg->streams[i].header < 0)
@@ -540,15 +549,16 @@ static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
{
struct ogg *ogg;
struct ogg_stream *os;
- int idx = -1;
+ int idx = -1, ret;
int pstart, psize;
int64_t fpos, pts, dts;
//Get an ogg packet
retry:
do{
- if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0)
- return AVERROR(EIO);
+ ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
+ if (ret < 0)
+ return ret;
}while (idx < 0 || !s->streams[idx]);
ogg = s->priv_data;
@@ -562,8 +572,9 @@ retry:
os->keyframe_seek = 0;
//Alloc a pkt
- if (av_new_packet (pkt, psize) < 0)
- return AVERROR(EIO);
+ ret = av_new_packet(pkt, psize);
+ if (ret < 0)
+ return ret;
pkt->stream_index = idx;
memcpy (pkt->data, os->buf + pstart, psize);
@@ -626,7 +637,7 @@ static int ogg_read_seek(AVFormatContext *s, int stream_index,
&& !(flags & AVSEEK_FLAG_ANY))
os->keyframe_seek = 1;
- ret = av_seek_frame_binary(s, stream_index, timestamp, flags);
+ ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
os = ogg->streams + stream_index;
if (ret < 0)
os->keyframe_seek = 0;
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index e7d1022..184a628 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -98,6 +98,7 @@ struct ogg {
#define OGG_FLAG_BOS 2
#define OGG_FLAG_EOS 4
+extern const struct ogg_codec ff_celt_codec;
extern const struct ogg_codec ff_dirac_codec;
extern const struct ogg_codec ff_flac_codec;
extern const struct ogg_codec ff_ogm_audio_codec;
diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index bc4b3c1..33aba87 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -20,6 +20,7 @@
*/
#include "libavutil/crc.h"
+#include "libavutil/mathematics.h"
#include "libavutil/random_seed.h"
#include "libavcodec/xiph.h"
#include "libavcodec/bytestream.h"
@@ -223,7 +224,7 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact,
int *header_len, AVDictionary **m, int framing_bit)
{
- const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
+ const char *vendor = bitexact ? "Libav" : LIBAVFORMAT_IDENT;
int size;
uint8_t *p, *p0;
unsigned int count;
@@ -253,7 +254,7 @@ static int ogg_build_flac_headers(AVCodecContext *avctx,
uint8_t *streaminfo;
uint8_t *p;
- if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
+ if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo))
return -1;
// first packet: STREAMINFO
@@ -322,9 +323,9 @@ static int ogg_write_header(AVFormatContext *s)
unsigned serial_num = i;
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
- av_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
+ avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
if (st->codec->codec_id != CODEC_ID_VORBIS &&
st->codec->codec_id != CODEC_ID_THEORA &&
st->codec->codec_id != CODEC_ID_SPEEX &&
@@ -376,7 +377,7 @@ static int ogg_write_header(AVFormatContext *s)
int header_type = st->codec->codec_id == CODEC_ID_VORBIS ? 3 : 0x81;
int framing_bit = st->codec->codec_id == CODEC_ID_VORBIS ? 1 : 0;
- if (ff_split_xiph_headers(st->codec->extradata, st->codec->extradata_size,
+ if (avpriv_split_xiph_headers(st->codec->extradata, st->codec->extradata_size,
st->codec->codec_id == CODEC_ID_VORBIS ? 30 : 42,
oggstream->header, oggstream->header_len) < 0) {
av_log(s, AV_LOG_ERROR, "Extradata corrupted\n");
@@ -504,14 +505,14 @@ static int ogg_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_ogg_muxer = {
- "ogg",
- NULL_IF_CONFIG_SMALL("Ogg"),
- "application/ogg",
- "ogg,ogv,spx",
- sizeof(OGGContext),
- CODEC_ID_FLAC,
- CODEC_ID_THEORA,
- ogg_write_header,
- ogg_write_packet,
- ogg_write_trailer,
+ .name = "ogg",
+ .long_name = NULL_IF_CONFIG_SMALL("Ogg"),
+ .mime_type = "application/ogg",
+ .extensions = "ogg,ogv,spx",
+ .priv_data_size = sizeof(OGGContext),
+ .audio_codec = CODEC_ID_FLAC,
+ .video_codec = CODEC_ID_THEORA,
+ .write_header = ogg_write_header,
+ .write_packet = ogg_write_packet,
+ .write_trailer = ogg_write_trailer,
};
diff --git a/libavformat/oggparsecelt.c b/libavformat/oggparsecelt.c
new file mode 100644
index 0000000..5f07de4
--- /dev/null
+++ b/libavformat/oggparsecelt.c
@@ -0,0 +1,96 @@
+/*
+ * Xiph CELT / Opus parser for Ogg
+ * Copyright (c) 2011 Nicolas George
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+#include "oggdec.h"
+
+struct oggcelt_private {
+ int extra_headers_left;
+};
+
+static int celt_header(AVFormatContext *s, int idx)
+{
+ struct ogg *ogg = s->priv_data;
+ struct ogg_stream *os = ogg->streams + idx;
+ AVStream *st = s->streams[idx];
+ struct oggcelt_private *priv = os->private;
+ uint8_t *p = os->buf + os->pstart;
+
+ if (os->psize == 60 &&
+ !memcmp(p, ff_celt_codec.magic, ff_celt_codec.magicsize)) {
+ /* Main header */
+
+ uint32_t version, sample_rate, nb_channels, frame_size;
+ uint32_t overlap, extra_headers;
+ uint8_t *extradata;
+
+ extradata = av_malloc(2 * sizeof(uint32_t) +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ priv = av_malloc(sizeof(struct oggcelt_private));
+ if (!extradata || !priv) {
+ av_free(extradata);
+ av_free(priv);
+ return AVERROR(ENOMEM);
+ }
+ version = AV_RL32(p + 28);
+ /* unused header size field skipped */
+ sample_rate = AV_RL32(p + 36);
+ nb_channels = AV_RL32(p + 40);
+ frame_size = AV_RL32(p + 44);
+ overlap = AV_RL32(p + 48);
+ /* unused bytes per packet field skipped */
+ extra_headers = AV_RL32(p + 56);
+ av_free(os->private);
+ av_free(st->codec->extradata);
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = CODEC_ID_CELT;
+ st->codec->sample_rate = sample_rate;
+ st->codec->channels = nb_channels;
+ st->codec->frame_size = frame_size;
+ st->codec->extradata = extradata;
+ st->codec->extradata_size = 2 * sizeof(uint32_t);
+ if (sample_rate)
+ avpriv_set_pts_info(st, 64, 1, sample_rate);
+ priv->extra_headers_left = 1 + extra_headers;
+ os->private = priv;
+ AV_WL32(extradata + 0, overlap);
+ AV_WL32(extradata + 4, version);
+ return 1;
+ } else if (priv && priv->extra_headers_left) {
+ /* Extra headers (vorbiscomment) */
+
+ ff_vorbis_comment(s, &st->metadata, p, os->psize);
+ priv->extra_headers_left--;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+const struct ogg_codec ff_celt_codec = {
+ .magic = "CELT ",
+ .magicsize = 8,
+ .header = celt_header,
+};
diff --git a/libavformat/oggparsedirac.c b/libavformat/oggparsedirac.c
index f6afafd..8d3a802 100644
--- a/libavformat/oggparsedirac.c
+++ b/libavformat/oggparsedirac.c
@@ -21,6 +21,7 @@
#include "libavcodec/get_bits.h"
#include "libavcodec/dirac.h"
#include "avformat.h"
+#include "internal.h"
#include "oggdec.h"
static int dirac_header(AVFormatContext *s, int idx)
@@ -36,13 +37,13 @@ static int dirac_header(AVFormatContext *s, int idx)
return 0;
init_get_bits(&gb, os->buf + os->pstart + 13, (os->psize - 13) * 8);
- if (ff_dirac_parse_sequence_header(st->codec, &gb, &source) < 0)
+ if (avpriv_dirac_parse_sequence_header(st->codec, &gb, &source) < 0)
return -1;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_DIRAC;
// dirac in ogg always stores timestamps as though the video were interlaced
- av_set_pts_info(st, 64, st->codec->time_base.num, 2*st->codec->time_base.den);
+ avpriv_set_pts_info(st, 64, st->codec->time_base.num, 2*st->codec->time_base.den);
return 1;
}
@@ -79,7 +80,7 @@ static int old_dirac_header(AVFormatContext *s, int idx)
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_DIRAC;
- av_set_pts_info(st, 64, AV_RB32(buf+12), AV_RB32(buf+8));
+ avpriv_set_pts_info(st, 64, AV_RB32(buf+12), AV_RB32(buf+8));
return 1;
}
diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c
index 53cd0fa..b1d18ed 100644
--- a/libavformat/oggparseflac.c
+++ b/libavformat/oggparseflac.c
@@ -22,6 +22,7 @@
#include "libavcodec/get_bits.h"
#include "libavcodec/flac.h"
#include "avformat.h"
+#include "internal.h"
#include "oggdec.h"
#define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F
@@ -55,7 +56,7 @@ flac_header (AVFormatContext * s, int idx)
if (get_bits_long(&gb, 32) != FLAC_STREAMINFO_SIZE)
return -1;
- ff_flac_parse_streaminfo(st->codec, &si, streaminfo_start);
+ avpriv_flac_parse_streaminfo(st->codec, &si, streaminfo_start);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_FLAC;
@@ -65,7 +66,7 @@ flac_header (AVFormatContext * s, int idx)
memcpy(st->codec->extradata, streaminfo_start, FLAC_STREAMINFO_SIZE);
st->codec->extradata_size = FLAC_STREAMINFO_SIZE;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
} else if (mdt == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
ff_vorbis_comment (s, &st->metadata, os->buf + os->pstart + 4, os->psize - 4);
}
diff --git a/libavformat/oggparseogm.c b/libavformat/oggparseogm.c
index 9526c3a..0a8a7c6 100644
--- a/libavformat/oggparseogm.c
+++ b/libavformat/oggparseogm.c
@@ -27,6 +27,7 @@
#include "libavcodec/get_bits.h"
#include "libavcodec/bytestream.h"
#include "avformat.h"
+#include "internal.h"
#include "oggdec.h"
#include "riff.h"
@@ -81,13 +82,13 @@ ogm_header(AVFormatContext *s, int idx)
st->codec->height = bytestream_get_le32(&p);
st->codec->time_base.den = spu * 10000000;
st->codec->time_base.num = time_unit;
- av_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
+ avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
} else {
st->codec->channels = bytestream_get_le16(&p);
p += 2; /* block_align */
st->codec->bit_rate = bytestream_get_le32(&p) * 8;
st->codec->sample_rate = spu * 10000000 / time_unit;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
}
} else if (*p == 3) {
if (os->psize > 8)
diff --git a/libavformat/oggparseskeleton.c b/libavformat/oggparseskeleton.c
index ceb7c69..62dd14d 100644
--- a/libavformat/oggparseskeleton.c
+++ b/libavformat/oggparseskeleton.c
@@ -20,6 +20,7 @@
#include "libavcodec/bytestream.h"
#include "avformat.h"
+#include "internal.h"
#include "oggdec.h"
static int skeleton_header(AVFormatContext *s, int idx)
@@ -62,7 +63,7 @@ static int skeleton_header(AVFormatContext *s, int idx)
if (start_den) {
int base_den;
av_reduce(&start_time, &base_den, start_num, start_den, INT_MAX);
- av_set_pts_info(st, 64, 1, base_den);
+ avpriv_set_pts_info(st, 64, 1, base_den);
os->lastpts =
st->start_time = start_time;
}
diff --git a/libavformat/oggparsespeex.c b/libavformat/oggparsespeex.c
index 2f4aec7..435ed0c 100644
--- a/libavformat/oggparsespeex.c
+++ b/libavformat/oggparsespeex.c
@@ -28,9 +28,11 @@
#include "libavcodec/get_bits.h"
#include "libavcodec/bytestream.h"
#include "avformat.h"
+#include "internal.h"
#include "oggdec.h"
struct speex_params {
+ int packet_size;
int final_packet_duration;
int seq;
};
@@ -58,21 +60,17 @@ static int speex_header(AVFormatContext *s, int idx) {
st->codec->sample_rate = AV_RL32(p + 36);
st->codec->channels = AV_RL32(p + 48);
- /* We treat the whole Speex packet as a single frame everywhere Speex
- is handled in Libav. This avoids the complexities of splitting
- and joining individual Speex frames, which are not always
- byte-aligned. */
- st->codec->frame_size = AV_RL32(p + 56);
- frames_per_packet = AV_RL32(p + 64);
+ spxp->packet_size = AV_RL32(p + 56);
+ frames_per_packet = AV_RL32(p + 64);
if (frames_per_packet)
- st->codec->frame_size *= frames_per_packet;
+ spxp->packet_size *= frames_per_packet;
st->codec->extradata_size = os->psize;
st->codec->extradata = av_malloc(st->codec->extradata_size
+ FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(st->codec->extradata, p, st->codec->extradata_size);
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
} else
ff_vorbis_comment(s, &st->metadata, p, os->psize);
@@ -95,7 +93,7 @@ static int speex_packet(AVFormatContext *s, int idx)
struct ogg *ogg = s->priv_data;
struct ogg_stream *os = ogg->streams + idx;
struct speex_params *spxp = os->private;
- int packet_size = s->streams[idx]->codec->frame_size;
+ int packet_size = spxp->packet_size;
if (os->flags & OGG_FLAG_EOS && os->lastpts != AV_NOPTS_VALUE &&
os->granule > 0) {
@@ -108,9 +106,10 @@ static int speex_packet(AVFormatContext *s, int idx)
if (!os->lastpts && os->granule > 0)
/* first packet */
- os->pduration = os->granule - packet_size * (ogg_page_packets(os) - 1);
- else if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs &&
- spxp->final_packet_duration)
+ os->lastpts = os->lastdts = os->granule - packet_size *
+ ogg_page_packets(os);
+ if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs &&
+ spxp->final_packet_duration)
/* final packet */
os->pduration = spxp->final_packet_duration;
else
diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c
index d02781f..993db3e 100644
--- a/libavformat/oggparsetheora.c
+++ b/libavformat/oggparsetheora.c
@@ -26,6 +26,7 @@
#include "libavutil/bswap.h"
#include "libavcodec/get_bits.h"
#include "avformat.h"
+#include "internal.h"
#include "oggdec.h"
struct theora_params {
@@ -91,7 +92,7 @@ theora_header (AVFormatContext * s, int idx)
st->codec->time_base.num = 1;
st->codec->time_base.den = 25;
}
- av_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
+ avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
st->sample_aspect_ratio.num = get_bits_long(&gb, 24);
st->sample_aspect_ratio.den = get_bits_long(&gb, 24);
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index 86951f3..ba9b348 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -45,7 +45,7 @@ static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
return 0;
- ff_new_chapter(as, cnum, (AVRational){1,1000},
+ avpriv_new_chapter(as, cnum, (AVRational){1,1000},
ms + 1000*(s + 60*(m + 60*h)),
AV_NOPTS_VALUE, NULL);
av_free(val);
@@ -254,7 +254,7 @@ vorbis_header (AVFormatContext * s, int idx)
if (srate > 0) {
st->codec->sample_rate = srate;
- av_set_pts_info(st, 64, 1, srate);
+ avpriv_set_pts_info(st, 64, 1, srate);
}
} else if (os->buf[os->pstart] == 3) {
if (os->psize > 8 &&
diff --git a/libavformat/oma.c b/libavformat/oma.c
index 6fdf75f..930991c 100644
--- a/libavformat/oma.c
+++ b/libavformat/oma.c
@@ -1,8 +1,5 @@
/*
- * Sony OpenMG (OMA) demuxer
- *
- * Copyright (c) 2008 Maxim Poliakovski
- * 2008 Benjamin Larsson
+ * Sony OpenMG (OMA) common data
*
* This file is part of Libav.
*
@@ -21,188 +18,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/**
- * @file
- * This is a demuxer for Sony OpenMG Music files
- *
- * Known file extensions: ".oma", "aa3"
- * The format of such files consists of three parts:
- * - "ea3" header carrying overall info and metadata. Except for starting with
- * "ea" instead of "ID", it's an ID3v2 header.
- * - "EA3" header is a Sony-specific header containing information about
- * the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA),
- * codec specific info (packet size, sample rate, channels and so on)
- * and DRM related info (file encryption, content id).
- * - Sound data organized in packets follow the EA3 header
- * (can be encrypted using the Sony DRM!).
- *
- * LIMITATIONS: This version supports only plain (unencrypted) OMA files.
- * If any DRM-protected (encrypted) file is encountered you will get the
- * corresponding error message. Try to remove the encryption using any
- * Sony software (for example SonicStage).
- * CODEC SUPPORT: Only ATRAC3 codec is currently supported!
- */
-
-#include "avformat.h"
-#include "libavutil/intreadwrite.h"
-#include "pcm.h"
-#include "riff.h"
-#include "id3v2.h"
+#include "internal.h"
+#include "oma.h"
+#include "libavcodec/avcodec.h"
-#define EA3_HEADER_SIZE 96
+const uint16_t ff_oma_srate_tab[6] = { 320, 441, 480, 882, 960, 0 };
-enum {
- OMA_CODECID_ATRAC3 = 0,
- OMA_CODECID_ATRAC3P = 1,
- OMA_CODECID_MP3 = 3,
- OMA_CODECID_LPCM = 4,
- OMA_CODECID_WMA = 5,
+const AVCodecTag ff_oma_codec_tags[] = {
+ { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 },
+ { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P },
+ { CODEC_ID_MP3, OMA_CODECID_MP3 },
+ { CODEC_ID_PCM_S16BE, OMA_CODECID_LPCM },
+ { 0 },
};
-
-static const AVCodecTag codec_oma_tags[] = {
- { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 },
- { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P },
- { CODEC_ID_MP3, OMA_CODECID_MP3 },
-};
-
-#define ID3v2_EA3_MAGIC "ea3"
-
-static int oma_read_header(AVFormatContext *s,
- AVFormatParameters *ap)
-{
- static const uint16_t srate_tab[6] = {320,441,480,882,960,0};
- int ret, framesize, jsflag, samplerate;
- uint32_t codec_params;
- int16_t eid;
- uint8_t buf[EA3_HEADER_SIZE];
- uint8_t *edata;
- AVStream *st;
-
- ff_id3v2_read(s, ID3v2_EA3_MAGIC);
- ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
- if (ret < EA3_HEADER_SIZE)
- return -1;
-
- if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
- av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
- return -1;
- }
-
- eid = AV_RB16(&buf[6]);
- if (eid != -1 && eid != -128) {
- av_log(s, AV_LOG_ERROR, "Encrypted file! Eid: %d\n", eid);
- return -1;
- }
-
- codec_params = AV_RB24(&buf[33]);
-
- st = av_new_stream(s, 0);
- if (!st)
- return AVERROR(ENOMEM);
-
- st->start_time = 0;
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_tag = buf[32];
- st->codec->codec_id = ff_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_ask_for_sample(s, "Unsupported sample rate: %d\n",
- samplerate);
-
- framesize = (codec_params & 0x3FF) * 8;
- jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */
- 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;
- edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!edata)
- return AVERROR(ENOMEM);
-
- st->codec->extradata = edata;
- AV_WL16(&edata[0], 1); // always 1
- AV_WL32(&edata[2], samplerate); // samples rate
- AV_WL16(&edata[6], jsflag); // coding mode
- 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->block_align = framesize;
-
- return 0;
-}
-
-
-static int oma_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
- int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align);
-
- pkt->stream_index = 0;
- if (ret <= 0)
- return AVERROR(EIO);
-
- return ret;
-}
-
-static int oma_read_probe(AVProbeData *p)
-{
- const uint8_t *buf;
- unsigned tag_len = 0;
-
- buf = p->buf;
- /* version must be 3 and flags byte zero */
- if (ff_id3v2_match(buf, ID3v2_EA3_MAGIC) && buf[3] == 3 && !buf[4])
- tag_len = ff_id3v2_tag_len(buf);
-
- // This check cannot overflow as tag_len has at most 28 bits
- if (p->buf_size < tag_len + 5)
- return 0;
-
- buf += tag_len;
-
- if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE)
- return AVPROBE_SCORE_MAX;
- else
- return 0;
-}
-
-
-AVInputFormat ff_oma_demuxer = {
- "oma",
- NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
- 0,
- oma_read_probe,
- oma_read_header,
- oma_read_packet,
- 0,
- pcm_read_seek,
- .flags= AVFMT_GENERIC_INDEX,
- .extensions = "oma,aa3",
- .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0},
-};
-
diff --git a/libavformat/oma.h b/libavformat/oma.h
new file mode 100644
index 0000000..bac8bcb
--- /dev/null
+++ b/libavformat/oma.h
@@ -0,0 +1,44 @@
+/*
+ * Sony OpenMG (OMA) common data
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFORMAT_OMA_H
+#define AVFORMAT_OMA_H
+
+#include <stdint.h>
+
+#include "internal.h"
+
+#define EA3_HEADER_SIZE 96
+#define ID3v2_EA3_MAGIC "ea3"
+#define OMA_ENC_HEADER_SIZE 16
+
+enum {
+ OMA_CODECID_ATRAC3 = 0,
+ OMA_CODECID_ATRAC3P = 1,
+ OMA_CODECID_MP3 = 3,
+ OMA_CODECID_LPCM = 4,
+ OMA_CODECID_WMA = 5,
+};
+
+extern const uint16_t ff_oma_srate_tab[6];
+
+extern const AVCodecTag ff_oma_codec_tags[];
+
+#endif /* AVFORMAT_OMA_H */
diff --git a/libavformat/omadec.c b/libavformat/omadec.c
new file mode 100644
index 0000000..0beed71
--- /dev/null
+++ b/libavformat/omadec.c
@@ -0,0 +1,446 @@
+/*
+ * Sony OpenMG (OMA) demuxer
+ *
+ * Copyright (c) 2008 Maxim Poliakovski
+ * 2008 Benjamin Larsson
+ * 2011 David Goldwich
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * This is a demuxer for Sony OpenMG Music files
+ *
+ * Known file extensions: ".oma", "aa3"
+ * The format of such files consists of three parts:
+ * - "ea3" header carrying overall info and metadata. Except for starting with
+ * "ea" instead of "ID", it's an ID3v2 header.
+ * - "EA3" header is a Sony-specific header containing information about
+ * the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA),
+ * codec specific info (packet size, sample rate, channels and so on)
+ * and DRM related info (file encryption, content id).
+ * - Sound data organized in packets follow the EA3 header
+ * (can be encrypted using the Sony DRM!).
+ *
+ * CODEC SUPPORT: Only ATRAC3 codec is currently supported!
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/des.h"
+#include "oma.h"
+#include "pcm.h"
+#include "riff.h"
+#include "id3v2.h"
+
+
+static const uint64_t leaf_table[] = {
+ 0xd79e8283acea4620, 0x7a9762f445afd0d8,
+ 0x354d60a60b8c79f1, 0x584e1cde00b07aee,
+ 0x1573cd93da7df623, 0x47f98d79620dd535
+};
+
+typedef struct OMAContext {
+ uint64_t content_start;
+ int encrypted;
+ uint16_t k_size;
+ uint16_t e_size;
+ uint16_t i_size;
+ uint16_t s_size;
+ uint32_t rid;
+ uint8_t r_val[24];
+ uint8_t n_val[24];
+ uint8_t m_val[8];
+ uint8_t s_val[8];
+ uint8_t sm_val[8];
+ uint8_t e_val[8];
+ uint8_t iv[8];
+ struct AVDES av_des;
+} OMAContext;
+
+static void hex_log(AVFormatContext *s, int level, const char *name, const uint8_t *value, int len)
+{
+ char buf[33];
+ len = FFMIN(len, 16);
+ if (av_log_get_level() < level)
+ return;
+ ff_data_to_hex(buf, value, len, 1);
+ buf[len<<1] = '\0';
+ av_log(s, level, "%s: %s\n", name, buf);
+}
+
+static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val, int len)
+{
+ OMAContext *oc = s->priv_data;
+
+ if (!r_val && !n_val)
+ return -1;
+
+ len = FFMIN(len, 16);
+
+ /* use first 64 bits in the third round again */
+ if (r_val) {
+ if (r_val != oc->r_val) {
+ memset(oc->r_val, 0, 24);
+ memcpy(oc->r_val, r_val, len);
+ }
+ memcpy(&oc->r_val[16], r_val, 8);
+ }
+ if (n_val) {
+ if (n_val != oc->n_val) {
+ memset(oc->n_val, 0, 24);
+ memcpy(oc->n_val, n_val, len);
+ }
+ memcpy(&oc->n_val[16], n_val, 8);
+ }
+
+ return 0;
+}
+
+static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val)
+{
+ OMAContext *oc = s->priv_data;
+ unsigned int pos;
+ struct AVDES av_des;
+
+ if (!enc_header || !r_val)
+ return -1;
+
+ /* m_val */
+ av_des_init(&av_des, r_val, 192, 1);
+ av_des_crypt(&av_des, oc->m_val, &enc_header[48], 1, NULL, 1);
+
+ /* s_val */
+ av_des_init(&av_des, oc->m_val, 64, 0);
+ av_des_crypt(&av_des, oc->s_val, NULL, 1, NULL, 0);
+
+ /* sm_val */
+ pos = OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size;
+ av_des_init(&av_des, oc->s_val, 64, 0);
+ av_des_mac(&av_des, oc->sm_val, &enc_header[pos], (oc->i_size >> 3));
+
+ pos += oc->i_size;
+
+ return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0;
+}
+
+static int nprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *n_val)
+{
+ OMAContext *oc = s->priv_data;
+ uint32_t pos, taglen, datalen;
+ struct AVDES av_des;
+
+ if (!enc_header || !n_val)
+ return -1;
+
+ pos = OMA_ENC_HEADER_SIZE + oc->k_size;
+ if (!memcmp(&enc_header[pos], "EKB ", 4))
+ pos += 32;
+
+ if (AV_RB32(&enc_header[pos]) != oc->rid)
+ av_log(s, AV_LOG_DEBUG, "Mismatching RID\n");
+
+ taglen = AV_RB32(&enc_header[pos+32]);
+ datalen = AV_RB32(&enc_header[pos+36]) >> 4;
+
+ pos += 44 + taglen;
+
+ av_des_init(&av_des, n_val, 192, 1);
+ while (datalen-- > 0) {
+ av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1);
+ kset(s, oc->r_val, NULL, 16);
+ if (!rprobe(s, enc_header, oc->r_val))
+ return 0;
+ pos += 16;
+ }
+
+ return -1;
+}
+
+static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
+{
+ OMAContext *oc = s->priv_data;
+ ID3v2ExtraMetaGEOB *geob = NULL;
+ uint8_t *gdata;
+
+ oc->encrypted = 1;
+ av_log(s, AV_LOG_INFO, "File is encrypted\n");
+
+ /* find GEOB metadata */
+ while (em) {
+ if (!strcmp(em->tag, "GEOB") &&
+ (geob = em->data) &&
+ (!strcmp(geob->description, "OMG_LSI") ||
+ !strcmp(geob->description, "OMG_BKLSI"))) {
+ break;
+ }
+ em = em->next;
+ }
+ if (!em) {
+ av_log(s, AV_LOG_ERROR, "No encryption header found\n");
+ return -1;
+ }
+
+ if (geob->datasize < 64) {
+ av_log(s, AV_LOG_ERROR, "Invalid GEOB data size: %u\n", geob->datasize);
+ return -1;
+ }
+
+ gdata = geob->data;
+
+ if (AV_RB16(gdata) != 1)
+ av_log(s, AV_LOG_WARNING, "Unknown version in encryption header\n");
+
+ oc->k_size = AV_RB16(&gdata[2]);
+ oc->e_size = AV_RB16(&gdata[4]);
+ oc->i_size = AV_RB16(&gdata[6]);
+ oc->s_size = AV_RB16(&gdata[8]);
+
+ if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING ", 12)) {
+ av_log(s, AV_LOG_ERROR, "Invalid encryption header\n");
+ return -1;
+ }
+ oc->rid = AV_RB32(&gdata[OMA_ENC_HEADER_SIZE + 28]);
+ av_log(s, AV_LOG_DEBUG, "RID: %.8x\n", oc->rid);
+
+ memcpy(oc->iv, &header[0x58], 8);
+ hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8);
+
+ hex_log(s, AV_LOG_DEBUG, "CBC-MAC", &gdata[OMA_ENC_HEADER_SIZE+oc->k_size+oc->e_size+oc->i_size], 8);
+
+ if (s->keylen > 0) {
+ kset(s, s->key, s->key, s->keylen);
+ }
+ if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) ||
+ rprobe(s, gdata, oc->r_val) < 0 &&
+ nprobe(s, gdata, oc->n_val) < 0) {
+ int i;
+ for (i = 0; i < sizeof(leaf_table); i += 2) {
+ uint8_t buf[16];
+ AV_WL64(buf, leaf_table[i]);
+ AV_WL64(&buf[8], leaf_table[i+1]);
+ kset(s, buf, buf, 16);
+ if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, oc->n_val))
+ break;
+ }
+ if (i >= sizeof(leaf_table)) {
+ av_log(s, AV_LOG_ERROR, "Invalid key\n");
+ return -1;
+ }
+ }
+
+ /* e_val */
+ av_des_init(&oc->av_des, oc->m_val, 64, 0);
+ av_des_crypt(&oc->av_des, oc->e_val, &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
+ hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8);
+
+ /* init e_val */
+ av_des_init(&oc->av_des, oc->e_val, 64, 1);
+
+ return 0;
+}
+
+static int oma_read_header(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ int ret, framesize, jsflag, samplerate;
+ uint32_t codec_params;
+ int16_t eid;
+ uint8_t buf[EA3_HEADER_SIZE];
+ uint8_t *edata;
+ AVStream *st;
+ ID3v2ExtraMeta *extra_meta = NULL;
+ OMAContext *oc = s->priv_data;
+
+ ff_id3v2_read_all(s, ID3v2_EA3_MAGIC, &extra_meta);
+ ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
+ if (ret < EA3_HEADER_SIZE)
+ return -1;
+
+ if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
+ av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
+ return -1;
+ }
+
+ oc->content_start = avio_tell(s->pb);
+
+ /* encrypted file */
+ eid = AV_RB16(&buf[6]);
+ if (eid != -1 && eid != -128 && decrypt_init(s, extra_meta, buf) < 0) {
+ ff_id3v2_free_extra_meta(&extra_meta);
+ return -1;
+ }
+
+ ff_id3v2_free_extra_meta(&extra_meta);
+
+ codec_params = AV_RB24(&buf[33]);
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ st->start_time = 0;
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_tag = buf[32];
+ st->codec->codec_id = ff_codec_get_id(ff_oma_codec_tags, st->codec->codec_tag);
+
+ switch (buf[32]) {
+ case OMA_CODECID_ATRAC3:
+ samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100;
+ if (samplerate != 44100)
+ av_log_ask_for_sample(s, "Unsupported sample rate: %d\n",
+ samplerate);
+
+ framesize = (codec_params & 0x3FF) * 8;
+ jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */
+ 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;
+ edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!edata)
+ return AVERROR(ENOMEM);
+
+ st->codec->extradata = edata;
+ AV_WL16(&edata[0], 1); // always 1
+ AV_WL32(&edata[2], samplerate); // samples rate
+ AV_WL16(&edata[6], jsflag); // coding mode
+ AV_WL16(&edata[8], jsflag); // coding mode
+ AV_WL16(&edata[10], 1); // always 1
+ // AV_WL16(&edata[12], 0); // always 0
+
+ avpriv_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 = ff_oma_srate_tab[(codec_params >> 13) & 7]*100;
+ st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024;
+ avpriv_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;
+ case OMA_CODECID_LPCM:
+ /* PCM 44.1 kHz 16 bit stereo big-endian */
+ st->codec->channels = 2;
+ st->codec->sample_rate = 44100;
+ framesize = 1024;
+ /* bit rate = sample rate x PCM block align (= 4) x 8 */
+ st->codec->bit_rate = st->codec->sample_rate * 32;
+ st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]);
+ return -1;
+ }
+
+ st->codec->block_align = framesize;
+
+ return 0;
+}
+
+
+static int oma_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ OMAContext *oc = s->priv_data;
+ int packet_size = s->streams[0]->codec->block_align;
+ int ret = av_get_packet(s->pb, pkt, packet_size);
+
+ if (ret <= 0)
+ return AVERROR(EIO);
+
+ pkt->stream_index = 0;
+
+ if (oc->encrypted) {
+ /* previous unencrypted block saved in IV for the next packet (CBC mode) */
+ av_des_crypt(&oc->av_des, pkt->data, pkt->data, (packet_size >> 3), oc->iv, 1);
+ }
+
+ return ret;
+}
+
+static int oma_read_probe(AVProbeData *p)
+{
+ const uint8_t *buf;
+ unsigned tag_len = 0;
+
+ buf = p->buf;
+
+ if (p->buf_size < ID3v2_HEADER_SIZE ||
+ !ff_id3v2_match(buf, ID3v2_EA3_MAGIC) ||
+ buf[3] != 3 || // version must be 3
+ buf[4]) // flags byte zero
+ return 0;
+
+ tag_len = ff_id3v2_tag_len(buf);
+
+ /* This check cannot overflow as tag_len has at most 28 bits */
+ if (p->buf_size < tag_len + 5)
+ /* EA3 header comes late, might be outside of the probe buffer */
+ return AVPROBE_SCORE_MAX / 2;
+
+ buf += tag_len;
+
+ if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE)
+ return AVPROBE_SCORE_MAX;
+ else
+ return 0;
+}
+
+static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+{
+ OMAContext *oc = s->priv_data;
+
+ pcm_read_seek(s, stream_index, timestamp, flags);
+
+ if (oc->encrypted) {
+ /* readjust IV for CBC */
+ int64_t pos = avio_tell(s->pb);
+ if (pos < oc->content_start)
+ memset(oc->iv, 0, 8);
+ else {
+ if (avio_seek(s->pb, -8, SEEK_CUR) < 0 || avio_read(s->pb, oc->iv, 8) < 8) {
+ memset(oc->iv, 0, 8);
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+AVInputFormat ff_oma_demuxer = {
+ .name = "oma",
+ .long_name = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
+ .priv_data_size = sizeof(OMAContext),
+ .read_probe = oma_read_probe,
+ .read_header = oma_read_header,
+ .read_packet = oma_read_packet,
+ .read_seek = oma_read_seek,
+ .flags = AVFMT_GENERIC_INDEX,
+ .extensions = "oma,omg,aa3",
+ .codec_tag = (const AVCodecTag* const []){ff_oma_codec_tags, 0},
+};
+
diff --git a/libavformat/omaenc.c b/libavformat/omaenc.c
new file mode 100644
index 0000000..e932b4b
--- /dev/null
+++ b/libavformat/omaenc.c
@@ -0,0 +1,105 @@
+/*
+ * Sony OpenMG (OMA) muxer
+ *
+ * Copyright (c) 2011 Michael Karcher
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "avio_internal.h"
+#include "id3v2.h"
+#include "internal.h"
+#include "oma.h"
+#include "rawenc.h"
+
+static av_cold int oma_write_header(AVFormatContext *s)
+{
+ int i;
+ AVCodecContext *format;
+ int srate_index;
+ int isjointstereo;
+
+ format = s->streams[0]->codec;
+ /* check for support of the format first */
+
+ for (srate_index = 0; ; srate_index++) {
+ if (ff_oma_srate_tab[srate_index] == 0) {
+ av_log(s, AV_LOG_ERROR, "Sample rate %d not supported in OpenMG audio\n",
+ format->sample_rate);
+ return AVERROR(EINVAL);
+ }
+
+ if (ff_oma_srate_tab[srate_index] * 100 == format->sample_rate)
+ break;
+ }
+
+ /* Metadata; OpenMG does not support ID3v2.4 */
+ ff_id3v2_write(s, 3, ID3v2_EA3_MAGIC);
+
+ ffio_wfourcc(s->pb, "EA3\0");
+ avio_w8(s->pb, EA3_HEADER_SIZE >> 7);
+ avio_w8(s->pb, EA3_HEADER_SIZE & 0x7F);
+ avio_wl16(s->pb, 0xFFFF); /* not encrypted */
+ for (i = 0; i < 6; i++)
+ avio_wl32(s->pb, 0); /* Padding + DRM id */
+
+ switch(format->codec_tag) {
+ case OMA_CODECID_ATRAC3:
+ if (format->channels != 2) {
+ av_log(s, AV_LOG_ERROR, "ATRAC3 in OMA is only supported with 2 channels");
+ return AVERROR(EINVAL);
+ }
+ if (format->extradata_size == 14) /* WAV format extradata */
+ isjointstereo = format->extradata[6] != 0;
+ else if(format->extradata_size == 10) /* RM format extradata */
+ isjointstereo = format->extradata[8] == 0x12;
+ else {
+ av_log(s, AV_LOG_ERROR, "ATRAC3: Unsupported extradata size\n");
+ return AVERROR(EINVAL);
+ }
+ avio_wb32(s->pb, (OMA_CODECID_ATRAC3 << 24) |
+ (isjointstereo << 17) |
+ (srate_index << 13) |
+ (format->block_align/8));
+ break;
+ case OMA_CODECID_ATRAC3P:
+ avio_wb32(s->pb, (OMA_CODECID_ATRAC3P << 24) |
+ (srate_index << 13) |
+ (format->channels << 10) |
+ (format->block_align/8 - 1));
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "OMA: unsupported codec tag %d for write\n",
+ format->codec_tag);
+ }
+ for (i = 0; i < (EA3_HEADER_SIZE - 36)/4; i++)
+ avio_wl32(s->pb, 0); /* Padding */
+
+ return 0;
+}
+
+AVOutputFormat ff_oma_muxer = {
+ .name = "oma",
+ .long_name = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
+ .mime_type = "audio/x-oma",
+ .extensions = "oma",
+ .audio_codec = CODEC_ID_ATRAC3,
+ .write_header = oma_write_header,
+ .write_packet = ff_raw_write_packet,
+ .codec_tag = (const AVCodecTag* const []){ff_oma_codec_tags, 0},
+};
diff --git a/libavformat/options.c b/libavformat/options.c
index c2729b7..a9e2c1c 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
+#include "avio_internal.h"
#include "libavutil/opt.h"
/**
@@ -33,30 +34,49 @@ static const char* format_to_name(void* ptr)
else return "NULL";
}
-static const AVOption *opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
+static void *format_child_next(void *obj, void *prev)
+{
+ AVFormatContext *s = obj;
+ if (!prev && s->priv_data &&
+ ((s->iformat && s->iformat->priv_class) ||
+ s->oformat && s->oformat->priv_class))
+ return s->priv_data;
+#if !FF_API_OLD_AVIO
+ if (s->pb && s->pb->av_class && prev != s->pb)
+ return s->pb;
+#endif
+ return NULL;
+}
+
+static const AVClass *format_child_class_next(const AVClass *prev)
{
- AVFormatContext *s = obj;
AVInputFormat *ifmt = NULL;
AVOutputFormat *ofmt = NULL;
- if (s->priv_data) {
- if ((s->iformat && !s->iformat->priv_class) ||
- (s->oformat && !s->oformat->priv_class))
- return NULL;
- return av_opt_find(s->priv_data, name, unit, opt_flags, search_flags);
- }
-
- while ((ifmt = av_iformat_next(ifmt))) {
- const AVOption *o;
-
- if (ifmt->priv_class && (o = av_opt_find(&ifmt->priv_class, name, unit, opt_flags, search_flags)))
- return o;
- }
- while ((ofmt = av_oformat_next(ofmt))) {
- const AVOption *o;
-
- if (ofmt->priv_class && (o = av_opt_find(&ofmt->priv_class, name, unit, opt_flags, search_flags)))
- return o;
- }
+
+ if (!prev)
+#if !FF_API_OLD_AVIO
+ return &ffio_url_class;
+#else
+ prev = (void *)&ifmt; // Dummy pointer;
+#endif
+
+ while ((ifmt = av_iformat_next(ifmt)))
+ if (ifmt->priv_class == prev)
+ break;
+
+ if (!ifmt)
+ while ((ofmt = av_oformat_next(ofmt)))
+ if (ofmt->priv_class == prev)
+ break;
+ if (!ofmt)
+ while (ifmt = av_iformat_next(ifmt))
+ if (ifmt->priv_class)
+ return ifmt->priv_class;
+
+ while (ofmt = av_oformat_next(ofmt))
+ if (ofmt->priv_class)
+ return ofmt->priv_class;
+
return NULL;
}
@@ -67,26 +87,32 @@ static const AVOption *opt_find(void *obj, const char *name, const char *unit, i
#define D AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[]={
-{"probesize", "set probing size", OFFSET(probesize), FF_OPT_TYPE_INT, {.dbl = 5000000 }, 32, INT_MAX, D},
-{"muxrate", "set mux rate", OFFSET(mux_rate), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
-{"packetsize", "set packet size", OFFSET(packet_size), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
-{"fflags", NULL, OFFSET(flags), FF_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"},
-{"ignidx", "ignore index", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, "fflags"},
-{"genpts", "generate pts", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_GENPTS }, INT_MIN, INT_MAX, D, "fflags"},
-{"nofillin", "do not fill in missing values that can be exactly calculated", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_NOFILLIN }, INT_MIN, INT_MAX, D, "fflags"},
-{"noparse", "disable AVParsers, this needs nofillin too", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_NOPARSE }, INT_MIN, INT_MAX, D, "fflags"},
-{"igndts", "ignore dts", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"},
+{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.dbl = 5000000 }, 32, INT_MAX, D},
+#if FF_API_MUXRATE
+{"muxrate", "set mux rate", OFFSET(mux_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
+#endif
+{"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E},
+{"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"},
+{"ignidx", "ignore index", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, "fflags"},
+{"genpts", "generate pts", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_GENPTS }, INT_MIN, INT_MAX, D, "fflags"},
+{"nofillin", "do not fill in missing values that can be exactly calculated", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_NOFILLIN }, INT_MIN, INT_MAX, D, "fflags"},
+{"noparse", "disable AVParsers, this needs nofillin too", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_NOPARSE }, INT_MIN, INT_MAX, D, "fflags"},
+{"igndts", "ignore dts", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"},
#if FF_API_FLAG_RTP_HINT
-{"rtphint", "add rtp hinting (deprecated, use the -movflags rtphint option instead)", 0, FF_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_RTP_HINT }, INT_MIN, INT_MAX, E, "fflags"},
+{"rtphint", "add rtp hinting (deprecated, use the -movflags rtphint option instead)", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_RTP_HINT }, INT_MIN, INT_MAX, E, "fflags"},
#endif
-{"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), FF_OPT_TYPE_INT, {.dbl = 5*AV_TIME_BASE }, 0, INT_MAX, D},
-{"cryptokey", "decryption key", OFFSET(key), FF_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D},
-{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), FF_OPT_TYPE_INT, {.dbl = 1<<20 }, 0, INT_MAX, D},
-{"rtbufsize", "max memory used for buffering real-time frames", OFFSET(max_picture_buffer), FF_OPT_TYPE_INT, {.dbl = 3041280 }, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */
-{"fdebug", "print specific debug info", OFFSET(debug), FF_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, INT_MAX, E|D, "fdebug"},
-{"ts", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_FDEBUG_TS }, INT_MIN, INT_MAX, E|D, "fdebug"},
-{"max_delay", "maximum muxing or demuxing delay in microseconds", OFFSET(max_delay), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E|D},
-{"fpsprobesize", "number of frames used to probe fps", OFFSET(fps_probe_size), FF_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX-1, D},
+{"discardcorrupt", "discard corrupted frames", 0, AV_OPT_TYPE_CONST, {.dbl = AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, "fflags"},
+{"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), AV_OPT_TYPE_INT, {.dbl = 5*AV_TIME_BASE }, 0, INT_MAX, D},
+{"cryptokey", "decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D},
+{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.dbl = 1<<20 }, 0, INT_MAX, D},
+{"rtbufsize", "max memory used for buffering real-time frames", OFFSET(max_picture_buffer), AV_OPT_TYPE_INT, {.dbl = 3041280 }, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */
+{"fdebug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, INT_MAX, E|D, "fdebug"},
+{"ts", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_FDEBUG_TS }, INT_MIN, INT_MAX, E|D, "fdebug"},
+{"max_delay", "maximum muxing or demuxing delay in microseconds", OFFSET(max_delay), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, E|D},
+{"fer", "set error detection aggressivity", OFFSET(error_recognition), AV_OPT_TYPE_INT, {.dbl = FF_ER_CAREFUL }, INT_MIN, INT_MAX, D, "fer"},
+{"careful", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_ER_CAREFUL }, INT_MIN, INT_MAX, D, "fer"},
+{"explode", "abort decoding on error recognition", 0, AV_OPT_TYPE_CONST, {.dbl = FF_ER_EXPLODE }, INT_MIN, INT_MAX, D, "fer"},
+{"fpsprobesize", "number of frames used to probe fps", OFFSET(fps_probe_size), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX-1, D},
{NULL},
};
@@ -99,7 +125,8 @@ static const AVClass av_format_context_class = {
.item_name = format_to_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
- .opt_find = opt_find,
+ .child_next = format_child_next,
+ .child_class_next = format_child_class_next,
};
static void avformat_get_context_defaults(AVFormatContext *s)
@@ -119,3 +146,8 @@ AVFormatContext *avformat_alloc_context(void)
avformat_get_context_defaults(ic);
return ic;
}
+
+const AVClass *avformat_get_class(void)
+{
+ return &av_format_context_class;
+}
diff --git a/libavformat/os_support.c b/libavformat/os_support.c
index a0fcd6c..889a005 100644
--- a/libavformat/os_support.c
+++ b/libavformat/os_support.c
@@ -1,5 +1,5 @@
/*
- * Various utilities for ffmpeg system
+ * various OS-feature replacement utilities
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* copyright (c) 2002 Francois Revol
*
@@ -71,7 +71,6 @@ int ff_win32_open(const char *filename_utf8, int oflag, int pmode)
#if !HAVE_INET_ATON
#include <stdlib.h>
-#include <strings.h>
int ff_inet_aton (const char * str, struct in_addr * add)
{
diff --git a/libavformat/os_support.h b/libavformat/os_support.h
index 521e997..20c6d73 100644
--- a/libavformat/os_support.h
+++ b/libavformat/os_support.h
@@ -1,5 +1,5 @@
/*
- * various utilities for ffmpeg system
+ * various OS-feature replacement utilities
* copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
* This file is part of Libav.
diff --git a/libavformat/output-example.c b/libavformat/output-example.c
index ddd16f1..a1702cd 100644
--- a/libavformat/output-example.c
+++ b/libavformat/output-example.c
@@ -1,7 +1,4 @@
/*
- * Libavformat API example: Output a media file in any supported
- * libavformat format. The default codecs are used.
- *
* Copyright (c) 2003 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -22,11 +19,22 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
+/**
+ * @file
+ * libavformat API example.
+ *
+ * @example libavformat/output-example.c
+ * Output a media file in any supported libavformat format.
+ * The default codecs are used.
+ */
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
+#include "libavutil/mathematics.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
@@ -43,11 +51,11 @@ static int sws_flags = SWS_BICUBIC;
/**************************************************************/
/* audio output */
-float t, tincr, tincr2;
-int16_t *samples;
-uint8_t *audio_outbuf;
-int audio_outbuf_size;
-int audio_input_frame_size;
+static float t, tincr, tincr2;
+static int16_t *samples;
+static uint8_t *audio_outbuf;
+static int audio_outbuf_size;
+static int audio_input_frame_size;
/*
* add an audio output stream
@@ -182,9 +190,9 @@ static void close_audio(AVFormatContext *oc, AVStream *st)
/**************************************************************/
/* video output */
-AVFrame *picture, *tmp_picture;
-uint8_t *video_outbuf;
-int frame_count, video_outbuf_size;
+static AVFrame *picture, *tmp_picture;
+static uint8_t *video_outbuf;
+static int frame_count, video_outbuf_size;
/* add a video output stream */
static AVStream *add_video_stream(AVFormatContext *oc, enum CodecID codec_id)
@@ -192,7 +200,7 @@ static AVStream *add_video_stream(AVFormatContext *oc, enum CodecID codec_id)
AVCodecContext *c;
AVStream *st;
- st = av_new_stream(oc, 0);
+ st = avformat_new_stream(oc, NULL);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
exit(1);
@@ -437,7 +445,7 @@ int main(int argc, char **argv)
"The output format is automatically guessed according to the file extension.\n"
"Raw images can also be output by using '%%d' in the filename\n"
"\n", argv[0]);
- exit(1);
+ return 1;
}
filename = argv[1];
@@ -451,14 +459,14 @@ int main(int argc, char **argv)
}
if (!fmt) {
fprintf(stderr, "Could not find suitable output format\n");
- exit(1);
+ return 1;
}
/* allocate the output media context */
oc = avformat_alloc_context();
if (!oc) {
fprintf(stderr, "Memory error\n");
- exit(1);
+ return 1;
}
oc->oformat = fmt;
snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
@@ -478,7 +486,7 @@ int main(int argc, char **argv)
parameters). */
if (av_set_parameters(oc, NULL) < 0) {
fprintf(stderr, "Invalid output format parameters\n");
- exit(1);
+ return 1;
}
av_dump_format(oc, 0, filename, 1);
@@ -494,7 +502,7 @@ int main(int argc, char **argv)
if (!(fmt->flags & AVFMT_NOFILE)) {
if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
fprintf(stderr, "Could not open '%s'\n", filename);
- exit(1);
+ return 1;
}
}
diff --git a/libavformat/pcm.c b/libavformat/pcm.c
index 26ab142..7d5fed5 100644
--- a/libavformat/pcm.c
+++ b/libavformat/pcm.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/mathematics.h"
#include "avformat.h"
#include "pcm.h"
diff --git a/libavformat/pcmdec.c b/libavformat/pcmdec.c
index 343bbf0..b61fb33 100644
--- a/libavformat/pcmdec.c
+++ b/libavformat/pcmdec.c
@@ -22,6 +22,8 @@
#include "avformat.h"
#include "rawdec.h"
#include "pcm.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
#define RAW_SAMPLES 1024
@@ -46,20 +48,30 @@ static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
}
-#define PCMDEF(name, long_name, ext, codec) \
-AVInputFormat ff_pcm_ ## name ## _demuxer = {\
- #name,\
- NULL_IF_CONFIG_SMALL(long_name),\
- sizeof(RawAudioDemuxerContext),\
- NULL,\
- ff_raw_read_header,\
- raw_read_packet,\
- NULL,\
- pcm_read_seek,\
- .flags= AVFMT_GENERIC_INDEX,\
- .extensions = ext,\
- .value = codec,\
- .priv_class = &ff_rawaudio_demuxer_class,\
+static const AVOption pcm_options[] = {
+ { "sample_rate", "", offsetof(RawAudioDemuxerContext, sample_rate), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "channels", "", offsetof(RawAudioDemuxerContext, channels), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { NULL },
+};
+
+#define PCMDEF(name_, long_name_, ext, codec) \
+static const AVClass name_ ## _demuxer_class = { \
+ .class_name = #name_ " demuxer", \
+ .item_name = av_default_item_name, \
+ .option = pcm_options, \
+ .version = LIBAVUTIL_VERSION_INT, \
+}; \
+AVInputFormat ff_pcm_ ## name_ ## _demuxer = { \
+ .name = #name_, \
+ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+ .priv_data_size = sizeof(RawAudioDemuxerContext), \
+ .read_header = ff_raw_read_header, \
+ .read_packet = raw_read_packet, \
+ .read_seek = pcm_read_seek, \
+ .flags = AVFMT_GENERIC_INDEX, \
+ .extensions = ext, \
+ .value = codec, \
+ .priv_class = &name_ ## _demuxer_class, \
};
PCMDEF(f64be, "PCM 64 bit floating-point big-endian format",
diff --git a/libavformat/pcmenc.c b/libavformat/pcmenc.c
index 928124e..553df1f 100644
--- a/libavformat/pcmenc.c
+++ b/libavformat/pcmenc.c
@@ -22,18 +22,15 @@
#include "avformat.h"
#include "rawenc.h"
-#define PCMDEF(name, long_name, ext, codec) \
-AVOutputFormat ff_pcm_ ## name ## _muxer = {\
- #name,\
- NULL_IF_CONFIG_SMALL(long_name),\
- NULL,\
- ext,\
- 0,\
- codec,\
- CODEC_ID_NONE,\
- NULL,\
- ff_raw_write_packet,\
- .flags= AVFMT_NOTIMESTAMPS,\
+#define PCMDEF(name_, long_name_, ext, codec) \
+AVOutputFormat ff_pcm_ ## name_ ## _muxer = { \
+ .name = #name_, \
+ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+ .extensions = ext, \
+ .audio_codec = codec, \
+ .video_codec = CODEC_ID_NONE, \
+ .write_packet = ff_raw_write_packet, \
+ .flags = AVFMT_NOTIMESTAMPS, \
};
PCMDEF(f64be, "PCM 64 bit floating-point big-endian format",
diff --git a/libavformat/pmpdec.c b/libavformat/pmpdec.c
new file mode 100644
index 0000000..96c7048
--- /dev/null
+++ b/libavformat/pmpdec.c
@@ -0,0 +1,180 @@
+/*
+ * PMP demuxer
+ * Copyright (c) 2011 Reimar Döffinger
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+
+typedef struct PMPContext {
+ int cur_stream;
+ int num_streams;
+ int audio_packets;
+ int current_packet;
+ uint32_t *packet_sizes;
+ int packet_sizes_alloc;
+} PMPContext;
+
+static int pmp_probe(AVProbeData *p)
+{
+ if (!memcmp(p->buf, "pmpm\1\0\0\0", 8))
+ return AVPROBE_SCORE_MAX;
+ return 0;
+}
+
+static int pmp_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ PMPContext *pmp = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int tb_num, tb_den;
+ int index_cnt;
+ int audio_codec_id = CODEC_ID_NONE;
+ int srate, channels;
+ int i;
+ uint64_t pos;
+ AVStream *vst = avformat_new_stream(s, NULL);
+ if (!vst)
+ return AVERROR(ENOMEM);
+ vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ avio_skip(pb, 8);
+ switch (avio_rl32(pb)) {
+ case 0:
+ vst->codec->codec_id = CODEC_ID_MPEG4;
+ break;
+ case 1:
+ vst->codec->codec_id = CODEC_ID_H264;
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "Unsupported video format\n");
+ break;
+ }
+ index_cnt = avio_rl32(pb);
+ vst->codec->width = avio_rl32(pb);
+ vst->codec->height = avio_rl32(pb);
+
+ tb_num = avio_rl32(pb);
+ tb_den = avio_rl32(pb);
+ avpriv_set_pts_info(vst, 32, tb_num, tb_den);
+ vst->nb_frames = index_cnt;
+ vst->duration = index_cnt;
+
+ switch (avio_rl32(pb)) {
+ case 0:
+ audio_codec_id = CODEC_ID_MP3;
+ break;
+ case 1:
+ av_log(s, AV_LOG_WARNING, "AAC is not yet correctly supported\n");
+ audio_codec_id = CODEC_ID_AAC;
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "Unsupported audio format\n");
+ break;
+ }
+ pmp->num_streams = avio_rl16(pb) + 1;
+ avio_skip(pb, 10);
+ srate = avio_rl32(pb);
+ channels = avio_rl32(pb) + 1;
+ for (i = 1; i < pmp->num_streams; i++) {
+ AVStream *ast = avformat_new_stream(s, NULL);
+ if (!ast)
+ return AVERROR(ENOMEM);
+ ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ ast->codec->codec_id = audio_codec_id;
+ ast->codec->channels = channels;
+ ast->codec->sample_rate = srate;
+ avpriv_set_pts_info(ast, 32, 1, srate);
+ }
+ pos = avio_tell(pb) + 4 * index_cnt;
+ for (i = 0; i < index_cnt; i++) {
+ int size = avio_rl32(pb);
+ int flags = size & 1 ? AVINDEX_KEYFRAME : 0;
+ size >>= 1;
+ av_add_index_entry(vst, pos, i, size, 0, flags);
+ pos += size;
+ }
+ return 0;
+}
+
+static int pmp_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ PMPContext *pmp = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int ret = 0;
+ int i;
+
+ if (pb->eof_reached)
+ return AVERROR_EOF;
+ if (pmp->cur_stream == 0) {
+ int num_packets;
+ pmp->audio_packets = avio_r8(pb);
+ num_packets = (pmp->num_streams - 1) * pmp->audio_packets + 1;
+ avio_skip(pb, 8);
+ pmp->current_packet = 0;
+ av_fast_malloc(&pmp->packet_sizes,
+ &pmp->packet_sizes_alloc,
+ num_packets * sizeof(*pmp->packet_sizes));
+ if (!pmp->packet_sizes_alloc) {
+ av_log(s, AV_LOG_ERROR, "Cannot (re)allocate packet buffer\n");
+ return AVERROR(ENOMEM);
+ }
+ for (i = 0; i < num_packets; i++)
+ pmp->packet_sizes[i] = avio_rl32(pb);
+ }
+ ret = av_get_packet(pb, pkt, pmp->packet_sizes[pmp->current_packet]);
+ if (ret > 0) {
+ ret = 0;
+ // FIXME: this is a hack that should be removed once
+ // compute_pkt_fields() can handle timestamps properly
+ if (pmp->cur_stream == 0)
+ pkt->dts = s->streams[0]->cur_dts++;
+ pkt->stream_index = pmp->cur_stream;
+ }
+ pmp->current_packet++;
+ if (pmp->current_packet == 1 || pmp->current_packet > pmp->audio_packets)
+ pmp->cur_stream = (pmp->cur_stream + 1) % pmp->num_streams;
+
+ return ret;
+}
+
+static int pmp_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
+{
+ PMPContext *pmp = s->priv_data;
+ pmp->cur_stream = 0;
+ // fallback to default seek now
+ return -1;
+}
+
+static int pmp_close(AVFormatContext *s)
+{
+ PMPContext *pmp = s->priv_data;
+ av_freep(&pmp->packet_sizes);
+ return 0;
+}
+
+AVInputFormat ff_pmp_demuxer = {
+ .name = "pmp",
+ .long_name = NULL_IF_CONFIG_SMALL("Playstation Portable PMP format"),
+ .priv_data_size = sizeof(PMPContext),
+ .read_probe = pmp_probe,
+ .read_header = pmp_header,
+ .read_packet = pmp_packet,
+ .read_seek = pmp_seek,
+ .read_close = pmp_close,
+};
diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c
index b7a9d3b..d22de08 100644
--- a/libavformat/psxstr.c
+++ b/libavformat/psxstr.c
@@ -31,6 +31,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define RIFF_TAG MKTAG('R', 'I', 'F', 'F')
#define CDXA_TAG MKTAG('C', 'D', 'X', 'A')
@@ -162,10 +163,10 @@ static int str_read_packet(AVFormatContext *s,
if(str->channels[channel].video_stream_index < 0){
/* allocate a new AVStream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 64, 1, 15);
+ avpriv_set_pts_info(st, 64, 1, 15);
str->channels[channel].video_stream_index = st->index;
@@ -210,7 +211,7 @@ static int str_read_packet(AVFormatContext *s,
if(str->channels[channel].audio_stream_index < 0){
int fmt = sector[0x13];
/* allocate a new AVStream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -224,7 +225,7 @@ static int str_read_packet(AVFormatContext *s,
// st->codec->bit_rate = 0; //FIXME;
st->codec->block_align = 128;
- av_set_pts_info(st, 64, 128, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 128, st->codec->sample_rate);
}
pkt = ret_pkt;
if (av_new_packet(pkt, 2304))
@@ -234,7 +235,6 @@ static int str_read_packet(AVFormatContext *s,
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 */
@@ -259,11 +259,11 @@ static int str_read_close(AVFormatContext *s)
}
AVInputFormat ff_str_demuxer = {
- "psxstr",
- NULL_IF_CONFIG_SMALL("Sony Playstation STR format"),
- sizeof(StrDemuxContext),
- str_probe,
- str_read_header,
- str_read_packet,
- str_read_close,
+ .name = "psxstr",
+ .long_name = NULL_IF_CONFIG_SMALL("Sony Playstation STR format"),
+ .priv_data_size = sizeof(StrDemuxContext),
+ .read_probe = str_probe,
+ .read_header = str_read_header,
+ .read_packet = str_read_packet,
+ .read_close = str_read_close,
};
diff --git a/libavformat/pva.c b/libavformat/pva.c
index 79b959c..263fb5f 100644
--- a/libavformat/pva.c
+++ b/libavformat/pva.c
@@ -20,6 +20,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "mpeg.h"
#define PVA_MAX_PAYLOAD_LENGTH 0x17f8
@@ -43,20 +44,20 @@ static int pva_probe(AVProbeData * pd) {
static int pva_read_header(AVFormatContext *s, AVFormatParameters *ap) {
AVStream *st;
- if (!(st = av_new_stream(s, 0)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_MPEG2VIDEO;
st->need_parsing = AVSTREAM_PARSE_FULL;
- av_set_pts_info(st, 32, 1, 90000);
+ avpriv_set_pts_info(st, 32, 1, 90000);
av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME);
- if (!(st = av_new_stream(s, 1)))
+ if (!(st = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_MP2;
st->need_parsing = AVSTREAM_PARSE_FULL;
- av_set_pts_info(st, 33, 1, 90000);
+ avpriv_set_pts_info(st, 33, 1, 90000);
av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME);
/* the parameters will be extracted from the compressed bitstream */
@@ -201,11 +202,11 @@ static int64_t pva_read_timestamp(struct AVFormatContext *s, int stream_index,
}
AVInputFormat ff_pva_demuxer = {
- "pva",
- NULL_IF_CONFIG_SMALL("TechnoTrend PVA file and stream format"),
- sizeof(PVAContext),
- pva_probe,
- pva_read_header,
- pva_read_packet,
+ .name = "pva",
+ .long_name = NULL_IF_CONFIG_SMALL("TechnoTrend PVA file and stream format"),
+ .priv_data_size = sizeof(PVAContext),
+ .read_probe = pva_probe,
+ .read_header = pva_read_header,
+ .read_packet = pva_read_packet,
.read_timestamp = pva_read_timestamp
};
diff --git a/libavformat/qcp.c b/libavformat/qcp.c
index 635d531..191e9dd 100644
--- a/libavformat/qcp.c
+++ b/libavformat/qcp.c
@@ -23,7 +23,7 @@
* @file
* QCP format (.qcp) demuxer
* @author Kenan Gillet
- * @sa RFC 3625: "The QCP File Format and Media Types for Speech Data"
+ * @see RFC 3625: "The QCP File Format and Media Types for Speech Data"
* http://tools.ietf.org/html/rfc3625
*/
@@ -84,7 +84,7 @@ static int qcp_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
AVIOContext *pb = s->pb;
QCPContext *c = s->priv_data;
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
uint8_t buf[16];
int i, nb_rates;
@@ -92,8 +92,7 @@ static int qcp_read_header(AVFormatContext *s, AVFormatParameters *ap)
return AVERROR(ENOMEM);
avio_rb32(pb); // "RIFF"
- s->file_size = avio_rl32(pb) + 8;
- avio_skip(pb, 8 + 4 + 1 + 1); // "QLCMfmt " + chunk-size + major-version + minor-version
+ avio_skip(pb, 4 + 8 + 4 + 1 + 1); // filesize + "QLCMfmt " + chunk-size + major-version + minor-version
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->channels = 1;
diff --git a/libavformat/r3d.c b/libavformat/r3d.c
index 619c6a7..73e7398 100644
--- a/libavformat/r3d.c
+++ b/libavformat/r3d.c
@@ -23,7 +23,9 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
#include "avformat.h"
+#include "internal.h"
typedef struct {
unsigned video_offsets_count;
@@ -51,7 +53,7 @@ static int read_atom(AVFormatContext *s, Atom *atom)
static int r3d_read_red1(AVFormatContext *s)
{
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
char filename[258];
int tmp;
int av_unused tmp2;
@@ -69,7 +71,7 @@ static int r3d_read_red1(AVFormatContext *s)
av_dlog(s, "unknown1 %d\n", tmp);
tmp = avio_rb32(s->pb);
- av_set_pts_info(st, 32, 1, tmp);
+ avpriv_set_pts_info(st, 32, 1, tmp);
tmp = avio_rb32(s->pb); // filenum
av_dlog(s, "filenum %d\n", tmp);
@@ -88,13 +90,13 @@ static int r3d_read_red1(AVFormatContext *s)
tmp = avio_r8(s->pb); // audio channels
av_dlog(s, "audio channels %d\n", tmp);
if (tmp > 0) {
- AVStream *ast = av_new_stream(s, 1);
+ AVStream *ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
ast->codec->codec_id = CODEC_ID_PCM_S32BE;
ast->codec->channels = tmp;
- av_set_pts_info(ast, 32, 1, st->time_base.den);
+ avpriv_set_pts_info(ast, 32, 1, st->time_base.den);
}
avio_read(s->pb, filename, 257);
@@ -383,12 +385,12 @@ static int r3d_close(AVFormatContext *s)
}
AVInputFormat ff_r3d_demuxer = {
- "r3d",
- NULL_IF_CONFIG_SMALL("REDCODE R3D format"),
- sizeof(R3DContext),
- r3d_probe,
- r3d_read_header,
- r3d_read_packet,
- r3d_close,
- r3d_seek,
+ .name = "r3d",
+ .long_name = NULL_IF_CONFIG_SMALL("REDCODE R3D format"),
+ .priv_data_size = sizeof(R3DContext),
+ .read_probe = r3d_probe,
+ .read_header = r3d_read_header,
+ .read_packet = r3d_read_packet,
+ .read_close = r3d_close,
+ .read_seek = r3d_seek,
};
diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c
index cc05c35..589cdd5 100644
--- a/libavformat/rawdec.c
+++ b/libavformat/rawdec.c
@@ -21,6 +21,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "avio_internal.h"
#include "rawdec.h"
#include "libavutil/opt.h"
@@ -33,7 +34,7 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap)
AVStream *st;
enum CodecID id;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -49,23 +50,20 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap)
case AVMEDIA_TYPE_AUDIO: {
RawAudioDemuxerContext *s1 = s->priv_data;
-#if FF_API_FORMAT_PARAMETERS
- if (ap->sample_rate)
- st->codec->sample_rate = ap->sample_rate;
- if (ap->channels)
- st->codec->channels = ap->channels;
- else st->codec->channels = 1;
-#endif
+ st->codec->channels = 1;
+
+ if (id == CODEC_ID_ADPCM_G722)
+ st->codec->sample_rate = 16000;
- if (s1->sample_rate)
+ if (s1 && s1->sample_rate)
st->codec->sample_rate = s1->sample_rate;
- if (s1->channels)
+ if (s1 && s1->channels)
st->codec->channels = s1->channels;
st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
assert(st->codec->bits_per_coded_sample > 0);
st->codec->block_align = st->codec->bits_per_coded_sample*st->codec->channels/8;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
break;
}
case AVMEDIA_TYPE_VIDEO: {
@@ -87,17 +85,7 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap)
av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s1->framerate);
goto fail;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->width > 0)
- width = ap->width;
- if (ap->height > 0)
- height = ap->height;
- if (ap->pix_fmt)
- pix_fmt = ap->pix_fmt;
- if (ap->time_base.num)
- framerate = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
- av_set_pts_info(st, 64, framerate.den, framerate.num);
+ avpriv_set_pts_info(st, 64, framerate.den, framerate.num);
st->codec->width = width;
st->codec->height = height;
st->codec->pix_fmt = pix_fmt;
@@ -135,7 +123,7 @@ int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt)
int ff_raw_audio_read_header(AVFormatContext *s,
AVFormatParameters *ap)
{
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -156,7 +144,7 @@ int ff_raw_video_read_header(AVFormatContext *s,
int ret = 0;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st) {
ret = AVERROR(ENOMEM);
goto fail;
@@ -170,13 +158,9 @@ int ff_raw_video_read_header(AVFormatContext *s,
av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s1->framerate);
goto fail;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->time_base.num)
- framerate = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
- st->codec->time_base = (AVRational){framerate.den, framerate.num};
- av_set_pts_info(st, 64, 1, 1200000);
+ st->r_frame_rate = st->avg_frame_rate = framerate;
+ avpriv_set_pts_info(st, 64, 1, 1200000);
fail:
return ret;
@@ -184,63 +168,34 @@ fail:
/* Note: Do not forget to add new entries to the Makefile as well. */
-static const AVOption audio_options[] = {
- { "sample_rate", "", offsetof(RawAudioDemuxerContext, sample_rate), FF_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
- { "channels", "", offsetof(RawAudioDemuxerContext, channels), FF_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
- { NULL },
-};
-
-const AVClass ff_rawaudio_demuxer_class = {
- .class_name = "rawaudio demuxer",
- .item_name = av_default_item_name,
- .option = audio_options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
#define OFFSET(x) offsetof(FFRawVideoDemuxerContext, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
-static const AVOption video_options[] = {
- { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "pixel_format", "", OFFSET(pixel_format), FF_OPT_TYPE_STRING, {.str = "yuv420p"}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+const AVOption ff_rawvideo_options[] = {
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC},
{ NULL },
};
-#undef OFFSET
-#undef DEC
-
-const AVClass ff_rawvideo_demuxer_class = {
- .class_name = "rawvideo demuxer",
- .item_name = av_default_item_name,
- .option = video_options,
- .version = LIBAVUTIL_VERSION_INT,
-};
#if CONFIG_G722_DEMUXER
AVInputFormat ff_g722_demuxer = {
- "g722",
- NULL_IF_CONFIG_SMALL("raw G.722"),
- sizeof(RawAudioDemuxerContext),
- NULL,
- ff_raw_read_header,
- ff_raw_read_partial_packet,
+ .name = "g722",
+ .long_name = NULL_IF_CONFIG_SMALL("raw G.722"),
+ .read_header = ff_raw_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "g722,722",
.value = CODEC_ID_ADPCM_G722,
- .priv_class = &ff_rawaudio_demuxer_class,
};
#endif
-#if CONFIG_GSM_DEMUXER
-AVInputFormat ff_gsm_demuxer = {
- "gsm",
- NULL_IF_CONFIG_SMALL("raw GSM"),
- 0,
- NULL,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+#if CONFIG_LATM_DEMUXER
+AVInputFormat ff_latm_demuxer = {
+ .name = "latm",
+ .long_name = NULL_IF_CONFIG_SMALL("raw LOAS/LATM"),
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
- .extensions = "gsm",
- .value = CODEC_ID_GSM,
+ .extensions = "latm",
+ .value = CODEC_ID_AAC_LATM,
};
#endif
@@ -250,12 +205,10 @@ FF_DEF_RAWVIDEO_DEMUXER(mjpeg, "raw MJPEG video", NULL, "mjpg,mjpeg", CODEC_ID_M
#if CONFIG_MLP_DEMUXER
AVInputFormat ff_mlp_demuxer = {
- "mlp",
- NULL_IF_CONFIG_SMALL("raw MLP"),
- 0,
- NULL,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "mlp",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MLP"),
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "mlp",
.value = CODEC_ID_MLP,
@@ -264,12 +217,10 @@ AVInputFormat ff_mlp_demuxer = {
#if CONFIG_TRUEHD_DEMUXER
AVInputFormat ff_truehd_demuxer = {
- "truehd",
- NULL_IF_CONFIG_SMALL("raw TrueHD"),
- 0,
- NULL,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
+ .name = "truehd",
+ .long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"),
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "thd",
.value = CODEC_ID_TRUEHD,
@@ -278,13 +229,11 @@ AVInputFormat ff_truehd_demuxer = {
#if CONFIG_SHORTEN_DEMUXER
AVInputFormat ff_shorten_demuxer = {
- "shn",
- NULL_IF_CONFIG_SMALL("raw Shorten"),
- 0,
- NULL,
- ff_raw_audio_read_header,
- ff_raw_read_partial_packet,
- .flags= AVFMT_GENERIC_INDEX,
+ .name = "shn",
+ .long_name = NULL_IF_CONFIG_SMALL("raw Shorten"),
+ .read_header = ff_raw_audio_read_header,
+ .read_packet = ff_raw_read_partial_packet,
+ .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK,
.extensions = "shn",
.value = CODEC_ID_SHORTEN,
};
diff --git a/libavformat/rawdec.h b/libavformat/rawdec.h
index 76e8053..136f6c2 100644
--- a/libavformat/rawdec.h
+++ b/libavformat/rawdec.h
@@ -24,6 +24,7 @@
#include "avformat.h"
#include "libavutil/log.h"
+#include "libavutil/opt.h"
typedef struct RawAudioDemuxerContext {
AVClass *class;
@@ -38,8 +39,7 @@ typedef struct FFRawVideoDemuxerContext {
char *framerate; /**< String describing framerate, set by a private option. */
} FFRawVideoDemuxerContext;
-extern const AVClass ff_rawaudio_demuxer_class;
-extern const AVClass ff_rawvideo_demuxer_class;
+extern const AVOption ff_rawvideo_options[];
int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap);
@@ -49,7 +49,16 @@ int ff_raw_audio_read_header(AVFormatContext *s, AVFormatParameters *ap);
int ff_raw_video_read_header(AVFormatContext *s, AVFormatParameters *ap);
+#define FF_RAWVIDEO_DEMUXER_CLASS(name)\
+static const AVClass name ## _demuxer_class = {\
+ .class_name = #name " demuxer",\
+ .item_name = av_default_item_name,\
+ .option = ff_rawvideo_options,\
+ .version = LIBAVUTIL_VERSION_INT,\
+};
+
#define FF_DEF_RAWVIDEO_DEMUXER(shortname, longname, probe, ext, id)\
+FF_RAWVIDEO_DEMUXER_CLASS(shortname)\
AVInputFormat ff_ ## shortname ## _demuxer = {\
.name = #shortname,\
.long_name = NULL_IF_CONFIG_SMALL(longname),\
@@ -60,7 +69,7 @@ AVInputFormat ff_ ## shortname ## _demuxer = {\
.flags = AVFMT_GENERIC_INDEX,\
.value = id,\
.priv_data_size = sizeof(FFRawVideoDemuxerContext),\
- .priv_class = &ff_rawvideo_demuxer_class,\
+ .priv_class = &shortname ## _demuxer_class,\
};
#endif /* AVFORMAT_RAWDEC_H */
diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c
index 00e43df..5f2065e 100644
--- a/libavformat/rawenc.c
+++ b/libavformat/rawenc.c
@@ -34,195 +34,163 @@ int ff_raw_write_packet(AVFormatContext *s, AVPacket *pkt)
#if CONFIG_AC3_MUXER
AVOutputFormat ff_ac3_muxer = {
- "ac3",
- NULL_IF_CONFIG_SMALL("raw AC-3"),
- "audio/x-ac3",
- "ac3",
- 0,
- CODEC_ID_AC3,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "ac3",
+ .long_name = NULL_IF_CONFIG_SMALL("raw AC-3"),
+ .mime_type = "audio/x-ac3",
+ .extensions = "ac3",
+ .audio_codec = CODEC_ID_AC3,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_DIRAC_MUXER
AVOutputFormat ff_dirac_muxer = {
- "dirac",
- NULL_IF_CONFIG_SMALL("raw Dirac"),
- NULL,
- "drc",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_DIRAC,
- NULL,
- ff_raw_write_packet,
+ .name = "dirac",
+ .long_name = NULL_IF_CONFIG_SMALL("raw Dirac"),
+ .extensions = "drc",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_DIRAC,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_DNXHD_MUXER
AVOutputFormat ff_dnxhd_muxer = {
- "dnxhd",
- NULL_IF_CONFIG_SMALL("raw DNxHD (SMPTE VC-3)"),
- NULL,
- "dnxhd",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_DNXHD,
- NULL,
- ff_raw_write_packet,
+ .name = "dnxhd",
+ .long_name = NULL_IF_CONFIG_SMALL("raw DNxHD (SMPTE VC-3)"),
+ .extensions = "dnxhd",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_DNXHD,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_DTS_MUXER
AVOutputFormat ff_dts_muxer = {
- "dts",
- NULL_IF_CONFIG_SMALL("raw DTS"),
- "audio/x-dca",
- "dts",
- 0,
- CODEC_ID_DTS,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "dts",
+ .long_name = NULL_IF_CONFIG_SMALL("raw DTS"),
+ .mime_type = "audio/x-dca",
+ .extensions = "dts",
+ .audio_codec = CODEC_ID_DTS,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_EAC3_MUXER
AVOutputFormat ff_eac3_muxer = {
- "eac3",
- NULL_IF_CONFIG_SMALL("raw E-AC-3"),
- "audio/x-eac3",
- "eac3",
- 0,
- CODEC_ID_EAC3,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "eac3",
+ .long_name = NULL_IF_CONFIG_SMALL("raw E-AC-3"),
+ .mime_type = "audio/x-eac3",
+ .extensions = "eac3",
+ .audio_codec = CODEC_ID_EAC3,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_G722_MUXER
AVOutputFormat ff_g722_muxer = {
- "g722",
- NULL_IF_CONFIG_SMALL("raw G.722"),
- "audio/G722",
- "g722",
- 0,
- CODEC_ID_ADPCM_G722,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "g722",
+ .long_name = NULL_IF_CONFIG_SMALL("raw G.722"),
+ .mime_type = "audio/G722",
+ .extensions = "g722",
+ .audio_codec = CODEC_ID_ADPCM_G722,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_H261_MUXER
AVOutputFormat ff_h261_muxer = {
- "h261",
- NULL_IF_CONFIG_SMALL("raw H.261"),
- "video/x-h261",
- "h261",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_H261,
- NULL,
- ff_raw_write_packet,
+ .name = "h261",
+ .long_name = NULL_IF_CONFIG_SMALL("raw H.261"),
+ .mime_type = "video/x-h261",
+ .extensions = "h261",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_H261,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_H263_MUXER
AVOutputFormat ff_h263_muxer = {
- "h263",
- NULL_IF_CONFIG_SMALL("raw H.263"),
- "video/x-h263",
- "h263",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_H263,
- NULL,
- ff_raw_write_packet,
+ .name = "h263",
+ .long_name = NULL_IF_CONFIG_SMALL("raw H.263"),
+ .mime_type = "video/x-h263",
+ .extensions = "h263",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_H263,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_H264_MUXER
AVOutputFormat ff_h264_muxer = {
- "h264",
- NULL_IF_CONFIG_SMALL("raw H.264 video format"),
- NULL,
- "h264",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_H264,
- NULL,
- ff_raw_write_packet,
+ .name = "h264",
+ .long_name = NULL_IF_CONFIG_SMALL("raw H.264 video format"),
+ .extensions = "h264",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_H264,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_CAVSVIDEO_MUXER
AVOutputFormat ff_cavsvideo_muxer = {
- "cavsvideo",
- NULL_IF_CONFIG_SMALL("raw Chinese AVS video"),
- NULL,
- "cavs",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_CAVS,
- NULL,
- ff_raw_write_packet,
+ .name = "cavsvideo",
+ .long_name = NULL_IF_CONFIG_SMALL("raw Chinese AVS video"),
+ .extensions = "cavs",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_CAVS,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_M4V_MUXER
AVOutputFormat ff_m4v_muxer = {
- "m4v",
- NULL_IF_CONFIG_SMALL("raw MPEG-4 video format"),
- NULL,
- "m4v",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_MPEG4,
- NULL,
- ff_raw_write_packet,
+ .name = "m4v",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-4 video format"),
+ .extensions = "m4v",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_MJPEG_MUXER
AVOutputFormat ff_mjpeg_muxer = {
- "mjpeg",
- NULL_IF_CONFIG_SMALL("raw MJPEG video"),
- "video/x-mjpeg",
- "mjpg,mjpeg",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_MJPEG,
- NULL,
- ff_raw_write_packet,
+ .name = "mjpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MJPEG video"),
+ .mime_type = "video/x-mjpeg",
+ .extensions = "mjpg,mjpeg",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_MJPEG,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_MLP_MUXER
AVOutputFormat ff_mlp_muxer = {
- "mlp",
- NULL_IF_CONFIG_SMALL("raw MLP"),
- NULL,
- "mlp",
- 0,
- CODEC_ID_MLP,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "mlp",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MLP"),
+ .extensions = "mlp",
+ .audio_codec = CODEC_ID_MLP,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
@@ -241,60 +209,49 @@ AVOutputFormat ff_srt_muxer = {
#if CONFIG_TRUEHD_MUXER
AVOutputFormat ff_truehd_muxer = {
- "truehd",
- NULL_IF_CONFIG_SMALL("raw TrueHD"),
- NULL,
- "thd",
- 0,
- CODEC_ID_TRUEHD,
- CODEC_ID_NONE,
- NULL,
- ff_raw_write_packet,
+ .name = "truehd",
+ .long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"),
+ .extensions = "thd",
+ .audio_codec = CODEC_ID_TRUEHD,
+ .video_codec = CODEC_ID_NONE,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_MPEG1VIDEO_MUXER
AVOutputFormat ff_mpeg1video_muxer = {
- "mpeg1video",
- NULL_IF_CONFIG_SMALL("raw MPEG-1 video"),
- "video/x-mpeg",
- "mpg,mpeg,m1v",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_MPEG1VIDEO,
- NULL,
- ff_raw_write_packet,
+ .name = "mpeg1video",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-1 video"),
+ .mime_type = "video/x-mpeg",
+ .extensions = "mpg,mpeg,m1v",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_MPEG1VIDEO,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_MPEG2VIDEO_MUXER
AVOutputFormat ff_mpeg2video_muxer = {
- "mpeg2video",
- NULL_IF_CONFIG_SMALL("raw MPEG-2 video"),
- NULL,
- "m2v",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_MPEG2VIDEO,
- NULL,
- ff_raw_write_packet,
+ .name = "mpeg2video",
+ .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-2 video"),
+ .extensions = "m2v",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_MPEG2VIDEO,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
#if CONFIG_RAWVIDEO_MUXER
AVOutputFormat ff_rawvideo_muxer = {
- "rawvideo",
- NULL_IF_CONFIG_SMALL("raw video format"),
- NULL,
- "yuv,rgb",
- 0,
- CODEC_ID_NONE,
- CODEC_ID_RAWVIDEO,
- NULL,
- ff_raw_write_packet,
+ .name = "rawvideo",
+ .long_name = NULL_IF_CONFIG_SMALL("raw video format"),
+ .extensions = "yuv,rgb",
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_packet = ff_raw_write_packet,
.flags= AVFMT_NOTIMESTAMPS,
};
#endif
diff --git a/libavformat/rawvideodec.c b/libavformat/rawvideodec.c
index f8d9b65..6ca17d5 100644
--- a/libavformat/rawvideodec.c
+++ b/libavformat/rawvideodec.c
@@ -44,15 +44,30 @@ static int rawvideo_read_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
+#define OFFSET(x) offsetof(FFRawVideoDemuxerContext, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+static const AVOption rawvideo_options[] = {
+ { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "yuv420p"}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+ { NULL },
+};
+
+static const AVClass rawvideo_demuxer_class = {
+ .class_name = "rawvideo demuxer",
+ .item_name = av_default_item_name,
+ .option = rawvideo_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_rawvideo_demuxer = {
- "rawvideo",
- NULL_IF_CONFIG_SMALL("raw video format"),
- sizeof(FFRawVideoDemuxerContext),
- NULL,
- ff_raw_read_header,
- rawvideo_read_packet,
+ .name = "rawvideo",
+ .long_name = NULL_IF_CONFIG_SMALL("raw video format"),
+ .priv_data_size = sizeof(FFRawVideoDemuxerContext),
+ .read_header = ff_raw_read_header,
+ .read_packet = rawvideo_read_packet,
.flags= AVFMT_GENERIC_INDEX,
.extensions = "yuv,cif,qcif,rgb",
.value = CODEC_ID_RAWVIDEO,
- .priv_class = &ff_rawvideo_demuxer_class,
+ .priv_class = &rawvideo_demuxer_class,
};
diff --git a/libavformat/rdt.c b/libavformat/rdt.c
index 9155cfc..207fc92 100644
--- a/libavformat/rdt.c
+++ b/libavformat/rdt.c
@@ -459,8 +459,9 @@ add_dstream(AVFormatContext *s, AVStream *orig_st)
{
AVStream *st;
- if (!(st = av_new_stream(s, orig_st->id)))
+ if (!(st = avformat_new_stream(s, NULL)))
return NULL;
+ st->id = orig_st->id;
st->codec->codec_type = orig_st->codec->codec_type;
st->first_dts = orig_st->first_dts;
@@ -483,7 +484,7 @@ real_parse_asm_rulebook(AVFormatContext *s, AVStream *orig_st,
* is set and once for if it isn't. We only read the first because we
* don't care much (that's what the "odd" variable is for).
* Each rule contains a set of one or more statements, optionally
- * preceeded by a single condition. If there's a condition, the rule
+ * preceded by a single condition. If there's a condition, the rule
* starts with a '#'. Multiple conditions are merged between brackets,
* so there are never multiple conditions spread out over separate
* statements. Generally, these conditions are bitrate limits (min/max)
@@ -523,7 +524,11 @@ rdt_new_context (void)
{
PayloadContext *rdt = av_mallocz(sizeof(PayloadContext));
- avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL);
+ int ret = avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL);
+ if (ret < 0) {
+ av_free(rdt);
+ return NULL;
+ }
return rdt;
}
@@ -539,7 +544,7 @@ rdt_free_context (PayloadContext *rdt)
av_freep(&rdt->rmst[i]);
}
if (rdt->rmctx)
- av_close_input_file(rdt->rmctx);
+ avformat_close_input(&rdt->rmctx);
av_freep(&rdt->mlti_data);
av_freep(&rdt->rmst);
av_free(rdt);
diff --git a/libavformat/rdt.h b/libavformat/rdt.h
index 08b17bc..a393299 100644
--- a/libavformat/rdt.h
+++ b/libavformat/rdt.h
@@ -80,16 +80,16 @@ void ff_rdt_subscribe_rule(char *cmd, int size,
*
* @param buf input buffer
* @param len length of input buffer
- * @param set_id will be set to the set ID this packet belongs to
- * @param seq_no will be set to the sequence number of the packet
- * @param stream_id will be set to the stream ID this packet belongs to
- * @param is_keyframe will be whether this packet belongs to a keyframe
- * @param timestamp will be set to the timestamp of the packet
+ * @param pset_id will be set to the set ID this packet belongs to
+ * @param pseq_no will be set to the sequence number of the packet
+ * @param pstream_id will be set to the stream ID this packet belongs to
+ * @param pis_keyframe will be whether this packet belongs to a keyframe
+ * @param ptimestamp will be set to the timestamp of the packet
* @return the amount of bytes consumed, or negative on error
*/
int ff_rdt_parse_header(const uint8_t *buf, int len,
- int *set_id, int *seq_no, int *stream_id,
- int *is_keyframe, uint32_t *timestamp);
+ int *pset_id, int *pseq_no, int *pstream_id,
+ int *pis_keyframe, uint32_t *ptimestamp);
/**
* Parse RDT-style packet data (header + media data).
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 0df569e..1d226ab 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/mathematics.h"
#include "libavcodec/avcodec.h"
#include "avformat.h"
#include "avio_internal.h"
@@ -86,6 +87,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_MPEG4, MKTAG('G', 'E', 'O', 'V') },
{ CODEC_ID_MPEG4, MKTAG('S', 'I', 'P', 'P') }, /* Samsung SHR-6040 */
{ CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'X') },
+ { CODEC_ID_MPEG4, MKTAG('D', 'r', 'e', 'X') },
{ CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') },
{ CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '3') },
{ CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', 'G', '3') },
@@ -172,10 +174,13 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', 's') },
{ CODEC_ID_RAWVIDEO, MKTAG('P', '4', '2', '2') },
{ CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', '1', '2') },
+ { CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', '1', '6') },
+ { CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', '2', '4') },
{ CODEC_ID_RAWVIDEO, MKTAG('U', 'Y', 'V', 'Y') },
{ CODEC_ID_RAWVIDEO, MKTAG('V', 'Y', 'U', 'Y') },
{ CODEC_ID_RAWVIDEO, MKTAG('I', 'Y', 'U', 'V') },
{ CODEC_ID_RAWVIDEO, MKTAG('Y', '8', '0', '0') },
+ { CODEC_ID_RAWVIDEO, MKTAG('Y', '8', ' ', ' ') },
{ CODEC_ID_RAWVIDEO, MKTAG('H', 'D', 'Y', 'C') },
{ CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', 'U', '9') },
{ CODEC_ID_RAWVIDEO, MKTAG('V', 'D', 'T', 'Z') }, /* SoftLab-NSK VideoTizer */
@@ -191,6 +196,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_R10K, MKTAG('R', '1', '0', 'k') },
{ CODEC_ID_R210, MKTAG('r', '2', '1', '0') },
{ CODEC_ID_V210, MKTAG('v', '2', '1', '0') },
+ { CODEC_ID_V410, MKTAG('v', '4', '1', '0') },
{ CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '1') },
{ CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '2') },
{ CODEC_ID_INDEO4, MKTAG('I', 'V', '4', '1') },
@@ -236,10 +242,10 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_QPEG, MKTAG('Q', '1', '.', '0') },
{ CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') },
{ CODEC_ID_WMV3, MKTAG('W', 'M', 'V', '3') },
- { CODEC_ID_WMV3, MKTAG('W', 'M', 'V', 'P') },
+ { CODEC_ID_WMV3IMAGE, MKTAG('W', 'M', 'V', 'P') },
{ CODEC_ID_VC1, MKTAG('W', 'V', 'C', '1') },
{ CODEC_ID_VC1, MKTAG('W', 'M', 'V', 'A') },
- { CODEC_ID_VC1, MKTAG('W', 'V', 'P', '2') },
+ { CODEC_ID_VC1IMAGE, MKTAG('W', 'V', 'P', '2') },
{ CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') },
{ CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') },
{ CODEC_ID_AASC, MKTAG('A', 'A', 'S', 'C') },
@@ -253,11 +259,13 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_CAVS, MKTAG('C', 'A', 'V', 'S') },
{ CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') },
{ CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') },
+ { CODEC_ID_JPEG2000, MKTAG('L', 'J', '2', 'C') },
+ { CODEC_ID_JPEG2000, MKTAG('L', 'J', '2', 'K') },
{ CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') },
{ CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') },
{ CODEC_ID_PNG, MKTAG('M', 'P', 'N', 'G') },
{ CODEC_ID_PNG, MKTAG('P', 'N', 'G', '1') },
- { CODEC_ID_CLJR, MKTAG('c', 'l', 'j', 'r') },
+ { CODEC_ID_CLJR, MKTAG('C', 'L', 'J', 'R') },
{ CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
{ CODEC_ID_RPZA, MKTAG('a', 'z', 'p', 'r') },
{ CODEC_ID_RPZA, MKTAG('R', 'P', 'Z', 'A') },
@@ -268,6 +276,12 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{ CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') },
{ CODEC_ID_KGV1, MKTAG('K', 'G', 'V', '1') },
{ CODEC_ID_LAGARITH, MKTAG('L', 'A', 'G', 'S') },
+ { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'R', 'A') },
+ { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'R', 'G') },
+ { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'Y', '0') },
+ { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'Y', '2') },
+ { CODEC_ID_VBLE, MKTAG('V', 'B', 'L', 'E') },
+ { CODEC_ID_DXTORY, MKTAG('x', 't', 'o', 'r') },
{ CODEC_ID_NONE, 0 }
};
@@ -317,6 +331,7 @@ const AVCodecTag ff_codec_wav_tags[] = {
{ CODEC_ID_PCM_MULAW, 0x6c75 },
{ CODEC_ID_AAC, 0x706d },
{ CODEC_ID_AAC, 0x4143 },
+ { CODEC_ID_SPEEX, 0xA109 },
{ CODEC_ID_FLAC, 0xF1AC },
{ CODEC_ID_ADPCM_SWF, ('S'<<8)+'F' },
{ CODEC_ID_VORBIS, ('V'<<8)+'o' }, //HACK/FIXME, does vorbis in WAV/AVI have an (in)official id?
@@ -329,6 +344,28 @@ const AVCodecTag ff_codec_wav_tags[] = {
{ CODEC_ID_NONE, 0 },
};
+const AVMetadataConv ff_riff_info_conv[] = {
+ { "IART", "artist" },
+ { "ICMT", "comment" },
+ { "ICOP", "copyright" },
+ { "ICRD", "date" },
+ { "IGNR", "genre" },
+ { "ILNG", "language" },
+ { "INAM", "title" },
+ { "IPRD", "album" },
+ { "IPRT", "track" },
+ { "ISFT", "encoder" },
+ { "ITCH", "encoded_by"},
+ { 0 },
+};
+
+const char ff_riff_tags[][5] = {
+ "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
+ "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
+ "IPRT", "ISBJ", "ISFT", "ISHP", "ISRC", "ISRF", "ITCH",
+ {0}
+};
+
#if CONFIG_MUXERS
int64_t ff_start_tag(AVIOContext *pb, const char *tag)
{
@@ -373,11 +410,13 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
avio_wl32(pb, enc->sample_rate);
if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) {
bps = 0;
- } else if (enc->codec_id == CODEC_ID_ADPCM_G726) {
- bps = 4;
} else {
- if (!(bps = av_get_bits_per_sample(enc->codec_id)))
- bps = 16; // default to 16
+ if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
+ if (enc->bits_per_coded_sample)
+ bps = enc->bits_per_coded_sample;
+ else
+ bps = 16; // default to 16
+ }
}
if(bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample){
av_log(enc, AV_LOG_WARNING, "requested bits_per_coded_sample (%d) and actually stored (%d) differ\n", enc->bits_per_coded_sample, bps);
@@ -388,12 +427,10 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
//blkalign = 144 * enc->bit_rate/enc->sample_rate;
} else if (enc->codec_id == CODEC_ID_AC3) {
blkalign = 3840; //maximum bytes per frame
- } else if (enc->codec_id == CODEC_ID_ADPCM_G726) { //
- blkalign = 1;
} else if (enc->block_align != 0) { /* specified by the codec */
blkalign = enc->block_align;
} else
- blkalign = enc->channels*bps >> 3;
+ blkalign = bps * enc->channels / av_gcd(8, bps);
if (enc->codec_id == CODEC_ID_PCM_U8 ||
enc->codec_id == CODEC_ID_PCM_S24LE ||
enc->codec_id == CODEC_ID_PCM_S32LE ||
@@ -431,8 +468,6 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
riff_extradata_start= enc->extradata;
riff_extradata= enc->extradata + enc->extradata_size;
hdrsize += enc->extradata_size;
- } else if (!waveformatextensible){
- hdrsize -= 2;
}
if(waveformatextensible) { /* write WAVEFORMATEXTENSIBLE extensions */
hdrsize += 22;
@@ -443,8 +478,8 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
avio_wl32(pb, 0x00100000);
avio_wl32(pb, 0xAA000080);
avio_wl32(pb, 0x719B3800);
- } else if(riff_extradata - riff_extradata_start) {
- avio_wl16(pb, riff_extradata - riff_extradata_start);
+ } else {
+ avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
}
avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
if(hdrsize&1){
@@ -535,6 +570,9 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
codec->channels = 0;
codec->sample_rate = 0;
}
+ /* override bits_per_coded_sample for G.726 */
+ if (codec->codec_id == CODEC_ID_ADPCM_G726)
+ codec->bits_per_coded_sample = codec->bit_rate / codec->sample_rate;
return 0;
}
@@ -599,3 +637,49 @@ void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssiz
*au_scale /= gcd;
*au_rate /= gcd;
}
+
+int ff_read_riff_info(AVFormatContext *s, int64_t size)
+{
+ int64_t start, end, cur;
+ AVIOContext *pb = s->pb;
+
+ start = avio_tell(pb);
+ end = start + size;
+
+ while ((cur = avio_tell(pb)) >= 0 && cur <= end - 8 /* = tag + size */) {
+ uint32_t chunk_code;
+ int64_t chunk_size;
+ char key[5] = {0};
+ char *value;
+
+ chunk_code = avio_rl32(pb);
+ chunk_size = avio_rl32(pb);
+ if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) {
+ av_log(s, AV_LOG_ERROR, "too big INFO subchunk\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ chunk_size += (chunk_size & 1);
+
+ value = av_malloc(chunk_size + 1);
+ if (!value) {
+ av_log(s, AV_LOG_ERROR, "out of memory, unable to read INFO tag\n");
+ return AVERROR(ENOMEM);
+ }
+
+ AV_WL32(key, chunk_code);
+
+ if (avio_read(pb, value, chunk_size) != chunk_size) {
+ av_freep(key);
+ av_freep(value);
+ av_log(s, AV_LOG_ERROR, "premature end of file while reading INFO tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ value[chunk_size] = 0;
+
+ av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
+ }
+
+ return 0;
+}
diff --git a/libavformat/riff.h b/libavformat/riff.h
index a2fa8b7..3bd309f 100644
--- a/libavformat/riff.h
+++ b/libavformat/riff.h
@@ -31,6 +31,10 @@
#include "libavcodec/avcodec.h"
#include "avio.h"
#include "internal.h"
+#include "metadata.h"
+
+extern const AVMetadataConv ff_riff_info_conv[];
+extern const char ff_riff_tags[][5];
int64_t ff_start_tag(AVIOContext *pb, const char *tag);
void ff_end_tag(AVIOContext *pb, int64_t start);
@@ -54,4 +58,6 @@ unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum CodecID id);
enum CodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag);
void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale);
+int ff_read_riff_info(AVFormatContext *s, int64_t size);
+
#endif /* AVFORMAT_RIFF_H */
diff --git a/libavformat/rl2.c b/libavformat/rl2.c
index b4172c2..b2be7c0 100644
--- a/libavformat/rl2.c
+++ b/libavformat/rl2.c
@@ -23,8 +23,7 @@
* RL2 file demuxer
* @file
* @author Sascha Sommer (saschasommer at freenet.de)
- * For more information regarding the RL2 file format, visit:
- * http://wiki.multimedia.cx/index.php?title=RL2
+ * @see http://wiki.multimedia.cx/index.php?title=RL2
*
* extradata:
* 2 byte le initial drawing offset within 320x200 viewport
@@ -34,7 +33,9 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
#include "avformat.h"
+#include "internal.h"
#define EXTRADATA1_SIZE (6 + 256 * 3) ///< video base, clr, palette
@@ -110,7 +111,7 @@ static av_cold int rl2_read_header(AVFormatContext *s,
def_sound_size = avio_rl16(pb);
/** setup video stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if(!st)
return AVERROR(ENOMEM);
@@ -140,7 +141,7 @@ static av_cold int rl2_read_header(AVFormatContext *s,
pts_num = def_sound_size;
pts_den = rate;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -153,10 +154,10 @@ static av_cold int rl2_read_header(AVFormatContext *s,
st->codec->bits_per_coded_sample;
st->codec->block_align = st->codec->channels *
st->codec->bits_per_coded_sample / 8;
- av_set_pts_info(st,32,1,rate);
+ avpriv_set_pts_info(st,32,1,rate);
}
- av_set_pts_info(s->streams[0], 32, pts_num, pts_den);
+ avpriv_set_pts_info(s->streams[0], 32, pts_num, pts_den);
chunk_size = av_malloc(frame_count * sizeof(uint32_t));
audio_size = av_malloc(frame_count * sizeof(uint32_t));
@@ -286,13 +287,12 @@ static int rl2_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
}
AVInputFormat ff_rl2_demuxer = {
- "rl2",
- NULL_IF_CONFIG_SMALL("RL2 format"),
- sizeof(Rl2DemuxContext),
- rl2_probe,
- rl2_read_header,
- rl2_read_packet,
- NULL,
- rl2_read_seek,
+ .name = "rl2",
+ .long_name = NULL_IF_CONFIG_SMALL("RL2 format"),
+ .priv_data_size = sizeof(Rl2DemuxContext),
+ .read_probe = rl2_probe,
+ .read_header = rl2_read_header,
+ .read_packet = rl2_read_packet,
+ .read_seek = rl2_read_seek,
};
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index fbc4d0c..66b6f8a 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -23,9 +23,17 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
#include "rm.h"
+#define DEINT_ID_GENR MKTAG('g', 'e', 'n', 'r') ///< interleaving for Cooker/Atrac
+#define DEINT_ID_INT0 MKTAG('I', 'n', 't', '0') ///< no interleaving needed
+#define DEINT_ID_INT4 MKTAG('I', 'n', 't', '4') ///< interleaving for 28.8
+#define DEINT_ID_SIPR MKTAG('s', 'i', 'p', 'r') ///< interleaving for Sipro
+#define DEINT_ID_VBRF MKTAG('v', 'b', 'r', 'f') ///< VBR case for AAC
+#define DEINT_ID_VBRS MKTAG('v', 'b', 'r', 's') ///< VBR case for AAC
+
struct RMStream {
AVPacket pkt; ///< place to store merged video frame / reordered audio data
int videobufsize; ///< current assembled frame size
@@ -39,6 +47,7 @@ struct RMStream {
int sub_packet_size, sub_packet_h, coded_framesize; ///< Descrambling parameters from container
int audio_framesize; /// Audio frame size from container
int sub_packet_lengths[16]; /// Length of each subpacket
+ int32_t deint_id; ///< deinterleaver used in audio stream
};
typedef struct {
@@ -147,6 +156,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
st->codec->channels = 1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_RA_144;
+ ast->deint_id = DEINT_ID_INT0;
} else {
int flavor, sub_packet_h, coded_framesize, sub_packet_size;
int codecdata_length;
@@ -172,17 +182,19 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
avio_rb32(pb);
st->codec->channels = avio_rb16(pb);
if (version == 5) {
- avio_rb32(pb);
+ ast->deint_id = avio_rl32(pb);
avio_read(pb, buf, 4);
buf[4] = 0;
} else {
get_str8(pb, buf, sizeof(buf)); /* desc */
+ ast->deint_id = AV_RL32(buf);
get_str8(pb, buf, sizeof(buf)); /* desc */
}
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_tag = AV_RL32(buf);
st->codec->codec_id = ff_codec_get_id(ff_rm_codec_tags,
st->codec->codec_tag);
+
switch (st->codec->codec_id) {
case CODEC_ID_AC3:
st->need_parsing = AVSTREAM_PARSE_FULL;
@@ -191,13 +203,6 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
st->codec->extradata_size= 0;
ast->audio_framesize = st->codec->block_align;
st->codec->block_align = coded_framesize;
-
- if(ast->audio_framesize >= UINT_MAX / sub_packet_h){
- av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n");
- return -1;
- }
-
- av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h);
break;
case CODEC_ID_COOK:
case CODEC_ID_ATRAC3:
@@ -228,13 +233,6 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
}
if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0)
return ret;
-
- if(ast->audio_framesize >= UINT_MAX / sub_packet_h){
- av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n");
- return -1;
- }
-
- av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h);
break;
case CODEC_ID_AAC:
avio_rb16(pb); avio_r8(pb);
@@ -254,6 +252,37 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
default:
av_strlcpy(st->codec->codec_name, buf, sizeof(st->codec->codec_name));
}
+ if (ast->deint_id == DEINT_ID_INT4 ||
+ ast->deint_id == DEINT_ID_GENR ||
+ ast->deint_id == DEINT_ID_SIPR) {
+ if (st->codec->block_align <= 0 ||
+ ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX ||
+ ast->audio_framesize * sub_packet_h < st->codec->block_align)
+ return AVERROR_INVALIDDATA;
+ if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0)
+ return AVERROR(ENOMEM);
+ }
+ switch (ast->deint_id) {
+ case DEINT_ID_INT4:
+ if (ast->coded_framesize > ast->audio_framesize ||
+ ast->coded_framesize * sub_packet_h > (2 + (sub_packet_h & 1)) * ast->audio_framesize)
+ return AVERROR_INVALIDDATA;
+ break;
+ case DEINT_ID_GENR:
+ if (ast->sub_packet_size <= 0 ||
+ ast->sub_packet_size > ast->audio_framesize)
+ return AVERROR_INVALIDDATA;
+ break;
+ case DEINT_ID_SIPR:
+ case DEINT_ID_INT0:
+ case DEINT_ID_VBRS:
+ case DEINT_ID_VBRF:
+ break;
+ default:
+ av_log(NULL,0,"Unknown interleaver %X\n", ast->deint_id);
+ return AVERROR_INVALIDDATA;
+ }
+
if (read_all) {
avio_r8(pb);
avio_r8(pb);
@@ -273,7 +302,7 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb,
int64_t codec_pos;
int ret;
- av_set_pts_info(st, 64, 1, 1000);
+ avpriv_set_pts_info(st, 64, 1, 1000);
codec_pos = avio_tell(pb);
v = avio_rb32(pb);
if (v == MKTAG(0xfd, 'a', 'r', '.')) {
@@ -293,30 +322,20 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb,
// av_log(s, AV_LOG_DEBUG, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0'));
if (st->codec->codec_id == CODEC_ID_NONE)
goto fail1;
- st->codec->width = avio_rb16(pb);
+ st->codec->width = avio_rb16(pb);
st->codec->height = avio_rb16(pb);
- st->codec->time_base.num= 1;
- fps= avio_rb16(pb);
+ avio_skip(pb, 2); // looks like bits per sample
+ avio_skip(pb, 4); // always zero?
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- avio_rb32(pb);
- avio_skip(pb, 2);
- avio_rb16(pb);
+ st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
+ fps = avio_rb32(pb);
if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (avio_tell(pb) - codec_pos))) < 0)
return ret;
-// av_log(s, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2);
- st->codec->time_base.den = fps * st->codec->time_base.num;
- //XXX: do we really need that?
- switch(st->codec->extradata[4]>>4){
- case 1: st->codec->codec_id = CODEC_ID_RV10; break;
- case 2: st->codec->codec_id = CODEC_ID_RV20; break;
- case 3: st->codec->codec_id = CODEC_ID_RV30; break;
- case 4: st->codec->codec_id = CODEC_ID_RV40; break;
- default:
- av_log(st->codec, AV_LOG_ERROR, "extra:%02X %02X %02X %02X %02X\n", st->codec->extradata[0], st->codec->extradata[1], st->codec->extradata[2], st->codec->extradata[3], st->codec->extradata[4]);
- goto fail1;
- }
+ av_reduce(&st->r_frame_rate.den, &st->r_frame_rate.num,
+ 0x10000, fps, (1 << 30) - 1);
+ st->avg_frame_rate = st->r_frame_rate;
}
skip:
@@ -371,13 +390,13 @@ skip:
return 0;
}
-static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap)
+static int rm_read_header_old(AVFormatContext *s)
{
RMDemuxContext *rm = s->priv_data;
AVStream *st;
rm->old_format = 1;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
st->priv_data = ff_rm_alloc_rmstream();
@@ -399,7 +418,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
tag = avio_rl32(pb);
if (tag == MKTAG('.', 'r', 'a', 0xfd)) {
/* very old .ra format */
- return rm_read_header_old(s, ap);
+ return rm_read_header_old(s);
} else if (tag != MKTAG('.', 'R', 'M', 'F')) {
return AVERROR(EIO);
}
@@ -443,7 +462,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
rm_read_metadata(s, 1);
break;
case MKTAG('M', 'D', 'P', 'R'):
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->id = avio_rb16(pb);
@@ -578,7 +597,8 @@ skip:
static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
RMDemuxContext *rm, RMStream *vst,
- AVPacket *pkt, int len, int *pseq)
+ AVPacket *pkt, int len, int *pseq,
+ int64_t *timestamp)
{
int hdr, seq, pic_num, len2, pos;
int type;
@@ -598,8 +618,10 @@ static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
return -1;
rm->remaining_len = len;
if(type&1){ // frame, not slice
- if(type == 3) // frame as a part of packet
+ if(type == 3){ // frame as a part of packet
len= len2;
+ *timestamp = pos;
+ }
if(rm->remaining_len < len)
return -1;
rm->remaining_len -= len;
@@ -707,13 +729,12 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
rm->current_stream= st->id;
- if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq))
+ if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq, ×tamp))
return -1; //got partial frame
} else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- if ((st->codec->codec_id == CODEC_ID_RA_288) ||
- (st->codec->codec_id == CODEC_ID_COOK) ||
- (st->codec->codec_id == CODEC_ID_ATRAC3) ||
- (st->codec->codec_id == CODEC_ID_SIPR)) {
+ if ((ast->deint_id == DEINT_ID_GENR) ||
+ (ast->deint_id == DEINT_ID_INT4) ||
+ (ast->deint_id == DEINT_ID_SIPR)) {
int x;
int sps = ast->sub_packet_size;
int cfs = ast->coded_framesize;
@@ -726,30 +747,30 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,
if (!y)
ast->audiotimestamp = timestamp;
- switch(st->codec->codec_id) {
- case CODEC_ID_RA_288:
+ switch (ast->deint_id) {
+ case DEINT_ID_INT4:
for (x = 0; x < h/2; x++)
avio_read(pb, ast->pkt.data+x*2*w+y*cfs, cfs);
break;
- case CODEC_ID_ATRAC3:
- case CODEC_ID_COOK:
+ case DEINT_ID_GENR:
for (x = 0; x < w/sps; x++)
avio_read(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);
break;
- case CODEC_ID_SIPR:
+ case DEINT_ID_SIPR:
avio_read(pb, ast->pkt.data + y * w, w);
break;
}
if (++(ast->sub_packet_cnt) < h)
return -1;
- if (st->codec->codec_id == CODEC_ID_SIPR)
+ if (ast->deint_id == DEINT_ID_SIPR)
ff_rm_reorder_sipr_data(ast->pkt.data, h, w);
ast->sub_packet_cnt = 0;
rm->audio_stream_num = st->index;
rm->audio_pkt_cnt = h * w / st->codec->block_align;
- } else if (st->codec->codec_id == CODEC_ID_AAC) {
+ } else if ((ast->deint_id == DEINT_ID_VBRF) ||
+ (ast->deint_id == DEINT_ID_VBRS)) {
int x;
rm->audio_stream_num = st->index;
ast->sub_packet_cnt = (avio_rb16(pb) & 0xf0) >> 4;
@@ -782,7 +803,7 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,
}
#endif
- pkt->pts= timestamp;
+ pkt->pts = timestamp;
if (flags & 2)
pkt->flags |= AV_PKT_FLAG_KEY;
@@ -797,7 +818,8 @@ ff_rm_retrieve_cache (AVFormatContext *s, AVIOContext *pb,
assert (rm->audio_pkt_cnt > 0);
- if (st->codec->codec_id == CODEC_ID_AAC)
+ if (ast->deint_id == DEINT_ID_VBRF ||
+ ast->deint_id == DEINT_ID_VBRS)
av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]);
else {
av_new_packet(pkt, st->codec->block_align);
@@ -935,23 +957,20 @@ static int64_t rm_read_dts(AVFormatContext *s, int stream_index,
}
AVInputFormat ff_rm_demuxer = {
- "rm",
- NULL_IF_CONFIG_SMALL("RealMedia format"),
- sizeof(RMDemuxContext),
- rm_probe,
- rm_read_header,
- rm_read_packet,
- rm_read_close,
- NULL,
- rm_read_dts,
+ .name = "rm",
+ .long_name = NULL_IF_CONFIG_SMALL("RealMedia format"),
+ .priv_data_size = sizeof(RMDemuxContext),
+ .read_probe = rm_probe,
+ .read_header = rm_read_header,
+ .read_packet = rm_read_packet,
+ .read_close = rm_read_close,
+ .read_timestamp = rm_read_dts,
};
AVInputFormat ff_rdt_demuxer = {
- "rdt",
- NULL_IF_CONFIG_SMALL("RDT demuxer"),
- sizeof(RMDemuxContext),
- NULL,
- NULL,
- NULL,
- rm_read_close,
+ .name = "rdt",
+ .long_name = NULL_IF_CONFIG_SMALL("RDT demuxer"),
+ .priv_data_size = sizeof(RMDemuxContext),
+ .read_close = rm_read_close,
+ .flags = AVFMT_NOFILE,
};
diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c
index 2476cb0..0846a0a 100644
--- a/libavformat/rmenc.c
+++ b/libavformat/rmenc.c
@@ -461,15 +461,15 @@ static int rm_write_trailer(AVFormatContext *s)
AVOutputFormat ff_rm_muxer = {
- "rm",
- NULL_IF_CONFIG_SMALL("RealMedia format"),
- "application/vnd.rn-realmedia",
- "rm,ra",
- sizeof(RMMuxContext),
- CODEC_ID_AC3,
- CODEC_ID_RV10,
- rm_write_header,
- rm_write_packet,
- rm_write_trailer,
+ .name = "rm",
+ .long_name = NULL_IF_CONFIG_SMALL("RealMedia format"),
+ .mime_type = "application/vnd.rn-realmedia",
+ .extensions = "rm,ra",
+ .priv_data_size = sizeof(RMMuxContext),
+ .audio_codec = CODEC_ID_AC3,
+ .video_codec = CODEC_ID_RV10,
+ .write_header = rm_write_header,
+ .write_packet = rm_write_packet,
+ .write_trailer = rm_write_trailer,
.codec_tag= (const AVCodecTag* const []){ff_rm_codec_tags, 0},
};
diff --git a/libavformat/rpl.c b/libavformat/rpl.c
index f67d3cd..0fa00f3 100644
--- a/libavformat/rpl.c
+++ b/libavformat/rpl.c
@@ -22,6 +22,7 @@
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
#include "avformat.h"
+#include "internal.h"
#include <stdlib.h>
#define RPL_SIGNATURE "ARMovie\x0A"
@@ -139,7 +140,7 @@ static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap)
av_dict_set(&s->metadata, "author" , line, 0);
// video headers
- vst = av_new_stream(s, 0);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -149,7 +150,7 @@ static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap)
vst->codec->bits_per_coded_sample = read_line_and_int(pb, &error); // video bits per sample
error |= read_line(pb, line, sizeof(line)); // video frames per second
fps = read_fps(line, &error);
- av_set_pts_info(vst, 32, fps.den, fps.num);
+ avpriv_set_pts_info(vst, 32, fps.den, fps.num);
// Figure out the video codec
switch (vst->codec->codec_tag) {
@@ -181,7 +182,7 @@ static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap)
// samples, though. This code will ignore additional tracks.
audio_format = read_line_and_int(pb, &error); // audio format ID
if (audio_format) {
- ast = av_new_stream(s, 0);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -226,7 +227,7 @@ static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap)
"RPL audio format %i not supported yet!\n",
audio_format);
}
- av_set_pts_info(ast, 32, 1, ast->codec->bit_rate);
+ avpriv_set_pts_info(ast, 32, 1, ast->codec->bit_rate);
} else {
for (i = 0; i < 3; i++)
error |= read_line(pb, line, sizeof(line));
@@ -351,10 +352,10 @@ static int rpl_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_rpl_demuxer = {
- "rpl",
- NULL_IF_CONFIG_SMALL("RPL/ARMovie format"),
- sizeof(RPLContext),
- rpl_probe,
- rpl_read_header,
- rpl_read_packet,
+ .name = "rpl",
+ .long_name = NULL_IF_CONFIG_SMALL("RPL/ARMovie format"),
+ .priv_data_size = sizeof(RPLContext),
+ .read_probe = rpl_probe,
+ .read_header = rpl_read_header,
+ .read_packet = rpl_read_packet,
};
diff --git a/libavformat/rso.h b/libavformat/rso.h
index bdb39e8..e3e88ea 100644
--- a/libavformat/rso.h
+++ b/libavformat/rso.h
@@ -26,7 +26,7 @@
#define RSO_HEADER_SIZE 8
-/* The ffmpeg codecs we support, and the IDs they have in the file */
+/* The libavcodec codecs we support, and the IDs they have in the file */
extern const AVCodecTag ff_codec_rso_tags[];
#endif /* AVFORMAT_RSO_H */
diff --git a/libavformat/rsodec.c b/libavformat/rsodec.c
index 98de8fe..54a3faa 100644
--- a/libavformat/rsodec.c
+++ b/libavformat/rsodec.c
@@ -54,7 +54,7 @@ static int rso_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
/* now we are ready: build format streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -65,7 +65,7 @@ static int rso_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->channels = 1;
st->codec->sample_rate = rate;
- av_set_pts_info(st, 64, 1, rate);
+ avpriv_set_pts_info(st, 64, 1, rate);
return 0;
}
@@ -92,11 +92,8 @@ AVInputFormat ff_rso_demuxer = {
.name = "rso",
.long_name = NULL_IF_CONFIG_SMALL("Lego Mindstorms RSO format"),
.extensions = "rso",
- .priv_data_size = 0,
- .read_probe = NULL, /* no magic value in this format */
.read_header = rso_read_header,
.read_packet = rso_read_packet,
- .read_close = NULL,
.read_seek = pcm_read_seek,
.codec_tag = (const AVCodecTag* const []){ff_codec_rso_tags, 0},
};
diff --git a/libavformat/rsoenc.c b/libavformat/rsoenc.c
index 338ecf0..f338d0d 100644
--- a/libavformat/rsoenc.c
+++ b/libavformat/rsoenc.c
@@ -104,7 +104,6 @@ AVOutputFormat ff_rso_muxer = {
.name = "rso",
.long_name = NULL_IF_CONFIG_SMALL("Lego Mindstorms RSO format"),
.extensions = "rso",
- .priv_data_size = 0,
.audio_codec = CODEC_ID_PCM_U8,
.video_codec = CODEC_ID_NONE,
.write_header = rso_write_header,
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 35ef7fd..8c455a0 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -21,6 +21,7 @@
#include "libavcodec/bytestream.h"
#include "libavutil/avstring.h"
+#include "libavutil/intfloat.h"
#include "avformat.h"
#include "rtmppkt.h"
@@ -36,7 +37,7 @@ void ff_amf_write_bool(uint8_t **dst, int val)
void ff_amf_write_number(uint8_t **dst, double val)
{
bytestream_put_byte(dst, AMF_DATA_TYPE_NUMBER);
- bytestream_put_be64(dst, av_dbl2int(val));
+ bytestream_put_be64(dst, av_double2int(val));
}
void ff_amf_write_string(uint8_t **dst, const char *str)
@@ -317,7 +318,7 @@ int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end,
if (size == namelen && !memcmp(data-size, name, namelen)) {
switch (*data++) {
case AMF_DATA_TYPE_NUMBER:
- snprintf(dst, dst_size, "%g", av_int2dbl(AV_RB64(data)));
+ snprintf(dst, dst_size, "%g", av_int2double(AV_RB64(data)));
break;
case AMF_DATA_TYPE_BOOL:
snprintf(dst, dst_size, "%s", *data ? "true" : "false");
@@ -369,7 +370,7 @@ static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *d
return;
switch (*data++) {
case AMF_DATA_TYPE_NUMBER:
- av_log(ctx, AV_LOG_DEBUG, " number %g\n", av_int2dbl(AV_RB64(data)));
+ av_log(ctx, AV_LOG_DEBUG, " number %g\n", av_int2double(AV_RB64(data)));
return;
case AMF_DATA_TYPE_BOOL:
av_log(ctx, AV_LOG_DEBUG, " bool %d\n", *data);
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index f499bd3..53d912e 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -26,6 +26,7 @@
#include "libavcodec/bytestream.h"
#include "libavutil/avstring.h"
+#include "libavutil/intfloat.h"
#include "libavutil/lfg.h"
#include "libavutil/sha.h"
#include "avformat.h"
@@ -70,6 +71,11 @@ typedef struct RTMPContext {
uint32_t client_report_size; ///< number of bytes after which client should report to server
uint32_t bytes_read; ///< number of bytes read from server
uint32_t last_bytes_read; ///< number of bytes read last reported to server
+ int skip_bytes; ///< number of bytes to skip from the input FLV stream in the next write call
+ uint8_t flv_header[11]; ///< partial incoming flv packet header
+ int flv_header_bytes; ///< number of initialized bytes in flv_header
+ int nb_invokes; ///< keeps track of invoke messages
+ int create_stream_invoke; ///< invoke id for the create stream command
} RTMPContext;
#define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing
@@ -110,7 +116,7 @@ static void gen_connect(URLContext *s, RTMPContext *rt, const char *proto,
ff_url_join(tcurl, sizeof(tcurl), proto, NULL, host, port, "/%s", rt->app);
ff_amf_write_string(&p, "connect");
- ff_amf_write_number(&p, 1.0);
+ ff_amf_write_number(&p, ++rt->nb_invokes);
ff_amf_write_object_start(&p);
ff_amf_write_field_name(&p, "app");
ff_amf_write_string(&p, rt->app);
@@ -162,7 +168,7 @@ static void gen_release_stream(URLContext *s, RTMPContext *rt)
av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
p = pkt.data;
ff_amf_write_string(&p, "releaseStream");
- ff_amf_write_number(&p, 2.0);
+ ff_amf_write_number(&p, ++rt->nb_invokes);
ff_amf_write_null(&p);
ff_amf_write_string(&p, rt->playpath);
@@ -185,7 +191,7 @@ static void gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
p = pkt.data;
ff_amf_write_string(&p, "FCPublish");
- ff_amf_write_number(&p, 3.0);
+ ff_amf_write_number(&p, ++rt->nb_invokes);
ff_amf_write_null(&p);
ff_amf_write_string(&p, rt->playpath);
@@ -208,7 +214,7 @@ static void gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
p = pkt.data;
ff_amf_write_string(&p, "FCUnpublish");
- ff_amf_write_number(&p, 5.0);
+ ff_amf_write_number(&p, ++rt->nb_invokes);
ff_amf_write_null(&p);
ff_amf_write_string(&p, rt->playpath);
@@ -230,8 +236,9 @@ static void gen_create_stream(URLContext *s, RTMPContext *rt)
p = pkt.data;
ff_amf_write_string(&p, "createStream");
- ff_amf_write_number(&p, rt->is_input ? 3.0 : 4.0);
+ ff_amf_write_number(&p, ++rt->nb_invokes);
ff_amf_write_null(&p);
+ rt->create_stream_invoke = rt->nb_invokes;
ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
@@ -252,7 +259,7 @@ static void gen_delete_stream(URLContext *s, RTMPContext *rt)
p = pkt.data;
ff_amf_write_string(&p, "deleteStream");
- ff_amf_write_number(&p, 0.0);
+ ff_amf_write_number(&p, ++rt->nb_invokes);
ff_amf_write_null(&p);
ff_amf_write_number(&p, rt->main_channel_id);
@@ -276,7 +283,7 @@ static void gen_play(URLContext *s, RTMPContext *rt)
p = pkt.data;
ff_amf_write_string(&p, "play");
- ff_amf_write_number(&p, 0.0);
+ ff_amf_write_number(&p, ++rt->nb_invokes);
ff_amf_write_null(&p);
ff_amf_write_string(&p, rt->playpath);
@@ -310,7 +317,7 @@ static void gen_publish(URLContext *s, RTMPContext *rt)
p = pkt.data;
ff_amf_write_string(&p, "publish");
- ff_amf_write_number(&p, 0.0);
+ ff_amf_write_number(&p, ++rt->nb_invokes);
ff_amf_write_null(&p);
ff_amf_write_string(&p, rt->playpath);
ff_amf_write_string(&p, "live");
@@ -608,8 +615,8 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
/* hack for Wowza Media Server, it does not send result for
* releaseStream and FCPublish calls */
if (!pkt->data[10]) {
- int pkt_id = (int) av_int2dbl(AV_RB64(pkt->data + 11));
- if (pkt_id == 4)
+ int pkt_id = av_int2double(AV_RB64(pkt->data + 11));
+ if (pkt_id == rt->create_stream_invoke)
rt->state = STATE_CONNECTING;
}
if (rt->state != STATE_CONNECTING)
@@ -619,7 +626,7 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
} else {
- rt->main_channel_id = (int) av_int2dbl(AV_RB64(pkt->data + 21));
+ rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
}
if (rt->is_input) {
gen_play(s, rt);
@@ -761,7 +768,6 @@ static int get_packet(URLContext *s, int for_header)
}
ff_rtmp_packet_destroy(&rpkt);
}
- return 0;
}
static int rtmp_close(URLContext *h)
@@ -780,7 +786,6 @@ static int rtmp_close(URLContext *h)
av_freep(&rt->flv_data);
ffurl_close(rt->stream);
- av_free(rt);
return 0;
}
@@ -795,16 +800,12 @@ static int rtmp_close(URLContext *h)
*/
static int rtmp_open(URLContext *s, const char *uri, int flags)
{
- RTMPContext *rt;
+ RTMPContext *rt = s->priv_data;
char proto[8], hostname[256], path[1024], *fname;
uint8_t buf[2048];
int port;
int ret;
- rt = av_mallocz(sizeof(RTMPContext));
- if (!rt)
- return AVERROR(ENOMEM);
- s->priv_data = rt;
rt->is_input = !(flags & AVIO_FLAG_WRITE);
av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
@@ -814,14 +815,15 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
port = RTMP_DEFAULT_PORT;
ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
- if (ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE) < 0) {
+ if (ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
+ &s->interrupt_callback, NULL) < 0) {
av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
goto fail;
}
rt->state = STATE_START;
if (rtmp_handshake(s, rt))
- return -1;
+ goto fail;
rt->chunk_size = 128;
rt->state = STATE_HANDSHAKED;
@@ -879,6 +881,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
rt->flv_size = 0;
rt->flv_data = NULL;
rt->flv_off = 0;
+ rt->skip_bytes = 13;
}
s->max_packet_size = rt->stream->max_packet_size;
@@ -925,25 +928,29 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
uint32_t ts;
const uint8_t *buf_temp = buf;
- if (size < 11) {
- av_log(s, AV_LOG_DEBUG, "FLV packet too small %d\n", size);
- return 0;
- }
-
do {
- if (!rt->flv_off) {
- //skip flv header
- if (buf_temp[0] == 'F' && buf_temp[1] == 'L' && buf_temp[2] == 'V') {
- buf_temp += 9 + 4;
- size_temp -= 9 + 4;
- }
+ if (rt->skip_bytes) {
+ int skip = FFMIN(rt->skip_bytes, size_temp);
+ buf_temp += skip;
+ size_temp -= skip;
+ rt->skip_bytes -= skip;
+ continue;
+ }
+
+ if (rt->flv_header_bytes < 11) {
+ const uint8_t *header = rt->flv_header;
+ int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
+ bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
+ rt->flv_header_bytes += copy;
+ size_temp -= copy;
+ if (rt->flv_header_bytes < 11)
+ break;
- pkttype = bytestream_get_byte(&buf_temp);
- pktsize = bytestream_get_be24(&buf_temp);
- ts = bytestream_get_be24(&buf_temp);
- ts |= bytestream_get_byte(&buf_temp) << 24;
- bytestream_get_be24(&buf_temp);
- size_temp -= 11;
+ pkttype = bytestream_get_byte(&header);
+ pktsize = bytestream_get_be24(&header);
+ ts = bytestream_get_be24(&header);
+ ts |= bytestream_get_byte(&header) << 24;
+ bytestream_get_be24(&header);
rt->flv_size = pktsize;
//force 12bytes header
@@ -966,27 +973,31 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
if (rt->flv_size - rt->flv_off > size_temp) {
bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
rt->flv_off += size_temp;
+ size_temp = 0;
} else {
bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
+ size_temp -= rt->flv_size - rt->flv_off;
rt->flv_off += rt->flv_size - rt->flv_off;
}
if (rt->flv_off == rt->flv_size) {
- bytestream_get_be32(&buf_temp);
+ rt->skip_bytes = 4;
ff_rtmp_packet_write(rt->stream, &rt->out_pkt, rt->chunk_size, rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&rt->out_pkt);
rt->flv_size = 0;
rt->flv_off = 0;
+ rt->flv_header_bytes = 0;
}
- } while (buf_temp - buf < size_temp);
+ } while (buf_temp - buf < size);
return size;
}
URLProtocol ff_rtmp_protocol = {
- .name = "rtmp",
- .url_open = rtmp_open,
- .url_read = rtmp_read,
- .url_write = rtmp_write,
- .url_close = rtmp_close,
+ .name = "rtmp",
+ .url_open = rtmp_open,
+ .url_read = rtmp_read,
+ .url_write = rtmp_write,
+ .url_close = rtmp_close,
+ .priv_data_size = sizeof(RTMPContext),
};
diff --git a/libavformat/rtp.c b/libavformat/rtp.c
index d59b694..b6b4b72 100644
--- a/libavformat/rtp.c
+++ b/libavformat/rtp.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <libavutil/opt.h>
#include "avformat.h"
#include "rtp.h"
@@ -89,21 +90,32 @@ int ff_rtp_get_codec_info(AVCodecContext *codec, int payload_type)
return -1;
}
-int ff_rtp_get_payload_type(AVCodecContext *codec)
+int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec)
{
- int i, payload_type;
+ int i;
+ AVOutputFormat *ofmt = fmt ? fmt->oformat : NULL;
+
+ /* Was the payload type already specified for the RTP muxer? */
+ if (ofmt && ofmt->priv_class) {
+ int64_t payload_type;
+ if (av_opt_get_int(fmt->priv_data, "payload_type", 0, &payload_type) >= 0 &&
+ payload_type >= 0)
+ return (int)payload_type;
+ }
- /* compute the payload type */
- for (payload_type = -1, i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
+ /* static payload type */
+ for (i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
if (AVRtpPayloadTypes[i].codec_id == codec->codec_id) {
if (codec->codec_id == CODEC_ID_H263)
continue;
if (codec->codec_id == CODEC_ID_PCM_S16BE)
if (codec->channels != AVRtpPayloadTypes[i].audio_channels)
continue;
- payload_type = AVRtpPayloadTypes[i].pt;
+ return AVRtpPayloadTypes[i].pt;
}
- return payload_type;
+
+ /* dynamic payload type */
+ return RTP_PT_PRIVATE + (codec->codec_type == AVMEDIA_TYPE_AUDIO);
}
const char *ff_rtp_enc_name(int payload_type)
diff --git a/libavformat/rtp.h b/libavformat/rtp.h
index 36157ce..e619008 100644
--- a/libavformat/rtp.h
+++ b/libavformat/rtp.h
@@ -21,17 +21,17 @@
#ifndef AVFORMAT_RTP_H
#define AVFORMAT_RTP_H
+#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
/**
- * Return the payload type for a given codec.
+ * Return the payload type for a given codec used in the given format context.
*
+ * @param fmt The context of the format
* @param codec The context of the codec
- * @return In case of unknown payload type or dynamic payload type, a
- * negative value is returned; otherwise, the payload type (the 'PT' field
- * in the RTP header) is returned.
+ * @return The payload type (the 'PT' field in the RTP header).
*/
-int ff_rtp_get_payload_type(AVCodecContext *codec);
+int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec);
/**
* Initialize a codec context based on the payload type.
@@ -72,7 +72,7 @@ enum CodecID ff_rtp_codec_id(const char *buf, enum AVMediaType codec_type);
#define RTP_VERSION 2
#define RTP_MAX_SDES 256 /**< maximum text length for SDES */
-/* RTCP paquets use 0.5 % of the bandwidth */
+/* RTCP packets use 0.5% of the bandwidth */
#define RTCP_TX_RATIO_NUM 5
#define RTCP_TX_RATIO_DEN 1000
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index a910cf0..7e8b52a 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -19,13 +19,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/mathematics.h"
+#include "libavutil/avstring.h"
#include "libavcodec/get_bits.h"
#include "avformat.h"
#include "mpegts.h"
#include "url.h"
#include <unistd.h>
-#include <strings.h>
#include "network.h"
#include "rtpdec.h"
@@ -82,6 +83,11 @@ void av_register_rtp_dynamic_payload_handlers(void)
ff_register_dynamic_payload_handler(&ff_qt_rtp_vid_handler);
ff_register_dynamic_payload_handler(&ff_quicktime_rtp_aud_handler);
ff_register_dynamic_payload_handler(&ff_quicktime_rtp_vid_handler);
+
+ ff_register_dynamic_payload_handler(&ff_g726_16_dynamic_handler);
+ ff_register_dynamic_payload_handler(&ff_g726_24_dynamic_handler);
+ ff_register_dynamic_payload_handler(&ff_g726_32_dynamic_handler);
+ ff_register_dynamic_payload_handler(&ff_g726_40_dynamic_handler);
}
RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name,
@@ -90,7 +96,7 @@ RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name,
RTPDynamicProtocolHandler *handler;
for (handler = RTPFirstDynamicPayloadHandler;
handler; handler = handler->next)
- if (!strcasecmp(name, handler->enc_name) &&
+ if (!av_strcasecmp(name, handler->enc_name) &&
codec_type == handler->codec_type)
return handler;
return NULL;
@@ -111,14 +117,15 @@ RTPDynamicProtocolHandler *ff_rtp_handler_find_by_id(int id,
static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)
{
int payload_len;
- while (len >= 2) {
+ while (len >= 4) {
+ payload_len = FFMIN(len, (AV_RB16(buf + 2) + 1) * 4);
+
switch (buf[1]) {
case RTCP_SR:
- if (len < 16) {
+ if (payload_len < 20) {
av_log(NULL, AV_LOG_ERROR, "Invalid length for RTCP SR packet\n");
return AVERROR_INVALIDDATA;
}
- payload_len = (AV_RB16(buf + 2) + 1) * 4;
s->last_rtcp_ntp_time = AV_RB64(buf + 8);
s->last_rtcp_timestamp = AV_RB32(buf + 16);
@@ -129,14 +136,13 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l
s->rtcp_ts_offset = s->last_rtcp_timestamp - s->base_timestamp;
}
- buf += payload_len;
- len -= payload_len;
break;
case RTCP_BYE:
return -RTCP_BYE;
- default:
- return -1;
}
+
+ buf += payload_len;
+ len -= payload_len;
}
return -1;
}
@@ -217,23 +223,7 @@ static int rtp_valid_packet_in_sequence(RTPStatistics *s, uint16_t seq)
return 1;
}
-#if 0
-/**
-* This function is currently unused; without a valid local ntp time, I don't see how we could calculate the
-* difference between the arrival and sent timestamp. As a result, the jitter and transit statistics values
-* never change. I left this in in case someone else can see a way. (rdm)
-*/
-static void rtcp_update_jitter(RTPStatistics *s, uint32_t sent_timestamp, uint32_t arrival_timestamp)
-{
- uint32_t transit= arrival_timestamp - sent_timestamp;
- int d;
- s->transit= transit;
- d= FFABS(transit - s->transit);
- s->jitter += d - ((s->jitter + 8)>>4);
-}
-#endif
-
-int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
+int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
{
AVIOContext *pb;
uint8_t *buf;
@@ -330,7 +320,7 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
return 0;
}
-void rtp_send_punch_packets(URLContext* rtp_handle)
+void ff_rtp_send_punch_packets(URLContext* rtp_handle)
{
AVIOContext *pb;
uint8_t *buf;
@@ -374,7 +364,7 @@ void rtp_send_punch_packets(URLContext* rtp_handle)
* MPEG2TS streams to indicate that they should be demuxed inside the
* rtp demux (otherwise CODEC_ID_MPEG2TS packets are returned)
*/
-RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, int queue_size)
+RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, int queue_size)
{
RTPDemuxContext *s;
@@ -422,8 +412,8 @@ RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *r
}
void
-rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
- RTPDynamicProtocolHandler *handler)
+ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
+ RTPDynamicProtocolHandler *handler)
{
s->dynamic_protocol_context = ctx;
s->parse_packet = handler->parse_packet;
@@ -436,7 +426,10 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
{
if (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE)
return; /* Timestamp already set by depacketizer */
- if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && timestamp != RTP_NOTS_VALUE) {
+ if (timestamp == RTP_NOTS_VALUE)
+ return;
+
+ if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && s->ic->nb_streams > 1) {
int64_t addend;
int delta_timestamp;
@@ -448,11 +441,16 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
delta_timestamp;
return;
}
- if (timestamp == RTP_NOTS_VALUE)
- return;
+
if (!s->base_timestamp)
s->base_timestamp = timestamp;
- pkt->pts = s->range_start_offset + timestamp - s->base_timestamp;
+ /* assume that the difference is INT32_MIN < x < INT32_MAX, but allow the first timestamp to exceed INT32_MAX */
+ if (!s->timestamp)
+ s->unwrapped_timestamp += timestamp;
+ else
+ s->unwrapped_timestamp += (int32_t)(timestamp - s->timestamp);
+ s->timestamp = timestamp;
+ pkt->pts = s->unwrapped_timestamp + s->range_start_offset - s->base_timestamp;
}
static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt,
@@ -737,8 +735,8 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
* @return 0 if a packet is returned, 1 if a packet is returned and more can follow
* (use buf as NULL to read the next). -1 if no packet (error or no more packet).
*/
-int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
- uint8_t **bufptr, int len)
+int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
+ uint8_t **bufptr, int len)
{
int rv = rtp_parse_one_packet(s, pkt, bufptr, len);
s->prev_ret = rv;
@@ -747,7 +745,7 @@ int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
return rv ? rv : has_next_packet(s);
}
-void rtp_parse_close(RTPDemuxContext *s)
+void ff_rtp_parse_close(RTPDemuxContext *s)
{
ff_rtp_reset_packet_queue(s);
if (!strcmp(ff_rtp_enc_name(s->payload_type), "MP2T")) {
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index a4d21aa..9e2bfd0 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -38,18 +38,18 @@ typedef struct RTPDynamicProtocolHandler_s RTPDynamicProtocolHandler;
#define RTP_NOTS_VALUE ((uint32_t)-1)
typedef struct RTPDemuxContext RTPDemuxContext;
-RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, int queue_size);
-void rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
- RTPDynamicProtocolHandler *handler);
-int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
- uint8_t **buf, int len);
-void rtp_parse_close(RTPDemuxContext *s);
+RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, int queue_size);
+void ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
+ RTPDynamicProtocolHandler *handler);
+int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
+ uint8_t **buf, int len);
+void ff_rtp_parse_close(RTPDemuxContext *s);
int64_t ff_rtp_queued_packet_time(RTPDemuxContext *s);
void ff_rtp_reset_packet_queue(RTPDemuxContext *s);
-int rtp_get_local_rtp_port(URLContext *h);
-int rtp_get_local_rtcp_port(URLContext *h);
+int ff_rtp_get_local_rtp_port(URLContext *h);
+int ff_rtp_get_local_rtcp_port(URLContext *h);
-int rtp_set_remote_url(URLContext *h, const char *uri);
+int ff_rtp_set_remote_url(URLContext *h, const char *uri);
/**
* Send a dummy packet on both port pairs to set up the connection
@@ -62,19 +62,19 @@ int rtp_set_remote_url(URLContext *h, const char *uri);
* The same routine is used with RDT too, even if RDT doesn't use normal
* RTP packets otherwise.
*/
-void rtp_send_punch_packets(URLContext* rtp_handle);
+void ff_rtp_send_punch_packets(URLContext* rtp_handle);
/**
* some rtp servers assume client is dead if they don't hear from them...
* so we send a Receiver Report to the provided ByteIO context
* (we don't have access to the rtcp handle from here)
*/
-int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count);
+int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, int count);
/**
* Get the file handle for the RTCP socket.
*/
-int rtp_get_rtcp_file_handle(URLContext *h);
+int ff_rtp_get_rtcp_file_handle(URLContext *h);
// these statistics are used for rtcp receiver reports...
typedef struct {
@@ -122,6 +122,7 @@ struct RTPDynamicProtocolHandler_s {
* require any custom depacketization code. */
// may be null
+ int (*init)(AVFormatContext *s, int st_index, PayloadContext *priv_data); ///< Initialize dynamic protocol handler, called after the full rtpmap line is parsed
int (*parse_sdp_a_line) (AVFormatContext *s,
int st_index,
PayloadContext *priv_data,
@@ -151,6 +152,7 @@ struct RTPDemuxContext {
uint32_t timestamp;
uint32_t base_timestamp;
uint32_t cur_timestamp;
+ int64_t unwrapped_timestamp;
int64_t range_start_offset;
int max_payload_size;
struct MpegTSContext *ts; /* only used for MP2T payloads */
diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c
index 287025f..483b196 100644
--- a/libavformat/rtpdec_asf.c
+++ b/libavformat/rtpdec_asf.c
@@ -33,6 +33,7 @@
#include "rtsp.h"
#include "asf.h"
#include "avio_internal.h"
+#include "internal.h"
/**
* From MSDN 2.2.1.4, we learn that ASF data packets over RTP should not
@@ -107,8 +108,7 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
"Failed to fix invalid RTSP-MS/ASF min_pktsize\n");
init_packetizer(&pb, buf, len);
if (rt->asf_ctx) {
- av_close_input_file(rt->asf_ctx);
- rt->asf_ctx = NULL;
+ avformat_close_input(&rt->asf_ctx);
}
if (!(rt->asf_ctx = avformat_alloc_context()))
return AVERROR(ENOMEM);
@@ -141,7 +141,7 @@ static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index,
*rt->asf_ctx->streams[i]->codec;
rt->asf_ctx->streams[i]->codec->extradata_size = 0;
rt->asf_ctx->streams[i]->codec->extradata = NULL;
- av_set_pts_info(s->streams[stream_index], 32, 1, 1000);
+ avpriv_set_pts_info(s->streams[stream_index], 32, 1, 1000);
}
}
}
@@ -233,8 +233,14 @@ static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
int cur_len = start_off + len_off - off;
int prev_len = out_len;
+ void *newmem;
out_len += cur_len;
- asf->buf = av_realloc(asf->buf, out_len);
+ if (FFMIN(cur_len, len - off) < 0)
+ return -1;
+ newmem = av_realloc(asf->buf, out_len);
+ if (!newmem)
+ return -1;
+ asf->buf = newmem;
memcpy(asf->buf + prev_len, buf + off,
FFMIN(cur_len, len - off));
avio_skip(pb, cur_len);
diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h
index 708c299..3074565 100644
--- a/libavformat/rtpdec_formats.h
+++ b/libavformat/rtpdec_formats.h
@@ -33,6 +33,10 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p);
extern RTPDynamicProtocolHandler ff_amr_nb_dynamic_handler;
extern RTPDynamicProtocolHandler ff_amr_wb_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_g726_16_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_g726_24_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_g726_32_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_g726_40_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h264_dynamic_handler;
diff --git a/libavformat/rtpdec_g726.c b/libavformat/rtpdec_g726.c
new file mode 100644
index 0000000..4a0b6ac
--- /dev/null
+++ b/libavformat/rtpdec_g726.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011 Miroslav Slugeň <Thunder.m at seznam.cz>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "rtpdec_formats.h"
+
+#define RTP_G726_HANDLER(bitrate) \
+static int g726_ ## bitrate ##_init(AVFormatContext *s, int st_index, PayloadContext *data) \
+{ \
+ AVStream *stream = s->streams[st_index]; \
+ AVCodecContext *codec = stream->codec; \
+\
+ codec->bits_per_coded_sample = bitrate/8; \
+ codec->bit_rate = codec->bits_per_coded_sample * codec->sample_rate; \
+\
+ return 0; \
+} \
+\
+RTPDynamicProtocolHandler ff_g726_ ## bitrate ## _dynamic_handler = { \
+ .enc_name = "G726-" #bitrate, \
+ .codec_type = AVMEDIA_TYPE_AUDIO, \
+ .codec_id = CODEC_ID_ADPCM_G726, \
+ .init = g726_ ## bitrate ## _init, \
+}
+
+RTP_G726_HANDLER(16);
+RTP_G726_HANDLER(24);
+RTP_G726_HANDLER(32);
+RTP_G726_HANDLER(40);
diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c
index 42317a9..96f4e83 100644
--- a/libavformat/rtpdec_latm.c
+++ b/libavformat/rtpdec_latm.c
@@ -23,7 +23,6 @@
#include "internal.h"
#include "libavutil/avstring.h"
#include "libavcodec/get_bits.h"
-#include <strings.h>
struct PayloadContext {
AVIOContext *dyn_buf;
diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c
index 7a63cc3..b143c1a 100644
--- a/libavformat/rtpdec_mpeg4.c
+++ b/libavformat/rtpdec_mpeg4.c
@@ -31,7 +31,6 @@
#include "internal.h"
#include "libavutil/avstring.h"
#include "libavcodec/get_bits.h"
-#include <strings.h>
/** Structure listing useful vars to parse RTP packet payload*/
struct PayloadContext
@@ -206,7 +205,7 @@ static int parse_fmtp(AVStream *stream, PayloadContext *data,
if (codec->codec_id == CODEC_ID_AAC) {
/* Looking for a known attribute */
for (i = 0; attr_names[i].str; ++i) {
- if (!strcasecmp(attr, attr_names[i].str)) {
+ if (!av_strcasecmp(attr, attr_names[i].str)) {
if (attr_names[i].type == ATTR_NAME_TYPE_INT) {
*(int *)((char *)data+
attr_names[i].offset) = atoi(value);
@@ -235,9 +234,6 @@ RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler = {
.codec_type = AVMEDIA_TYPE_VIDEO,
.codec_id = CODEC_ID_MPEG4,
.parse_sdp_a_line = parse_sdp_line,
- .alloc = NULL,
- .free = NULL,
- .parse_packet = NULL
};
RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler = {
diff --git a/libavformat/rtpdec_qdm2.c b/libavformat/rtpdec_qdm2.c
index 66dd874..76b4c53 100644
--- a/libavformat/rtpdec_qdm2.c
+++ b/libavformat/rtpdec_qdm2.c
@@ -52,8 +52,8 @@ struct PayloadContext {
};
/**
- * Parses configuration (basically the codec-specific extradata) from
- * a RTP config subpacket (starts with 0xff).
+ * Parse configuration (basically the codec-specific extradata) from
+ * an RTP config subpacket (starts with 0xff).
*
* Layout of the config subpacket (in bytes):
* 1: 0xFF <- config ID
@@ -128,7 +128,7 @@ static int qdm2_parse_config(PayloadContext *qdm, AVStream *st,
}
/**
- * Parses a single subpacket. We store this subpacket in an intermediate
+ * Parse a single subpacket. We store this subpacket in an intermediate
* buffer (position depends on the ID (byte[0]). When called, at least
* 4 bytes are available for reading (see qdm2_parse_packet()).
*
@@ -179,7 +179,7 @@ static int qdm2_parse_subpacket(PayloadContext *qdm, AVStream *st,
}
/**
- * Adds a superblock header around a set of subpackets.
+ * Add a superblock header around a set of subpackets.
*
* @return <0 on error, else 0.
*/
diff --git a/libavformat/rtpdec_qt.c b/libavformat/rtpdec_qt.c
index 8dd2968..1037154 100644
--- a/libavformat/rtpdec_qt.c
+++ b/libavformat/rtpdec_qt.c
@@ -26,6 +26,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "avio_internal.h"
#include "rtp.h"
#include "rtpdec.h"
@@ -110,7 +111,7 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
(st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
tag != MKTAG('s','o','u','n')))
return AVERROR_INVALIDDATA;
- av_set_pts_info(st, 32, 1, avio_rb32(&pb));
+ avpriv_set_pts_info(st, 32, 1, avio_rb32(&pb));
if (pos + data_len > len)
return AVERROR_INVALIDDATA;
diff --git a/libavformat/rtpdec_svq3.c b/libavformat/rtpdec_svq3.c
index 3314342..4df3e3a 100644
--- a/libavformat/rtpdec_svq3.c
+++ b/libavformat/rtpdec_svq3.c
@@ -22,8 +22,8 @@
/**
* @file
* @brief RTP support for the SV3V (SVQ3) payload
- * (http://wiki.multimedia.cx/index.php?title=Sorenson_Video_3#Packetization)
* @author Ronald S. Bultje <rbultje at ronald.bitfreak.net>
+ * @see http://wiki.multimedia.cx/index.php?title=Sorenson_Video_3#Packetization
*/
#include <string.h>
diff --git a/libavformat/rtpdec_vp8.c b/libavformat/rtpdec_vp8.c
index 026728e..d13c398 100644
--- a/libavformat/rtpdec_vp8.c
+++ b/libavformat/rtpdec_vp8.c
@@ -23,7 +23,7 @@
* @file
* @brief RTP support for the VP8 payload
* @author Josh Allmann <joshua.allmann at gmail.com>
- * ( http://www.webmproject.org/code/specs/rtp/ )
+ * @see http://www.webmproject.org/code/specs/rtp/
*/
#include "libavcodec/bytestream.h"
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index 3da6dfb..1f036a6 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -22,6 +22,7 @@
#include "avformat.h"
#include "mpegts.h"
#include "internal.h"
+#include "libavutil/mathematics.h"
#include "libavutil/random_seed.h"
#include "libavutil/opt.h"
@@ -31,6 +32,7 @@
static const AVOption options[] = {
FF_RTP_FLAG_OPTS(RTPMuxContext, flags),
+ { "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.dbl = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM },
{ NULL },
};
@@ -70,6 +72,7 @@ static int is_supported(enum CodecID id)
case CODEC_ID_THEORA:
case CODEC_ID_VP8:
case CODEC_ID_ADPCM_G722:
+ case CODEC_ID_ADPCM_G726:
return 1;
default:
return 0;
@@ -91,10 +94,8 @@ static int rtp_write_header(AVFormatContext *s1)
return -1;
}
- s->payload_type = ff_rtp_get_payload_type(st->codec);
if (s->payload_type < 0)
- s->payload_type = RTP_PT_PRIVATE + (st->codec->codec_type == AVMEDIA_TYPE_AUDIO);
-
+ s->payload_type = ff_rtp_get_payload_type(s1, st->codec);
s->base_timestamp = av_get_random_seed();
s->timestamp = s->base_timestamp;
s->cur_timestamp = 0;
@@ -121,7 +122,7 @@ static int rtp_write_header(AVFormatContext *s1)
if (st->codec->frame_size == 0) {
av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n");
} else {
- s->max_frames_per_packet = av_rescale_rnd(s1->max_delay, st->codec->sample_rate, AV_TIME_BASE * st->codec->frame_size, AV_ROUND_DOWN);
+ s->max_frames_per_packet = av_rescale_rnd(s1->max_delay, st->codec->sample_rate, AV_TIME_BASE * (int64_t)st->codec->frame_size, AV_ROUND_DOWN);
}
}
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -130,7 +131,7 @@ static int rtp_write_header(AVFormatContext *s1)
}
}
- av_set_pts_info(st, 32, 1, 90000);
+ avpriv_set_pts_info(st, 32, 1, 90000);
switch(st->codec->codec_id) {
case CODEC_ID_MP2:
case CODEC_ID_MP3:
@@ -166,7 +167,7 @@ static int rtp_write_header(AVFormatContext *s1)
case CODEC_ID_ADPCM_G722:
/* Due to a historical error, the clock rate for G722 in RTP is
* 8000, even if the sample rate is 16000. See RFC 3551. */
- av_set_pts_info(st, 32, 1, 8000);
+ avpriv_set_pts_info(st, 32, 1, 8000);
break;
case CODEC_ID_AMR_NB:
case CODEC_ID_AMR_WB:
@@ -190,7 +191,7 @@ static int rtp_write_header(AVFormatContext *s1)
default:
defaultcase:
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- av_set_pts_info(st, 32, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);
}
s->buf_ptr = s->buf;
break;
@@ -248,14 +249,16 @@ void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
/* send an integer number of samples and compute time stamp and fill
the rtp send buffer before sending. */
static void rtp_send_samples(AVFormatContext *s1,
- const uint8_t *buf1, int size, int sample_size)
+ const uint8_t *buf1, int size, int sample_size_bits)
{
RTPMuxContext *s = s1->priv_data;
int len, max_packet_size, n;
+ /* Calculate the number of bytes to get samples aligned on a byte border */
+ int aligned_samples_size = sample_size_bits/av_gcd(sample_size_bits, 8);
- max_packet_size = (s->max_payload_size / sample_size) * sample_size;
- /* not needed, but who nows */
- if ((size % sample_size) != 0)
+ max_packet_size = (s->max_payload_size / aligned_samples_size) * aligned_samples_size;
+ /* Not needed, but who knows. Don't check if samples aren't an even number of bytes. */
+ if ((sample_size_bits % 8) == 0 && ((8 * size) % sample_size_bits) != 0)
av_abort();
n = 0;
while (size > 0) {
@@ -267,7 +270,7 @@ static void rtp_send_samples(AVFormatContext *s1,
s->buf_ptr += len;
buf1 += len;
size -= len;
- s->timestamp = s->cur_timestamp + n / sample_size;
+ s->timestamp = s->cur_timestamp + n * 8 / sample_size_bits;
ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
n += (s->buf_ptr - s->buf);
}
@@ -394,19 +397,24 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
case CODEC_ID_PCM_ALAW:
case CODEC_ID_PCM_U8:
case CODEC_ID_PCM_S8:
- rtp_send_samples(s1, pkt->data, size, 1 * st->codec->channels);
+ rtp_send_samples(s1, pkt->data, size, 8 * st->codec->channels);
break;
case CODEC_ID_PCM_U16BE:
case CODEC_ID_PCM_U16LE:
case CODEC_ID_PCM_S16BE:
case CODEC_ID_PCM_S16LE:
- rtp_send_samples(s1, pkt->data, size, 2 * st->codec->channels);
+ rtp_send_samples(s1, pkt->data, size, 16 * st->codec->channels);
break;
case CODEC_ID_ADPCM_G722:
/* The actual sample size is half a byte per sample, but since the
* stream clock rate is 8000 Hz while the sample rate is 16000 Hz,
- * the correct parameter for send_samples is 1 byte per stream clock. */
- rtp_send_samples(s1, pkt->data, size, 1 * st->codec->channels);
+ * the correct parameter for send_samples_bits is 8 bits per stream
+ * clock. */
+ rtp_send_samples(s1, pkt->data, size, 8 * st->codec->channels);
+ break;
+ case CODEC_ID_ADPCM_G726:
+ rtp_send_samples(s1, pkt->data, size,
+ st->codec->bits_per_coded_sample * st->codec->channels);
break;
case CODEC_ID_MP2:
case CODEC_ID_MP3:
@@ -461,15 +469,13 @@ static int rtp_write_trailer(AVFormatContext *s1)
}
AVOutputFormat ff_rtp_muxer = {
- "rtp",
- NULL_IF_CONFIG_SMALL("RTP output format"),
- NULL,
- NULL,
- sizeof(RTPMuxContext),
- CODEC_ID_PCM_MULAW,
- CODEC_ID_NONE,
- rtp_write_header,
- rtp_write_packet,
- rtp_write_trailer,
+ .name = "rtp",
+ .long_name = NULL_IF_CONFIG_SMALL("RTP output format"),
+ .priv_data_size = sizeof(RTPMuxContext),
+ .audio_codec = CODEC_ID_PCM_MULAW,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = rtp_write_header,
+ .write_packet = rtp_write_packet,
+ .write_trailer = rtp_write_trailer,
.priv_class = &rtp_muxer_class,
};
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index 3a9e19b..72d7f65 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -66,8 +66,8 @@ typedef struct RTPMuxContext RTPMuxContext;
#define FF_RTP_FLAG_MP4A_LATM 1
#define FF_RTP_FLAG_OPTS(ctx, fieldname) \
- { "rtpflags", "RTP muxer flags", offsetof(ctx, fieldname), FF_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
- { "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, FF_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" } \
+ { "rtpflags", "RTP muxer flags", offsetof(ctx, fieldname), AV_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
+ { "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, AV_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" } \
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m);
diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
index 0fb47f6..b9d1690 100644
--- a/libavformat/rtpenc_chain.c
+++ b/libavformat/rtpenc_chain.c
@@ -31,6 +31,8 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
AVFormatContext *rtpctx;
int ret;
AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
+ uint8_t *rtpflags;
+ AVDictionary *opts = NULL;
if (!rtp_format)
return NULL;
@@ -41,21 +43,19 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
return NULL;
rtpctx->oformat = rtp_format;
- if (!av_new_stream(rtpctx, 0)) {
+ if (!avformat_new_stream(rtpctx, NULL)) {
av_free(rtpctx);
return NULL;
}
+ /* Pass the interrupt callback on */
+ rtpctx->interrupt_callback = s->interrupt_callback;
/* Copy the max delay setting; the rtp muxer reads this. */
rtpctx->max_delay = s->max_delay;
/* Copy other stream parameters. */
rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio;
- av_set_parameters(rtpctx, NULL);
- /* Copy the rtpflags values straight through */
- if (s->oformat->priv_class &&
- av_find_opt(s->priv_data, "rtpflags", NULL, 0, 0))
- av_set_int(rtpctx->priv_data, "rtpflags",
- av_get_int(s->priv_data, "rtpflags", NULL));
+ if (av_opt_get(s, "rtpflags", AV_OPT_SEARCH_CHILDREN, &rtpflags) >= 0)
+ av_dict_set(&opts, "rtpflags", rtpflags, AV_DICT_DONT_STRDUP_VAL);
/* Set the synchronized start time. */
rtpctx->start_time_realtime = s->start_time_realtime;
@@ -66,7 +66,8 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
ffio_fdopen(&rtpctx->pb, handle);
} else
ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
- ret = avformat_write_header(rtpctx, NULL);
+ ret = avformat_write_header(rtpctx, &opts);
+ av_dict_free(&opts);
if (ret) {
if (handle) {
diff --git a/libavformat/rtpenc_h264.c b/libavformat/rtpenc_h264.c
index 9ca6f7f..776da83 100644
--- a/libavformat/rtpenc_h264.c
+++ b/libavformat/rtpenc_h264.c
@@ -29,6 +29,21 @@
#include "avc.h"
#include "rtpenc.h"
+static const uint8_t *avc_mp4_find_startcode(const uint8_t *start, const uint8_t *end, int nal_length_size)
+{
+ int res = 0;
+
+ if (end - start < nal_length_size)
+ return NULL;
+ while (nal_length_size--)
+ res = (res << 8) | *start++;
+
+ if (start + res > end || res < 0 || start + res < start)
+ return NULL;
+
+ return start + res;
+}
+
static void nal_send(AVFormatContext *s1, const uint8_t *buf, int size, int last)
{
RTPMuxContext *s = s1->priv_data;
@@ -62,17 +77,27 @@ static void nal_send(AVFormatContext *s1, const uint8_t *buf, int size, int last
void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size)
{
- const uint8_t *r;
+ const uint8_t *r, *end = buf1 + size;
RTPMuxContext *s = s1->priv_data;
s->timestamp = s->cur_timestamp;
- r = ff_avc_find_startcode(buf1, buf1 + size);
- while (r < buf1 + size) {
+ if (s->nal_length_size)
+ r = avc_mp4_find_startcode(buf1, end, s->nal_length_size) ? buf1 : end;
+ else
+ r = ff_avc_find_startcode(buf1, end);
+ while (r < end) {
const uint8_t *r1;
- while(!*(r++));
- r1 = ff_avc_find_startcode(r, buf1 + size);
- nal_send(s1, r, r1 - r, (r1 == buf1 + size));
+ if (s->nal_length_size) {
+ r1 = avc_mp4_find_startcode(r, end, s->nal_length_size);
+ if (!r1)
+ r1 = end;
+ r += s->nal_length_size;
+ } else {
+ while (!*(r++));
+ r1 = ff_avc_find_startcode(r, end);
+ }
+ nal_send(s1, r, r1 - r, r1 == end);
r = r1;
}
}
diff --git a/libavformat/rtpenc_mpv.c b/libavformat/rtpenc_mpv.c
index f6a5d77..1c67f95 100644
--- a/libavformat/rtpenc_mpv.c
+++ b/libavformat/rtpenc_mpv.c
@@ -56,7 +56,7 @@ void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size)
r1 = buf1;
while (1) {
start_code = -1;
- r = ff_find_start_code(r1, end, &start_code);
+ r = avpriv_mpv_find_start_code(r1, end, &start_code);
if((start_code & 0xFFFFFF00) == 0x100) {
/* New start code found */
if (start_code == 0x100) {
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index 1340665..93cad3c 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -60,7 +60,7 @@ typedef struct RTPContext {
* @return zero if no error.
*/
-int rtp_set_remote_url(URLContext *h, const char *uri)
+int ff_rtp_set_remote_url(URLContext *h, const char *uri)
{
RTPContext *s = h->priv_data;
char hostname[256];
@@ -86,7 +86,7 @@ int rtp_set_remote_url(URLContext *h, const char *uri)
* "http://host:port/path?option1=val1&option2=val2...
*/
-static void url_add_option(char *buf, int buf_size, const char *fmt, ...)
+static av_printf_format(3, 4) void url_add_option(char *buf, int buf_size, const char *fmt, ...)
{
char buf1[1024];
va_list ap;
@@ -136,7 +136,7 @@ static void build_udp_url(char *buf, int buf_size,
static int rtp_open(URLContext *h, const char *uri, int flags)
{
- RTPContext *s;
+ RTPContext *s = h->priv_data;
int rtp_port, rtcp_port,
ttl, connect,
local_rtp_port, local_rtcp_port, max_packet_size;
@@ -145,11 +145,6 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
char path[1024];
const char *p;
- s = av_mallocz(sizeof(RTPContext));
- if (!s)
- return AVERROR(ENOMEM);
- h->priv_data = s;
-
av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
path, sizeof(path), uri);
/* extract parameters */
@@ -188,7 +183,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
build_udp_url(buf, sizeof(buf),
hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
connect);
- if (ffurl_open(&s->rtp_hd, buf, flags) < 0)
+ if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
goto fail;
if (local_rtp_port>=0 && local_rtcp_port<0)
local_rtcp_port = ff_udp_get_local_port(s->rtp_hd) + 1;
@@ -196,7 +191,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
build_udp_url(buf, sizeof(buf),
hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
connect);
- if (ffurl_open(&s->rtcp_hd, buf, flags) < 0)
+ if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
goto fail;
/* just to ease handle access. XXX: need to suppress direct handle
@@ -213,7 +208,6 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
ffurl_close(s->rtp_hd);
if (s->rtcp_hd)
ffurl_close(s->rtcp_hd);
- av_free(s);
return AVERROR(EIO);
}
@@ -225,22 +219,8 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
int len, n;
struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}};
-#if 0
- for(;;) {
- from_len = sizeof(from);
- len = recvfrom (s->rtp_fd, buf, size, 0,
- (struct sockaddr *)&from, &from_len);
- if (len < 0) {
- if (ff_neterrno() == AVERROR(EAGAIN) ||
- ff_neterrno() == AVERROR(EINTR))
- continue;
- return AVERROR(EIO);
- }
- break;
- }
-#else
for(;;) {
- if (url_interrupt_cb())
+ if (ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT;
/* build fdset to listen to RTP and RTCP packets */
n = poll(p, 2, 100);
@@ -277,7 +257,6 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
return AVERROR(EIO);
}
}
-#endif
return len;
}
@@ -296,14 +275,6 @@ static int rtp_write(URLContext *h, const uint8_t *buf, int size)
}
ret = ffurl_write(hd, buf, size);
-#if 0
- {
- struct timespec ts;
- ts.tv_sec = 0;
- ts.tv_nsec = 10 * 1000000;
- nanosleep(&ts, NULL);
- }
-#endif
return ret;
}
@@ -313,7 +284,6 @@ static int rtp_close(URLContext *h)
ffurl_close(s->rtp_hd);
ffurl_close(s->rtcp_hd);
- av_free(s);
return 0;
}
@@ -323,7 +293,7 @@ static int rtp_close(URLContext *h)
* @return the local port number
*/
-int rtp_get_local_rtp_port(URLContext *h)
+int ff_rtp_get_local_rtp_port(URLContext *h)
{
RTPContext *s = h->priv_data;
return ff_udp_get_local_port(s->rtp_hd);
@@ -335,7 +305,7 @@ int rtp_get_local_rtp_port(URLContext *h)
* @return the local port number
*/
-int rtp_get_local_rtcp_port(URLContext *h)
+int ff_rtp_get_local_rtcp_port(URLContext *h)
{
RTPContext *s = h->priv_data;
return ff_udp_get_local_port(s->rtcp_hd);
@@ -347,7 +317,7 @@ static int rtp_get_file_handle(URLContext *h)
return s->rtp_fd;
}
-int rtp_get_rtcp_file_handle(URLContext *h) {
+int ff_rtp_get_rtcp_file_handle(URLContext *h) {
RTPContext *s = h->priv_data;
return s->rtcp_fd;
}
@@ -359,4 +329,5 @@ URLProtocol ff_rtp_protocol = {
.url_write = rtp_write,
.url_close = rtp_close,
.url_get_file_handle = rtp_get_file_handle,
+ .priv_data_size = sizeof(RTPContext),
};
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 80cd587..fcf168d 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -22,9 +22,11 @@
#include "libavutil/base64.h"
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
#include "libavutil/random_seed.h"
#include "libavutil/dict.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "avio_internal.h"
@@ -32,7 +34,6 @@
#if HAVE_POLL_H
#include <poll.h>
#endif
-#include <strings.h>
#include "internal.h"
#include "network.h"
#include "os_support.h"
@@ -44,6 +45,7 @@
#include "rtpdec_formats.h"
#include "rtpenc_chain.h"
#include "url.h"
+#include "rtpenc.h"
//#define DEBUG
@@ -55,6 +57,44 @@
#define SDP_MAX_SIZE 16384
#define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
+#define OFFSET(x) offsetof(RTSPState, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+
+#define RTSP_FLAG_OPTS(name, longname) \
+ { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
+ { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }
+
+#define RTSP_MEDIATYPE_OPTS(name, longname) \
+ { name, longname, OFFSET(media_type_mask), AV_OPT_TYPE_FLAGS, { (1 << (AVMEDIA_TYPE_DATA+1)) - 1 }, INT_MIN, INT_MAX, DEC, "allowed_media_types" }, \
+ { "video", "Video", 0, AV_OPT_TYPE_CONST, {1 << AVMEDIA_TYPE_VIDEO}, 0, 0, DEC, "allowed_media_types" }, \
+ { "audio", "Audio", 0, AV_OPT_TYPE_CONST, {1 << AVMEDIA_TYPE_AUDIO}, 0, 0, DEC, "allowed_media_types" }, \
+ { "data", "Data", 0, AV_OPT_TYPE_CONST, {1 << AVMEDIA_TYPE_DATA}, 0, 0, DEC, "allowed_media_types" }
+
+const AVOption ff_rtsp_options[] = {
+ { "initial_pause", "Don't start playing the stream immediately", OFFSET(initial_pause), AV_OPT_TYPE_INT, {0}, 0, 1, DEC },
+ FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags),
+ { "rtsp_transport", "RTSP transport protocols", OFFSET(lower_transport_mask), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC|ENC, "rtsp_transport" }, \
+ { "udp", "UDP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
+ { "tcp", "TCP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_TCP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
+ { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" },
+ { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {(1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" },
+ RTSP_FLAG_OPTS("rtsp_flags", "RTSP flags"),
+ RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
+ { NULL },
+};
+
+static const AVOption sdp_options[] = {
+ RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
+ RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
+ { NULL },
+};
+
+static const AVOption rtp_options[] = {
+ RTSP_FLAG_OPTS("rtp_flags", "RTP flags"),
+ { NULL },
+};
+
static void get_word_until_chars(char *buf, int buf_size,
const char *sep, const char **pp)
{
@@ -132,8 +172,11 @@ static void init_rtp_handler(RTPDynamicProtocolHandler *handler,
return;
codec->codec_id = handler->codec_id;
rtsp_st->dynamic_handler = handler;
- if (handler->alloc)
+ if (handler->alloc) {
rtsp_st->dynamic_protocol_context = handler->alloc();
+ if (!rtsp_st->dynamic_protocol_context)
+ rtsp_st->dynamic_handler = NULL;
+ }
}
/* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
@@ -185,7 +228,7 @@ static int sdp_parse_rtpmap(AVFormatContext *s,
codec->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS;
if (i > 0) {
codec->sample_rate = i;
- av_set_pts_info(st, 32, 1, codec->sample_rate);
+ avpriv_set_pts_info(st, 32, 1, codec->sample_rate);
get_word_sep(buf, sizeof(buf), "/", &p);
i = atoi(buf);
if (i > 0)
@@ -203,11 +246,14 @@ static int sdp_parse_rtpmap(AVFormatContext *s,
case AVMEDIA_TYPE_VIDEO:
av_log(s, AV_LOG_DEBUG, "video codec set to: %s\n", c_name);
if (i > 0)
- av_set_pts_info(st, 32, 1, i);
+ avpriv_set_pts_info(st, 32, 1, i);
break;
default:
break;
}
+ if (rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->init)
+ rtsp_st->dynamic_handler->init(s, st->index,
+ rtsp_st->dynamic_protocol_context);
return 0;
}
@@ -293,6 +339,7 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
case 'm':
/* new stream */
s1->skip_media = 0;
+ codec_type = AVMEDIA_TYPE_UNKNOWN;
get_word(st_type, sizeof(st_type), &p);
if (!strcmp(st_type, "audio")) {
codec_type = AVMEDIA_TYPE_AUDIO;
@@ -300,7 +347,8 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
codec_type = AVMEDIA_TYPE_VIDEO;
} else if (!strcmp(st_type, "application")) {
codec_type = AVMEDIA_TYPE_DATA;
- } else {
+ }
+ if (codec_type == AVMEDIA_TYPE_UNKNOWN || !(rt->media_type_mask & (1 << codec_type))) {
s1->skip_media = 1;
return;
}
@@ -325,9 +373,10 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
/* no corresponding stream */
} else {
- st = av_new_stream(s, rt->nb_rtsp_streams - 1);
+ st = avformat_new_stream(s, NULL);
if (!st)
return;
+ st->id = rt->nb_rtsp_streams - 1;
rtsp_st->stream_index = st->index;
st->codec->codec_type = codec_type;
if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
@@ -336,11 +385,14 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
ff_rtp_get_codec_info(st->codec, rtsp_st->sdp_payload_type);
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
st->codec->sample_rate > 0)
- av_set_pts_info(st, 32, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);
/* Even static payload types may need a custom depacketizer */
handler = ff_rtp_handler_find_by_id(
rtsp_st->sdp_payload_type, st->codec->codec_type);
init_rtp_handler(handler, rtsp_st, st->codec);
+ if (handler && handler->init)
+ handler->init(s, st->index,
+ rtsp_st->dynamic_protocol_context);
}
}
/* put a default control url */
@@ -500,7 +552,7 @@ void ff_rtsp_undo_setup(AVFormatContext *s)
} else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
ff_rdt_parse_close(rtsp_st->transport_priv);
else if (CONFIG_RTPDEC)
- rtp_parse_close(rtsp_st->transport_priv);
+ ff_rtp_parse_close(rtsp_st->transport_priv);
}
rtsp_st->transport_priv = NULL;
if (rtsp_st->rtp_handle)
@@ -528,8 +580,7 @@ void ff_rtsp_close_streams(AVFormatContext *s)
}
av_free(rt->rtsp_streams);
if (rt->asf_ctx) {
- av_close_input_stream (rt->asf_ctx);
- rt->asf_ctx = NULL;
+ avformat_close_input(&rt->asf_ctx);
}
av_free(rt->p);
av_free(rt->recvbuf);
@@ -557,7 +608,7 @@ static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
rtsp_st->dynamic_protocol_context,
rtsp_st->dynamic_handler);
else if (CONFIG_RTPDEC)
- rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle,
+ rtsp_st->transport_priv = ff_rtp_parse_open(s, st, rtsp_st->rtp_handle,
rtsp_st->sdp_payload_type,
(rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP || !s->max_delay)
? 0 : RTP_REORDER_QUEUE_DEFAULT_SIZE);
@@ -566,9 +617,9 @@ static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
return AVERROR(ENOMEM);
} else if (rt->transport != RTSP_TRANSPORT_RDT && CONFIG_RTPDEC) {
if (rtsp_st->dynamic_handler) {
- rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
- rtsp_st->dynamic_protocol_context,
- rtsp_st->dynamic_handler);
+ ff_rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
+ rtsp_st->dynamic_protocol_context,
+ rtsp_st->dynamic_handler);
}
}
@@ -617,7 +668,7 @@ static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p)
get_word_sep(transport_protocol, sizeof(transport_protocol),
"/", &p);
- if (!strcasecmp (transport_protocol, "rtp")) {
+ if (!av_strcasecmp (transport_protocol, "rtp")) {
get_word_sep(profile, sizeof(profile), "/;,", &p);
lower_transport[0] = '\0';
/* rtp/avp/<protocol> */
@@ -626,14 +677,14 @@ static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p)
";,", &p);
}
th->transport = RTSP_TRANSPORT_RTP;
- } else if (!strcasecmp (transport_protocol, "x-pn-tng") ||
- !strcasecmp (transport_protocol, "x-real-rdt")) {
+ } else if (!av_strcasecmp (transport_protocol, "x-pn-tng") ||
+ !av_strcasecmp (transport_protocol, "x-real-rdt")) {
/* x-pn-tng/<protocol> */
get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p);
profile[0] = '\0';
th->transport = RTSP_TRANSPORT_RDT;
}
- if (!strcasecmp(lower_transport, "TCP"))
+ if (!av_strcasecmp(lower_transport, "TCP"))
th->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
else
th->lower_transport = RTSP_LOWER_TRANSPORT_UDP;
@@ -807,6 +858,9 @@ void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
if (strstr(p, "GET_PARAMETER") &&
method && !strcmp(method, "OPTIONS"))
rt->get_parameter_supported = 1;
+ } else if (av_stristart(p, "x-Accept-Dynamic-Rate:", &p) && rt) {
+ p += strspn(p, SPACE_CHARS);
+ rt->accept_dynamic_rate = atoi(p);
}
}
@@ -1110,25 +1164,18 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
"?localport=%d", j);
/* we will use two ports per rtp stream (rtp and rtcp) */
j += 2;
- if (ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE) == 0)
+ if (ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE,
+ &s->interrupt_callback, NULL) == 0)
goto rtp_opened;
}
}
-#if 0
- /* then try on any port */
- if (ffurl_open(&rtsp_st->rtp_handle, "rtp://", AVIO_FLAG_READ) < 0) {
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
-#else
av_log(s, AV_LOG_ERROR, "Unable to open an input RTP port\n");
err = AVERROR(EIO);
goto fail;
-#endif
rtp_opened:
- port = rtp_get_local_rtp_port(rtsp_st->rtp_handle);
+ port = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
have_port:
snprintf(transport, sizeof(transport) - 1,
"%s/UDP;", trans_pref);
@@ -1172,6 +1219,8 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
snprintf(cmd, sizeof(cmd),
"Transport: %s\r\n",
transport);
+ if (rt->accept_dynamic_rate)
+ av_strlcat(cmd, "x-Dynamic-Rate: 0\r\n", sizeof(cmd));
if (i == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) {
char real_res[41], real_csum[9];
ff_rdt_calc_response_and_checksum(real_res, real_csum,
@@ -1220,7 +1269,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
case RTSP_LOWER_TRANSPORT_UDP: {
char url[1024], options[30] = "";
- if (rt->filter_source)
+ if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
av_strlcpy(options, "?connect=1", sizeof(options));
/* Use source address if specified */
if (reply->transports[0].source[0]) {
@@ -1232,7 +1281,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
reply->transports[0].server_port_min, "%s", options);
}
if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
- rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
+ ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
}
@@ -1242,7 +1291,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
*/
if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat &&
CONFIG_RTPDEC)
- rtp_send_punch_packets(rtsp_st->rtp_handle);
+ ff_rtp_send_punch_packets(rtsp_st->rtp_handle);
break;
}
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
@@ -1263,7 +1312,8 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
port, "?ttl=%d", ttl);
- if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) {
+ if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
+ &s->interrupt_callback, NULL) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
}
@@ -1310,8 +1360,17 @@ int ff_rtsp_connect(AVFormatContext *s)
if (!ff_network_init())
return AVERROR(EIO);
-redirect:
+
rt->control_transport = RTSP_MODE_PLAIN;
+ if (rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_HTTP)) {
+ rt->lower_transport_mask = 1 << RTSP_LOWER_TRANSPORT_TCP;
+ rt->control_transport = RTSP_MODE_TUNNEL;
+ }
+ /* Only pass through valid flags from here */
+ rt->lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
+
+redirect:
+ lower_transport_mask = rt->lower_transport_mask;
/* extract hostname and port */
av_url_split(NULL, 0, auth, sizeof(auth),
host, sizeof(host), &port, path, sizeof(path), s->filename);
@@ -1321,6 +1380,7 @@ redirect:
if (port < 0)
port = RTSP_DEFAULT_PORT;
+#if FF_API_RTSP_URL_OPTIONS
/* search for options */
option_list = strrchr(path, '?');
if (option_list) {
@@ -1328,6 +1388,7 @@ redirect:
* the options back into the same string. */
filename = option_list;
while (option_list) {
+ int handled = 1;
/* move the option pointer */
option = ++option_list;
option_list = strchr(option_list, '&');
@@ -1345,7 +1406,7 @@ redirect:
lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP);
rt->control_transport = RTSP_MODE_TUNNEL;
} else if (!strcmp(option, "filter_src")) {
- rt->filter_source = 1;
+ rt->rtsp_flags |= RTSP_FLAG_FILTER_SRC;
} else {
/* Write options back into the buffer, using memmove instead
* of strcpy since the strings may overlap. */
@@ -1353,10 +1414,16 @@ redirect:
memmove(++filename, option, len);
filename += len;
if (option_list) *filename = '&';
+ handled = 0;
}
+ if (handled)
+ av_log(s, AV_LOG_WARNING, "Options passed via URL are "
+ "deprecated, use -rtsp_transport "
+ "and -rtsp_flags instead.\n");
}
*filename = 0;
}
+#endif
if (!lower_transport_mask)
lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
@@ -1390,7 +1457,8 @@ redirect:
av_get_random_seed(), av_get_random_seed());
/* GET requests */
- if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ) < 0) {
+ if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ,
+ &s->interrupt_callback) < 0) {
err = AVERROR(EIO);
goto fail;
}
@@ -1402,16 +1470,17 @@ redirect:
"Pragma: no-cache\r\n"
"Cache-Control: no-cache\r\n",
sessioncookie);
- ff_http_set_headers(rt->rtsp_hd, headers);
+ av_opt_set(rt->rtsp_hd->priv_data, "headers", headers, 0);
/* complete the connection */
- if (ffurl_connect(rt->rtsp_hd)) {
+ if (ffurl_connect(rt->rtsp_hd, NULL)) {
err = AVERROR(EIO);
goto fail;
}
/* POST requests */
- if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE) < 0 ) {
+ if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE,
+ &s->interrupt_callback) < 0 ) {
err = AVERROR(EIO);
goto fail;
}
@@ -1425,8 +1494,8 @@ redirect:
"Content-Length: 32767\r\n"
"Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n",
sessioncookie);
- ff_http_set_headers(rt->rtsp_hd_out, headers);
- ff_http_set_chunked_transfer_encoding(rt->rtsp_hd_out, 0);
+ av_opt_set(rt->rtsp_hd_out->priv_data, "headers", headers, 0);
+ av_opt_set(rt->rtsp_hd_out->priv_data, "chunked_post", "0", 0);
/* Initialize the authentication state for the POST session. The HTTP
* protocol implementation doesn't properly handle multi-pass
@@ -1447,14 +1516,15 @@ redirect:
ff_http_init_auth_state(rt->rtsp_hd_out, rt->rtsp_hd);
/* complete the connection */
- if (ffurl_connect(rt->rtsp_hd_out)) {
+ if (ffurl_connect(rt->rtsp_hd_out, NULL)) {
err = AVERROR(EIO);
goto fail;
}
} else {
/* open the tcp connection */
ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL);
- if (ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE) < 0) {
+ if (ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
+ &s->interrupt_callback, NULL) < 0) {
err = AVERROR(EIO);
goto fail;
}
@@ -1498,7 +1568,7 @@ redirect:
if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
rt->server_type = RTSP_SERVER_REAL;
continue;
- } else if (!strncasecmp(reply->server, "WMServer/", 9)) {
+ } else if (!av_strncasecmp(reply->server, "WMServer/", 9)) {
rt->server_type = RTSP_SERVER_WMS;
} else if (rt->server_type == RTSP_SERVER_REAL)
strcpy(real_challenge, reply->real_challenge);
@@ -1559,7 +1629,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
struct pollfd *p = rt->p;
for (;;) {
- if (url_interrupt_cb())
+ if (ff_check_interrupt(&s->interrupt_callback))
return AVERROR_EXIT;
if (wait_end && wait_end - av_gettime() < 0)
return AVERROR(EAGAIN);
@@ -1576,7 +1646,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
if (rtsp_st->rtp_handle) {
p[max_p].fd = ffurl_get_file_handle(rtsp_st->rtp_handle);
p[max_p++].events = POLLIN;
- p[max_p].fd = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
+ p[max_p].fd = ff_rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
p[max_p++].events = POLLIN;
}
}
@@ -1631,7 +1701,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
if (rt->transport == RTSP_TRANSPORT_RDT) {
ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
} else
- ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
+ ret = ff_rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
if (ret == 0) {
rt->cur_transport_priv = NULL;
return 0;
@@ -1679,13 +1749,13 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
len = udp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
- rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
+ ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
break;
}
if (len == AVERROR(EAGAIN) && first_queue_st &&
rt->transport == RTSP_TRANSPORT_RTP) {
rtsp_st = first_queue_st;
- ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
+ ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
goto end;
}
if (len < 0)
@@ -1695,7 +1765,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
if (rt->transport == RTSP_TRANSPORT_RDT) {
ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
} else {
- ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
+ ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
if (ret < 0) {
/* Either bad packet, or a RTCP packet. Check if the
* first_rtcp_ntp_time field was initialized. */
@@ -1799,9 +1869,11 @@ static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap)
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
ff_url_join(url, sizeof(url), "rtp", NULL,
namebuf, rtsp_st->sdp_port,
- "?localport=%d&ttl=%d", rtsp_st->sdp_port,
- rtsp_st->sdp_ttl);
- if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) {
+ "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port,
+ rtsp_st->sdp_ttl,
+ rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0);
+ if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
+ &s->interrupt_callback, NULL) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
}
@@ -1822,14 +1894,22 @@ static int sdp_read_close(AVFormatContext *s)
return 0;
}
+static const AVClass sdp_demuxer_class = {
+ .class_name = "SDP demuxer",
+ .item_name = av_default_item_name,
+ .option = sdp_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_sdp_demuxer = {
- "sdp",
- NULL_IF_CONFIG_SMALL("SDP"),
- sizeof(RTSPState),
- sdp_probe,
- sdp_read_header,
- ff_rtsp_fetch_packet,
- sdp_read_close,
+ .name = "sdp",
+ .long_name = NULL_IF_CONFIG_SMALL("SDP"),
+ .priv_data_size = sizeof(RTSPState),
+ .read_probe = sdp_probe,
+ .read_header = sdp_read_header,
+ .read_packet = ff_rtsp_fetch_packet,
+ .read_close = sdp_read_close,
+ .priv_class = &sdp_demuxer_class
};
#endif /* CONFIG_SDP_DEMUXER */
@@ -1853,11 +1933,13 @@ static int rtp_read_header(AVFormatContext *s,
struct sockaddr_storage addr;
AVIOContext pb;
socklen_t addrlen = sizeof(addr);
+ RTSPState *rt = s->priv_data;
if (!ff_network_init())
return AVERROR(EIO);
- ret = ffurl_open(&in, s->filename, AVIO_FLAG_READ);
+ ret = ffurl_open(&in, s->filename, AVIO_FLAG_READ,
+ &s->interrupt_callback, NULL);
if (ret)
goto fail;
@@ -1915,6 +1997,8 @@ static int rtp_read_header(AVFormatContext *s,
/* sdp_read_header initializes this again */
ff_network_close();
+ rt->media_type_mask = (1 << (AVMEDIA_TYPE_DATA+1)) - 1;
+
ret = sdp_read_header(s, ap);
s->pb = NULL;
return ret;
@@ -1926,15 +2010,23 @@ fail:
return ret;
}
+static const AVClass rtp_demuxer_class = {
+ .class_name = "RTP demuxer",
+ .item_name = av_default_item_name,
+ .option = rtp_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_rtp_demuxer = {
- "rtp",
- NULL_IF_CONFIG_SMALL("RTP input format"),
- sizeof(RTSPState),
- rtp_probe,
- rtp_read_header,
- ff_rtsp_fetch_packet,
- sdp_read_close,
+ .name = "rtp",
+ .long_name = NULL_IF_CONFIG_SMALL("RTP input format"),
+ .priv_data_size = sizeof(RTSPState),
+ .read_probe = rtp_probe,
+ .read_header = rtp_read_header,
+ .read_packet = ff_rtsp_fetch_packet,
+ .read_close = sdp_read_close,
.flags = AVFMT_NOFILE,
+ .priv_class = &rtp_demuxer_class
};
#endif /* CONFIG_RTP_DEMUXER */
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 7d2460f..662407f 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -29,6 +29,7 @@
#include "httpauth.h"
#include "libavutil/log.h"
+#include "libavutil/opt.h"
/**
* Network layer over which RTP/etc packet data will be transported.
@@ -37,7 +38,10 @@ enum RTSPLowerTransport {
RTSP_LOWER_TRANSPORT_UDP = 0, /**< UDP/unicast */
RTSP_LOWER_TRANSPORT_TCP = 1, /**< TCP; interleaved in RTSP */
RTSP_LOWER_TRANSPORT_UDP_MULTICAST = 2, /**< UDP/multicast */
- RTSP_LOWER_TRANSPORT_NB
+ RTSP_LOWER_TRANSPORT_NB,
+ RTSP_LOWER_TRANSPORT_HTTP = 8, /**< HTTP tunneled - not a proper
+ transport mode as such,
+ only for use via AVOptions */
};
/**
@@ -182,7 +186,7 @@ enum RTSPClientState {
};
/**
- * Identifies particular servers that require special handling, such as
+ * Identify particular servers that require special handling, such as
* standards-incompliant "Transport:" lines in the SETUP request.
*/
enum RTSPServerType {
@@ -220,9 +224,6 @@ typedef struct RTSPState {
* see rtsp_read_play() and rtsp_read_seek(). */
int64_t seek_timestamp;
- /* XXX: currently we use unbuffered input */
- // AVIOContext rtsp_gb;
-
int seq; /**< RTSP command sequence number */
/** copy of RTSPMessageHeader->session_id, i.e. the server-provided session
@@ -316,10 +317,6 @@ typedef struct RTSPState {
/** Reusable buffer for receiving packets */
uint8_t* recvbuf;
- /** Filter incoming UDP packets - receive packets only from the right
- * source address and port. */
- int filter_source;
-
/**
* A mask with all requested transport methods
*/
@@ -349,10 +346,27 @@ typedef struct RTSPState {
* Option flags for the chained RTP muxer.
*/
int rtp_muxer_flags;
+
+ /** Whether the server accepts the x-Dynamic-Rate header */
+ int accept_dynamic_rate;
+
+ /**
+ * Various option flags for the RTSP muxer/demuxer.
+ */
+ int rtsp_flags;
+
+ /**
+ * Mask of all requested media types
+ */
+ int media_type_mask;
} RTSPState;
+#define RTSP_FLAG_FILTER_SRC 0x1 /**< Filter incoming UDP packets -
+ receive packets only from the right
+ source address and port. */
+
/**
- * Describes a single stream, as identified by a single m= line block in the
+ * Describe a single stream, as identified by a single m= line block in the
* SDP content. In the case of RDT, one RTSPStream can represent multiple
* AVStreams. In this case, each AVStream in this set has similar content
* (but different codec/bitrate).
@@ -488,9 +502,9 @@ void ff_rtsp_close_streams(AVFormatContext *s);
/**
* Close all connection handles within the RTSP (de)muxer
*
- * @param rt RTSP (de)muxer context
+ * @param s RTSP (de)muxer context
*/
-void ff_rtsp_close_connections(AVFormatContext *rt);
+void ff_rtsp_close_connections(AVFormatContext *s);
/**
* Get the description of the stream and set up the RTSPStream child
@@ -537,4 +551,6 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
*/
void ff_rtsp_undo_setup(AVFormatContext *s);
+extern const AVOption ff_rtsp_options[];
+
#endif /* AVFORMAT_RTSP_H */
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 9cd9be1..1b4982f 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -21,7 +21,7 @@
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
-#include "libavutil/opt.h"
+#include "libavutil/mathematics.h"
#include "avformat.h"
#include "internal.h"
@@ -52,6 +52,8 @@ static int rtsp_read_play(AVFormatContext *s)
rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE;
rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
rtpctx->base_timestamp = 0;
+ rtpctx->timestamp = 0;
+ rtpctx->unwrapped_timestamp = 0;
rtpctx->rtcp_ts_offset = 0;
}
}
@@ -163,11 +165,6 @@ static int rtsp_read_header(AVFormatContext *s,
return AVERROR(ENOMEM);
rt->real_setup = rt->real_setup_cache + s->nb_streams;
-#if FF_API_FORMAT_PARAMETERS
- if (ap->initial_pause)
- rt->initial_pause = ap->initial_pause;
-#endif
-
if (rt->initial_pause) {
/* do not start immediately */
} else {
@@ -382,12 +379,6 @@ static int rtsp_read_close(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
-#if 0
- /* NOTE: it is valid to flush the buffer here */
- if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
- avio_close(&rt->rtsp_gb);
- }
-#endif
ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
ff_rtsp_close_streams(s);
@@ -398,27 +389,22 @@ static int rtsp_read_close(AVFormatContext *s)
return 0;
}
-static const AVOption options[] = {
- { "initial_pause", "Don't start playing the stream immediately", offsetof(RTSPState, initial_pause), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
- { NULL },
-};
-
const AVClass rtsp_demuxer_class = {
.class_name = "RTSP demuxer",
.item_name = av_default_item_name,
- .option = options,
+ .option = ff_rtsp_options,
.version = LIBAVUTIL_VERSION_INT,
};
AVInputFormat ff_rtsp_demuxer = {
- "rtsp",
- NULL_IF_CONFIG_SMALL("RTSP input format"),
- sizeof(RTSPState),
- rtsp_probe,
- rtsp_read_header,
- rtsp_read_packet,
- rtsp_read_close,
- rtsp_read_seek,
+ .name = "rtsp",
+ .long_name = NULL_IF_CONFIG_SMALL("RTSP input format"),
+ .priv_data_size = sizeof(RTSPState),
+ .read_probe = rtsp_probe,
+ .read_header = rtsp_read_header,
+ .read_packet = rtsp_read_packet,
+ .read_close = rtsp_read_close,
+ .read_seek = rtsp_read_seek,
.flags = AVFMT_NOFILE,
.read_play = rtsp_read_play,
.read_pause = rtsp_read_pause,
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index b76b6ad..e4e79ca 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -33,20 +33,13 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
#include "url.h"
-#include "libavutil/opt.h"
-#include "rtpenc.h"
#define SDP_MAX_SIZE 16384
-static const AVOption options[] = {
- FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags),
- { NULL },
-};
-
static const AVClass rtsp_muxer_class = {
.class_name = "RTSP muxer",
.item_name = av_default_item_name,
- .option = options,
+ .option = ff_rtsp_options,
.version = LIBAVUTIL_VERSION_INT,
};
@@ -241,16 +234,14 @@ static int rtsp_write_close(AVFormatContext *s)
}
AVOutputFormat ff_rtsp_muxer = {
- "rtsp",
- NULL_IF_CONFIG_SMALL("RTSP output format"),
- NULL,
- NULL,
- sizeof(RTSPState),
- CODEC_ID_AAC,
- CODEC_ID_MPEG4,
- rtsp_write_header,
- rtsp_write_packet,
- rtsp_write_close,
+ .name = "rtsp",
+ .long_name = NULL_IF_CONFIG_SMALL("RTSP output format"),
+ .priv_data_size = sizeof(RTSPState),
+ .audio_codec = CODEC_ID_AAC,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = rtsp_write_header,
+ .write_packet = rtsp_write_packet,
+ .write_trailer = rtsp_write_close,
.flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER,
.priv_class = &rtsp_muxer_class,
};
diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c
index 15d772c..531cfd2 100644
--- a/libavformat/sapdec.c
+++ b/libavformat/sapdec.c
@@ -52,7 +52,7 @@ static int sap_read_close(AVFormatContext *s)
{
struct SAPState *sap = s->priv_data;
if (sap->sdp_ctx)
- av_close_input_file(sap->sdp_ctx);
+ avformat_close_input(&sap->sdp_ctx);
if (sap->ann_fd)
ffurl_close(sap->ann_fd);
av_freep(&sap->sdp);
@@ -85,7 +85,8 @@ static int sap_read_header(AVFormatContext *s,
ff_url_join(url, sizeof(url), "udp", NULL, host, port, "?localport=%d",
port);
- ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_READ);
+ ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_READ,
+ &s->interrupt_callback, NULL);
if (ret)
goto fail;
@@ -157,17 +158,19 @@ static int sap_read_header(AVFormatContext *s,
}
sap->sdp_ctx->max_delay = s->max_delay;
sap->sdp_ctx->pb = &sap->sdp_pb;
+ sap->sdp_ctx->interrupt_callback = s->interrupt_callback;
ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL);
if (ret < 0)
goto fail;
if (sap->sdp_ctx->ctx_flags & AVFMTCTX_NOHEADER)
s->ctx_flags |= AVFMTCTX_NOHEADER;
for (i = 0; i < sap->sdp_ctx->nb_streams; i++) {
- AVStream *st = av_new_stream(s, i);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st) {
ret = AVERROR(ENOMEM);
goto fail;
}
+ st->id = i;
avcodec_copy_context(st->codec, sap->sdp_ctx->streams[i]->codec);
st->time_base = sap->sdp_ctx->streams[i]->time_base;
}
@@ -211,11 +214,12 @@ static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt)
if (s->ctx_flags & AVFMTCTX_NOHEADER) {
while (sap->sdp_ctx->nb_streams > s->nb_streams) {
int i = s->nb_streams;
- AVStream *st = av_new_stream(s, i);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st) {
av_free_packet(pkt);
return AVERROR(ENOMEM);
}
+ st->id = i;
avcodec_copy_context(st->codec, sap->sdp_ctx->streams[i]->codec);
st->time_base = sap->sdp_ctx->streams[i]->time_base;
}
@@ -224,13 +228,13 @@ static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_sap_demuxer = {
- "sap",
- NULL_IF_CONFIG_SMALL("SAP input format"),
- sizeof(struct SAPState),
- sap_probe,
- sap_read_header,
- sap_fetch_packet,
- sap_read_close,
+ .name = "sap",
+ .long_name = NULL_IF_CONFIG_SMALL("SAP input format"),
+ .priv_data_size = sizeof(struct SAPState),
+ .read_probe = sap_probe,
+ .read_header = sap_read_header,
+ .read_packet = sap_fetch_packet,
+ .read_close = sap_read_close,
.flags = AVFMT_NOFILE,
};
diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
index 3abd79e..d8ec465 100644
--- a/libavformat/sapenc.c
+++ b/libavformat/sapenc.c
@@ -146,7 +146,7 @@ static int sap_write_header(AVFormatContext *s)
"?ttl=%d", ttl);
if (!same_port)
base_port += 2;
- ret = ffurl_open(&fd, url, AVIO_FLAG_WRITE);
+ ret = ffurl_open(&fd, url, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL);
if (ret) {
ret = AVERROR(EIO);
goto fail;
@@ -158,7 +158,8 @@ static int sap_write_header(AVFormatContext *s)
ff_url_join(url, sizeof(url), "udp", NULL, announce_addr, port,
"?ttl=%d&connect=1", ttl);
- ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_WRITE);
+ ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, NULL);
if (ret) {
ret = AVERROR(EIO);
goto fail;
@@ -250,16 +251,14 @@ static int sap_write_packet(AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_sap_muxer = {
- "sap",
- NULL_IF_CONFIG_SMALL("SAP output format"),
- NULL,
- NULL,
- sizeof(struct SAPState),
- CODEC_ID_AAC,
- CODEC_ID_MPEG4,
- sap_write_header,
- sap_write_packet,
- sap_write_close,
+ .name = "sap",
+ .long_name = NULL_IF_CONFIG_SMALL("SAP output format"),
+ .priv_data_size = sizeof(struct SAPState),
+ .audio_codec = CODEC_ID_AAC,
+ .video_codec = CODEC_ID_MPEG4,
+ .write_header = sap_write_header,
+ .write_packet = sap_write_packet,
+ .write_trailer = sap_write_close,
.flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER,
};
diff --git a/libavformat/sdp.c b/libavformat/sdp.c
index c227c7f..d89591f 100644
--- a/libavformat/sdp.c
+++ b/libavformat/sdp.c
@@ -156,6 +156,8 @@ static char *extradata2psets(AVCodecContext *c)
char *psets, *p;
const uint8_t *r;
const char *pset_string = "; sprop-parameter-sets=";
+ uint8_t *orig_extradata = NULL;
+ int orig_extradata_size = 0;
if (c->extradata_size > MAX_EXTRADATA_SIZE) {
av_log(c, AV_LOG_ERROR, "Too much extradata!\n");
@@ -172,6 +174,15 @@ static char *extradata2psets(AVCodecContext *c)
return NULL;
}
+
+ orig_extradata_size = c->extradata_size;
+ orig_extradata = av_mallocz(orig_extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!orig_extradata) {
+ av_bitstream_filter_close(bsfc);
+ return NULL;
+ }
+ memcpy(orig_extradata, c->extradata, orig_extradata_size);
av_bitstream_filter_filter(bsfc, c, NULL, &dummy_p, &dummy_int, NULL, 0, 0);
av_bitstream_filter_close(bsfc);
}
@@ -179,6 +190,7 @@ static char *extradata2psets(AVCodecContext *c)
psets = av_mallocz(MAX_PSET_SIZE);
if (psets == NULL) {
av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the parameter sets.\n");
+ av_free(orig_extradata);
return NULL;
}
memcpy(psets, pset_string, strlen(pset_string));
@@ -208,6 +220,11 @@ static char *extradata2psets(AVCodecContext *c)
p += strlen(p);
r = r1;
}
+ if (orig_extradata) {
+ av_free(c->extradata);
+ c->extradata = orig_extradata;
+ c->extradata_size = orig_extradata_size;
+ }
return psets;
}
@@ -252,7 +269,7 @@ static char *xiph_extradata2config(AVCodecContext *c)
return NULL;
}
- if (ff_split_xiph_headers(c->extradata, c->extradata_size,
+ if (avpriv_split_xiph_headers(c->extradata, c->extradata_size,
first_header_size, header_start,
header_len) < 0) {
av_log(c, AV_LOG_ERROR, "Extradata corrupt.\n");
@@ -342,7 +359,7 @@ static char *latm_context2config(AVCodecContext *c)
char *config;
for (rate_index = 0; rate_index < 16; rate_index++)
- if (ff_mpeg4audio_sample_rates[rate_index] == c->sample_rate)
+ if (avpriv_mpeg4audio_sample_rates[rate_index] == c->sample_rate)
break;
if (rate_index == 16) {
av_log(c, AV_LOG_ERROR, "Unsupported sample rate\n");
@@ -517,6 +534,14 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
payload_type,
8000, c->channels);
break;
+ case CODEC_ID_ADPCM_G726: {
+ if (payload_type >= RTP_PT_PRIVATE)
+ av_strlcatf(buff, size, "a=rtpmap:%d G726-%d/%d\r\n",
+ payload_type,
+ c->bits_per_coded_sample*8,
+ c->sample_rate);
+ break;
+ }
default:
/* Nothing special to do here... */
break;
@@ -532,10 +557,7 @@ void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *des
const char *type;
int payload_type;
- payload_type = ff_rtp_get_payload_type(c);
- if (payload_type < 0) {
- payload_type = RTP_PT_PRIVATE + (c->codec_type == AVMEDIA_TYPE_AUDIO);
- }
+ payload_type = ff_rtp_get_payload_type(fmt, c);
switch (c->codec_type) {
case AVMEDIA_TYPE_VIDEO : type = "video" ; break;
diff --git a/libavformat/seek-test.c b/libavformat/seek-test.c
new file mode 100644
index 0000000..699c693
--- /dev/null
+++ b/libavformat/seek-test.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2007 Michael Niedermayer
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libavutil/common.h"
+#include "libavutil/mathematics.h"
+#include "libavformat/avformat.h"
+
+#undef printf
+#undef fprintf
+
+static char buffer[20];
+
+static const char *ret_str(int v)
+{
+ switch (v) {
+ case AVERROR_EOF: return "-EOF";
+ case AVERROR(EIO): return "-EIO";
+ case AVERROR(ENOMEM): return "-ENOMEM";
+ case AVERROR(EINVAL): return "-EINVAL";
+ default:
+ snprintf(buffer, sizeof(buffer), "%2d", v);
+ return buffer;
+ }
+}
+
+static void ts_str(char buffer[60], int64_t ts, AVRational base)
+{
+ double tsval;
+ if (ts == AV_NOPTS_VALUE) {
+ strcpy(buffer, " NOPTS ");
+ return;
+ }
+ tsval = ts * av_q2d(base);
+ snprintf(buffer, 60, "%9f", tsval);
+}
+
+int main(int argc, char **argv)
+{
+ const char *filename;
+ AVFormatContext *ic = NULL;
+ int i, ret, stream_id;
+ int64_t timestamp;
+ AVDictionary *format_opts = NULL;
+
+ av_dict_set(&format_opts, "channels", "1", 0);
+ av_dict_set(&format_opts, "sample_rate", "22050", 0);
+
+ /* initialize libavcodec, and register all codecs and formats */
+ av_register_all();
+
+ if (argc != 2) {
+ printf("usage: %s input_file\n"
+ "\n", argv[0]);
+ return 1;
+ }
+
+ filename = argv[1];
+
+ ret = avformat_open_input(&ic, filename, NULL, &format_opts);
+ av_dict_free(&format_opts);
+ if (ret < 0) {
+ fprintf(stderr, "cannot open %s\n", filename);
+ return 1;
+ }
+
+ ret = avformat_find_stream_info(ic, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "%s: could not find codec parameters\n", filename);
+ return 1;
+ }
+
+ for(i=0; ; i++){
+ AVPacket pkt;
+ AVStream *av_uninit(st);
+ char ts_buf[60];
+
+ memset(&pkt, 0, sizeof(pkt));
+ if(ret>=0){
+ ret= av_read_frame(ic, &pkt);
+ if(ret>=0){
+ char dts_buf[60];
+ st= ic->streams[pkt.stream_index];
+ ts_str(dts_buf, pkt.dts, st->time_base);
+ ts_str(ts_buf, pkt.pts, st->time_base);
+ printf("ret:%-10s st:%2d flags:%d dts:%s pts:%s pos:%7" PRId64 " size:%6d", ret_str(ret), pkt.stream_index, pkt.flags, dts_buf, ts_buf, pkt.pos, pkt.size);
+ av_free_packet(&pkt);
+ } else
+ printf("ret:%s", ret_str(ret)); // necessary to avoid trailing whitespace
+ printf("\n");
+ }
+
+ if(i>25) break;
+
+ stream_id= (i>>1)%(ic->nb_streams+1) - 1;
+ timestamp= (i*19362894167LL) % (4*AV_TIME_BASE) - AV_TIME_BASE;
+ if(stream_id>=0){
+ st= ic->streams[stream_id];
+ timestamp= av_rescale_q(timestamp, AV_TIME_BASE_Q, st->time_base);
+ }
+ //FIXME fully test the new seek API
+ if(i&1) ret = avformat_seek_file(ic, stream_id, INT64_MIN, timestamp, timestamp, 0);
+ else ret = avformat_seek_file(ic, stream_id, timestamp, timestamp, INT64_MAX, 0);
+ ts_str(ts_buf, timestamp, stream_id < 0 ? AV_TIME_BASE_Q : st->time_base);
+ printf("ret:%-10s st:%2d flags:%d ts:%s\n", ret_str(ret), stream_id, i&1, ts_buf);
+ }
+
+ avformat_close_input(&ic);
+
+ return 0;
+}
diff --git a/libavformat/seek.c b/libavformat/seek.c
index 71e2f8a..6c4286b 100644
--- a/libavformat/seek.c
+++ b/libavformat/seek.c
@@ -21,6 +21,7 @@
*/
#include "seek.h"
+#include "libavutil/mathematics.h"
#include "libavutil/mem.h"
#include "internal.h"
diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c
index 0ad5fbb..5c346a7 100644
--- a/libavformat/segafilm.c
+++ b/libavformat/segafilm.c
@@ -29,11 +29,13 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define FILM_TAG MKBETAG('F', 'I', 'L', 'M')
#define FDSC_TAG MKBETAG('F', 'D', 'S', 'C')
#define STAB_TAG MKBETAG('S', 'T', 'A', 'B')
#define CVID_TAG MKBETAG('c', 'v', 'i', 'd')
+#define RAW_TAG MKBETAG('r', 'a', 'w', ' ')
typedef struct {
int stream;
@@ -111,11 +113,16 @@ static int film_read_header(AVFormatContext *s,
film->audio_samplerate = AV_RB16(&scratch[24]);
film->audio_channels = scratch[21];
film->audio_bits = scratch[22];
- if (film->audio_bits == 8)
- film->audio_type = CODEC_ID_PCM_S8;
- else if (film->audio_bits == 16)
- film->audio_type = CODEC_ID_PCM_S16BE;
- else
+ if (scratch[23] == 2)
+ film->audio_type = CODEC_ID_ADPCM_ADX;
+ else if (film->audio_channels > 0) {
+ if (film->audio_bits == 8)
+ film->audio_type = CODEC_ID_PCM_S8;
+ else if (film->audio_bits == 16)
+ film->audio_type = CODEC_ID_PCM_S16BE;
+ else
+ film->audio_type = CODEC_ID_NONE;
+ } else
film->audio_type = CODEC_ID_NONE;
}
@@ -124,12 +131,15 @@ static int film_read_header(AVFormatContext *s,
if (AV_RB32(&scratch[8]) == CVID_TAG) {
film->video_type = CODEC_ID_CINEPAK;
- } else
+ } else if (AV_RB32(&scratch[8]) == RAW_TAG) {
+ film->video_type = CODEC_ID_RAWVIDEO;
+ } else {
film->video_type = CODEC_ID_NONE;
+ }
/* initialize the decoder streams */
if (film->video_type) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
film->video_stream_index = st->index;
@@ -138,10 +148,19 @@ static int film_read_header(AVFormatContext *s,
st->codec->codec_tag = 0; /* no fourcc */
st->codec->width = AV_RB32(&scratch[16]);
st->codec->height = AV_RB32(&scratch[12]);
+
+ if (film->video_type == CODEC_ID_RAWVIDEO) {
+ if (scratch[20] == 24) {
+ st->codec->pix_fmt = PIX_FMT_RGB24;
+ } else {
+ av_log(s, AV_LOG_ERROR, "raw video is using unhandled %dbpp\n", scratch[20]);
+ return -1;
+ }
+ }
}
if (film->audio_type) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
film->audio_stream_index = st->index;
@@ -149,12 +168,20 @@ static int film_read_header(AVFormatContext *s,
st->codec->codec_id = film->audio_type;
st->codec->codec_tag = 1;
st->codec->channels = film->audio_channels;
- st->codec->bits_per_coded_sample = film->audio_bits;
st->codec->sample_rate = film->audio_samplerate;
+
+ if (film->audio_type == CODEC_ID_ADPCM_ADX) {
+ st->codec->bits_per_coded_sample = 18 * 8 / 32;
+ st->codec->block_align = st->codec->channels * 18;
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ } else {
+ st->codec->bits_per_coded_sample = film->audio_bits;
+ st->codec->block_align = st->codec->channels *
+ st->codec->bits_per_coded_sample / 8;
+ }
+
st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
st->codec->bits_per_coded_sample;
- st->codec->block_align = st->codec->channels *
- st->codec->bits_per_coded_sample / 8;
}
/* load the sample table */
@@ -167,9 +194,11 @@ static int film_read_header(AVFormatContext *s,
if(film->sample_count >= UINT_MAX / sizeof(film_sample))
return -1;
film->sample_table = av_malloc(film->sample_count * sizeof(film_sample));
+ if (!film->sample_table)
+ return AVERROR(ENOMEM);
for(i=0; i<s->nb_streams; i++)
- av_set_pts_info(s->streams[i], 33, 1, film->base_clock);
+ avpriv_set_pts_info(s->streams[i], 33, 1, film->base_clock);
audio_frame_counter = 0;
for (i = 0; i < film->sample_count; i++) {
@@ -187,8 +216,12 @@ static int film_read_header(AVFormatContext *s,
film->sample_table[i].pts *= film->base_clock;
film->sample_table[i].pts /= film->audio_samplerate;
- audio_frame_counter += (film->sample_table[i].sample_size /
- (film->audio_channels * film->audio_bits / 8));
+ if (film->audio_type == CODEC_ID_ADPCM_ADX)
+ audio_frame_counter += (film->sample_table[i].sample_size * 32 /
+ (18 * film->audio_channels));
+ else if (film->audio_type != CODEC_ID_NONE)
+ audio_frame_counter += (film->sample_table[i].sample_size /
+ (film->audio_channels * film->audio_bits / 8));
} else {
film->sample_table[i].stream = film->video_stream_index;
film->sample_table[i].pts = AV_RB32(&scratch[8]) & 0x7FFFFFFF;
@@ -227,7 +260,8 @@ static int film_read_packet(AVFormatContext *s,
return AVERROR(ENOMEM);
avio_read(pb, pkt->data, sample->sample_size);
} else if ((sample->stream == film->audio_stream_index) &&
- (film->audio_channels == 2)) {
+ (film->audio_channels == 2) &&
+ (film->audio_type != CODEC_ID_ADPCM_ADX)) {
/* stereo PCM needs to be interleaved */
if (av_new_packet(pkt, sample->sample_size))
@@ -238,6 +272,10 @@ static int film_read_packet(AVFormatContext *s,
av_free(film->stereo_buffer);
film->stereo_buffer_size = sample->sample_size;
film->stereo_buffer = av_malloc(film->stereo_buffer_size);
+ if (!film->stereo_buffer) {
+ film->stereo_buffer_size = 0;
+ return AVERROR(ENOMEM);
+ }
}
pkt->pos= avio_tell(pb);
@@ -283,11 +321,11 @@ static int film_read_close(AVFormatContext *s)
}
AVInputFormat ff_segafilm_demuxer = {
- "film_cpk",
- NULL_IF_CONFIG_SMALL("Sega FILM/CPK format"),
- sizeof(FilmDemuxContext),
- film_probe,
- film_read_header,
- film_read_packet,
- film_read_close,
+ .name = "film_cpk",
+ .long_name = NULL_IF_CONFIG_SMALL("Sega FILM/CPK format"),
+ .priv_data_size = sizeof(FilmDemuxContext),
+ .read_probe = film_probe,
+ .read_header = film_read_header,
+ .read_packet = film_read_packet,
+ .read_close = film_read_close,
};
diff --git a/libavformat/segment.c b/libavformat/segment.c
new file mode 100644
index 0000000..89ae62d
--- /dev/null
+++ b/libavformat/segment.c
@@ -0,0 +1,273 @@
+/*
+ * Generic segmenter
+ * Copyright (c) 2011, Luca Barbato
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <strings.h>
+#include <float.h>
+
+#include "avformat.h"
+#include "internal.h"
+
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "libavutil/avstring.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/mathematics.h"
+
+typedef struct {
+ const AVClass *class; /**< Class for private options. */
+ int number;
+ AVFormatContext *avf;
+ char *format; /**< Set by a private option. */
+ char *list; /**< Set by a private option. */
+ float time; /**< Set by a private option. */
+ int size; /**< Set by a private option. */
+ int64_t offset_time;
+ int64_t recording_time;
+ int has_video;
+ AVIOContext *pb;
+} SegmentContext;
+
+static int segment_start(AVFormatContext *s)
+{
+ SegmentContext *c = s->priv_data;
+ AVFormatContext *oc = c->avf;
+ int err = 0;
+
+ if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
+ s->filename, c->number++) < 0)
+ return AVERROR(EINVAL);
+
+ if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, NULL)) < 0)
+ return err;
+
+ if (!oc->priv_data && oc->oformat->priv_data_size > 0) {
+ oc->priv_data = av_mallocz(oc->oformat->priv_data_size);
+ if (!oc->priv_data) {
+ avio_close(oc->pb);
+ return AVERROR(ENOMEM);
+ }
+ if (oc->oformat->priv_class) {
+ *(const AVClass**)oc->priv_data = oc->oformat->priv_class;
+ av_opt_set_defaults(oc->priv_data);
+ }
+ }
+
+ if ((err = oc->oformat->write_header(oc)) < 0) {
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ avio_close(oc->pb);
+ av_freep(&oc->priv_data);
+
+ return err;
+}
+
+static int segment_end(AVFormatContext *oc)
+{
+ int ret = 0;
+
+ if (oc->oformat->write_trailer)
+ ret = oc->oformat->write_trailer(oc);
+
+ avio_close(oc->pb);
+ if (oc->oformat->priv_class)
+ av_opt_free(oc->priv_data);
+ av_freep(&oc->priv_data);
+
+ return ret;
+}
+
+static int seg_write_header(AVFormatContext *s)
+{
+ SegmentContext *seg = s->priv_data;
+ AVFormatContext *oc;
+ int ret, i;
+
+ seg->number = 0;
+ seg->offset_time = 0;
+ seg->recording_time = seg->time * 1000000;
+
+ if (seg->list)
+ if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, NULL)) < 0)
+ return ret;
+
+ for (i = 0; i< s->nb_streams; i++)
+ seg->has_video +=
+ (s->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO);
+
+ if (seg->has_video > 1)
+ av_log(s, AV_LOG_WARNING,
+ "More than a single video stream present, "
+ "expect issues decoding it.\n");
+
+ oc = avformat_alloc_context();
+
+ if (!oc) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ oc->oformat = av_guess_format(seg->format, s->filename, NULL);
+
+ if (!oc->oformat) {
+ ret = AVERROR_MUXER_NOT_FOUND;
+ goto fail;
+ }
+ if (oc->oformat->flags & AVFMT_NOFILE) {
+ av_log(s, AV_LOG_ERROR, "format %s not supported.\n",
+ oc->oformat->name);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ seg->avf = oc;
+
+ oc->streams = s->streams;
+ oc->nb_streams = s->nb_streams;
+
+ if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
+ s->filename, seg->number++) < 0) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, NULL)) < 0)
+ goto fail;
+
+ if ((ret = avformat_write_header(oc, NULL)) < 0) {
+ avio_close(oc->pb);
+ goto fail;
+ }
+
+ if (seg->list) {
+ avio_printf(seg->pb, "%s\n", oc->filename);
+ avio_flush(seg->pb);
+ }
+
+fail:
+ if (ret) {
+ oc->streams = NULL;
+ oc->nb_streams = 0;
+ if (seg->list)
+ avio_close(seg->pb);
+ avformat_free_context(oc);
+ }
+ return ret;
+}
+
+static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ SegmentContext *seg = s->priv_data;
+ AVFormatContext *oc = seg->avf;
+ AVStream *st = oc->streams[pkt->stream_index];
+ int64_t end_pts = seg->recording_time * seg->number;
+ int ret;
+
+ if ((seg->has_video && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
+ av_compare_ts(pkt->pts, st->time_base,
+ end_pts, AV_TIME_BASE_Q) >= 0 &&
+ pkt->flags & AV_PKT_FLAG_KEY) {
+
+ av_log(s, AV_LOG_DEBUG, "Next segment starts at %d %"PRId64"\n",
+ pkt->stream_index, pkt->pts);
+
+ ret = segment_end(oc);
+
+ if (!ret)
+ ret = segment_start(s);
+
+ if (ret)
+ goto fail;
+
+ if (seg->list) {
+ avio_printf(seg->pb, "%s\n", oc->filename);
+ avio_flush(seg->pb);
+ if (!(seg->number % seg->size)) {
+ avio_close(seg->pb);
+ if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, NULL)) < 0)
+ goto fail;
+
+ }
+ }
+ }
+
+ ret = oc->oformat->write_packet(oc, pkt);
+
+fail:
+ if (ret < 0) {
+ oc->streams = NULL;
+ oc->nb_streams = 0;
+ if (seg->list)
+ avio_close(seg->pb);
+ avformat_free_context(oc);
+ }
+
+ return ret;
+}
+
+static int seg_write_trailer(struct AVFormatContext *s)
+{
+ SegmentContext *seg = s->priv_data;
+ AVFormatContext *oc = seg->avf;
+ int ret = segment_end(oc);
+ if (seg->list)
+ avio_close(seg->pb);
+ oc->streams = NULL;
+ oc->nb_streams = 0;
+ avformat_free_context(oc);
+ return ret;
+}
+
+#define OFFSET(x) offsetof(SegmentContext, x)
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "segment_format", "container format used for the segments", OFFSET(format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
+ { "segment_time", "segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E },
+ { "segment_list", "output the segment list", OFFSET(list), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
+ { "segment_list_size", "maximum number of playlist entries", OFFSET(size), AV_OPT_TYPE_INT, {.dbl = 5}, 0, INT_MAX, E },
+ { NULL },
+};
+
+static const AVClass seg_class = {
+ .class_name = "segment muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+
+AVOutputFormat ff_segment_muxer = {
+ .name = "segment",
+ .long_name = NULL_IF_CONFIG_SMALL("segment muxer"),
+ .priv_data_size = sizeof(SegmentContext),
+ .flags = AVFMT_GLOBALHEADER | AVFMT_NOFILE,
+ .write_header = seg_write_header,
+ .write_packet = seg_write_packet,
+ .write_trailer = seg_write_trailer,
+ .priv_class = &seg_class,
+};
diff --git a/libavformat/sierravmd.c b/libavformat/sierravmd.c
index c0fb222..1b5f04b 100644
--- a/libavformat/sierravmd.c
+++ b/libavformat/sierravmd.c
@@ -29,6 +29,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define VMD_HEADER_SIZE 0x0330
#define BYTES_PER_FRAME_RECORD 16
@@ -104,10 +105,10 @@ static int vmd_read_header(AVFormatContext *s,
else
vmd->is_indeo3 = 0;
/* start up the decoders */
- vst = av_new_stream(s, 0);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return AVERROR(ENOMEM);
- av_set_pts_info(vst, 33, 1, 10);
+ avpriv_set_pts_info(vst, 33, 1, 10);
vmd->video_stream_index = vst->index;
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vst->codec->codec_id = vmd->is_indeo3 ? CODEC_ID_INDEO3 : CODEC_ID_VMDVIDEO;
@@ -125,7 +126,7 @@ static int vmd_read_header(AVFormatContext *s,
/* if sample rate is 0, assume no audio */
vmd->sample_rate = AV_RL16(&vmd->vmd_header[804]);
if (vmd->sample_rate) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
vmd->audio_stream_index = st->index;
@@ -148,8 +149,8 @@ static int vmd_read_header(AVFormatContext *s,
num = st->codec->block_align;
den = st->codec->sample_rate * st->codec->channels;
av_reduce(&den, &num, den, num, (1UL<<31)-1);
- av_set_pts_info(vst, 33, num, den);
- av_set_pts_info(st, 33, num, den);
+ avpriv_set_pts_info(vst, 33, num, den);
+ avpriv_set_pts_info(st, 33, num, den);
}
toc_offset = AV_RL32(&vmd->vmd_header[812]);
@@ -281,11 +282,11 @@ static int vmd_read_close(AVFormatContext *s)
}
AVInputFormat ff_vmd_demuxer = {
- "vmd",
- NULL_IF_CONFIG_SMALL("Sierra VMD format"),
- sizeof(VmdDemuxContext),
- vmd_probe,
- vmd_read_header,
- vmd_read_packet,
- vmd_read_close,
+ .name = "vmd",
+ .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD format"),
+ .priv_data_size = sizeof(VmdDemuxContext),
+ .read_probe = vmd_probe,
+ .read_header = vmd_read_header,
+ .read_packet = vmd_read_packet,
+ .read_close = vmd_read_close,
};
diff --git a/libavformat/siff.c b/libavformat/siff.c
index 23c122f..9f4d733 100644
--- a/libavformat/siff.c
+++ b/libavformat/siff.c
@@ -21,6 +21,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
enum SIFFTags{
TAG_SIFF = MKTAG('S', 'I', 'F', 'F'),
@@ -71,7 +72,7 @@ static int siff_probe(AVProbeData *p)
static int create_audio_stream(AVFormatContext *s, SIFFContext *c)
{
AVStream *ast;
- ast = av_new_stream(s, 0);
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return -1;
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -80,7 +81,7 @@ static int create_audio_stream(AVFormatContext *s, SIFFContext *c)
ast->codec->bits_per_coded_sample = c->bits;
ast->codec->sample_rate = c->rate;
ast->codec->frame_size = c->block_align;
- av_set_pts_info(ast, 16, 1, c->rate);
+ avpriv_set_pts_info(ast, 16, 1, c->rate);
return 0;
}
@@ -115,7 +116,7 @@ static int siff_parse_vbv1(AVFormatContext *s, SIFFContext *c, AVIOContext *pb)
avio_skip(pb, 16); //zeroes
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -124,7 +125,7 @@ static int siff_parse_vbv1(AVFormatContext *s, SIFFContext *c, AVIOContext *pb)
st->codec->width = width;
st->codec->height = height;
st->codec->pix_fmt = PIX_FMT_PAL8;
- av_set_pts_info(st, 16, 1, 12);
+ avpriv_set_pts_info(st, 16, 1, 12);
c->cur_frame = 0;
c->has_video = 1;
@@ -228,11 +229,11 @@ static int siff_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_siff_demuxer = {
- "siff",
- NULL_IF_CONFIG_SMALL("Beam Software SIFF"),
- sizeof(SIFFContext),
- siff_probe,
- siff_read_header,
- siff_read_packet,
+ .name = "siff",
+ .long_name = NULL_IF_CONFIG_SMALL("Beam Software SIFF"),
+ .priv_data_size = sizeof(SIFFContext),
+ .read_probe = siff_probe,
+ .read_header = siff_read_header,
+ .read_packet = siff_read_packet,
.extensions = "vb,son"
};
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index a817c31..770f536 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -26,16 +26,17 @@
#include "libavutil/bswap.h"
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define SMACKER_PAL 0x01
#define SMACKER_FLAG_RING_FRAME 0x01
enum SAudFlags {
- SMK_AUD_PACKED = 0x80000000,
- SMK_AUD_16BITS = 0x20000000,
- SMK_AUD_STEREO = 0x10000000,
- SMK_AUD_BINKAUD = 0x08000000,
- SMK_AUD_USEDCT = 0x04000000
+ SMK_AUD_PACKED = 0x80,
+ SMK_AUD_16BITS = 0x20,
+ SMK_AUD_STEREO = 0x10,
+ SMK_AUD_BINKAUD = 0x08,
+ SMK_AUD_USEDCT = 0x04
};
typedef struct SmackerContext {
@@ -48,6 +49,7 @@ typedef struct SmackerContext {
uint32_t audio[7];
uint32_t treesize;
uint32_t mmap_size, mclr_size, full_size, type_size;
+ uint8_t aflags[7];
uint32_t rates[7];
uint32_t pad;
/* frame info */
@@ -129,8 +131,10 @@ static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap)
smk->mclr_size = avio_rl32(pb);
smk->full_size = avio_rl32(pb);
smk->type_size = avio_rl32(pb);
- for(i = 0; i < 7; i++)
- smk->rates[i] = avio_rl32(pb);
+ for(i = 0; i < 7; i++) {
+ smk->rates[i] = avio_rl24(pb);
+ smk->aflags[i] = avio_r8(pb);
+ }
smk->pad = avio_rl32(pb);
/* setup data */
if(smk->frames > 0xFFFFFF) {
@@ -151,7 +155,7 @@ static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
/* init video codec */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
smk->videoindex = st->index;
@@ -168,31 +172,31 @@ static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap)
smk->pts_inc *= 100;
tbase = 100000;
av_reduce(&tbase, &smk->pts_inc, tbase, smk->pts_inc, (1UL<<31)-1);
- av_set_pts_info(st, 33, smk->pts_inc, tbase);
+ avpriv_set_pts_info(st, 33, smk->pts_inc, tbase);
st->duration = smk->frames;
/* handle possible audio streams */
for(i = 0; i < 7; i++) {
smk->indexes[i] = -1;
- if(smk->rates[i] & 0xFFFFFF){
- ast[i] = av_new_stream(s, 0);
+ if (smk->rates[i]) {
+ ast[i] = avformat_new_stream(s, NULL);
smk->indexes[i] = ast[i]->index;
ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- if (smk->rates[i] & SMK_AUD_BINKAUD) {
+ if (smk->aflags[i] & SMK_AUD_BINKAUD) {
ast[i]->codec->codec_id = CODEC_ID_BINKAUDIO_RDFT;
- } else if (smk->rates[i] & SMK_AUD_USEDCT) {
+ } else if (smk->aflags[i] & SMK_AUD_USEDCT) {
ast[i]->codec->codec_id = CODEC_ID_BINKAUDIO_DCT;
- } else if (smk->rates[i] & SMK_AUD_PACKED){
+ } else if (smk->aflags[i] & SMK_AUD_PACKED){
ast[i]->codec->codec_id = CODEC_ID_SMACKAUDIO;
ast[i]->codec->codec_tag = MKTAG('S', 'M', 'K', 'A');
} else {
ast[i]->codec->codec_id = CODEC_ID_PCM_U8;
}
- ast[i]->codec->channels = (smk->rates[i] & SMK_AUD_STEREO) ? 2 : 1;
- ast[i]->codec->sample_rate = smk->rates[i] & 0xFFFFFF;
- ast[i]->codec->bits_per_coded_sample = (smk->rates[i] & SMK_AUD_16BITS) ? 16 : 8;
+ ast[i]->codec->channels = (smk->aflags[i] & SMK_AUD_STEREO) ? 2 : 1;
+ ast[i]->codec->sample_rate = smk->rates[i];
+ ast[i]->codec->bits_per_coded_sample = (smk->aflags[i] & SMK_AUD_16BITS) ? 16 : 8;
if(ast[i]->codec->bits_per_coded_sample == 16 && ast[i]->codec->codec_id == CODEC_ID_PCM_U8)
ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE;
- av_set_pts_info(ast[i], 64, 1, ast[i]->codec->sample_rate
+ avpriv_set_pts_info(ast[i], 64, 1, ast[i]->codec->sample_rate
* ast[i]->codec->channels * ast[i]->codec->bits_per_coded_sample / 8);
}
}
@@ -347,11 +351,11 @@ static int smacker_read_close(AVFormatContext *s)
}
AVInputFormat ff_smacker_demuxer = {
- "smk",
- NULL_IF_CONFIG_SMALL("Smacker video"),
- sizeof(SmackerContext),
- smacker_probe,
- smacker_read_header,
- smacker_read_packet,
- smacker_read_close,
+ .name = "smk",
+ .long_name = NULL_IF_CONFIG_SMALL("Smacker video"),
+ .priv_data_size = sizeof(SmackerContext),
+ .read_probe = smacker_probe,
+ .read_header = smacker_read_header,
+ .read_packet = smacker_read_packet,
+ .read_close = smacker_read_close,
};
diff --git a/libavformat/smjpeg.c b/libavformat/smjpeg.c
new file mode 100644
index 0000000..dc94361
--- /dev/null
+++ b/libavformat/smjpeg.c
@@ -0,0 +1,187 @@
+/*
+ * SMJPEG demuxer
+ * Copyright (c) 2011 Paul B Mahol
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * This is a demuxer for Loki SDL Motion JPEG files
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "riff.h"
+
+static const AVCodecTag codec_smjpeg_video_tags[] = {
+ { CODEC_ID_MJPEG, MKTAG('J', 'F', 'I', 'F') },
+ { CODEC_ID_NONE, 0 },
+};
+
+static const AVCodecTag codec_smjpeg_audio_tags[] = {
+ { CODEC_ID_ADPCM_IMA_SMJPEG, MKTAG('A', 'P', 'C', 'M') },
+ { CODEC_ID_PCM_S16LE, MKTAG('N', 'O', 'N', 'E') },
+ { CODEC_ID_NONE, 0 },
+};
+
+typedef struct SMJPEGContext {
+ int audio_stream_index;
+ int video_stream_index;
+} SMJPEGContext;
+
+static int smjpeg_probe(AVProbeData *p)
+{
+ if (!memcmp(p->buf, "\x0\xaSMJPEG", 8))
+ return AVPROBE_SCORE_MAX;
+ return 0;
+}
+
+static int smjpeg_read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ SMJPEGContext *sc = s->priv_data;
+ AVStream *ast = NULL, *vst = NULL;
+ AVIOContext *pb = s->pb;
+ uint32_t version, htype, hlength, duration;
+ char *comment;
+
+ avio_skip(pb, 8); // magic
+ version = avio_rb32(pb);
+ if (version)
+ av_log_ask_for_sample(s, "unknown version %d\n", version);
+
+ duration = avio_rb32(pb); // in msec
+
+ while (!pb->eof_reached) {
+ htype = avio_rl32(pb);
+ switch (htype) {
+ case MKTAG('_', 'T', 'X', 'T'):
+ hlength = avio_rb32(pb);
+ if (!hlength || hlength > 512)
+ return AVERROR_INVALIDDATA;
+ comment = av_malloc(hlength + 1);
+ if (!comment)
+ return AVERROR(ENOMEM);
+ if (avio_read(pb, comment, hlength) != hlength) {
+ av_freep(&comment);
+ av_log(s, AV_LOG_ERROR, "error when reading comment\n");
+ return AVERROR_INVALIDDATA;
+ }
+ comment[hlength] = 0;
+ av_dict_set(&s->metadata, "comment", comment,
+ AV_DICT_DONT_STRDUP_VAL);
+ break;
+ case MKTAG('_', 'S', 'N', 'D'):
+ if (ast) {
+ av_log_ask_for_sample(s, "multiple audio streams not supported\n");
+ return AVERROR_INVALIDDATA;
+ }
+ hlength = avio_rb32(pb);
+ if (hlength < 8)
+ return AVERROR_INVALIDDATA;
+ ast = avformat_new_stream(s, 0);
+ if (!ast)
+ return AVERROR(ENOMEM);
+ ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ ast->codec->sample_rate = avio_rb16(pb);
+ ast->codec->bits_per_coded_sample = avio_r8(pb);
+ ast->codec->channels = avio_r8(pb);
+ ast->codec->codec_tag = avio_rl32(pb);
+ ast->codec->codec_id = ff_codec_get_id(codec_smjpeg_audio_tags,
+ ast->codec->codec_tag);
+ ast->duration = duration;
+ sc->audio_stream_index = ast->index;
+ avpriv_set_pts_info(ast, 32, 1, 1000);
+ avio_skip(pb, hlength - 8);
+ break;
+ case MKTAG('_', 'V', 'I', 'D'):
+ if (vst) {
+ av_log_ask_for_sample(s, "multiple video streams not supported\n");
+ return AVERROR_INVALIDDATA;
+ }
+ hlength = avio_rb32(pb);
+ if (hlength < 12)
+ return AVERROR_INVALIDDATA;
+ avio_skip(pb, 4); // number of frames
+ vst = avformat_new_stream(s, 0);
+ if (!vst)
+ return AVERROR(ENOMEM);
+ vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ vst->codec->width = avio_rb16(pb);
+ vst->codec->height = avio_rb16(pb);
+ vst->codec->codec_tag = avio_rl32(pb);
+ vst->codec->codec_id = ff_codec_get_id(codec_smjpeg_video_tags,
+ vst->codec->codec_tag);
+ vst->duration = duration;
+ sc->video_stream_index = vst->index;
+ avpriv_set_pts_info(vst, 32, 1, 1000);
+ avio_skip(pb, hlength - 12);
+ break;
+ case MKTAG('H', 'E', 'N', 'D'):
+ return 0;
+ default:
+ av_log(s, AV_LOG_ERROR, "unknown header %x\n", htype);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ return AVERROR_EOF;
+}
+
+static int smjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ SMJPEGContext *sc = s->priv_data;
+ uint32_t dtype, ret, size, timestamp;
+
+ if (s->pb->eof_reached)
+ return AVERROR_EOF;
+ dtype = avio_rl32(s->pb);
+ switch (dtype) {
+ case MKTAG('s', 'n', 'd', 'D'):
+ timestamp = avio_rb32(s->pb);
+ size = avio_rb32(s->pb);
+ ret = av_get_packet(s->pb, pkt, size);
+ pkt->stream_index = sc->audio_stream_index;
+ pkt->pts = timestamp;
+ break;
+ case MKTAG('v', 'i', 'd', 'D'):
+ timestamp = avio_rb32(s->pb);
+ size = avio_rb32(s->pb);
+ ret = av_get_packet(s->pb, pkt, size);
+ pkt->stream_index = sc->video_stream_index;
+ pkt->pts = timestamp;
+ break;
+ case MKTAG('D', 'O', 'N', 'E'):
+ ret = AVERROR_EOF;
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "unknown chunk %x\n", dtype);
+ ret = AVERROR_INVALIDDATA;
+ break;
+ }
+ return ret;
+}
+
+AVInputFormat ff_smjpeg_demuxer = {
+ .name = "smjpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("Loki SDL MJPEG"),
+ .priv_data_size = sizeof(SMJPEGContext),
+ .read_probe = smjpeg_probe,
+ .read_header = smjpeg_read_header,
+ .read_packet = smjpeg_read_packet,
+ .extensions = "mjpg",
+};
diff --git a/libavformat/sol.c b/libavformat/sol.c
index 1ebb4d2..31c84ce 100644
--- a/libavformat/sol.c
+++ b/libavformat/sol.c
@@ -23,8 +23,9 @@
* Based on documents from Game Audio Player and own research
*/
-#include "libavutil/bswap.h"
+#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#include "pcm.h"
/* if we don't know the size in advance */
@@ -33,8 +34,7 @@
static int sol_probe(AVProbeData *p)
{
/* check file header */
- uint16_t magic;
- magic=av_le2ne16(*((uint16_t*)p->buf));
+ uint16_t magic = AV_RL32(p->buf);
if ((magic == 0x0B8D || magic == 0x0C0D || magic == 0x0C8D) &&
p->buf[2] == 'S' && p->buf[3] == 'O' &&
p->buf[4] == 'L' && p->buf[5] == 0)
@@ -110,7 +110,7 @@ static int sol_read_header(AVFormatContext *s,
else id = 0;
/* now we are ready: build format streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -118,7 +118,7 @@ static int sol_read_header(AVFormatContext *s,
st->codec->codec_id = codec;
st->codec->channels = channels;
st->codec->sample_rate = rate;
- av_set_pts_info(st, 64, 1, rate);
+ avpriv_set_pts_info(st, 64, 1, rate);
return 0;
}
@@ -132,6 +132,8 @@ static int sol_read_packet(AVFormatContext *s,
if (s->pb->eof_reached)
return AVERROR(EIO);
ret= av_get_packet(s->pb, pkt, MAX_SIZE);
+ if (ret < 0)
+ return ret;
pkt->stream_index = 0;
/* note: we need to modify the packet size here to handle the last
@@ -141,12 +143,10 @@ static int sol_read_packet(AVFormatContext *s,
}
AVInputFormat ff_sol_demuxer = {
- "sol",
- NULL_IF_CONFIG_SMALL("Sierra SOL format"),
- 0,
- sol_probe,
- sol_read_header,
- sol_read_packet,
- NULL,
- pcm_read_seek,
+ .name = "sol",
+ .long_name = NULL_IF_CONFIG_SMALL("Sierra SOL format"),
+ .read_probe = sol_probe,
+ .read_header = sol_read_header,
+ .read_packet = sol_read_packet,
+ .read_seek = pcm_read_seek,
};
diff --git a/libavformat/soxdec.c b/libavformat/soxdec.c
index fb7b063..1074b3f 100644
--- a/libavformat/soxdec.c
+++ b/libavformat/soxdec.c
@@ -23,15 +23,17 @@
*/
/**
- * SoX native format demuxer
* @file
+ * SoX native format demuxer
* @author Daniel Verkamp
- * @sa http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format
+ * @see http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
#include "libavutil/dict.h"
#include "avformat.h"
+#include "internal.h"
#include "pcm.h"
#include "sox.h"
@@ -50,7 +52,7 @@ static int sox_read_header(AVFormatContext *s,
double sample_rate, sample_rate_frac;
AVStream *st;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -60,14 +62,14 @@ static int sox_read_header(AVFormatContext *s,
st->codec->codec_id = CODEC_ID_PCM_S32LE;
header_size = avio_rl32(pb);
avio_skip(pb, 8); /* sample count */
- sample_rate = av_int2dbl(avio_rl64(pb));
+ sample_rate = av_int2double(avio_rl64(pb));
st->codec->channels = avio_rl32(pb);
comment_size = avio_rl32(pb);
} else {
st->codec->codec_id = CODEC_ID_PCM_S32BE;
header_size = avio_rb32(pb);
avio_skip(pb, 8); /* sample count */
- sample_rate = av_int2dbl(avio_rb64(pb));
+ sample_rate = av_int2double(avio_rb64(pb));
st->codec->channels = avio_rb32(pb);
comment_size = avio_rb32(pb);
}
@@ -116,7 +118,7 @@ static int sox_read_header(AVFormatContext *s,
st->codec->block_align = st->codec->bits_per_coded_sample *
st->codec->channels / 8;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
return 0;
}
@@ -142,12 +144,10 @@ static int sox_read_packet(AVFormatContext *s,
}
AVInputFormat ff_sox_demuxer = {
- "sox",
- NULL_IF_CONFIG_SMALL("SoX native format"),
- 0,
- sox_probe,
- sox_read_header,
- sox_read_packet,
- NULL,
- pcm_read_seek,
+ .name = "sox",
+ .long_name = NULL_IF_CONFIG_SMALL("SoX native format"),
+ .read_probe = sox_probe,
+ .read_header = sox_read_header,
+ .read_packet = sox_read_packet,
+ .read_seek = pcm_read_seek,
};
diff --git a/libavformat/soxenc.c b/libavformat/soxenc.c
index 01d0cda..55d5bd9 100644
--- a/libavformat/soxenc.c
+++ b/libavformat/soxenc.c
@@ -23,13 +23,14 @@
*/
/**
- * SoX native format muxer
* @file
+ * SoX native format muxer
* @author Daniel Verkamp
- * @sa http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format
+ * @see http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
#include "libavutil/dict.h"
#include "avformat.h"
#include "avio_internal.h"
@@ -58,14 +59,14 @@ static int sox_write_header(AVFormatContext *s)
ffio_wfourcc(pb, ".SoX");
avio_wl32(pb, sox->header_size);
avio_wl64(pb, 0); /* number of samples */
- avio_wl64(pb, av_dbl2int(enc->sample_rate));
+ avio_wl64(pb, av_double2int(enc->sample_rate));
avio_wl32(pb, enc->channels);
avio_wl32(pb, comment_size);
} else if (enc->codec_id == CODEC_ID_PCM_S32BE) {
ffio_wfourcc(pb, "XoS.");
avio_wb32(pb, sox->header_size);
avio_wb64(pb, 0); /* number of samples */
- avio_wb64(pb, av_dbl2int(enc->sample_rate));
+ avio_wb64(pb, av_double2int(enc->sample_rate));
avio_wb32(pb, enc->channels);
avio_wb32(pb, comment_size);
} else {
@@ -115,14 +116,13 @@ static int sox_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_sox_muxer = {
- "sox",
- NULL_IF_CONFIG_SMALL("SoX native format"),
- NULL,
- "sox",
- sizeof(SoXContext),
- CODEC_ID_PCM_S32LE,
- CODEC_ID_NONE,
- sox_write_header,
- sox_write_packet,
- sox_write_trailer,
+ .name = "sox",
+ .long_name = NULL_IF_CONFIG_SMALL("SoX native format"),
+ .extensions = "sox",
+ .priv_data_size = sizeof(SoXContext),
+ .audio_codec = CODEC_ID_PCM_S32LE,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = sox_write_header,
+ .write_packet = sox_write_packet,
+ .write_trailer = sox_write_trailer,
};
diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c
index 1c09025..3daf23f 100644
--- a/libavformat/spdifdec.c
+++ b/libavformat/spdifdec.c
@@ -57,7 +57,7 @@ static int spdif_get_offset_and_codec(AVFormatContext *s,
break;
case IEC61937_MPEG2_AAC:
init_get_bits(&gbc, buf, AAC_ADTS_HEADER_SIZE * 8);
- if (ff_aac_parse_header(&gbc, &aac_hdr)) {
+ if (avpriv_aac_parse_header(&gbc, &aac_hdr)) {
if (s) /* be silent during a probe */
av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n");
return AVERROR_INVALIDDATA;
@@ -205,7 +205,7 @@ static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
if (!s->nb_streams) {
/* first packet, create a stream */
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st) {
av_free_packet(pkt);
return AVERROR(ENOMEM);
@@ -226,11 +226,10 @@ static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_spdif_demuxer = {
- "spdif",
- NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"),
- 0,
- spdif_probe,
- spdif_read_header,
- spdif_read_packet,
+ .name = "spdif",
+ .long_name = NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"),
+ .read_probe = spdif_probe,
+ .read_header = spdif_read_header,
+ .read_packet = spdif_read_packet,
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c
index 7355460..d541aba 100644
--- a/libavformat/spdifenc.c
+++ b/libavformat/spdifenc.c
@@ -86,10 +86,10 @@ typedef struct IEC61937Context {
} IEC61937Context;
static const AVOption options[] = {
-{ "spdif_flags", "IEC 61937 encapsulation flags", offsetof(IEC61937Context, spdif_flags), FF_OPT_TYPE_FLAGS, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "spdif_flags" },
-{ "be", "output in big-endian format (for use as s16be)", 0, FF_OPT_TYPE_CONST, {.dbl = SPDIF_FLAG_BIGENDIAN}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "spdif_flags" },
-{ "dtshd_rate", "mux complete DTS frames in HD mode at the specified IEC958 rate (in Hz, default 0=disabled)", offsetof(IEC61937Context, dtshd_rate), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 768000, AV_OPT_FLAG_ENCODING_PARAM },
-{ "dtshd_fallback_time", "min secs to strip HD for after an overflow (-1: till the end, default 60)", offsetof(IEC61937Context, dtshd_fallback), FF_OPT_TYPE_INT, {.dbl = 60}, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+{ "spdif_flags", "IEC 61937 encapsulation flags", offsetof(IEC61937Context, spdif_flags), AV_OPT_TYPE_FLAGS, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "spdif_flags" },
+{ "be", "output in big-endian format (for use as s16be)", 0, AV_OPT_TYPE_CONST, {.dbl = SPDIF_FLAG_BIGENDIAN}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "spdif_flags" },
+{ "dtshd_rate", "mux complete DTS frames in HD mode at the specified IEC958 rate (in Hz, default 0=disabled)", offsetof(IEC61937Context, dtshd_rate), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 768000, AV_OPT_FLAG_ENCODING_PARAM },
+{ "dtshd_fallback_time", "min secs to strip HD for after an overflow (-1: till the end, default 60)", offsetof(IEC61937Context, dtshd_fallback), AV_OPT_TYPE_INT, {.dbl = 60}, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
{ NULL },
};
@@ -349,7 +349,7 @@ static int spdif_header_aac(AVFormatContext *s, AVPacket *pkt)
int ret;
init_get_bits(&gbc, pkt->data, AAC_ADTS_HEADER_SIZE * 8);
- ret = ff_aac_parse_header(&gbc, &hdr);
+ ret = avpriv_aac_parse_header(&gbc, &hdr);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Wrong AAC file format\n");
return AVERROR_INVALIDDATA;
@@ -541,16 +541,15 @@ static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt)
}
AVOutputFormat ff_spdif_muxer = {
- "spdif",
- NULL_IF_CONFIG_SMALL("IEC 61937 (used on S/PDIF - IEC958)"),
- NULL,
- "spdif",
- sizeof(IEC61937Context),
- CODEC_ID_AC3,
- CODEC_ID_NONE,
- spdif_write_header,
- spdif_write_packet,
- spdif_write_trailer,
+ .name = "spdif",
+ .long_name = NULL_IF_CONFIG_SMALL("IEC 61937 (used on S/PDIF - IEC958)"),
+ .extensions = "spdif",
+ .priv_data_size = sizeof(IEC61937Context),
+ .audio_codec = CODEC_ID_AC3,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = spdif_write_header,
+ .write_packet = spdif_write_packet,
+ .write_trailer = spdif_write_trailer,
.flags = AVFMT_NOTIMESTAMPS,
.priv_class = &class,
};
diff --git a/libavformat/srtdec.c b/libavformat/srtdec.c
index 72c5c80..ca0a304 100644
--- a/libavformat/srtdec.c
+++ b/libavformat/srtdec.c
@@ -42,10 +42,10 @@ static int srt_probe(AVProbeData *p)
static int srt_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
if (!st)
return -1;
- av_set_pts_info(st, 64, 1, 1000);
+ avpriv_set_pts_info(st, 64, 1, 1000);
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codec->codec_id = CODEC_ID_SRT;
return 0;
diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c
index eec9524..1fc301b 100644
--- a/libavformat/swfdec.c
+++ b/libavformat/swfdec.c
@@ -106,12 +106,13 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
avio_rl16(pb);
avio_r8(pb);
/* Check for FLV1 */
- vst = av_new_stream(s, ch_id);
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return -1;
+ vst->id = ch_id;
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vst->codec->codec_id = ff_codec_get_id(swf_codec_tags, avio_r8(pb));
- av_set_pts_info(vst, 16, 256, swf->frame_rate);
+ avpriv_set_pts_info(vst, 16, 256, swf->frame_rate);
vst->codec->time_base = (AVRational){ 256, swf->frame_rate };
len -= 8;
} else if (tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) {
@@ -127,18 +128,20 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
avio_r8(pb);
v = avio_r8(pb);
swf->samples_per_frame = avio_rl16(pb);
- ast = av_new_stream(s, -1); /* -1 to avoid clash with video stream ch_id */
+ ast = avformat_new_stream(s, NULL);
if (!ast)
return -1;
+ ast->id = -1; /* -1 to avoid clash with video stream ch_id */
ast->codec->channels = 1 + (v&1);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
ast->codec->codec_id = ff_codec_get_id(swf_audio_codec_tags, (v>>4) & 15);
ast->need_parsing = AVSTREAM_PARSE_FULL;
sample_rate_code= (v>>2) & 3;
if (!sample_rate_code)
- return AVERROR(EIO);
- ast->codec->sample_rate = 11025 << (sample_rate_code-1);
- av_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
+ ast->codec->sample_rate = 5512;
+ else
+ ast->codec->sample_rate = 11025 << (sample_rate_code-1);
+ avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
len -= 4;
} else if (tag == TAG_VIDEOFRAME) {
int ch_id = avio_rl16(pb);
@@ -176,12 +179,13 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
break;
}
if (i == s->nb_streams) {
- vst = av_new_stream(s, -2); /* -2 to avoid clash with video stream and audio stream */
+ vst = avformat_new_stream(s, NULL);
if (!vst)
return -1;
+ vst->id = -2; /* -2 to avoid clash with video stream and audio stream */
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vst->codec->codec_id = CODEC_ID_MJPEG;
- av_set_pts_info(vst, 64, 256, swf->frame_rate);
+ avpriv_set_pts_info(vst, 64, 256, swf->frame_rate);
vst->codec->time_base = (AVRational){ 256, swf->frame_rate };
st = vst;
}
@@ -204,14 +208,13 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
skip:
avio_skip(pb, len);
}
- return 0;
}
AVInputFormat ff_swf_demuxer = {
- "swf",
- NULL_IF_CONFIG_SMALL("Flash format"),
- sizeof(SWFContext),
- swf_probe,
- swf_read_header,
- swf_read_packet,
+ .name = "swf",
+ .long_name = NULL_IF_CONFIG_SMALL("Flash format"),
+ .priv_data_size = sizeof(SWFContext),
+ .read_probe = swf_probe,
+ .read_header = swf_read_header,
+ .read_packet = swf_read_packet,
};
diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c
index 4c5c315..f4494cd 100644
--- a/libavformat/swfenc.c
+++ b/libavformat/swfenc.c
@@ -507,29 +507,28 @@ static int swf_write_trailer(AVFormatContext *s)
#if CONFIG_SWF_MUXER
AVOutputFormat ff_swf_muxer = {
- "swf",
- NULL_IF_CONFIG_SMALL("Flash format"),
- "application/x-shockwave-flash",
- "swf",
- sizeof(SWFContext),
- CODEC_ID_MP3,
- CODEC_ID_FLV1,
- swf_write_header,
- swf_write_packet,
- swf_write_trailer,
+ .name = "swf",
+ .long_name = NULL_IF_CONFIG_SMALL("Flash format"),
+ .mime_type = "application/x-shockwave-flash",
+ .extensions = "swf",
+ .priv_data_size = sizeof(SWFContext),
+ .audio_codec = CODEC_ID_MP3,
+ .video_codec = CODEC_ID_FLV1,
+ .write_header = swf_write_header,
+ .write_packet = swf_write_packet,
+ .write_trailer = swf_write_trailer,
};
#endif
#if CONFIG_AVM2_MUXER
AVOutputFormat ff_avm2_muxer = {
- "avm2",
- NULL_IF_CONFIG_SMALL("Flash 9 (AVM2) format"),
- "application/x-shockwave-flash",
- NULL,
- sizeof(SWFContext),
- CODEC_ID_MP3,
- CODEC_ID_FLV1,
- swf_write_header,
- swf_write_packet,
- swf_write_trailer,
+ .name = "avm2",
+ .long_name = NULL_IF_CONFIG_SMALL("Flash 9 (AVM2) format"),
+ .mime_type = "application/x-shockwave-flash",
+ .priv_data_size = sizeof(SWFContext),
+ .audio_codec = CODEC_ID_MP3,
+ .video_codec = CODEC_ID_FLV1,
+ .write_header = swf_write_header,
+ .write_packet = swf_write_packet,
+ .write_trailer = swf_write_trailer,
};
#endif
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index e602a55..0d3aeaf 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -39,7 +39,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
{
struct addrinfo hints, *ai, *cur_ai;
int port, fd = -1;
- TCPContext *s = NULL;
+ TCPContext *s = h->priv_data;
int listen_socket = 0;
const char *p;
char buf[256];
@@ -100,7 +100,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
struct pollfd p = {fd, POLLOUT, 0};
ret = ff_neterrno();
if (ret == AVERROR(EINTR)) {
- if (url_interrupt_cb()) {
+ if (ff_check_interrupt(&h->interrupt_callback)) {
ret = AVERROR_EXIT;
goto fail1;
}
@@ -112,7 +112,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
/* wait until we are connected or until abort */
while(timeout--) {
- if (url_interrupt_cb()) {
+ if (ff_check_interrupt(&h->interrupt_callback)) {
ret = AVERROR_EXIT;
goto fail1;
}
@@ -135,12 +135,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
goto fail;
}
}
- s = av_malloc(sizeof(TCPContext));
- if (!s) {
- freeaddrinfo(ai);
- return AVERROR(ENOMEM);
- }
- h->priv_data = s;
h->is_streamed = 1;
s->fd = fd;
freeaddrinfo(ai);
@@ -193,7 +187,6 @@ static int tcp_close(URLContext *h)
{
TCPContext *s = h->priv_data;
closesocket(s->fd);
- av_free(s);
return 0;
}
@@ -210,4 +203,5 @@ URLProtocol ff_tcp_protocol = {
.url_write = tcp_write,
.url_close = tcp_close,
.url_get_file_handle = tcp_get_file_handle,
+ .priv_data_size = sizeof(TCPContext),
};
diff --git a/libavformat/thp.c b/libavformat/thp.c
index 6cdcefd..25efcbb 100644
--- a/libavformat/thp.c
+++ b/libavformat/thp.c
@@ -20,7 +20,9 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
#include "avformat.h"
+#include "internal.h"
typedef struct ThpDemuxContext {
int version;
@@ -67,7 +69,7 @@ static int thp_read_header(AVFormatContext *s,
avio_rb32(pb); /* Max buf size. */
avio_rb32(pb); /* Max samples. */
- thp->fps = av_d2q(av_int2flt(avio_rb32(pb)), INT_MAX);
+ thp->fps = av_d2q(av_int2float(avio_rb32(pb)), INT_MAX);
thp->framecnt = avio_rb32(pb);
thp->first_framesz = avio_rb32(pb);
avio_rb32(pb); /* Data size. */
@@ -93,13 +95,13 @@ static int thp_read_header(AVFormatContext *s,
break;
/* Video component. */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
/* The denominator and numerator are switched because 1/fps
is required. */
- av_set_pts_info(st, 64, thp->fps.den, thp->fps.num);
+ avpriv_set_pts_info(st, 64, thp->fps.den, thp->fps.num);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_THP;
st->codec->codec_tag = 0; /* no fourcc */
@@ -116,7 +118,7 @@ static int thp_read_header(AVFormatContext *s,
break;
/* Audio component. */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -126,7 +128,7 @@ static int thp_read_header(AVFormatContext *s,
st->codec->channels = avio_rb32(pb); /* numChannels. */
st->codec->sample_rate = avio_rb32(pb); /* Frequency. */
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
thp->audio_stream_index = st->index;
thp->has_audio = 1;
@@ -188,10 +190,10 @@ static int thp_read_packet(AVFormatContext *s,
}
AVInputFormat ff_thp_demuxer = {
- "thp",
- NULL_IF_CONFIG_SMALL("THP"),
- sizeof(ThpDemuxContext),
- thp_probe,
- thp_read_header,
- thp_read_packet
+ .name = "thp",
+ .long_name = NULL_IF_CONFIG_SMALL("THP"),
+ .priv_data_size = sizeof(ThpDemuxContext),
+ .read_probe = thp_probe,
+ .read_header = thp_read_header,
+ .read_packet = thp_read_packet
};
diff --git a/libavformat/tiertexseq.c b/libavformat/tiertexseq.c
index 7ca0464..0590190 100644
--- a/libavformat/tiertexseq.c
+++ b/libavformat/tiertexseq.c
@@ -25,6 +25,7 @@
*/
#include "avformat.h"
+#include "internal.h"
#define SEQ_FRAME_SIZE 6144
#define SEQ_FRAME_W 256
@@ -206,11 +207,11 @@ static int seq_read_header(AVFormatContext *s, AVFormatParameters *ap)
seq->audio_buffer_full = 0;
/* initialize the video decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 32, 1, SEQ_FRAME_RATE);
+ avpriv_set_pts_info(st, 32, 1, SEQ_FRAME_RATE);
seq->video_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_TIERTEXSEQVIDEO;
@@ -219,11 +220,11 @@ static int seq_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->codec->height = SEQ_FRAME_H;
/* initialize the audio decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 32, 1, SEQ_SAMPLE_RATE);
+ avpriv_set_pts_info(st, 32, 1, SEQ_SAMPLE_RATE);
seq->audio_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_PCM_S16BE;
@@ -303,11 +304,11 @@ static int seq_read_close(AVFormatContext *s)
}
AVInputFormat ff_tiertexseq_demuxer = {
- "tiertexseq",
- NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ format"),
- sizeof(SeqDemuxContext),
- seq_probe,
- seq_read_header,
- seq_read_packet,
- seq_read_close,
+ .name = "tiertexseq",
+ .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ format"),
+ .priv_data_size = sizeof(SeqDemuxContext),
+ .read_probe = seq_probe,
+ .read_header = seq_read_header,
+ .read_packet = seq_read_packet,
+ .read_close = seq_read_close,
};
diff --git a/libavformat/timefilter.c b/libavformat/timefilter.c
deleted file mode 100644
index 4860a4f..0000000
--- a/libavformat/timefilter.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Delay Locked Loop based time filter
- * Copyright (c) 2009 Samalyse
- * Copyright (c) 2009 Michael Niedermayer
- * Author: Olivier Guilyardi <olivier samalyse com>
- * Michael Niedermayer <michaelni gmx at>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-#include "config.h"
-#include "avformat.h"
-#include "timefilter.h"
-
-struct TimeFilter {
- /// Delay Locked Loop data. These variables refer to mathematical
- /// concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf
- double cycle_time;
- double feedback2_factor;
- double feedback3_factor;
- double clock_period;
- int count;
-};
-
-TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor)
-{
- TimeFilter *self = av_mallocz(sizeof(TimeFilter));
- self->clock_period = clock_period;
- self->feedback2_factor = feedback2_factor;
- self->feedback3_factor = feedback3_factor;
- return self;
-}
-
-void ff_timefilter_destroy(TimeFilter *self)
-{
- av_freep(&self);
-}
-
-void ff_timefilter_reset(TimeFilter *self)
-{
- self->count = 0;
-}
-
-double ff_timefilter_update(TimeFilter *self, double system_time, double period)
-{
- self->count++;
- if (self->count==1) {
- /// init loop
- self->cycle_time = system_time;
- } else {
- double loop_error;
- self->cycle_time += self->clock_period * period;
- /// calculate loop error
- loop_error = system_time - self->cycle_time;
-
- /// update loop
- self->cycle_time += FFMAX(self->feedback2_factor, 1.0/(self->count)) * loop_error;
- self->clock_period += self->feedback3_factor * loop_error / period;
- }
- return self->cycle_time;
-}
-
-#ifdef TEST
-#include "libavutil/lfg.h"
-#define LFG_MAX ((1LL << 32) - 1)
-
-#undef printf
-
-int main(void)
-{
- AVLFG prng;
- double n0,n1;
-#define SAMPLES 1000
- double ideal[SAMPLES];
- double samples[SAMPLES];
-#if 1
- for(n0= 0; n0<40; n0=2*n0+1){
- for(n1= 0; n1<10; n1=2*n1+1){
-#else
- {{
- n0=7;
- n1=1;
-#endif
- double best_error= 1000000000;
- double bestpar0=1;
- double bestpar1=0.001;
- int better, i;
-
- av_lfg_init(&prng, 123);
- for(i=0; i<SAMPLES; i++){
- ideal[i] = 10 + i + n1*i/(1000);
- samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2)
- / (LFG_MAX * 10LL);
- }
-
- do{
- double par0, par1;
- better=0;
- for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){
- for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){
- double error=0;
- TimeFilter *tf= ff_timefilter_new(1, par0, par1);
- for(i=0; i<SAMPLES; i++){
- double filtered;
- filtered= ff_timefilter_update(tf, samples[i], 1);
- error += (filtered - ideal[i]) * (filtered - ideal[i]);
- }
- ff_timefilter_destroy(tf);
- if(error < best_error){
- best_error= error;
- bestpar0= par0;
- bestpar1= par1;
- better=1;
- }
- }
- }
- }while(better);
-#if 0
- double lastfil=9;
- TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1);
- for(i=0; i<SAMPLES; i++){
- double filtered;
- filtered= ff_timefilter_update(tf, samples[i], 1);
- printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil);
- lastfil= filtered;
- }
- ff_timefilter_destroy(tf);
-#else
- printf(" [%f %f %9f]", bestpar0, bestpar1, best_error);
-#endif
- }
- printf("\n");
- }
- return 0;
-}
-#endif
diff --git a/libavformat/timefilter.h b/libavformat/timefilter.h
deleted file mode 100644
index aa7db53..0000000
--- a/libavformat/timefilter.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Delay Locked Loop based time filter prototypes and declarations
- * Copyright (c) 2009 Samalyse
- * Copyright (c) 2009 Michael Niedermayer
- * Author: Olivier Guilyardi <olivier samalyse com>
- * Michael Niedermayer <michaelni gmx at>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVFORMAT_TIMEFILTER_H
-#define AVFORMAT_TIMEFILTER_H
-
-/**
- * Opaque type representing a time filter state
- *
- * The purpose of this filter is to provide a way to compute accurate time
- * stamps that can be compared to wall clock time, especially when dealing
- * with two clocks: the system clock and a hardware device clock, such as
- * a soundcard.
- */
-typedef struct TimeFilter TimeFilter;
-
-
-/**
- * Create a new Delay Locked Loop time filter
- *
- * feedback2_factor and feedback3_factor are the factors used for the
- * multiplications that are respectively performed in the second and third
- * feedback paths of the loop.
- *
- * Unless you know what you are doing, you should set these as follow:
- *
- * o = 2 * M_PI * bandwidth * period
- * feedback2_factor = sqrt(2 * o)
- * feedback3_factor = o * o
- *
- * Where bandwidth is up to you to choose. Smaller values will filter out more
- * of the jitter, but also take a longer time for the loop to settle. A good
- * starting point is something between 0.3 and 3 Hz.
- *
- * @param clock_period period of the hardware clock in seconds
- * (for example 1.0/44100)
- *
- * For more details about these parameters and background concepts please see:
- * http://www.kokkinizita.net/papers/usingdll.pdf
- */
-TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor);
-
-/**
- * Update the filter
- *
- * This function must be called in real time, at each process cycle.
- *
- * @param period the device cycle duration in clock_periods. For example, at
- * 44.1kHz and a buffer size of 512 frames, period = 512 when clock_period
- * was 1.0/44100, or 512/44100 if clock_period was 1.
- *
- * system_time, in seconds, should be the value of the system clock time,
- * at (or as close as possible to) the moment the device hardware interrupt
- * occured (or any other event the device clock raises at the beginning of a
- * cycle).
- *
- * @return the filtered time, in seconds
- */
-double ff_timefilter_update(TimeFilter *self, double system_time, double period);
-
-/**
- * Reset the filter
- *
- * This function should mainly be called in case of XRUN.
- *
- * Warning: after calling this, the filter is in an undetermined state until
- * the next call to ff_timefilter_update()
- */
-void ff_timefilter_reset(TimeFilter *);
-
-/**
- * Free all resources associated with the filter
- */
-void ff_timefilter_destroy(TimeFilter *);
-
-#endif /* AVFORMAT_TIMEFILTER_H */
diff --git a/libavformat/tls.c b/libavformat/tls.c
new file mode 100644
index 0000000..26f5ee5
--- /dev/null
+++ b/libavformat/tls.c
@@ -0,0 +1,251 @@
+/*
+ * TLS/SSL Protocol
+ * Copyright (c) 2011 Martin Storsjo
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "url.h"
+#include "libavutil/avstring.h"
+#if CONFIG_GNUTLS
+#include <gnutls/gnutls.h>
+#define TLS_read(c, buf, size) gnutls_record_recv(c->session, buf, size)
+#define TLS_write(c, buf, size) gnutls_record_send(c->session, buf, size)
+#define TLS_shutdown(c) gnutls_bye(c->session, GNUTLS_SHUT_RDWR)
+#define TLS_free(c) do { \
+ if (c->session) \
+ gnutls_deinit(c->session); \
+ if (c->cred) \
+ gnutls_certificate_free_credentials(c->cred); \
+ } while (0)
+#elif CONFIG_OPENSSL
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#define TLS_read(c, buf, size) SSL_read(c->ssl, buf, size)
+#define TLS_write(c, buf, size) SSL_write(c->ssl, buf, size)
+#define TLS_shutdown(c) SSL_shutdown(c->ssl)
+#define TLS_free(c) do { \
+ if (c->ssl) \
+ SSL_free(c->ssl); \
+ if (c->ctx) \
+ SSL_CTX_free(c->ctx); \
+ } while (0)
+#endif
+#include "network.h"
+#include "os_support.h"
+#include "internal.h"
+#if HAVE_POLL_H
+#include <poll.h>
+#endif
+
+typedef struct {
+ const AVClass *class;
+ URLContext *tcp;
+#if CONFIG_GNUTLS
+ gnutls_session_t session;
+ gnutls_certificate_credentials_t cred;
+#elif CONFIG_OPENSSL
+ SSL_CTX *ctx;
+ SSL *ssl;
+#endif
+ int fd;
+} TLSContext;
+
+static int do_tls_poll(URLContext *h, int ret)
+{
+ TLSContext *c = h->priv_data;
+ struct pollfd p = { c->fd, 0, 0 };
+#if CONFIG_GNUTLS
+ if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED) {
+ av_log(h, AV_LOG_ERROR, "%s\n", gnutls_strerror(ret));
+ return AVERROR(EIO);
+ }
+ if (gnutls_record_get_direction(c->session))
+ p.events = POLLOUT;
+ else
+ p.events = POLLIN;
+#elif CONFIG_OPENSSL
+ ret = SSL_get_error(c->ssl, ret);
+ if (ret == SSL_ERROR_WANT_READ) {
+ p.events = POLLIN;
+ } else if (ret == SSL_ERROR_WANT_WRITE) {
+ p.events = POLLOUT;
+ } else {
+ av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
+ return AVERROR(EIO);
+ }
+#endif
+ if (h->flags & AVIO_FLAG_NONBLOCK)
+ return AVERROR(EAGAIN);
+ while (1) {
+ int n = poll(&p, 1, 100);
+ if (n > 0)
+ break;
+ if (ff_check_interrupt(&h->interrupt_callback))
+ return AVERROR(EINTR);
+ }
+ return 0;
+}
+
+static int tls_open(URLContext *h, const char *uri, int flags)
+{
+ TLSContext *c = h->priv_data;
+ int ret;
+ int port;
+ char buf[200], host[200];
+ int numerichost = 0;
+ struct addrinfo hints = { 0 }, *ai = NULL;
+ const char *proxy_path;
+ int use_proxy;
+
+ ff_tls_init();
+
+ proxy_path = getenv("http_proxy");
+ use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
+ av_strstart(proxy_path, "http://", NULL);
+
+ av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri);
+ ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, NULL);
+
+ hints.ai_flags = AI_NUMERICHOST;
+ if (!getaddrinfo(host, NULL, &hints, &ai)) {
+ numerichost = 1;
+ freeaddrinfo(ai);
+ }
+
+ if (use_proxy) {
+ char proxy_host[200], proxy_auth[200], dest[200];
+ int proxy_port;
+ av_url_split(NULL, 0, proxy_auth, sizeof(proxy_auth),
+ proxy_host, sizeof(proxy_host), &proxy_port, NULL, 0,
+ proxy_path);
+ ff_url_join(dest, sizeof(dest), NULL, NULL, host, port, NULL);
+ ff_url_join(buf, sizeof(buf), "httpproxy", proxy_auth, proxy_host,
+ proxy_port, "/%s", dest);
+ }
+
+ ret = ffurl_open(&c->tcp, buf, AVIO_FLAG_READ_WRITE,
+ &h->interrupt_callback, NULL);
+ if (ret)
+ goto fail;
+ c->fd = ffurl_get_file_handle(c->tcp);
+
+#if CONFIG_GNUTLS
+ gnutls_init(&c->session, GNUTLS_CLIENT);
+ if (!numerichost)
+ gnutls_server_name_set(c->session, GNUTLS_NAME_DNS, host, strlen(host));
+ gnutls_certificate_allocate_credentials(&c->cred);
+ gnutls_certificate_set_verify_flags(c->cred, 0);
+ gnutls_credentials_set(c->session, GNUTLS_CRD_CERTIFICATE, c->cred);
+ gnutls_transport_set_ptr(c->session, (gnutls_transport_ptr_t)
+ (intptr_t) c->fd);
+ gnutls_priority_set_direct(c->session, "NORMAL", NULL);
+ while (1) {
+ ret = gnutls_handshake(c->session);
+ if (ret == 0)
+ break;
+ if ((ret = do_tls_poll(h, ret)) < 0)
+ goto fail;
+ }
+#elif CONFIG_OPENSSL
+ c->ctx = SSL_CTX_new(TLSv1_client_method());
+ if (!c->ctx) {
+ av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+ c->ssl = SSL_new(c->ctx);
+ if (!c->ssl) {
+ av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+ SSL_set_fd(c->ssl, c->fd);
+ if (!numerichost)
+ SSL_set_tlsext_host_name(c->ssl, host);
+ while (1) {
+ ret = SSL_connect(c->ssl);
+ if (ret > 0)
+ break;
+ if (ret == 0) {
+ av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
+ ret = AVERROR(EIO);
+ goto fail;
+ }
+ if ((ret = do_tls_poll(h, ret)) < 0)
+ goto fail;
+ }
+#endif
+ return 0;
+fail:
+ TLS_free(c);
+ if (c->tcp)
+ ffurl_close(c->tcp);
+ ff_tls_deinit();
+ return ret;
+}
+
+static int tls_read(URLContext *h, uint8_t *buf, int size)
+{
+ TLSContext *c = h->priv_data;
+ while (1) {
+ int ret = TLS_read(c, buf, size);
+ if (ret > 0)
+ return ret;
+ if (ret == 0)
+ return AVERROR(EIO);
+ if ((ret = do_tls_poll(h, ret)) < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int tls_write(URLContext *h, const uint8_t *buf, int size)
+{
+ TLSContext *c = h->priv_data;
+ while (1) {
+ int ret = TLS_write(c, buf, size);
+ if (ret > 0)
+ return ret;
+ if (ret == 0)
+ return AVERROR(EIO);
+ if ((ret = do_tls_poll(h, ret)) < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int tls_close(URLContext *h)
+{
+ TLSContext *c = h->priv_data;
+ TLS_shutdown(c);
+ TLS_free(c);
+ ffurl_close(c->tcp);
+ ff_tls_deinit();
+ return 0;
+}
+
+URLProtocol ff_tls_protocol = {
+ .name = "tls",
+ .url_open = tls_open,
+ .url_read = tls_read,
+ .url_write = tls_write,
+ .url_close = tls_close,
+ .priv_data_size = sizeof(TLSContext),
+};
diff --git a/libavformat/tmv.c b/libavformat/tmv.c
index f894eab..73b44bb 100644
--- a/libavformat/tmv.c
+++ b/libavformat/tmv.c
@@ -20,14 +20,15 @@
*/
/**
- * 8088flex TMV file demuxer
* @file
+ * 8088flex TMV file demuxer
* @author Daniel Verkamp
- * @sa http://www.oldskool.org/pc/8088_Corruption
+ * @see http://www.oldskool.org/pc/8088_Corruption
*/
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
enum {
TMV_PADDING = 0x01,
@@ -73,10 +74,10 @@ static int tmv_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (avio_rl32(pb) != TMV_TAG)
return -1;
- if (!(vst = av_new_stream(s, 0)))
+ if (!(vst = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
- if (!(ast = av_new_stream(s, 0)))
+ if (!(ast = avformat_new_stream(s, NULL)))
return AVERROR(ENOMEM);
ast->codec->sample_rate = avio_rl16(pb);
@@ -115,7 +116,7 @@ static int tmv_read_header(AVFormatContext *s, AVFormatParameters *ap)
ast->codec->bits_per_coded_sample = 8;
ast->codec->bit_rate = ast->codec->sample_rate *
ast->codec->bits_per_coded_sample;
- av_set_pts_info(ast, 32, 1, ast->codec->sample_rate);
+ avpriv_set_pts_info(ast, 32, 1, ast->codec->sample_rate);
fps.num = ast->codec->sample_rate * ast->codec->channels;
fps.den = tmv->audio_chunk_size;
@@ -126,7 +127,7 @@ static int tmv_read_header(AVFormatContext *s, AVFormatParameters *ap)
vst->codec->pix_fmt = PIX_FMT_PAL8;
vst->codec->width = char_cols * 8;
vst->codec->height = char_rows * 8;
- av_set_pts_info(vst, 32, fps.den, fps.num);
+ avpriv_set_pts_info(vst, 32, fps.den, fps.num);
if (features & TMV_PADDING)
tmv->padding =
@@ -179,13 +180,12 @@ static int tmv_read_seek(AVFormatContext *s, int stream_index,
}
AVInputFormat ff_tmv_demuxer = {
- "tmv",
- NULL_IF_CONFIG_SMALL("8088flex TMV"),
- sizeof(TMVContext),
- tmv_probe,
- tmv_read_header,
- tmv_read_packet,
- NULL,
- tmv_read_seek,
+ .name = "tmv",
+ .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"),
+ .priv_data_size = sizeof(TMVContext),
+ .read_probe = tmv_probe,
+ .read_header = tmv_read_header,
+ .read_packet = tmv_read_packet,
+ .read_seek = tmv_read_seek,
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/tta.c b/libavformat/tta.c
index 49234a8..37a359b 100644
--- a/libavformat/tta.c
+++ b/libavformat/tta.c
@@ -21,6 +21,7 @@
#include "libavcodec/get_bits.h"
#include "avformat.h"
+#include "internal.h"
#include "id3v1.h"
#include "libavutil/dict.h"
@@ -77,11 +78,11 @@ static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap)
return -1;
}
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 64, 1, samplerate);
+ avpriv_set_pts_info(st, 64, 1, samplerate);
st->start_time = 0;
st->duration = datalen;
@@ -107,6 +108,10 @@ static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap)
return -1;
}
st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codec->extradata) {
+ st->codec->extradata_size = 0;
+ return AVERROR(ENOMEM);
+ }
avio_seek(s->pb, start_offset, SEEK_SET);
avio_read(s->pb, st->codec->extradata, st->codec->extradata_size);
@@ -145,13 +150,12 @@ static int tta_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
}
AVInputFormat ff_tta_demuxer = {
- "tta",
- NULL_IF_CONFIG_SMALL("True Audio"),
- sizeof(TTAContext),
- tta_probe,
- tta_read_header,
- tta_read_packet,
- NULL,
- tta_read_seek,
+ .name = "tta",
+ .long_name = NULL_IF_CONFIG_SMALL("True Audio"),
+ .priv_data_size = sizeof(TTAContext),
+ .read_probe = tta_probe,
+ .read_header = tta_read_header,
+ .read_packet = tta_read_packet,
+ .read_seek = tta_read_seek,
.extensions = "tta",
};
diff --git a/libavformat/tty.c b/libavformat/tty.c
index ee6b2f1..8041900 100644
--- a/libavformat/tty.c
+++ b/libavformat/tty.c
@@ -31,6 +31,7 @@
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "avformat.h"
+#include "internal.h"
#include "sauce.h"
typedef struct {
@@ -76,7 +77,7 @@ static int read_header(AVFormatContext *avctx,
{
TtyDemuxContext *s = avctx->priv_data;
int width = 0, height = 0, ret = 0;
- AVStream *st = av_new_stream(avctx, 0);
+ AVStream *st = avformat_new_stream(avctx, NULL);
AVRational framerate;
if (!st) {
@@ -95,23 +96,11 @@ static int read_header(AVFormatContext *avctx,
av_log(avctx, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s->framerate);
goto fail;
}
-#if FF_API_FORMAT_PARAMETERS
- if (ap->width > 0)
- width = ap->width;
- if (ap->height > 0)
- height = ap->height;
- if (ap->time_base.num)
- framerate = (AVRational){ap->time_base.den, ap->time_base.num};
-#endif
st->codec->width = width;
st->codec->height = height;
- av_set_pts_info(st, 60, framerate.den, framerate.num);
+ avpriv_set_pts_info(st, 60, framerate.den, framerate.num);
/* simulate tty display speed */
-#if FF_API_FORMAT_PARAMETERS
- if (ap->sample_rate)
- s->chars_per_frame = ap->sample_rate;
-#endif
s->chars_per_frame = FFMAX(av_q2d(st->time_base)*s->chars_per_frame, 1);
if (avctx->pb->seekable) {
@@ -154,9 +143,9 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt)
#define OFFSET(x) offsetof(TtyDemuxContext, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "chars_per_frame", "", offsetof(TtyDemuxContext, chars_per_frame), FF_OPT_TYPE_INT, {.dbl = 6000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM},
- { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
- { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+ { "chars_per_frame", "", offsetof(TtyDemuxContext, chars_per_frame), AV_OPT_TYPE_INT, {.dbl = 6000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM},
+ { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
{ NULL },
};
diff --git a/libavformat/txd.c b/libavformat/txd.c
index 0a93b7c..a601ea0 100644
--- a/libavformat/txd.c
+++ b/libavformat/txd.c
@@ -40,7 +40,7 @@ static int txd_probe(AVProbeData * pd) {
static int txd_read_header(AVFormatContext *s, AVFormatParameters *ap) {
AVStream *st;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -90,12 +90,10 @@ next_chunk:
return 0;
}
-AVInputFormat ff_txd_demuxer =
-{
- "txd",
- NULL_IF_CONFIG_SMALL("Renderware TeXture Dictionary"),
- 0,
- txd_probe,
- txd_read_header,
- txd_read_packet,
+AVInputFormat ff_txd_demuxer = {
+ .name = "txd",
+ .long_name = NULL_IF_CONFIG_SMALL("Renderware TeXture Dictionary"),
+ .read_probe = txd_probe,
+ .read_header = txd_read_header,
+ .read_packet = txd_read_packet,
};
diff --git a/libavformat/udp.c b/libavformat/udp.c
index d6522bf..2bdd3dc 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -29,6 +29,7 @@
#include "avformat.h"
#include "avio_internal.h"
#include "libavutil/parseutils.h"
+#include "libavutil/avstring.h"
#include <unistd.h>
#include "internal.h"
#include "network.h"
@@ -178,8 +179,8 @@ static int udp_set_url(struct sockaddr_storage *addr,
return addr_len;
}
-static int udp_socket_create(UDPContext *s,
- struct sockaddr_storage *addr, int *addr_len)
+static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr,
+ int *addr_len, const char *localaddr)
{
int udp_fd = -1;
struct addrinfo *res0 = NULL, *res = NULL;
@@ -187,7 +188,8 @@ static int udp_socket_create(UDPContext *s,
if (((struct sockaddr *) &s->dest_addr)->sa_family)
family = ((struct sockaddr *) &s->dest_addr)->sa_family;
- res0 = udp_resolve_host(0, s->local_port, SOCK_DGRAM, family, AI_PASSIVE);
+ res0 = udp_resolve_host(localaddr[0] ? localaddr : NULL, s->local_port,
+ SOCK_DGRAM, family, AI_PASSIVE);
if (res0 == 0)
goto fail;
for (res = res0; res; res=res->ai_next) {
@@ -302,9 +304,9 @@ static int udp_get_file_handle(URLContext *h)
/* return non zero if error */
static int udp_open(URLContext *h, const char *uri, int flags)
{
- char hostname[1024];
+ char hostname[1024], localaddr[1024] = "";
int port, udp_fd = -1, tmp, bind_ret = -1;
- UDPContext *s = NULL;
+ UDPContext *s = h->priv_data;
int is_output;
const char *p;
char buf[256];
@@ -317,18 +319,13 @@ static int udp_open(URLContext *h, const char *uri, int flags)
is_output = !(flags & AVIO_FLAG_READ);
- s = av_mallocz(sizeof(UDPContext));
- if (!s)
- return AVERROR(ENOMEM);
-
- h->priv_data = s;
s->ttl = 16;
s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE;
p = strchr(uri, '?');
if (p) {
if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) {
- const char *endptr=NULL;
+ char *endptr = NULL;
s->reuse_socket = strtol(buf, &endptr, 10);
/* assume if no digits were found it is a request to enable it */
if (buf == endptr)
@@ -350,6 +347,9 @@ static int udp_open(URLContext *h, const char *uri, int flags)
if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
s->is_connected = strtol(buf, NULL, 10);
}
+ if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
+ av_strlcpy(localaddr, buf, sizeof(localaddr));
+ }
}
/* fill the dest addr */
@@ -365,14 +365,14 @@ static int udp_open(URLContext *h, const char *uri, int flags)
goto fail;
}
- if (s->is_multicast && (h->flags & AVIO_FLAG_READ))
+ if ((s->is_multicast || !s->local_port) && (h->flags & AVIO_FLAG_READ))
s->local_port = port;
- udp_fd = udp_socket_create(s, &my_addr, &len);
+ udp_fd = udp_socket_create(s, &my_addr, &len, localaddr);
if (udp_fd < 0)
goto fail;
/* Follow the requested reuse option, unless it's multicast in which
- * case enable reuse unless explicitely disabled.
+ * case enable reuse unless explicitly disabled.
*/
if (s->reuse_socket || (s->is_multicast && !reuse_specified)) {
s->reuse_socket = 1;
@@ -435,7 +435,6 @@ static int udp_open(URLContext *h, const char *uri, int flags)
fail:
if (udp_fd >= 0)
closesocket(udp_fd);
- av_free(s);
return AVERROR(EIO);
}
@@ -481,7 +480,6 @@ static int udp_close(URLContext *h)
if (s->is_multicast && (h->flags & AVIO_FLAG_READ))
udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);
closesocket(s->udp_fd);
- av_free(s);
return 0;
}
@@ -492,4 +490,5 @@ URLProtocol ff_udp_protocol = {
.url_write = udp_write,
.url_close = udp_close,
.url_get_file_handle = udp_get_file_handle,
+ .priv_data_size = sizeof(UDPContext),
};
diff --git a/libavformat/url.h b/libavformat/url.h
index caafe07..ea8c7ab 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -28,11 +28,16 @@
#include "avio.h"
#include "libavformat/version.h"
+#include "libavutil/dict.h"
+#include "libavutil/log.h"
+
#if !FF_API_OLD_AVIO
#define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */
extern int (*url_interrupt_cb)(void);
+extern const AVClass ffurl_context_class;
+
typedef struct URLContext {
const AVClass *av_class; /**< information for av_log(). Set by url_open(). */
struct URLProtocol *prot;
@@ -42,11 +47,18 @@ typedef struct URLContext {
int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */
int is_streamed; /**< true if streamed (no seek possible), default = false */
int is_connected;
+ AVIOInterruptCB interrupt_callback;
} URLContext;
typedef struct URLProtocol {
const char *name;
int (*url_open)( URLContext *h, const char *url, int flags);
+ /**
+ * This callback is to be used by protocols which open further nested
+ * protocols. options are then to be passed to ffurl_open()/ffurl_connect()
+ * for those nested protocols.
+ */
+ int (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options);
int (*url_read)( URLContext *h, unsigned char *buf, int size);
int (*url_write)(URLContext *h, const unsigned char *buf, int size);
int64_t (*url_seek)( URLContext *h, int64_t pos, int whence);
@@ -71,15 +83,23 @@ typedef struct URLProtocol {
* function puts the pointer to the created URLContext
* @param flags flags which control how the resource indicated by url
* is to be opened
+ * @param int_cb interrupt callback to use for the URLContext, may be
+ * NULL
* @return 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
-int ffurl_alloc(URLContext **h, const char *url, int flags);
+int ffurl_alloc(URLContext **puc, const char *filename, int flags,
+ const AVIOInterruptCB *int_cb);
/**
* Connect an URLContext that has been allocated by ffurl_alloc
+ *
+ * @param options A dictionary filled with options for nested protocols,
+ * i.e. it will be passed to url_open2() for protocols implementing it.
+ * This parameter will be destroyed and replaced with a dict containing options
+ * that were not found. May be NULL.
*/
-int ffurl_connect(URLContext *h);
+int ffurl_connect(URLContext *uc, AVDictionary **options);
/**
* Create an URLContext for accessing to the resource indicated by
@@ -89,10 +109,16 @@ int ffurl_connect(URLContext *h);
* function puts the pointer to the created URLContext
* @param flags flags which control how the resource indicated by url
* is to be opened
+ * @param int_cb interrupt callback to use for the URLContext, may be
+ * NULL
+ * @param options A dictionary filled with protocol-private options. On return
+ * this parameter will be destroyed and replaced with a dict containing options
+ * that were not found. May be NULL.
* @return 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
-int ffurl_open(URLContext **h, const char *url, int flags);
+int ffurl_open(URLContext **puc, const char *filename, int flags,
+ const AVIOInterruptCB *int_cb, AVDictionary **options);
/**
* Read up to size bytes from the resource accessed by h, and store
@@ -169,6 +195,19 @@ int ffurl_get_file_handle(URLContext *h);
*/
int ffurl_register_protocol(URLProtocol *protocol, int size);
+/**
+ * Check if the user has requested to interrup a blocking function
+ * associated with cb.
+ */
+int ff_check_interrupt(AVIOInterruptCB *cb);
+
+/**
+ * Iterate over all available protocols.
+ *
+ * @param prev result of the previous call to this functions or NULL.
+ */
+URLProtocol *ffurl_protocol_next(URLProtocol *prev);
+
/* udp.c */
int ff_udp_set_remote_url(URLContext *h, const char *uri);
int ff_udp_get_local_port(URLContext *h);
diff --git a/libavformat/utils.c b/libavformat/utils.c
index aa3ca59..aa2c276 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -25,18 +25,20 @@
#include "avio_internal.h"
#include "internal.h"
#include "libavcodec/internal.h"
+#include "libavcodec/bytestream.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
#include "libavutil/pixdesc.h"
#include "metadata.h"
#include "id3v2.h"
#include "libavutil/avstring.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/parseutils.h"
#include "riff.h"
#include "audiointerleave.h"
#include "url.h"
#include <sys/time.h>
#include <time.h>
-#include <strings.h>
#include <stdarg.h>
#if CONFIG_NETWORK
#include "network.h"
@@ -78,7 +80,7 @@ const char *avformat_license(void)
* @param num must be >= 0
* @param den must be >= 1
*/
-static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
+static void frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
{
num += (den >> 1);
if (num >= den) {
@@ -96,7 +98,7 @@ static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
* @param f fractional number
* @param incr increment, can be positive or negative
*/
-static void av_frac_add(AVFrac *f, int64_t incr)
+static void frac_add(AVFrac *f, int64_t incr)
{
int64_t num, den;
@@ -168,7 +170,7 @@ int av_match_ext(const char *filename, const char *extensions)
while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
*q++ = *p++;
*q = '\0';
- if (!strcasecmp(ext1, ext))
+ if (!av_strcasecmp(ext1, ext))
return 1;
if (*p == '\0')
break;
@@ -189,11 +191,11 @@ static int match_format(const char *name, const char *names)
namelen = strlen(name);
while ((p = strchr(names, ','))) {
len = FFMAX(p - names, namelen);
- if (!strncasecmp(name, names, len))
+ if (!av_strncasecmp(name, names, len))
return 1;
names = p+1;
}
- return !strcasecmp(name, names);
+ return !av_strcasecmp(name, names);
}
AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
@@ -338,7 +340,7 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score
}
/* a hack for files with huge id3v2 tags -- try to guess by file extension. */
- if (!fmt && id3 && *score_max < AVPROBE_SCORE_MAX/4) {
+ if (!fmt && is_opened && *score_max < AVPROBE_SCORE_MAX/4) {
while ((fmt = av_iformat_next(fmt)))
if (fmt->extensions && av_match_ext(lpd.filename, fmt->extensions)) {
*score_max = AVPROBE_SCORE_MAX/4;
@@ -346,6 +348,14 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score
}
}
+ if (!fmt && id3 && *score_max < AVPROBE_SCORE_MAX/4-1) {
+ while ((fmt = av_iformat_next(fmt)))
+ if (fmt->extensions && av_match_ext("mp3", fmt->extensions)) {
+ *score_max = AVPROBE_SCORE_MAX/4-1;
+ break;
+ }
+ }
+
return fmt;
}
@@ -500,9 +510,9 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
return AVERROR(EINVAL);
}
- for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt && ret >= 0;
+ for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt;
probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) {
- int ret, score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0;
+ int score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0;
int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1;
if (probe_size < offset) {
@@ -567,7 +577,7 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
#endif
/* open input file and probe the format if necessary */
-static int init_input(AVFormatContext *s, const char *filename)
+static int init_input(AVFormatContext *s, const char *filename, AVDictionary **options)
{
int ret;
AVProbeData pd = {filename, NULL, 0};
@@ -585,8 +595,9 @@ static int init_input(AVFormatContext *s, const char *filename)
(!s->iformat && (s->iformat = av_probe_input_format(&pd, 0))))
return 0;
- if ((ret = avio_open(&s->pb, filename, AVIO_FLAG_READ)) < 0)
- return ret;
+ if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ,
+ &s->interrupt_callback, options)) < 0)
+ return ret;
if (s->iformat)
return 0;
return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0);
@@ -596,7 +607,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
{
AVFormatContext *s = *ps;
int ret = 0;
- AVFormatParameters ap = { 0 };
+ AVFormatParameters ap = { { 0 } };
AVDictionary *tmp = NULL;
if (!s && !(s = avformat_alloc_context()))
@@ -610,7 +621,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail;
- if ((ret = init_input(s, filename)) < 0)
+ if ((ret = init_input(s, filename, &tmp)) < 0)
goto fail;
/* check filename in case an image number is expected */
@@ -718,6 +729,16 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
s->streams[i]->probe_packets = 0;
continue;
}
+
+ if ((s->flags & AVFMT_FLAG_DISCARD_CORRUPT) &&
+ (pkt->flags & AV_PKT_FLAG_CORRUPT)) {
+ av_log(s, AV_LOG_WARNING,
+ "Dropped corrupted packet (stream = %d)\n",
+ pkt->stream_index);
+ av_free_packet(pkt);
+ continue;
+ }
+
st= s->streams[pkt->stream_index];
switch(st->codec->codec_type){
@@ -750,7 +771,7 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
- //FIXME we dont reduce score to 0 for the case of running out of buffer space in bytes
+ //FIXME we do not reduce score to 0 for the case of running out of buffer space in bytes
set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0);
if(st->codec->codec_id != CODEC_ID_PROBE){
pd->buf_size=0;
@@ -806,7 +827,10 @@ static void compute_frame_duration(int *pnum, int *pden, AVStream *st,
*pden = 0;
switch(st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
- if(st->time_base.num*1000LL > st->time_base.den){
+ if (st->r_frame_rate.num) {
+ *pnum = st->r_frame_rate.den;
+ *pden = st->r_frame_rate.num;
+ } else if(st->time_base.num*1000LL > st->time_base.den) {
*pnum = st->time_base.num;
*pden = st->time_base.den;
}else if(st->codec->time_base.num*1000LL > st->codec->time_base.den){
@@ -842,6 +866,7 @@ static int is_intra_only(AVCodecContext *enc){
case CODEC_ID_MJPEG:
case CODEC_ID_MJPEGB:
case CODEC_ID_LJPEG:
+ case CODEC_ID_PRORES:
case CODEC_ID_RAWVIDEO:
case CODEC_ID_DVVIDEO:
case CODEC_ID_HUFFYUV:
@@ -943,11 +968,6 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
delay= st->codec->has_b_frames;
presentation_delayed = 0;
- // ignore delay caused by frame threading so that the mpeg2-without-dts
- // warning will not trigger
- if (delay && st->codec->active_thread_type&FF_THREAD_FRAME)
- delay -= st->codec->thread_count-1;
-
/* XXX: need has_b_frame, but cannot get it if the codec is
not initialized */
if (delay &&
@@ -1062,7 +1082,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
if(pkt->dts == AV_NOPTS_VALUE)
pkt->dts= st->pts_buffer[0];
- if(st->codec->codec_id == CODEC_ID_H264){ //we skiped it above so we try here
+ if(st->codec->codec_id == CODEC_ID_H264){ // we skipped it above so we try here
update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts); // this should happen on the first packet
}
if(pkt->dts > st->cur_dts)
@@ -1087,7 +1107,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
}
-static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
+static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
{
AVStream *st;
int len, ret, i;
@@ -1136,7 +1156,7 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
st->cur_pkt.data = NULL;
assert(st->cur_len == 0);
}else{
- pkt->destruct = NULL;
+ pkt->destruct = NULL;
}
compute_pkt_fields(s, st, st->parser, pkt);
@@ -1217,7 +1237,7 @@ 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, duration=%d, flags=%d\n",
+ av_log(s, AV_LOG_DEBUG, "read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n",
pkt->stream_index,
pkt->pts,
pkt->dts,
@@ -1263,7 +1283,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
}
}
if(genpts){
- int ret= av_read_frame_internal(s, pkt);
+ int ret= read_frame_internal(s, pkt);
if(ret<0){
if(pktl && ret != AVERROR(EAGAIN)){
eof=1;
@@ -1277,7 +1297,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
return AVERROR(ENOMEM);
}else{
assert(!s->packet_buffer);
- return av_read_frame_internal(s, pkt);
+ return read_frame_internal(s, pkt);
}
}
}
@@ -1363,7 +1383,15 @@ void ff_read_frame_flush(AVFormatContext *s)
}
}
-void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){
+#if FF_API_SEEK_PUBLIC
+void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
+{
+ ff_update_cur_dts(s, ref_st, timestamp);
+}
+#endif
+
+void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
+{
int i;
for(i = 0; i < s->nb_streams; i++) {
@@ -1483,7 +1511,14 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp,
wanted_timestamp, flags);
}
+#if FF_API_SEEK_PUBLIC
int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
+ return ff_seek_frame_binary(s, stream_index, target_ts, flags);
+}
+#endif
+
+int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
+{
AVInputFormat *avif= s->iformat;
int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit;
int64_t ts_min, ts_max, ts;
@@ -1530,7 +1565,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
}
}
- pos= av_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp);
+ pos= ff_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp);
if(pos<0)
return -1;
@@ -1538,12 +1573,28 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
if ((ret = avio_seek(s->pb, pos, SEEK_SET)) < 0)
return ret;
- av_update_cur_dts(s, st, ts);
+ ff_update_cur_dts(s, st, ts);
return 0;
}
-int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )){
+#if FF_API_SEEK_PUBLIC
+int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
+ int64_t pos_min, int64_t pos_max, int64_t pos_limit,
+ int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
+ return ff_gen_search(s, stream_index, target_ts, pos_min, pos_max,
+ pos_limit, ts_min, ts_max, flags, ts_ret,
+ read_timestamp);
+}
+#endif
+
+int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
+ int64_t pos_min, int64_t pos_max, int64_t pos_limit,
+ int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
int64_t pos, ts;
int64_t start_pos, filesize;
int no_change;
@@ -1649,7 +1700,7 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
return pos;
}
-static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){
+static int seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){
int64_t pos_min, pos_max;
#if 0
AVStream *st;
@@ -1674,7 +1725,7 @@ static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos,
return 0;
}
-static int av_seek_frame_generic(AVFormatContext *s,
+static int seek_frame_generic(AVFormatContext *s,
int stream_index, int64_t timestamp, int flags)
{
int index;
@@ -1690,7 +1741,6 @@ static int av_seek_frame_generic(AVFormatContext *s,
return -1;
if(index < 0 || index==st->nb_index_entries-1){
- int i;
AVPacket pkt;
if(st->nb_index_entries){
@@ -1698,17 +1748,17 @@ static int av_seek_frame_generic(AVFormatContext *s,
ie= &st->index_entries[st->nb_index_entries-1];
if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
return ret;
- av_update_cur_dts(s, st, ie->timestamp);
+ ff_update_cur_dts(s, st, ie->timestamp);
}else{
if ((ret = avio_seek(s->pb, s->data_offset, SEEK_SET)) < 0)
return ret;
}
- for(i=0;; i++) {
- int ret;
+ for (;;) {
+ int read_status;
do{
- ret = av_read_frame(s, &pkt);
- }while(ret == AVERROR(EAGAIN));
- if(ret<0)
+ read_status = av_read_frame(s, &pkt);
+ } while (read_status == AVERROR(EAGAIN));
+ if (read_status < 0)
break;
av_free_packet(&pkt);
if(stream_index == pkt.stream_index){
@@ -1729,7 +1779,7 @@ static int av_seek_frame_generic(AVFormatContext *s,
ie = &st->index_entries[index];
if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
return ret;
- av_update_cur_dts(s, st, ie->timestamp);
+ ff_update_cur_dts(s, st, ie->timestamp);
return 0;
}
@@ -1739,10 +1789,12 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f
int ret;
AVStream *st;
- ff_read_frame_flush(s);
-
- if(flags & AVSEEK_FLAG_BYTE)
- return av_seek_frame_byte(s, stream_index, timestamp, flags);
+ if (flags & AVSEEK_FLAG_BYTE) {
+ if (s->iformat->flags & AVFMT_NO_BYTE_SEEK)
+ return -1;
+ ff_read_frame_flush(s);
+ return seek_frame_byte(s, stream_index, timestamp, flags);
+ }
if(stream_index < 0){
stream_index= av_find_default_stream_index(s);
@@ -1750,23 +1802,27 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f
return -1;
st= s->streams[stream_index];
- /* timestamp for default must be expressed in AV_TIME_BASE units */
+ /* timestamp for default must be expressed in AV_TIME_BASE units */
timestamp = av_rescale(timestamp, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
}
/* first, we try the format specific seek */
- if (s->iformat->read_seek)
+ if (s->iformat->read_seek) {
+ ff_read_frame_flush(s);
ret = s->iformat->read_seek(s, stream_index, timestamp, flags);
- else
+ } else
ret = -1;
if (ret >= 0) {
return 0;
}
- if(s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH))
- return av_seek_frame_binary(s, stream_index, timestamp, flags);
- else if (!(s->iformat->flags & AVFMT_NOGENSEARCH))
- return av_seek_frame_generic(s, stream_index, timestamp, flags);
+ if (s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH)) {
+ ff_read_frame_flush(s);
+ return ff_seek_frame_binary(s, stream_index, timestamp, flags);
+ } else if (!(s->iformat->flags & AVFMT_NOGENSEARCH)) {
+ ff_read_frame_flush(s);
+ return seek_frame_generic(s, stream_index, timestamp, flags);
+ }
else
return -1;
}
@@ -1776,10 +1832,10 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int
if(min_ts > ts || max_ts < ts)
return -1;
- ff_read_frame_flush(s);
-
- if (s->iformat->read_seek2)
+ if (s->iformat->read_seek2) {
+ ff_read_frame_flush(s);
return s->iformat->read_seek2(s, stream_index, min_ts, ts, max_ts, flags);
+ }
if(s->iformat->read_timestamp){
//try to seek via read_timestamp()
@@ -1790,7 +1846,7 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int
if(s->iformat->read_seek || 1)
return av_seek_frame(s, stream_index, ts, flags | (ts - min_ts > (uint64_t)(max_ts - ts) ? AVSEEK_FLAG_BACKWARD : 0));
- // try some generic seek like av_seek_frame_generic() but with new ts semantics
+ // try some generic seek like seek_frame_generic() but with new ts semantics
}
/*******************************************************/
@@ -1800,7 +1856,7 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int
*
* @return TRUE if the stream has accurate duration for at least one component.
*/
-static int av_has_duration(AVFormatContext *ic)
+static int has_duration(AVFormatContext *ic)
{
int i;
AVStream *st;
@@ -1818,10 +1874,10 @@ static int av_has_duration(AVFormatContext *ic)
*
* Also computes the global bitrate if possible.
*/
-static void av_update_stream_timings(AVFormatContext *ic)
+static void update_stream_timings(AVFormatContext *ic)
{
int64_t start_time, start_time1, end_time, end_time1;
- int64_t duration, duration1;
+ int64_t duration, duration1, filesize;
int i;
AVStream *st;
@@ -1832,33 +1888,28 @@ static void av_update_stream_timings(AVFormatContext *ic)
st = ic->streams[i];
if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
- if (start_time1 < start_time)
- start_time = start_time1;
+ start_time = FFMIN(start_time, start_time1);
if (st->duration != AV_NOPTS_VALUE) {
end_time1 = start_time1
+ av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
- if (end_time1 > end_time)
- end_time = end_time1;
+ end_time = FFMAX(end_time, end_time1);
}
}
if (st->duration != AV_NOPTS_VALUE) {
duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
- if (duration1 > duration)
- duration = duration1;
+ duration = FFMAX(duration, duration1);
}
}
if (start_time != INT64_MAX) {
ic->start_time = start_time;
- if (end_time != INT64_MIN) {
- if (end_time - start_time > duration)
- duration = end_time - start_time;
- }
+ if (end_time != INT64_MIN)
+ duration = FFMAX(duration, end_time - start_time);
}
if (duration != INT64_MIN) {
ic->duration = duration;
- if (ic->file_size > 0) {
+ if (ic->pb && (filesize = avio_size(ic->pb)) > 0) {
/* compute the bitrate */
- ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE /
+ ic->bit_rate = (double)filesize * 8.0 * AV_TIME_BASE /
(double)ic->duration;
}
}
@@ -1869,7 +1920,7 @@ static void fill_all_stream_timings(AVFormatContext *ic)
int i;
AVStream *st;
- av_update_stream_timings(ic);
+ update_stream_timings(ic);
for(i = 0;i < ic->nb_streams; i++) {
st = ic->streams[i];
if (st->start_time == AV_NOPTS_VALUE) {
@@ -1881,7 +1932,7 @@ static void fill_all_stream_timings(AVFormatContext *ic)
}
}
-static void av_estimate_timings_from_bit_rate(AVFormatContext *ic)
+static void estimate_timings_from_bit_rate(AVFormatContext *ic)
{
int64_t filesize, duration;
int bit_rate, i;
@@ -1900,9 +1951,8 @@ static void av_estimate_timings_from_bit_rate(AVFormatContext *ic)
/* if duration is already set, we believe it */
if (ic->duration == AV_NOPTS_VALUE &&
- ic->bit_rate != 0 &&
- ic->file_size != 0) {
- filesize = ic->file_size;
+ ic->bit_rate != 0) {
+ filesize = ic->pb ? avio_size(ic->pb) : 0;
if (filesize > 0) {
for(i = 0; i < ic->nb_streams; i++) {
st = ic->streams[i];
@@ -1918,7 +1968,7 @@ static void av_estimate_timings_from_bit_rate(AVFormatContext *ic)
#define DURATION_MAX_RETRY 3
/* only usable for MPEG-PS streams */
-static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
+static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
{
AVPacket pkt1, *pkt = &pkt1;
AVStream *st;
@@ -1935,7 +1985,7 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset
for (i=0; i<ic->nb_streams; i++) {
st = ic->streams[i];
if (st->start_time == AV_NOPTS_VALUE && st->first_dts == AV_NOPTS_VALUE)
- av_log(st->codec, AV_LOG_WARNING, "start time is not set in av_estimate_timings_from_pts\n");
+ av_log(st->codec, AV_LOG_WARNING, "start time is not set in estimate_timings_from_pts\n");
if (st->parser) {
av_parser_close(st->parser);
@@ -1946,42 +1996,43 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset
/* estimate the end time (duration) */
/* XXX: may need to support wrapping */
- filesize = ic->file_size;
+ filesize = ic->pb ? avio_size(ic->pb) : 0;
end_time = AV_NOPTS_VALUE;
do{
- offset = filesize - (DURATION_MAX_READ_SIZE<<retry);
- if (offset < 0)
- offset = 0;
+ offset = filesize - (DURATION_MAX_READ_SIZE<<retry);
+ if (offset < 0)
+ offset = 0;
- avio_seek(ic->pb, offset, SEEK_SET);
- read_size = 0;
- for(;;) {
- if (read_size >= DURATION_MAX_READ_SIZE<<(FFMAX(retry-1,0)))
- break;
+ avio_seek(ic->pb, offset, SEEK_SET);
+ read_size = 0;
+ for(;;) {
+ if (read_size >= DURATION_MAX_READ_SIZE<<(FFMAX(retry-1,0)))
+ break;
- do{
- ret = av_read_packet(ic, pkt);
- }while(ret == AVERROR(EAGAIN));
- if (ret != 0)
- break;
- read_size += pkt->size;
- st = ic->streams[pkt->stream_index];
- if (pkt->pts != AV_NOPTS_VALUE &&
- (st->start_time != AV_NOPTS_VALUE ||
- st->first_dts != AV_NOPTS_VALUE)) {
- duration = end_time = pkt->pts;
- if (st->start_time != AV_NOPTS_VALUE) duration -= st->start_time;
- else duration -= st->first_dts;
- if (duration < 0)
- duration += 1LL<<st->pts_wrap_bits;
- if (duration > 0) {
- if (st->duration == AV_NOPTS_VALUE ||
- st->duration < duration)
- st->duration = duration;
+ do {
+ ret = av_read_packet(ic, pkt);
+ } while(ret == AVERROR(EAGAIN));
+ if (ret != 0)
+ break;
+ read_size += pkt->size;
+ st = ic->streams[pkt->stream_index];
+ if (pkt->pts != AV_NOPTS_VALUE &&
+ (st->start_time != AV_NOPTS_VALUE ||
+ st->first_dts != AV_NOPTS_VALUE)) {
+ duration = end_time = pkt->pts;
+ if (st->start_time != AV_NOPTS_VALUE)
+ duration -= st->start_time;
+ else
+ duration -= st->first_dts;
+ if (duration < 0)
+ duration += 1LL<<st->pts_wrap_bits;
+ if (duration > 0) {
+ if (st->duration == AV_NOPTS_VALUE || st->duration < duration)
+ st->duration = duration;
+ }
}
+ av_free_packet(pkt);
}
- av_free_packet(pkt);
- }
}while( end_time==AV_NOPTS_VALUE
&& filesize > (DURATION_MAX_READ_SIZE<<retry)
&& ++retry <= DURATION_MAX_RETRY);
@@ -1997,7 +2048,7 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset
}
}
-static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset)
+static void estimate_timings(AVFormatContext *ic, int64_t old_offset)
{
int64_t file_size;
@@ -2006,26 +2057,24 @@ static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset)
file_size = 0;
} else {
file_size = avio_size(ic->pb);
- if (file_size < 0)
- file_size = 0;
+ file_size = FFMAX(0, file_size);
}
- ic->file_size = file_size;
if ((!strcmp(ic->iformat->name, "mpeg") ||
!strcmp(ic->iformat->name, "mpegts")) &&
file_size && ic->pb->seekable) {
/* get accurate estimate from the PTSes */
- av_estimate_timings_from_pts(ic, old_offset);
- } else if (av_has_duration(ic)) {
+ estimate_timings_from_pts(ic, old_offset);
+ } else if (has_duration(ic)) {
/* at least one component has timings - we use them for all
the components */
fill_all_stream_timings(ic);
} else {
av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this may be inaccurate\n");
/* less precise: use bitrate info */
- av_estimate_timings_from_bit_rate(ic);
+ estimate_timings_from_bit_rate(ic);
}
- av_update_stream_timings(ic);
+ update_stream_timings(ic);
{
int i;
@@ -2043,43 +2092,43 @@ static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset)
}
}
-static int has_codec_parameters(AVCodecContext *enc)
+static int has_codec_parameters(AVCodecContext *avctx)
{
int val;
- switch(enc->codec_type) {
+ switch (avctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- val = enc->sample_rate && enc->channels && enc->sample_fmt != AV_SAMPLE_FMT_NONE;
- if(!enc->frame_size &&
- (enc->codec_id == CODEC_ID_VORBIS ||
- enc->codec_id == CODEC_ID_AAC ||
- enc->codec_id == CODEC_ID_MP1 ||
- enc->codec_id == CODEC_ID_MP2 ||
- enc->codec_id == CODEC_ID_MP3 ||
- enc->codec_id == CODEC_ID_SPEEX))
+ val = avctx->sample_rate && avctx->channels && avctx->sample_fmt != AV_SAMPLE_FMT_NONE;
+ if (!avctx->frame_size &&
+ (avctx->codec_id == CODEC_ID_VORBIS ||
+ avctx->codec_id == CODEC_ID_AAC ||
+ avctx->codec_id == CODEC_ID_MP1 ||
+ avctx->codec_id == CODEC_ID_MP2 ||
+ avctx->codec_id == CODEC_ID_MP3 ||
+ avctx->codec_id == CODEC_ID_CELT))
return 0;
break;
case AVMEDIA_TYPE_VIDEO:
- val = enc->width && enc->pix_fmt != PIX_FMT_NONE;
+ val = avctx->width && avctx->pix_fmt != PIX_FMT_NONE;
break;
default:
val = 1;
break;
}
- return enc->codec_id != CODEC_ID_NONE && val != 0;
+ return avctx->codec_id != CODEC_ID_NONE && val != 0;
}
static int has_decode_delay_been_guessed(AVStream *st)
{
return st->codec->codec_id != CODEC_ID_H264 ||
- st->codec_info_nb_frames >= 6 + st->codec->has_b_frames;
+ st->info->nb_decoded_frames >= 6;
}
static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options)
{
- int16_t *samples;
AVCodec *codec;
- int got_picture, data_size, ret=0;
+ int got_picture, ret = 0;
AVFrame picture;
+ AVPacket pkt = *avpkt;
if(!st->codec->codec){
codec = avcodec_find_decoder(st->codec->codec_id);
@@ -2090,27 +2139,30 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option
return ret;
}
- if(!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st)){
+ while (pkt.size > 0 && ret >= 0 &&
+ (!has_codec_parameters(st->codec) ||
+ !has_decode_delay_been_guessed(st) ||
+ (!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) {
+ got_picture = 0;
+ avcodec_get_frame_defaults(&picture);
switch(st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
- avcodec_get_frame_defaults(&picture);
ret = avcodec_decode_video2(st->codec, &picture,
- &got_picture, avpkt);
+ &got_picture, &pkt);
break;
case AVMEDIA_TYPE_AUDIO:
- data_size = FFMAX(avpkt->size, AVCODEC_MAX_AUDIO_FRAME_SIZE);
- samples = av_malloc(data_size);
- if (!samples)
- goto fail;
- ret = avcodec_decode_audio3(st->codec, samples,
- &data_size, avpkt);
- av_free(samples);
+ ret = avcodec_decode_audio4(st->codec, &picture, &got_picture, &pkt);
break;
default:
break;
}
+ if (ret >= 0) {
+ if (got_picture)
+ st->info->nb_decoded_frames++;
+ pkt.data += ret;
+ pkt.size -= ret;
+ }
}
- fail:
return ret;
}
@@ -2132,7 +2184,7 @@ enum CodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
return tags[i].id;
}
for(i=0; tags[i].id != CODEC_ID_NONE; i++) {
- if (ff_toupper4(tag) == ff_toupper4(tags[i].tag))
+ if (avpriv_toupper4(tag) == avpriv_toupper4(tags[i].tag))
return tags[i].id;
}
return CODEC_ID_NONE;
@@ -2222,11 +2274,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
for(i=0;i<ic->nb_streams;i++) {
AVCodec *codec;
st = ic->streams[i];
- if (st->codec->codec_id == CODEC_ID_AAC) {
- st->codec->sample_rate = 0;
- st->codec->frame_size = 0;
- st->codec->channels = 0;
- }
+
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
/* if(!st->time_base.num)
@@ -2244,12 +2292,10 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
assert(!st->codec->codec);
codec = avcodec_find_decoder(st->codec->codec_id);
- /* Force decoding of at least one frame of codec data
- * this makes sure the codec initializes the channel configuration
- * and does not trust the values from the container.
- */
- if (codec && codec->capabilities & CODEC_CAP_CHANNEL_CONF)
- st->codec->channels = 0;
+ /* this function doesn't flush the decoders, so force thread count
+ * to 1 to fix behavior when thread count > number of frames in the file */
+ if (options)
+ av_dict_set(&options[i], "threads", "1", 0);
/* Ensure that subtitle_header is properly set. */
if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
@@ -2270,7 +2316,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
count = 0;
read_size = 0;
for(;;) {
- if(url_interrupt_cb()){
+ if (ff_check_interrupt(&ic->interrupt_callback)){
ret= AVERROR_EXIT;
av_log(ic, AV_LOG_DEBUG, "interrupted\n");
break;
@@ -2320,8 +2366,11 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
/* NOTE: a new stream can be added there if no header in file
(AVFMTCTX_NOHEADER) */
- ret = av_read_frame_internal(ic, &pkt1);
- if (ret < 0 && ret != AVERROR(EAGAIN)) {
+ ret = read_frame_internal(ic, &pkt1);
+ if (ret == AVERROR(EAGAIN))
+ continue;
+
+ if (ret < 0) {
/* EOF or error */
ret = -1; /* we could not have all the codec parameters before EOF */
for(i=0;i<ic->nb_streams;i++) {
@@ -2337,9 +2386,6 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
break;
}
- if (ret == AVERROR(EAGAIN))
- continue;
-
pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end);
if ((ret = av_dup_packet(pkt)) < 0)
goto find_stream_info_err;
@@ -2356,9 +2402,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
}
{
int64_t last = st->info->last_dts;
- int64_t duration= pkt->dts - last;
- if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){
+ if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && pkt->dts > last){
+ int64_t duration= pkt->dts - last;
double dur= duration * av_q2d(st->time_base);
// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
@@ -2392,9 +2438,13 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
/* if still no information, we try to open the codec and to
decompress the frame. We try to avoid that in most cases as
it takes longer and uses more memory. For MPEG-4, we need to
- decompress for QuickTime. */
- if (!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st))
- try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i] : NULL);
+ decompress for QuickTime.
+
+ If CODEC_CAP_CHANNEL_CONF is set this will force decoding of at
+ least one frame of codec data, this makes sure the codec initializes
+ the channel configuration and does not only trust the values from the container.
+ */
+ try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i] : NULL);
st->codec_info_nb_frames++;
count++;
@@ -2469,7 +2519,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
}
}
- av_estimate_timings(ic, old_offset);
+ estimate_timings(ic, old_offset);
compute_chapters_end(ic);
@@ -2588,6 +2638,7 @@ int av_read_pause(AVFormatContext *s)
return AVERROR(ENOSYS);
}
+#if FF_API_FORMAT_PARAMETERS
void av_close_input_stream(AVFormatContext *s)
{
flush_packet_queue(s);
@@ -2595,6 +2646,7 @@ void av_close_input_stream(AVFormatContext *s)
s->iformat->read_close(s);
avformat_free_context(s);
}
+#endif
void avformat_free_context(AVFormatContext *s)
{
@@ -2638,17 +2690,39 @@ void avformat_free_context(AVFormatContext *s)
av_free(s);
}
+#if FF_API_CLOSE_INPUT_FILE
void av_close_input_file(AVFormatContext *s)
{
+ avformat_close_input(&s);
+}
+#endif
+
+void avformat_close_input(AVFormatContext **ps)
+{
+ AVFormatContext *s = *ps;
AVIOContext *pb = (s->iformat->flags & AVFMT_NOFILE) || (s->flags & AVFMT_FLAG_CUSTOM_IO) ?
NULL : s->pb;
- av_close_input_stream(s);
+ flush_packet_queue(s);
+ if (s->iformat->read_close)
+ s->iformat->read_close(s);
+ avformat_free_context(s);
+ *ps = NULL;
if (pb)
avio_close(pb);
}
+#if FF_API_NEW_STREAM
AVStream *av_new_stream(AVFormatContext *s, int id)
{
+ AVStream *st = avformat_new_stream(s, NULL);
+ if (st)
+ st->id = id;
+ return st;
+}
+#endif
+
+AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
+{
AVStream *st;
int i;
AVStream **streams;
@@ -2668,13 +2742,12 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
return NULL;
}
- st->codec= avcodec_alloc_context();
+ st->codec = avcodec_alloc_context3(c);
if (s->iformat) {
/* no default bitrate if decoding */
st->codec->bit_rate = 0;
}
st->index = s->nb_streams;
- st->id = id;
st->start_time = AV_NOPTS_VALUE;
st->duration = AV_NOPTS_VALUE;
/* we set the current DTS to 0 so that formats without any timestamps
@@ -2686,7 +2759,7 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
st->probe_packets = MAX_PROBE_PACKETS;
/* default pts setting is MPEG-like */
- av_set_pts_info(st, 33, 1, 90000);
+ avpriv_set_pts_info(st, 33, 1, 90000);
st->last_IP_pts = AV_NOPTS_VALUE;
for(i=0; i<MAX_REORDER_DELAY+1; i++)
st->pts_buffer[i]= AV_NOPTS_VALUE;
@@ -2721,7 +2794,7 @@ AVProgram *av_new_program(AVFormatContext *ac, int id)
return program;
}
-AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title)
+AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title)
{
AVChapter *chapter = NULL;
int i;
@@ -2789,7 +2862,7 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st)
for (n = 0; s->oformat->codec_tag[n]; n++) {
avctag = s->oformat->codec_tag[n];
while (avctag->id != CODEC_ID_NONE) {
- if (ff_toupper4(avctag->tag) == ff_toupper4(st->codec->codec_tag)) {
+ if (avpriv_toupper4(avctag->tag) == avpriv_toupper4(st->codec->codec_tag)) {
id = avctag->id;
if (id == st->codec->codec_id)
return 1;
@@ -2933,7 +3006,7 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
ret = AVERROR_INVALIDDATA;
goto fail;
}
- av_frac_init(&st->pts, 0, 0, den);
+ frac_init(&st->pts, 0, 0, den);
}
}
@@ -3011,11 +3084,11 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt){
likely equal to the encoder delay, but it would be better if we
had the real timestamps from the encoder */
if (frame_size >= 0 && (pkt->size || st->pts.num!=st->pts.den>>1 || st->pts.val)) {
- av_frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
+ frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
}
break;
case AVMEDIA_TYPE_VIDEO:
- av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num);
+ frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num);
break;
default:
break;
@@ -3031,6 +3104,9 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt)
return ret;
ret= s->oformat->write_packet(s, pkt);
+
+ if (ret >= 0)
+ s->streams[pkt->stream_index]->nb_frames++;
return ret;
}
@@ -3121,7 +3197,7 @@ int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pk
* @return 1 if a packet was output, 0 if no packet could be output,
* < 0 if an error occurred
*/
-static int av_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){
+static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){
if(s->oformat->interleave_packet)
return s->oformat->interleave_packet(s, out, in, flush);
else
@@ -3146,11 +3222,13 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
for(;;){
AVPacket opkt;
- int ret= av_interleave_packet(s, &opkt, pkt, 0);
+ int ret= interleave_packet(s, &opkt, pkt, 0);
if(ret<=0) //FIXME cleanup needed for ret<0 ?
return ret;
ret= s->oformat->write_packet(s, &opkt);
+ if (ret >= 0)
+ s->streams[opkt.stream_index]->nb_frames++;
av_free_packet(&opkt);
pkt= NULL;
@@ -3166,13 +3244,15 @@ int av_write_trailer(AVFormatContext *s)
for(;;){
AVPacket pkt;
- ret= av_interleave_packet(s, &pkt, NULL, 1);
+ ret= interleave_packet(s, &pkt, NULL, 1);
if(ret<0) //FIXME cleanup needed for ret<0 ?
goto fail;
if(!ret)
break;
ret= s->oformat->write_packet(s, &pkt);
+ if (ret >= 0)
+ s->streams[pkt.stream_index]->nb_frames++;
av_free_packet(&pkt);
@@ -3187,7 +3267,7 @@ fail:
av_freep(&s->streams[i]->priv_data);
av_freep(&s->streams[i]->index_entries);
}
- if (s->iformat && s->iformat->priv_class)
+ if (s->oformat->priv_class)
av_opt_free(s->priv_data);
av_freep(&s->priv_data);
return ret;
@@ -3320,7 +3400,7 @@ void av_dump_format(AVFormatContext *ic,
int is_output)
{
int i;
- uint8_t *printed = av_mallocz(ic->nb_streams);
+ uint8_t *printed = ic->nb_streams ? av_mallocz(ic->nb_streams) : NULL;
if (ic->nb_streams && !printed)
return;
@@ -3682,9 +3762,17 @@ int ff_hex_to_data(uint8_t *data, const char *p)
return len;
}
+#if FF_API_SET_PTS_INFO
void av_set_pts_info(AVStream *s, int pts_wrap_bits,
unsigned int pts_num, unsigned int pts_den)
{
+ avpriv_set_pts_info(s, pts_wrap_bits, pts_num, pts_den);
+}
+#endif
+
+void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits,
+ unsigned int pts_num, unsigned int pts_den)
+{
AVRational new_tb;
if(av_reduce(&new_tb.num, &new_tb.den, pts_num, pts_den, INT_MAX)){
if(new_tb.num != pts_num)
@@ -3877,3 +3965,98 @@ void ff_make_absolute_url(char *buf, int size, const char *base,
}
av_strlcat(buf, rel, size);
}
+
+int64_t ff_iso8601_to_unix_time(const char *datestr)
+{
+#if HAVE_STRPTIME
+ struct tm time1 = {0}, time2 = {0};
+ char *ret1, *ret2;
+ ret1 = strptime(datestr, "%Y - %m - %d %T", &time1);
+ ret2 = strptime(datestr, "%Y - %m - %dT%T", &time2);
+ if (ret2 && !ret1)
+ return av_timegm(&time2);
+ else
+ return av_timegm(&time1);
+#else
+ av_log(NULL, AV_LOG_WARNING, "strptime() unavailable on this system, cannot convert "
+ "the date string.\n");
+ return 0;
+#endif
+}
+
+int avformat_query_codec(AVOutputFormat *ofmt, enum CodecID codec_id, int std_compliance)
+{
+ if (ofmt) {
+ if (ofmt->query_codec)
+ return ofmt->query_codec(codec_id, std_compliance);
+ else if (ofmt->codec_tag)
+ return !!av_codec_get_tag(ofmt->codec_tag, codec_id);
+ else if (codec_id == ofmt->video_codec || codec_id == ofmt->audio_codec ||
+ codec_id == ofmt->subtitle_codec)
+ return 1;
+ }
+ return AVERROR_PATCHWELCOME;
+}
+
+int avformat_network_init(void)
+{
+#if CONFIG_NETWORK
+ int ret;
+ ff_network_inited_globally = 1;
+ if ((ret = ff_network_init()) < 0)
+ return ret;
+ ff_tls_init();
+#endif
+ return 0;
+}
+
+int avformat_network_deinit(void)
+{
+#if CONFIG_NETWORK
+ ff_network_close();
+ ff_tls_deinit();
+#endif
+ return 0;
+}
+
+int ff_add_param_change(AVPacket *pkt, int32_t channels,
+ uint64_t channel_layout, int32_t sample_rate,
+ int32_t width, int32_t height)
+{
+ uint32_t flags = 0;
+ int size = 4;
+ uint8_t *data;
+ if (!pkt)
+ return AVERROR(EINVAL);
+ if (channels) {
+ size += 4;
+ flags |= AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT;
+ }
+ if (channel_layout) {
+ size += 8;
+ flags |= AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT;
+ }
+ if (sample_rate) {
+ size += 4;
+ flags |= AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE;
+ }
+ if (width || height) {
+ size += 8;
+ flags |= AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS;
+ }
+ data = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, size);
+ if (!data)
+ return AVERROR(ENOMEM);
+ bytestream_put_le32(&data, flags);
+ if (channels)
+ bytestream_put_le32(&data, channels);
+ if (channel_layout)
+ bytestream_put_le64(&data, channel_layout);
+ if (sample_rate)
+ bytestream_put_le32(&data, sample_rate);
+ if (width || height) {
+ bytestream_put_le32(&data, width);
+ bytestream_put_le32(&data, height);
+ }
+ return 0;
+}
diff --git a/libavformat/vc1test.c b/libavformat/vc1test.c
index 07f3247..6789b9d 100644
--- a/libavformat/vc1test.c
+++ b/libavformat/vc1test.c
@@ -28,6 +28,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define VC1_EXTRADATA_SIZE 4
@@ -54,7 +55,7 @@ static int vc1t_read_header(AVFormatContext *s,
return -1;
/* init video codec */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
@@ -71,13 +72,13 @@ static int vc1t_read_header(AVFormatContext *s,
avio_skip(pb, 8);
fps = avio_rl32(pb);
if(fps == 0xFFFFFFFF)
- av_set_pts_info(st, 32, 1, 1000);
+ avpriv_set_pts_info(st, 32, 1, 1000);
else{
if (!fps) {
av_log(s, AV_LOG_ERROR, "Zero FPS specified, defaulting to 1 FPS\n");
fps = 1;
}
- av_set_pts_info(st, 24, 1, fps);
+ avpriv_set_pts_info(st, 24, 1, fps);
st->duration = frames;
}
@@ -110,11 +111,10 @@ static int vc1t_read_packet(AVFormatContext *s,
}
AVInputFormat ff_vc1t_demuxer = {
- "vc1test",
- NULL_IF_CONFIG_SMALL("VC-1 test bitstream format"),
- 0,
- vc1t_probe,
- vc1t_read_header,
- vc1t_read_packet,
+ .name = "vc1test",
+ .long_name = NULL_IF_CONFIG_SMALL("VC-1 test bitstream format"),
+ .read_probe = vc1t_probe,
+ .read_header = vc1t_read_header,
+ .read_packet = vc1t_read_packet,
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/vc1testenc.c b/libavformat/vc1testenc.c
index 2b0728d..a1228d8 100644
--- a/libavformat/vc1testenc.c
+++ b/libavformat/vc1testenc.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
+#include "internal.h"
typedef struct RCVContext {
int frames;
@@ -47,7 +48,7 @@ static int vc1test_write_header(AVFormatContext *s)
avio_wl32(pb, s->streams[0]->r_frame_rate.den);
else
avio_wl32(pb, 0xFFFFFFFF); //variable framerate
- av_set_pts_info(s->streams[0], 32, 1, 1000);
+ avpriv_set_pts_info(s->streams[0], 32, 1, 1000);
return 0;
}
@@ -82,14 +83,14 @@ static int vc1test_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_vc1t_muxer = {
- "rcv",
- NULL_IF_CONFIG_SMALL("VC-1 test bitstream"),
- "",
- "rcv",
- sizeof(RCVContext),
- CODEC_ID_NONE,
- CODEC_ID_WMV3,
- vc1test_write_header,
- vc1test_write_packet,
- vc1test_write_trailer,
+ .name = "rcv",
+ .long_name = NULL_IF_CONFIG_SMALL("VC-1 test bitstream"),
+ .mime_type = "",
+ .extensions = "rcv",
+ .priv_data_size = sizeof(RCVContext),
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_WMV3,
+ .write_header = vc1test_write_header,
+ .write_packet = vc1test_write_packet,
+ .write_trailer = vc1test_write_trailer,
};
diff --git a/libavformat/version.h b/libavformat/version.h
index 635b582..e113a24 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -21,10 +21,16 @@
#ifndef AVFORMAT_VERSION_H
#define AVFORMAT_VERSION_H
+/**
+ * @file
+ * @ingroup libavf
+ * Libavformat version macros
+ */
+
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 53
-#define LIBAVFORMAT_VERSION_MINOR 3
+#define LIBAVFORMAT_VERSION_MINOR 19
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -74,5 +80,50 @@
#ifndef FF_API_FLAG_RTP_HINT
#define FF_API_FLAG_RTP_HINT (LIBAVFORMAT_VERSION_MAJOR < 54)
#endif
+#ifndef FF_API_AVSTREAM_QUALITY
+#define FF_API_AVSTREAM_QUALITY (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_LOOP_INPUT
+#define FF_API_LOOP_INPUT (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_LOOP_OUTPUT
+#define FF_API_LOOP_OUTPUT (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_TIMESTAMP
+#define FF_API_TIMESTAMP (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_FILESIZE
+#define FF_API_FILESIZE (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_MUXRATE
+#define FF_API_MUXRATE (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_RTSP_URL_OPTIONS
+#define FF_API_RTSP_URL_OPTIONS (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_NEW_STREAM
+#define FF_API_NEW_STREAM (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_PRELOAD
+#define FF_API_PRELOAD (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_STREAM_COPY
+#define FF_API_STREAM_COPY (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_SEEK_PUBLIC
+#define FF_API_SEEK_PUBLIC (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_REORDER_PRIVATE
+#define FF_API_REORDER_PRIVATE (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_OLD_INTERRUPT_CB
+#define FF_API_OLD_INTERRUPT_CB (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_SET_PTS_INFO
+#define FF_API_SET_PTS_INFO (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_CLOSE_INPUT_FILE
+#define FF_API_CLOSE_INPUT_FILE (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
#endif /* AVFORMAT_VERSION_H */
diff --git a/libavformat/vocdec.c b/libavformat/vocdec.c
index eaa2f25..638c15a 100644
--- a/libavformat/vocdec.c
+++ b/libavformat/vocdec.c
@@ -52,7 +52,7 @@ static int voc_read_header(AVFormatContext *s, AVFormatParameters *ap)
return AVERROR(ENOSYS);
}
avio_skip(pb, header_size);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -157,11 +157,11 @@ static int voc_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_voc_demuxer = {
- "voc",
- NULL_IF_CONFIG_SMALL("Creative Voice file format"),
- sizeof(VocDecContext),
- voc_probe,
- voc_read_header,
- voc_read_packet,
+ .name = "voc",
+ .long_name = NULL_IF_CONFIG_SMALL("Creative Voice file format"),
+ .priv_data_size = sizeof(VocDecContext),
+ .read_probe = voc_probe,
+ .read_header = voc_read_header,
+ .read_packet = voc_read_packet,
.codec_tag=(const AVCodecTag* const []){ff_voc_codec_tags, 0},
};
diff --git a/libavformat/vocenc.c b/libavformat/vocenc.c
index bbb69c8..d0986bb 100644
--- a/libavformat/vocenc.c
+++ b/libavformat/vocenc.c
@@ -90,15 +90,15 @@ static int voc_write_trailer(AVFormatContext *s)
}
AVOutputFormat ff_voc_muxer = {
- "voc",
- NULL_IF_CONFIG_SMALL("Creative Voice file format"),
- "audio/x-voc",
- "voc",
- sizeof(VocEncContext),
- CODEC_ID_PCM_U8,
- CODEC_ID_NONE,
- voc_write_header,
- voc_write_packet,
- voc_write_trailer,
+ .name = "voc",
+ .long_name = NULL_IF_CONFIG_SMALL("Creative Voice file format"),
+ .mime_type = "audio/x-voc",
+ .extensions = "voc",
+ .priv_data_size = sizeof(VocEncContext),
+ .audio_codec = CODEC_ID_PCM_U8,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = voc_write_header,
+ .write_packet = voc_write_packet,
+ .write_trailer = voc_write_trailer,
.codec_tag=(const AVCodecTag* const []){ff_voc_codec_tags, 0},
};
diff --git a/libavformat/vorbiscomment.h b/libavformat/vorbiscomment.h
index 7b82dc1..95e1a56 100644
--- a/libavformat/vorbiscomment.h
+++ b/libavformat/vorbiscomment.h
@@ -39,7 +39,7 @@ int ff_vorbiscomment_length(AVDictionary *m, const char *vendor_string,
unsigned *count);
/**
- * Writes a VorbisComment into a buffer. The buffer, p, must have enough
+ * Write a VorbisComment into a buffer. The buffer, p, must have enough
* data to hold the whole VorbisComment. The minimum size required can be
* obtained by passing the same AVDictionary and vendor_string to
* ff_vorbiscomment_length()
diff --git a/libavformat/vqf.c b/libavformat/vqf.c
index 5be7dfe..aba763d 100644
--- a/libavformat/vqf.c
+++ b/libavformat/vqf.c
@@ -20,8 +20,10 @@
*/
#include "avformat.h"
+#include "internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
typedef struct VqfContext {
int frame_bit_len;
@@ -63,12 +65,13 @@ static void add_metadata(AVFormatContext *s, const char *tag,
static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
VqfContext *c = s->priv_data;
- AVStream *st = av_new_stream(s, 0);
+ AVStream *st = avformat_new_stream(s, NULL);
int chunk_tag;
int rate_flag = -1;
int header_size;
int read_bitrate = 0;
int size;
+ uint8_t comm_chunk[12];
if (!st)
return AVERROR(ENOMEM);
@@ -99,13 +102,13 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap)
switch(chunk_tag){
case MKTAG('C','O','M','M'):
- st->codec->channels = avio_rb32(s->pb) + 1;
- read_bitrate = avio_rb32(s->pb);
- rate_flag = avio_rb32(s->pb);
+ avio_read(s->pb, comm_chunk, 12);
+ st->codec->channels = AV_RB32(comm_chunk ) + 1;
+ read_bitrate = AV_RB32(comm_chunk + 4);
+ rate_flag = AV_RB32(comm_chunk + 8);
avio_skip(s->pb, len-12);
st->codec->bit_rate = read_bitrate*1000;
- st->codec->bits_per_coded_sample = 16;
break;
case MKTAG('N','A','M','E'):
add_metadata(s, "title" , len, header_size);
@@ -190,7 +193,13 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap)
return -1;
}
c->frame_bit_len = st->codec->bit_rate*size/st->codec->sample_rate;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+
+ /* put first 12 bytes of COMM chunk in extradata */
+ if (!(st->codec->extradata = av_malloc(12 + FF_INPUT_BUFFER_PADDING_SIZE)))
+ return AVERROR(ENOMEM);
+ st->codec->extradata_size = 12;
+ memcpy(st->codec->extradata, comm_chunk, 12);
return 0;
}
@@ -249,13 +258,12 @@ static int vqf_read_seek(AVFormatContext *s,
}
AVInputFormat ff_vqf_demuxer = {
- "vqf",
- NULL_IF_CONFIG_SMALL("Nippon Telegraph and Telephone Corporation (NTT) TwinVQ"),
- sizeof(VqfContext),
- vqf_probe,
- vqf_read_header,
- vqf_read_packet,
- NULL,
- vqf_read_seek,
+ .name = "vqf",
+ .long_name = NULL_IF_CONFIG_SMALL("Nippon Telegraph and Telephone Corporation (NTT) TwinVQ"),
+ .priv_data_size = sizeof(VqfContext),
+ .read_probe = vqf_probe,
+ .read_header = vqf_read_header,
+ .read_packet = vqf_read_packet,
+ .read_seek = vqf_read_seek,
.extensions = "vqf",
};
diff --git a/libavformat/wav.c b/libavformat/wav.c
index 92c9bfc..47cb5f8 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -22,21 +22,86 @@
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
+#include "libavutil/avassert.h"
+#include "libavutil/dict.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "avformat.h"
+#include "internal.h"
#include "avio_internal.h"
#include "pcm.h"
#include "riff.h"
+#include "avio.h"
+#include "metadata.h"
typedef struct {
+ const AVClass *class;
int64_t data;
int64_t data_end;
int64_t minpts;
int64_t maxpts;
int last_duration;
int w64;
+ int write_bext;
} WAVContext;
#if CONFIG_WAV_MUXER
+static inline void bwf_write_bext_string(AVFormatContext *s, const char *key, int maxlen)
+{
+ AVDictionaryEntry *tag;
+ int len = 0;
+
+ if (tag = av_dict_get(s->metadata, key, NULL, 0)) {
+ len = strlen(tag->value);
+ len = FFMIN(len, maxlen);
+ avio_write(s->pb, tag->value, len);
+ }
+
+ ffio_fill(s->pb, 0, maxlen - len);
+}
+
+static void bwf_write_bext_chunk(AVFormatContext *s)
+{
+ AVDictionaryEntry *tmp_tag;
+ uint64_t time_reference = 0;
+ int64_t bext = ff_start_tag(s->pb, "bext");
+
+ bwf_write_bext_string(s, "description", 256);
+ bwf_write_bext_string(s, "originator", 32);
+ bwf_write_bext_string(s, "originator_reference", 32);
+ bwf_write_bext_string(s, "origination_date", 10);
+ bwf_write_bext_string(s, "origination_time", 8);
+
+ if (tmp_tag = av_dict_get(s->metadata, "time_reference", NULL, 0))
+ time_reference = strtoll(tmp_tag->value, NULL, 10);
+ avio_wl64(s->pb, time_reference);
+ avio_wl16(s->pb, 1); // set version to 1
+
+ if (tmp_tag = av_dict_get(s->metadata, "umid", NULL, 0)) {
+ unsigned char umidpart_str[17] = {0};
+ int i;
+ uint64_t umidpart;
+ int len = strlen(tmp_tag->value+2);
+
+ for (i = 0; i < len/16; i++) {
+ memcpy(umidpart_str, tmp_tag->value + 2 + (i*16), 16);
+ umidpart = strtoll(umidpart_str, NULL, 16);
+ avio_wb64(s->pb, umidpart);
+ }
+ ffio_fill(s->pb, 0, 64 - i*8);
+ } else
+ ffio_fill(s->pb, 0, 64); // zero UMID
+
+ ffio_fill(s->pb, 0, 190); // Reserved
+
+ if (tmp_tag = av_dict_get(s->metadata, "coding_history", NULL, 0))
+ avio_put_str(s->pb, tmp_tag->value);
+
+ ff_end_tag(s->pb, bext);
+}
+
static int wav_write_header(AVFormatContext *s)
{
WAVContext *wav = s->priv_data;
@@ -63,7 +128,10 @@ static int wav_write_header(AVFormatContext *s)
ff_end_tag(pb, fact);
}
- av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
+ if (wav->write_bext)
+ bwf_write_bext_chunk(s);
+
+ avpriv_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
wav->maxpts = wav->last_duration = 0;
wav->minpts = INT64_MAX;
@@ -123,25 +191,40 @@ static int wav_write_trailer(AVFormatContext *s)
return 0;
}
+#define OFFSET(x) offsetof(WAVContext, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "write_bext", "Write BEXT chunk.", OFFSET(write_bext), AV_OPT_TYPE_INT, { 0 }, 0, 1, ENC },
+ { NULL },
+};
+
+static const AVClass wav_muxer_class = {
+ .class_name = "WAV muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_wav_muxer = {
- "wav",
- NULL_IF_CONFIG_SMALL("WAV format"),
- "audio/x-wav",
- "wav",
- sizeof(WAVContext),
- CODEC_ID_PCM_S16LE,
- CODEC_ID_NONE,
- wav_write_header,
- wav_write_packet,
- wav_write_trailer,
+ .name = "wav",
+ .long_name = NULL_IF_CONFIG_SMALL("WAV format"),
+ .mime_type = "audio/x-wav",
+ .extensions = "wav",
+ .priv_data_size = sizeof(WAVContext),
+ .audio_codec = CODEC_ID_PCM_S16LE,
+ .video_codec = CODEC_ID_NONE,
+ .write_header = wav_write_header,
+ .write_packet = wav_write_packet,
+ .write_trailer = wav_write_trailer,
.codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0},
+ .priv_class = &wav_muxer_class,
};
#endif /* CONFIG_WAV_MUXER */
#if CONFIG_WAV_DEMUXER
-static int64_t next_tag(AVIOContext *pb, unsigned int *tag)
+static int64_t next_tag(AVIOContext *pb, uint32_t *tag)
{
*tag = avio_rl32(pb);
return avio_rl32(pb);
@@ -184,6 +267,117 @@ static int wav_probe(AVProbeData *p)
return 0;
}
+static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
+{
+ AVIOContext *pb = s->pb;
+ int ret;
+
+ /* parse fmt header */
+ *st = avformat_new_stream(s, NULL);
+ if (!*st)
+ return AVERROR(ENOMEM);
+
+ ret = ff_get_wav_header(pb, (*st)->codec, size);
+ if (ret < 0)
+ return ret;
+ (*st)->need_parsing = AVSTREAM_PARSE_FULL;
+
+ avpriv_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate);
+
+ return 0;
+}
+
+static inline int wav_parse_bext_string(AVFormatContext *s, const char *key,
+ int length)
+{
+ char temp[257];
+ int ret;
+
+ av_assert0(length <= sizeof(temp));
+ if ((ret = avio_read(s->pb, temp, length)) < 0)
+ return ret;
+
+ temp[length] = 0;
+
+ if (strlen(temp))
+ return av_dict_set(&s->metadata, key, temp, 0);
+
+ return 0;
+}
+
+static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
+{
+ char temp[131], *coding_history;
+ int ret, x;
+ uint64_t time_reference;
+ int64_t umid_parts[8], umid_mask = 0;
+
+ if ((ret = wav_parse_bext_string(s, "description", 256)) < 0 ||
+ (ret = wav_parse_bext_string(s, "originator", 32)) < 0 ||
+ (ret = wav_parse_bext_string(s, "originator_reference", 32)) < 0 ||
+ (ret = wav_parse_bext_string(s, "origination_date", 10)) < 0 ||
+ (ret = wav_parse_bext_string(s, "origination_time", 8)) < 0)
+ return ret;
+
+ time_reference = avio_rl64(s->pb);
+ snprintf(temp, sizeof(temp), "%"PRIu64, time_reference);
+ if ((ret = av_dict_set(&s->metadata, "time_reference", temp, 0)) < 0)
+ return ret;
+
+ /* check if version is >= 1, in which case an UMID may be present */
+ if (avio_rl16(s->pb) >= 1) {
+ for (x = 0; x < 8; x++)
+ umid_mask |= umid_parts[x] = avio_rb64(s->pb);
+
+ if (umid_mask) {
+ /* the string formatting below is per SMPTE 330M-2004 Annex C */
+ if (umid_parts[4] == 0 && umid_parts[5] == 0 && umid_parts[6] == 0 && umid_parts[7] == 0) {
+ /* basic UMID */
+ snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+ umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3]);
+ } else {
+ /* extended UMID */
+ snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
+ "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+ umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3],
+ umid_parts[4], umid_parts[5], umid_parts[6], umid_parts[7]);
+ }
+
+ if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0)
+ return ret;
+ }
+
+ avio_skip(s->pb, 190);
+ } else
+ avio_skip(s->pb, 254);
+
+ if (size > 602) {
+ /* CodingHistory present */
+ size -= 602;
+
+ if (!(coding_history = av_malloc(size+1)))
+ return AVERROR(ENOMEM);
+
+ if ((ret = avio_read(s->pb, coding_history, size)) < 0)
+ return ret;
+
+ coding_history[size] = 0;
+ if ((ret = av_dict_set(&s->metadata, "coding_history", coding_history,
+ AV_DICT_DONT_STRDUP_VAL)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const AVMetadataConv wav_metadata_conv[] = {
+ {"description", "comment" },
+ {"originator", "encoded_by" },
+ {"origination_date", "date" },
+ {"origination_time", "creation_time"},
+ {0},
+};
+
/* wav input */
static int wav_read_header(AVFormatContext *s,
AVFormatParameters *ap)
@@ -191,11 +385,12 @@ static int wav_read_header(AVFormatContext *s,
int64_t size, av_uninit(data_size);
int64_t sample_count=0;
int rf64;
- unsigned int tag;
+ uint32_t tag, list_type;
AVIOContext *pb = s->pb;
AVStream *st;
WAVContext *wav = s->priv_data;
- int ret;
+ int ret, got_fmt = 0;
+ int64_t next_tag_ofs, data_ofs = -1;
/* check RIFF header */
tag = avio_rl32(pb);
@@ -217,49 +412,97 @@ static int wav_read_header(AVFormatContext *s,
avio_rl64(pb); /* RIFF size */
data_size = avio_rl64(pb);
sample_count = avio_rl64(pb);
+ if (data_size < 0 || sample_count < 0) {
+ av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
+ "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
+ data_size, sample_count);
+ return AVERROR_INVALIDDATA;
+ }
avio_skip(pb, size - 16); /* skip rest of ds64 chunk */
}
- /* parse fmt header */
- size = find_tag(pb, MKTAG('f', 'm', 't', ' '));
- if (size < 0)
- return -1;
- st = av_new_stream(s, 0);
- if (!st)
- return AVERROR(ENOMEM);
+ for (;;) {
+ size = next_tag(pb, &tag);
+ next_tag_ofs = avio_tell(pb) + size;
- ret = ff_get_wav_header(pb, st->codec, size);
- if (ret < 0)
- return ret;
- st->need_parsing = AVSTREAM_PARSE_FULL;
+ if (pb->eof_reached)
+ break;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ switch (tag) {
+ case MKTAG('f', 'm', 't', ' '):
+ /* only parse the first 'fmt ' tag found */
+ if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st) < 0)) {
+ return ret;
+ } else if (got_fmt)
+ av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n");
- for (;;) {
- if (pb->eof_reached)
- return -1;
- size = next_tag(pb, &tag);
- if (tag == MKTAG('d', 'a', 't', 'a')){
+ got_fmt = 1;
+ break;
+ case MKTAG('d', 'a', 't', 'a'):
+ if (!got_fmt) {
+ av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'data' tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (rf64) {
+ next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
+ } else {
+ data_size = size;
+ next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
+ }
+
+ data_ofs = avio_tell(pb);
+
+ /* don't look for footer metadata if we can't seek or if we don't
+ * know where the data tag ends
+ */
+ if (!pb->seekable || (!rf64 && !size))
+ goto break_loop;
+ break;
+ case MKTAG('f','a','c','t'):
+ if (!sample_count)
+ sample_count = avio_rl32(pb);
+ break;
+ case MKTAG('b','e','x','t'):
+ if ((ret = wav_parse_bext_tag(s, size)) < 0)
+ return ret;
+ break;
+ case MKTAG('L', 'I', 'S', 'T'):
+ list_type = avio_rl32(pb);
+ if (size <= 4) {
+ av_log(s, AV_LOG_ERROR, "too short LIST");
+ return AVERROR_INVALIDDATA;
+ }
+ switch (list_type) {
+ case MKTAG('I', 'N', 'F', 'O'):
+ if ((ret = ff_read_riff_info(s, size - 4)) < 0)
+ return ret;
+ }
+ break;
+ }
+
+ /* seek to next tag unless we know that we'll run into EOF */
+ if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
+ avio_seek(pb, next_tag_ofs, SEEK_SET) < 0) {
break;
- }else if (tag == MKTAG('f','a','c','t') && !sample_count){
- sample_count = avio_rl32(pb);
- size -= 4;
}
- avio_skip(pb, size);
}
- if (rf64)
- size = data_size;
- if (size < 0)
- return -1;
- if (!size) {
- wav->data_end = INT64_MAX;
- } else
- wav->data_end= avio_tell(pb) + size;
+break_loop:
+ if (data_ofs < 0) {
+ av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ avio_seek(pb, data_ofs, SEEK_SET);
if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id))
- sample_count = (size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
+ sample_count = (data_size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
if (sample_count)
st->duration = sample_count;
+
+ ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
+ ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
+
return 0;
}
@@ -344,14 +587,13 @@ static int wav_read_seek(AVFormatContext *s,
}
AVInputFormat ff_wav_demuxer = {
- "wav",
- NULL_IF_CONFIG_SMALL("WAV format"),
- sizeof(WAVContext),
- wav_probe,
- wav_read_header,
- wav_read_packet,
- NULL,
- wav_read_seek,
+ .name = "wav",
+ .long_name = NULL_IF_CONFIG_SMALL("WAV format"),
+ .priv_data_size = sizeof(WAVContext),
+ .read_probe = wav_probe,
+ .read_header = wav_read_header,
+ .read_packet = wav_read_packet,
+ .read_seek = wav_read_seek,
.flags= AVFMT_GENERIC_INDEX,
.codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0},
};
@@ -407,7 +649,7 @@ static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap)
return -1;
}
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -419,7 +661,7 @@ static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap)
st->need_parsing = AVSTREAM_PARSE_FULL;
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
size = find_guid(pb, guid_data);
if (size < 0) {
@@ -433,14 +675,13 @@ static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
AVInputFormat ff_w64_demuxer = {
- "w64",
- NULL_IF_CONFIG_SMALL("Sony Wave64 format"),
- sizeof(WAVContext),
- w64_probe,
- w64_read_header,
- wav_read_packet,
- NULL,
- wav_read_seek,
+ .name = "w64",
+ .long_name = NULL_IF_CONFIG_SMALL("Sony Wave64 format"),
+ .priv_data_size = sizeof(WAVContext),
+ .read_probe = w64_probe,
+ .read_header = w64_read_header,
+ .read_packet = wav_read_packet,
+ .read_seek = wav_read_seek,
.flags = AVFMT_GENERIC_INDEX,
.codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
};
diff --git a/libavformat/wc3movie.c b/libavformat/wc3movie.c
index e57a9bf..af5470f 100644
--- a/libavformat/wc3movie.c
+++ b/libavformat/wc3movie.c
@@ -30,6 +30,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "avformat.h"
+#include "internal.h"
#define FORM_TAG MKTAG('F', 'O', 'R', 'M')
#define MOVE_TAG MKTAG('M', 'O', 'V', 'E')
@@ -152,7 +153,6 @@ static int wc3_read_header(AVFormatContext *s,
(uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24),
(uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24));
return AVERROR_INVALIDDATA;
- break;
}
fourcc_tag = avio_rl32(pb);
@@ -164,10 +164,10 @@ static int wc3_read_header(AVFormatContext *s,
} while (fourcc_tag != BRCH_TAG);
/* initialize the decoder streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 33, 1, WC3_FRAME_FPS);
+ avpriv_set_pts_info(st, 33, 1, WC3_FRAME_FPS);
wc3->video_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_XAN_WC3;
@@ -175,10 +175,10 @@ static int wc3_read_header(AVFormatContext *s,
st->codec->width = wc3->width;
st->codec->height = wc3->height;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 33, 1, WC3_FRAME_FPS);
+ avpriv_set_pts_info(st, 33, 1, WC3_FRAME_FPS);
wc3->audio_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_PCM_S16LE;
@@ -293,11 +293,11 @@ static int wc3_read_close(AVFormatContext *s)
}
AVInputFormat ff_wc3_demuxer = {
- "wc3movie",
- NULL_IF_CONFIG_SMALL("Wing Commander III movie format"),
- sizeof(Wc3DemuxContext),
- wc3_probe,
- wc3_read_header,
- wc3_read_packet,
- wc3_read_close,
+ .name = "wc3movie",
+ .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III movie format"),
+ .priv_data_size = sizeof(Wc3DemuxContext),
+ .read_probe = wc3_probe,
+ .read_header = wc3_read_header,
+ .read_packet = wc3_read_packet,
+ .read_close = wc3_read_close,
};
diff --git a/libavformat/westwood.c b/libavformat/westwood.c
index 7c2b17d..82b7e94 100644
--- a/libavformat/westwood.c
+++ b/libavformat/westwood.c
@@ -35,6 +35,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define AUD_HEADER_SIZE 12
#define AUD_CHUNK_PREAMBLE_SIZE 8
@@ -144,10 +145,10 @@ static int wsaud_read_header(AVFormatContext *s,
wsaud->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8;
/* initialize the audio decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 33, 1, wsaud->audio_samplerate);
+ avpriv_set_pts_info(st, 33, 1, wsaud->audio_samplerate);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = wsaud->audio_type;
st->codec->codec_tag = 0; /* no tag */
@@ -221,10 +222,10 @@ static int wsvqa_read_header(AVFormatContext *s,
unsigned int chunk_size;
/* initialize the video decoder stream */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 33, 1, VQA_FRAMERATE);
+ avpriv_set_pts_info(st, 33, 1, VQA_FRAMERATE);
wsvqa->video_stream_index = st->index;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_WS_VQA;
@@ -247,10 +248,10 @@ static int wsvqa_read_header(AVFormatContext *s,
/* initialize the audio decoder stream for VQA v1 or nonzero samplerate */
if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) {
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
- av_set_pts_info(st, 33, 1, VQA_FRAMERATE);
+ avpriv_set_pts_info(st, 33, 1, VQA_FRAMERATE);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
if (AV_RL16(&header[0]) == 1)
st->codec->codec_id = CODEC_ID_WESTWOOD_SND1;
@@ -325,6 +326,11 @@ static int wsvqa_read_packet(AVFormatContext *s,
chunk_size = AV_RB32(&preamble[4]);
skip_byte = chunk_size & 0x01;
+ if ((chunk_type == SND2_TAG || chunk_type == SND1_TAG) && wsvqa->audio_channels == 0) {
+ av_log(s, AV_LOG_ERROR, "audio chunk without any audio header information found\n");
+ return AVERROR_INVALIDDATA;
+ }
+
if ((chunk_type == SND1_TAG) || (chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) {
if (av_new_packet(pkt, chunk_size))
@@ -368,21 +374,21 @@ static int wsvqa_read_packet(AVFormatContext *s,
#if CONFIG_WSAUD_DEMUXER
AVInputFormat ff_wsaud_demuxer = {
- "wsaud",
- NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
- sizeof(WsAudDemuxContext),
- wsaud_probe,
- wsaud_read_header,
- wsaud_read_packet,
+ .name = "wsaud",
+ .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
+ .priv_data_size = sizeof(WsAudDemuxContext),
+ .read_probe = wsaud_probe,
+ .read_header = wsaud_read_header,
+ .read_packet = wsaud_read_packet,
};
#endif
#if CONFIG_WSVQA_DEMUXER
AVInputFormat ff_wsvqa_demuxer = {
- "wsvqa",
- NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"),
- sizeof(WsVqaDemuxContext),
- wsvqa_probe,
- wsvqa_read_header,
- wsvqa_read_packet,
+ .name = "wsvqa",
+ .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"),
+ .priv_data_size = sizeof(WsVqaDemuxContext),
+ .read_probe = wsvqa_probe,
+ .read_header = wsvqa_read_header,
+ .read_packet = wsvqa_read_packet,
};
#endif
diff --git a/libavformat/wtv.c b/libavformat/wtv.c
index 0f9fdef..e4b9ae5 100644
--- a/libavformat/wtv.c
+++ b/libavformat/wtv.c
@@ -26,14 +26,13 @@
*/
#include "libavutil/intreadwrite.h"
-#include "libavutil/intfloat_readwrite.h"
+#include "libavutil/intfloat.h"
#include "libavutil/dict.h"
#include "avformat.h"
#include "internal.h"
#include "riff.h"
#include "asf.h"
#include "mpegts.h"
-#include <strings.h>
/* Macros for formating GUIDs */
#define PRI_GUID \
@@ -459,7 +458,7 @@ static void crazytime_to_iso8601(char *buf, int buf_size, int64_t value)
*/
static void oledate_to_iso8601(char *buf, int buf_size, int64_t value)
{
- time_t t = 631112400LL + 86400*av_int2dbl(value);
+ time_t t = 631112400LL + 86400*av_int2double(value);
strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
}
@@ -481,7 +480,7 @@ static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length)
if (!filesize)
goto done;
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
goto done;
av_dict_set(&st->metadata, "title", description, 0);
@@ -524,7 +523,7 @@ static void get_tag(AVFormatContext *s, AVIOContext *pb, const char *key, int ty
else if (!strcmp(key, "WM/WMRVExpirationDate"))
oledate_to_iso8601(buf, buf_size, num);
else if (!strcmp(key, "WM/WMRVBitrate"))
- snprintf(buf, buf_size, "%f", av_int2dbl(num));
+ snprintf(buf, buf_size, "%f", av_int2double(num));
else
snprintf(buf, buf_size, "%"PRIi64, num);
} else if (type == 5 && length == 2) {
@@ -626,14 +625,15 @@ static AVStream * new_stream(AVFormatContext *s, AVStream *st, int sid, int code
WtvStream *wst = av_mallocz(sizeof(WtvStream));
if (!wst)
return NULL;
- st = av_new_stream(s, sid);
+ st = avformat_new_stream(s, NULL);
if (!st)
return NULL;
+ st->id = sid;
st->priv_data = wst;
}
st->codec->codec_type = codec_type;
st->need_parsing = AVSTREAM_PARSE_FULL;
- av_set_pts_info(st, 64, 1, 10000000);
+ avpriv_set_pts_info(st, 64, 1, 10000000);
return st;
}
@@ -766,7 +766,7 @@ enum {
* Parse WTV chunks
* @param mode SEEK_TO_DATA or SEEK_TO_PTS
* @param seekts timestamp
- * @param[out] len Length of data chunk
+ * @param[out] len_ptr Length of data chunk
* @return stream index of data chunk, or <0 on error
*/
static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_ptr)
@@ -836,7 +836,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p
buf_size = FFMIN(len - consumed, sizeof(buf));
avio_read(pb, buf, buf_size);
consumed += buf_size;
- ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, 0, 0, 0, 0);
+ ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0, NULL);
}
} else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) {
int stream_index = ff_find_stream_index(s, sid);
diff --git a/libavformat/wv.c b/libavformat/wv.c
index d6d7099..5f7b3b4 100644
--- a/libavformat/wv.c
+++ b/libavformat/wv.c
@@ -23,6 +23,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "avformat.h"
+#include "internal.h"
#include "apetag.h"
#include "id3v1.h"
@@ -220,7 +221,7 @@ static int wv_read_header(AVFormatContext *s,
}
/* now we are ready: build format streams */
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return -1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -229,7 +230,7 @@ static int wv_read_header(AVFormatContext *s,
st->codec->channel_layout = wc->chmask;
st->codec->sample_rate = wc->rate;
st->codec->bits_per_coded_sample = wc->bpp;
- av_set_pts_info(st, 64, 1, wc->rate);
+ avpriv_set_pts_info(st, 64, 1, wc->rate);
st->start_time = 0;
st->duration = wc->samples;
@@ -250,6 +251,7 @@ static int wv_read_packet(AVFormatContext *s,
WVContext *wc = s->priv_data;
int ret;
int size, ver, off;
+ int64_t pos;
if (s->pb->eof_reached)
return AVERROR(EIO);
@@ -258,6 +260,7 @@ static int wv_read_packet(AVFormatContext *s,
return -1;
}
+ pos = wc->pos;
off = wc->multichannel ? 4 : 0;
if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0)
return AVERROR(ENOMEM);
@@ -314,7 +317,7 @@ static int wv_read_packet(AVFormatContext *s,
pkt->stream_index = 0;
wc->block_parsed = 1;
pkt->pts = wc->soff;
- av_add_index_entry(s->streams[0], wc->pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
+ av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
return 0;
}
@@ -328,7 +331,8 @@ static int wv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
int64_t pos, pts;
/* if found, seek there */
- if (index >= 0){
+ if (index >= 0 &&
+ timestamp <= st->index_entries[st->nb_index_entries - 1].timestamp) {
wc->block_parsed = 1;
avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
return 0;
@@ -351,12 +355,11 @@ static int wv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
}
AVInputFormat ff_wv_demuxer = {
- "wv",
- NULL_IF_CONFIG_SMALL("WavPack"),
- sizeof(WVContext),
- wv_probe,
- wv_read_header,
- wv_read_packet,
- NULL,
- wv_read_seek,
+ .name = "wv",
+ .long_name = NULL_IF_CONFIG_SMALL("WavPack"),
+ .priv_data_size = sizeof(WVContext),
+ .read_probe = wv_probe,
+ .read_header = wv_read_header,
+ .read_packet = wv_read_packet,
+ .read_seek = wv_read_seek,
};
diff --git a/libavformat/xa.c b/libavformat/xa.c
index c3421a3..0a1ad59 100644
--- a/libavformat/xa.c
+++ b/libavformat/xa.c
@@ -29,6 +29,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
#define XA00_TAG MKTAG('X', 'A', 0, 0)
#define XAI0_TAG MKTAG('X', 'A', 'I', 0)
@@ -70,7 +71,7 @@ static int xa_read_header(AVFormatContext *s,
AVStream *st;
/*Set up the XA Audio Decoder*/
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -86,7 +87,7 @@ static int xa_read_header(AVFormatContext *s,
st->codec->block_align = avio_rl16(pb);
st->codec->bits_per_coded_sample = avio_rl16(pb);
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
return 0;
}
@@ -119,10 +120,10 @@ static int xa_read_packet(AVFormatContext *s,
}
AVInputFormat ff_xa_demuxer = {
- "xa",
- NULL_IF_CONFIG_SMALL("Maxis XA File Format"),
- sizeof(MaxisXADemuxContext),
- xa_probe,
- xa_read_header,
- xa_read_packet,
+ .name = "xa",
+ .long_name = NULL_IF_CONFIG_SMALL("Maxis XA File Format"),
+ .priv_data_size = sizeof(MaxisXADemuxContext),
+ .read_probe = xa_probe,
+ .read_header = xa_read_header,
+ .read_packet = xa_read_packet,
};
diff --git a/libavformat/xmv.c b/libavformat/xmv.c
new file mode 100644
index 0000000..bc4b239
--- /dev/null
+++ b/libavformat/xmv.c
@@ -0,0 +1,568 @@
+/*
+ * Microsoft XMV demuxer
+ * Copyright (c) 2011 Sven Hesse <drmccoy at drmccoy.de>
+ * Copyright (c) 2011 Matthew Hoops <clone2727 at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Microsoft XMV demuxer
+ */
+
+#include <stdint.h>
+
+#include "libavutil/intreadwrite.h"
+
+#include "avformat.h"
+#include "internal.h"
+#include "riff.h"
+
+#define XMV_MIN_HEADER_SIZE 36
+
+#define XMV_AUDIO_ADPCM51_FRONTLEFTRIGHT 1
+#define XMV_AUDIO_ADPCM51_FRONTCENTERLOW 2
+#define XMV_AUDIO_ADPCM51_REARLEFTRIGHT 4
+
+#define XMV_AUDIO_ADPCM51 (XMV_AUDIO_ADPCM51_FRONTLEFTRIGHT | \
+ XMV_AUDIO_ADPCM51_FRONTCENTERLOW | \
+ XMV_AUDIO_ADPCM51_REARLEFTRIGHT)
+
+typedef struct XMVAudioTrack {
+ uint16_t compression;
+ uint16_t channels;
+ uint32_t sample_rate;
+ uint16_t bits_per_sample;
+ uint32_t bit_rate;
+ uint16_t flags;
+ uint16_t block_align;
+ uint16_t block_samples;
+
+ enum CodecID codec_id;
+} XMVAudioTrack;
+
+typedef struct XMVVideoPacket {
+ /* The decoder stream index for this video packet. */
+ int stream_index;
+
+ uint32_t data_size;
+ uint32_t data_offset;
+
+ uint32_t current_frame;
+ uint32_t frame_count;
+
+ /* Does the video packet contain extra data? */
+ int has_extradata;
+
+ /* Extra data */
+ uint8_t extradata[4];
+
+ int64_t last_pts;
+ int64_t pts;
+} XMVVideoPacket;
+
+typedef struct XMVAudioPacket {
+ /* The decoder stream index for this audio packet. */
+ int stream_index;
+
+ /* The audio track this packet encodes. */
+ XMVAudioTrack *track;
+
+ uint32_t data_size;
+ uint32_t data_offset;
+
+ uint32_t frame_size;
+
+ uint32_t block_count;
+} XMVAudioPacket;
+
+typedef struct XMVDemuxContext {
+ uint16_t audio_track_count;
+
+ XMVAudioTrack *audio_tracks;
+
+ uint32_t this_packet_size;
+ uint32_t next_packet_size;
+
+ uint32_t this_packet_offset;
+ uint32_t next_packet_offset;
+
+ uint16_t current_stream;
+ uint16_t stream_count;
+
+ XMVVideoPacket video;
+ XMVAudioPacket *audio;
+} XMVDemuxContext;
+
+static int xmv_probe(AVProbeData *p)
+{
+ uint32_t file_version;
+
+ if (p->buf_size < XMV_MIN_HEADER_SIZE)
+ return 0;
+
+ file_version = AV_RL32(p->buf + 16);
+ if ((file_version == 0) || (file_version > 4))
+ return 0;
+
+ if (!memcmp(p->buf + 12, "xobX", 4))
+ return AVPROBE_SCORE_MAX;
+
+ return 0;
+}
+
+static int xmv_read_header(AVFormatContext *s,
+ AVFormatParameters *ap)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ AVStream *vst = NULL;
+
+ uint32_t file_version;
+ uint32_t this_packet_size;
+ uint16_t audio_track;
+
+ avio_skip(pb, 4); /* Next packet size */
+
+ this_packet_size = avio_rl32(pb);
+
+ avio_skip(pb, 4); /* Max packet size */
+ avio_skip(pb, 4); /* "xobX" */
+
+ file_version = avio_rl32(pb);
+ if ((file_version != 4) && (file_version != 2))
+ av_log_ask_for_sample(s, "Found uncommon version %d\n", file_version);
+
+
+ /* Video track */
+
+ vst = avformat_new_stream(s, NULL);
+ if (!vst)
+ return AVERROR(ENOMEM);
+
+ avpriv_set_pts_info(vst, 32, 1, 1000);
+
+ vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ vst->codec->codec_id = CODEC_ID_WMV2;
+ vst->codec->codec_tag = MKBETAG('W', 'M', 'V', '2');
+ vst->codec->width = avio_rl32(pb);
+ vst->codec->height = avio_rl32(pb);
+
+ vst->duration = avio_rl32(pb);
+
+ xmv->video.stream_index = vst->index;
+
+ /* Audio tracks */
+
+ xmv->audio_track_count = avio_rl16(pb);
+
+ avio_skip(pb, 2); /* Unknown (padding?) */
+
+ xmv->audio_tracks = av_malloc(xmv->audio_track_count * sizeof(XMVAudioTrack));
+ if (!xmv->audio_tracks)
+ return AVERROR(ENOMEM);
+
+ xmv->audio = av_malloc(xmv->audio_track_count * sizeof(XMVAudioPacket));
+ if (!xmv->audio)
+ return AVERROR(ENOMEM);
+
+ for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
+ XMVAudioTrack *track = &xmv->audio_tracks[audio_track];
+ XMVAudioPacket *packet = &xmv->audio [audio_track];
+ AVStream *ast = NULL;
+
+ track->compression = avio_rl16(pb);
+ track->channels = avio_rl16(pb);
+ track->sample_rate = avio_rl32(pb);
+ track->bits_per_sample = avio_rl16(pb);
+ track->flags = avio_rl16(pb);
+
+ track->bit_rate = track->bits_per_sample *
+ track->sample_rate *
+ track->channels;
+ track->block_align = 36 * track->channels;
+ track->block_samples = 64;
+ track->codec_id = ff_wav_codec_get_id(track->compression,
+ track->bits_per_sample);
+
+ packet->track = track;
+ packet->stream_index = -1;
+
+ packet->frame_size = 0;
+ packet->block_count = 0;
+
+ /* TODO: ADPCM'd 5.1 sound is encoded in three separate streams.
+ * Those need to be interleaved to a proper 5.1 stream. */
+ if (track->flags & XMV_AUDIO_ADPCM51)
+ av_log(s, AV_LOG_WARNING, "Unsupported 5.1 ADPCM audio stream "
+ "(0x%04X)\n", track->flags);
+
+ ast = avformat_new_stream(s, NULL);
+ if (!ast)
+ return AVERROR(ENOMEM);
+
+ ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ ast->codec->codec_id = track->codec_id;
+ ast->codec->codec_tag = track->compression;
+ ast->codec->channels = track->channels;
+ ast->codec->sample_rate = track->sample_rate;
+ ast->codec->bits_per_coded_sample = track->bits_per_sample;
+ ast->codec->bit_rate = track->bit_rate;
+ ast->codec->block_align = 36 * track->channels;
+
+ avpriv_set_pts_info(ast, 32, track->block_samples, track->sample_rate);
+
+ packet->stream_index = ast->index;
+
+ ast->duration = vst->duration;
+ }
+
+
+ /** Initialize the packet context */
+
+ xmv->next_packet_offset = avio_tell(pb);
+ xmv->next_packet_size = this_packet_size - xmv->next_packet_offset;
+ xmv->stream_count = xmv->audio_track_count + 1;
+
+ return 0;
+}
+
+static void xmv_read_extradata(uint8_t *extradata, AVIOContext *pb)
+{
+ /* Read the XMV extradata */
+
+ uint32_t data = avio_rl32(pb);
+
+ int mspel_bit = !!(data & 0x01);
+ int loop_filter = !!(data & 0x02);
+ int abt_flag = !!(data & 0x04);
+ int j_type_bit = !!(data & 0x08);
+ int top_left_mv_flag = !!(data & 0x10);
+ int per_mb_rl_bit = !!(data & 0x20);
+ int slice_count = (data >> 6) & 7;
+
+ /* Write it back as standard WMV2 extradata */
+
+ data = 0;
+
+ data |= mspel_bit << 15;
+ data |= loop_filter << 14;
+ data |= abt_flag << 13;
+ data |= j_type_bit << 12;
+ data |= top_left_mv_flag << 11;
+ data |= per_mb_rl_bit << 10;
+ data |= slice_count << 7;
+
+ AV_WB32(extradata, data);
+}
+
+static int xmv_process_packet_header(AVFormatContext *s)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ AVIOContext *pb = s->pb;
+
+ uint8_t data[8];
+ uint16_t audio_track;
+ uint32_t data_offset;
+
+ /* Next packet size */
+ xmv->next_packet_size = avio_rl32(pb);
+
+ /* Packet video header */
+
+ if (avio_read(pb, data, 8) != 8)
+ return AVERROR(EIO);
+
+ xmv->video.data_size = AV_RL32(data) & 0x007FFFFF;
+
+ xmv->video.current_frame = 0;
+ xmv->video.frame_count = (AV_RL32(data) >> 23) & 0xFF;
+
+ xmv->video.has_extradata = (data[3] & 0x80) != 0;
+
+ /* Adding the audio data sizes and the video data size keeps you 4 bytes
+ * short for every audio track. But as playing around with XMV files with
+ * ADPCM audio showed, taking the extra 4 bytes from the audio data gives
+ * you either completely distorted audio or click (when skipping the
+ * remaining 68 bytes of the ADPCM block). Substracting 4 bytes for every
+ * audio track from the video data works at least for the audio. Probably
+ * some alignment thing?
+ * The video data has (always?) lots of padding, so it should work out...
+ */
+ xmv->video.data_size -= xmv->audio_track_count * 4;
+
+ xmv->current_stream = 0;
+ if (!xmv->video.frame_count) {
+ xmv->video.frame_count = 1;
+ xmv->current_stream = 1;
+ }
+
+ /* Packet audio header */
+
+ for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
+ XMVAudioPacket *packet = &xmv->audio[audio_track];
+
+ if (avio_read(pb, data, 4) != 4)
+ return AVERROR(EIO);
+
+ packet->data_size = AV_RL32(data) & 0x007FFFFF;
+ if ((packet->data_size == 0) && (audio_track != 0))
+ /* This happens when I create an XMV with several identical audio
+ * streams. From the size calculations, duplicating the previous
+ * stream's size works out, but the track data itself is silent.
+ * Maybe this should also redirect the offset to the previous track?
+ */
+ packet->data_size = xmv->audio[audio_track - 1].data_size;
+
+ /** Carve up the audio data in frame_count slices */
+ packet->frame_size = packet->data_size / xmv->video.frame_count;
+ packet->frame_size -= packet->frame_size % packet->track->block_align;
+ }
+
+ /* Packet data offsets */
+
+ data_offset = avio_tell(pb);
+
+ xmv->video.data_offset = data_offset;
+ data_offset += xmv->video.data_size;
+
+ for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
+ xmv->audio[audio_track].data_offset = data_offset;
+ data_offset += xmv->audio[audio_track].data_size;
+ }
+
+ /* Video frames header */
+
+ /* Read new video extra data */
+ if (xmv->video.data_size > 0) {
+ if (xmv->video.has_extradata) {
+ xmv_read_extradata(xmv->video.extradata, pb);
+
+ xmv->video.data_size -= 4;
+ xmv->video.data_offset += 4;
+
+ if (xmv->video.stream_index >= 0) {
+ AVStream *vst = s->streams[xmv->video.stream_index];
+
+ assert(xmv->video.stream_index < s->nb_streams);
+
+ if (vst->codec->extradata_size < 4) {
+ av_free(vst->codec->extradata);
+
+ vst->codec->extradata =
+ av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE);
+ vst->codec->extradata_size = 4;
+ }
+
+ memcpy(vst->codec->extradata, xmv->video.extradata, 4);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int xmv_fetch_new_packet(AVFormatContext *s)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int result;
+
+ /* Seek to it */
+ xmv->this_packet_offset = xmv->next_packet_offset;
+ if (avio_seek(pb, xmv->this_packet_offset, SEEK_SET) != xmv->this_packet_offset)
+ return AVERROR(EIO);
+
+ /* Update the size */
+ xmv->this_packet_size = xmv->next_packet_size;
+ if (xmv->this_packet_size < (12 + xmv->audio_track_count * 4))
+ return AVERROR(EIO);
+
+ /* Process the header */
+ result = xmv_process_packet_header(s);
+ if (result)
+ return result;
+
+ /* Update the offset */
+ xmv->next_packet_offset = xmv->this_packet_offset + xmv->this_packet_size;
+
+ return 0;
+}
+
+static int xmv_fetch_audio_packet(AVFormatContext *s,
+ AVPacket *pkt, uint32_t stream)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ XMVAudioPacket *audio = &xmv->audio[stream];
+
+ uint32_t data_size;
+ uint32_t block_count;
+ int result;
+
+ /* Seek to it */
+ if (avio_seek(pb, audio->data_offset, SEEK_SET) != audio->data_offset)
+ return AVERROR(EIO);
+
+ if ((xmv->video.current_frame + 1) < xmv->video.frame_count)
+ /* Not the last frame, get at most frame_size bytes. */
+ data_size = FFMIN(audio->frame_size, audio->data_size);
+ else
+ /* Last frame, get the rest. */
+ data_size = audio->data_size;
+
+ /* Read the packet */
+ result = av_get_packet(pb, pkt, data_size);
+ if (result <= 0)
+ return result;
+
+ pkt->stream_index = audio->stream_index;
+
+ /* Calculate the PTS */
+
+ block_count = data_size / audio->track->block_align;
+
+ pkt->duration = block_count;
+ pkt->pts = audio->block_count;
+ pkt->dts = AV_NOPTS_VALUE;
+
+ audio->block_count += block_count;
+
+ /* Advance offset */
+ audio->data_size -= data_size;
+ audio->data_offset += data_size;
+
+ return 0;
+}
+
+static int xmv_fetch_video_packet(AVFormatContext *s,
+ AVPacket *pkt)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ AVIOContext *pb = s->pb;
+ XMVVideoPacket *video = &xmv->video;
+
+ int result;
+ uint32_t frame_header;
+ uint32_t frame_size, frame_timestamp;
+ uint32_t i;
+
+ /* Seek to it */
+ if (avio_seek(pb, video->data_offset, SEEK_SET) != video->data_offset)
+ return AVERROR(EIO);
+
+ /* Read the frame header */
+ frame_header = avio_rl32(pb);
+
+ frame_size = (frame_header & 0x1FFFF) * 4 + 4;
+ frame_timestamp = (frame_header >> 17);
+
+ if ((frame_size + 4) > video->data_size)
+ return AVERROR(EIO);
+
+ /* Create the packet */
+ result = av_new_packet(pkt, frame_size);
+ if (result)
+ return result;
+
+ /* Contrary to normal WMV2 video, the bit stream in XMV's
+ * WMV2 is little-endian.
+ * TODO: This manual swap is of course suboptimal.
+ */
+ for (i = 0; i < frame_size; i += 4)
+ AV_WB32(pkt->data + i, avio_rl32(pb));
+
+ pkt->stream_index = video->stream_index;
+
+ /* Calculate the PTS */
+
+ video->last_pts = frame_timestamp + video->pts;
+
+ pkt->duration = 0;
+ pkt->pts = video->last_pts;
+ pkt->dts = AV_NOPTS_VALUE;
+
+ video->pts += frame_timestamp;
+
+ /* Keyframe? */
+ pkt->flags = (pkt->data[0] & 0x80) ? 0 : AV_PKT_FLAG_KEY;
+
+ /* Advance offset */
+ video->data_size -= frame_size + 4;
+ video->data_offset += frame_size + 4;
+
+ return 0;
+}
+
+static int xmv_read_packet(AVFormatContext *s,
+ AVPacket *pkt)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+ int result;
+
+ if (xmv->video.current_frame == xmv->video.frame_count) {
+ /* No frames left in this packet, so we fetch a new one */
+
+ result = xmv_fetch_new_packet(s);
+ if (result)
+ return result;
+ }
+
+ if (xmv->current_stream == 0) {
+ /* Fetch a video frame */
+
+ result = xmv_fetch_video_packet(s, pkt);
+ if (result)
+ return result;
+
+ } else {
+ /* Fetch an audio frame */
+
+ result = xmv_fetch_audio_packet(s, pkt, xmv->current_stream - 1);
+ if (result)
+ return result;
+ }
+
+ /* Increase our counters */
+ if (++xmv->current_stream >= xmv->stream_count) {
+ xmv->current_stream = 0;
+ xmv->video.current_frame += 1;
+ }
+
+ return 0;
+}
+
+static int xmv_read_close(AVFormatContext *s)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+
+ av_free(xmv->audio);
+ av_free(xmv->audio_tracks);
+
+ return 0;
+}
+
+AVInputFormat ff_xmv_demuxer = {
+ .name = "xmv",
+ .long_name = NULL_IF_CONFIG_SMALL("Microsoft XMV"),
+ .priv_data_size = sizeof(XMVDemuxContext),
+ .read_probe = xmv_probe,
+ .read_header = xmv_read_header,
+ .read_packet = xmv_read_packet,
+ .read_close = xmv_read_close,
+};
diff --git a/libavformat/xwma.c b/libavformat/xwma.c
index d18ab48..5839bdc 100644
--- a/libavformat/xwma.c
+++ b/libavformat/xwma.c
@@ -22,6 +22,7 @@
#include <inttypes.h>
#include "avformat.h"
+#include "internal.h"
#include "riff.h"
/*
@@ -69,7 +70,7 @@ static int xwma_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (tag != MKTAG('f', 'm', 't', ' '))
return -1;
size = avio_rl32(pb);
- st = av_new_stream(s, 0);
+ st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -115,7 +116,7 @@ static int xwma_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
/* set the sample rate */
- av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
/* parse the remaining RIFF chunks */
for (;;) {
@@ -252,10 +253,10 @@ static int xwma_read_packet(AVFormatContext *s, AVPacket *pkt)
}
AVInputFormat ff_xwma_demuxer = {
- "xwma",
- NULL_IF_CONFIG_SMALL("Microsoft xWMA"),
- sizeof(XWMAContext),
- xwma_probe,
- xwma_read_header,
- xwma_read_packet,
+ .name = "xwma",
+ .long_name = NULL_IF_CONFIG_SMALL("Microsoft xWMA"),
+ .priv_data_size = sizeof(XWMAContext),
+ .read_probe = xwma_probe,
+ .read_header = xwma_read_header,
+ .read_packet = xwma_read_packet,
};
diff --git a/libavformat/yop.c b/libavformat/yop.c
index e367187..a317825 100644
--- a/libavformat/yop.c
+++ b/libavformat/yop.c
@@ -1,5 +1,4 @@
-/**
- * @file
+/*
* Psygnosis YOP demuxer
*
* Copyright (C) 2010 Mohamed Naufal Basheer <naufal11 at gmail.com>
@@ -25,6 +24,7 @@
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "internal.h"
typedef struct yop_dec_context {
AVPacket video_packet;
@@ -57,8 +57,8 @@ static int yop_read_header(AVFormatContext *s, AVFormatParameters *ap)
int frame_rate, ret;
- audio_stream = av_new_stream(s, 0);
- video_stream = av_new_stream(s, 1);
+ audio_stream = avformat_new_stream(s, NULL);
+ video_stream = avformat_new_stream(s, NULL);
// Extra data that will be passed to the decoder
video_stream->codec->extradata_size = 8;
@@ -106,7 +106,7 @@ static int yop_read_header(AVFormatContext *s, AVFormatParameters *ap)
avio_seek(pb, 2048, SEEK_SET);
- av_set_pts_info(video_stream, 32, 1, frame_rate);
+ avpriv_set_pts_info(video_stream, 32, 1, frame_rate);
return 0;
}
@@ -203,14 +203,14 @@ static int yop_read_seek(AVFormatContext *s, int stream_index,
}
AVInputFormat ff_yop_demuxer = {
- "yop",
- NULL_IF_CONFIG_SMALL("Psygnosis YOP Format"),
- sizeof(YopDecContext),
- yop_probe,
- yop_read_header,
- yop_read_packet,
- yop_read_close,
- yop_read_seek,
+ .name = "yop",
+ .long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Format"),
+ .priv_data_size = sizeof(YopDecContext),
+ .read_probe = yop_probe,
+ .read_header = yop_read_header,
+ .read_packet = yop_read_packet,
+ .read_close = yop_read_close,
+ .read_seek = yop_read_seek,
.extensions = "yop",
.flags = AVFMT_GENERIC_INDEX,
};
diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c
index 9a6a0c8..698ee68 100644
--- a/libavformat/yuv4mpeg.c
+++ b/libavformat/yuv4mpeg.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
+#include "internal.h"
#define Y4M_MAGIC "YUV4MPEG2"
#define Y4M_FRAME_MAGIC "FRAME"
@@ -38,23 +39,24 @@ static int yuv4_generate_header(AVFormatContext *s, char* buf)
char inter;
const char *colorspace = "";
- st = s->streams[0];
- width = st->codec->width;
+ st = s->streams[0];
+ width = st->codec->width;
height = st->codec->height;
- av_reduce(&raten, &rated, st->codec->time_base.den, st->codec->time_base.num, (1UL<<31)-1);
+ av_reduce(&raten, &rated, st->codec->time_base.den,
+ st->codec->time_base.num, (1UL << 31) - 1);
aspectn = st->sample_aspect_ratio.num;
aspectd = st->sample_aspect_ratio.den;
- if ( aspectn == 0 && aspectd == 1 ) aspectd = 0; // 0:0 means unknown
+ if (aspectn == 0 && aspectd == 1)
+ aspectd = 0; // 0:0 means unknown
inter = 'p'; /* progressive is the default */
- if (st->codec->coded_frame && st->codec->coded_frame->interlaced_frame) {
+ if (st->codec->coded_frame && st->codec->coded_frame->interlaced_frame)
inter = st->codec->coded_frame->top_field_first ? 't' : 'b';
- }
- switch(st->codec->pix_fmt) {
+ switch (st->codec->pix_fmt) {
case PIX_FMT_GRAY8:
colorspace = " Cmono";
break;
@@ -62,9 +64,11 @@ static int yuv4_generate_header(AVFormatContext *s, char* buf)
colorspace = " C411 XYSCSS=411";
break;
case PIX_FMT_YUV420P:
- colorspace = (st->codec->chroma_sample_location == AVCHROMA_LOC_TOPLEFT)?" C420paldv XYSCSS=420PALDV":
- (st->codec->chroma_sample_location == AVCHROMA_LOC_LEFT) ?" C420mpeg2 XYSCSS=420MPEG2":
- " C420jpeg XYSCSS=420JPEG";
+ switch (st->codec->chroma_sample_location) {
+ case AVCHROMA_LOC_TOPLEFT: colorspace = " C420paldv XYSCSS=420PALDV"; break;
+ case AVCHROMA_LOC_LEFT: colorspace = " C420mpeg2 XYSCSS=420MPEG2"; break;
+ default: colorspace = " C420jpeg XYSCSS=420JPEG"; break;
+ }
break;
case PIX_FMT_YUV422P:
colorspace = " C422 XYSCSS=422";
@@ -76,13 +80,8 @@ static int yuv4_generate_header(AVFormatContext *s, char* buf)
/* construct stream header, if this is the first frame */
n = snprintf(buf, Y4M_LINE_MAX, "%s W%d H%d F%d:%d I%c A%d:%d%s\n",
- Y4M_MAGIC,
- width,
- height,
- raten, rated,
- inter,
- aspectn, aspectd,
- colorspace);
+ Y4M_MAGIC, width, height, raten, rated, inter,
+ aspectn, aspectd, colorspace);
return n;
}
@@ -95,7 +94,7 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
int* first_pkt = s->priv_data;
int width, height, h_chroma_shift, v_chroma_shift;
int i;
- char buf2[Y4M_LINE_MAX+1];
+ char buf2[Y4M_LINE_MAX + 1];
char buf1[20];
uint8_t *ptr, *ptr1, *ptr2;
@@ -105,7 +104,8 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
if (*first_pkt) {
*first_pkt = 0;
if (yuv4_generate_header(s, buf2) < 0) {
- av_log(s, AV_LOG_ERROR, "Error. YUV4MPEG stream header write failed.\n");
+ av_log(s, AV_LOG_ERROR,
+ "Error. YUV4MPEG stream header write failed.\n");
return AVERROR(EIO);
} else {
avio_write(pb, buf2, strlen(buf2));
@@ -117,31 +117,32 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
snprintf(buf1, sizeof(buf1), "%s\n", Y4M_FRAME_MAGIC);
avio_write(pb, buf1, strlen(buf1));
- width = st->codec->width;
+ width = st->codec->width;
height = st->codec->height;
ptr = picture->data[0];
- for(i=0;i<height;i++) {
+ for (i = 0; i < height; i++) {
avio_write(pb, ptr, width);
ptr += picture->linesize[0];
}
- if (st->codec->pix_fmt != PIX_FMT_GRAY8){
- // Adjust for smaller Cb and Cr planes
- avcodec_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift, &v_chroma_shift);
- width >>= h_chroma_shift;
- height >>= v_chroma_shift;
-
- ptr1 = picture->data[1];
- ptr2 = picture->data[2];
- for(i=0;i<height;i++) { /* Cb */
- avio_write(pb, ptr1, width);
- ptr1 += picture->linesize[1];
- }
- for(i=0;i<height;i++) { /* Cr */
- avio_write(pb, ptr2, width);
+ if (st->codec->pix_fmt != PIX_FMT_GRAY8) {
+ // Adjust for smaller Cb and Cr planes
+ avcodec_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift,
+ &v_chroma_shift);
+ width >>= h_chroma_shift;
+ height >>= v_chroma_shift;
+
+ ptr1 = picture->data[1];
+ ptr2 = picture->data[2];
+ for (i = 0; i < height; i++) { /* Cb */
+ avio_write(pb, ptr1, width);
+ ptr1 += picture->linesize[1];
+ }
+ for (i = 0; i < height; i++) { /* Cr */
+ avio_write(pb, ptr2, width);
ptr2 += picture->linesize[2];
- }
+ }
}
avio_flush(pb);
return 0;
@@ -149,19 +150,21 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
static int yuv4_write_header(AVFormatContext *s)
{
- int* first_pkt = s->priv_data;
+ int *first_pkt = s->priv_data;
if (s->nb_streams != 1)
return AVERROR(EIO);
if (s->streams[0]->codec->pix_fmt == PIX_FMT_YUV411P) {
- av_log(s, AV_LOG_ERROR, "Warning: generating rarely used 4:1:1 YUV stream, some mjpegtools might not work.\n");
- }
- else if ((s->streams[0]->codec->pix_fmt != PIX_FMT_YUV420P) &&
- (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV422P) &&
- (s->streams[0]->codec->pix_fmt != PIX_FMT_GRAY8) &&
- (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV444P)) {
- av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg only handles yuv444p, yuv422p, yuv420p, yuv411p and gray pixel formats. Use -pix_fmt to select one.\n");
+ av_log(s, AV_LOG_ERROR, "Warning: generating rarely used 4:1:1 YUV "
+ "stream, some mjpegtools might not work.\n");
+ } else if ((s->streams[0]->codec->pix_fmt != PIX_FMT_YUV420P) &&
+ (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV422P) &&
+ (s->streams[0]->codec->pix_fmt != PIX_FMT_GRAY8) &&
+ (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV444P)) {
+ av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg only handles yuv444p, "
+ "yuv422p, yuv420p, yuv411p and gray pixel formats. "
+ "Use -pix_fmt to select one.\n");
return AVERROR(EIO);
}
@@ -170,16 +173,16 @@ static int yuv4_write_header(AVFormatContext *s)
}
AVOutputFormat ff_yuv4mpegpipe_muxer = {
- "yuv4mpegpipe",
- NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"),
- "",
- "y4m",
- sizeof(int),
- CODEC_ID_NONE,
- CODEC_ID_RAWVIDEO,
- yuv4_write_header,
- yuv4_write_packet,
- .flags = AVFMT_RAWPICTURE,
+ .name = "yuv4mpegpipe",
+ .long_name = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"),
+ .mime_type = "",
+ .extensions = "y4m",
+ .priv_data_size = sizeof(int),
+ .audio_codec = CODEC_ID_NONE,
+ .video_codec = CODEC_ID_RAWVIDEO,
+ .write_header = yuv4_write_header,
+ .write_packet = yuv4_write_packet,
+ .flags = AVFMT_RAWPICTURE,
};
#endif
@@ -189,85 +192,96 @@ AVOutputFormat ff_yuv4mpegpipe_muxer = {
static int yuv4_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
- char header[MAX_YUV4_HEADER+10]; // Include headroom for the longest option
- char *tokstart,*tokend,*header_end;
+ char header[MAX_YUV4_HEADER + 10]; // Include headroom for
+ // the longest option
+ char *tokstart, *tokend, *header_end;
int i;
AVIOContext *pb = s->pb;
- int width=-1, height=-1, raten=0, rated=0, aspectn=0, aspectd=0;
- enum PixelFormat pix_fmt=PIX_FMT_NONE,alt_pix_fmt=PIX_FMT_NONE;
+ int width = -1, height = -1, raten = 0,
+ rated = 0, aspectn = 0, aspectd = 0;
+ enum PixelFormat pix_fmt = PIX_FMT_NONE, alt_pix_fmt = PIX_FMT_NONE;
enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED;
AVStream *st;
struct frame_attributes *s1 = s->priv_data;
- for (i=0; i<MAX_YUV4_HEADER; i++) {
+ for (i = 0; i < MAX_YUV4_HEADER; i++) {
header[i] = avio_r8(pb);
if (header[i] == '\n') {
- header[i+1] = 0x20; // Add a space after last option. Makes parsing "444" vs "444alpha" easier.
- header[i+2] = 0;
+ header[i + 1] = 0x20; // Add a space after last option.
+ // Makes parsing "444" vs "444alpha" easier.
+ header[i + 2] = 0;
break;
}
}
- if (i == MAX_YUV4_HEADER) return -1;
- if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC))) return -1;
+ if (i == MAX_YUV4_HEADER)
+ return -1;
+ if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC)))
+ return -1;
s1->interlaced_frame = 0;
s1->top_field_first = 0;
- header_end = &header[i+1]; // Include space
- for(tokstart = &header[strlen(Y4M_MAGIC) + 1]; tokstart < header_end; tokstart++) {
- if (*tokstart==0x20) continue;
+ header_end = &header[i + 1]; // Include space
+ for (tokstart = &header[strlen(Y4M_MAGIC) + 1];
+ tokstart < header_end; tokstart++) {
+ if (*tokstart == 0x20)
+ continue;
switch (*tokstart++) {
case 'W': // Width. Required.
- width = strtol(tokstart, &tokend, 10);
- tokstart=tokend;
+ width = strtol(tokstart, &tokend, 10);
+ tokstart = tokend;
break;
case 'H': // Height. Required.
- height = strtol(tokstart, &tokend, 10);
- tokstart=tokend;
+ height = strtol(tokstart, &tokend, 10);
+ tokstart = tokend;
break;
case 'C': // Color space
- if (strncmp("420jpeg",tokstart,7)==0) {
+ if (strncmp("420jpeg", tokstart, 7) == 0) {
pix_fmt = PIX_FMT_YUV420P;
chroma_sample_location = AVCHROMA_LOC_CENTER;
- } else if (strncmp("420mpeg2",tokstart,8)==0) {
+ } else if (strncmp("420mpeg2", tokstart, 8) == 0) {
pix_fmt = PIX_FMT_YUV420P;
chroma_sample_location = AVCHROMA_LOC_LEFT;
- } else if (strncmp("420paldv", tokstart, 8)==0) {
+ } else if (strncmp("420paldv", tokstart, 8) == 0) {
pix_fmt = PIX_FMT_YUV420P;
chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
- } else if (strncmp("411", tokstart, 3)==0)
+ } else if (strncmp("411", tokstart, 3) == 0)
pix_fmt = PIX_FMT_YUV411P;
- else if (strncmp("422", tokstart, 3)==0)
+ else if (strncmp("422", tokstart, 3) == 0)
pix_fmt = PIX_FMT_YUV422P;
- else if (strncmp("444alpha", tokstart, 8)==0) {
- av_log(s, AV_LOG_ERROR, "Cannot handle 4:4:4:4 YUV4MPEG stream.\n");
+ else if (strncmp("444alpha", tokstart, 8) == 0 ) {
+ av_log(s, AV_LOG_ERROR, "Cannot handle 4:4:4:4 "
+ "YUV4MPEG stream.\n");
return -1;
- } else if (strncmp("444", tokstart, 3)==0)
+ } else if (strncmp("444", tokstart, 3) == 0)
pix_fmt = PIX_FMT_YUV444P;
- else if (strncmp("mono",tokstart, 4)==0) {
+ else if (strncmp("mono", tokstart, 4) == 0) {
pix_fmt = PIX_FMT_GRAY8;
} else {
- av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown pixel format.\n");
+ av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown "
+ "pixel format.\n");
return -1;
}
- while(tokstart<header_end&&*tokstart!=0x20) tokstart++;
+ while (tokstart < header_end && *tokstart != 0x20)
+ tokstart++;
break;
case 'I': // Interlace type
switch (*tokstart++){
case '?':
break;
case 'p':
- s1->interlaced_frame=0;
+ s1->interlaced_frame = 0;
break;
case 't':
- s1->interlaced_frame=1;
- s1->top_field_first=1;
+ s1->interlaced_frame = 1;
+ s1->top_field_first = 1;
break;
case 'b':
- s1->interlaced_frame=1;
- s1->top_field_first=0;
+ s1->interlaced_frame = 1;
+ s1->top_field_first = 0;
break;
case 'm':
- av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed interlaced and non-interlaced frames.\n");
+ av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed "
+ "interlaced and non-interlaced frames.\n");
return -1;
default:
av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
@@ -275,36 +289,39 @@ static int yuv4_read_header(AVFormatContext *s, AVFormatParameters *ap)
}
break;
case 'F': // Frame rate
- sscanf(tokstart,"%d:%d",&raten,&rated); // 0:0 if unknown
- while(tokstart<header_end&&*tokstart!=0x20) tokstart++;
+ sscanf(tokstart, "%d:%d", &raten, &rated); // 0:0 if unknown
+ while (tokstart < header_end && *tokstart != 0x20)
+ tokstart++;
break;
case 'A': // Pixel aspect
- sscanf(tokstart,"%d:%d",&aspectn,&aspectd); // 0:0 if unknown
- while(tokstart<header_end&&*tokstart!=0x20) tokstart++;
+ sscanf(tokstart, "%d:%d", &aspectn, &aspectd); // 0:0 if unknown
+ while (tokstart < header_end && *tokstart != 0x20)
+ tokstart++;
break;
case 'X': // Vendor extensions
- if (strncmp("YSCSS=",tokstart,6)==0) {
+ if (strncmp("YSCSS=", tokstart, 6) == 0) {
// Older nonstandard pixel format representation
- tokstart+=6;
- if (strncmp("420JPEG",tokstart,7)==0)
- alt_pix_fmt=PIX_FMT_YUV420P;
- else if (strncmp("420MPEG2",tokstart,8)==0)
- alt_pix_fmt=PIX_FMT_YUV420P;
- else if (strncmp("420PALDV",tokstart,8)==0)
- alt_pix_fmt=PIX_FMT_YUV420P;
- else if (strncmp("411",tokstart,3)==0)
- alt_pix_fmt=PIX_FMT_YUV411P;
- else if (strncmp("422",tokstart,3)==0)
- alt_pix_fmt=PIX_FMT_YUV422P;
- else if (strncmp("444",tokstart,3)==0)
- alt_pix_fmt=PIX_FMT_YUV444P;
+ tokstart += 6;
+ if (strncmp("420JPEG", tokstart, 7) == 0)
+ alt_pix_fmt = PIX_FMT_YUV420P;
+ else if (strncmp("420MPEG2", tokstart, 8) == 0)
+ alt_pix_fmt = PIX_FMT_YUV420P;
+ else if (strncmp("420PALDV", tokstart, 8) == 0)
+ alt_pix_fmt = PIX_FMT_YUV420P;
+ else if (strncmp("411", tokstart, 3) == 0)
+ alt_pix_fmt = PIX_FMT_YUV411P;
+ else if (strncmp("422", tokstart, 3) == 0)
+ alt_pix_fmt = PIX_FMT_YUV422P;
+ else if (strncmp("444", tokstart, 3) == 0)
+ alt_pix_fmt = PIX_FMT_YUV444P;
}
- while(tokstart<header_end&&*tokstart!=0x20) tokstart++;
+ while (tokstart < header_end && *tokstart != 0x20)
+ tokstart++;
break;
}
}
- if ((width == -1) || (height == -1)) {
+ if (width == -1 || height == -1) {
av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
return -1;
}
@@ -327,17 +344,17 @@ static int yuv4_read_header(AVFormatContext *s, AVFormatParameters *ap)
aspectd = 1;
}
- st = av_new_stream(s, 0);
- if(!st)
+ st = avformat_new_stream(s, NULL);
+ if (!st)
return AVERROR(ENOMEM);
- st->codec->width = width;
+ st->codec->width = width;
st->codec->height = height;
- av_reduce(&raten, &rated, raten, rated, (1UL<<31)-1);
- av_set_pts_info(st, 64, rated, raten);
- st->codec->pix_fmt = pix_fmt;
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = CODEC_ID_RAWVIDEO;
- st->sample_aspect_ratio= (AVRational){aspectn, aspectd};
+ av_reduce(&raten, &rated, raten, rated, (1UL << 31) - 1);
+ avpriv_set_pts_info(st, 64, rated, raten);
+ st->codec->pix_fmt = pix_fmt;
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = CODEC_ID_RAWVIDEO;
+ st->sample_aspect_ratio = (AVRational){ aspectn, aspectd };
st->codec->chroma_sample_location = chroma_sample_location;
return 0;
@@ -351,17 +368,19 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
AVStream *st = s->streams[0];
struct frame_attributes *s1 = s->priv_data;
- for (i=0; i<MAX_FRAME_HEADER; i++) {
+ for (i = 0; i < MAX_FRAME_HEADER; i++) {
header[i] = avio_r8(s->pb);
if (header[i] == '\n') {
- header[i+1] = 0;
+ header[i + 1] = 0;
break;
}
}
- if (i == MAX_FRAME_HEADER) return -1;
- if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC))) return -1;
+ if (i == MAX_FRAME_HEADER)
+ return -1;
+ if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC)))
+ return -1;
- width = st->codec->width;
+ width = st->codec->width;
height = st->codec->height;
packet_size = avpicture_get_size(st->codec->pix_fmt, width, height);
@@ -371,9 +390,9 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
if (av_get_packet(s->pb, pkt, packet_size) != packet_size)
return AVERROR(EIO);
- if (s->streams[0]->codec->coded_frame) {
- s->streams[0]->codec->coded_frame->interlaced_frame = s1->interlaced_frame;
- s->streams[0]->codec->coded_frame->top_field_first = s1->top_field_first;
+ if (st->codec->coded_frame) {
+ st->codec->coded_frame->interlaced_frame = s1->interlaced_frame;
+ st->codec->coded_frame->top_field_first = s1->top_field_first;
}
pkt->stream_index = 0;
@@ -383,7 +402,7 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
static int yuv4_probe(AVProbeData *pd)
{
/* check file header */
- if (strncmp(pd->buf, Y4M_MAGIC, sizeof(Y4M_MAGIC)-1)==0)
+ if (strncmp(pd->buf, Y4M_MAGIC, sizeof(Y4M_MAGIC) - 1) == 0)
return AVPROBE_SCORE_MAX;
else
return 0;
@@ -391,12 +410,12 @@ static int yuv4_probe(AVProbeData *pd)
#if CONFIG_YUV4MPEGPIPE_DEMUXER
AVInputFormat ff_yuv4mpegpipe_demuxer = {
- "yuv4mpegpipe",
- NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"),
- sizeof(struct frame_attributes),
- yuv4_probe,
- yuv4_read_header,
- yuv4_read_packet,
- .extensions = "y4m"
+ .name = "yuv4mpegpipe",
+ .long_name = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"),
+ .priv_data_size = sizeof(struct frame_attributes),
+ .read_probe = yuv4_probe,
+ .read_header = yuv4_read_header,
+ .read_packet = yuv4_read_packet,
+ .extensions = "y4m"
};
#endif
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 0d8f01d..6896846 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -1,5 +1,3 @@
-include $(SUBDIR)../config.mak
-
NAME = avutil
HEADERS = adler32.h \
@@ -77,13 +75,12 @@ OBJS-$(ARCH_ARM) += arm/cpu.o
OBJS-$(ARCH_PPC) += ppc/cpu.o
OBJS-$(ARCH_X86) += x86/cpu.o
-TESTPROGS = adler32 aes base64 cpu crc des eval lls md5 pca sha tree
+TESTPROGS = adler32 aes avstring base64 cpu crc des eval file fifo lfg lls \
+ md5 opt parseutils rational sha tree
TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo
DIRS = arm bfin sh4 x86
ARCH_HEADERS = bswap.h intmath.h intreadwrite.h timer.h
-include $(SUBDIR)../subdir.mak
-
$(SUBDIR)lzo-test$(EXESUF): ELIBS = -llzo2
diff --git a/libavutil/adler32.c b/libavutil/adler32.c
index 4f20010..7f5afdb 100644
--- a/libavutil/adler32.c
+++ b/libavutil/adler32.c
@@ -26,24 +26,28 @@
#define BASE 65521L /* largest prime smaller than 65536 */
-#define DO1(buf) {s1 += *buf++; s2 += s1;}
+#define DO1(buf) { s1 += *buf++; s2 += s1; }
#define DO4(buf) DO1(buf); DO1(buf); DO1(buf); DO1(buf);
#define DO16(buf) DO4(buf); DO4(buf); DO4(buf); DO4(buf);
-unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, unsigned int len)
+unsigned long av_adler32_update(unsigned long adler, const uint8_t * buf,
+ unsigned int len)
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = adler >> 16;
- while (len>0) {
+ while (len > 0) {
#if CONFIG_SMALL
- while(len>4 && s2 < (1U<<31)){
- DO4(buf); len-=4;
+ while (len > 4 && s2 < (1U << 31)) {
+ DO4(buf);
+ len -= 4;
+ }
#else
- while(len>16 && s2 < (1U<<31)){
- DO16(buf); len-=16;
-#endif
+ while (len > 16 && s2 < (1U << 31)) {
+ DO16(buf);
+ len -= 16;
}
+#endif
DO1(buf); len--;
s1 %= BASE;
s2 %= BASE;
@@ -52,22 +56,34 @@ unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, unsigne
}
#ifdef TEST
+#include <string.h>
#include "log.h"
#include "timer.h"
#define LEN 7001
-volatile int checksum;
-int main(void){
+
+static volatile int checksum;
+
+int main(int argc, char **argv)
+{
int i;
char data[LEN];
+
av_log_set_level(AV_LOG_DEBUG);
- for(i=0; i<LEN; i++)
- data[i]= ((i*i)>>3) + 123*i;
- for(i=0; i<1000; i++){
- START_TIMER
- checksum= av_adler32_update(1, data, LEN);
- STOP_TIMER("adler")
+
+ for (i = 0; i < LEN; i++)
+ data[i] = ((i * i) >> 3) + 123 * i;
+
+ if (argc > 1 && !strcmp(argv[1], "-t")) {
+ for (i = 0; i < 1000; i++) {
+ START_TIMER;
+ checksum = av_adler32_update(1, data, LEN);
+ STOP_TIMER("adler");
+ }
+ } else {
+ checksum = av_adler32_update(1, data, LEN);
}
- av_log(NULL, AV_LOG_DEBUG, "%X == 50E6E508\n", checksum);
- return 0;
+
+ av_log(NULL, AV_LOG_DEBUG, "%X (expected 50E6E508)\n", checksum);
+ return checksum == 0x50e6e508 ? 0 : 1;
}
#endif
diff --git a/libavutil/adler32.h b/libavutil/adler32.h
index 913db2d..a8ff6f9 100644
--- a/libavutil/adler32.h
+++ b/libavutil/adler32.h
@@ -25,6 +25,7 @@
#include "attributes.h"
/**
+ * @ingroup lavu_crypto
* Calculate the Adler32 checksum of a buffer.
*
* Passing the return value to a subsequent av_adler32_update() call
diff --git a/libavutil/aes.c b/libavutil/aes.c
index 346676b..6803c71 100644
--- a/libavutil/aes.c
+++ b/libavutil/aes.c
@@ -22,6 +22,7 @@
#include "common.h"
#include "aes.h"
+#include "intreadwrite.h"
typedef union {
uint64_t u64[2];
@@ -30,13 +31,13 @@ typedef union {
uint8_t u8[16];
} av_aes_block;
-typedef struct AVAES{
+typedef struct AVAES {
// Note: round_key[16] is accessed in the init code, but this only
- // overwrites state, which does not matter (see also r7471).
+ // overwrites state, which does not matter (see also commit ba554c0).
av_aes_block round_key[15];
av_aes_block state[2];
int rounds;
-}AVAES;
+} AVAES;
const int av_aes_size= sizeof(AVAES);
@@ -54,23 +55,58 @@ static uint32_t enc_multbl[4][256];
static uint32_t dec_multbl[4][256];
#endif
-static inline void addkey(av_aes_block *dst, const av_aes_block *src, const av_aes_block *round_key){
+#if HAVE_BIGENDIAN
+# define ROT(x, s) ((x >> s) | (x << (32-s)))
+#else
+# define ROT(x, s) ((x << s) | (x >> (32-s)))
+#endif
+
+static inline void addkey(av_aes_block *dst, const av_aes_block *src,
+ const av_aes_block *round_key)
+{
dst->u64[0] = src->u64[0] ^ round_key->u64[0];
dst->u64[1] = src->u64[1] ^ round_key->u64[1];
}
-static void subshift(av_aes_block s0[2], int s, const uint8_t *box){
- av_aes_block *s1= (av_aes_block *)(s0[0].u8 - s);
- av_aes_block *s3= (av_aes_block *)(s0[0].u8 + s);
- s0[0].u8[0]=box[s0[1].u8[ 0]]; s0[0].u8[ 4]=box[s0[1].u8[ 4]]; s0[0].u8[ 8]=box[s0[1].u8[ 8]]; s0[0].u8[12]=box[s0[1].u8[12]];
- s1[0].u8[3]=box[s1[1].u8[ 7]]; s1[0].u8[ 7]=box[s1[1].u8[11]]; s1[0].u8[11]=box[s1[1].u8[15]]; s1[0].u8[15]=box[s1[1].u8[ 3]];
- s0[0].u8[2]=box[s0[1].u8[10]]; s0[0].u8[10]=box[s0[1].u8[ 2]]; s0[0].u8[ 6]=box[s0[1].u8[14]]; s0[0].u8[14]=box[s0[1].u8[ 6]];
- s3[0].u8[1]=box[s3[1].u8[13]]; s3[0].u8[13]=box[s3[1].u8[ 9]]; s3[0].u8[ 9]=box[s3[1].u8[ 5]]; s3[0].u8[ 5]=box[s3[1].u8[ 1]];
+static inline void addkey_s(av_aes_block *dst, const uint8_t *src,
+ const av_aes_block *round_key)
+{
+ dst->u64[0] = AV_RN64(src) ^ round_key->u64[0];
+ dst->u64[1] = AV_RN64(src + 8) ^ round_key->u64[1];
+}
+
+static inline void addkey_d(uint8_t *dst, const av_aes_block *src,
+ const av_aes_block *round_key)
+{
+ AV_WN64(dst, src->u64[0] ^ round_key->u64[0]);
+ AV_WN64(dst + 8, src->u64[1] ^ round_key->u64[1]);
+}
+
+static void subshift(av_aes_block s0[2], int s, const uint8_t *box)
+{
+ av_aes_block *s1 = (av_aes_block *) (s0[0].u8 - s);
+ av_aes_block *s3 = (av_aes_block *) (s0[0].u8 + s);
+
+ s0[0].u8[ 0] = box[s0[1].u8[ 0]];
+ s0[0].u8[ 4] = box[s0[1].u8[ 4]];
+ s0[0].u8[ 8] = box[s0[1].u8[ 8]];
+ s0[0].u8[12] = box[s0[1].u8[12]];
+ s1[0].u8[ 3] = box[s1[1].u8[ 7]];
+ s1[0].u8[ 7] = box[s1[1].u8[11]];
+ s1[0].u8[11] = box[s1[1].u8[15]];
+ s1[0].u8[15] = box[s1[1].u8[ 3]];
+ s0[0].u8[ 2] = box[s0[1].u8[10]];
+ s0[0].u8[10] = box[s0[1].u8[ 2]];
+ s0[0].u8[ 6] = box[s0[1].u8[14]];
+ s0[0].u8[14] = box[s0[1].u8[ 6]];
+ s3[0].u8[ 1] = box[s3[1].u8[13]];
+ s3[0].u8[13] = box[s3[1].u8[ 9]];
+ s3[0].u8[ 9] = box[s3[1].u8[ 5]];
+ s3[0].u8[ 5] = box[s3[1].u8[ 1]];
}
static inline int mix_core(uint32_t multbl[][256], int a, int b, int c, int d){
#if CONFIG_SMALL
-#define ROT(x,s) ((x<<s)|(x>>(32-s)))
return multbl[0][a] ^ ROT(multbl[0][b], 8) ^ ROT(multbl[0][c], 16) ^ ROT(multbl[0][d], 24);
#else
return multbl[0][a] ^ multbl[1][b] ^ multbl[2][c] ^ multbl[3][d];
@@ -85,117 +121,137 @@ static inline void mix(av_aes_block state[2], uint32_t multbl[][256], int s1, in
state[0].u32[3] = mix_core(multbl, src[3][0], src[s1-1][1], src[1][2], src[s3-1][3]);
}
-static inline void crypt(AVAES *a, int s, const uint8_t *sbox, uint32_t multbl[][256]){
+static inline void crypt(AVAES *a, int s, const uint8_t *sbox,
+ uint32_t multbl[][256])
+{
int r;
- for(r=a->rounds-1; r>0; r--){
- mix(a->state, multbl, 3-s, 1+s);
+ for (r = a->rounds - 1; r > 0; r--) {
+ mix(a->state, multbl, 3 - s, 1 + s);
addkey(&a->state[1], &a->state[0], &a->round_key[r]);
}
+
subshift(&a->state[0], s, sbox);
}
-void av_aes_crypt(AVAES *a, uint8_t *dst_, const uint8_t *src_, int count, uint8_t *iv_, int decrypt){
- av_aes_block *dst = (av_aes_block *)dst_;
- const av_aes_block *src = (const av_aes_block *)src_;
- av_aes_block *iv = (av_aes_block *)iv_;
- while(count--){
- addkey(&a->state[1], src, &a->round_key[a->rounds]);
- if(decrypt) {
+void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src,
+ int count, uint8_t *iv, int decrypt)
+{
+ while (count--) {
+ addkey_s(&a->state[1], src, &a->round_key[a->rounds]);
+ if (decrypt) {
crypt(a, 0, inv_sbox, dec_multbl);
- if(iv){
- addkey(&a->state[0], &a->state[0], iv);
+ if (iv) {
+ addkey_s(&a->state[0], iv, &a->state[0]);
memcpy(iv, src, 16);
}
- addkey(dst, &a->state[0], &a->round_key[0]);
- }else{
- if(iv) addkey(&a->state[1], &a->state[1], iv);
- crypt(a, 2, sbox, enc_multbl);
- addkey(dst, &a->state[0], &a->round_key[0]);
- if(iv) memcpy(iv, dst, 16);
+ addkey_d(dst, &a->state[0], &a->round_key[0]);
+ } else {
+ if (iv)
+ addkey_s(&a->state[1], iv, &a->state[1]);
+ crypt(a, 2, sbox, enc_multbl);
+ addkey_d(dst, &a->state[0], &a->round_key[0]);
+ if (iv)
+ memcpy(iv, dst, 16);
}
- src++;
- dst++;
+ src += 16;
+ dst += 16;
}
}
-static void init_multbl2(uint8_t tbl[1024], const int c[4], const uint8_t *log8, const uint8_t *alog8, const uint8_t *sbox){
- int i, j;
- for(i=0; i<1024; i++){
- int x= sbox[i>>2];
- if(x) tbl[i]= alog8[ log8[x] + log8[c[i&3]] ];
- }
+static void init_multbl2(uint32_t tbl[][256], const int c[4],
+ const uint8_t *log8, const uint8_t *alog8,
+ const uint8_t *sbox)
+{
+ int i;
+
+ for (i = 0; i < 256; i++) {
+ int x = sbox[i];
+ if (x) {
+ int k, l, m, n;
+ x = log8[x];
+ k = alog8[x + log8[c[0]]];
+ l = alog8[x + log8[c[1]]];
+ m = alog8[x + log8[c[2]]];
+ n = alog8[x + log8[c[3]]];
+ tbl[0][i] = AV_NE(MKBETAG(k,l,m,n), MKTAG(k,l,m,n));
#if !CONFIG_SMALL
- for(j=256; j<1024; j++)
- for(i=0; i<4; i++)
- tbl[4*j+i]= tbl[4*j + ((i-1)&3) - 1024];
+ tbl[1][i] = ROT(tbl[0][i], 8);
+ tbl[2][i] = ROT(tbl[0][i], 16);
+ tbl[3][i] = ROT(tbl[0][i], 24);
#endif
+ }
+ }
}
// this is based on the reference AES code by Paulo Barreto and Vincent Rijmen
-int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) {
+int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
+{
int i, j, t, rconpointer = 0;
uint8_t tk[8][4];
- int KC= key_bits>>5;
- int rounds= KC + 6;
- uint8_t log8[256];
+ int KC = key_bits >> 5;
+ int rounds = KC + 6;
+ uint8_t log8[256];
uint8_t alog8[512];
- if(!enc_multbl[FF_ARRAY_ELEMS(enc_multbl)-1][FF_ARRAY_ELEMS(enc_multbl[0])-1]){
- j=1;
- for(i=0; i<255; i++){
- alog8[i]=
- alog8[i+255]= j;
- log8[j]= i;
- j^= j+j;
- if(j>255) j^= 0x11B;
+ if (!enc_multbl[FF_ARRAY_ELEMS(enc_multbl)-1][FF_ARRAY_ELEMS(enc_multbl[0])-1]) {
+ j = 1;
+ for (i = 0; i < 255; i++) {
+ alog8[i] = alog8[i + 255] = j;
+ log8[j] = i;
+ j ^= j + j;
+ if (j > 255)
+ j ^= 0x11B;
}
- for(i=0; i<256; i++){
- j= i ? alog8[255-log8[i]] : 0;
- j ^= (j<<1) ^ (j<<2) ^ (j<<3) ^ (j<<4);
- j = (j ^ (j>>8) ^ 99) & 255;
- inv_sbox[j]= i;
- sbox [i]= j;
+ for (i = 0; i < 256; i++) {
+ j = i ? alog8[255 - log8[i]] : 0;
+ j ^= (j << 1) ^ (j << 2) ^ (j << 3) ^ (j << 4);
+ j = (j ^ (j >> 8) ^ 99) & 255;
+ inv_sbox[j] = i;
+ sbox[i] = j;
}
- init_multbl2(dec_multbl[0], (const int[4]){0xe, 0x9, 0xd, 0xb}, log8, alog8, inv_sbox);
- init_multbl2(enc_multbl[0], (const int[4]){0x2, 0x1, 0x1, 0x3}, log8, alog8, sbox);
+ init_multbl2(dec_multbl, (const int[4]) { 0xe, 0x9, 0xd, 0xb },
+ log8, alog8, inv_sbox);
+ init_multbl2(enc_multbl, (const int[4]) { 0x2, 0x1, 0x1, 0x3 },
+ log8, alog8, sbox);
}
- if(key_bits!=128 && key_bits!=192 && key_bits!=256)
+ if (key_bits != 128 && key_bits != 192 && key_bits != 256)
return -1;
- a->rounds= rounds;
-
- memcpy(tk, key, KC*4);
+ a->rounds = rounds;
- for(t= 0; t < (rounds+1)*16;) {
- memcpy(a->round_key[0].u8+t, tk, KC*4);
- t+= KC*4;
+ memcpy(tk, key, KC * 4);
+ memcpy(a->round_key[0].u8, key, KC * 4);
- for(i = 0; i < 4; i++)
- tk[0][i] ^= sbox[tk[KC-1][(i+1)&3]];
+ for (t = KC * 4; t < (rounds + 1) * 16; t += KC * 4) {
+ for (i = 0; i < 4; i++)
+ tk[0][i] ^= sbox[tk[KC - 1][(i + 1) & 3]];
tk[0][0] ^= rcon[rconpointer++];
- for(j = 1; j < KC; j++){
- if(KC != 8 || j != KC>>1)
- for(i = 0; i < 4; i++) tk[j][i] ^= tk[j-1][i];
+ for (j = 1; j < KC; j++) {
+ if (KC != 8 || j != KC >> 1)
+ for (i = 0; i < 4; i++)
+ tk[j][i] ^= tk[j - 1][i];
else
- for(i = 0; i < 4; i++) tk[j][i] ^= sbox[tk[j-1][i]];
+ for (i = 0; i < 4; i++)
+ tk[j][i] ^= sbox[tk[j - 1][i]];
}
+
+ memcpy(a->round_key[0].u8 + t, tk, KC * 4);
}
- if(decrypt){
- for(i=1; i<rounds; i++){
+ if (decrypt) {
+ for (i = 1; i < rounds; i++) {
av_aes_block tmp[3];
- memcpy(&tmp[2], &a->round_key[i], 16);
+ tmp[2] = a->round_key[i];
subshift(&tmp[1], 0, sbox);
mix(tmp, dec_multbl, 1, 3);
- memcpy(&a->round_key[i], &tmp[0], 16);
+ a->round_key[i] = tmp[0];
}
- }else{
- for(i=0; i<(rounds+1)>>1; i++){
- for(j=0; j<16; j++)
- FFSWAP(int, a->round_key[i].u8[j], a->round_key[rounds-i].u8[j]);
+ } else {
+ for (i = 0; i < (rounds + 1) >> 1; i++) {
+ FFSWAP(av_aes_block, a->round_key[i], a->round_key[rounds-i]);
}
}
@@ -203,53 +259,76 @@ int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) {
}
#ifdef TEST
+#include <string.h>
#include "lfg.h"
#include "log.h"
-int main(void){
- int i,j;
- AVAES ae, ad, b;
- uint8_t rkey[2][16]= {
- {0},
- {0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3, 0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59}};
+int main(int argc, char **argv)
+{
+ int i, j;
+ AVAES b;
+ uint8_t rkey[2][16] = {
+ { 0 },
+ { 0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3,
+ 0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59 }
+ };
uint8_t pt[16], rpt[2][16]= {
- {0x6a, 0x84, 0x86, 0x7c, 0xd7, 0x7e, 0x12, 0xad, 0x07, 0xea, 0x1b, 0xe8, 0x95, 0xc5, 0x3f, 0xa3},
- {0}};
+ { 0x6a, 0x84, 0x86, 0x7c, 0xd7, 0x7e, 0x12, 0xad,
+ 0x07, 0xea, 0x1b, 0xe8, 0x95, 0xc5, 0x3f, 0xa3 },
+ { 0 }
+ };
uint8_t rct[2][16]= {
- {0x73, 0x22, 0x81, 0xc0, 0xa0, 0xaa, 0xb8, 0xf7, 0xa5, 0x4a, 0x0c, 0x67, 0xa0, 0xc4, 0x5e, 0xcf},
- {0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0, 0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65}};
+ { 0x73, 0x22, 0x81, 0xc0, 0xa0, 0xaa, 0xb8, 0xf7,
+ 0xa5, 0x4a, 0x0c, 0x67, 0xa0, 0xc4, 0x5e, 0xcf },
+ { 0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0,
+ 0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65 }
+ };
uint8_t temp[16];
- AVLFG prng;
+ int err = 0;
- av_aes_init(&ae, "PI=3.141592654..", 128, 0);
- av_aes_init(&ad, "PI=3.141592654..", 128, 1);
av_log_set_level(AV_LOG_DEBUG);
- av_lfg_init(&prng, 1);
- for(i=0; i<2; i++){
+ for (i = 0; i < 2; i++) {
av_aes_init(&b, rkey[i], 128, 1);
av_aes_crypt(&b, temp, rct[i], 1, NULL, 1);
- for(j=0; j<16; j++)
- if(rpt[i][j] != temp[j])
- av_log(NULL, AV_LOG_ERROR, "%d %02X %02X\n", j, rpt[i][j], temp[j]);
+ for (j = 0; j < 16; j++) {
+ if (rpt[i][j] != temp[j]) {
+ av_log(NULL, AV_LOG_ERROR, "%d %02X %02X\n",
+ j, rpt[i][j], temp[j]);
+ err = 1;
+ }
+ }
}
- for(i=0; i<10000; i++){
- for(j=0; j<16; j++){
- pt[j] = av_lfg_get(&prng);
- }
-{START_TIMER
- av_aes_crypt(&ae, temp, pt, 1, NULL, 0);
- if(!(i&(i-1)))
- av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n", temp[0], temp[5], temp[10], temp[15]);
- av_aes_crypt(&ad, temp, temp, 1, NULL, 1);
-STOP_TIMER("aes")}
- for(j=0; j<16; j++){
- if(pt[j] != temp[j]){
- av_log(NULL, AV_LOG_ERROR, "%d %d %02X %02X\n", i,j, pt[j], temp[j]);
+ if (argc > 1 && !strcmp(argv[1], "-t")) {
+ AVAES ae, ad;
+ AVLFG prng;
+
+ av_aes_init(&ae, "PI=3.141592654..", 128, 0);
+ av_aes_init(&ad, "PI=3.141592654..", 128, 1);
+ av_lfg_init(&prng, 1);
+
+ for (i = 0; i < 10000; i++) {
+ for (j = 0; j < 16; j++) {
+ pt[j] = av_lfg_get(&prng);
+ }
+ {
+ START_TIMER;
+ av_aes_crypt(&ae, temp, pt, 1, NULL, 0);
+ if (!(i & (i - 1)))
+ av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n",
+ temp[0], temp[5], temp[10], temp[15]);
+ av_aes_crypt(&ad, temp, temp, 1, NULL, 1);
+ STOP_TIMER("aes");
+ }
+ for (j = 0; j < 16; j++) {
+ if (pt[j] != temp[j]) {
+ av_log(NULL, AV_LOG_ERROR, "%d %d %02X %02X\n",
+ i, j, pt[j], temp[j]);
+ }
}
}
}
- return 0;
+ return err;
}
#endif
diff --git a/libavutil/aes.h b/libavutil/aes.h
index 6e5d320..cf7b462 100644
--- a/libavutil/aes.h
+++ b/libavutil/aes.h
@@ -23,6 +23,12 @@
#include <stdint.h>
+/**
+ * @defgroup lavu_aes AES
+ * @ingroup lavu_crypto
+ * @{
+ */
+
extern const int av_aes_size;
struct AVAES;
@@ -44,4 +50,8 @@ int av_aes_init(struct AVAES *a, const uint8_t *key, int key_bits, int decrypt);
*/
void av_aes_crypt(struct AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt);
+/**
+ * @}
+ */
+
#endif /* AVUTIL_AES_H */
diff --git a/libavutil/arm/bswap.h b/libavutil/arm/bswap.h
index 478ae98..f94cbcf 100644
--- a/libavutil/arm/bswap.h
+++ b/libavutil/arm/bswap.h
@@ -51,6 +51,7 @@ static av_always_inline av_const unsigned av_bswap16(unsigned x)
}
#endif
+#if !AV_GCC_VERSION_AT_LEAST(4,5)
#define av_bswap32 av_bswap32
static av_always_inline av_const uint32_t av_bswap32(uint32_t x)
{
@@ -66,6 +67,7 @@ static av_always_inline av_const uint32_t av_bswap32(uint32_t x)
#endif /* HAVE_ARMV6 */
return x;
}
+#endif /* !AV_GCC_VERSION_AT_LEAST(4,5) */
#endif /* __ARMCC_VERSION */
diff --git a/libavutil/arm/intmath.h b/libavutil/arm/intmath.h
index 4340b59..b6a45c1 100644
--- a/libavutil/arm/intmath.h
+++ b/libavutil/arm/intmath.h
@@ -36,6 +36,7 @@ static av_always_inline av_const int FASTDIV(int a, int b)
int r;
__asm__ ("cmp %2, #2 \n\t"
"ldr %0, [%3, %2, lsl #2] \n\t"
+ "ite le \n\t"
"lsrle %0, %1, #1 \n\t"
"smmulgt %0, %0, %1 \n\t"
: "=&r"(r) : "r"(a), "r"(b), "r"(ff_inverse) : "cc");
@@ -101,6 +102,7 @@ static av_always_inline av_const int32_t av_clipl_int32_arm(int64_t a)
{
int x, y;
__asm__ ("adds %1, %R2, %Q2, lsr #31 \n\t"
+ "itet ne \n\t"
"mvnne %1, #1<<31 \n\t"
"moveq %0, %Q2 \n\t"
"eorne %0, %1, %R2, asr #31 \n\t"
diff --git a/libavutil/attributes.h b/libavutil/attributes.h
index 4abe78f..ef990a1 100644
--- a/libavutil/attributes.h
+++ b/libavutil/attributes.h
@@ -127,8 +127,10 @@
#ifdef __GNUC__
# define av_builtin_constant_p __builtin_constant_p
+# define av_printf_format(fmtpos, attrpos) __attribute__((__format__(__printf__, fmtpos, attrpos)))
#else
# define av_builtin_constant_p(x) 0
+# define av_printf_format(fmtpos, attrpos)
#endif
#endif /* AVUTIL_ATTRIBUTES_H */
diff --git a/libavutil/audioconvert.c b/libavutil/audioconvert.c
index fa27f01..e9f9e41 100644
--- a/libavutil/audioconvert.c
+++ b/libavutil/audioconvert.c
@@ -28,11 +28,26 @@
#include "audioconvert.h"
static const char * const channel_names[] = {
- "FL", "FR", "FC", "LFE", "BL", "BR", "FLC", "FRC",
- "BC", "SL", "SR", "TC", "TFL", "TFC", "TFR", "TBL",
- "TBC", "TBR",
- [29] = "DL",
- [30] = "DR",
+ [0] = "FL", /* front left */
+ [1] = "FR", /* front right */
+ [2] = "FC", /* front center */
+ [3] = "LFE", /* low frequency */
+ [4] = "BL", /* back left */
+ [5] = "BR", /* back right */
+ [6] = "FLC", /* front left-of-center */
+ [7] = "FRC", /* front right-of-center */
+ [8] = "BC", /* back-center */
+ [9] = "SL", /* side left */
+ [10] = "SR", /* side right */
+ [11] = "TC", /* top center */
+ [12] = "TFL", /* top front left */
+ [13] = "TFC", /* top front center */
+ [14] = "TFR", /* top front right */
+ [15] = "TBL", /* top back left */
+ [16] = "TBC", /* top back center */
+ [17] = "TBR", /* top back right */
+ [29] = "DL", /* downmix left */
+ [30] = "DR", /* downmix right */
};
static const char *get_channel_name(int channel_id)
@@ -45,7 +60,7 @@ static const char *get_channel_name(int channel_id)
static const struct {
const char *name;
int nb_channels;
- int64_t layout;
+ uint64_t layout;
} channel_layout_map[] = {
{ "mono", 1, AV_CH_LAYOUT_MONO },
{ "stereo", 2, AV_CH_LAYOUT_STEREO },
@@ -62,7 +77,7 @@ static const struct {
{ 0 }
};
-int64_t av_get_channel_layout(const char *name)
+uint64_t av_get_channel_layout(const char *name)
{
int i = 0;
do {
@@ -75,7 +90,7 @@ int64_t av_get_channel_layout(const char *name)
}
void av_get_channel_layout_string(char *buf, int buf_size,
- int nb_channels, int64_t channel_layout)
+ int nb_channels, uint64_t channel_layout)
{
int i;
@@ -91,13 +106,14 @@ void av_get_channel_layout_string(char *buf, int buf_size,
snprintf(buf, buf_size, "%d channels", nb_channels);
if (channel_layout) {
- int i,ch;
+ int i, ch;
av_strlcat(buf, " (", buf_size);
- for(i=0,ch=0; i<64; i++) {
- if ((channel_layout & (1L<<i))) {
+ for (i = 0, ch = 0; i < 64; i++) {
+ if ((channel_layout & (UINT64_C(1) << i))) {
const char *name = get_channel_name(i);
if (name) {
- if (ch>0) av_strlcat(buf, "|", buf_size);
+ if (ch > 0)
+ av_strlcat(buf, "|", buf_size);
av_strlcat(buf, name, buf_size);
}
ch++;
@@ -107,7 +123,7 @@ void av_get_channel_layout_string(char *buf, int buf_size,
}
}
-int av_get_channel_layout_nb_channels(int64_t channel_layout)
+int av_get_channel_layout_nb_channels(uint64_t channel_layout)
{
int count;
uint64_t x = channel_layout;
diff --git a/libavutil/audioconvert.h b/libavutil/audioconvert.h
index e37a2e8..00ed0ff 100644
--- a/libavutil/audioconvert.h
+++ b/libavutil/audioconvert.h
@@ -29,7 +29,15 @@
* audio conversion routines
*/
-/* Audio channel masks */
+/**
+ * @addtogroup lavu_audio
+ * @{
+ */
+
+/**
+ * @defgroup channel_masks Audio channel masks
+ * @{
+ */
#define AV_CH_FRONT_LEFT 0x00000001
#define AV_CH_FRONT_RIGHT 0x00000002
#define AV_CH_FRONT_CENTER 0x00000004
@@ -50,33 +58,56 @@
#define AV_CH_TOP_BACK_RIGHT 0x00020000
#define AV_CH_STEREO_LEFT 0x20000000 ///< Stereo downmix.
#define AV_CH_STEREO_RIGHT 0x40000000 ///< See AV_CH_STEREO_LEFT.
+#define AV_CH_WIDE_LEFT 0x0000000080000000ULL
+#define AV_CH_WIDE_RIGHT 0x0000000100000000ULL
+#define AV_CH_SURROUND_DIRECT_LEFT 0x0000000200000000ULL
+#define AV_CH_SURROUND_DIRECT_RIGHT 0x0000000400000000ULL
/** Channel mask value used for AVCodecContext.request_channel_layout
to indicate that the user requests the channel order of the decoder output
to be the native codec channel order. */
-#define AV_CH_LAYOUT_NATIVE 0x8000000000000000LL
+#define AV_CH_LAYOUT_NATIVE 0x8000000000000000ULL
-/* Audio channel convenience macros */
+/**
+ * @}
+ * @defgroup channel_mask_c Audio channel convenience macros
+ * @{
+ * */
#define AV_CH_LAYOUT_MONO (AV_CH_FRONT_CENTER)
#define AV_CH_LAYOUT_STEREO (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)
+#define AV_CH_LAYOUT_2POINT1 (AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY)
#define AV_CH_LAYOUT_2_1 (AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER)
#define AV_CH_LAYOUT_SURROUND (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER)
+#define AV_CH_LAYOUT_3POINT1 (AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY)
#define AV_CH_LAYOUT_4POINT0 (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_4POINT1 (AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY)
#define AV_CH_LAYOUT_2_2 (AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT)
#define AV_CH_LAYOUT_QUAD (AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
#define AV_CH_LAYOUT_5POINT0 (AV_CH_LAYOUT_SURROUND|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT)
#define AV_CH_LAYOUT_5POINT1 (AV_CH_LAYOUT_5POINT0|AV_CH_LOW_FREQUENCY)
#define AV_CH_LAYOUT_5POINT0_BACK (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
#define AV_CH_LAYOUT_5POINT1_BACK (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY)
+#define AV_CH_LAYOUT_6POINT0 (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_6POINT0_FRONT (AV_CH_LAYOUT_2_2|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
+#define AV_CH_LAYOUT_HEXAGONAL (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_6POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_6POINT1_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER)
+#define AV_CH_LAYOUT_6POINT1_FRONT (AV_CH_LAYOUT_6POINT0_FRONT|AV_CH_LOW_FREQUENCY)
#define AV_CH_LAYOUT_7POINT0 (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
+#define AV_CH_LAYOUT_7POINT0_FRONT (AV_CH_LAYOUT_5POINT0|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
#define AV_CH_LAYOUT_7POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
-#define AV_CH_LAYOUT_7POINT1_WIDE (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
+#define AV_CH_LAYOUT_7POINT1_WIDE (AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
+#define AV_CH_LAYOUT_OCTAGONAL (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT)
#define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT)
/**
+ * @}
+ */
+
+/**
* Return a channel layout id that matches name, 0 if no match.
*/
-int64_t av_get_channel_layout(const char *name);
+uint64_t av_get_channel_layout(const char *name);
/**
* Return a description of a channel layout.
@@ -85,11 +116,15 @@ int64_t av_get_channel_layout(const char *name);
* @param buf put here the string containing the channel layout
* @param buf_size size in bytes of the buffer
*/
-void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout);
+void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout);
/**
* Return the number of channels in the channel layout.
*/
-int av_get_channel_layout_nb_channels(int64_t channel_layout);
+int av_get_channel_layout_nb_channels(uint64_t channel_layout);
+
+/**
+ * @}
+ */
#endif /* AVUTIL_AUDIOCONVERT_H */
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index 2b8c2d4..11f3a7c 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -134,6 +134,27 @@ char *av_get_token(const char **buf, const char *term)
return ret;
}
+int av_strcasecmp(const char *a, const char *b)
+{
+ uint8_t c1, c2;
+ do {
+ c1 = av_tolower(*a++);
+ c2 = av_tolower(*b++);
+ } while (c1 && c1 == c2);
+ return c1 - c2;
+}
+
+int av_strncasecmp(const char *a, const char *b, size_t n)
+{
+ const char *end = a + n;
+ uint8_t c1, c2;
+ do {
+ c1 = av_tolower(*a++);
+ c2 = av_tolower(*b++);
+ } while (a < end && c1 && c1 == c2);
+ return c1 - c2;
+}
+
#ifdef TEST
#undef printf
diff --git a/libavutil/avstring.h b/libavutil/avstring.h
index b40acf6..ed4e465 100644
--- a/libavutil/avstring.h
+++ b/libavutil/avstring.h
@@ -22,6 +22,12 @@
#define AVUTIL_AVSTRING_H
#include <stddef.h>
+#include "attributes.h"
+
+/**
+ * @addtogroup lavu_string
+ * @{
+ */
/**
* Return non-zero if pfx is a prefix of str. If it is, *ptr is set to
@@ -71,7 +77,7 @@ char *av_stristr(const char *haystack, const char *needle);
* @param size size of destination buffer
* @return the length of src
*
- * WARNING: since the return value is the length of src, src absolutely
+ * @warning since the return value is the length of src, src absolutely
* _must_ be a properly 0-terminated string, otherwise this will read beyond
* the end of the buffer and possibly crash.
*/
@@ -89,9 +95,9 @@ size_t av_strlcpy(char *dst, const char *src, size_t size);
* @param size size of destination buffer
* @return the total length of src and dst
*
- * WARNING: since the return value use the length of src and dst, these absolutely
- * _must_ be a properly 0-terminated strings, otherwise this will read beyond
- * the end of the buffer and possibly crash.
+ * @warning since the return value use the length of src and dst, these
+ * absolutely _must_ be a properly 0-terminated strings, otherwise this
+ * will read beyond the end of the buffer and possibly crash.
*/
size_t av_strlcat(char *dst, const char *src, size_t size);
@@ -107,7 +113,7 @@ size_t av_strlcat(char *dst, const char *src, size_t size);
* @return the length of the string that would have been generated
* if enough space had been available
*/
-size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...);
+size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) av_printf_format(3, 4);
/**
* Convert a number to a av_malloced string.
@@ -130,4 +136,40 @@ char *av_d2str(double d);
*/
char *av_get_token(const char **buf, const char *term);
+/**
+ * Locale-independent conversion of ASCII characters to uppercase.
+ */
+static inline int av_toupper(int c)
+{
+ if (c >= 'a' && c <= 'z')
+ c ^= 0x20;
+ return c;
+}
+
+/**
+ * Locale-independent conversion of ASCII characters to lowercase.
+ */
+static inline int av_tolower(int c)
+{
+ if (c >= 'A' && c <= 'Z')
+ c ^= 0x20;
+ return c;
+}
+
+/*
+ * Locale-independent case-insensitive compare.
+ * @note This means only ASCII-range characters are case-insensitive
+ */
+int av_strcasecmp(const char *a, const char *b);
+
+/**
+ * Locale-independent case-insensitive compare.
+ * @note This means only ASCII-range characters are case-insensitive
+ */
+int av_strncasecmp(const char *a, const char *b, size_t n);
+
+/**
+ * @}
+ */
+
#endif /* AVUTIL_AVSTRING_H */
diff --git a/libavutil/avutil.h b/libavutil/avutil.h
index 1846146..fa84eff 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
@@ -26,6 +26,96 @@
* external API header
*/
+/**
+ * @mainpage
+ *
+ * @section libav_intro Introduction
+ *
+ * This document describe the usage of the different libraries
+ * provided by Libav.
+ *
+ * @li @ref libavc "libavcodec" encoding/decoding library
+ * @li @subpage libavfilter graph based frame editing library
+ * @li @ref libavf "libavformat" I/O and muxing/demuxing library
+ * @li @ref lavd "libavdevice" special devices muxing/demuxing library
+ * @li @ref lavu "libavutil" common utility library
+ * @li @subpage libpostproc post processing library
+ * @li @subpage libswscale color conversion and scaling library
+ *
+ */
+
+/**
+ * @defgroup lavu Common utility functions
+ *
+ * @brief
+ * libavutil contains the code shared across all the other Libav
+ * libraries
+ *
+ * @note In order to use the functions provided by avutil you must include
+ * the specific header.
+ *
+ * @{
+ *
+ * @defgroup lavu_crypto Crypto and Hashing
+ *
+ * @{
+ * @}
+ *
+ * @defgroup lavu_math Maths
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_string String Manipulation
+ *
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_mem Memory Management
+ *
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_data Data Structures
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_audio Audio related
+ *
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_error Error Codes
+ *
+ * @{
+ *
+ * @}
+ *
+ * @defgroup lavu_misc Other
+ *
+ * @{
+ *
+ * @defgroup lavu_internal Internal
+ *
+ * Not exported functions, for internal usage only
+ *
+ * @{
+ *
+ * @}
+ */
+
+
+/**
+ * @defgroup preproc_misc Preprocessor String Macros
+ *
+ * String manipulation macros
+ *
+ * @{
+ */
#define AV_STRINGIFY(s) AV_TOSTRING(s)
#define AV_TOSTRING(s) #s
@@ -35,12 +125,36 @@
#define AV_PRAGMA(s) _Pragma(#s)
+/**
+ * @}
+ */
+
+/**
+ * @defgroup version_utils Library Version Macros
+ *
+ * Useful to check and match library version in order to maintain
+ * backward compatibility.
+ *
+ * @{
+ */
+
#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c)
#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c
#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)
+/**
+ * @}
+ *
+ * @defgroup lavu_ver Version and Build diagnostics
+ *
+ * Macros and function useful to check at compiletime and at runtime
+ * which version of libavutil is in use.
+ *
+ * @{
+ */
+
#define LIBAVUTIL_VERSION_MAJOR 51
-#define LIBAVUTIL_VERSION_MINOR 7
+#define LIBAVUTIL_VERSION_MINOR 20
#define LIBAVUTIL_VERSION_MICRO 0
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
@@ -54,8 +168,16 @@
#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION)
/**
+ * @}
+ *
+ * @defgroup depr_guards Deprecation guards
* Those FF_API_* defines are not part of public API.
* They may change, break or disappear at any time.
+ *
+ * They are used mostly internally to mark code that will be removed
+ * on the next major version.
+ *
+ * @{
*/
#ifndef FF_API_GET_BITS_PER_SAMPLE_FMT
#define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52)
@@ -63,6 +185,21 @@
#ifndef FF_API_FIND_OPT
#define FF_API_FIND_OPT (LIBAVUTIL_VERSION_MAJOR < 52)
#endif
+#ifndef FF_API_AV_FIFO_PEEK
+#define FF_API_AV_FIFO_PEEK (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+#ifndef FF_API_OLD_AVOPTIONS
+#define FF_API_OLD_AVOPTIONS (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup lavu_ver
+ * @{
+ */
/**
* Return the LIBAVUTIL_VERSION_INT constant.
@@ -79,16 +216,35 @@ const char *avutil_configuration(void);
*/
const char *avutil_license(void);
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup lavu_media Media Type
+ * @brief Media Type
+ */
+
enum AVMediaType {
- AVMEDIA_TYPE_UNKNOWN = -1,
+ AVMEDIA_TYPE_UNKNOWN = -1, ///< Usually treated as AVMEDIA_TYPE_DATA
AVMEDIA_TYPE_VIDEO,
AVMEDIA_TYPE_AUDIO,
- AVMEDIA_TYPE_DATA,
+ AVMEDIA_TYPE_DATA, ///< Opaque data information usually continuous
AVMEDIA_TYPE_SUBTITLE,
- AVMEDIA_TYPE_ATTACHMENT,
+ AVMEDIA_TYPE_ATTACHMENT, ///< Opaque data information usually sparse
AVMEDIA_TYPE_NB
};
+/**
+ * @defgroup lavu_const Constants
+ * @{
+ *
+ * @defgroup lavu_enc Encoding specific
+ *
+ * @note those definition should move to avcodec
+ * @{
+ */
+
#define FF_LAMBDA_SHIFT 7
#define FF_LAMBDA_SCALE (1<<FF_LAMBDA_SHIFT)
#define FF_QP2LAMBDA 118 ///< factor to convert from H.263 QP to lambda
@@ -96,10 +252,46 @@ enum AVMediaType {
#define FF_QUALITY_SCALE FF_LAMBDA_SCALE //FIXME maybe remove
+/**
+ * @}
+ * @defgroup lavu_time Timestamp specific
+ *
+ * Libav internal timebase and timestamp definitions
+ *
+ * @{
+ */
+
+/**
+ * @brief Undefined timestamp value
+ *
+ * Usually reported by demuxer that work on containers that do not provide
+ * either pts or dts.
+ */
+
#define AV_NOPTS_VALUE INT64_C(0x8000000000000000)
+
+/**
+ * Internal time base represented as integer
+ */
+
#define AV_TIME_BASE 1000000
+
+/**
+ * Internal time base represented as fractional value
+ */
+
#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}
+/**
+ * @}
+ * @}
+ * @defgroup lavu_picture Image related
+ *
+ * AVPicture types, pixel formats and basic image planes manipulation.
+ *
+ * @{
+ */
+
enum AVPictureType {
AV_PICTURE_TYPE_I = 1, ///< Intra
AV_PICTURE_TYPE_P, ///< Predicted
@@ -119,12 +311,16 @@ enum AVPictureType {
*/
char av_get_picture_type_char(enum AVPictureType pict_type);
+/**
+ * @}
+ */
+
#include "common.h"
#include "error.h"
-#include "mathematics.h"
-#include "rational.h"
-#include "intfloat_readwrite.h"
-#include "log.h"
-#include "pixfmt.h"
+
+/**
+ * @}
+ * @}
+ */
#endif /* AVUTIL_AVUTIL_H */
diff --git a/libavutil/base64.h b/libavutil/base64.h
index 96c0a4a..4750cf5 100644
--- a/libavutil/base64.h
+++ b/libavutil/base64.h
@@ -24,6 +24,13 @@
#include <stdint.h>
/**
+ * @defgroup lavu_base64 Base64
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+
+/**
* Decode a base64-encoded string.
*
* @param out buffer for decoded data
@@ -51,4 +58,8 @@ char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size);
*/
#define AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1)
+ /**
+ * @}
+ */
+
#endif /* AVUTIL_BASE64_H */
diff --git a/libavutil/bswap.h b/libavutil/bswap.h
index 3657ccd..8a350e1 100644
--- a/libavutil/bswap.h
+++ b/libavutil/bswap.h
@@ -65,23 +65,14 @@ static av_always_inline av_const uint16_t av_bswap16(uint16_t x)
#ifndef av_bswap32
static av_always_inline av_const uint32_t av_bswap32(uint32_t x)
{
- x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF);
- x= (x>>16) | (x<<16);
- return x;
+ return AV_BSWAP32C(x);
}
#endif
#ifndef av_bswap64
static inline uint64_t av_const av_bswap64(uint64_t x)
{
- union {
- uint64_t ll;
- uint32_t l[2];
- } w, r;
- w.ll = x;
- r.l[0] = av_bswap32 (w.l[1]);
- r.l[1] = av_bswap32 (w.l[0]);
- return r.ll;
+ return (uint64_t)av_bswap32(x) << 32 | av_bswap32(x >> 32);
}
#endif
diff --git a/libavutil/common.h b/libavutil/common.h
index a985fa4..7e93a1a 100644
--- a/libavutil/common.h
+++ b/libavutil/common.h
@@ -218,8 +218,8 @@ static av_always_inline av_const int av_popcount_c(uint32_t x)
return (x + (x >> 16)) & 0x3F;
}
-#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
-#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((a) << 24))
+#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24))
+#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24))
/**
* Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
@@ -268,16 +268,16 @@ static av_always_inline av_const int av_popcount_c(uint32_t x)
}\
}\
-/*!
- * \def PUT_UTF8(val, tmp, PUT_BYTE)
+/**
+ * @def PUT_UTF8(val, tmp, PUT_BYTE)
* Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long).
- * \param val is an input-only argument and should be of type uint32_t. It holds
+ * @param val is an input-only argument and should be of type uint32_t. It holds
* a UCS-4 encoded Unicode character that is to be converted to UTF-8. If
* val is given as a function it is executed only once.
- * \param tmp is a temporary variable and should be of type uint8_t. It
+ * @param tmp is a temporary variable and should be of type uint8_t. It
* represents an intermediate value during conversion that is to be
* output by PUT_BYTE.
- * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination.
+ * @param PUT_BYTE writes the converted UTF-8 bytes to any proper destination.
* It could be a function or a statement, and uses tmp as the input byte.
* For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be
* executed up to 4 times for values in the valid UTF-8 range and up to
@@ -304,16 +304,16 @@ static av_always_inline av_const int av_popcount_c(uint32_t x)
}\
}
-/*!
- * \def PUT_UTF16(val, tmp, PUT_16BIT)
+/**
+ * @def PUT_UTF16(val, tmp, PUT_16BIT)
* Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes).
- * \param val is an input-only argument and should be of type uint32_t. It holds
+ * @param val is an input-only argument and should be of type uint32_t. It holds
* a UCS-4 encoded Unicode character that is to be converted to UTF-16. If
* val is given as a function it is executed only once.
- * \param tmp is a temporary variable and should be of type uint16_t. It
+ * @param tmp is a temporary variable and should be of type uint16_t. It
* represents an intermediate value during conversion that is to be
* output by PUT_16BIT.
- * \param PUT_16BIT writes the converted UTF-16 data to any proper destination
+ * @param PUT_16BIT writes the converted UTF-16 data to any proper destination
* in desired endianness. It could be a function or a statement, and uses tmp
* as the input byte. For example, PUT_BYTE could be "*output++ = tmp;"
* PUT_BYTE will be executed 1 or 2 times depending on input character.
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index ddccd00..25895d6 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -39,32 +39,47 @@ int av_get_cpu_flags(void)
#undef printf
#include <stdio.h>
+static const struct {
+ int flag;
+ const char *name;
+} cpu_flag_tab[] = {
+#if ARCH_ARM
+ { AV_CPU_FLAG_IWMMXT, "iwmmxt" },
+#elif ARCH_PPC
+ { AV_CPU_FLAG_ALTIVEC, "altivec" },
+#elif ARCH_X86
+ { AV_CPU_FLAG_MMX, "mmx" },
+ { AV_CPU_FLAG_MMX2, "mmx2" },
+ { AV_CPU_FLAG_SSE, "sse" },
+ { AV_CPU_FLAG_SSE2, "sse2" },
+ { AV_CPU_FLAG_SSE2SLOW, "sse2(slow)" },
+ { AV_CPU_FLAG_SSE3, "sse3" },
+ { AV_CPU_FLAG_SSE3SLOW, "sse3(slow)" },
+ { AV_CPU_FLAG_SSSE3, "ssse3" },
+ { AV_CPU_FLAG_ATOM, "atom" },
+ { AV_CPU_FLAG_SSE4, "sse4.1" },
+ { AV_CPU_FLAG_SSE42, "sse4.2" },
+ { AV_CPU_FLAG_AVX, "avx" },
+ { AV_CPU_FLAG_XOP, "xop" },
+ { AV_CPU_FLAG_FMA4, "fma4" },
+ { AV_CPU_FLAG_3DNOW, "3dnow" },
+ { AV_CPU_FLAG_3DNOWEXT, "3dnowext" },
+#endif
+ { 0 }
+};
+
int main(void)
{
int cpu_flags = av_get_cpu_flags();
+ int i;
printf("cpu_flags = 0x%08X\n", cpu_flags);
- printf("cpu_flags = %s%s%s%s%s%s%s%s%s%s%s%s%s\n",
-#if ARCH_ARM
- cpu_flags & AV_CPU_FLAG_IWMMXT ? "IWMMXT " : "",
-#elif ARCH_PPC
- cpu_flags & AV_CPU_FLAG_ALTIVEC ? "ALTIVEC " : "",
-#elif ARCH_X86
- cpu_flags & AV_CPU_FLAG_MMX ? "MMX " : "",
- cpu_flags & AV_CPU_FLAG_MMX2 ? "MMX2 " : "",
- cpu_flags & AV_CPU_FLAG_SSE ? "SSE " : "",
- cpu_flags & AV_CPU_FLAG_SSE2 ? "SSE2 " : "",
- cpu_flags & AV_CPU_FLAG_SSE2SLOW ? "SSE2(slow) " : "",
- cpu_flags & AV_CPU_FLAG_SSE3 ? "SSE3 " : "",
- cpu_flags & AV_CPU_FLAG_SSE3SLOW ? "SSE3(slow) " : "",
- cpu_flags & AV_CPU_FLAG_SSSE3 ? "SSSE3 " : "",
- cpu_flags & AV_CPU_FLAG_ATOM ? "Atom " : "",
- cpu_flags & AV_CPU_FLAG_SSE4 ? "SSE4.1 " : "",
- cpu_flags & AV_CPU_FLAG_SSE42 ? "SSE4.2 " : "",
- cpu_flags & AV_CPU_FLAG_AVX ? "AVX " : "",
- cpu_flags & AV_CPU_FLAG_3DNOW ? "3DNow " : "",
- cpu_flags & AV_CPU_FLAG_3DNOWEXT ? "3DNowExt " : "");
-#endif
+ printf("cpu_flags =");
+ for (i = 0; cpu_flag_tab[i].flag; i++)
+ if (cpu_flags & cpu_flag_tab[i].flag)
+ printf(" %s", cpu_flag_tab[i].name);
+ printf("\n");
+
return 0;
}
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 777cdc0..df7bf44 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -38,6 +38,8 @@
#define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions
#define AV_CPU_FLAG_SSE42 0x0200 ///< Nehalem SSE4.2 functions
#define AV_CPU_FLAG_AVX 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used
+#define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions
+#define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions
#define AV_CPU_FLAG_IWMMXT 0x0100 ///< XScale IWMMXT
#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard
diff --git a/libavutil/crc.c b/libavutil/crc.c
index 6c9f928..ee925d6 100644
--- a/libavutil/crc.c
+++ b/libavutil/crc.c
@@ -56,32 +56,34 @@ static AVCRC av_crc_table[AV_CRC_MAX][257];
* @param ctx_size size of ctx in bytes
* @return <0 on failure
*/
-int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size){
- int i, j;
+int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size)
+{
+ unsigned i, j;
uint32_t c;
- if (bits < 8 || bits > 32 || poly >= (1LL<<bits))
+ if (bits < 8 || bits > 32 || poly >= (1LL << bits))
return -1;
- if (ctx_size != sizeof(AVCRC)*257 && ctx_size != sizeof(AVCRC)*1024)
+ if (ctx_size != sizeof(AVCRC) * 257 && ctx_size != sizeof(AVCRC) * 1024)
return -1;
for (i = 0; i < 256; i++) {
if (le) {
for (c = i, j = 0; j < 8; j++)
- c = (c>>1)^(poly & (-(c&1)));
+ c = (c >> 1) ^ (poly & (-(c & 1)));
ctx[i] = c;
} else {
for (c = i << 24, j = 0; j < 8; j++)
- c = (c<<1) ^ ((poly<<(32-bits)) & (((int32_t)c)>>31) );
+ c = (c << 1) ^ ((poly << (32 - bits)) & (((int32_t) c) >> 31));
ctx[i] = av_bswap32(c);
}
}
- ctx[256]=1;
+ ctx[256] = 1;
#if !CONFIG_SMALL
- if(ctx_size >= sizeof(AVCRC)*1024)
+ if (ctx_size >= sizeof(AVCRC) * 1024)
for (i = 0; i < 256; i++)
- for(j=0; j<3; j++)
- ctx[256*(j+1) + i]= (ctx[256*j + i]>>8) ^ ctx[ ctx[256*j + i]&0xFF ];
+ for (j = 0; j < 3; j++)
+ ctx[256 *(j + 1) + i] =
+ (ctx[256 * j + i] >> 8) ^ ctx[ctx[256 * j + i] & 0xFF];
#endif
return 0;
@@ -92,9 +94,10 @@ int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size){
* @param crc_id ID of a standard CRC
* @return a pointer to the CRC table or NULL on failure
*/
-const AVCRC *av_crc_get_table(AVCRCId crc_id){
+const AVCRC *av_crc_get_table(AVCRCId crc_id)
+{
#if !CONFIG_HARDCODED_TABLES
- if (!av_crc_table[crc_id][FF_ARRAY_ELEMS(av_crc_table[crc_id])-1])
+ if (!av_crc_table[crc_id][FF_ARRAY_ELEMS(av_crc_table[crc_id]) - 1])
if (av_crc_init(av_crc_table[crc_id],
av_crc_table_params[crc_id].le,
av_crc_table_params[crc_id].bits,
@@ -112,46 +115,50 @@ const AVCRC *av_crc_get_table(AVCRCId crc_id){
*
* @see av_crc_init() "le" parameter
*/
-uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length){
- const uint8_t *end= buffer+length;
+uint32_t av_crc(const AVCRC *ctx, uint32_t crc,
+ const uint8_t *buffer, size_t length)
+{
+ const uint8_t *end = buffer + length;
#if !CONFIG_SMALL
- if(!ctx[256]) {
- while(((intptr_t) buffer & 3) && buffer < end)
- crc = ctx[((uint8_t)crc) ^ *buffer++] ^ (crc >> 8);
+ if (!ctx[256]) {
+ while (((intptr_t) buffer & 3) && buffer < end)
+ crc = ctx[((uint8_t) crc) ^ *buffer++] ^ (crc >> 8);
- while(buffer<end-3){
- crc ^= av_le2ne32(*(const uint32_t*)buffer); buffer+=4;
- crc = ctx[3*256 + ( crc &0xFF)]
- ^ctx[2*256 + ((crc>>8 )&0xFF)]
- ^ctx[1*256 + ((crc>>16)&0xFF)]
- ^ctx[0*256 + ((crc>>24) )];
+ while (buffer < end - 3) {
+ crc ^= av_le2ne32(*(const uint32_t *) buffer); buffer += 4;
+ crc = ctx[3 * 256 + ( crc & 0xFF)] ^
+ ctx[2 * 256 + ((crc >> 8 ) & 0xFF)] ^
+ ctx[1 * 256 + ((crc >> 16) & 0xFF)] ^
+ ctx[0 * 256 + ((crc >> 24) )];
}
}
#endif
- while(buffer<end)
- crc = ctx[((uint8_t)crc) ^ *buffer++] ^ (crc >> 8);
+ while (buffer < end)
+ crc = ctx[((uint8_t) crc) ^ *buffer++] ^ (crc >> 8);
return crc;
}
#ifdef TEST
#undef printf
-int main(void){
+int main(void)
+{
uint8_t buf[1999];
int i;
- int p[4][3]={{AV_CRC_32_IEEE_LE, 0xEDB88320, 0x3D5CDD04},
- {AV_CRC_32_IEEE , 0x04C11DB7, 0xC0F5BAE0},
- {AV_CRC_16_ANSI , 0x8005, 0x1FBB },
- {AV_CRC_8_ATM , 0x07, 0xE3 },};
+ int p[4][3] = { { AV_CRC_32_IEEE_LE, 0xEDB88320, 0x3D5CDD04 },
+ { AV_CRC_32_IEEE , 0x04C11DB7, 0xC0F5BAE0 },
+ { AV_CRC_16_ANSI , 0x8005 , 0x1FBB },
+ { AV_CRC_8_ATM , 0x07 , 0xE3 }
+ };
const AVCRC *ctx;
- for(i=0; i<sizeof(buf); i++)
- buf[i]= i+i*i;
+ for (i = 0; i < sizeof(buf); i++)
+ buf[i] = i + i * i;
- for(i=0; i<4; i++){
+ for (i = 0; i < 4; i++) {
ctx = av_crc_get_table(p[i][0]);
- printf("crc %08X =%X\n", p[i][1], av_crc(ctx, 0, buf, sizeof(buf)));
+ printf("crc %08X = %X\n", p[i][1], av_crc(ctx, 0, buf, sizeof(buf)));
}
return 0;
}
diff --git a/libavutil/des.c b/libavutil/des.c
index e8009a2..d65760e 100644
--- a/libavutil/des.c
+++ b/libavutil/des.c
@@ -39,6 +39,7 @@ static const uint8_t IP_shuffle[] = {
};
#undef T
+#if CONFIG_SMALL || defined(GENTABLES)
#define T(a, b, c, d) 32-a,32-b,32-c,32-d
static const uint8_t P_shuffle[] = {
T(16, 7, 20, 21),
@@ -51,6 +52,7 @@ static const uint8_t P_shuffle[] = {
T(22, 11, 4, 25)
};
#undef T
+#endif
#define T(a, b, c, d, e, f, g) 64-a,64-b,64-c,64-d,64-e,64-f,64-g
static const uint8_t PC1_shuffle[] = {
@@ -240,7 +242,7 @@ static uint32_t f_func(uint32_t r, uint64_t k) {
}
/**
- * \brief rotate the two halves of the expanded 56 bit key each 1 bit left
+ * @brief rotate the two halves of the expanded 56 bit key each 1 bit left
*
* Note: the specification calls this "shift", so I kept it although
* it is confusing.
@@ -296,11 +298,11 @@ int av_des_init(AVDES *d, const uint8_t *key, int key_bits, int decrypt) {
return 0;
}
-void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
- uint64_t iv_val = iv ? av_be2ne64(*(uint64_t *)iv) : 0;
+static void av_des_crypt_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt, int mac) {
+ uint64_t iv_val = iv ? AV_RB64(iv) : 0;
while (count-- > 0) {
uint64_t dst_val;
- uint64_t src_val = src ? av_be2ne64(*(const uint64_t *)src) : 0;
+ uint64_t src_val = src ? AV_RB64(src) : 0;
if (decrypt) {
uint64_t tmp = src_val;
if (d->triple_des) {
@@ -317,12 +319,21 @@ void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t
}
iv_val = iv ? dst_val : 0;
}
- *(uint64_t *)dst = av_be2ne64(dst_val);
+ AV_WB64(dst, dst_val);
src += 8;
- dst += 8;
+ if (!mac)
+ dst += 8;
}
if (iv)
- *(uint64_t *)iv = av_be2ne64(iv_val);
+ AV_WB64(iv, iv_val);
+}
+
+void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
+ av_des_crypt_mac(d, dst, src, count, iv, decrypt, 0);
+}
+
+void av_des_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count) {
+ av_des_crypt_mac(d, dst, src, count, (uint8_t[8]){0}, 0, 1);
}
#ifdef TEST
@@ -402,7 +413,7 @@ int main(void) {
printf("Partial Monte-Carlo test failed\n");
return 1;
}
- for (i = 0; i < 1000000; i++) {
+ for (i = 0; i < 1000; i++) {
key[0] = rand64(); key[1] = rand64(); key[2] = rand64();
data = rand64();
av_des_init(&d, key, 192, 0);
diff --git a/libavutil/des.h b/libavutil/des.h
index 5a6d4a1..cda9812 100644
--- a/libavutil/des.h
+++ b/libavutil/des.h
@@ -30,23 +30,32 @@ struct AVDES {
};
/**
- * \brief Initializes an AVDES context.
+ * @brief Initializes an AVDES context.
*
- * \param key_bits must be 64 or 192
- * \param decrypt 0 for encryption, 1 for decryption
+ * @param key_bits must be 64 or 192
+ * @param decrypt 0 for encryption/CBC-MAC, 1 for decryption
*/
int av_des_init(struct AVDES *d, const uint8_t *key, int key_bits, int decrypt);
/**
- * \brief Encrypts / decrypts using the DES algorithm.
+ * @brief Encrypts / decrypts using the DES algorithm.
*
- * \param count number of 8 byte blocks
- * \param dst destination array, can be equal to src, must be 8-byte aligned
- * \param src source array, can be equal to dst, must be 8-byte aligned, may be NULL
- * \param iv initialization vector for CBC mode, if NULL then ECB will be used,
+ * @param count number of 8 byte blocks
+ * @param dst destination array, can be equal to src, must be 8-byte aligned
+ * @param src source array, can be equal to dst, must be 8-byte aligned, may be NULL
+ * @param iv initialization vector for CBC mode, if NULL then ECB will be used,
* must be 8-byte aligned
- * \param decrypt 0 for encryption, 1 for decryption
+ * @param decrypt 0 for encryption, 1 for decryption
*/
void av_des_crypt(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt);
+/**
+ * @brief Calculates CBC-MAC using the DES algorithm.
+ *
+ * @param count number of 8 byte blocks
+ * @param dst destination array, can be equal to src, must be 8-byte aligned
+ * @param src source array, can be equal to dst, must be 8-byte aligned, may be NULL
+ */
+void av_des_mac(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count);
+
#endif /* AVUTIL_DES_H */
diff --git a/libavutil/dict.c b/libavutil/dict.c
index 3ea7e55..cb5f7b1 100644
--- a/libavutil/dict.c
+++ b/libavutil/dict.c
@@ -18,7 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <strings.h>
#include "avstring.h"
#include "dict.h"
#include "internal.h"
diff --git a/libavutil/dict.h b/libavutil/dict.h
index 397ce38..6e28b61 100644
--- a/libavutil/dict.h
+++ b/libavutil/dict.h
@@ -25,10 +25,45 @@
#ifndef AVUTIL_DICT_H
#define AVUTIL_DICT_H
+/**
+ * @addtogroup lavu_dict AVDictionary
+ * @ingroup lavu_data
+ *
+ * @brief Simple key:value store
+ *
+ * @{
+ * Dictionaries are used for storing key:value pairs. To create
+ * an AVDictionary, simply pass an address of a NULL pointer to
+ * av_dict_set(). NULL can be used as an empty dictionary wherever
+ * a pointer to an AVDictionary is required.
+ * Use av_dict_get() to retrieve an entry or iterate over all
+ * entries and finally av_dict_free() to free the dictionary
+ * and all its contents.
+ *
+ * @code
+ * AVDictionary *d = NULL; // "create" an empty dictionary
+ * av_dict_set(&d, "foo", "bar", 0); // add an entry
+ *
+ * char *k = av_strdup("key"); // if your strings are already allocated,
+ * char *v = av_strdup("value"); // you can avoid copying them like this
+ * av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
+ *
+ * AVDictionaryEntry *t = NULL;
+ * while (t = av_dict_get(d, "", t, AV_DICT_IGNORE_SUFFIX)) {
+ * <....> // iterate over all entries in d
+ * }
+ *
+ * av_dict_free(&d);
+ * @endcode
+ *
+ */
+
#define AV_DICT_MATCH_CASE 1
#define AV_DICT_IGNORE_SUFFIX 2
-#define AV_DICT_DONT_STRDUP_KEY 4
-#define AV_DICT_DONT_STRDUP_VAL 8
+#define AV_DICT_DONT_STRDUP_KEY 4 /**< Take ownership of a key that's been
+ allocated with av_malloc() and children. */
+#define AV_DICT_DONT_STRDUP_VAL 8 /**< Take ownership of a value that's been
+ allocated with av_malloc() and chilren. */
#define AV_DICT_DONT_OVERWRITE 16 ///< Don't overwrite existing entries.
#define AV_DICT_APPEND 32 /**< If the entry already exists, append to it. Note that no
delimiter is added, the strings are simply concatenated. */
@@ -74,8 +109,13 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags
void av_dict_copy(AVDictionary **dst, AVDictionary *src, int flags);
/**
- * Free all the memory allocated for an AVDictionary struct.
+ * Free all the memory allocated for an AVDictionary struct
+ * and all keys and values.
*/
void av_dict_free(AVDictionary **m);
+/**
+ * @}
+ */
+
#endif // AVUTIL_DICT_H
diff --git a/libavutil/error.c b/libavutil/error.c
index ddcc038..a330e9f 100644
--- a/libavutil/error.c
+++ b/libavutil/error.c
@@ -38,6 +38,7 @@ int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
case AVERROR_PATCHWELCOME: errstr = "Not yet implemented in Libav, patches welcome"; break;
case AVERROR_PROTOCOL_NOT_FOUND:errstr = "Protocol not found" ; break;
case AVERROR_STREAM_NOT_FOUND: errstr = "Stream not found" ; break;
+ case AVERROR_BUG: errstr = "Bug detected, please report the issue" ; break;
}
if (errstr) {
diff --git a/libavutil/error.h b/libavutil/error.h
index ba12d2b..2db65cb 100644
--- a/libavutil/error.h
+++ b/libavutil/error.h
@@ -27,6 +27,13 @@
#include <errno.h>
#include "avutil.h"
+/**
+ * @addtogroup lavu_error
+ *
+ * @{
+ */
+
+
/* error handling */
#if EDOM > 0
#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions.
@@ -50,6 +57,7 @@
#define AVERROR_PATCHWELCOME (-MKTAG( 'P','A','W','E')) ///< Not yet implemented in Libav, patches welcome
#define AVERROR_PROTOCOL_NOT_FOUND (-MKTAG(0xF8,'P','R','O')) ///< Protocol not found
#define AVERROR_STREAM_NOT_FOUND (-MKTAG(0xF8,'S','T','R')) ///< Stream not found
+#define AVERROR_BUG (-MKTAG( 'B','U','G',' ')) ///< Bug detected, please report the issue
/**
* Put a description of the AVERROR code errnum in errbuf.
@@ -65,4 +73,8 @@
*/
int av_strerror(int errnum, char *errbuf, size_t errbuf_size);
+/**
+ * @}
+ */
+
#endif /* AVUTIL_ERROR_H */
diff --git a/libavutil/eval.c b/libavutil/eval.c
index 8bcba36..9941ed7 100644
--- a/libavutil/eval.c
+++ b/libavutil/eval.c
@@ -28,6 +28,7 @@
#include "avutil.h"
#include "eval.h"
+#include "log.h"
typedef struct Parser {
const AVClass *class;
@@ -122,6 +123,7 @@ struct AVExpr {
e_mod, e_max, e_min, e_eq, e_gt, e_gte,
e_pow, e_mul, e_div, e_add,
e_last, e_st, e_while, e_floor, e_ceil, e_trunc,
+ e_sqrt, e_not,
} type;
double value; // is sign in other types
union {
@@ -148,6 +150,8 @@ static double eval_expr(Parser *p, AVExpr *e)
case e_floor: return e->value * floor(eval_expr(p, e->param[0]));
case e_ceil : return e->value * ceil (eval_expr(p, e->param[0]));
case e_trunc: return e->value * trunc(eval_expr(p, e->param[0]));
+ case e_sqrt: return e->value * sqrt (eval_expr(p, e->param[0]));
+ case e_not: return e->value * eval_expr(p, e->param[0]) == 0;
case e_while: {
double d = NAN;
while (eval_expr(p, e->param[0]))
@@ -282,6 +286,8 @@ static int parse_primary(AVExpr **e, Parser *p)
else if (strmatch(next, "floor" )) d->type = e_floor;
else if (strmatch(next, "ceil" )) d->type = e_ceil;
else if (strmatch(next, "trunc" )) d->type = e_trunc;
+ else if (strmatch(next, "sqrt" )) d->type = e_sqrt;
+ else if (strmatch(next, "not" )) d->type = e_not;
else {
for (i=0; p->func1_names && p->func1_names[i]; i++) {
if (strmatch(next, p->func1_names[i])) {
@@ -449,6 +455,8 @@ static int verify_expr(AVExpr *e)
case e_floor:
case e_ceil:
case e_trunc:
+ case e_sqrt:
+ case e_not:
return verify_expr(e->param[0]);
default: return verify_expr(e->param[0]) && verify_expr(e->param[1]);
}
@@ -460,7 +468,7 @@ int av_expr_parse(AVExpr **expr, const char *s,
const char * const *func2_names, double (* const *funcs2)(void *, double, double),
int log_offset, void *log_ctx)
{
- Parser p;
+ Parser p = { 0 };
AVExpr *e = NULL;
char *w = av_malloc(strlen(s) + 1);
char *wp = w;
@@ -506,7 +514,7 @@ end:
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
{
- Parser p;
+ Parser p = { 0 };
p.const_values = const_values;
p.opaque = opaque;
@@ -533,6 +541,8 @@ int av_expr_parse_and_eval(double *d, const char *s,
#ifdef TEST
#undef printf
+#include <string.h>
+
static double const_values[] = {
M_PI,
M_E,
@@ -545,7 +555,7 @@ static const char *const_names[] = {
0
};
-int main(void)
+int main(int argc, char **argv)
{
int i;
double d;
@@ -556,7 +566,7 @@ int main(void)
"-PI",
"+PI",
"1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
- "80G/80Gi"
+ "80G/80Gi",
"1k",
"1Gi",
"1gi",
@@ -597,6 +607,11 @@ int main(void)
"trunc(-123.123)",
"ceil(123.123)",
"ceil(-123.123)",
+ "sqrt(1764)",
+ "isnan(sqrt(-1))",
+ "not(1)",
+ "not(NAN)",
+ "not(0)",
NULL
};
@@ -617,13 +632,16 @@ int main(void)
NULL, NULL, NULL, NULL, NULL, 0, NULL);
printf("%f == 0.931322575\n", d);
- for (i=0; i<1050; i++) {
- START_TIMER
+ if (argc > 1 && !strcmp(argv[1], "-t")) {
+ for (i = 0; i < 1050; i++) {
+ START_TIMER;
av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
const_names, const_values,
NULL, NULL, NULL, NULL, NULL, 0, NULL);
- STOP_TIMER("av_expr_parse_and_eval")
+ STOP_TIMER("av_expr_parse_and_eval");
+ }
}
+
return 0;
}
#endif
diff --git a/libavutil/eval.h b/libavutil/eval.h
index c485c69..ccb29e7 100644
--- a/libavutil/eval.h
+++ b/libavutil/eval.h
@@ -58,7 +58,7 @@ int av_expr_parse_and_eval(double *res, const char *s,
* Parse an expression.
*
* @param expr a pointer where is put an AVExpr containing the parsed
- * value in case of successfull parsing, or NULL otherwise.
+ * value in case of successful parsing, or NULL otherwise.
* The pointed to AVExpr must be freed with av_expr_free() by the user
* when it is not needed anymore.
* @param s expression as a zero terminated string, for example "1+2^3+5*5+sin(2/3)"
diff --git a/libavutil/fifo.c b/libavutil/fifo.c
index f87a99d..5774d33 100644
--- a/libavutil/fifo.c
+++ b/libavutil/fifo.c
@@ -127,3 +127,39 @@ void av_fifo_drain(AVFifoBuffer *f, int size)
f->rptr -= f->end - f->buffer;
f->rndx += size;
}
+
+#ifdef TEST
+
+#undef printf
+
+int main(void)
+{
+ /* create a FIFO buffer */
+ AVFifoBuffer *fifo = av_fifo_alloc(13 * sizeof(int));
+ int i, j, n;
+
+ /* fill data */
+ for (i = 0; av_fifo_space(fifo) >= sizeof(int); i++)
+ av_fifo_generic_write(fifo, &i, sizeof(int), NULL);
+
+ /* peek at FIFO */
+ n = av_fifo_size(fifo)/sizeof(int);
+ for (i = -n+1; i < n; i++) {
+ int *v = (int *)av_fifo_peek2(fifo, i*sizeof(int));
+ printf("%d: %d\n", i, *v);
+ }
+ printf("\n");
+
+ /* read data */
+ for (i = 0; av_fifo_size(fifo) >= sizeof(int); i++) {
+ av_fifo_generic_read(fifo, &j, sizeof(int), NULL);
+ printf("%d ", j);
+ }
+ printf("\n");
+
+ av_fifo_free(fifo);
+
+ return 0;
+}
+
+#endif
diff --git a/libavutil/fifo.h b/libavutil/fifo.h
index cd361b0..f106239 100644
--- a/libavutil/fifo.h
+++ b/libavutil/fifo.h
@@ -25,6 +25,7 @@
#define AVUTIL_FIFO_H
#include <stdint.h>
+#include "avutil.h"
typedef struct AVFifoBuffer {
uint8_t *buffer;
@@ -41,20 +42,20 @@ AVFifoBuffer *av_fifo_alloc(unsigned int size);
/**
* Free an AVFifoBuffer.
- * @param *f AVFifoBuffer to free
+ * @param f AVFifoBuffer to free
*/
void av_fifo_free(AVFifoBuffer *f);
/**
* Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied.
- * @param *f AVFifoBuffer to reset
+ * @param f AVFifoBuffer to reset
*/
void av_fifo_reset(AVFifoBuffer *f);
/**
* Return the amount of data in bytes in the AVFifoBuffer, that is the
* amount of data you can read from it.
- * @param *f AVFifoBuffer to read from
+ * @param f AVFifoBuffer to read from
* @return size
*/
int av_fifo_size(AVFifoBuffer *f);
@@ -62,27 +63,27 @@ int av_fifo_size(AVFifoBuffer *f);
/**
* Return the amount of space in bytes in the AVFifoBuffer, that is the
* amount of data you can write into it.
- * @param *f AVFifoBuffer to write into
+ * @param f AVFifoBuffer to write into
* @return size
*/
int av_fifo_space(AVFifoBuffer *f);
/**
* Feed data from an AVFifoBuffer to a user-supplied callback.
- * @param *f AVFifoBuffer to read from
+ * @param f AVFifoBuffer to read from
* @param buf_size number of bytes to read
- * @param *func generic read function
- * @param *dest data destination
+ * @param func generic read function
+ * @param dest data destination
*/
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int));
/**
* Feed data from a user-supplied callback to an AVFifoBuffer.
- * @param *f AVFifoBuffer to write to
- * @param *src data source; non-const since it may be used as a
+ * @param f AVFifoBuffer to write to
+ * @param src data source; non-const since it may be used as a
* modifiable context by the function defined in func
* @param size number of bytes to write
- * @param *func generic write function; the first parameter is src,
+ * @param func generic write function; the first parameter is src,
* the second is dest_buf, the third is dest_buf_size.
* func must return the number of bytes written to dest_buf, or <= 0 to
* indicate no more data available to write.
@@ -93,7 +94,7 @@ int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void
/**
* Resize an AVFifoBuffer.
- * @param *f AVFifoBuffer to resize
+ * @param f AVFifoBuffer to resize
* @param size new AVFifoBuffer size in bytes
* @return <0 for failure, >=0 otherwise
*/
@@ -101,16 +102,40 @@ int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size);
/**
* Read and discard the specified amount of data from an AVFifoBuffer.
- * @param *f AVFifoBuffer to read from
+ * @param f AVFifoBuffer to read from
* @param size amount of data to read in bytes
*/
void av_fifo_drain(AVFifoBuffer *f, int size);
-static inline uint8_t av_fifo_peek(AVFifoBuffer *f, int offs)
+/**
+ * Return a pointer to the data stored in a FIFO buffer at a certain offset.
+ * The FIFO buffer is not modified.
+ *
+ * @param f AVFifoBuffer to peek at, f must be non-NULL
+ * @param offs an offset in bytes, its absolute value must be less
+ * than the used buffer size or the returned pointer will
+ * point outside to the buffer data.
+ * The used buffer size can be checked with av_fifo_size().
+ */
+static inline uint8_t *av_fifo_peek2(const AVFifoBuffer *f, int offs)
{
uint8_t *ptr = f->rptr + offs;
if (ptr >= f->end)
- ptr -= f->end - f->buffer;
- return *ptr;
+ ptr = f->buffer + (ptr - f->end);
+ else if (ptr < f->buffer)
+ ptr = f->end - (f->buffer - ptr);
+ return ptr;
}
+
+#if FF_API_AV_FIFO_PEEK
+/**
+ * @deprecated Use av_fifo_peek2() instead.
+ */
+attribute_deprecated
+static inline uint8_t av_fifo_peek(AVFifoBuffer *f, int offs)
+{
+ return *av_fifo_peek2(f, offs);
+}
+#endif
+
#endif /* AVUTIL_FIFO_H */
diff --git a/libavutil/file.c b/libavutil/file.c
index f0e48b5..649bb76 100644
--- a/libavutil/file.c
+++ b/libavutil/file.c
@@ -17,6 +17,7 @@
*/
#include "file.h"
+#include "log.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c
index 9dc4f01..b734db7 100644
--- a/libavutil/imgutils.c
+++ b/libavutil/imgutils.c
@@ -23,6 +23,7 @@
#include "imgutils.h"
#include "internal.h"
+#include "log.h"
#include "pixdesc.h"
void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4],
diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h
index fad4435..3815a49 100644
--- a/libavutil/imgutils.h
+++ b/libavutil/imgutils.h
@@ -22,6 +22,9 @@
/**
* @file
* misc image utilities
+ *
+ * @addtogroup lavu_picture
+ * @{
*/
#include "avutil.h"
@@ -106,8 +109,8 @@ void av_image_copy_plane(uint8_t *dst, int dst_linesize,
/**
* Copy image in src_data to dst_data.
*
- * @param dst_linesize linesizes for the image in dst_data
- * @param src_linesize linesizes for the image in src_data
+ * @param dst_linesizes linesizes for the image in dst_data
+ * @param src_linesizes linesizes for the image in src_data
*/
void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
const uint8_t *src_data[4], const int src_linesizes[4],
@@ -127,4 +130,9 @@ int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *lo
int ff_set_systematic_pal2(uint32_t pal[256], enum PixelFormat pix_fmt);
+/**
+ * @}
+ */
+
+
#endif /* AVUTIL_IMGUTILS_H */
diff --git a/libavutil/integer.c b/libavutil/integer.c
deleted file mode 100644
index 0114bb0..0000000
--- a/libavutil/integer.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * arbitrary precision integers
- * Copyright (c) 2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * arbitrary precision integers
- * @author Michael Niedermayer <michaelni at gmx.at>
- */
-
-#include "common.h"
-#include "integer.h"
-
-AVInteger av_add_i(AVInteger a, AVInteger b){
- int i, carry=0;
-
- for(i=0; i<AV_INTEGER_SIZE; i++){
- carry= (carry>>16) + a.v[i] + b.v[i];
- a.v[i]= carry;
- }
- return a;
-}
-
-AVInteger av_sub_i(AVInteger a, AVInteger b){
- int i, carry=0;
-
- for(i=0; i<AV_INTEGER_SIZE; i++){
- carry= (carry>>16) + a.v[i] - b.v[i];
- a.v[i]= carry;
- }
- return a;
-}
-
-int av_log2_i(AVInteger a){
- int i;
-
- for(i=AV_INTEGER_SIZE-1; i>=0; i--){
- if(a.v[i])
- return av_log2_16bit(a.v[i]) + 16*i;
- }
- return -1;
-}
-
-AVInteger av_mul_i(AVInteger a, AVInteger b){
- AVInteger out;
- int i, j;
- int na= (av_log2_i(a)+16) >> 4;
- int nb= (av_log2_i(b)+16) >> 4;
-
- memset(&out, 0, sizeof(out));
-
- for(i=0; i<na; i++){
- unsigned int carry=0;
-
- if(a.v[i])
- for(j=i; j<AV_INTEGER_SIZE && j-i<=nb; j++){
- carry= (carry>>16) + out.v[j] + a.v[i]*b.v[j-i];
- out.v[j]= carry;
- }
- }
-
- return out;
-}
-
-int av_cmp_i(AVInteger a, AVInteger b){
- int i;
- int v= (int16_t)a.v[AV_INTEGER_SIZE-1] - (int16_t)b.v[AV_INTEGER_SIZE-1];
- if(v) return (v>>16)|1;
-
- for(i=AV_INTEGER_SIZE-2; i>=0; i--){
- int v= a.v[i] - b.v[i];
- if(v) return (v>>16)|1;
- }
- return 0;
-}
-
-AVInteger av_shr_i(AVInteger a, int s){
- AVInteger out;
- int i;
-
- for(i=0; i<AV_INTEGER_SIZE; i++){
- unsigned int index= i + (s>>4);
- unsigned int v=0;
- if(index+1<AV_INTEGER_SIZE) v = a.v[index+1]<<16;
- if(index <AV_INTEGER_SIZE) v+= a.v[index ];
- out.v[i]= v >> (s&15);
- }
- return out;
-}
-
-AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b){
- int i= av_log2_i(a) - av_log2_i(b);
- AVInteger quot_temp;
- if(!quot) quot = "_temp;
-
- assert((int16_t)a[AV_INTEGER_SIZE-1] >= 0 && (int16_t)b[AV_INTEGER_SIZE-1] >= 0);
- assert(av_log2(b)>=0);
-
- if(i > 0)
- b= av_shr_i(b, -i);
-
- memset(quot, 0, sizeof(AVInteger));
-
- while(i-- >= 0){
- *quot= av_shr_i(*quot, -1);
- if(av_cmp_i(a, b) >= 0){
- a= av_sub_i(a, b);
- quot->v[0] += 1;
- }
- b= av_shr_i(b, 1);
- }
- return a;
-}
-
-AVInteger av_div_i(AVInteger a, AVInteger b){
- AVInteger quot;
- av_mod_i(", a, b);
- return quot;
-}
-
-AVInteger av_int2i(int64_t a){
- AVInteger out;
- int i;
-
- for(i=0; i<AV_INTEGER_SIZE; i++){
- out.v[i]= a;
- a>>=16;
- }
- return out;
-}
-
-int64_t av_i2int(AVInteger a){
- int i;
- int64_t out=(int8_t)a.v[AV_INTEGER_SIZE-1];
-
- for(i= AV_INTEGER_SIZE-2; i>=0; i--){
- out = (out<<16) + a.v[i];
- }
- return out;
-}
-
-#ifdef TEST
-#undef NDEBUG
-#include <assert.h>
-
-const uint8_t ff_log2_tab[256]={
- 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
-};
-
-int main(void){
- int64_t a,b;
-
- for(a=7; a<256*256*256; a+=13215){
- for(b=3; b<256*256*256; b+=27118){
- AVInteger ai= av_int2i(a);
- AVInteger bi= av_int2i(b);
-
- assert(av_i2int(ai) == a);
- assert(av_i2int(bi) == b);
- assert(av_i2int(av_add_i(ai,bi)) == a+b);
- assert(av_i2int(av_sub_i(ai,bi)) == a-b);
- assert(av_i2int(av_mul_i(ai,bi)) == a*b);
- assert(av_i2int(av_shr_i(ai, 9)) == a>>9);
- assert(av_i2int(av_shr_i(ai,-9)) == a<<9);
- assert(av_i2int(av_shr_i(ai, 17)) == a>>17);
- assert(av_i2int(av_shr_i(ai,-17)) == a<<17);
- assert(av_log2_i(ai) == av_log2(a));
- assert(av_i2int(av_div_i(ai,bi)) == a/b);
- }
- }
- return 0;
-}
-#endif
diff --git a/libavutil/integer.h b/libavutil/integer.h
deleted file mode 100644
index f434cfa..0000000
--- a/libavutil/integer.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * arbitrary precision integers
- * Copyright (c) 2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * arbitrary precision integers
- * @author Michael Niedermayer <michaelni at gmx.at>
- */
-
-#ifndef AVUTIL_INTEGER_H
-#define AVUTIL_INTEGER_H
-
-#include <stdint.h>
-#include "common.h"
-
-#define AV_INTEGER_SIZE 8
-
-typedef struct AVInteger{
- uint16_t v[AV_INTEGER_SIZE];
-} AVInteger;
-
-AVInteger av_add_i(AVInteger a, AVInteger b) av_const;
-AVInteger av_sub_i(AVInteger a, AVInteger b) av_const;
-
-/**
- * Return the rounded-down value of the base 2 logarithm of the given
- * AVInteger. This is simply the index of the most significant bit
- * which is 1, or 0 if all bits are 0.
- */
-int av_log2_i(AVInteger a) av_const;
-AVInteger av_mul_i(AVInteger a, AVInteger b) av_const;
-
-/**
- * Return 0 if a==b, 1 if a>b and -1 if a<b.
- */
-int av_cmp_i(AVInteger a, AVInteger b) av_const;
-
-/**
- * bitwise shift
- * @param s the number of bits by which the value should be shifted right,
- may be negative for shifting left
- */
-AVInteger av_shr_i(AVInteger a, int s) av_const;
-
-/**
- * Return a % b.
- * @param quot a/b will be stored here.
- */
-AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b);
-
-/**
- * Return a/b.
- */
-AVInteger av_div_i(AVInteger a, AVInteger b) av_const;
-
-/**
- * Convert the given int64_t to an AVInteger.
- */
-AVInteger av_int2i(int64_t a) av_const;
-
-/**
- * Convert the given AVInteger to an int64_t.
- * If the AVInteger is too large to fit into an int64_t,
- * then only the least significant 64 bits will be used.
- */
-int64_t av_i2int(AVInteger a) av_const;
-
-#endif /* AVUTIL_INTEGER_H */
diff --git a/libavutil/internal.h b/libavutil/internal.h
index 5ed3fb8..ae678d5 100644
--- a/libavutil/internal.h
+++ b/libavutil/internal.h
@@ -155,6 +155,10 @@ struct AVDictionary {
#define puts please_use_av_log_instead_of_puts
#undef perror
#define perror please_use_av_log_instead_of_perror
+#undef strcasecmp
+#define strcasecmp please_use_av_strcasecmp
+#undef strncasecmp
+#define strncasecmp please_use_av_strncasecmp
#define FF_ALLOC_OR_GOTO(ctx, p, size, label)\
{\
@@ -217,7 +221,7 @@ struct AVDictionary {
#endif
/**
- * Returns NULL if a threading library has not been enabled.
+ * Return NULL if a threading library has not been enabled.
* Used to disable threading functions in AVCodec definitions
* when not needed.
*/
diff --git a/libavutil/intfloat.h b/libavutil/intfloat.h
new file mode 100644
index 0000000..9db624a
--- /dev/null
+++ b/libavutil/intfloat.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 Mans Rullgard
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_INTFLOAT_H
+#define AVUTIL_INTFLOAT_H
+
+#include <stdint.h>
+#include "attributes.h"
+
+union av_intfloat32 {
+ uint32_t i;
+ float f;
+};
+
+union av_intfloat64 {
+ uint64_t i;
+ double f;
+};
+
+/**
+ * Reinterpret a 32-bit integer as a float.
+ */
+static av_always_inline float av_int2float(uint32_t i)
+{
+ union av_intfloat32 v = { .i = i };
+ return v.f;
+}
+
+/**
+ * Reinterpret a float as a 32-bit integer.
+ */
+static av_always_inline uint32_t av_float2int(float f)
+{
+ union av_intfloat32 v = { .f = f };
+ return v.i;
+}
+
+/**
+ * Reinterpret a 64-bit integer as a double.
+ */
+static av_always_inline double av_int2double(uint64_t i)
+{
+ union av_intfloat64 v = { .i = i };
+ return v.f;
+}
+
+/**
+ * Reinterpret a double as a 64-bit integer.
+ */
+static av_always_inline uint64_t av_double2int(double f)
+{
+ union av_intfloat64 v = { .f = f };
+ return v.i;
+}
+
+#endif /* AVUTIL_INTFLOAT_H */
diff --git a/libavutil/intfloat_readwrite.c b/libavutil/intfloat_readwrite.c
index 21a1c31..4c8de7b 100644
--- a/libavutil/intfloat_readwrite.c
+++ b/libavutil/intfloat_readwrite.c
@@ -30,13 +30,13 @@
#include "intfloat_readwrite.h"
double av_int2dbl(int64_t v){
- if(v+v > 0xFFEULL<<52)
+ if((uint64_t)v+v > 0xFFEULL<<52)
return NAN;
return ldexp(((v&((1LL<<52)-1)) + (1LL<<52)) * (v>>63|1), (v>>52&0x7FF)-1075);
}
float av_int2flt(int32_t v){
- if(v+v > 0xFF000000U)
+ if((uint32_t)v+v > 0xFF000000U)
return NAN;
return ldexp(((v&0x7FFFFF) + (1<<23)) * (v>>31|1), (v>>23&0xFF)-150);
}
diff --git a/libavutil/intfloat_readwrite.h b/libavutil/intfloat_readwrite.h
index 10ecbed..f093b92 100644
--- a/libavutil/intfloat_readwrite.h
+++ b/libavutil/intfloat_readwrite.h
@@ -30,11 +30,11 @@ typedef struct AVExtFloat {
uint8_t mantissa[8];
} AVExtFloat;
-double av_int2dbl(int64_t v) av_const;
-float av_int2flt(int32_t v) av_const;
-double av_ext2dbl(const AVExtFloat ext) av_const;
-int64_t av_dbl2int(double d) av_const;
-int32_t av_flt2int(float d) av_const;
-AVExtFloat av_dbl2ext(double d) av_const;
+attribute_deprecated double av_int2dbl(int64_t v) av_const;
+attribute_deprecated float av_int2flt(int32_t v) av_const;
+attribute_deprecated double av_ext2dbl(const AVExtFloat ext) av_const;
+attribute_deprecated int64_t av_dbl2int(double d) av_const;
+attribute_deprecated int32_t av_flt2int(float d) av_const;
+attribute_deprecated AVExtFloat av_dbl2ext(double d) av_const;
#endif /* AVUTIL_INTFLOAT_READWRITE_H */
diff --git a/libavutil/intmath.h b/libavutil/intmath.h
index 3325975..e6a2e10 100644
--- a/libavutil/intmath.h
+++ b/libavutil/intmath.h
@@ -25,6 +25,11 @@
#include "config.h"
#include "attributes.h"
+/**
+ * @addtogroup lavu_internal
+ * @{
+ */
+
extern const uint32_t ff_inverse[257];
#if ARCH_ARM
@@ -76,4 +81,7 @@ static inline av_const unsigned int ff_sqrt(unsigned int a)
return b - (a < b * b);
}
+/**
+ * @}
+ */
#endif /* AVUTIL_INTMATH_H */
diff --git a/libavutil/lfg.c b/libavutil/lfg.c
index 7fab806..227af68 100644
--- a/libavutil/lfg.c
+++ b/libavutil/lfg.c
@@ -27,19 +27,21 @@
#include "intreadwrite.h"
#include "attributes.h"
-void av_cold av_lfg_init(AVLFG *c, unsigned int seed){
- uint8_t tmp[16]={0};
+void av_cold av_lfg_init(AVLFG *c, unsigned int seed)
+{
+ uint8_t tmp[16] = { 0 };
int i;
- for(i=8; i<64; i+=4){
- AV_WL32(tmp, seed); tmp[4]=i;
- av_md5_sum(tmp, tmp, 16);
- c->state[i ]= AV_RL32(tmp);
- c->state[i+1]= AV_RL32(tmp+4);
- c->state[i+2]= AV_RL32(tmp+8);
- c->state[i+3]= AV_RL32(tmp+12);
+ for (i = 8; i < 64; i += 4) {
+ AV_WL32(tmp, seed);
+ tmp[4] = i;
+ av_md5_sum(tmp, tmp, 16);
+ c->state[i ] = AV_RL32(tmp);
+ c->state[i + 1] = AV_RL32(tmp + 4);
+ c->state[i + 2] = AV_RL32(tmp + 8);
+ c->state[i + 3] = AV_RL32(tmp + 12);
}
- c->index=0;
+ c->index = 0;
}
void av_bmg_get(AVLFG *lfg, double out[2])
@@ -47,9 +49,9 @@ void av_bmg_get(AVLFG *lfg, double out[2])
double x1, x2, w;
do {
- x1 = 2.0/UINT_MAX*av_lfg_get(lfg) - 1.0;
- x2 = 2.0/UINT_MAX*av_lfg_get(lfg) - 1.0;
- w = x1*x1 + x2*x2;
+ x1 = 2.0 / UINT_MAX * av_lfg_get(lfg) - 1.0;
+ x2 = 2.0 / UINT_MAX * av_lfg_get(lfg) - 1.0;
+ w = x1 * x1 + x2 * x2;
} while (w >= 1.0);
w = sqrt((-2.0 * log(w)) / w);
@@ -63,7 +65,7 @@ void av_bmg_get(AVLFG *lfg, double out[2])
int main(void)
{
- int x=0;
+ int x = 0;
int i, j;
AVLFG state;
@@ -71,8 +73,8 @@ int main(void)
for (j = 0; j < 10000; j++) {
START_TIMER
for (i = 0; i < 624; i++) {
-// av_log(NULL,AV_LOG_ERROR, "%X\n", av_lfg_get(&state));
- x+=av_lfg_get(&state);
+ //av_log(NULL, AV_LOG_ERROR, "%X\n", av_lfg_get(&state));
+ x += av_lfg_get(&state);
}
STOP_TIMER("624 calls of av_lfg_get");
}
diff --git a/libavutil/lls.c b/libavutil/lls.c
index 6797385..b29fc96 100644
--- a/libavutil/lls.c
+++ b/libavutil/lls.c
@@ -30,105 +30,123 @@
#include "lls.h"
-void av_init_lls(LLSModel *m, int indep_count){
+void av_init_lls(LLSModel *m, int indep_count)
+{
memset(m, 0, sizeof(LLSModel));
-
- m->indep_count= indep_count;
+ m->indep_count = indep_count;
}
-void av_update_lls(LLSModel *m, double *var, double decay){
- int i,j;
+void av_update_lls(LLSModel *m, double *var, double decay)
+{
+ int i, j;
- for(i=0; i<=m->indep_count; i++){
- for(j=i; j<=m->indep_count; j++){
+ for (i = 0; i <= m->indep_count; i++) {
+ for (j = i; j <= m->indep_count; j++) {
m->covariance[i][j] *= decay;
- m->covariance[i][j] += var[i]*var[j];
+ m->covariance[i][j] += var[i] * var[j];
}
}
}
-void av_solve_lls(LLSModel *m, double threshold, int min_order){
- int i,j,k;
- double (*factor)[MAX_VARS+1]= (void*)&m->covariance[1][0];
- double (*covar )[MAX_VARS+1]= (void*)&m->covariance[1][1];
- double *covar_y = m->covariance[0];
- int count= m->indep_count;
-
- for(i=0; i<count; i++){
- for(j=i; j<count; j++){
- double sum= covar[i][j];
-
- for(k=i-1; k>=0; k--)
- sum -= factor[i][k]*factor[j][k];
-
- if(i==j){
- if(sum < threshold)
- sum= 1.0;
- factor[i][i]= sqrt(sum);
- }else
- factor[j][i]= sum / factor[i][i];
+void av_solve_lls(LLSModel *m, double threshold, int min_order)
+{
+ int i, j, k;
+ double (*factor)[MAX_VARS + 1] = (void *) &m->covariance[1][0];
+ double (*covar) [MAX_VARS + 1] = (void *) &m->covariance[1][1];
+ double *covar_y = m->covariance[0];
+ int count = m->indep_count;
+
+ for (i = 0; i < count; i++) {
+ for (j = i; j < count; j++) {
+ double sum = covar[i][j];
+
+ for (k = i - 1; k >= 0; k--)
+ sum -= factor[i][k] * factor[j][k];
+
+ if (i == j) {
+ if (sum < threshold)
+ sum = 1.0;
+ factor[i][i] = sqrt(sum);
+ } else {
+ factor[j][i] = sum / factor[i][i];
+ }
}
}
- for(i=0; i<count; i++){
- double sum= covar_y[i+1];
- for(k=i-1; k>=0; k--)
- sum -= factor[i][k]*m->coeff[0][k];
- m->coeff[0][i]= sum / factor[i][i];
+
+ for (i = 0; i < count; i++) {
+ double sum = covar_y[i + 1];
+
+ for (k = i - 1; k >= 0; k--)
+ sum -= factor[i][k] * m->coeff[0][k];
+
+ m->coeff[0][i] = sum / factor[i][i];
}
- for(j=count-1; j>=min_order; j--){
- for(i=j; i>=0; i--){
- double sum= m->coeff[0][i];
- for(k=i+1; k<=j; k++)
- sum -= factor[k][i]*m->coeff[j][k];
- m->coeff[j][i]= sum / factor[i][i];
+ for (j = count - 1; j >= min_order; j--) {
+ for (i = j; i >= 0; i--) {
+ double sum = m->coeff[0][i];
+
+ for (k = i + 1; k <= j; k++)
+ sum -= factor[k][i] * m->coeff[j][k];
+
+ m->coeff[j][i] = sum / factor[i][i];
}
- m->variance[j]= covar_y[0];
- for(i=0; i<=j; i++){
- double sum= m->coeff[j][i]*covar[i][i] - 2*covar_y[i+1];
- for(k=0; k<i; k++)
- sum += 2*m->coeff[j][k]*covar[k][i];
- m->variance[j] += m->coeff[j][i]*sum;
+ m->variance[j] = covar_y[0];
+
+ for (i = 0; i <= j; i++) {
+ double sum = m->coeff[j][i] * covar[i][i] - 2 * covar_y[i + 1];
+
+ for (k = 0; k < i; k++)
+ sum += 2 * m->coeff[j][k] * covar[k][i];
+
+ m->variance[j] += m->coeff[j][i] * sum;
}
}
}
-double av_evaluate_lls(LLSModel *m, double *param, int order){
+double av_evaluate_lls(LLSModel *m, double *param, int order)
+{
int i;
- double out= 0;
+ double out = 0;
- for(i=0; i<=order; i++)
- out+= param[i]*m->coeff[order][i];
+ for (i = 0; i <= order; i++)
+ out += param[i] * m->coeff[order][i];
return out;
}
#ifdef TEST
-#include <stdlib.h>
#include <stdio.h>
+#include <limits.h>
+#include "lfg.h"
-int main(void){
+int main(void)
+{
LLSModel m;
int i, order;
+ AVLFG lfg;
+ av_lfg_init(&lfg, 1);
av_init_lls(&m, 3);
- for(i=0; i<100; i++){
+ for (i = 0; i < 100; i++) {
double var[4];
double eval;
- var[0] = (rand() / (double)RAND_MAX - 0.5)*2;
- var[1] = var[0] + rand() / (double)RAND_MAX - 0.5;
- var[2] = var[1] + rand() / (double)RAND_MAX - 0.5;
- var[3] = var[2] + rand() / (double)RAND_MAX - 0.5;
+
+ var[0] = (av_lfg_get(&lfg) / (double) UINT_MAX - 0.5) * 2;
+ var[1] = var[0] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
+ var[2] = var[1] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
+ var[3] = var[2] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
av_update_lls(&m, var, 0.99);
av_solve_lls(&m, 0.001, 0);
- for(order=0; order<3; order++){
- eval= av_evaluate_lls(&m, var+1, order);
+ for (order = 0; order < 3; order++) {
+ eval = av_evaluate_lls(&m, var + 1, order);
printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n",
- var[0], order, eval, sqrt(m.variance[order] / (i+1)),
- m.coeff[order][0], m.coeff[order][1], m.coeff[order][2]);
+ var[0], order, eval, sqrt(m.variance[order] / (i + 1)),
+ m.coeff[order][0], m.coeff[order][1],
+ m.coeff[order][2]);
}
}
return 0;
diff --git a/libavutil/log.c b/libavutil/log.c
index c44130c..2969355 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -35,104 +35,116 @@ static int flags;
#if defined(_WIN32) && !defined(__MINGW32CE__)
#include <windows.h>
-static const uint8_t color[] = {12,12,12,14,7,7,7};
+static const uint8_t color[] = { 12, 12, 12, 14, 7, 7, 7 };
static int16_t background, attr_orig;
static HANDLE con;
#define set_color(x) SetConsoleTextAttribute(con, background | color[x])
#define reset_color() SetConsoleTextAttribute(con, attr_orig)
#else
-static const uint8_t color[]={0x41,0x41,0x11,0x03,9,9,9};
-#define set_color(x) fprintf(stderr, "\033[%d;3%dm", color[x]>>4, color[x]&15)
+static const uint8_t color[] = { 0x41, 0x41, 0x11, 0x03, 9, 9, 9 };
+#define set_color(x) fprintf(stderr, "\033[%d;3%dm", color[x] >> 4, color[x]&15)
#define reset_color() fprintf(stderr, "\033[0m")
#endif
-static int use_color=-1;
+static int use_color = -1;
#undef fprintf
-static void colored_fputs(int level, const char *str){
- if(use_color<0){
+static void colored_fputs(int level, const char *str)
+{
+ if (use_color < 0) {
#if defined(_WIN32) && !defined(__MINGW32CE__)
CONSOLE_SCREEN_BUFFER_INFO con_info;
con = GetStdHandle(STD_ERROR_HANDLE);
- use_color = (con != INVALID_HANDLE_VALUE) && !getenv("NO_COLOR") && !getenv("FFMPEG_FORCE_NOCOLOR");
+ use_color = (con != INVALID_HANDLE_VALUE) && !getenv("NO_COLOR") &&
+ !getenv("AV_LOG_FORCE_NOCOLOR");
if (use_color) {
GetConsoleScreenBufferInfo(con, &con_info);
attr_orig = con_info.wAttributes;
background = attr_orig & 0xF0;
}
#elif HAVE_ISATTY
- use_color= !getenv("NO_COLOR") && !getenv("FFMPEG_FORCE_NOCOLOR") &&
- (getenv("TERM") && isatty(2) || getenv("FFMPEG_FORCE_COLOR"));
+ use_color = !getenv("NO_COLOR") && !getenv("AV_LOG_FORCE_NOCOLOR") &&
+ (getenv("TERM") && isatty(2) ||
+ getenv("AV_LOG_FORCE_COLOR"));
#else
- use_color= getenv("FFMPEG_FORCE_COLOR") && !getenv("NO_COLOR") && !getenv("FFMPEG_FORCE_NOCOLOR");
+ use_color = getenv("AV_LOG_FORCE_COLOR") && !getenv("NO_COLOR") &&
+ !getenv("AV_LOG_FORCE_NOCOLOR");
#endif
}
- if(use_color){
+ if (use_color) {
set_color(level);
}
fputs(str, stderr);
- if(use_color){
+ if (use_color) {
reset_color();
}
}
-const char* av_default_item_name(void* ptr){
- return (*(AVClass**)ptr)->class_name;
+const char *av_default_item_name(void *ptr)
+{
+ return (*(AVClass **) ptr)->class_name;
}
void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
{
- static int print_prefix=1;
+ static int print_prefix = 1;
static int count;
static char prev[1024];
char line[1024];
static int is_atty;
- AVClass* avc= ptr ? *(AVClass**)ptr : NULL;
- if(level>av_log_level)
+ AVClass* avc = ptr ? *(AVClass **) ptr : NULL;
+ if (level > av_log_level)
return;
- line[0]=0;
+ line[0] = 0;
#undef fprintf
- if(print_prefix && avc) {
+ if (print_prefix && avc) {
if (avc->parent_log_context_offset) {
- AVClass** parent= *(AVClass***)(((uint8_t*)ptr) + avc->parent_log_context_offset);
- if(parent && *parent){
- snprintf(line, sizeof(line), "[%s @ %p] ", (*parent)->item_name(parent), parent);
+ AVClass** parent = *(AVClass ***) (((uint8_t *) ptr) +
+ avc->parent_log_context_offset);
+ if (parent && *parent) {
+ snprintf(line, sizeof(line), "[%s @ %p] ",
+ (*parent)->item_name(parent), parent);
}
}
- snprintf(line + strlen(line), sizeof(line) - strlen(line), "[%s @ %p] ", avc->item_name(ptr), ptr);
+ snprintf(line + strlen(line), sizeof(line) - strlen(line), "[%s @ %p] ",
+ avc->item_name(ptr), ptr);
}
vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, vl);
- print_prefix = strlen(line) && line[strlen(line)-1] == '\n';
+ print_prefix = strlen(line) && line[strlen(line) - 1] == '\n';
#if HAVE_ISATTY
- if(!is_atty) is_atty= isatty(2) ? 1 : -1;
+ if (!is_atty)
+ is_atty = isatty(2) ? 1 : -1;
#endif
- if(print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strncmp(line, prev, sizeof line)){
+ if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) &&
+ !strncmp(line, prev, sizeof line)) {
count++;
- if(is_atty==1)
+ if (is_atty == 1)
fprintf(stderr, " Last message repeated %d times\r", count);
return;
}
- if(count>0){
+ if (count > 0) {
fprintf(stderr, " Last message repeated %d times\n", count);
- count=0;
+ count = 0;
}
- colored_fputs(av_clip(level>>3, 0, 6), line);
+ colored_fputs(av_clip(level >> 3, 0, 6), line);
av_strlcpy(prev, line, sizeof line);
}
-static void (*av_log_callback)(void*, int, const char*, va_list) = av_log_default_callback;
+static void (*av_log_callback)(void*, int, const char*, va_list) =
+ av_log_default_callback;
void av_log(void* avcl, int level, const char *fmt, ...)
{
- AVClass* avc= avcl ? *(AVClass**)avcl : NULL;
+ AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
va_list vl;
va_start(vl, fmt);
- if(avc && avc->version >= (50<<16 | 15<<8 | 2) && avc->log_level_offset_offset && level>=AV_LOG_FATAL)
- level += *(int*)(((uint8_t*)avcl) + avc->log_level_offset_offset);
+ if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
+ avc->log_level_offset_offset && level >= AV_LOG_FATAL)
+ level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset);
av_vlog(avcl, level, fmt, vl);
va_end(vl);
}
@@ -154,7 +166,7 @@ void av_log_set_level(int level)
void av_log_set_flags(int arg)
{
- flags= arg;
+ flags = arg;
}
void av_log_set_callback(void (*callback)(void*, int, const char*, va_list))
diff --git a/libavutil/log.h b/libavutil/log.h
index c823a76..0678e1a 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -23,13 +23,14 @@
#include <stdarg.h>
#include "avutil.h"
+#include "attributes.h"
/**
* Describe the class of an AVClass context structure. That is an
* arbitrary struct of which the first field is a pointer to an
* AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
*/
-typedef struct {
+typedef struct AVClass {
/**
* The name of the class; usually it is the same name as the
* context structure type to which the AVClass is associated.
@@ -72,11 +73,19 @@ typedef struct {
int parent_log_context_offset;
/**
- * A function for extended searching, e.g. in possible
- * children objects.
+ * Return next AVOptions-enabled child or NULL
*/
- const struct AVOption* (*opt_find)(void *obj, const char *name, const char *unit,
- int opt_flags, int search_flags);
+ void* (*child_next)(void *obj, void *prev);
+
+ /**
+ * Return an AVClass corresponding to next potential
+ * AVOptions-enabled child.
+ *
+ * The difference between child_next and this is that
+ * child_next iterates over _already existing_ objects, while
+ * child_class_next iterates over _all possible_ children.
+ */
+ const struct AVClass* (*child_class_next)(const struct AVClass *prev);
} AVClass;
/* av_log API */
@@ -129,11 +138,7 @@ typedef struct {
* subsequent arguments are converted to output.
* @see av_vlog
*/
-#ifdef __GNUC__
-void av_log(void *avcl, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4)));
-#else
-void av_log(void *avcl, int level, const char *fmt, ...);
-#endif
+void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4);
void av_vlog(void *avcl, int level, const char *fmt, va_list);
int av_log_get_level(void);
diff --git a/libavutil/lzo.c b/libavutil/lzo.c
index ef01653..26cda12 100644
--- a/libavutil/lzo.c
+++ b/libavutil/lzo.c
@@ -21,14 +21,14 @@
#include "avutil.h"
#include "common.h"
-//! Avoid e.g. MPlayers fast_memcpy, it slows things down here.
+/// Avoid e.g. MPlayers fast_memcpy, it slows things down here.
#undef memcpy
#include <string.h>
#include "lzo.h"
-//! Define if we may write up to 12 bytes beyond the output buffer.
+/// Define if we may write up to 12 bytes beyond the output buffer.
#define OUTBUF_PADDED 1
-//! Define if we may read up to 8 bytes beyond the input buffer.
+/// Define if we may read up to 8 bytes beyond the input buffer.
#define INBUF_PADDED 1
typedef struct LZOContext {
const uint8_t *in, *in_end;
@@ -37,8 +37,8 @@ typedef struct LZOContext {
} LZOContext;
/**
- * \brief Reads one byte from the input buffer, avoiding an overrun.
- * \return byte read
+ * @brief Reads one byte from the input buffer, avoiding an overrun.
+ * @return byte read
*/
static inline int get_byte(LZOContext *c) {
if (c->in < c->in_end)
@@ -54,10 +54,10 @@ static inline int get_byte(LZOContext *c) {
#endif
/**
- * \brief Decodes a length value in the coding used by lzo.
- * \param x previous byte value
- * \param mask bits used from x
- * \return decoded length value
+ * @brief Decodes a length value in the coding used by lzo.
+ * @param x previous byte value
+ * @param mask bits used from x
+ * @return decoded length value
*/
static inline int get_len(LZOContext *c, int x, int mask) {
int cnt = x & mask;
@@ -82,8 +82,8 @@ static inline int get_len(LZOContext *c, int x, int mask) {
#endif
/**
- * \brief Copies bytes from input to output buffer with checking.
- * \param cnt number of bytes to copy, must be >= 0
+ * @brief Copies bytes from input to output buffer with checking.
+ * @param cnt number of bytes to copy, must be >= 0
*/
static inline void copy(LZOContext *c, int cnt) {
register const uint8_t *src = c->in;
@@ -111,9 +111,9 @@ static inline void copy(LZOContext *c, int cnt) {
static inline void memcpy_backptr(uint8_t *dst, int back, int cnt);
/**
- * \brief Copies previously decoded bytes to current position.
- * \param back how many bytes back we start
- * \param cnt number of bytes to copy, must be >= 0
+ * @brief Copies previously decoded bytes to current position.
+ * @param back how many bytes back we start
+ * @param cnt number of bytes to copy, must be >= 0
*
* cnt > back is valid, this will copy the bytes we just copied,
* thus creating a repeating pattern with a period length of back.
diff --git a/libavutil/lzo.h b/libavutil/lzo.h
index a3924de..1b774a5 100644
--- a/libavutil/lzo.h
+++ b/libavutil/lzo.h
@@ -22,30 +22,37 @@
#ifndef AVUTIL_LZO_H
#define AVUTIL_LZO_H
+/**
+ * @defgroup lavu_lzo LZO
+ * @ingroup lavu_crypto
+ *
+ * @{
+ */
+
#include <stdint.h>
/** @name Error flags returned by av_lzo1x_decode
- * \{ */
-//! end of the input buffer reached before decoding finished
+ * @{ */
+/// end of the input buffer reached before decoding finished
#define AV_LZO_INPUT_DEPLETED 1
-//! decoded data did not fit into output buffer
+/// decoded data did not fit into output buffer
#define AV_LZO_OUTPUT_FULL 2
-//! a reference to previously decoded data was wrong
+/// a reference to previously decoded data was wrong
#define AV_LZO_INVALID_BACKPTR 4
-//! a non-specific error in the compressed bitstream
+/// a non-specific error in the compressed bitstream
#define AV_LZO_ERROR 8
-/** \} */
+/** @} */
#define AV_LZO_INPUT_PADDING 8
#define AV_LZO_OUTPUT_PADDING 12
/**
- * \brief Decodes LZO 1x compressed data.
- * \param out output buffer
- * \param outlen size of output buffer, number of bytes left are returned here
- * \param in input buffer
- * \param inlen size of input buffer, number of bytes left are returned here
- * \return 0 on success, otherwise a combination of the error flags above
+ * @brief Decodes LZO 1x compressed data.
+ * @param out output buffer
+ * @param outlen size of output buffer, number of bytes left are returned here
+ * @param in input buffer
+ * @param inlen size of input buffer, number of bytes left are returned here
+ * @return 0 on success, otherwise a combination of the error flags above
*
* Make sure all buffers are appropriately padded, in must provide
* AV_LZO_INPUT_PADDING, out must provide AV_LZO_OUTPUT_PADDING additional bytes.
@@ -53,14 +60,18 @@
int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen);
/**
- * \brief deliberately overlapping memcpy implementation
- * \param dst destination buffer; must be padded with 12 additional bytes
- * \param back how many bytes back we start (the initial size of the overlapping window)
- * \param cnt number of bytes to copy, must be >= 0
+ * @brief deliberately overlapping memcpy implementation
+ * @param dst destination buffer; must be padded with 12 additional bytes
+ * @param back how many bytes back we start (the initial size of the overlapping window)
+ * @param cnt number of bytes to copy, must be >= 0
*
* cnt > back is valid, this will copy the bytes we just copied,
* thus creating a repeating pattern with a period length of back.
*/
void av_memcpy_backptr(uint8_t *dst, int back, int cnt);
+/**
+ * @}
+ */
+
#endif /* AVUTIL_LZO_H */
diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c
index 53155c3..e6ce2f9 100644
--- a/libavutil/mathematics.c
+++ b/libavutil/mathematics.c
@@ -150,32 +150,3 @@ int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod){
c-= mod;
return c;
}
-
-#ifdef TEST
-#include "integer.h"
-#undef printf
-int main(void){
- int64_t a,b,c,d,e;
-
- for(a=7; a<(1LL<<62); a+=a/3+1){
- for(b=3; b<(1LL<<62); b+=b/4+1){
- for(c=9; c<(1LL<<62); c+=(c*2)/5+3){
- int64_t r= c/2;
- AVInteger ai;
- ai= av_mul_i(av_int2i(a), av_int2i(b));
- ai= av_add_i(ai, av_int2i(r));
-
- d= av_i2int(av_div_i(ai, av_int2i(c)));
-
- e= av_rescale(a,b,c);
-
- if((double)a * (double)b / (double)c > (1LL<<63))
- continue;
-
- if(d!=e) printf("%"PRId64"*%"PRId64"/%"PRId64"= %"PRId64"=%"PRId64"\n", a, b, c, d, e);
- }
- }
- }
- return 0;
-}
-#endif
diff --git a/libavutil/mathematics.h b/libavutil/mathematics.h
index 35494bb..0b072eb 100644
--- a/libavutil/mathematics.h
+++ b/libavutil/mathematics.h
@@ -57,6 +57,12 @@
#define INFINITY (1.0/0.0)
#endif
+/**
+ * @addtogroup lavu_math
+ * @{
+ */
+
+
enum AVRounding {
AV_ROUND_ZERO = 0, ///< Round toward zero.
AV_ROUND_INF = 1, ///< Round away from zero.
@@ -109,4 +115,8 @@ int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b);
*/
int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod);
+/**
+ * @}
+ */
+
#endif /* AVUTIL_MATHEMATICS_H */
diff --git a/libavutil/md5.c b/libavutil/md5.c
index 271d71f..ca0e598 100644
--- a/libavutil/md5.c
+++ b/libavutil/md5.c
@@ -30,8 +30,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <string.h>
+#include <stdint.h>
#include "bswap.h"
+#include "intreadwrite.h"
#include "md5.h"
typedef struct AVMD5{
@@ -40,7 +41,7 @@ typedef struct AVMD5{
uint32_t ABCD[4];
} AVMD5;
-const int av_md5_size= sizeof(AVMD5);
+const int av_md5_size = sizeof(AVMD5);
static const uint8_t S[4][4] = {
{ 7, 12, 17, 22 }, /* round 1 */
@@ -71,42 +72,49 @@ static const uint32_t T[64] = { // T[i]= fabs(sin(i+1)<<32)
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
};
-#define CORE(i, a, b, c, d) \
- t = S[i>>4][i&3];\
- a += T[i];\
-\
- if(i<32){\
- if(i<16) a += (d ^ (b&(c^d))) + X[ i &15 ];\
- else a += (c ^ (d&(c^b))) + X[ (1+5*i)&15 ];\
- }else{\
- if(i<48) a += (b^c^d) + X[ (5+3*i)&15 ];\
- else a += (c^(b|~d)) + X[ ( 7*i)&15 ];\
- }\
- a = b + (( a << t ) | ( a >> (32 - t) ));
-
-static void body(uint32_t ABCD[4], uint32_t X[16]){
-
+#define CORE(i, a, b, c, d) do { \
+ t = S[i >> 4][i & 3]; \
+ a += T[i]; \
+ \
+ if (i < 32) { \
+ if (i < 16) a += (d ^ (b & (c ^ d))) + X[ i & 15]; \
+ else a += (c ^ (d & (c ^ b))) + X[(1 + 5*i) & 15]; \
+ } else { \
+ if (i < 48) a += (b ^ c ^ d) + X[(5 + 3*i) & 15]; \
+ else a += (c ^ (b | ~d)) + X[( 7*i) & 15]; \
+ } \
+ a = b + (a << t | a >> (32 - t)); \
+ } while (0)
+
+static void body(uint32_t ABCD[4], uint32_t X[16])
+{
int t;
int i av_unused;
- unsigned int a= ABCD[3];
- unsigned int b= ABCD[2];
- unsigned int c= ABCD[1];
- unsigned int d= ABCD[0];
+ unsigned int a = ABCD[3];
+ unsigned int b = ABCD[2];
+ unsigned int c = ABCD[1];
+ unsigned int d = ABCD[0];
#if HAVE_BIGENDIAN
- for(i=0; i<16; i++)
- X[i]= av_bswap32(X[i]);
+ for (i = 0; i < 16; i++)
+ X[i] = av_bswap32(X[i]);
#endif
#if CONFIG_SMALL
- for( i = 0; i < 64; i++ ){
- CORE(i,a,b,c,d)
- t=d; d=c; c=b; b=a; a=t;
+ for (i = 0; i < 64; i++) {
+ CORE(i, a, b, c, d);
+ t = d;
+ d = c;
+ c = b;
+ b = a;
+ a = t;
}
#else
-#define CORE2(i) CORE(i,a,b,c,d) CORE((i+1),d,a,b,c) CORE((i+2),c,d,a,b) CORE((i+3),b,c,d,a)
-#define CORE4(i) CORE2(i) CORE2((i+4)) CORE2((i+8)) CORE2((i+12))
-CORE4(0) CORE4(16) CORE4(32) CORE4(48)
+#define CORE2(i) \
+ CORE( i, a,b,c,d); CORE((i+1),d,a,b,c); \
+ CORE((i+2),c,d,a,b); CORE((i+3),b,c,d,a)
+#define CORE4(i) CORE2(i); CORE2((i+4)); CORE2((i+8)); CORE2((i+12))
+ CORE4(0); CORE4(16); CORE4(32); CORE4(48);
#endif
ABCD[0] += d;
@@ -115,8 +123,9 @@ CORE4(0) CORE4(16) CORE4(32) CORE4(48)
ABCD[3] += a;
}
-void av_md5_init(AVMD5 *ctx){
- ctx->len = 0;
+void av_md5_init(AVMD5 *ctx)
+{
+ ctx->len = 0;
ctx->ABCD[0] = 0x10325476;
ctx->ABCD[1] = 0x98badcfe;
@@ -124,59 +133,72 @@ void av_md5_init(AVMD5 *ctx){
ctx->ABCD[3] = 0x67452301;
}
-void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len){
+void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len)
+{
int i, j;
- j= ctx->len & 63;
+ j = ctx->len & 63;
ctx->len += len;
- for( i = 0; i < len; i++ ){
+ for (i = 0; i < len; i++) {
ctx->block[j++] = src[i];
- if( 64 == j ){
- body(ctx->ABCD, (uint32_t*) ctx->block);
+ if (j == 64) {
+ body(ctx->ABCD, (uint32_t *) ctx->block);
j = 0;
}
}
}
-void av_md5_final(AVMD5 *ctx, uint8_t *dst){
+void av_md5_final(AVMD5 *ctx, uint8_t *dst)
+{
int i;
- uint64_t finalcount= av_le2ne64(ctx->len<<3);
+ uint64_t finalcount = av_le2ne64(ctx->len << 3);
av_md5_update(ctx, "\200", 1);
- while((ctx->len & 63)!=56)
+ while ((ctx->len & 63) != 56)
av_md5_update(ctx, "", 1);
- av_md5_update(ctx, (uint8_t*)&finalcount, 8);
+ av_md5_update(ctx, (uint8_t *)&finalcount, 8);
- for(i=0; i<4; i++)
- ((uint32_t*)dst)[i]= av_le2ne32(ctx->ABCD[3-i]);
+ for (i = 0; i < 4; i++)
+ AV_WL32(dst + 4*i, ctx->ABCD[3 - i]);
}
-void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len){
- AVMD5 ctx[1];
+void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len)
+{
+ AVMD5 ctx;
- av_md5_init(ctx);
- av_md5_update(ctx, src, len);
- av_md5_final(ctx, dst);
+ av_md5_init(&ctx);
+ av_md5_update(&ctx, src, len);
+ av_md5_final(&ctx, dst);
}
#ifdef TEST
-#include <stdio.h>
-#include <inttypes.h>
#undef printf
+#include <stdio.h>
+
+static void print_md5(uint8_t *md5)
+{
+ int i;
+ for (i = 0; i < 16; i++)
+ printf("%02x", md5[i]);
+ printf("\n");
+}
+
int main(void){
- uint64_t md5val;
+ uint8_t md5val[16];
int i;
uint8_t in[1000];
- for(i=0; i<1000; i++) in[i]= i*i;
- av_md5_sum( (uint8_t*)&md5val, in, 1000); printf("%"PRId64"\n", md5val);
- av_md5_sum( (uint8_t*)&md5val, in, 63); printf("%"PRId64"\n", md5val);
- av_md5_sum( (uint8_t*)&md5val, in, 64); printf("%"PRId64"\n", md5val);
- av_md5_sum( (uint8_t*)&md5val, in, 65); printf("%"PRId64"\n", md5val);
- for(i=0; i<1000; i++) in[i]= i % 127;
- av_md5_sum( (uint8_t*)&md5val, in, 999); printf("%"PRId64"\n", md5val);
+ for (i = 0; i < 1000; i++)
+ in[i] = i * i;
+ av_md5_sum(md5val, in, 1000); print_md5(md5val);
+ av_md5_sum(md5val, in, 63); print_md5(md5val);
+ av_md5_sum(md5val, in, 64); print_md5(md5val);
+ av_md5_sum(md5val, in, 65); print_md5(md5val);
+ for (i = 0; i < 1000; i++)
+ in[i] = i % 127;
+ av_md5_sum(md5val, in, 999); print_md5(md5val);
return 0;
}
diff --git a/libavutil/md5.h b/libavutil/md5.h
index c178bbb..1412ee2 100644
--- a/libavutil/md5.h
+++ b/libavutil/md5.h
@@ -23,6 +23,12 @@
#include <stdint.h>
+/**
+ * @defgroup lavu_md5 MD5
+ * @ingroup lavu_crypto
+ * @{
+ */
+
extern const int av_md5_size;
struct AVMD5;
@@ -32,5 +38,9 @@ void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, const int len);
void av_md5_final(struct AVMD5 *ctx, uint8_t *dst);
void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len);
+/**
+ * @}
+ */
+
#endif /* AVUTIL_MD5_H */
diff --git a/libavutil/mem.h b/libavutil/mem.h
index 5dea492..cd8490b 100644
--- a/libavutil/mem.h
+++ b/libavutil/mem.h
@@ -29,6 +29,12 @@
#include "attributes.h"
#include "avutil.h"
+/**
+ * @addtogroup lavu_mem
+ * @{
+ */
+
+
#if defined(__ICC) && _ICC < 1200 || defined(__SUNPRO_C)
#define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
#define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v
@@ -76,10 +82,10 @@ void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1);
* Allocate or reallocate a block of memory.
* If ptr is NULL and size > 0, allocate a new block. If
* size is zero, free the memory block pointed to by ptr.
- * @param size Size in bytes for the memory block to be allocated or
- * reallocated.
* @param ptr Pointer to a memory block already allocated with
* av_malloc(z)() or av_realloc() or NULL.
+ * @param size Size in bytes for the memory block to be allocated or
+ * reallocated.
* @return Pointer to a newly reallocated block or NULL if the block
* cannot be reallocated or the function is used to free the memory block.
* @see av_fast_realloc()
@@ -123,4 +129,8 @@ char *av_strdup(const char *s) av_malloc_attrib;
*/
void av_freep(void *ptr);
+/**
+ * @}
+ */
+
#endif /* AVUTIL_MEM_H */
diff --git a/libavutil/opt.c b/libavutil/opt.c
index 518863a..7c53024 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -30,6 +30,7 @@
#include "opt.h"
#include "eval.h"
#include "dict.h"
+#include "log.h"
#if FF_API_FIND_OPT
//FIXME order them and do a bin search
@@ -46,36 +47,50 @@ const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mas
}
#endif
+#if FF_API_OLD_AVOPTIONS
const AVOption *av_next_option(void *obj, const AVOption *last)
{
- if (last && last[1].name) return ++last;
- else if (last) return NULL;
- else return (*(AVClass**)obj)->option;
+ return av_opt_next(obj, last);
}
+#endif
-static int av_set_number2(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out)
+const AVOption *av_opt_next(void *obj, const AVOption *last)
{
- const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
- void *dst;
- if (o_out)
- *o_out= o;
- if (!o || o->offset<=0)
- return AVERROR_OPTION_NOT_FOUND;
+ AVClass *class = *(AVClass**)obj;
+ if (!last && class->option[0].name) return class->option;
+ if (last && last[1].name) return ++last;
+ return NULL;
+}
+static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum)
+{
+ switch (o->type) {
+ case AV_OPT_TYPE_FLAGS: *intnum = *(unsigned int*)dst;return 0;
+ case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0;
+ case AV_OPT_TYPE_INT64: *intnum = *(int64_t *)dst;return 0;
+ case AV_OPT_TYPE_FLOAT: *num = *(float *)dst;return 0;
+ case AV_OPT_TYPE_DOUBLE: *num = *(double *)dst;return 0;
+ case AV_OPT_TYPE_RATIONAL: *intnum = ((AVRational*)dst)->num;
+ *den = ((AVRational*)dst)->den;
+ return 0;
+ }
+ return AVERROR(EINVAL);
+}
+
+static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
+{
if (o->max*den < num*intnum || o->min*den > num*intnum) {
- av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, name);
+ av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, o->name);
return AVERROR(ERANGE);
}
- dst= ((uint8_t*)obj) + o->offset;
-
switch (o->type) {
- case FF_OPT_TYPE_FLAGS:
- case FF_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break;
- case FF_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break;
- case FF_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break;
- case FF_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break;
- case FF_OPT_TYPE_RATIONAL:
+ case AV_OPT_TYPE_FLAGS:
+ case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break;
+ case AV_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break;
+ case AV_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break;
+ case AV_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break;
+ case AV_OPT_TYPE_RATIONAL:
if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
break;
@@ -85,15 +100,6 @@ static int av_set_number2(void *obj, const char *name, double num, int den, int6
return 0;
}
-static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum)
-{
- const AVOption *o = NULL;
- if (av_set_number2(obj, name, num, den, intnum, &o) < 0)
- return NULL;
- else
- return o;
-}
-
static const double const_values[] = {
M_PI,
M_E,
@@ -115,114 +121,202 @@ static int hexchar2int(char c) {
return -1;
}
+static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
+{
+ int *lendst = (int *)(dst + 1);
+ uint8_t *bin, *ptr;
+ int len = strlen(val);
+
+ av_freep(dst);
+ *lendst = 0;
+
+ if (len & 1)
+ return AVERROR(EINVAL);
+ len /= 2;
+
+ ptr = bin = av_malloc(len);
+ while (*val) {
+ int a = hexchar2int(*val++);
+ int b = hexchar2int(*val++);
+ if (a < 0 || b < 0) {
+ av_free(bin);
+ return AVERROR(EINVAL);
+ }
+ *ptr++ = (a << 4) | b;
+ }
+ *dst = bin;
+ *lendst = len;
+
+ return 0;
+}
+
+static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
+{
+ av_freep(dst);
+ *dst = av_strdup(val);
+ return 0;
+}
+
+static int set_string_number(void *obj, const AVOption *o, const char *val, void *dst)
+{
+ int ret = 0, notfirst = 0;
+ for (;;) {
+ int i, den = 1;
+ char buf[256];
+ int cmd = 0;
+ double d, num = 1;
+ int64_t intnum = 1;
+
+ if (*val == '+' || *val == '-')
+ cmd = *(val++);
+
+ for (i = 0; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
+ buf[i] = val[i];
+ buf[i] = 0;
+
+ {
+ const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);
+ if (o_named && o_named->type == AV_OPT_TYPE_CONST)
+ d = o_named->default_val.dbl;
+ else if (!strcmp(buf, "default")) d = o->default_val.dbl;
+ else if (!strcmp(buf, "max" )) d = o->max;
+ else if (!strcmp(buf, "min" )) d = o->min;
+ else if (!strcmp(buf, "none" )) d = 0;
+ else if (!strcmp(buf, "all" )) d = ~0;
+ else {
+ int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
+ if (res < 0) {
+ av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
+ return res;
+ }
+ }
+ }
+ if (o->type == AV_OPT_TYPE_FLAGS) {
+ read_number(o, dst, NULL, NULL, &intnum);
+ if (cmd == '+') d = intnum | (int64_t)d;
+ else if (cmd == '-') d = intnum &~(int64_t)d;
+ } else {
+ read_number(o, dst, &num, &den, &intnum);
+ if (cmd == '+') d = notfirst*num*intnum/den + d;
+ else if (cmd == '-') d = notfirst*num*intnum/den - d;
+ }
+
+ if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
+ return ret;
+ val += i;
+ if (!*val)
+ return 0;
+ notfirst = 1;
+ }
+
+ return 0;
+}
+
+#if FF_API_OLD_AVOPTIONS
int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
{
- int ret;
const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
if (o_out)
*o_out = o;
- if (!o)
+ return av_opt_set(obj, name, val, 0);
+}
+#endif
+
+int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
+{
+ void *dst, *target_obj;
+ const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ if (!o || !target_obj)
return AVERROR_OPTION_NOT_FOUND;
- if (!val || o->offset<=0)
+ if (!val)
return AVERROR(EINVAL);
- if (o->type == FF_OPT_TYPE_BINARY) {
- uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset);
- int *lendst = (int *)(dst + 1);
- uint8_t *bin, *ptr;
- int len = strlen(val);
- av_freep(dst);
- *lendst = 0;
- if (len & 1) return AVERROR(EINVAL);
- len /= 2;
- ptr = bin = av_malloc(len);
- while (*val) {
- int a = hexchar2int(*val++);
- int b = hexchar2int(*val++);
- if (a < 0 || b < 0) {
- av_free(bin);
- return AVERROR(EINVAL);
- }
- *ptr++ = (a << 4) | b;
- }
- *dst = bin;
- *lendst = len;
- return 0;
+ dst = ((uint8_t*)target_obj) + o->offset;
+ switch (o->type) {
+ case AV_OPT_TYPE_STRING: return set_string(obj, o, val, dst);
+ case AV_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst);
+ case AV_OPT_TYPE_FLAGS:
+ case AV_OPT_TYPE_INT:
+ case AV_OPT_TYPE_INT64:
+ case AV_OPT_TYPE_FLOAT:
+ case AV_OPT_TYPE_DOUBLE:
+ case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, o, val, dst);
}
- if (o->type != FF_OPT_TYPE_STRING) {
- int notfirst=0;
- for (;;) {
- int i;
- char buf[256];
- int cmd=0;
- double d;
-
- if (*val == '+' || *val == '-')
- cmd= *(val++);
-
- for (i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++)
- buf[i]= val[i];
- buf[i]=0;
-
- {
- const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);
- if (o_named && o_named->type == FF_OPT_TYPE_CONST)
- d= o_named->default_val.dbl;
- else if (!strcmp(buf, "default")) d= o->default_val.dbl;
- else if (!strcmp(buf, "max" )) d= o->max;
- else if (!strcmp(buf, "min" )) d= o->min;
- else if (!strcmp(buf, "none" )) d= 0;
- else if (!strcmp(buf, "all" )) d= ~0;
- else {
- int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
- if (res < 0) {
- av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
- return res;
- }
- }
- }
- if (o->type == FF_OPT_TYPE_FLAGS) {
- if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d;
- else if (cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d;
- } else {
- if (cmd=='+') d= notfirst*av_get_double(obj, name, NULL) + d;
- else if (cmd=='-') d= notfirst*av_get_double(obj, name, NULL) - d;
- }
- if ((ret = av_set_number2(obj, name, d, 1, 1, o_out)) < 0)
- return ret;
- val+= i;
- if (!*val)
- return 0;
- notfirst=1;
- }
- return AVERROR(EINVAL);
- }
+ av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
+ return AVERROR(EINVAL);
+}
- if (alloc) {
- av_free(*(void**)(((uint8_t*)obj) + o->offset));
- val= av_strdup(val);
+#define OPT_EVAL_NUMBER(name, opttype, vartype)\
+ int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
+ {\
+ if (!o || o->type != opttype)\
+ return AVERROR(EINVAL);\
+ return set_string_number(obj, o, val, name ## _out);\
}
- memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val));
- return 0;
+OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int)
+OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int)
+OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t)
+OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float)
+OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double)
+OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational)
+
+static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
+ int search_flags)
+{
+ void *dst, *target_obj;
+ const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+
+ if (!o || !target_obj)
+ return AVERROR_OPTION_NOT_FOUND;
+
+ dst = ((uint8_t*)target_obj) + o->offset;
+ return write_number(obj, o, dst, num, den, intnum);
}
+#if FF_API_OLD_AVOPTIONS
const AVOption *av_set_double(void *obj, const char *name, double n)
{
- return av_set_number(obj, name, n, 1, 1);
+ const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
+ if (set_number(obj, name, n, 1, 1, 0) < 0)
+ return NULL;
+ return o;
}
const AVOption *av_set_q(void *obj, const char *name, AVRational n)
{
- return av_set_number(obj, name, n.num, n.den, 1);
+ const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
+ if (set_number(obj, name, n.num, n.den, 1, 0) < 0)
+ return NULL;
+ return o;
}
const AVOption *av_set_int(void *obj, const char *name, int64_t n)
{
- return av_set_number(obj, name, 1, 1, n);
+ const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
+ if (set_number(obj, name, 1, 1, n, 0) < 0)
+ return NULL;
+ return o;
+}
+#endif
+
+int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
+{
+ return set_number(obj, name, 1, 1, val, search_flags);
}
+int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
+{
+ return set_number(obj, name, val, 1, 1, search_flags);
+}
+
+int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
+{
+ return set_number(obj, name, val.num, val.den, 1, search_flags);
+}
+
+#if FF_API_OLD_AVOPTIONS
/**
*
* @param buf a buffer which is used for returning non string values as strings, can be NULL
@@ -234,23 +328,23 @@ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, c
void *dst;
uint8_t *bin;
int len, i;
- if (!o || o->offset<=0)
+ if (!o)
return NULL;
- if (o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len))
+ if (o->type != AV_OPT_TYPE_STRING && (!buf || !buf_len))
return NULL;
dst= ((uint8_t*)obj) + o->offset;
if (o_out) *o_out= o;
switch (o->type) {
- case FF_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break;
- case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break;
- case FF_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
- case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break;
- case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break;
- case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
- case FF_OPT_TYPE_STRING: return *(void**)dst;
- case FF_OPT_TYPE_BINARY:
+ case AV_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break;
+ case AV_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break;
+ case AV_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
+ case AV_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break;
+ case AV_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break;
+ case AV_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
+ case AV_OPT_TYPE_STRING: return *(void**)dst;
+ case AV_OPT_TYPE_BINARY:
len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
if (len >= (buf_len + 1)/2) return NULL;
bin = *(uint8_t**)dst;
@@ -260,40 +354,81 @@ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, c
}
return buf;
}
+#endif
-static int av_get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum)
+int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
{
- const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
- void *dst;
- if (!o || o->offset<=0)
- goto error;
+ void *dst, *target_obj;
+ const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ uint8_t *bin, buf[128];
+ int len, i, ret;
- dst= ((uint8_t*)obj) + o->offset;
+ if (!o || !target_obj)
+ return AVERROR_OPTION_NOT_FOUND;
- if (o_out) *o_out= o;
+ dst = (uint8_t*)target_obj + o->offset;
+ buf[0] = 0;
switch (o->type) {
- case FF_OPT_TYPE_FLAGS: *intnum= *(unsigned int*)dst;return 0;
- case FF_OPT_TYPE_INT: *intnum= *(int *)dst;return 0;
- case FF_OPT_TYPE_INT64: *intnum= *(int64_t*)dst;return 0;
- case FF_OPT_TYPE_FLOAT: *num= *(float *)dst;return 0;
- case FF_OPT_TYPE_DOUBLE: *num= *(double *)dst;return 0;
- case FF_OPT_TYPE_RATIONAL: *intnum= ((AVRational*)dst)->num;
- *den = ((AVRational*)dst)->den;
- return 0;
+ case AV_OPT_TYPE_FLAGS: ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);break;
+ case AV_OPT_TYPE_INT: ret = snprintf(buf, sizeof(buf), "%d" , *(int *)dst);break;
+ case AV_OPT_TYPE_INT64: ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break;
+ case AV_OPT_TYPE_FLOAT: ret = snprintf(buf, sizeof(buf), "%f" , *(float *)dst);break;
+ case AV_OPT_TYPE_DOUBLE: ret = snprintf(buf, sizeof(buf), "%f" , *(double *)dst);break;
+ case AV_OPT_TYPE_RATIONAL: ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
+ case AV_OPT_TYPE_STRING:
+ if (*(uint8_t**)dst)
+ *out_val = av_strdup(*(uint8_t**)dst);
+ else
+ *out_val = av_strdup("");
+ return 0;
+ case AV_OPT_TYPE_BINARY:
+ len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
+ if ((uint64_t)len*2 + 1 > INT_MAX)
+ return AVERROR(EINVAL);
+ if (!(*out_val = av_malloc(len*2 + 1)))
+ return AVERROR(ENOMEM);
+ bin = *(uint8_t**)dst;
+ for (i = 0; i < len; i++)
+ snprintf(*out_val + i*2, 3, "%02X", bin[i]);
+ return 0;
+ default:
+ return AVERROR(EINVAL);
}
+
+ if (ret >= sizeof(buf))
+ return AVERROR(EINVAL);
+ *out_val = av_strdup(buf);
+ return 0;
+}
+
+static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
+ int search_flags)
+{
+ void *dst, *target_obj;
+ const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ if (!o || !target_obj)
+ goto error;
+
+ dst = ((uint8_t*)target_obj) + o->offset;
+
+ if (o_out) *o_out= o;
+
+ return read_number(o, dst, num, den, intnum);
+
error:
*den=*intnum=0;
return -1;
}
+#if FF_API_OLD_AVOPTIONS
double av_get_double(void *obj, const char *name, const AVOption **o_out)
{
int64_t intnum=1;
double num=1;
int den=1;
- if (av_get_number(obj, name, o_out, &num, &den, &intnum) < 0)
+ if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
return NAN;
return num*intnum/den;
}
@@ -304,7 +439,7 @@ AVRational av_get_q(void *obj, const char *name, const AVOption **o_out)
double num=1;
int den=1;
- if (av_get_number(obj, name, o_out, &num, &den, &intnum) < 0)
+ if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
return (AVRational){0, 0};
if (num == 1.0 && (int)intnum == intnum)
return (AVRational){intnum, den};
@@ -318,19 +453,63 @@ int64_t av_get_int(void *obj, const char *name, const AVOption **o_out)
double num=1;
int den=1;
- if (av_get_number(obj, name, o_out, &num, &den, &intnum) < 0)
+ if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
return -1;
return num*intnum/den;
}
+#endif
+
+int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
+{
+ int64_t intnum = 1;
+ double num = 1;
+ int ret, den = 1;
+
+ if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
+ return ret;
+ *out_val = num*intnum/den;
+ return 0;
+}
+
+int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
+{
+ int64_t intnum = 1;
+ double num = 1;
+ int ret, den = 1;
+
+ if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
+ return ret;
+ *out_val = num*intnum/den;
+ return 0;
+}
+
+int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
+{
+ int64_t intnum = 1;
+ double num = 1;
+ int ret, den = 1;
+
+ if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
+ return ret;
+
+ if (num == 1.0 && (int)intnum == intnum)
+ *out_val = (AVRational){intnum, den};
+ else
+ *out_val = av_d2q(num*intnum/den, 1<<24);
+ return 0;
+}
int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
{
- const AVOption *field = av_find_opt(obj, field_name, NULL, 0, 0);
- const AVOption *flag = av_find_opt(obj, flag_name, NULL, 0, 0);
+ const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
+ const AVOption *flag = av_opt_find(obj, flag_name,
+ field ? field->unit : NULL, 0, 0);
+ int64_t res;
- if (!field || !flag || flag->type != FF_OPT_TYPE_CONST)
+ if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
+ av_opt_get_int(obj, field_name, 0, &res) < 0)
return 0;
- return av_get_int(obj, field_name, NULL) & (int) flag->default_val.dbl;
+ return res & (int) flag->default_val.dbl;
}
static void opt_list(void *obj, void *av_log_obj, const char *unit,
@@ -338,7 +517,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
{
const AVOption *opt=NULL;
- while ((opt= av_next_option(obj, opt))) {
+ while ((opt = av_opt_next(obj, opt))) {
if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
continue;
@@ -346,43 +525,43 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
* Don't print anything but CONST's on level two.
* Only print items from the requested unit.
*/
- if (!unit && opt->type==FF_OPT_TYPE_CONST)
+ if (!unit && opt->type==AV_OPT_TYPE_CONST)
continue;
- else if (unit && opt->type!=FF_OPT_TYPE_CONST)
+ else if (unit && opt->type!=AV_OPT_TYPE_CONST)
continue;
- else if (unit && opt->type==FF_OPT_TYPE_CONST && strcmp(unit, opt->unit))
+ else if (unit && opt->type==AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
continue;
- else if (unit && opt->type == FF_OPT_TYPE_CONST)
+ else if (unit && opt->type == AV_OPT_TYPE_CONST)
av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
else
av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name);
switch (opt->type) {
- case FF_OPT_TYPE_FLAGS:
+ case AV_OPT_TYPE_FLAGS:
av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>");
break;
- case FF_OPT_TYPE_INT:
+ case AV_OPT_TYPE_INT:
av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<int>");
break;
- case FF_OPT_TYPE_INT64:
+ case AV_OPT_TYPE_INT64:
av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>");
break;
- case FF_OPT_TYPE_DOUBLE:
+ case AV_OPT_TYPE_DOUBLE:
av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<double>");
break;
- case FF_OPT_TYPE_FLOAT:
+ case AV_OPT_TYPE_FLOAT:
av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<float>");
break;
- case FF_OPT_TYPE_STRING:
+ case AV_OPT_TYPE_STRING:
av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<string>");
break;
- case FF_OPT_TYPE_RATIONAL:
+ case AV_OPT_TYPE_RATIONAL:
av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>");
break;
- case FF_OPT_TYPE_BINARY:
+ case AV_OPT_TYPE_BINARY:
av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<binary>");
break;
- case FF_OPT_TYPE_CONST:
+ case AV_OPT_TYPE_CONST:
default:
av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "");
break;
@@ -396,7 +575,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
if (opt->help)
av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
av_log(av_log_obj, AV_LOG_INFO, "\n");
- if (opt->unit && opt->type != FF_OPT_TYPE_CONST) {
+ if (opt->unit && opt->type != AV_OPT_TYPE_CONST) {
opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
}
}
@@ -414,51 +593,54 @@ int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
return 0;
}
-/** Set the values of the AVCodecContext or AVFormatContext structure.
- * They are set to the defaults specified in the according AVOption options
- * array default_val field.
- *
- * @param s AVCodecContext or AVFormatContext for which the defaults will be set
- */
+void av_opt_set_defaults(void *s)
+{
+#if FF_API_OLD_AVOPTIONS
+ av_opt_set_defaults2(s, 0, 0);
+}
+
void av_opt_set_defaults2(void *s, int mask, int flags)
{
+#endif
const AVOption *opt = NULL;
- while ((opt = av_next_option(s, opt)) != NULL) {
+ while ((opt = av_opt_next(s, opt)) != NULL) {
+#if FF_API_OLD_AVOPTIONS
if ((opt->flags & mask) != flags)
continue;
+#endif
switch (opt->type) {
- case FF_OPT_TYPE_CONST:
+ case AV_OPT_TYPE_CONST:
/* Nothing to be done here */
break;
- case FF_OPT_TYPE_FLAGS:
- case FF_OPT_TYPE_INT: {
+ case AV_OPT_TYPE_FLAGS:
+ case AV_OPT_TYPE_INT: {
int val;
val = opt->default_val.dbl;
- av_set_int(s, opt->name, val);
+ av_opt_set_int(s, opt->name, val, 0);
}
break;
- case FF_OPT_TYPE_INT64:
+ case AV_OPT_TYPE_INT64:
if ((double)(opt->default_val.dbl+0.6) == opt->default_val.dbl)
av_log(s, AV_LOG_DEBUG, "loss of precision in default of %s\n", opt->name);
- av_set_int(s, opt->name, opt->default_val.dbl);
+ av_opt_set_int(s, opt->name, opt->default_val.dbl, 0);
break;
- case FF_OPT_TYPE_DOUBLE:
- case FF_OPT_TYPE_FLOAT: {
+ case AV_OPT_TYPE_DOUBLE:
+ case AV_OPT_TYPE_FLOAT: {
double val;
val = opt->default_val.dbl;
- av_set_double(s, opt->name, val);
+ av_opt_set_double(s, opt->name, val, 0);
}
break;
- case FF_OPT_TYPE_RATIONAL: {
+ case AV_OPT_TYPE_RATIONAL: {
AVRational val;
val = av_d2q(opt->default_val.dbl, INT_MAX);
- av_set_q(s, opt->name, val);
+ av_opt_set_q(s, opt->name, val, 0);
}
break;
- case FF_OPT_TYPE_STRING:
- av_set_string3(s, opt->name, opt->default_val.str, 1, NULL);
+ case AV_OPT_TYPE_STRING:
+ av_opt_set(s, opt->name, opt->default_val.str, 0);
break;
- case FF_OPT_TYPE_BINARY:
+ case AV_OPT_TYPE_BINARY:
/* Cannot set default for binary */
break;
default:
@@ -467,11 +649,6 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
}
}
-void av_opt_set_defaults(void *s)
-{
- av_opt_set_defaults2(s, 0, 0);
-}
-
/**
* Store the value in the field in ctx that is named like key.
* ctx must be an AVClass context, storing is done using AVOptions.
@@ -486,7 +663,7 @@ void av_opt_set_defaults(void *s)
* set, or a negative value corresponding to an AVERROR code in case
* of error:
* AVERROR(EINVAL) if the key/value pair cannot be parsed,
- * the error code issued by av_set_string3() if the key/value pair
+ * the error code issued by av_opt_set() if the key/value pair
* cannot be set
*/
static int parse_key_value_pair(void *ctx, const char **buf,
@@ -507,7 +684,7 @@ static int parse_key_value_pair(void *ctx, const char **buf,
av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", val, key);
- ret = av_set_string3(ctx, key, val, 1, NULL);
+ ret = av_opt_set(ctx, key, val, 0);
if (ret == AVERROR_OPTION_NOT_FOUND)
av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
@@ -521,6 +698,9 @@ int av_set_options_string(void *ctx, const char *opts,
{
int ret, count = 0;
+ if (!opts)
+ return 0;
+
while (*opts) {
if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
return ret;
@@ -536,8 +716,8 @@ int av_set_options_string(void *ctx, const char *opts,
void av_opt_free(void *obj)
{
const AVOption *o = NULL;
- while ((o = av_next_option(obj, o)))
- if (o->type == FF_OPT_TYPE_STRING || o->type == FF_OPT_TYPE_BINARY)
+ while ((o = av_opt_next(obj, o)))
+ if (o->type == AV_OPT_TYPE_STRING || o->type == AV_OPT_TYPE_BINARY)
av_freep((uint8_t *)obj + o->offset);
}
@@ -548,7 +728,7 @@ int av_opt_set_dict(void *obj, AVDictionary **options)
int ret = 0;
while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
- ret = av_set_string3(obj, t->key, t->value, 1, NULL);
+ ret = av_opt_set(obj, t->key, t->value, 0);
if (ret == AVERROR_OPTION_NOT_FOUND)
av_dict_set(&tmp, t->key, t->value, 0);
else if (ret < 0) {
@@ -565,21 +745,60 @@ int av_opt_set_dict(void *obj, AVDictionary **options)
const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
int opt_flags, int search_flags)
{
- AVClass *c = *(AVClass**)obj;
+ return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
+}
+
+const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
+ int opt_flags, int search_flags, void **target_obj)
+{
+ const AVClass *c = *(AVClass**)obj;
const AVOption *o = NULL;
- if (c->opt_find && search_flags & AV_OPT_SEARCH_CHILDREN &&
- (o = c->opt_find(obj, name, unit, opt_flags, search_flags)))
- return o;
+ if (search_flags & AV_OPT_SEARCH_CHILDREN) {
+ if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
+ const AVClass *child = NULL;
+ while (child = av_opt_child_class_next(c, child))
+ if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
+ return o;
+ } else {
+ void *child = NULL;
+ while (child = av_opt_child_next(obj, child))
+ if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
+ return o;
+ }
+ }
- while (o = av_next_option(obj, o)) {
- if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) &&
- (o->flags & opt_flags) == opt_flags)
+ while (o = av_opt_next(obj, o)) {
+ if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
+ ((!unit && o->type != AV_OPT_TYPE_CONST) ||
+ (unit && o->unit && !strcmp(o->unit, unit)))) {
+ if (target_obj) {
+ if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
+ *target_obj = obj;
+ else
+ *target_obj = NULL;
+ }
return o;
+ }
}
return NULL;
}
+void *av_opt_child_next(void *obj, void *prev)
+{
+ const AVClass *c = *(AVClass**)obj;
+ if (c->child_next)
+ return c->child_next(obj, prev);
+ return NULL;
+}
+
+const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
+{
+ if (parent->child_class_next)
+ return parent->child_class_next(prev);
+ return NULL;
+}
+
#ifdef TEST
#undef printf
@@ -601,14 +820,14 @@ typedef struct TestContext
#define TEST_FLAG_MU 04
static const AVOption test_options[]= {
-{"num", "set num", OFFSET(num), FF_OPT_TYPE_INT, 0, 0, 100 },
-{"toggle", "set toggle", OFFSET(toggle), FF_OPT_TYPE_INT, 0, 0, 1 },
-{"rational", "set rational", OFFSET(rational), FF_OPT_TYPE_RATIONAL, 0, 0, 10 },
-{"string", "set string", OFFSET(string), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX },
-{"flags", "set flags", OFFSET(flags), FF_OPT_TYPE_FLAGS, 0, 0, INT_MAX, 0, "flags" },
-{"cool", "set cool flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_COOL, INT_MIN, INT_MAX, 0, "flags" },
-{"lame", "set lame flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_LAME, INT_MIN, INT_MAX, 0, "flags" },
-{"mu", "set mu flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_MU, INT_MIN, INT_MAX, 0, "flags" },
+{"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, {0}, 0, 100 },
+{"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, {0}, 0, 1 },
+{"rational", "set rational", OFFSET(rational), AV_OPT_TYPE_RATIONAL, {0}, 0, 10 },
+{"string", "set string", OFFSET(string), AV_OPT_TYPE_STRING, {0}, CHAR_MIN, CHAR_MAX },
+{"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {0}, 0, INT_MAX, 0, "flags" },
+{"cool", "set cool flag ", 0, AV_OPT_TYPE_CONST, {TEST_FLAG_COOL}, INT_MIN, INT_MAX, 0, "flags" },
+{"lame", "set lame flag ", 0, AV_OPT_TYPE_CONST, {TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0, "flags" },
+{"mu", "set mu flag ", 0, AV_OPT_TYPE_CONST, {TEST_FLAG_MU}, INT_MIN, INT_MAX, 0, "flags" },
{NULL},
};
@@ -653,7 +872,7 @@ int main(void)
};
test_ctx.class = &test_class;
- av_opt_set_defaults2(&test_ctx, 0, 0);
+ av_opt_set_defaults(&test_ctx);
test_ctx.string = av_strdup("default");
av_log_set_level(AV_LOG_DEBUG);
diff --git a/libavutil/opt.h b/libavutil/opt.h
index ce65865..1954940 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -30,9 +30,203 @@
#include "rational.h"
#include "avutil.h"
#include "dict.h"
+#include "log.h"
+
+/**
+ * @defgroup avoptions AVOptions
+ * @ingroup lavu_data
+ * @{
+ * AVOptions provide a generic system to declare options on arbitrary structs
+ * ("objects"). An option can have a help text, a type and a range of possible
+ * values. Options may then be enumerated, read and written to.
+ *
+ * @section avoptions_implement Implementing AVOptions
+ * This section describes how to add AVOptions capabilities to a struct.
+ *
+ * All AVOptions-related information is stored in an AVClass. Therefore
+ * the first member of the struct must be a pointer to an AVClass describing it.
+ * The option field of the AVClass must be set to a NULL-terminated static array
+ * of AVOptions. Each AVOption must have a non-empty name, a type, a default
+ * value and for number-type AVOptions also a range of allowed values. It must
+ * also declare an offset in bytes from the start of the struct, where the field
+ * associated with this AVOption is located. Other fields in the AVOption struct
+ * should also be set when applicable, but are not required.
+ *
+ * The following example illustrates an AVOptions-enabled struct:
+ * @code
+ * typedef struct test_struct {
+ * AVClass *class;
+ * int int_opt;
+ * char *str_opt;
+ * uint8_t *bin_opt;
+ * int bin_len;
+ * } test_struct;
+ *
+ * static const AVOption options[] = {
+ * { "test_int", "This is a test option of int type.", offsetof(test_struct, int_opt),
+ * AV_OPT_TYPE_INT, { -1 }, INT_MIN, INT_MAX },
+ * { "test_str", "This is a test option of string type.", offsetof(test_struct, str_opt),
+ * AV_OPT_TYPE_STRING },
+ * { "test_bin", "This is a test option of binary type.", offsetof(test_struct, bin_opt),
+ * AV_OPT_TYPE_BINARY },
+ * { NULL },
+ * };
+ *
+ * static const AVClass test_class = {
+ * .class_name = "test class",
+ * .item_name = av_default_item_name,
+ * .option = options,
+ * .version = LIBAVUTIL_VERSION_INT,
+ * };
+ * @endcode
+ *
+ * Next, when allocating your struct, you must ensure that the AVClass pointer
+ * is set to the correct value. Then, av_opt_set_defaults() must be called to
+ * initialize defaults. After that the struct is ready to be used with the
+ * AVOptions API.
+ *
+ * When cleaning up, you may use the av_opt_free() function to automatically
+ * free all the allocated string and binary options.
+ *
+ * Continuing with the above example:
+ *
+ * @code
+ * test_struct *alloc_test_struct(void)
+ * {
+ * test_struct *ret = av_malloc(sizeof(*ret));
+ * ret->class = &test_class;
+ * av_opt_set_defaults(ret);
+ * return ret;
+ * }
+ * void free_test_struct(test_struct **foo)
+ * {
+ * av_opt_free(*foo);
+ * av_freep(foo);
+ * }
+ * @endcode
+ *
+ * @subsection avoptions_implement_nesting Nesting
+ * It may happen that an AVOptions-enabled struct contains another
+ * AVOptions-enabled struct as a member (e.g. AVCodecContext in
+ * libavcodec exports generic options, while its priv_data field exports
+ * codec-specific options). In such a case, it is possible to set up the
+ * parent struct to export a child's options. To do that, simply
+ * implement AVClass.child_next() and AVClass.child_class_next() in the
+ * parent struct's AVClass.
+ * Assuming that the test_struct from above now also contains a
+ * child_struct field:
+ *
+ * @code
+ * typedef struct child_struct {
+ * AVClass *class;
+ * int flags_opt;
+ * } child_struct;
+ * static const AVOption child_opts[] = {
+ * { "test_flags", "This is a test option of flags type.",
+ * offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { 0 }, INT_MIN, INT_MAX },
+ * { NULL },
+ * };
+ * static const AVClass child_class = {
+ * .class_name = "child class",
+ * .item_name = av_default_item_name,
+ * .option = child_opts,
+ * .version = LIBAVUTIL_VERSION_INT,
+ * };
+ *
+ * void *child_next(void *obj, void *prev)
+ * {
+ * test_struct *t = obj;
+ * if (!prev && t->child_struct)
+ * return t->child_struct;
+ * return NULL
+ * }
+ * const AVClass child_class_next(const AVClass *prev)
+ * {
+ * return prev ? NULL : &child_class;
+ * }
+ * @endcode
+ * Putting child_next() and child_class_next() as defined above into
+ * test_class will now make child_struct's options accessible through
+ * test_struct (again, proper setup as described above needs to be done on
+ * child_struct right after it is created).
+ *
+ * From the above example it might not be clear why both child_next()
+ * and child_class_next() are needed. The distinction is that child_next()
+ * iterates over actually existing objects, while child_class_next()
+ * iterates over all possible child classes. E.g. if an AVCodecContext
+ * was initialized to use a codec which has private options, then its
+ * child_next() will return AVCodecContext.priv_data and finish
+ * iterating. OTOH child_class_next() on AVCodecContext.av_class will
+ * iterate over all available codecs with private options.
+ *
+ * @subsection avoptions_implement_named_constants Named constants
+ * It is possible to create named constants for options. Simply set the unit
+ * field of the option the constants should apply to to a string and
+ * create the constants themselves as options of type AV_OPT_TYPE_CONST
+ * with their unit field set to the same string.
+ * Their default_val field should contain the value of the named
+ * constant.
+ * For example, to add some named constants for the test_flags option
+ * above, put the following into the child_opts array:
+ * @code
+ * { "test_flags", "This is a test option of flags type.",
+ * offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { 0 }, INT_MIN, INT_MAX, "test_unit" },
+ * { "flag1", "This is a flag with value 16", 0, AV_OPT_TYPE_CONST, { 16 }, 0, 0, "test_unit" },
+ * @endcode
+ *
+ * @section avoptions_use Using AVOptions
+ * This section deals with accessing options in an AVOptions-enabled struct.
+ * Such structs in Libav are e.g. AVCodecContext in libavcodec or
+ * AVFormatContext in libavformat.
+ *
+ * @subsection avoptions_use_examine Examining AVOptions
+ * The basic functions for examining options are av_opt_next(), which iterates
+ * over all options defined for one object, and av_opt_find(), which searches
+ * for an option with the given name.
+ *
+ * The situation is more complicated with nesting. An AVOptions-enabled struct
+ * may have AVOptions-enabled children. Passing the AV_OPT_SEARCH_CHILDREN flag
+ * to av_opt_find() will make the function search children recursively.
+ *
+ * For enumerating there are basically two cases. The first is when you want to
+ * get all options that may potentially exist on the struct and its children
+ * (e.g. when constructing documentation). In that case you should call
+ * av_opt_child_class_next() recursively on the parent struct's AVClass. The
+ * second case is when you have an already initialized struct with all its
+ * children and you want to get all options that can be actually written or read
+ * from it. In that case you should call av_opt_child_next() recursively (and
+ * av_opt_next() on each result).
+ *
+ * @subsection avoptions_use_get_set Reading and writing AVOptions
+ * When setting options, you often have a string read directly from the
+ * user. In such a case, simply passing it to av_opt_set() is enough. For
+ * non-string type options, av_opt_set() will parse the string according to the
+ * option type.
+ *
+ * Similarly av_opt_get() will read any option type and convert it to a string
+ * which will be returned. Do not forget that the string is allocated, so you
+ * have to free it with av_free().
+ *
+ * In some cases it may be more convenient to put all options into an
+ * AVDictionary and call av_opt_set_dict() on it. A specific case of this
+ * are the format/codec open functions in lavf/lavc which take a dictionary
+ * filled with option as a parameter. This allows to set some options
+ * that cannot be set otherwise, since e.g. the input file format is not known
+ * before the file is actually opened.
+ */
enum AVOptionType{
- FF_OPT_TYPE_FLAGS,
+ AV_OPT_TYPE_FLAGS,
+ AV_OPT_TYPE_INT,
+ AV_OPT_TYPE_INT64,
+ AV_OPT_TYPE_DOUBLE,
+ AV_OPT_TYPE_FLOAT,
+ AV_OPT_TYPE_STRING,
+ AV_OPT_TYPE_RATIONAL,
+ AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length
+ AV_OPT_TYPE_CONST = 128,
+#if FF_API_OLD_AVOPTIONS
+ FF_OPT_TYPE_FLAGS = 0,
FF_OPT_TYPE_INT,
FF_OPT_TYPE_INT64,
FF_OPT_TYPE_DOUBLE,
@@ -41,6 +235,7 @@ enum AVOptionType{
FF_OPT_TYPE_RATIONAL,
FF_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length
FF_OPT_TYPE_CONST=128,
+#endif
};
/**
@@ -111,6 +306,7 @@ attribute_deprecated
const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags);
#endif
+#if FF_API_OLD_AVOPTIONS
/**
* Set the field of obj with the given name to value.
*
@@ -129,25 +325,27 @@ const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int m
* similarly, '-' unsets a flag.
* @param[out] o_out if non-NULL put here a pointer to the AVOption
* found
- * @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
+ * @param alloc this parameter is currently ignored
* @return 0 if the value has been set, or an AVERROR code in case of
* error:
* AVERROR_OPTION_NOT_FOUND if no matching option exists
* AVERROR(ERANGE) if the value is out of range
* AVERROR(EINVAL) if the value is not valid
+ * @deprecated use av_opt_set()
*/
+attribute_deprecated
int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out);
-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);
-double av_get_double(void *obj, const char *name, const AVOption **o_out);
-AVRational av_get_q(void *obj, const char *name, const AVOption **o_out);
-int64_t av_get_int(void *obj, const char *name, const AVOption **o_out);
-const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len);
-const AVOption *av_next_option(void *obj, const AVOption *last);
+attribute_deprecated const AVOption *av_set_double(void *obj, const char *name, double n);
+attribute_deprecated const AVOption *av_set_q(void *obj, const char *name, AVRational n);
+attribute_deprecated const AVOption *av_set_int(void *obj, const char *name, int64_t n);
+
+attribute_deprecated double av_get_double(void *obj, const char *name, const AVOption **o_out);
+attribute_deprecated AVRational av_get_q(void *obj, const char *name, const AVOption **o_out);
+attribute_deprecated int64_t av_get_int(void *obj, const char *name, const AVOption **o_out);
+attribute_deprecated const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len);
+attribute_deprecated const AVOption *av_next_option(void *obj, const AVOption *last);
+#endif
/**
* Show the obj options.
@@ -160,8 +358,17 @@ const AVOption *av_next_option(void *obj, const AVOption *last);
*/
int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags);
+/**
+ * Set the values of all AVOption fields to their default values.
+ *
+ * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass)
+ */
void av_opt_set_defaults(void *s);
+
+#if FF_API_OLD_AVOPTIONS
+attribute_deprecated
void av_opt_set_defaults2(void *s, int mask, int flags);
+#endif
/**
* Parse the key/value pairs list in opts. For each key/value pair
@@ -213,8 +420,39 @@ int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
*/
int av_opt_set_dict(void *obj, struct AVDictionary **options);
+/**
+ * @defgroup opt_eval_funcs Evaluating option strings
+ * @{
+ * This group of functions can be used to evaluate option strings
+ * and get numbers out of them. They do the same thing as av_opt_set(),
+ * except the result is written into the caller-supplied pointer.
+ *
+ * @param obj a struct whose first element is a pointer to AVClass.
+ * @param o an option for which the string is to be evaluated.
+ * @param val string to be evaluated.
+ * @param *_out value of the string will be written here.
+ *
+ * @return 0 on success, a negative number on failure.
+ */
+int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int *flags_out);
+int av_opt_eval_int (void *obj, const AVOption *o, const char *val, int *int_out);
+int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t *int64_out);
+int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float *float_out);
+int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double *double_out);
+int av_opt_eval_q (void *obj, const AVOption *o, const char *val, AVRational *q_out);
+/**
+ * @}
+ */
+
#define AV_OPT_SEARCH_CHILDREN 0x0001 /**< Search in possible children of the
given object first. */
+/**
+ * The obj passed to av_opt_find() is fake -- only a double pointer to AVClass
+ * instead of a required pointer to a struct containing AVClass. This is
+ * useful for searching for options without needing to allocate the corresponding
+ * object.
+ */
+#define AV_OPT_SEARCH_FAKE_OBJ 0x0002
/**
* Look for an option in an object. Consider only options which
@@ -222,6 +460,8 @@ int av_opt_set_dict(void *obj, struct AVDictionary **options);
*
* @param[in] obj A pointer to a struct whose first element is a
* pointer to an AVClass.
+ * Alternatively a double pointer to an AVClass, if
+ * AV_OPT_SEARCH_FAKE_OBJ search flag is set.
* @param[in] name The name of the option to look for.
* @param[in] unit When searching for named constants, name of the unit
* it belongs to.
@@ -239,4 +479,113 @@ int av_opt_set_dict(void *obj, struct AVDictionary **options);
const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
int opt_flags, int search_flags);
+/**
+ * Look for an option in an object. Consider only options which
+ * have all the specified flags set.
+ *
+ * @param[in] obj A pointer to a struct whose first element is a
+ * pointer to an AVClass.
+ * Alternatively a double pointer to an AVClass, if
+ * AV_OPT_SEARCH_FAKE_OBJ search flag is set.
+ * @param[in] name The name of the option to look for.
+ * @param[in] unit When searching for named constants, name of the unit
+ * it belongs to.
+ * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG).
+ * @param search_flags A combination of AV_OPT_SEARCH_*.
+ * @param[out] target_obj if non-NULL, an object to which the option belongs will be
+ * written here. It may be different from obj if AV_OPT_SEARCH_CHILDREN is present
+ * in search_flags. This parameter is ignored if search_flags contain
+ * AV_OPT_SEARCH_FAKE_OBJ.
+ *
+ * @return A pointer to the option found, or NULL if no option
+ * was found.
+ */
+const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
+ int opt_flags, int search_flags, void **target_obj);
+
+/**
+ * Iterate over all AVOptions belonging to obj.
+ *
+ * @param obj an AVOptions-enabled struct or a double pointer to an
+ * AVClass describing it.
+ * @param prev result of the previous call to av_opt_next() on this object
+ * or NULL
+ * @return next AVOption or NULL
+ */
+const AVOption *av_opt_next(void *obj, const AVOption *prev);
+
+/**
+ * Iterate over AVOptions-enabled children of obj.
+ *
+ * @param prev result of a previous call to this function or NULL
+ * @return next AVOptions-enabled child or NULL
+ */
+void *av_opt_child_next(void *obj, void *prev);
+
+/**
+ * Iterate over potential AVOptions-enabled children of parent.
+ *
+ * @param prev result of a previous call to this function or NULL
+ * @return AVClass corresponding to next potential child or NULL
+ */
+const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev);
+
+/**
+ * @defgroup opt_set_funcs Option setting functions
+ * @{
+ * Those functions set the field of obj with the given name to value.
+ *
+ * @param[in] obj A struct whose first element is a pointer to an AVClass.
+ * @param[in] name the name of the field to set
+ * @param[in] val The value to set. In case of av_opt_set() if the field is not
+ * of a string type, then the given string is parsed.
+ * SI postfixes and some named scalars are supported.
+ * If the field is of a numeric type, it has to be a numeric or named
+ * scalar. Behavior with more than one scalar and +- infix operators
+ * is undefined.
+ * If the field is of a flags type, it has to be a sequence of numeric
+ * scalars or named flags separated by '+' or '-'. Prefixing a flag
+ * with '+' causes it to be set without affecting the other flags;
+ * similarly, '-' unsets a flag.
+ * @param search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
+ * is passed here, then the option may be set on a child of obj.
+ *
+ * @return 0 if the value has been set, or an AVERROR code in case of
+ * error:
+ * AVERROR_OPTION_NOT_FOUND if no matching option exists
+ * AVERROR(ERANGE) if the value is out of range
+ * AVERROR(EINVAL) if the value is not valid
+ */
+int av_opt_set (void *obj, const char *name, const char *val, int search_flags);
+int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags);
+int av_opt_set_double(void *obj, const char *name, double val, int search_flags);
+int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags);
+/**
+ * @}
+ */
+
+/**
+ * @defgroup opt_get_funcs Option getting functions
+ * @{
+ * Those functions get a value of the option with the given name from an object.
+ *
+ * @param[in] obj a struct whose first element is a pointer to an AVClass.
+ * @param[in] name name of the option to get.
+ * @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
+ * is passed here, then the option may be found in a child of obj.
+ * @param[out] out_val value of the option will be written here
+ * @return 0 on success, a negative error code otherwise
+ */
+/**
+ * @note the returned string will av_malloc()ed and must be av_free()ed by the caller
+ */
+int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val);
+int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val);
+int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val);
+int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val);
+/**
+ * @}
+ * @}
+ */
+
#endif /* AVUTIL_OPT_H */
diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c
index 0272c3e..a1d221b 100644
--- a/libavutil/parseutils.c
+++ b/libavutil/parseutils.c
@@ -21,13 +21,13 @@
* misc parsing utilities
*/
-#include <strings.h>
#include <sys/time.h>
#include <time.h>
#include "avstring.h"
#include "avutil.h"
#include "eval.h"
+#include "log.h"
#include "random_seed.h"
#include "parseutils.h"
@@ -293,7 +293,7 @@ static ColorEntry color_table[] = {
static int color_table_compare(const void *lhs, const void *rhs)
{
- return strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
+ return av_strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
}
#define ALPHA_SEP '@'
@@ -319,7 +319,7 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
len = strlen(color_string2);
rgba_color[3] = 255;
- if (!strcasecmp(color_string2, "random") || !strcasecmp(color_string2, "bikeshed")) {
+ if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) {
int rgba = av_get_random_seed();
rgba_color[0] = rgba >> 24;
rgba_color[1] = rgba >> 16;
@@ -400,10 +400,7 @@ static int date_get_num(const char **pp,
return val;
}
-/* small strptime for ffmpeg */
-static
-const char *small_strptime(const char *p, const char *fmt,
- struct tm *dt)
+static const char *small_strptime(const char *p, const char *fmt, struct tm *dt)
{
int c, val;
@@ -462,10 +459,9 @@ const char *small_strptime(const char *p, const char *fmt,
p++;
}
}
- return p;
}
-static time_t mktimegm(struct tm *tm)
+time_t av_timegm(struct tm *tm)
{
time_t t;
@@ -484,7 +480,7 @@ static time_t mktimegm(struct tm *tm)
return t;
}
-int av_parse_time(int64_t *timeval, const char *datestr, int duration)
+int av_parse_time(int64_t *timeval, const char *timestr, int duration)
{
const char *p;
int64_t t;
@@ -506,19 +502,19 @@ int av_parse_time(int64_t *timeval, const char *datestr, int duration)
#undef time
time_t now = time(0);
- len = strlen(datestr);
+ len = strlen(timestr);
if (len > 0)
- lastch = datestr[len - 1];
+ lastch = timestr[len - 1];
else
lastch = '\0';
is_utc = (lastch == 'z' || lastch == 'Z');
memset(&dt, 0, sizeof(dt));
- p = datestr;
+ p = timestr;
q = NULL;
if (!duration) {
- if (!strncasecmp(datestr, "now", len)) {
+ if (!av_strncasecmp(timestr, "now", len)) {
*timeval = (int64_t) now * 1000000;
return 0;
}
@@ -555,15 +551,15 @@ int av_parse_time(int64_t *timeval, const char *datestr, int duration)
}
}
} else {
- /* parse datestr as a duration */
+ /* parse timestr as a duration */
if (p[0] == '-') {
negative = 1;
++p;
}
- /* parse datestr as HH:MM:SS */
+ /* parse timestr as HH:MM:SS */
q = small_strptime(p, time_fmt[0], &dt);
if (!q) {
- /* parse datestr as S+ */
+ /* parse timestr as S+ */
dt.tm_sec = strtol(p, (char **)&q, 10);
if (q == p) {
/* the parsing didn't succeed */
@@ -586,7 +582,7 @@ int av_parse_time(int64_t *timeval, const char *datestr, int duration)
} else {
dt.tm_isdst = -1; /* unknown */
if (is_utc) {
- t = mktimegm(&dt);
+ t = av_timegm(&dt);
} else {
t = mktime(&dt);
}
diff --git a/libavutil/parseutils.h b/libavutil/parseutils.h
index befbbb5..0844abb 100644
--- a/libavutil/parseutils.h
+++ b/libavutil/parseutils.h
@@ -19,6 +19,8 @@
#ifndef AVUTIL_PARSEUTILS_H
#define AVUTIL_PARSEUTILS_H
+#include <time.h>
+
#include "rational.h"
/**
@@ -73,7 +75,7 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
void *log_ctx);
/**
- * Parses timestr and returns in *time a corresponding number of
+ * Parse timestr and return in *time a corresponding number of
* microseconds.
*
* @param timeval puts here the number of microseconds corresponding
@@ -83,7 +85,7 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
* January, 1970 up to the time of the parsed date. If timestr cannot
* be successfully parsed, set *time to INT64_MIN.
- * @param datestr a string representing a date or a duration.
+ * @param timestr a string representing a date or a duration.
* - If a date the syntax is:
* @code
* [{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH[:MM[:SS[.m...]]]}|{HH[MM[SS[.m...]]]}}[Z]
@@ -114,4 +116,9 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration);
*/
int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info);
+/**
+ * Convert the decomposed UTC time in tm to a time_t value.
+ */
+time_t av_timegm(struct tm *tm);
+
#endif /* AVUTIL_PARSEUTILS_H */
diff --git a/libavutil/pca.c b/libavutil/pca.c
deleted file mode 100644
index 56bf707..0000000
--- a/libavutil/pca.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * principal component analysis (PCA)
- * Copyright (c) 2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * principal component analysis (PCA)
- */
-
-#include "common.h"
-#include "pca.h"
-
-typedef struct PCA{
- int count;
- int n;
- double *covariance;
- double *mean;
-}PCA;
-
-PCA *ff_pca_init(int n){
- PCA *pca;
- if(n<=0)
- return NULL;
-
- pca= av_mallocz(sizeof(PCA));
- pca->n= n;
- pca->count=0;
- pca->covariance= av_mallocz(sizeof(double)*n*n);
- pca->mean= av_mallocz(sizeof(double)*n);
-
- return pca;
-}
-
-void ff_pca_free(PCA *pca){
- av_freep(&pca->covariance);
- av_freep(&pca->mean);
- av_free(pca);
-}
-
-void ff_pca_add(PCA *pca, double *v){
- int i, j;
- const int n= pca->n;
-
- for(i=0; i<n; i++){
- pca->mean[i] += v[i];
- for(j=i; j<n; j++)
- pca->covariance[j + i*n] += v[i]*v[j];
- }
- pca->count++;
-}
-
-int ff_pca(PCA *pca, double *eigenvector, double *eigenvalue){
- int i, j, pass;
- int k=0;
- const int n= pca->n;
- double z[n];
-
- memset(eigenvector, 0, sizeof(double)*n*n);
-
- for(j=0; j<n; j++){
- pca->mean[j] /= pca->count;
- eigenvector[j + j*n] = 1.0;
- for(i=0; i<=j; i++){
- pca->covariance[j + i*n] /= pca->count;
- pca->covariance[j + i*n] -= pca->mean[i] * pca->mean[j];
- pca->covariance[i + j*n] = pca->covariance[j + i*n];
- }
- eigenvalue[j]= pca->covariance[j + j*n];
- z[j]= 0;
- }
-
- for(pass=0; pass < 50; pass++){
- double sum=0;
-
- for(i=0; i<n; i++)
- for(j=i+1; j<n; j++)
- sum += fabs(pca->covariance[j + i*n]);
-
- if(sum == 0){
- for(i=0; i<n; i++){
- double maxvalue= -1;
- for(j=i; j<n; j++){
- if(eigenvalue[j] > maxvalue){
- maxvalue= eigenvalue[j];
- k= j;
- }
- }
- eigenvalue[k]= eigenvalue[i];
- eigenvalue[i]= maxvalue;
- for(j=0; j<n; j++){
- double tmp= eigenvector[k + j*n];
- eigenvector[k + j*n]= eigenvector[i + j*n];
- eigenvector[i + j*n]= tmp;
- }
- }
- return pass;
- }
-
- for(i=0; i<n; i++){
- for(j=i+1; j<n; j++){
- double covar= pca->covariance[j + i*n];
- double t,c,s,tau,theta, h;
-
- if(pass < 3 && fabs(covar) < sum / (5*n*n)) //FIXME why pass < 3
- continue;
- if(fabs(covar) == 0.0) //FIXME should not be needed
- continue;
- if(pass >=3 && fabs((eigenvalue[j]+z[j])/covar) > (1LL<<32) && fabs((eigenvalue[i]+z[i])/covar) > (1LL<<32)){
- pca->covariance[j + i*n]=0.0;
- continue;
- }
-
- h= (eigenvalue[j]+z[j]) - (eigenvalue[i]+z[i]);
- theta=0.5*h/covar;
- t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
- if(theta < 0.0) t = -t;
-
- c=1.0/sqrt(1+t*t);
- s=t*c;
- tau=s/(1.0+c);
- z[i] -= t*covar;
- z[j] += t*covar;
-
-#define ROTATE(a,i,j,k,l) {\
- double g=a[j + i*n];\
- double h=a[l + k*n];\
- a[j + i*n]=g-s*(h+g*tau);\
- a[l + k*n]=h+s*(g-h*tau); }
- for(k=0; k<n; k++) {
- if(k!=i && k!=j){
- ROTATE(pca->covariance,FFMIN(k,i),FFMAX(k,i),FFMIN(k,j),FFMAX(k,j))
- }
- ROTATE(eigenvector,k,i,k,j)
- }
- pca->covariance[j + i*n]=0.0;
- }
- }
- for (i=0; i<n; i++) {
- eigenvalue[i] += z[i];
- z[i]=0.0;
- }
- }
-
- return -1;
-}
-
-#ifdef TEST
-
-#undef printf
-#include <stdio.h>
-#include <stdlib.h>
-#include "lfg.h"
-
-int main(void){
- PCA *pca;
- int i, j, k;
-#define LEN 8
- double eigenvector[LEN*LEN];
- double eigenvalue[LEN];
- AVLFG prng;
-
- av_lfg_init(&prng, 1);
-
- pca= ff_pca_init(LEN);
-
- for(i=0; i<9000000; i++){
- double v[2*LEN+100];
- double sum=0;
- int pos = av_lfg_get(&prng) % LEN;
- int v2 = av_lfg_get(&prng) % 101 - 50;
- v[0] = av_lfg_get(&prng) % 101 - 50;
- for(j=1; j<8; j++){
- if(j<=pos) v[j]= v[0];
- else v[j]= v2;
- sum += v[j];
- }
-/* for(j=0; j<LEN; j++){
- v[j] -= v[pos];
- }*/
-// sum += av_lfg_get(&prng) % 10;
-/* for(j=0; j<LEN; j++){
- v[j] -= sum/LEN;
- }*/
-// lbt1(v+100,v+100,LEN);
- ff_pca_add(pca, v);
- }
-
-
- ff_pca(pca, eigenvector, eigenvalue);
- for(i=0; i<LEN; i++){
- pca->count= 1;
- pca->mean[i]= 0;
-
-// (0.5^|x|)^2 = 0.5^2|x| = 0.25^|x|
-
-
-// pca.covariance[i + i*LEN]= pow(0.5, fabs
- for(j=i; j<LEN; j++){
- printf("%f ", pca->covariance[i + j*LEN]);
- }
- printf("\n");
- }
-
- for(i=0; i<LEN; i++){
- double v[LEN];
- double error=0;
- memset(v, 0, sizeof(v));
- for(j=0; j<LEN; j++){
- for(k=0; k<LEN; k++){
- v[j] += pca->covariance[FFMIN(k,j) + FFMAX(k,j)*LEN] * eigenvector[i + k*LEN];
- }
- v[j] /= eigenvalue[i];
- error += fabs(v[j] - eigenvector[i + j*LEN]);
- }
- printf("%f ", error);
- }
- printf("\n");
-
- for(i=0; i<LEN; i++){
- for(j=0; j<LEN; j++){
- printf("%9.6f ", eigenvector[i + j*LEN]);
- }
- printf(" %9.1f %f\n", eigenvalue[i], eigenvalue[i]/eigenvalue[0]);
- }
-
- return 0;
-}
-#endif
diff --git a/libavutil/pca.h b/libavutil/pca.h
deleted file mode 100644
index 436f122..0000000
--- a/libavutil/pca.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * principal component analysis (PCA)
- * Copyright (c) 2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * principal component analysis (PCA)
- */
-
-#ifndef AVUTIL_PCA_H
-#define AVUTIL_PCA_H
-
-struct PCA *ff_pca_init(int n);
-void ff_pca_free(struct PCA *pca);
-void ff_pca_add(struct PCA *pca, double *v);
-int ff_pca(struct PCA *pca, double *eigenvector, double *eigenvalue);
-
-#endif /* AVUTIL_PCA_H */
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index c70a413..6e1f23b 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -27,45 +27,46 @@
#include "intreadwrite.h"
void av_read_image_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4],
- const AVPixFmtDescriptor *desc, int x, int y, int c, int w, int read_pal_component)
+ const AVPixFmtDescriptor *desc, int x, int y, int c, int w,
+ int read_pal_component)
{
- AVComponentDescriptor comp= desc->comp[c];
- int plane= comp.plane;
- int depth= comp.depth_minus1+1;
- int mask = (1<<depth)-1;
- int shift= comp.shift;
- int step = comp.step_minus1+1;
- int flags= desc->flags;
+ AVComponentDescriptor comp = desc->comp[c];
+ int plane = comp.plane;
+ int depth = comp.depth_minus1 + 1;
+ int mask = (1 << depth) - 1;
+ int shift = comp.shift;
+ int step = comp.step_minus1 + 1;
+ int flags = desc->flags;
- if (flags & PIX_FMT_BITSTREAM){
- int skip = x*step + comp.offset_plus1-1;
- const uint8_t *p = data[plane] + y*linesize[plane] + (skip>>3);
- int shift = 8 - depth - (skip&7);
+ if (flags & PIX_FMT_BITSTREAM) {
+ int skip = x * step + comp.offset_plus1 - 1;
+ const uint8_t *p = data[plane] + y * linesize[plane] + (skip >> 3);
+ int shift = 8 - depth - (skip & 7);
- while(w--){
+ while (w--) {
int val = (*p >> shift) & mask;
- if(read_pal_component)
- val= data[1][4*val + c];
+ if (read_pal_component)
+ val = data[1][4*val + c];
shift -= step;
- p -= shift>>3;
+ p -= shift >> 3;
shift &= 7;
- *dst++= val;
+ *dst++ = val;
}
} else {
- const uint8_t *p = data[plane]+ y*linesize[plane] + x*step + comp.offset_plus1-1;
+ const uint8_t *p = data[plane] + y * linesize[plane] + x * step + comp.offset_plus1 - 1;
int is_8bit = shift + depth <= 8;
if (is_8bit)
p += !!(flags & PIX_FMT_BE);
- while(w--){
+ while (w--) {
int val = is_8bit ? *p :
flags & PIX_FMT_BE ? AV_RB16(p) : AV_RL16(p);
- val = (val>>shift) & mask;
- if(read_pal_component)
- val= data[1][4*val + c];
- p+= step;
- *dst++= val;
+ val = (val >> shift) & mask;
+ if (read_pal_component)
+ val = data[1][4 * val + c];
+ p += step;
+ *dst++ = val;
}
}
}
@@ -75,41 +76,41 @@ void av_write_image_line(const uint16_t *src, uint8_t *data[4], const int linesi
{
AVComponentDescriptor comp = desc->comp[c];
int plane = comp.plane;
- int depth = comp.depth_minus1+1;
- int step = comp.step_minus1+1;
+ int depth = comp.depth_minus1 + 1;
+ int step = comp.step_minus1 + 1;
int flags = desc->flags;
if (flags & PIX_FMT_BITSTREAM) {
- int skip = x*step + comp.offset_plus1-1;
- uint8_t *p = data[plane] + y*linesize[plane] + (skip>>3);
- int shift = 8 - depth - (skip&7);
+ int skip = x * step + comp.offset_plus1 - 1;
+ uint8_t *p = data[plane] + y * linesize[plane] + (skip >> 3);
+ int shift = 8 - depth - (skip & 7);
while (w--) {
*p |= *src++ << shift;
shift -= step;
- p -= shift>>3;
+ p -= shift >> 3;
shift &= 7;
}
} else {
int shift = comp.shift;
- uint8_t *p = data[plane]+ y*linesize[plane] + x*step + comp.offset_plus1-1;
+ uint8_t *p = data[plane] + y * linesize[plane] + x * step + comp.offset_plus1 - 1;
if (shift + depth <= 8) {
p += !!(flags & PIX_FMT_BE);
while (w--) {
- *p |= (*src++<<shift);
+ *p |= (*src++ << shift);
p += step;
}
} else {
while (w--) {
if (flags & PIX_FMT_BE) {
- uint16_t val = AV_RB16(p) | (*src++<<shift);
+ uint16_t val = AV_RB16(p) | (*src++ << shift);
AV_WB16(p, val);
} else {
- uint16_t val = AV_RL16(p) | (*src++<<shift);
+ uint16_t val = AV_RL16(p) | (*src++ << shift);
AV_WL16(p, val);
}
- p+= step;
+ p += step;
}
}
}
@@ -118,164 +119,173 @@ void av_write_image_line(const uint16_t *src, uint8_t *data[4], const int linesi
const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = {
[PIX_FMT_YUV420P] = {
.name = "yuv420p",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 0, 1, 0, 7 }, /* U */
+ { 2, 0, 1, 0, 7 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUYV422] = {
.name = "yuyv422",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,7}, /* Y */
- {0,3,2,0,7}, /* U */
- {0,3,4,0,7}, /* V */
+ { 0, 1, 1, 0, 7 }, /* Y */
+ { 0, 3, 2, 0, 7 }, /* U */
+ { 0, 3, 4, 0, 7 }, /* V */
},
},
[PIX_FMT_RGB24] = {
.name = "rgb24",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,2,1,0,7}, /* R */
- {0,2,2,0,7}, /* G */
- {0,2,3,0,7}, /* B */
+ { 0, 2, 1, 0, 7 }, /* R */
+ { 0, 2, 2, 0, 7 }, /* G */
+ { 0, 2, 3, 0, 7 }, /* B */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_BGR24] = {
.name = "bgr24",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,2,1,0,7}, /* B */
- {0,2,2,0,7}, /* G */
- {0,2,3,0,7}, /* R */
+ { 0, 2, 1, 0, 7 }, /* B */
+ { 0, 2, 2, 0, 7 }, /* G */
+ { 0, 2, 3, 0, 7 }, /* R */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_YUV422P] = {
.name = "yuv422p",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 0, 1, 0, 7 }, /* U */
+ { 2, 0, 1, 0, 7 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV444P] = {
.name = "yuv444p",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 0, 1, 0, 7 }, /* U */
+ { 2, 0, 1, 0, 7 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV410P] = {
.name = "yuv410p",
- .nb_components= 3,
- .log2_chroma_w= 2,
- .log2_chroma_h= 2,
+ .nb_components = 3,
+ .log2_chroma_w = 2,
+ .log2_chroma_h = 2,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 0, 1, 0, 7 }, /* U */
+ { 2, 0, 1, 0, 7 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV411P] = {
.name = "yuv411p",
- .nb_components= 3,
- .log2_chroma_w= 2,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 2,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 0, 1, 0, 7 }, /* U */
+ { 2, 0, 1, 0, 7 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_GRAY8] = {
.name = "gray",
- .nb_components= 1,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 1,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,0,7}, /* Y */
+ { 0, 0, 1, 0, 7 }, /* Y */
},
- .flags = PIX_FMT_PAL,
},
[PIX_FMT_MONOWHITE] = {
.name = "monow",
- .nb_components= 1,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 1,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,0,0}, /* Y */
+ { 0, 0, 1, 0, 0 }, /* Y */
},
.flags = PIX_FMT_BITSTREAM,
},
[PIX_FMT_MONOBLACK] = {
.name = "monob",
- .nb_components= 1,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 1,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,7,0}, /* Y */
+ { 0, 0, 1, 7, 0 }, /* Y */
},
.flags = PIX_FMT_BITSTREAM,
},
[PIX_FMT_PAL8] = {
.name = "pal8",
- .nb_components= 1,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 1,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,0,7},
+ { 0, 0, 1, 0, 7 },
},
.flags = PIX_FMT_PAL,
},
[PIX_FMT_YUVJ420P] = {
.name = "yuvj420p",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 0, 1, 0, 7 }, /* U */
+ { 2, 0, 1, 0, 7 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUVJ422P] = {
.name = "yuvj422p",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 0, 1, 0, 7 }, /* U */
+ { 2, 0, 1, 0, 7 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUVJ444P] = {
.name = "yuvj444p",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
+ {0, 0, 1, 0, 7}, /* Y */
+ {1, 0, 1, 0, 7}, /* U */
+ {2, 0, 1, 0, 7}, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_XVMC_MPEG2_MC] = {
.name = "xvmcmc",
@@ -287,220 +297,229 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = {
},
[PIX_FMT_UYVY422] = {
.name = "uyvy422",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,2,0,7}, /* Y */
- {0,3,1,0,7}, /* U */
- {0,3,3,0,7}, /* V */
+ { 0, 1, 2, 0, 7 }, /* Y */
+ { 0, 3, 1, 0, 7 }, /* U */
+ { 0, 3, 3, 0, 7 }, /* V */
},
},
[PIX_FMT_UYYVYY411] = {
.name = "uyyvyy411",
- .nb_components= 3,
- .log2_chroma_w= 2,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 2,
+ .log2_chroma_h = 0,
.comp = {
- {0,3,2,0,7}, /* Y */
- {0,5,1,0,7}, /* U */
- {0,5,4,0,7}, /* V */
+ { 0, 3, 2, 0, 7 }, /* Y */
+ { 0, 5, 1, 0, 7 }, /* U */
+ { 0, 5, 4, 0, 7 }, /* V */
},
},
[PIX_FMT_BGR8] = {
.name = "bgr8",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,6,1}, /* B */
- {0,0,1,3,2}, /* G */
- {0,0,1,0,2}, /* R */
+ { 0, 0, 1, 6, 1 }, /* B */
+ { 0, 0, 1, 3, 2 }, /* G */
+ { 0, 0, 1, 0, 2 }, /* R */
},
- .flags = PIX_FMT_PAL,
+ .flags = PIX_FMT_PAL | PIX_FMT_RGB,
},
[PIX_FMT_BGR4] = {
.name = "bgr4",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,3,1,0,0}, /* B */
- {0,3,2,0,1}, /* G */
- {0,3,4,0,0}, /* R */
+ { 0, 3, 1, 0, 0 }, /* B */
+ { 0, 3, 2, 0, 1 }, /* G */
+ { 0, 3, 4, 0, 0 }, /* R */
},
- .flags = PIX_FMT_BITSTREAM,
+ .flags = PIX_FMT_BITSTREAM | PIX_FMT_RGB,
},
[PIX_FMT_BGR4_BYTE] = {
.name = "bgr4_byte",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,3,0}, /* B */
- {0,0,1,1,1}, /* G */
- {0,0,1,0,0}, /* R */
+ { 0, 0, 1, 3, 0 }, /* B */
+ { 0, 0, 1, 1, 1 }, /* G */
+ { 0, 0, 1, 0, 0 }, /* R */
},
- .flags = PIX_FMT_PAL,
+ .flags = PIX_FMT_PAL | PIX_FMT_RGB,
},
[PIX_FMT_RGB8] = {
.name = "rgb8",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,6,1}, /* R */
- {0,0,1,3,2}, /* G */
- {0,0,1,0,2}, /* B */
+ { 0, 0, 1, 6, 1 }, /* R */
+ { 0, 0, 1, 3, 2 }, /* G */
+ { 0, 0, 1, 0, 2 }, /* B */
},
- .flags = PIX_FMT_PAL,
+ .flags = PIX_FMT_PAL | PIX_FMT_RGB,
},
[PIX_FMT_RGB4] = {
.name = "rgb4",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,3,1,0,0}, /* R */
- {0,3,2,0,1}, /* G */
- {0,3,4,0,0}, /* B */
+ { 0, 3, 1, 0, 0 }, /* R */
+ { 0, 3, 2, 0, 1 }, /* G */
+ { 0, 3, 4, 0, 0 }, /* B */
},
- .flags = PIX_FMT_BITSTREAM,
+ .flags = PIX_FMT_BITSTREAM | PIX_FMT_RGB,
},
[PIX_FMT_RGB4_BYTE] = {
.name = "rgb4_byte",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,0,1,3,0}, /* R */
- {0,0,1,1,1}, /* G */
- {0,0,1,0,0}, /* B */
+ { 0, 0, 1, 3, 0 }, /* R */
+ { 0, 0, 1, 1, 1 }, /* G */
+ { 0, 0, 1, 0, 0 }, /* B */
},
- .flags = PIX_FMT_PAL,
+ .flags = PIX_FMT_PAL | PIX_FMT_RGB,
},
[PIX_FMT_NV12] = {
.name = "nv12",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,1,1,0,7}, /* U */
- {1,1,2,0,7}, /* V */
+ { 0,0,1,0,7 }, /* Y */
+ { 1,1,1,0,7 }, /* U */
+ { 1,1,2,0,7 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_NV21] = {
.name = "nv21",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,1,1,0,7}, /* V */
- {1,1,2,0,7}, /* U */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 1, 1, 0, 7 }, /* V */
+ { 1, 1, 2, 0, 7 }, /* U */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_ARGB] = {
.name = "argb",
- .nb_components= 4,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 4,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,3,1,0,7}, /* A */
- {0,3,2,0,7}, /* R */
- {0,3,3,0,7}, /* G */
- {0,3,4,0,7}, /* B */
+ { 0, 3, 1, 0, 7 }, /* A */
+ { 0, 3, 2, 0, 7 }, /* R */
+ { 0, 3, 3, 0, 7 }, /* G */
+ { 0, 3, 4, 0, 7 }, /* B */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_RGBA] = {
.name = "rgba",
- .nb_components= 4,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 4,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,3,1,0,7}, /* R */
- {0,3,2,0,7}, /* G */
- {0,3,3,0,7}, /* B */
- {0,3,4,0,7}, /* A */
+ { 0, 3, 1, 0, 7 }, /* R */
+ { 0, 3, 2, 0, 7 }, /* G */
+ { 0, 3, 3, 0, 7 }, /* B */
+ { 0, 3, 4, 0, 7 }, /* A */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_ABGR] = {
.name = "abgr",
- .nb_components= 4,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 4,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,3,1,0,7}, /* A */
- {0,3,2,0,7}, /* B */
- {0,3,3,0,7}, /* G */
- {0,3,4,0,7}, /* R */
+ { 0, 3, 1, 0, 7 }, /* A */
+ { 0, 3, 2, 0, 7 }, /* B */
+ { 0, 3, 3, 0, 7 }, /* G */
+ { 0, 3, 4, 0, 7 }, /* R */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_BGRA] = {
.name = "bgra",
- .nb_components= 4,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 4,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,3,1,0,7}, /* B */
- {0,3,2,0,7}, /* G */
- {0,3,3,0,7}, /* R */
- {0,3,4,0,7}, /* A */
+ { 0, 3, 1, 0, 7 }, /* B */
+ { 0, 3, 2, 0, 7 }, /* G */
+ { 0, 3, 3, 0, 7 }, /* R */
+ { 0, 3, 4, 0, 7 }, /* A */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_GRAY16BE] = {
.name = "gray16be",
- .nb_components= 1,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 1,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,15}, /* Y */
+ { 0, 1, 1, 0, 15 }, /* Y */
},
.flags = PIX_FMT_BE,
},
[PIX_FMT_GRAY16LE] = {
.name = "gray16le",
- .nb_components= 1,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 1,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,15}, /* Y */
+ { 0, 1, 1, 0, 15 }, /* Y */
},
},
[PIX_FMT_YUV440P] = {
.name = "yuv440p",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 1,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 0, 1, 0, 7 }, /* U */
+ { 2, 0, 1, 0, 7 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUVJ440P] = {
.name = "yuvj440p",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 1,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 0, 1, 0, 7 }, /* U */
+ { 2, 0, 1, 0, 7 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUVA420P] = {
.name = "yuva420p",
- .nb_components= 4,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 4,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,0,1,0,7}, /* Y */
- {1,0,1,0,7}, /* U */
- {2,0,1,0,7}, /* V */
- {3,0,1,0,7}, /* A */
+ { 0, 0, 1, 0, 7 }, /* Y */
+ { 1, 0, 1, 0, 7 }, /* U */
+ { 2, 0, 1, 0, 7 }, /* V */
+ { 3, 0, 1, 0, 7 }, /* A */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_VDPAU_H264] = {
.name = "vdpau_h264",
@@ -540,187 +559,195 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = {
},
[PIX_FMT_RGB48BE] = {
.name = "rgb48be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,5,1,0,15}, /* R */
- {0,5,3,0,15}, /* G */
- {0,5,5,0,15}, /* B */
+ { 0, 5, 1, 0, 15 }, /* R */
+ { 0, 5, 3, 0, 15 }, /* G */
+ { 0, 5, 5, 0, 15 }, /* B */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_RGB | PIX_FMT_BE,
},
[PIX_FMT_RGB48LE] = {
.name = "rgb48le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,5,1,0,15}, /* R */
- {0,5,3,0,15}, /* G */
- {0,5,5,0,15}, /* B */
+ { 0, 5, 1, 0, 15 }, /* R */
+ { 0, 5, 3, 0, 15 }, /* G */
+ { 0, 5, 5, 0, 15 }, /* B */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_RGB565BE] = {
.name = "rgb565be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,0,3,4}, /* R */
- {0,1,1,5,5}, /* G */
- {0,1,1,0,4}, /* B */
+ { 0, 1, 0, 3, 4 }, /* R */
+ { 0, 1, 1, 5, 5 }, /* G */
+ { 0, 1, 1, 0, 4 }, /* B */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_RGB,
},
[PIX_FMT_RGB565LE] = {
.name = "rgb565le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,2,3,4}, /* R */
- {0,1,1,5,5}, /* G */
- {0,1,1,0,4}, /* B */
+ { 0, 1, 2, 3, 4 }, /* R */
+ { 0, 1, 1, 5, 5 }, /* G */
+ { 0, 1, 1, 0, 4 }, /* B */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_RGB555BE] = {
.name = "rgb555be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,0,2,4}, /* R */
- {0,1,1,5,4}, /* G */
- {0,1,1,0,4}, /* B */
+ { 0, 1, 0, 2, 4 }, /* R */
+ { 0, 1, 1, 5, 4 }, /* G */
+ { 0, 1, 1, 0, 4 }, /* B */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_RGB,
},
[PIX_FMT_RGB555LE] = {
.name = "rgb555le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,2,2,4}, /* R */
- {0,1,1,5,4}, /* G */
- {0,1,1,0,4}, /* B */
+ { 0, 1, 2, 2, 4 }, /* R */
+ { 0, 1, 1, 5, 4 }, /* G */
+ { 0, 1, 1, 0, 4 }, /* B */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_RGB444BE] = {
.name = "rgb444be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,0,0,3}, /* R */
- {0,1,1,4,3}, /* G */
- {0,1,1,0,3}, /* B */
+ { 0, 1, 0, 0, 3 }, /* R */
+ { 0, 1, 1, 4, 3 }, /* G */
+ { 0, 1, 1, 0, 3 }, /* B */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_RGB,
},
[PIX_FMT_RGB444LE] = {
.name = "rgb444le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,2,0,3}, /* R */
- {0,1,1,4,3}, /* G */
- {0,1,1,0,3}, /* B */
+ { 0, 1, 2, 0, 3 }, /* R */
+ { 0, 1, 1, 4, 3 }, /* G */
+ { 0, 1, 1, 0, 3 }, /* B */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_BGR48BE] = {
.name = "bgr48be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,5,1,0,15}, /* B */
- {0,5,3,0,15}, /* G */
- {0,5,5,0,15}, /* R */
+ { 0, 5, 1, 0, 15 }, /* B */
+ { 0, 5, 3, 0, 15 }, /* G */
+ { 0, 5, 5, 0, 15 }, /* R */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_RGB,
},
[PIX_FMT_BGR48LE] = {
.name = "bgr48le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,5,1,0,15}, /* B */
- {0,5,3,0,15}, /* G */
- {0,5,5,0,15}, /* R */
+ { 0, 5, 1, 0, 15 }, /* B */
+ { 0, 5, 3, 0, 15 }, /* G */
+ { 0, 5, 5, 0, 15 }, /* R */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_BGR565BE] = {
.name = "bgr565be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,0,3,4}, /* B */
- {0,1,1,5,5}, /* G */
- {0,1,1,0,4}, /* R */
+ { 0, 1, 0, 3, 4 }, /* B */
+ { 0, 1, 1, 5, 5 }, /* G */
+ { 0, 1, 1, 0, 4 }, /* R */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_RGB,
},
[PIX_FMT_BGR565LE] = {
.name = "bgr565le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,2,3,4}, /* B */
- {0,1,1,5,5}, /* G */
- {0,1,1,0,4}, /* R */
+ { 0, 1, 2, 3, 4 }, /* B */
+ { 0, 1, 1, 5, 5 }, /* G */
+ { 0, 1, 1, 0, 4 }, /* R */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_BGR555BE] = {
.name = "bgr555be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,0,2,4}, /* B */
- {0,1,1,5,4}, /* G */
- {0,1,1,0,4}, /* R */
+ { 0, 1, 0, 2, 4 }, /* B */
+ { 0, 1, 1, 5, 4 }, /* G */
+ { 0, 1, 1, 0, 4 }, /* R */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_RGB,
},
[PIX_FMT_BGR555LE] = {
.name = "bgr555le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,2,2,4}, /* B */
- {0,1,1,5,4}, /* G */
- {0,1,1,0,4}, /* R */
+ { 0, 1, 2, 2, 4 }, /* B */
+ { 0, 1, 1, 5, 4 }, /* G */
+ { 0, 1, 1, 0, 4 }, /* R */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_BGR444BE] = {
.name = "bgr444be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,0,0,3}, /* B */
- {0,1,1,4,3}, /* G */
- {0,1,1,0,3}, /* R */
+ { 0, 1, 0, 0, 3 }, /* B */
+ { 0, 1, 1, 4, 3 }, /* G */
+ { 0, 1, 1, 0, 3 }, /* R */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_RGB,
},
[PIX_FMT_BGR444LE] = {
.name = "bgr444le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,2,0,3}, /* B */
- {0,1,1,4,3}, /* G */
- {0,1,1,0,3}, /* R */
+ { 0, 1, 2, 0, 3 }, /* B */
+ { 0, 1, 1, 4, 3 }, /* G */
+ { 0, 1, 1, 0, 3 }, /* R */
},
+ .flags = PIX_FMT_RGB,
},
[PIX_FMT_VAAPI_MOCO] = {
.name = "vaapi_moco",
@@ -740,189 +767,227 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = {
.log2_chroma_h = 1,
.flags = PIX_FMT_HWACCEL,
},
+ [PIX_FMT_VDA_VLD] = {
+ .name = "vda_vld",
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
+ .flags = PIX_FMT_HWACCEL,
+ },
[PIX_FMT_YUV420P9LE] = {
.name = "yuv420p9le",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,1,1,0,8}, /* Y */
- {1,1,1,0,8}, /* U */
- {2,1,1,0,8}, /* V */
+ { 0, 1, 1, 0, 8 }, /* Y */
+ { 1, 1, 1, 0, 8 }, /* U */
+ { 2, 1, 1, 0, 8 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV420P9BE] = {
.name = "yuv420p9be",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,1,1,0,8}, /* Y */
- {1,1,1,0,8}, /* U */
- {2,1,1,0,8}, /* V */
+ { 0, 1, 1, 0, 8 }, /* Y */
+ { 1, 1, 1, 0, 8 }, /* U */
+ { 2, 1, 1, 0, 8 }, /* V */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
},
[PIX_FMT_YUV420P10LE] = {
.name = "yuv420p10le",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,1,1,0,9}, /* Y */
- {1,1,1,0,9}, /* U */
- {2,1,1,0,9}, /* V */
+ { 0, 1, 1, 0, 9 }, /* Y */
+ { 1, 1, 1, 0, 9 }, /* U */
+ { 2, 1, 1, 0, 9 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV420P10BE] = {
.name = "yuv420p10be",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,1,1,0,9}, /* Y */
- {1,1,1,0,9}, /* U */
- {2,1,1,0,9}, /* V */
+ { 0, 1, 1, 0, 9 }, /* Y */
+ { 1, 1, 1, 0, 9 }, /* U */
+ { 2, 1, 1, 0, 9 }, /* V */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
},
[PIX_FMT_YUV420P16LE] = {
.name = "yuv420p16le",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,1,1,0,15}, /* Y */
- {1,1,1,0,15}, /* U */
- {2,1,1,0,15}, /* V */
+ { 0, 1, 1, 0, 15 }, /* Y */
+ { 1, 1, 1, 0, 15 }, /* U */
+ { 2, 1, 1, 0, 15 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV420P16BE] = {
.name = "yuv420p16be",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 1,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 1,
.comp = {
- {0,1,1,0,15}, /* Y */
- {1,1,1,0,15}, /* U */
- {2,1,1,0,15}, /* V */
+ { 0, 1, 1, 0, 15 }, /* Y */
+ { 1, 1, 1, 0, 15 }, /* U */
+ { 2, 1, 1, 0, 15 }, /* V */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+ },
+ [PIX_FMT_YUV422P9LE] = {
+ .name = "yuv422p9le",
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 1, 1, 0, 8 }, /* Y */
+ { 1, 1, 1, 0, 8 }, /* U */
+ { 2, 1, 1, 0, 8 }, /* V */
+ },
+ .flags = PIX_FMT_PLANAR,
+ },
+ [PIX_FMT_YUV422P9BE] = {
+ .name = "yuv422p9be",
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 0,
+ .comp = {
+ {0,1,1,0,8}, /* Y */
+ {1,1,1,0,8}, /* U */
+ {2,1,1,0,8}, /* V */
+ },
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
},
[PIX_FMT_YUV422P10LE] = {
.name = "yuv422p10le",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,9}, /* Y */
- {1,1,1,0,9}, /* U */
- {2,1,1,0,9}, /* V */
+ { 0, 1, 1, 0, 9 }, /* Y */
+ { 1, 1, 1, 0, 9 }, /* U */
+ { 2, 1, 1, 0, 9 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV422P10BE] = {
.name = "yuv422p10be",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,9}, /* Y */
- {1,1,1,0,9}, /* U */
- {2,1,1,0,9}, /* V */
+ { 0, 1, 1, 0, 9 }, /* Y */
+ { 1, 1, 1, 0, 9 }, /* U */
+ { 2, 1, 1, 0, 9 }, /* V */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
},
[PIX_FMT_YUV422P16LE] = {
.name = "yuv422p16le",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,15}, /* Y */
- {1,1,1,0,15}, /* U */
- {2,1,1,0,15}, /* V */
+ { 0, 1, 1, 0, 15 }, /* Y */
+ { 1, 1, 1, 0, 15 }, /* U */
+ { 2, 1, 1, 0, 15 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV422P16BE] = {
.name = "yuv422p16be",
- .nb_components= 3,
- .log2_chroma_w= 1,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 1,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,15}, /* Y */
- {1,1,1,0,15}, /* U */
- {2,1,1,0,15}, /* V */
+ { 0, 1, 1, 0, 15 }, /* Y */
+ { 1, 1, 1, 0, 15 }, /* U */
+ { 2, 1, 1, 0, 15 }, /* V */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
},
[PIX_FMT_YUV444P16LE] = {
.name = "yuv444p16le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,15}, /* Y */
- {1,1,1,0,15}, /* U */
- {2,1,1,0,15}, /* V */
+ { 0, 1, 1, 0, 15 }, /* Y */
+ { 1, 1, 1, 0, 15 }, /* U */
+ { 2, 1, 1, 0, 15 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV444P16BE] = {
.name = "yuv444p16be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,15}, /* Y */
- {1,1,1,0,15}, /* U */
- {2,1,1,0,15}, /* V */
+ { 0, 1, 1, 0, 15 }, /* Y */
+ { 1, 1, 1, 0, 15 }, /* U */
+ { 2, 1, 1, 0, 15 }, /* V */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
},
[PIX_FMT_YUV444P10LE] = {
.name = "yuv444p10le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,9}, /* Y */
- {1,1,1,0,9}, /* U */
- {2,1,1,0,9}, /* V */
+ { 0, 1, 1, 0, 9 }, /* Y */
+ { 1, 1, 1, 0, 9 }, /* U */
+ { 2, 1, 1, 0, 9 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV444P10BE] = {
.name = "yuv444p10be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,9}, /* Y */
- {1,1,1,0,9}, /* U */
- {2,1,1,0,9}, /* V */
+ { 0, 1, 1, 0, 9 }, /* Y */
+ { 1, 1, 1, 0, 9 }, /* U */
+ { 2, 1, 1, 0, 9 }, /* V */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
},
[PIX_FMT_YUV444P9LE] = {
.name = "yuv444p9le",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,8}, /* Y */
- {1,1,1,0,8}, /* U */
- {2,1,1,0,8}, /* V */
+ { 0, 1, 1, 0, 8 }, /* Y */
+ { 1, 1, 1, 0, 8 }, /* U */
+ { 2, 1, 1, 0, 8 }, /* V */
},
+ .flags = PIX_FMT_PLANAR,
},
[PIX_FMT_YUV444P9BE] = {
.name = "yuv444p9be",
- .nb_components= 3,
- .log2_chroma_w= 0,
- .log2_chroma_h= 0,
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,8}, /* Y */
- {1,1,1,0,8}, /* U */
- {2,1,1,0,8}, /* V */
+ { 0, 1, 1, 0, 8 }, /* Y */
+ { 1, 1, 1, 0, 8 }, /* U */
+ { 2, 1, 1, 0, 8 }, /* V */
},
- .flags = PIX_FMT_BE,
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
},
[PIX_FMT_DXVA2_VLD] = {
.name = "dxva2_vld",
@@ -932,11 +997,95 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = {
},
[PIX_FMT_Y400A] = {
.name = "y400a",
- .nb_components= 2,
+ .nb_components = 2,
+ .comp = {
+ { 0, 1, 1, 0, 7 }, /* Y */
+ { 0, 1, 2, 0, 7 }, /* A */
+ },
+ },
+ [PIX_FMT_GBRP] = {
+ .name = "gbrp",
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 0, 1, 0, 7 }, /* G */
+ { 1, 0, 1, 0, 7 }, /* B */
+ { 2, 0, 1, 0, 7 }, /* R */
+ },
+ .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+ },
+ [PIX_FMT_GBRP9LE] = {
+ .name = "gbrp9le",
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 1, 1, 0, 8 }, /* G */
+ { 1, 1, 1, 0, 8 }, /* B */
+ { 2, 1, 1, 0, 8 }, /* R */
+ },
+ .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+ },
+ [PIX_FMT_GBRP9BE] = {
+ .name = "gbrp9be",
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 1, 1, 0, 8 }, /* G */
+ { 1, 1, 1, 0, 8 }, /* B */
+ { 2, 1, 1, 0, 8 }, /* R */
+ },
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+ },
+ [PIX_FMT_GBRP10LE] = {
+ .name = "gbrp10le",
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 1, 1, 0, 9 }, /* G */
+ { 1, 1, 1, 0, 9 }, /* B */
+ { 2, 1, 1, 0, 9 }, /* R */
+ },
+ .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+ },
+ [PIX_FMT_GBRP10BE] = {
+ .name = "gbrp10be",
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 1, 1, 0, 9 }, /* G */
+ { 1, 1, 1, 0, 9 }, /* B */
+ { 2, 1, 1, 0, 9 }, /* R */
+ },
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+ },
+ [PIX_FMT_GBRP16LE] = {
+ .name = "gbrp16le",
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 1, 1, 0, 15 }, /* G */
+ { 1, 1, 1, 0, 15 }, /* B */
+ { 2, 1, 1, 0, 15 }, /* R */
+ },
+ .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+ },
+ [PIX_FMT_GBRP16BE] = {
+ .name = "gbrp16be",
+ .nb_components = 3,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
.comp = {
- {0,1,1,0,7}, /* Y */
- {0,1,2,0,7}, /* A */
+ { 0, 1, 1, 0, 15 }, /* G */
+ { 1, 1, 1, 0, 15 }, /* B */
+ { 2, 1, 1, 0, 15 }, /* R */
},
+ .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
},
};
@@ -989,8 +1138,8 @@ int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
int log2_pixels = pixdesc->log2_chroma_w + pixdesc->log2_chroma_h;
for (c = 0; c < pixdesc->nb_components; c++) {
- int s = c==1 || c==2 ? 0 : log2_pixels;
- bits += (pixdesc->comp[c].depth_minus1+1) << s;
+ int s = c == 1 || c == 2 ? 0 : log2_pixels;
+ bits += (pixdesc->comp[c].depth_minus1 + 1) << s;
}
return bits >> log2_pixels;
@@ -1000,11 +1149,11 @@ char *av_get_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
{
/* print header */
if (pix_fmt < 0) {
- snprintf (buf, buf_size, "name " " nb_components" " nb_bits");
+ snprintf (buf, buf_size, "name" " nb_components" " nb_bits");
} else {
const AVPixFmtDescriptor *pixdesc = &av_pix_fmt_descriptors[pix_fmt];
- snprintf(buf, buf_size, "%-11s %7d %10d",
- pixdesc->name, pixdesc->nb_components, av_get_bits_per_pixel(pixdesc));
+ snprintf(buf, buf_size, "%-11s %7d %10d", pixdesc->name,
+ pixdesc->nb_components, av_get_bits_per_pixel(pixdesc));
}
return buf;
diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h
index 979a235..b5972c7 100644
--- a/libavutil/pixdesc.h
+++ b/libavutil/pixdesc.h
@@ -87,6 +87,8 @@ typedef struct AVPixFmtDescriptor{
#define PIX_FMT_PAL 2 ///< Pixel format has a palette in data[1], values are indexes in this palette.
#define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end.
#define PIX_FMT_HWACCEL 8 ///< Pixel format is an HW accelerated format.
+#define PIX_FMT_PLANAR 16 ///< At least one pixel component is not in the first data plane
+#define PIX_FMT_RGB 32 ///< The pixel format contains RGB-like data (as opposed to YUV/grayscale)
/**
* The array of all the pixel format descriptors.
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index e852d85..bd898bd 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -25,21 +25,21 @@
* @file
* pixel format definitions
*
- * @warning This file has to be considered an internal but installed
- * header, so it should not be directly included in your projects.
*/
#include "libavutil/avconfig.h"
/**
- * Pixel format. Notes:
+ * Pixel format.
*
+ * @note
* PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA
* color is put together as:
* (A << 24) | (R << 16) | (G << 8) | B
* This is stored as BGRA on little-endian CPU architectures and ARGB on
* big-endian CPUs.
*
+ * @par
* When the pixel format is palettized RGB (PIX_FMT_PAL8), the palettized
* image data is stored in AVFrame.data[0]. The palette is transported in
* AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is
@@ -49,13 +49,15 @@
* This is important as many custom PAL8 video codecs that were designed
* to run on the IBM VGA graphics adapter use 6-bit palette components.
*
+ * @par
* For all the 8bit per pixel formats, an RGB32 palette is in data[1] like
* for pal8. This palette is filled in automatically by the function
* allocating the picture.
*
- * Note, make sure that all newly added big endian formats have pix_fmt&1==1
- * and that all newly added little endian formats have pix_fmt&1==0
- * this allows simpler detection of big vs little endian.
+ * @note
+ * make sure that all newly added big endian formats have pix_fmt&1==1
+ * and that all newly added little endian formats have pix_fmt&1==0
+ * this allows simpler detection of big vs little endian.
*/
enum PixelFormat {
PIX_FMT_NONE= -1,
@@ -139,12 +141,22 @@ enum PixelFormat {
PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
PIX_FMT_YUV420P10LE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
- PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
- PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
- PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
- PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
- PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
- PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+ PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+ PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+ PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+ PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+ PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+ PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+ PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+ PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+ PIX_FMT_VDA_VLD, ///< hardware decoding through VDA
+ PIX_FMT_GBRP, ///< planar GBR 4:4:4 24bpp
+ PIX_FMT_GBRP9BE, ///< planar GBR 4:4:4 27bpp, big endian
+ PIX_FMT_GBRP9LE, ///< planar GBR 4:4:4 27bpp, little endian
+ PIX_FMT_GBRP10BE, ///< planar GBR 4:4:4 30bpp, big endian
+ PIX_FMT_GBRP10LE, ///< planar GBR 4:4:4 30bpp, little endian
+ PIX_FMT_GBRP16BE, ///< planar GBR 4:4:4 48bpp, big endian
+ PIX_FMT_GBRP16LE, ///< planar GBR 4:4:4 48bpp, little endian
PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
};
@@ -170,6 +182,7 @@ enum PixelFormat {
#define PIX_FMT_BGR444 PIX_FMT_NE(BGR444BE, BGR444LE)
#define PIX_FMT_YUV420P9 PIX_FMT_NE(YUV420P9BE , YUV420P9LE)
+#define PIX_FMT_YUV422P9 PIX_FMT_NE(YUV422P9BE , YUV422P9LE)
#define PIX_FMT_YUV444P9 PIX_FMT_NE(YUV444P9BE , YUV444P9LE)
#define PIX_FMT_YUV420P10 PIX_FMT_NE(YUV420P10BE, YUV420P10LE)
#define PIX_FMT_YUV422P10 PIX_FMT_NE(YUV422P10BE, YUV422P10LE)
@@ -178,4 +191,8 @@ enum PixelFormat {
#define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422P16BE, YUV422P16LE)
#define PIX_FMT_YUV444P16 PIX_FMT_NE(YUV444P16BE, YUV444P16LE)
+#define PIX_FMT_GBRP9 PIX_FMT_NE(GBRP9BE , GBRP9LE)
+#define PIX_FMT_GBRP10 PIX_FMT_NE(GBRP10BE, GBRP10LE)
+#define PIX_FMT_GBRP16 PIX_FMT_NE(GBRP16BE, GBRP16LE)
+
#endif /* AVUTIL_PIXFMT_H */
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c
index a1078d8..51ca99b 100644
--- a/libavutil/random_seed.c
+++ b/libavutil/random_seed.c
@@ -20,10 +20,10 @@
#include <unistd.h>
#include <fcntl.h>
+#include <math.h>
+#include <time.h>
#include "timer.h"
-#include "time.h"
#include "random_seed.h"
-#include "avutil.h"
static int read_random(uint32_t *dst, const char *file)
{
@@ -40,24 +40,24 @@ static int read_random(uint32_t *dst, const char *file)
static uint32_t get_generic_seed(void)
{
- clock_t last_t=0;
- int bits=0;
- uint64_t random=0;
+ clock_t last_t = 0;
+ int bits = 0;
+ uint64_t random = 0;
unsigned i;
- float s=0.000000000001;
+ float s = 0.000000000001;
- for(i=0;bits<64;i++){
- clock_t t= clock();
- if(last_t && fabs(t-last_t)>s || t==(clock_t)-1){
- if(i<10000 && s<(1<<24)){
- s+=s;
- i=t=0;
- }else{
- random= 2*random + (i&1);
+ for (i = 0; bits < 64; i++) {
+ clock_t t = clock();
+ if (last_t && fabs(t - last_t) > s || t == (clock_t) -1) {
+ if (i < 10000 && s < (1 << 24)) {
+ s += s;
+ i = t = 0;
+ } else {
+ random = 2 * random + (i & 1);
bits++;
}
}
- last_t= t;
+ last_t = t;
}
#ifdef AV_READ_TIME
random ^= AV_READ_TIME();
@@ -65,7 +65,7 @@ static uint32_t get_generic_seed(void)
random ^= clock();
#endif
- random += random>>32;
+ random += random >> 32;
return random;
}
diff --git a/libavutil/random_seed.h b/libavutil/random_seed.h
index 8157d42..b1fad13 100644
--- a/libavutil/random_seed.h
+++ b/libavutil/random_seed.h
@@ -22,10 +22,23 @@
#define AVUTIL_RANDOM_SEED_H
#include <stdint.h>
+/**
+ * @addtogroup lavu_crypto
+ * @{
+ */
/**
- * Get a seed to use in conjunction with random functions.
+ * Get random data.
+ *
+ * This function can be called repeatedly to generate more random bits
+ * as needed. It is generally quite slow, and usually used to seed a
+ * PRNG. As it uses /dev/urandom and /dev/random, the quality of the
+ * returned random data depends on the platform.
*/
uint32_t av_get_random_seed(void);
+/**
+ * @}
+ */
+
#endif /* AVUTIL_RANDOM_SEED_H */
diff --git a/libavutil/rational.c b/libavutil/rational.c
index b2b05cc..3e62e1b 100644
--- a/libavutil/rational.c
+++ b/libavutil/rational.c
@@ -33,75 +33,86 @@
#include "mathematics.h"
#include "rational.h"
-int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max){
- AVRational a0={0,1}, a1={1,0};
- int sign= (num<0) ^ (den<0);
- int64_t gcd= av_gcd(FFABS(num), FFABS(den));
-
- if(gcd){
- num = FFABS(num)/gcd;
- den = FFABS(den)/gcd;
+int av_reduce(int *dst_num, int *dst_den,
+ int64_t num, int64_t den, int64_t max)
+{
+ AVRational a0 = { 0, 1 }, a1 = { 1, 0 };
+ int sign = (num < 0) ^ (den < 0);
+ int64_t gcd = av_gcd(FFABS(num), FFABS(den));
+
+ if (gcd) {
+ num = FFABS(num) / gcd;
+ den = FFABS(den) / gcd;
}
- if(num<=max && den<=max){
- a1= (AVRational){num, den};
- den=0;
+ if (num <= max && den <= max) {
+ a1 = (AVRational) { num, den };
+ den = 0;
}
- while(den){
- uint64_t x = num / den;
- int64_t next_den= num - den*x;
- int64_t a2n= x*a1.num + a0.num;
- int64_t a2d= x*a1.den + a0.den;
+ while (den) {
+ uint64_t x = num / den;
+ int64_t next_den = num - den * x;
+ int64_t a2n = x * a1.num + a0.num;
+ int64_t a2d = x * a1.den + a0.den;
- if(a2n > max || a2d > max){
- if(a1.num) x= (max - a0.num) / a1.num;
- if(a1.den) x= FFMIN(x, (max - a0.den) / a1.den);
+ if (a2n > max || a2d > max) {
+ if (a1.num) x = (max - a0.num) / a1.num;
+ if (a1.den) x = FFMIN(x, (max - a0.den) / a1.den);
- if (den*(2*x*a1.den + a0.den) > num*a1.den)
- a1 = (AVRational){x*a1.num + a0.num, x*a1.den + a0.den};
+ if (den * (2 * x * a1.den + a0.den) > num * a1.den)
+ a1 = (AVRational) { x * a1.num + a0.num, x * a1.den + a0.den };
break;
}
- a0= a1;
- a1= (AVRational){a2n, a2d};
- num= den;
- den= next_den;
+ a0 = a1;
+ a1 = (AVRational) { a2n, a2d };
+ num = den;
+ den = next_den;
}
av_assert2(av_gcd(a1.num, a1.den) <= 1U);
*dst_num = sign ? -a1.num : a1.num;
*dst_den = a1.den;
- return den==0;
+ return den == 0;
}
-AVRational av_mul_q(AVRational b, AVRational c){
- av_reduce(&b.num, &b.den, b.num * (int64_t)c.num, b.den * (int64_t)c.den, INT_MAX);
+AVRational av_mul_q(AVRational b, AVRational c)
+{
+ av_reduce(&b.num, &b.den,
+ b.num * (int64_t) c.num,
+ b.den * (int64_t) c.den, INT_MAX);
return b;
}
-AVRational av_div_q(AVRational b, AVRational c){
- return av_mul_q(b, (AVRational){c.den, c.num});
+AVRational av_div_q(AVRational b, AVRational c)
+{
+ return av_mul_q(b, (AVRational) { c.den, c.num });
}
-AVRational av_add_q(AVRational b, AVRational c){
- av_reduce(&b.num, &b.den, b.num * (int64_t)c.den + c.num * (int64_t)b.den, b.den * (int64_t)c.den, INT_MAX);
+AVRational av_add_q(AVRational b, AVRational c) {
+ av_reduce(&b.num, &b.den,
+ b.num * (int64_t) c.den +
+ c.num * (int64_t) b.den,
+ b.den * (int64_t) c.den, INT_MAX);
return b;
}
-AVRational av_sub_q(AVRational b, AVRational c){
- return av_add_q(b, (AVRational){-c.num, c.den});
+AVRational av_sub_q(AVRational b, AVRational c)
+{
+ return av_add_q(b, (AVRational) { -c.num, c.den });
}
-AVRational av_d2q(double d, int max){
+AVRational av_d2q(double d, int max)
+{
AVRational a;
#define LOG2 0.69314718055994530941723212145817656807550013436025
int exponent;
int64_t den;
if (isnan(d))
- return (AVRational){0,0};
+ return (AVRational) { 0,0 };
if (isinf(d))
- return (AVRational){ d<0 ? -1:1, 0 };
+ return (AVRational) { d < 0 ? -1 : 1, 0 };
exponent = FFMAX( (int)(log(fabs(d) + 1e-20)/LOG2), 0);
den = 1LL << (61 - exponent);
av_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max);
@@ -127,7 +138,7 @@ int av_nearer_q(AVRational q, AVRational q1, AVRational q2)
int av_find_nearest_q_idx(AVRational q, const AVRational* q_list)
{
int i, nearest_q_idx = 0;
- for(i=0; q_list[i].den; i++)
+ for (i = 0; q_list[i].den; i++)
if (av_nearer_q(q, q_list[i], q_list[nearest_q_idx]) > 0)
nearest_q_idx = i;
@@ -135,21 +146,26 @@ int av_find_nearest_q_idx(AVRational q, const AVRational* q_list)
}
#ifdef TEST
-main(){
+int main(void)
+{
AVRational a,b;
- for(a.num=-2; a.num<=2; a.num++){
- for(a.den=-2; a.den<=2; a.den++){
- for(b.num=-2; b.num<=2; b.num++){
- for(b.den=-2; b.den<=2; b.den++){
- int c= av_cmp_q(a,b);
- double d= av_q2d(a) == av_q2d(b) ? 0 : (av_q2d(a) - av_q2d(b));
- if(d>0) d=1;
- else if(d<0) d=-1;
- else if(d != d) d= INT_MIN;
- if(c!=d) av_log(0, AV_LOG_ERROR, "%d/%d %d/%d, %d %f\n", a.num, a.den, b.num, b.den, c,d);
+ for (a.num = -2; a.num <= 2; a.num++) {
+ for (a.den = -2; a.den <= 2; a.den++) {
+ for (b.num = -2; b.num <= 2; b.num++) {
+ for (b.den = -2; b.den <= 2; b.den++) {
+ int c = av_cmp_q(a,b);
+ double d = av_q2d(a) == av_q2d(b) ?
+ 0 : (av_q2d(a) - av_q2d(b));
+ if (d > 0) d = 1;
+ else if (d < 0) d = -1;
+ else if (d != d) d = INT_MIN;
+ if (c != d)
+ av_log(0, AV_LOG_ERROR, "%d/%d %d/%d, %d %f\n", a.num,
+ a.den, b.num, b.den, c,d);
}
}
}
}
+ return 0;
}
#endif
diff --git a/libavutil/rational.h b/libavutil/rational.h
index a487114..0ec18ec 100644
--- a/libavutil/rational.h
+++ b/libavutil/rational.h
@@ -33,6 +33,11 @@
#include "attributes.h"
/**
+ * @addtogroup lavu_math
+ * @{
+ */
+
+/**
* rational number numerator/denominator
*/
typedef struct AVRational{
@@ -132,4 +137,8 @@ int av_nearer_q(AVRational q, AVRational q1, AVRational q2);
*/
int av_find_nearest_q_idx(AVRational q, const AVRational* q_list);
+/**
+ * @}
+ */
+
#endif /* AVUTIL_RATIONAL_H */
diff --git a/libavutil/rc4.h b/libavutil/rc4.h
index dc5066d..ec3b47c 100644
--- a/libavutil/rc4.h
+++ b/libavutil/rc4.h
@@ -29,21 +29,21 @@ struct AVRC4 {
};
/**
- * \brief Initializes an AVRC4 context.
+ * @brief Initializes an AVRC4 context.
*
- * \param key_bits must be a multiple of 8
- * \param decrypt 0 for encryption, 1 for decryption, currently has no effect
+ * @param key_bits must be a multiple of 8
+ * @param decrypt 0 for encryption, 1 for decryption, currently has no effect
*/
int av_rc4_init(struct AVRC4 *d, const uint8_t *key, int key_bits, int decrypt);
/**
- * \brief Encrypts / decrypts using the RC4 algorithm.
+ * @brief Encrypts / decrypts using the RC4 algorithm.
*
- * \param count number of bytes
- * \param dst destination array, can be equal to src
- * \param src source array, can be equal to dst, may be NULL
- * \param iv not (yet) used for RC4, should be NULL
- * \param decrypt 0 for encryption, 1 for decryption, not (yet) used
+ * @param count number of bytes
+ * @param dst destination array, can be equal to src
+ * @param src source array, can be equal to dst, may be NULL
+ * @param iv not (yet) used for RC4, should be NULL
+ * @param decrypt 0 for encryption, 1 for decryption, not (yet) used
*/
void av_rc4_crypt(struct AVRC4 *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt);
diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c
index 5b0bfa0..f38d05e 100644
--- a/libavutil/samplefmt.c
+++ b/libavutil/samplefmt.c
@@ -25,15 +25,21 @@
typedef struct SampleFmtInfo {
const char *name;
int bits;
+ int planar;
} SampleFmtInfo;
/** this table gives more information about formats */
static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB] = {
- [AV_SAMPLE_FMT_U8] = { .name = "u8", .bits = 8 },
- [AV_SAMPLE_FMT_S16] = { .name = "s16", .bits = 16 },
- [AV_SAMPLE_FMT_S32] = { .name = "s32", .bits = 32 },
- [AV_SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32 },
- [AV_SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64 },
+ [AV_SAMPLE_FMT_U8] = { .name = "u8", .bits = 8, .planar = 0 },
+ [AV_SAMPLE_FMT_S16] = { .name = "s16", .bits = 16, .planar = 0 },
+ [AV_SAMPLE_FMT_S32] = { .name = "s32", .bits = 32, .planar = 0 },
+ [AV_SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32, .planar = 0 },
+ [AV_SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64, .planar = 0 },
+ [AV_SAMPLE_FMT_U8P] = { .name = "u8p", .bits = 8, .planar = 1 },
+ [AV_SAMPLE_FMT_S16P] = { .name = "s16p", .bits = 16, .planar = 1 },
+ [AV_SAMPLE_FMT_S32P] = { .name = "s32p", .bits = 32, .planar = 1 },
+ [AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1 },
+ [AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1 },
};
const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
@@ -79,3 +85,75 @@ int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt)
0 : sample_fmt_info[sample_fmt].bits;
}
#endif
+
+int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
+{
+ if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
+ return 0;
+ return sample_fmt_info[sample_fmt].planar;
+}
+
+int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
+ enum AVSampleFormat sample_fmt, int align)
+{
+ int line_size;
+ int sample_size = av_get_bytes_per_sample(sample_fmt);
+ int planar = av_sample_fmt_is_planar(sample_fmt);
+
+ /* validate parameter ranges */
+ if (!sample_size || nb_samples <= 0 || nb_channels <= 0)
+ return AVERROR(EINVAL);
+
+ /* check for integer overflow */
+ if (nb_channels > INT_MAX / align ||
+ (int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) / sample_size)
+ return AVERROR(EINVAL);
+
+ line_size = planar ? FFALIGN(nb_samples * sample_size, align) :
+ FFALIGN(nb_samples * sample_size * nb_channels, align);
+ if (linesize)
+ *linesize = line_size;
+
+ return planar ? line_size * nb_channels : line_size;
+}
+
+int av_samples_fill_arrays(uint8_t **audio_data, int *linesize,
+ uint8_t *buf, int nb_channels, int nb_samples,
+ enum AVSampleFormat sample_fmt, int align)
+{
+ int ch, planar, buf_size;
+
+ planar = av_sample_fmt_is_planar(sample_fmt);
+ buf_size = av_samples_get_buffer_size(linesize, nb_channels, nb_samples,
+ sample_fmt, align);
+ if (buf_size < 0)
+ return buf_size;
+
+ audio_data[0] = buf;
+ for (ch = 1; planar && ch < nb_channels; ch++)
+ audio_data[ch] = audio_data[ch-1] + *linesize;
+
+ return 0;
+}
+
+int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
+ int nb_samples, enum AVSampleFormat sample_fmt, int align)
+{
+ uint8_t *buf;
+ int size = av_samples_get_buffer_size(NULL, nb_channels, nb_samples,
+ sample_fmt, align);
+ if (size < 0)
+ return size;
+
+ buf = av_mallocz(size);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ size = av_samples_fill_arrays(audio_data, linesize, buf, nb_channels,
+ nb_samples, sample_fmt, align);
+ if (size < 0) {
+ av_free(buf);
+ return size;
+ }
+ return 0;
+}
diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h
index e382149..b671556 100644
--- a/libavutil/samplefmt.h
+++ b/libavutil/samplefmt.h
@@ -31,6 +31,13 @@ enum AVSampleFormat {
AV_SAMPLE_FMT_S32, ///< signed 32 bits
AV_SAMPLE_FMT_FLT, ///< float
AV_SAMPLE_FMT_DBL, ///< double
+
+ AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar
+ AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar
+ AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar
+ AV_SAMPLE_FMT_FLTP, ///< float, planar
+ AV_SAMPLE_FMT_DBLP, ///< double, planar
+
AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically
};
@@ -77,4 +84,65 @@ int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt);
*/
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt);
+/**
+ * Check if the sample format is planar.
+ *
+ * @param sample_fmt the sample format to inspect
+ * @return 1 if the sample format is planar, 0 if it is interleaved
+ */
+int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt);
+
+/**
+ * Get the required buffer size for the given audio parameters.
+ *
+ * @param[out] linesize calculated linesize, may be NULL
+ * @param nb_channels the number of channels
+ * @param nb_samples the number of samples in a single channel
+ * @param sample_fmt the sample format
+ * @return required buffer size, or negative error code on failure
+ */
+int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
+ enum AVSampleFormat sample_fmt, int align);
+
+/**
+ * Fill channel data pointers and linesize for samples with sample
+ * format sample_fmt.
+ *
+ * The pointers array is filled with the pointers to the samples data:
+ * for planar, set the start point of each channel's data within the buffer,
+ * for packed, set the start point of the entire buffer only.
+ *
+ * The linesize array is filled with the aligned size of each channel's data
+ * buffer for planar layout, or the aligned size of the buffer for all channels
+ * for packed layout.
+ *
+ * @param[out] audio_data array to be filled with the pointer for each channel
+ * @param[out] linesize calculated linesize
+ * @param buf the pointer to a buffer containing the samples
+ * @param nb_channels the number of channels
+ * @param nb_samples the number of samples in a single channel
+ * @param sample_fmt the sample format
+ * @param align buffer size alignment (1 = no alignment required)
+ * @return 0 on success or a negative error code on failure
+ */
+int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, uint8_t *buf,
+ int nb_channels, int nb_samples,
+ enum AVSampleFormat sample_fmt, int align);
+
+/**
+ * Allocate a samples buffer for nb_samples samples, and fill data pointers and
+ * linesize accordingly.
+ * The allocated samples buffer can be freed by using av_freep(&audio_data[0])
+ *
+ * @param[out] audio_data array to be filled with the pointer for each channel
+ * @param[out] linesize aligned size for audio buffer(s)
+ * @param nb_channels number of audio channels
+ * @param nb_samples number of samples per channel
+ * @param align buffer size alignment (1 = no alignment required)
+ * @return 0 on success or a negative error code on failure
+ * @see av_samples_fill_arrays()
+ */
+int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
+ int nb_samples, enum AVSampleFormat sample_fmt, int align);
+
#endif /* AVUTIL_SAMPLEFMT_H */
diff --git a/libavutil/sha.c b/libavutil/sha.c
index ae6069d..5af742d 100644
--- a/libavutil/sha.c
+++ b/libavutil/sha.c
@@ -42,7 +42,7 @@ const int av_sha_size = sizeof(AVSHA);
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define blk0(i) (block[i] = av_be2ne32(((const uint32_t*)buffer)[i]))
+#define blk0(i) (block[i] = AV_RB32(buffer + 4 * (i)))
#define blk(i) (block[i] = rol(block[i-3] ^ block[i-8] ^ block[i-14] ^ block[i-16], 1))
#define R0(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk0(i) + 0x5A827999 + rol(v, 5); w = rol(w, 30);
@@ -67,7 +67,7 @@ static void sha1_transform(uint32_t state[5], const uint8_t buffer[64])
for (i = 0; i < 80; i++) {
int t;
if (i < 16)
- t = av_be2ne32(((uint32_t*)buffer)[i]);
+ t = AV_RB32(buffer + 4 * i);
else
t = rol(block[i-3] ^ block[i-8] ^ block[i-14] ^ block[i-16], 1);
block[i] = t;
diff --git a/libavutil/sha.h b/libavutil/sha.h
index df261fa..8350954 100644
--- a/libavutil/sha.h
+++ b/libavutil/sha.h
@@ -23,6 +23,12 @@
#include <stdint.h>
+/**
+ * @defgroup lavu_sha SHA
+ * @ingroup lavu_crypto
+ * @{
+ */
+
extern const int av_sha_size;
struct AVSHA;
@@ -53,4 +59,8 @@ void av_sha_update(struct AVSHA* context, const uint8_t* data, unsigned int len)
*/
void av_sha_final(struct AVSHA* context, uint8_t *digest);
+/**
+ * @}
+ */
+
#endif /* AVUTIL_SHA_H */
diff --git a/libavutil/timer.h b/libavutil/timer.h
index a2ca5cf..6333cc6 100644
--- a/libavutil/timer.h
+++ b/libavutil/timer.h
@@ -1,7 +1,4 @@
-/**
- * @file
- * high precision timer, useful to profile code
- *
+/*
* copyright (c) 2006 Michael Niedermayer <michaelni at gmx.at>
*
* This file is part of Libav.
@@ -21,6 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * high precision timer, useful to profile code
+ */
+
#ifndef AVUTIL_TIMER_H
#define AVUTIL_TIMER_H
@@ -59,7 +61,7 @@ tend= AV_READ_TIME();\
}else\
tskip_count++;\
if(((tcount+tskip_count)&(tcount+tskip_count-1))==0){\
- av_log(NULL, AV_LOG_ERROR, "%"PRIu64" dezicycles in %s, %d runs, %d skips\n",\
+ av_log(NULL, AV_LOG_ERROR, "%"PRIu64" decicycles in %s, %d runs, %d skips\n",\
tsum*10/tcount, id, tcount, tskip_count);\
}\
}
diff --git a/libavutil/tree.c b/libavutil/tree.c
index 067e5b0..e614f72 100644
--- a/libavutil/tree.c
+++ b/libavutil/tree.c
@@ -21,22 +21,24 @@
#include "log.h"
#include "tree.h"
-typedef struct AVTreeNode{
+typedef struct AVTreeNode {
struct AVTreeNode *child[2];
void *elem;
int state;
-}AVTreeNode;
+} AVTreeNode;
const int av_tree_node_size = sizeof(AVTreeNode);
-void *av_tree_find(const AVTreeNode *t, void *key, int (*cmp)(void *key, const void *b), void *next[2]){
- if(t){
- unsigned int v= cmp(key, t->elem);
- if(v){
- if(next) next[v>>31]= t->elem;
- return av_tree_find(t->child[(v>>31)^1], key, cmp, next);
- }else{
- if(next){
+void *av_tree_find(const AVTreeNode *t, void *key,
+ int (*cmp)(void *key, const void *b), void *next[2])
+{
+ if (t) {
+ unsigned int v = cmp(key, t->elem);
+ if (v) {
+ if (next) next[v >> 31] = t->elem;
+ return av_tree_find(t->child[(v >> 31) ^ 1], key, cmp, next);
+ } else {
+ if (next) {
av_tree_find(t->child[0], key, cmp, next);
av_tree_find(t->child[1], key, cmp, next);
}
@@ -46,41 +48,43 @@ void *av_tree_find(const AVTreeNode *t, void *key, int (*cmp)(void *key, const v
return NULL;
}
-void *av_tree_insert(AVTreeNode **tp, void *key, int (*cmp)(void *key, const void *b), AVTreeNode **next){
- AVTreeNode *t= *tp;
- if(t){
- unsigned int v= cmp(t->elem, key);
+void *av_tree_insert(AVTreeNode **tp, void *key,
+ int (*cmp)(void *key, const void *b), AVTreeNode **next)
+{
+ AVTreeNode *t = *tp;
+ if (t) {
+ unsigned int v = cmp(t->elem, key);
void *ret;
- if(!v){
- if(*next)
+ if (!v) {
+ if (*next)
return t->elem;
- else if(t->child[0]||t->child[1]){
- int i= !t->child[0];
+ else if (t->child[0] || t->child[1]) {
+ int i = !t->child[0];
void *next_elem[2];
av_tree_find(t->child[i], key, cmp, next_elem);
- key= t->elem= next_elem[i];
- v= -i;
- }else{
- *next= t;
- *tp=NULL;
+ key = t->elem = next_elem[i];
+ v = -i;
+ } else {
+ *next = t;
+ *tp = NULL;
return NULL;
}
}
- ret= av_tree_insert(&t->child[v>>31], key, cmp, next);
- if(!ret){
- int i= (v>>31) ^ !!*next;
- AVTreeNode **child= &t->child[i];
- t->state += 2*i - 1;
-
- if(!(t->state&1)){
- if(t->state){
+ ret = av_tree_insert(&t->child[v >> 31], key, cmp, next);
+ if (!ret) {
+ int i = (v >> 31) ^ !!*next;
+ AVTreeNode **child = &t->child[i];
+ t->state += 2 * i - 1;
+
+ if (!(t->state & 1)) {
+ if (t->state) {
/* The following code is equivalent to
if((*child)->state*2 == -t->state)
rotate(child, i^1);
rotate(tp, i);
with rotate():
- static void rotate(AVTreeNode **tp, int i){
+ static void rotate(AVTreeNode **tp, int i) {
AVTreeNode *t= *tp;
*tp= t->child[i];
@@ -92,54 +96,62 @@ void *av_tree_insert(AVTreeNode **tp, void *key, int (*cmp)(void *key, const voi
}
but such a rotate function is both bigger and slower
*/
- if((*child)->state*2 == -t->state){
- *tp= (*child)->child[i^1];
- (*child)->child[i^1]= (*tp)->child[i];
- (*tp)->child[i]= *child;
- *child= (*tp)->child[i^1];
- (*tp)->child[i^1]= t;
-
- (*tp)->child[0]->state= -((*tp)->state>0);
- (*tp)->child[1]->state= (*tp)->state<0 ;
- (*tp)->state=0;
- }else{
- *tp= *child;
- *child= (*child)->child[i^1];
- (*tp)->child[i^1]= t;
- if((*tp)->state) t->state = 0;
- else t->state>>= 1;
- (*tp)->state= -t->state;
+ if (( *child )->state * 2 == -t->state) {
+ *tp = (*child)->child[i ^ 1];
+ (*child)->child[i ^ 1] = (*tp)->child[i];
+ (*tp)->child[i] = *child;
+ *child = ( *tp )->child[i ^ 1];
+ (*tp)->child[i ^ 1] = t;
+
+ (*tp)->child[0]->state = -((*tp)->state > 0);
+ (*tp)->child[1]->state = (*tp)->state < 0;
+ (*tp)->state = 0;
+ } else {
+ *tp = *child;
+ *child = (*child)->child[i ^ 1];
+ (*tp)->child[i ^ 1] = t;
+ if ((*tp)->state) t->state = 0;
+ else t->state >>= 1;
+ (*tp)->state = -t->state;
}
}
}
- if(!(*tp)->state ^ !!*next)
+ if (!(*tp)->state ^ !!*next)
return key;
}
return ret;
- }else{
- *tp= *next; *next= NULL;
- if(*tp){
- (*tp)->elem= key;
+ } else {
+ *tp = *next;
+ *next = NULL;
+ if (*tp) {
+ (*tp)->elem = key;
return NULL;
- }else
+ } else
return key;
}
}
-void av_tree_destroy(AVTreeNode *t){
- if(t){
+void av_tree_destroy(AVTreeNode *t)
+{
+ if (t) {
av_tree_destroy(t->child[0]);
av_tree_destroy(t->child[1]);
av_free(t);
}
}
-void av_tree_enumerate(AVTreeNode *t, void *opaque, int (*cmp)(void *opaque, void *elem), int (*enu)(void *opaque, void *elem)){
- if(t){
- int v= cmp ? cmp(opaque, t->elem) : 0;
- if(v>=0) av_tree_enumerate(t->child[0], opaque, cmp, enu);
- if(v==0) enu(opaque, t->elem);
- if(v<=0) av_tree_enumerate(t->child[1], opaque, cmp, enu);
+void av_tree_enumerate(AVTreeNode *t, void *opaque,
+ int (*cmp)(void *opaque, void *elem),
+ int (*enu)(void *opaque, void *elem))
+{
+ if (t) {
+ int v = cmp ? cmp(opaque, t->elem) : 0;
+ if (v >= 0)
+ av_tree_enumerate(t->child[0], opaque, cmp, enu);
+ if (v == 0)
+ enu(opaque, t->elem);
+ if (v <= 0)
+ av_tree_enumerate(t->child[1], opaque, cmp, enu);
}
}
@@ -147,64 +159,68 @@ void av_tree_enumerate(AVTreeNode *t, void *opaque, int (*cmp)(void *opaque, voi
#include "lfg.h"
-static int check(AVTreeNode *t){
- if(t){
- int left= check(t->child[0]);
- int right= check(t->child[1]);
+static int check(AVTreeNode *t)
+{
+ if (t) {
+ int left = check(t->child[0]);
+ int right = check(t->child[1]);
- if(left>999 || right>999)
+ if (left>999 || right>999)
return 1000;
- if(right - left != t->state)
+ if (right - left != t->state)
return 1000;
- if(t->state>1 || t->state<-1)
+ if (t->state>1 || t->state<-1)
return 1000;
- return FFMAX(left, right)+1;
+ return FFMAX(left, right) + 1;
}
return 0;
}
-static void print(AVTreeNode *t, int depth){
+static void print(AVTreeNode *t, int depth)
+{
int i;
- for(i=0; i<depth*4; i++) av_log(NULL, AV_LOG_ERROR, " ");
- if(t){
+ for (i = 0; i < depth * 4; i++) av_log(NULL, AV_LOG_ERROR, " ");
+ if (t) {
av_log(NULL, AV_LOG_ERROR, "Node %p %2d %p\n", t, t->state, t->elem);
- print(t->child[0], depth+1);
- print(t->child[1], depth+1);
- }else
+ print(t->child[0], depth + 1);
+ print(t->child[1], depth + 1);
+ } else
av_log(NULL, AV_LOG_ERROR, "NULL\n");
}
-static int cmp(void *a, const void *b){
- return (uint8_t*)a-(const uint8_t*)b;
+static int cmp(void *a, const void *b)
+{
+ return (uint8_t *) a - (const uint8_t *) b;
}
-int main(void){
+int main (void)
+{
int i;
void *k;
- AVTreeNode *root= NULL, *node=NULL;
+ AVTreeNode *root = NULL, *node = NULL;
AVLFG prng;
av_lfg_init(&prng, 1);
- for(i=0; i<10000; i++){
+ for (i = 0; i < 10000; i++) {
int j = av_lfg_get(&prng) % 86294;
- if(check(root) > 999){
+ if (check(root) > 999) {
av_log(NULL, AV_LOG_ERROR, "FATAL error %d\n", i);
print(root, 0);
return -1;
}
av_log(NULL, AV_LOG_ERROR, "inserting %4d\n", j);
- if(!node)
- node= av_mallocz(av_tree_node_size);
- av_tree_insert(&root, (void*)(j+1), cmp, &node);
+ if (!node)
+ node = av_mallocz(av_tree_node_size);
+ av_tree_insert(&root, (void *) (j + 1), cmp, &node);
j = av_lfg_get(&prng) % 86294;
{
- AVTreeNode *node2=NULL;
+ AVTreeNode *node2 = NULL;
av_log(NULL, AV_LOG_ERROR, "removing %4d\n", j);
- av_tree_insert(&root, (void*)(j+1), cmp, &node2);
- k= av_tree_find(root, (void*)(j+1), cmp, NULL);
- if(k)
+ av_tree_insert(&root, (void *) (j + 1), cmp, &node2);
+ k = av_tree_find(root, (void *) (j + 1), cmp, NULL);
+ if (k)
av_log(NULL, AV_LOG_ERROR, "removal failure %d\n", i);
}
}
diff --git a/libavutil/tree.h b/libavutil/tree.h
index 9115e2f..59ea01d 100644
--- a/libavutil/tree.h
+++ b/libavutil/tree.h
@@ -21,14 +21,24 @@
/**
* @file
* A tree container.
- * Insertion, removal, finding equal, largest which is smaller than and
- * smallest which is larger than, all have O(log n) worst case complexity.
* @author Michael Niedermayer <michaelni at gmx.at>
*/
#ifndef AVUTIL_TREE_H
#define AVUTIL_TREE_H
+/**
+ * @addtogroup lavu_tree AVTree
+ * @ingroup lavu_data
+ *
+ * Low complexity tree container
+ *
+ * Insertion, removal, finding equal, largest which is smaller than and
+ * smallest which is larger than, all have O(log n) worst case complexity.
+ * @{
+ */
+
+
struct AVTreeNode;
extern const int av_tree_node_size;
@@ -91,5 +101,8 @@ void av_tree_destroy(struct AVTreeNode *t);
*/
void av_tree_enumerate(struct AVTreeNode *t, void *opaque, int (*cmp)(void *opaque, void *elem), int (*enu)(void *opaque, void *elem));
+/**
+ * @}
+ */
#endif /* AVUTIL_TREE_H */
diff --git a/libavutil/x86/bswap.h b/libavutil/x86/bswap.h
index b60d9cc..c6cf007 100644
--- a/libavutil/x86/bswap.h
+++ b/libavutil/x86/bswap.h
@@ -28,24 +28,20 @@
#include "config.h"
#include "libavutil/attributes.h"
+#if !AV_GCC_VERSION_AT_LEAST(4,1)
#define av_bswap16 av_bswap16
static av_always_inline av_const unsigned av_bswap16(unsigned x)
{
__asm__("rorw $8, %w0" : "+r"(x));
return x;
}
+#endif /* !AV_GCC_VERSION_AT_LEAST(4,1) */
+#if !AV_GCC_VERSION_AT_LEAST(4,5)
#define av_bswap32 av_bswap32
static av_always_inline av_const uint32_t av_bswap32(uint32_t x)
{
-#if HAVE_BSWAP
__asm__("bswap %0" : "+r" (x));
-#else
- __asm__("rorw $8, %w0 \n\t"
- "rorl $16, %0 \n\t"
- "rorw $8, %w0"
- : "+r"(x));
-#endif
return x;
}
@@ -57,5 +53,6 @@ static inline uint64_t av_const av_bswap64(uint64_t x)
return x;
}
#endif
+#endif /* !AV_GCC_VERSION_AT_LEAST(4,5) */
#endif /* AVUTIL_X86_BSWAP_H */
diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c
index f747e4d..2424fe4 100644
--- a/libavutil/x86/cpu.c
+++ b/libavutil/x86/cpu.c
@@ -74,7 +74,10 @@ int ff_get_cpu_flags_x86(void)
return 0; /* CPUID not supported */
#endif
- cpuid(0, max_std_level, vendor.i[0], vendor.i[2], vendor.i[1]);
+ cpuid(0, max_std_level, ebx, ecx, edx);
+ vendor.i[0] = ebx;
+ vendor.i[1] = edx;
+ vendor.i[2] = ecx;
if(max_std_level >= 1){
cpuid(1, eax, ebx, ecx, std_caps);
@@ -133,6 +136,15 @@ int ff_get_cpu_flags_x86(void)
rval & AV_CPU_FLAG_SSE2 && !(ecx & 0x00000040)) {
rval |= AV_CPU_FLAG_SSE2SLOW;
}
+
+ /* XOP and FMA4 use the AVX instruction coding scheme, so they can't be
+ * used unless the OS has AVX support. */
+ if (rval & AV_CPU_FLAG_AVX) {
+ if (ecx & 0x00000800)
+ rval |= AV_CPU_FLAG_XOP;
+ if (ecx & 0x00010000)
+ rval |= AV_CPU_FLAG_FMA4;
+ }
}
if (!strncmp(vendor.c, "GenuineIntel", 12)) {
diff --git a/libavutil/x86/x86inc.asm b/libavutil/x86/x86inc.asm
new file mode 100644
index 0000000..475e70e
--- /dev/null
+++ b/libavutil/x86/x86inc.asm
@@ -0,0 +1,1067 @@
+;*****************************************************************************
+;* x86inc.asm: x264asm abstraction layer
+;*****************************************************************************
+;* Copyright (C) 2005-2011 x264 project
+;*
+;* Authors: Loren Merritt <lorenm at u.washington.edu>
+;* Anton Mitrofanov <BugMaster at narod.ru>
+;* Jason Garrett-Glaser <darkshikari at gmail.com>
+;*
+;* Permission to use, copy, modify, and/or distribute this software for any
+;* purpose with or without fee is hereby granted, provided that the above
+;* copyright notice and this permission notice appear in all copies.
+;*
+;* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+;* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+;* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+;* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+;* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+;* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+;*****************************************************************************
+
+; This is a header file for the x264ASM assembly language, which uses
+; NASM/YASM syntax combined with a large number of macros to provide easy
+; abstraction between different calling conventions (x86_32, win64, linux64).
+; It also has various other useful features to simplify writing the kind of
+; DSP functions that are most often used in x264.
+
+; Unlike the rest of x264, this file is available under an ISC license, as it
+; has significant usefulness outside of x264 and we want it to be available
+; to the largest audience possible. Of course, if you modify it for your own
+; purposes to add a new feature, we strongly encourage contributing a patch
+; as this feature might be useful for others as well. Send patches or ideas
+; to x264-devel at videolan.org .
+
+%define program_name ff
+
+%ifdef ARCH_X86_64
+ %ifidn __OUTPUT_FORMAT__,win32
+ %define WIN64
+ %else
+ %define UNIX64
+ %endif
+%endif
+
+%ifdef PREFIX
+ %define mangle(x) _ %+ x
+%else
+ %define mangle(x) x
+%endif
+
+; FIXME: All of the 64bit asm functions that take a stride as an argument
+; via register, assume that the high dword of that register is filled with 0.
+; This is true in practice (since we never do any 64bit arithmetic on strides,
+; and x264's strides are all positive), but is not guaranteed by the ABI.
+
+; Name of the .rodata section.
+; Kludge: Something on OS X fails to align .rodata even given an align attribute,
+; so use a different read-only section.
+%macro SECTION_RODATA 0-1 16
+ %ifidn __OUTPUT_FORMAT__,macho64
+ SECTION .text align=%1
+ %elifidn __OUTPUT_FORMAT__,macho
+ SECTION .text align=%1
+ fakegot:
+ %elifidn __OUTPUT_FORMAT__,aout
+ section .text
+ %else
+ SECTION .rodata align=%1
+ %endif
+%endmacro
+
+; aout does not support align=
+%macro SECTION_TEXT 0-1 16
+ %ifidn __OUTPUT_FORMAT__,aout
+ SECTION .text
+ %else
+ SECTION .text align=%1
+ %endif
+%endmacro
+
+%ifdef WIN64
+ %define PIC
+%elifndef ARCH_X86_64
+; x86_32 doesn't require PIC.
+; Some distros prefer shared objects to be PIC, but nothing breaks if
+; the code contains a few textrels, so we'll skip that complexity.
+ %undef PIC
+%endif
+%ifdef PIC
+ default rel
+%endif
+
+; Macros to eliminate most code duplication between x86_32 and x86_64:
+; Currently this works only for leaf functions which load all their arguments
+; into registers at the start, and make no other use of the stack. Luckily that
+; covers most of x264's asm.
+
+; PROLOGUE:
+; %1 = number of arguments. loads them from stack if needed.
+; %2 = number of registers used. pushes callee-saved regs if needed.
+; %3 = number of xmm registers used. pushes callee-saved xmm regs if needed.
+; %4 = list of names to define to registers
+; PROLOGUE can also be invoked by adding the same options to cglobal
+
+; e.g.
+; cglobal foo, 2,3,0, dst, src, tmp
+; declares a function (foo), taking two args (dst and src) and one local variable (tmp)
+
+; TODO Some functions can use some args directly from the stack. If they're the
+; last args then you can just not declare them, but if they're in the middle
+; we need more flexible macro.
+
+; RET:
+; Pops anything that was pushed by PROLOGUE, and returns.
+
+; REP_RET:
+; Same, but if it doesn't pop anything it becomes a 2-byte ret, for athlons
+; which are slow when a normal ret follows a branch.
+
+; registers:
+; rN and rNq are the native-size register holding function argument N
+; rNd, rNw, rNb are dword, word, and byte size
+; rNm is the original location of arg N (a register or on the stack), dword
+; rNmp is native size
+
+%macro DECLARE_REG 6
+ %define r%1q %2
+ %define r%1d %3
+ %define r%1w %4
+ %define r%1b %5
+ %define r%1m %6
+ %ifid %6 ; i.e. it's a register
+ %define r%1mp %2
+ %elifdef ARCH_X86_64 ; memory
+ %define r%1mp qword %6
+ %else
+ %define r%1mp dword %6
+ %endif
+ %define r%1 %2
+%endmacro
+
+%macro DECLARE_REG_SIZE 2
+ %define r%1q r%1
+ %define e%1q r%1
+ %define r%1d e%1
+ %define e%1d e%1
+ %define r%1w %1
+ %define e%1w %1
+ %define r%1b %2
+ %define e%1b %2
+%ifndef ARCH_X86_64
+ %define r%1 e%1
+%endif
+%endmacro
+
+DECLARE_REG_SIZE ax, al
+DECLARE_REG_SIZE bx, bl
+DECLARE_REG_SIZE cx, cl
+DECLARE_REG_SIZE dx, dl
+DECLARE_REG_SIZE si, sil
+DECLARE_REG_SIZE di, dil
+DECLARE_REG_SIZE bp, bpl
+
+; t# defines for when per-arch register allocation is more complex than just function arguments
+
+%macro DECLARE_REG_TMP 1-*
+ %assign %%i 0
+ %rep %0
+ CAT_XDEFINE t, %%i, r%1
+ %assign %%i %%i+1
+ %rotate 1
+ %endrep
+%endmacro
+
+%macro DECLARE_REG_TMP_SIZE 0-*
+ %rep %0
+ %define t%1q t%1 %+ q
+ %define t%1d t%1 %+ d
+ %define t%1w t%1 %+ w
+ %define t%1b t%1 %+ b
+ %rotate 1
+ %endrep
+%endmacro
+
+DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9
+
+%ifdef ARCH_X86_64
+ %define gprsize 8
+%else
+ %define gprsize 4
+%endif
+
+%macro PUSH 1
+ push %1
+ %assign stack_offset stack_offset+gprsize
+%endmacro
+
+%macro POP 1
+ pop %1
+ %assign stack_offset stack_offset-gprsize
+%endmacro
+
+%macro SUB 2
+ sub %1, %2
+ %ifidn %1, rsp
+ %assign stack_offset stack_offset+(%2)
+ %endif
+%endmacro
+
+%macro ADD 2
+ add %1, %2
+ %ifidn %1, rsp
+ %assign stack_offset stack_offset-(%2)
+ %endif
+%endmacro
+
+%macro movifnidn 2
+ %ifnidn %1, %2
+ mov %1, %2
+ %endif
+%endmacro
+
+%macro movsxdifnidn 2
+ %ifnidn %1, %2
+ movsxd %1, %2
+ %endif
+%endmacro
+
+%macro ASSERT 1
+ %if (%1) == 0
+ %error assert failed
+ %endif
+%endmacro
+
+%macro DEFINE_ARGS 0-*
+ %ifdef n_arg_names
+ %assign %%i 0
+ %rep n_arg_names
+ CAT_UNDEF arg_name %+ %%i, q
+ CAT_UNDEF arg_name %+ %%i, d
+ CAT_UNDEF arg_name %+ %%i, w
+ CAT_UNDEF arg_name %+ %%i, b
+ CAT_UNDEF arg_name %+ %%i, m
+ CAT_UNDEF arg_name, %%i
+ %assign %%i %%i+1
+ %endrep
+ %endif
+
+ %assign %%i 0
+ %rep %0
+ %xdefine %1q r %+ %%i %+ q
+ %xdefine %1d r %+ %%i %+ d
+ %xdefine %1w r %+ %%i %+ w
+ %xdefine %1b r %+ %%i %+ b
+ %xdefine %1m r %+ %%i %+ m
+ CAT_XDEFINE arg_name, %%i, %1
+ %assign %%i %%i+1
+ %rotate 1
+ %endrep
+ %assign n_arg_names %%i
+%endmacro
+
+%ifdef WIN64 ; Windows x64 ;=================================================
+
+DECLARE_REG 0, rcx, ecx, cx, cl, ecx
+DECLARE_REG 1, rdx, edx, dx, dl, edx
+DECLARE_REG 2, r8, r8d, r8w, r8b, r8d
+DECLARE_REG 3, r9, r9d, r9w, r9b, r9d
+DECLARE_REG 4, rdi, edi, di, dil, [rsp + stack_offset + 40]
+DECLARE_REG 5, rsi, esi, si, sil, [rsp + stack_offset + 48]
+DECLARE_REG 6, rax, eax, ax, al, [rsp + stack_offset + 56]
+%define r7m [rsp + stack_offset + 64]
+%define r8m [rsp + stack_offset + 72]
+
+%macro LOAD_IF_USED 2 ; reg_id, number_of_args
+ %if %1 < %2
+ mov r%1, [rsp + stack_offset + 8 + %1*8]
+ %endif
+%endmacro
+
+%macro PROLOGUE 2-4+ 0 ; #args, #regs, #xmm_regs, arg_names...
+ ASSERT %2 >= %1
+ %assign regs_used %2
+ ASSERT regs_used <= 7
+ %if regs_used > 4
+ push r4
+ push r5
+ %assign stack_offset stack_offset+16
+ %endif
+ WIN64_SPILL_XMM %3
+ LOAD_IF_USED 4, %1
+ LOAD_IF_USED 5, %1
+ LOAD_IF_USED 6, %1
+ DEFINE_ARGS %4
+%endmacro
+
+%macro WIN64_SPILL_XMM 1
+ %assign xmm_regs_used %1
+ %if mmsize == 8
+ %assign xmm_regs_used 0
+ %endif
+ ASSERT xmm_regs_used <= 16
+ %if xmm_regs_used > 6
+ sub rsp, (xmm_regs_used-6)*16+16
+ %assign stack_offset stack_offset+(xmm_regs_used-6)*16+16
+ %assign %%i xmm_regs_used
+ %rep (xmm_regs_used-6)
+ %assign %%i %%i-1
+ movdqa [rsp + (%%i-6)*16+8], xmm %+ %%i
+ %endrep
+ %endif
+%endmacro
+
+%macro WIN64_RESTORE_XMM_INTERNAL 1
+ %if xmm_regs_used > 6
+ %assign %%i xmm_regs_used
+ %rep (xmm_regs_used-6)
+ %assign %%i %%i-1
+ movdqa xmm %+ %%i, [%1 + (%%i-6)*16+8]
+ %endrep
+ add %1, (xmm_regs_used-6)*16+16
+ %endif
+%endmacro
+
+%macro WIN64_RESTORE_XMM 1
+ WIN64_RESTORE_XMM_INTERNAL %1
+ %assign stack_offset stack_offset-(xmm_regs_used-6)*16+16
+ %assign xmm_regs_used 0
+%endmacro
+
+%macro RET 0
+ WIN64_RESTORE_XMM_INTERNAL rsp
+ %if regs_used > 4
+ pop r5
+ pop r4
+ %endif
+ ret
+%endmacro
+
+%macro REP_RET 0
+ %if regs_used > 4 || xmm_regs_used > 6
+ RET
+ %else
+ rep ret
+ %endif
+%endmacro
+
+%elifdef ARCH_X86_64 ; *nix x64 ;=============================================
+
+DECLARE_REG 0, rdi, edi, di, dil, edi
+DECLARE_REG 1, rsi, esi, si, sil, esi
+DECLARE_REG 2, rdx, edx, dx, dl, edx
+DECLARE_REG 3, rcx, ecx, cx, cl, ecx
+DECLARE_REG 4, r8, r8d, r8w, r8b, r8d
+DECLARE_REG 5, r9, r9d, r9w, r9b, r9d
+DECLARE_REG 6, rax, eax, ax, al, [rsp + stack_offset + 8]
+%define r7m [rsp + stack_offset + 16]
+%define r8m [rsp + stack_offset + 24]
+
+%macro LOAD_IF_USED 2 ; reg_id, number_of_args
+ %if %1 < %2
+ mov r%1, [rsp - 40 + %1*8]
+ %endif
+%endmacro
+
+%macro PROLOGUE 2-4+ ; #args, #regs, #xmm_regs, arg_names...
+ ASSERT %2 >= %1
+ ASSERT %2 <= 7
+ LOAD_IF_USED 6, %1
+ DEFINE_ARGS %4
+%endmacro
+
+%macro RET 0
+ ret
+%endmacro
+
+%macro REP_RET 0
+ rep ret
+%endmacro
+
+%else ; X86_32 ;==============================================================
+
+DECLARE_REG 0, eax, eax, ax, al, [esp + stack_offset + 4]
+DECLARE_REG 1, ecx, ecx, cx, cl, [esp + stack_offset + 8]
+DECLARE_REG 2, edx, edx, dx, dl, [esp + stack_offset + 12]
+DECLARE_REG 3, ebx, ebx, bx, bl, [esp + stack_offset + 16]
+DECLARE_REG 4, esi, esi, si, null, [esp + stack_offset + 20]
+DECLARE_REG 5, edi, edi, di, null, [esp + stack_offset + 24]
+DECLARE_REG 6, ebp, ebp, bp, null, [esp + stack_offset + 28]
+%define r7m [esp + stack_offset + 32]
+%define r8m [esp + stack_offset + 36]
+%define rsp esp
+
+%macro PUSH_IF_USED 1 ; reg_id
+ %if %1 < regs_used
+ push r%1
+ %assign stack_offset stack_offset+4
+ %endif
+%endmacro
+
+%macro POP_IF_USED 1 ; reg_id
+ %if %1 < regs_used
+ pop r%1
+ %endif
+%endmacro
+
+%macro LOAD_IF_USED 2 ; reg_id, number_of_args
+ %if %1 < %2
+ mov r%1, [esp + stack_offset + 4 + %1*4]
+ %endif
+%endmacro
+
+%macro PROLOGUE 2-4+ ; #args, #regs, #xmm_regs, arg_names...
+ ASSERT %2 >= %1
+ %assign regs_used %2
+ ASSERT regs_used <= 7
+ PUSH_IF_USED 3
+ PUSH_IF_USED 4
+ PUSH_IF_USED 5
+ PUSH_IF_USED 6
+ LOAD_IF_USED 0, %1
+ LOAD_IF_USED 1, %1
+ LOAD_IF_USED 2, %1
+ LOAD_IF_USED 3, %1
+ LOAD_IF_USED 4, %1
+ LOAD_IF_USED 5, %1
+ LOAD_IF_USED 6, %1
+ DEFINE_ARGS %4
+%endmacro
+
+%macro RET 0
+ POP_IF_USED 6
+ POP_IF_USED 5
+ POP_IF_USED 4
+ POP_IF_USED 3
+ ret
+%endmacro
+
+%macro REP_RET 0
+ %if regs_used > 3
+ RET
+ %else
+ rep ret
+ %endif
+%endmacro
+
+%endif ;======================================================================
+
+%ifndef WIN64
+%macro WIN64_SPILL_XMM 1
+%endmacro
+%macro WIN64_RESTORE_XMM 1
+%endmacro
+%endif
+
+
+
+;=============================================================================
+; arch-independent part
+;=============================================================================
+
+%assign function_align 16
+
+; Begin a function.
+; Applies any symbol mangling needed for C linkage, and sets up a define such that
+; subsequent uses of the function name automatically refer to the mangled version.
+; Appends cpuflags to the function name if cpuflags has been specified.
+%macro cglobal 1-2+ ; name, [PROLOGUE args]
+%if %0 == 1
+ cglobal_internal %1 %+ SUFFIX
+%else
+ cglobal_internal %1 %+ SUFFIX, %2
+%endif
+%endmacro
+%macro cglobal_internal 1-2+
+ %ifndef cglobaled_%1
+ %xdefine %1 mangle(program_name %+ _ %+ %1)
+ %xdefine %1.skip_prologue %1 %+ .skip_prologue
+ CAT_XDEFINE cglobaled_, %1, 1
+ %endif
+ %xdefine current_function %1
+ %ifidn __OUTPUT_FORMAT__,elf
+ global %1:function hidden
+ %else
+ global %1
+ %endif
+ align function_align
+ %1:
+ RESET_MM_PERMUTATION ; not really needed, but makes disassembly somewhat nicer
+ %assign stack_offset 0
+ %if %0 > 1
+ PROLOGUE %2
+ %endif
+%endmacro
+
+%macro cextern 1
+ %xdefine %1 mangle(program_name %+ _ %+ %1)
+ CAT_XDEFINE cglobaled_, %1, 1
+ extern %1
+%endmacro
+
+; like cextern, but without the prefix
+%macro cextern_naked 1
+ %xdefine %1 mangle(%1)
+ CAT_XDEFINE cglobaled_, %1, 1
+ extern %1
+%endmacro
+
+%macro const 2+
+ %xdefine %1 mangle(program_name %+ _ %+ %1)
+ global %1
+ %1: %2
+%endmacro
+
+; This is needed for ELF, otherwise the GNU linker assumes the stack is
+; executable by default.
+%ifidn __OUTPUT_FORMAT__,elf
+SECTION .note.GNU-stack noalloc noexec nowrite progbits
+%endif
+
+; cpuflags
+
+%assign cpuflags_mmx (1<<0)
+%assign cpuflags_mmx2 (1<<1) | cpuflags_mmx
+%assign cpuflags_3dnow (1<<2) | cpuflags_mmx
+%assign cpuflags_3dnow2 (1<<3) | cpuflags_3dnow
+%assign cpuflags_sse (1<<4) | cpuflags_mmx2
+%assign cpuflags_sse2 (1<<5) | cpuflags_sse
+%assign cpuflags_sse2slow (1<<6) | cpuflags_sse2
+%assign cpuflags_sse3 (1<<7) | cpuflags_sse2
+%assign cpuflags_ssse3 (1<<8) | cpuflags_sse3
+%assign cpuflags_sse4 (1<<9) | cpuflags_ssse3
+%assign cpuflags_sse42 (1<<10)| cpuflags_sse4
+%assign cpuflags_avx (1<<11)| cpuflags_sse42
+%assign cpuflags_xop (1<<12)| cpuflags_avx
+%assign cpuflags_fma4 (1<<13)| cpuflags_avx
+
+%assign cpuflags_cache32 (1<<16)
+%assign cpuflags_cache64 (1<<17)
+%assign cpuflags_slowctz (1<<18)
+%assign cpuflags_lzcnt (1<<19)
+%assign cpuflags_misalign (1<<20)
+%assign cpuflags_aligned (1<<21) ; not a cpu feature, but a function variant
+%assign cpuflags_atom (1<<22)
+
+%define cpuflag(x) ((cpuflags & (cpuflags_ %+ x)) == (cpuflags_ %+ x))
+%define notcpuflag(x) ((cpuflags & (cpuflags_ %+ x)) != (cpuflags_ %+ x))
+
+; Takes up to 2 cpuflags from the above list.
+; All subsequent functions (up to the next INIT_CPUFLAGS) is built for the specified cpu.
+; You shouldn't need to invoke this macro directly, it's a subroutine for INIT_MMX &co.
+%macro INIT_CPUFLAGS 0-2
+ %if %0 >= 1
+ %xdefine cpuname %1
+ %assign cpuflags cpuflags_%1
+ %if %0 >= 2
+ %xdefine cpuname %1_%2
+ %assign cpuflags cpuflags | cpuflags_%2
+ %endif
+ %xdefine SUFFIX _ %+ cpuname
+ %if cpuflag(avx)
+ %assign avx_enabled 1
+ %endif
+ %if mmsize == 16 && notcpuflag(sse2)
+ %define mova movaps
+ %define movu movups
+ %define movnta movntps
+ %endif
+ %if cpuflag(aligned)
+ %define movu mova
+ %elifidn %1, sse3
+ %define movu lddqu
+ %endif
+ %else
+ %xdefine SUFFIX
+ %undef cpuname
+ %undef cpuflags
+ %endif
+%endmacro
+
+; merge mmx and sse*
+
+%macro CAT_XDEFINE 3
+ %xdefine %1%2 %3
+%endmacro
+
+%macro CAT_UNDEF 2
+ %undef %1%2
+%endmacro
+
+%macro INIT_MMX 0-1+
+ %assign avx_enabled 0
+ %define RESET_MM_PERMUTATION INIT_MMX %1
+ %define mmsize 8
+ %define num_mmregs 8
+ %define mova movq
+ %define movu movq
+ %define movh movd
+ %define movnta movntq
+ %assign %%i 0
+ %rep 8
+ CAT_XDEFINE m, %%i, mm %+ %%i
+ CAT_XDEFINE nmm, %%i, %%i
+ %assign %%i %%i+1
+ %endrep
+ %rep 8
+ CAT_UNDEF m, %%i
+ CAT_UNDEF nmm, %%i
+ %assign %%i %%i+1
+ %endrep
+ INIT_CPUFLAGS %1
+%endmacro
+
+%macro INIT_XMM 0-1+
+ %assign avx_enabled 0
+ %define RESET_MM_PERMUTATION INIT_XMM %1
+ %define mmsize 16
+ %define num_mmregs 8
+ %ifdef ARCH_X86_64
+ %define num_mmregs 16
+ %endif
+ %define mova movdqa
+ %define movu movdqu
+ %define movh movq
+ %define movnta movntdq
+ %assign %%i 0
+ %rep num_mmregs
+ CAT_XDEFINE m, %%i, xmm %+ %%i
+ CAT_XDEFINE nxmm, %%i, %%i
+ %assign %%i %%i+1
+ %endrep
+ INIT_CPUFLAGS %1
+%endmacro
+
+; FIXME: INIT_AVX can be replaced by INIT_XMM avx
+%macro INIT_AVX 0
+ INIT_XMM
+ %assign avx_enabled 1
+ %define PALIGNR PALIGNR_SSSE3
+ %define RESET_MM_PERMUTATION INIT_AVX
+%endmacro
+
+%macro INIT_YMM 0-1+
+ %assign avx_enabled 1
+ %define RESET_MM_PERMUTATION INIT_YMM %1
+ %define mmsize 32
+ %define num_mmregs 8
+ %ifdef ARCH_X86_64
+ %define num_mmregs 16
+ %endif
+ %define mova vmovaps
+ %define movu vmovups
+ %undef movh
+ %define movnta vmovntps
+ %assign %%i 0
+ %rep num_mmregs
+ CAT_XDEFINE m, %%i, ymm %+ %%i
+ CAT_XDEFINE nymm, %%i, %%i
+ %assign %%i %%i+1
+ %endrep
+ INIT_CPUFLAGS %1
+%endmacro
+
+INIT_XMM
+
+; I often want to use macros that permute their arguments. e.g. there's no
+; efficient way to implement butterfly or transpose or dct without swapping some
+; arguments.
+;
+; I would like to not have to manually keep track of the permutations:
+; If I insert a permutation in the middle of a function, it should automatically
+; change everything that follows. For more complex macros I may also have multiple
+; implementations, e.g. the SSE2 and SSSE3 versions may have different permutations.
+;
+; Hence these macros. Insert a PERMUTE or some SWAPs at the end of a macro that
+; permutes its arguments. It's equivalent to exchanging the contents of the
+; registers, except that this way you exchange the register names instead, so it
+; doesn't cost any cycles.
+
+%macro PERMUTE 2-* ; takes a list of pairs to swap
+%rep %0/2
+ %xdefine tmp%2 m%2
+ %xdefine ntmp%2 nm%2
+ %rotate 2
+%endrep
+%rep %0/2
+ %xdefine m%1 tmp%2
+ %xdefine nm%1 ntmp%2
+ %undef tmp%2
+ %undef ntmp%2
+ %rotate 2
+%endrep
+%endmacro
+
+%macro SWAP 2-* ; swaps a single chain (sometimes more concise than pairs)
+%rep %0-1
+%ifdef m%1
+ %xdefine tmp m%1
+ %xdefine m%1 m%2
+ %xdefine m%2 tmp
+ CAT_XDEFINE n, m%1, %1
+ CAT_XDEFINE n, m%2, %2
+%else
+ ; If we were called as "SWAP m0,m1" rather than "SWAP 0,1" infer the original numbers here.
+ ; Be careful using this mode in nested macros though, as in some cases there may be
+ ; other copies of m# that have already been dereferenced and don't get updated correctly.
+ %xdefine %%n1 n %+ %1
+ %xdefine %%n2 n %+ %2
+ %xdefine tmp m %+ %%n1
+ CAT_XDEFINE m, %%n1, m %+ %%n2
+ CAT_XDEFINE m, %%n2, tmp
+ CAT_XDEFINE n, m %+ %%n1, %%n1
+ CAT_XDEFINE n, m %+ %%n2, %%n2
+%endif
+ %undef tmp
+ %rotate 1
+%endrep
+%endmacro
+
+; If SAVE_MM_PERMUTATION is placed at the end of a function, then any later
+; calls to that function will automatically load the permutation, so values can
+; be returned in mmregs.
+%macro SAVE_MM_PERMUTATION 0-1
+ %if %0
+ %xdefine %%f %1_m
+ %else
+ %xdefine %%f current_function %+ _m
+ %endif
+ %assign %%i 0
+ %rep num_mmregs
+ CAT_XDEFINE %%f, %%i, m %+ %%i
+ %assign %%i %%i+1
+ %endrep
+%endmacro
+
+%macro LOAD_MM_PERMUTATION 1 ; name to load from
+ %ifdef %1_m0
+ %assign %%i 0
+ %rep num_mmregs
+ CAT_XDEFINE m, %%i, %1_m %+ %%i
+ CAT_XDEFINE n, m %+ %%i, %%i
+ %assign %%i %%i+1
+ %endrep
+ %endif
+%endmacro
+
+; Append cpuflags to the callee's name iff the appended name is known and the plain name isn't
+%macro call 1
+ call_internal %1, %1 %+ SUFFIX
+%endmacro
+%macro call_internal 2
+ %xdefine %%i %1
+ %ifndef cglobaled_%1
+ %ifdef cglobaled_%2
+ %xdefine %%i %2
+ %endif
+ %endif
+ call %%i
+ LOAD_MM_PERMUTATION %%i
+%endmacro
+
+; Substitutions that reduce instruction size but are functionally equivalent
+%macro add 2
+ %ifnum %2
+ %if %2==128
+ sub %1, -128
+ %else
+ add %1, %2
+ %endif
+ %else
+ add %1, %2
+ %endif
+%endmacro
+
+%macro sub 2
+ %ifnum %2
+ %if %2==128
+ add %1, -128
+ %else
+ sub %1, %2
+ %endif
+ %else
+ sub %1, %2
+ %endif
+%endmacro
+
+;=============================================================================
+; AVX abstraction layer
+;=============================================================================
+
+%assign i 0
+%rep 16
+ %if i < 8
+ CAT_XDEFINE sizeofmm, i, 8
+ %endif
+ CAT_XDEFINE sizeofxmm, i, 16
+ CAT_XDEFINE sizeofymm, i, 32
+%assign i i+1
+%endrep
+%undef i
+
+;%1 == instruction
+;%2 == 1 if float, 0 if int
+;%3 == 1 if 4-operand (xmm, xmm, xmm, imm), 0 if 3-operand (xmm, xmm, xmm)
+;%4 == number of operands given
+;%5+: operands
+%macro RUN_AVX_INSTR 6-7+
+ %ifid %5
+ %define %%size sizeof%5
+ %else
+ %define %%size mmsize
+ %endif
+ %if %%size==32
+ v%1 %5, %6, %7
+ %else
+ %if %%size==8
+ %define %%regmov movq
+ %elif %2
+ %define %%regmov movaps
+ %else
+ %define %%regmov movdqa
+ %endif
+
+ %if %4>=3+%3
+ %ifnidn %5, %6
+ %if avx_enabled && sizeof%5==16
+ v%1 %5, %6, %7
+ %else
+ %%regmov %5, %6
+ %1 %5, %7
+ %endif
+ %else
+ %1 %5, %7
+ %endif
+ %elif %3
+ %1 %5, %6, %7
+ %else
+ %1 %5, %6
+ %endif
+ %endif
+%endmacro
+
+; 3arg AVX ops with a memory arg can only have it in src2,
+; whereas SSE emulation of 3arg prefers to have it in src1 (i.e. the mov).
+; So, if the op is symmetric and the wrong one is memory, swap them.
+%macro RUN_AVX_INSTR1 8
+ %assign %%swap 0
+ %if avx_enabled
+ %ifnid %6
+ %assign %%swap 1
+ %endif
+ %elifnidn %5, %6
+ %ifnid %7
+ %assign %%swap 1
+ %endif
+ %endif
+ %if %%swap && %3 == 0 && %8 == 1
+ RUN_AVX_INSTR %1, %2, %3, %4, %5, %7, %6
+ %else
+ RUN_AVX_INSTR %1, %2, %3, %4, %5, %6, %7
+ %endif
+%endmacro
+
+;%1 == instruction
+;%2 == 1 if float, 0 if int
+;%3 == 1 if 4-operand (xmm, xmm, xmm, imm), 0 if 3-operand (xmm, xmm, xmm)
+;%4 == 1 if symmetric (i.e. doesn't matter which src arg is which), 0 if not
+%macro AVX_INSTR 4
+ %macro %1 2-9 fnord, fnord, fnord, %1, %2, %3, %4
+ %ifidn %3, fnord
+ RUN_AVX_INSTR %6, %7, %8, 2, %1, %2
+ %elifidn %4, fnord
+ RUN_AVX_INSTR1 %6, %7, %8, 3, %1, %2, %3, %9
+ %elifidn %5, fnord
+ RUN_AVX_INSTR %6, %7, %8, 4, %1, %2, %3, %4
+ %else
+ RUN_AVX_INSTR %6, %7, %8, 5, %1, %2, %3, %4, %5
+ %endif
+ %endmacro
+%endmacro
+
+AVX_INSTR addpd, 1, 0, 1
+AVX_INSTR addps, 1, 0, 1
+AVX_INSTR addsd, 1, 0, 1
+AVX_INSTR addss, 1, 0, 1
+AVX_INSTR addsubpd, 1, 0, 0
+AVX_INSTR addsubps, 1, 0, 0
+AVX_INSTR andpd, 1, 0, 1
+AVX_INSTR andps, 1, 0, 1
+AVX_INSTR andnpd, 1, 0, 0
+AVX_INSTR andnps, 1, 0, 0
+AVX_INSTR blendpd, 1, 0, 0
+AVX_INSTR blendps, 1, 0, 0
+AVX_INSTR blendvpd, 1, 0, 0
+AVX_INSTR blendvps, 1, 0, 0
+AVX_INSTR cmppd, 1, 0, 0
+AVX_INSTR cmpps, 1, 0, 0
+AVX_INSTR cmpsd, 1, 0, 0
+AVX_INSTR cmpss, 1, 0, 0
+AVX_INSTR divpd, 1, 0, 0
+AVX_INSTR divps, 1, 0, 0
+AVX_INSTR divsd, 1, 0, 0
+AVX_INSTR divss, 1, 0, 0
+AVX_INSTR dppd, 1, 1, 0
+AVX_INSTR dpps, 1, 1, 0
+AVX_INSTR haddpd, 1, 0, 0
+AVX_INSTR haddps, 1, 0, 0
+AVX_INSTR hsubpd, 1, 0, 0
+AVX_INSTR hsubps, 1, 0, 0
+AVX_INSTR maxpd, 1, 0, 1
+AVX_INSTR maxps, 1, 0, 1
+AVX_INSTR maxsd, 1, 0, 1
+AVX_INSTR maxss, 1, 0, 1
+AVX_INSTR minpd, 1, 0, 1
+AVX_INSTR minps, 1, 0, 1
+AVX_INSTR minsd, 1, 0, 1
+AVX_INSTR minss, 1, 0, 1
+AVX_INSTR movsd, 1, 0, 0
+AVX_INSTR movss, 1, 0, 0
+AVX_INSTR mpsadbw, 0, 1, 0
+AVX_INSTR mulpd, 1, 0, 1
+AVX_INSTR mulps, 1, 0, 1
+AVX_INSTR mulsd, 1, 0, 1
+AVX_INSTR mulss, 1, 0, 1
+AVX_INSTR orpd, 1, 0, 1
+AVX_INSTR orps, 1, 0, 1
+AVX_INSTR packsswb, 0, 0, 0
+AVX_INSTR packssdw, 0, 0, 0
+AVX_INSTR packuswb, 0, 0, 0
+AVX_INSTR packusdw, 0, 0, 0
+AVX_INSTR paddb, 0, 0, 1
+AVX_INSTR paddw, 0, 0, 1
+AVX_INSTR paddd, 0, 0, 1
+AVX_INSTR paddq, 0, 0, 1
+AVX_INSTR paddsb, 0, 0, 1
+AVX_INSTR paddsw, 0, 0, 1
+AVX_INSTR paddusb, 0, 0, 1
+AVX_INSTR paddusw, 0, 0, 1
+AVX_INSTR palignr, 0, 1, 0
+AVX_INSTR pand, 0, 0, 1
+AVX_INSTR pandn, 0, 0, 0
+AVX_INSTR pavgb, 0, 0, 1
+AVX_INSTR pavgw, 0, 0, 1
+AVX_INSTR pblendvb, 0, 0, 0
+AVX_INSTR pblendw, 0, 1, 0
+AVX_INSTR pcmpestri, 0, 0, 0
+AVX_INSTR pcmpestrm, 0, 0, 0
+AVX_INSTR pcmpistri, 0, 0, 0
+AVX_INSTR pcmpistrm, 0, 0, 0
+AVX_INSTR pcmpeqb, 0, 0, 1
+AVX_INSTR pcmpeqw, 0, 0, 1
+AVX_INSTR pcmpeqd, 0, 0, 1
+AVX_INSTR pcmpeqq, 0, 0, 1
+AVX_INSTR pcmpgtb, 0, 0, 0
+AVX_INSTR pcmpgtw, 0, 0, 0
+AVX_INSTR pcmpgtd, 0, 0, 0
+AVX_INSTR pcmpgtq, 0, 0, 0
+AVX_INSTR phaddw, 0, 0, 0
+AVX_INSTR phaddd, 0, 0, 0
+AVX_INSTR phaddsw, 0, 0, 0
+AVX_INSTR phsubw, 0, 0, 0
+AVX_INSTR phsubd, 0, 0, 0
+AVX_INSTR phsubsw, 0, 0, 0
+AVX_INSTR pmaddwd, 0, 0, 1
+AVX_INSTR pmaddubsw, 0, 0, 0
+AVX_INSTR pmaxsb, 0, 0, 1
+AVX_INSTR pmaxsw, 0, 0, 1
+AVX_INSTR pmaxsd, 0, 0, 1
+AVX_INSTR pmaxub, 0, 0, 1
+AVX_INSTR pmaxuw, 0, 0, 1
+AVX_INSTR pmaxud, 0, 0, 1
+AVX_INSTR pminsb, 0, 0, 1
+AVX_INSTR pminsw, 0, 0, 1
+AVX_INSTR pminsd, 0, 0, 1
+AVX_INSTR pminub, 0, 0, 1
+AVX_INSTR pminuw, 0, 0, 1
+AVX_INSTR pminud, 0, 0, 1
+AVX_INSTR pmulhuw, 0, 0, 1
+AVX_INSTR pmulhrsw, 0, 0, 1
+AVX_INSTR pmulhw, 0, 0, 1
+AVX_INSTR pmullw, 0, 0, 1
+AVX_INSTR pmulld, 0, 0, 1
+AVX_INSTR pmuludq, 0, 0, 1
+AVX_INSTR pmuldq, 0, 0, 1
+AVX_INSTR por, 0, 0, 1
+AVX_INSTR psadbw, 0, 0, 1
+AVX_INSTR pshufb, 0, 0, 0
+AVX_INSTR psignb, 0, 0, 0
+AVX_INSTR psignw, 0, 0, 0
+AVX_INSTR psignd, 0, 0, 0
+AVX_INSTR psllw, 0, 0, 0
+AVX_INSTR pslld, 0, 0, 0
+AVX_INSTR psllq, 0, 0, 0
+AVX_INSTR pslldq, 0, 0, 0
+AVX_INSTR psraw, 0, 0, 0
+AVX_INSTR psrad, 0, 0, 0
+AVX_INSTR psrlw, 0, 0, 0
+AVX_INSTR psrld, 0, 0, 0
+AVX_INSTR psrlq, 0, 0, 0
+AVX_INSTR psrldq, 0, 0, 0
+AVX_INSTR psubb, 0, 0, 0
+AVX_INSTR psubw, 0, 0, 0
+AVX_INSTR psubd, 0, 0, 0
+AVX_INSTR psubq, 0, 0, 0
+AVX_INSTR psubsb, 0, 0, 0
+AVX_INSTR psubsw, 0, 0, 0
+AVX_INSTR psubusb, 0, 0, 0
+AVX_INSTR psubusw, 0, 0, 0
+AVX_INSTR punpckhbw, 0, 0, 0
+AVX_INSTR punpckhwd, 0, 0, 0
+AVX_INSTR punpckhdq, 0, 0, 0
+AVX_INSTR punpckhqdq, 0, 0, 0
+AVX_INSTR punpcklbw, 0, 0, 0
+AVX_INSTR punpcklwd, 0, 0, 0
+AVX_INSTR punpckldq, 0, 0, 0
+AVX_INSTR punpcklqdq, 0, 0, 0
+AVX_INSTR pxor, 0, 0, 1
+AVX_INSTR shufps, 1, 1, 0
+AVX_INSTR subpd, 1, 0, 0
+AVX_INSTR subps, 1, 0, 0
+AVX_INSTR subsd, 1, 0, 0
+AVX_INSTR subss, 1, 0, 0
+AVX_INSTR unpckhpd, 1, 0, 0
+AVX_INSTR unpckhps, 1, 0, 0
+AVX_INSTR unpcklpd, 1, 0, 0
+AVX_INSTR unpcklps, 1, 0, 0
+AVX_INSTR xorpd, 1, 0, 1
+AVX_INSTR xorps, 1, 0, 1
+
+; 3DNow instructions, for sharing code between AVX, SSE and 3DN
+AVX_INSTR pfadd, 1, 0, 1
+AVX_INSTR pfsub, 1, 0, 0
+AVX_INSTR pfmul, 1, 0, 1
+
+; base-4 constants for shuffles
+%assign i 0
+%rep 256
+ %assign j ((i>>6)&3)*1000 + ((i>>4)&3)*100 + ((i>>2)&3)*10 + (i&3)
+ %if j < 10
+ CAT_XDEFINE q000, j, i
+ %elif j < 100
+ CAT_XDEFINE q00, j, i
+ %elif j < 1000
+ CAT_XDEFINE q0, j, i
+ %else
+ CAT_XDEFINE q, j, i
+ %endif
+%assign i i+1
+%endrep
+%undef i
+%undef j
+
+%macro FMA_INSTR 3
+ %macro %1 4-7 %1, %2, %3
+ %if cpuflag(xop)
+ v%5 %1, %2, %3, %4
+ %else
+ %6 %1, %2, %3
+ %7 %1, %4
+ %endif
+ %endmacro
+%endmacro
+
+FMA_INSTR pmacsdd, pmulld, paddd
+FMA_INSTR pmacsww, pmullw, paddw
+FMA_INSTR pmadcswd, pmaddwd, paddd
diff --git a/libavutil/x86/x86util.asm b/libavutil/x86/x86util.asm
new file mode 100644
index 0000000..874443a
--- /dev/null
+++ b/libavutil/x86/x86util.asm
@@ -0,0 +1,587 @@
+;*****************************************************************************
+;* x86util.asm
+;*****************************************************************************
+;* Copyright (C) 2008-2010 x264 project
+;*
+;* Authors: Loren Merritt <lorenm at u.washington.edu>
+;* Holger Lubitz <holger at lubitz.org>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%macro SBUTTERFLY 4
+%if avx_enabled == 0
+ mova m%4, m%2
+ punpckl%1 m%2, m%3
+ punpckh%1 m%4, m%3
+%else
+ punpckh%1 m%4, m%2, m%3
+ punpckl%1 m%2, m%3
+%endif
+ SWAP %3, %4
+%endmacro
+
+%macro SBUTTERFLY2 4
+ punpckl%1 m%4, m%2, m%3
+ punpckh%1 m%2, m%2, m%3
+ SWAP %2, %4, %3
+%endmacro
+
+%macro SBUTTERFLYPS 3
+ movaps m%3, m%1
+ unpcklps m%1, m%2
+ unpckhps m%3, m%2
+ SWAP %2, %3
+%endmacro
+
+%macro TRANSPOSE4x4B 5
+ SBUTTERFLY bw, %1, %2, %5
+ SBUTTERFLY bw, %3, %4, %5
+ SBUTTERFLY wd, %1, %3, %5
+ SBUTTERFLY wd, %2, %4, %5
+ SWAP %2, %3
+%endmacro
+
+%macro TRANSPOSE4x4W 5
+ SBUTTERFLY wd, %1, %2, %5
+ SBUTTERFLY wd, %3, %4, %5
+ SBUTTERFLY dq, %1, %3, %5
+ SBUTTERFLY dq, %2, %4, %5
+ SWAP %2, %3
+%endmacro
+
+%macro TRANSPOSE2x4x4W 5
+ SBUTTERFLY wd, %1, %2, %5
+ SBUTTERFLY wd, %3, %4, %5
+ SBUTTERFLY dq, %1, %3, %5
+ SBUTTERFLY dq, %2, %4, %5
+ SBUTTERFLY qdq, %1, %2, %5
+ SBUTTERFLY qdq, %3, %4, %5
+%endmacro
+
+%macro TRANSPOSE4x4D 5
+ SBUTTERFLY dq, %1, %2, %5
+ SBUTTERFLY dq, %3, %4, %5
+ SBUTTERFLY qdq, %1, %3, %5
+ SBUTTERFLY qdq, %2, %4, %5
+ SWAP %2, %3
+%endmacro
+
+; identical behavior to TRANSPOSE4x4D, but using SSE1 float ops
+%macro TRANSPOSE4x4PS 5
+ SBUTTERFLYPS %1, %2, %5
+ SBUTTERFLYPS %3, %4, %5
+ movaps m%5, m%1
+ movlhps m%1, m%3
+ movhlps m%3, m%5
+ movaps m%5, m%2
+ movlhps m%2, m%4
+ movhlps m%4, m%5
+ SWAP %2, %3
+%endmacro
+
+%macro TRANSPOSE8x8W 9-11
+%ifdef ARCH_X86_64
+ SBUTTERFLY wd, %1, %2, %9
+ SBUTTERFLY wd, %3, %4, %9
+ SBUTTERFLY wd, %5, %6, %9
+ SBUTTERFLY wd, %7, %8, %9
+ SBUTTERFLY dq, %1, %3, %9
+ SBUTTERFLY dq, %2, %4, %9
+ SBUTTERFLY dq, %5, %7, %9
+ SBUTTERFLY dq, %6, %8, %9
+ SBUTTERFLY qdq, %1, %5, %9
+ SBUTTERFLY qdq, %2, %6, %9
+ SBUTTERFLY qdq, %3, %7, %9
+ SBUTTERFLY qdq, %4, %8, %9
+ SWAP %2, %5
+ SWAP %4, %7
+%else
+; in: m0..m7, unless %11 in which case m6 is in %9
+; out: m0..m7, unless %11 in which case m4 is in %10
+; spills into %9 and %10
+%if %0<11
+ movdqa %9, m%7
+%endif
+ SBUTTERFLY wd, %1, %2, %7
+ movdqa %10, m%2
+ movdqa m%7, %9
+ SBUTTERFLY wd, %3, %4, %2
+ SBUTTERFLY wd, %5, %6, %2
+ SBUTTERFLY wd, %7, %8, %2
+ SBUTTERFLY dq, %1, %3, %2
+ movdqa %9, m%3
+ movdqa m%2, %10
+ SBUTTERFLY dq, %2, %4, %3
+ SBUTTERFLY dq, %5, %7, %3
+ SBUTTERFLY dq, %6, %8, %3
+ SBUTTERFLY qdq, %1, %5, %3
+ SBUTTERFLY qdq, %2, %6, %3
+ movdqa %10, m%2
+ movdqa m%3, %9
+ SBUTTERFLY qdq, %3, %7, %2
+ SBUTTERFLY qdq, %4, %8, %2
+ SWAP %2, %5
+ SWAP %4, %7
+%if %0<11
+ movdqa m%5, %10
+%endif
+%endif
+%endmacro
+
+; PABSW macros assume %1 != %2, while ABS1/2 macros work in-place
+%macro PABSW_MMX 2
+ pxor %1, %1
+ pcmpgtw %1, %2
+ pxor %2, %1
+ psubw %2, %1
+ SWAP %1, %2
+%endmacro
+
+%macro PSIGNW_MMX 2
+ pxor %1, %2
+ psubw %1, %2
+%endmacro
+
+%macro PABSW_MMX2 2
+ pxor %1, %1
+ psubw %1, %2
+ pmaxsw %1, %2
+%endmacro
+
+%macro PABSW_SSSE3 2
+ pabsw %1, %2
+%endmacro
+
+%macro PSIGNW_SSSE3 2
+ psignw %1, %2
+%endmacro
+
+%macro ABS1_MMX 2 ; a, tmp
+ pxor %2, %2
+ pcmpgtw %2, %1
+ pxor %1, %2
+ psubw %1, %2
+%endmacro
+
+%macro ABS2_MMX 4 ; a, b, tmp0, tmp1
+ pxor %3, %3
+ pxor %4, %4
+ pcmpgtw %3, %1
+ pcmpgtw %4, %2
+ pxor %1, %3
+ pxor %2, %4
+ psubw %1, %3
+ psubw %2, %4
+%endmacro
+
+%macro ABS1_MMX2 2 ; a, tmp
+ pxor %2, %2
+ psubw %2, %1
+ pmaxsw %1, %2
+%endmacro
+
+%macro ABS2_MMX2 4 ; a, b, tmp0, tmp1
+ pxor %3, %3
+ pxor %4, %4
+ psubw %3, %1
+ psubw %4, %2
+ pmaxsw %1, %3
+ pmaxsw %2, %4
+%endmacro
+
+%macro ABS1_SSSE3 2
+ pabsw %1, %1
+%endmacro
+
+%macro ABS2_SSSE3 4
+ pabsw %1, %1
+ pabsw %2, %2
+%endmacro
+
+%macro ABSB_MMX 2
+ pxor %2, %2
+ psubb %2, %1
+ pminub %1, %2
+%endmacro
+
+%macro ABSB2_MMX 4
+ pxor %3, %3
+ pxor %4, %4
+ psubb %3, %1
+ psubb %4, %2
+ pminub %1, %3
+ pminub %2, %4
+%endmacro
+
+%macro ABSD2_MMX 4
+ pxor %3, %3
+ pxor %4, %4
+ pcmpgtd %3, %1
+ pcmpgtd %4, %2
+ pxor %1, %3
+ pxor %2, %4
+ psubd %1, %3
+ psubd %2, %4
+%endmacro
+
+%macro ABSB_SSSE3 2
+ pabsb %1, %1
+%endmacro
+
+%macro ABSB2_SSSE3 4
+ pabsb %1, %1
+ pabsb %2, %2
+%endmacro
+
+%macro ABS4 6
+ ABS2 %1, %2, %5, %6
+ ABS2 %3, %4, %5, %6
+%endmacro
+
+%define ABS1 ABS1_MMX
+%define ABS2 ABS2_MMX
+%define ABSB ABSB_MMX
+%define ABSB2 ABSB2_MMX
+
+%macro SPLATB_MMX 3
+ movd %1, [%2-3] ;to avoid crossing a cacheline
+ punpcklbw %1, %1
+ SPLATW %1, %1, 3
+%endmacro
+
+%macro SPLATB_SSSE3 3
+ movd %1, [%2-3]
+ pshufb %1, %3
+%endmacro
+
+%macro PALIGNR_MMX 4-5 ; [dst,] src1, src2, imm, tmp
+ %define %%dst %1
+%if %0==5
+%ifnidn %1, %2
+ mova %%dst, %2
+%endif
+ %rotate 1
+%endif
+%ifnidn %4, %2
+ mova %4, %2
+%endif
+%if mmsize==8
+ psllq %%dst, (8-%3)*8
+ psrlq %4, %3*8
+%else
+ pslldq %%dst, 16-%3
+ psrldq %4, %3
+%endif
+ por %%dst, %4
+%endmacro
+
+%macro PALIGNR_SSSE3 4-5
+%if %0==5
+ palignr %1, %2, %3, %4
+%else
+ palignr %1, %2, %3
+%endif
+%endmacro
+
+%macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
+%ifnum %5
+ pand m%3, m%5, m%4 ; src .. y6 .. y4
+ pand m%1, m%5, m%2 ; dst .. y6 .. y4
+%else
+ mova m%1, %5
+ pand m%3, m%1, m%4 ; src .. y6 .. y4
+ pand m%1, m%1, m%2 ; dst .. y6 .. y4
+%endif
+ psrlw m%2, 8 ; dst .. y7 .. y5
+ psrlw m%4, 8 ; src .. y7 .. y5
+%endmacro
+
+%macro SUMSUB_BA 3-4
+%if %0==3
+ padd%1 m%2, m%3
+ padd%1 m%3, m%3
+ psub%1 m%3, m%2
+%else
+%if avx_enabled == 0
+ mova m%4, m%2
+ padd%1 m%2, m%3
+ psub%1 m%3, m%4
+%else
+ padd%1 m%4, m%2, m%3
+ psub%1 m%3, m%2
+ SWAP %2, %4
+%endif
+%endif
+%endmacro
+
+%macro SUMSUB_BADC 5-6
+%if %0==6
+ SUMSUB_BA %1, %2, %3, %6
+ SUMSUB_BA %1, %4, %5, %6
+%else
+ padd%1 m%2, m%3
+ padd%1 m%4, m%5
+ padd%1 m%3, m%3
+ padd%1 m%5, m%5
+ psub%1 m%3, m%2
+ psub%1 m%5, m%4
+%endif
+%endmacro
+
+%macro SUMSUB2_AB 4
+%ifnum %3
+ psub%1 m%4, m%2, m%3
+ psub%1 m%4, m%3
+ padd%1 m%2, m%2
+ padd%1 m%2, m%3
+%else
+ mova m%4, m%2
+ padd%1 m%2, m%2
+ padd%1 m%2, %3
+ psub%1 m%4, %3
+ psub%1 m%4, %3
+%endif
+%endmacro
+
+%macro SUMSUB2_BA 4
+%if avx_enabled == 0
+ mova m%4, m%2
+ padd%1 m%2, m%3
+ padd%1 m%2, m%3
+ psub%1 m%3, m%4
+ psub%1 m%3, m%4
+%else
+ padd%1 m%4, m%2, m%3
+ padd%1 m%4, m%3
+ psub%1 m%3, m%2
+ psub%1 m%3, m%2
+ SWAP %2, %4
+%endif
+%endmacro
+
+%macro SUMSUBD2_AB 5
+%ifnum %4
+ psra%1 m%5, m%2, 1 ; %3: %3>>1
+ psra%1 m%4, m%3, 1 ; %2: %2>>1
+ padd%1 m%4, m%2 ; %3: %3>>1+%2
+ psub%1 m%5, m%3 ; %2: %2>>1-%3
+ SWAP %2, %5
+ SWAP %3, %4
+%else
+ mova %5, m%2
+ mova %4, m%3
+ psra%1 m%3, 1 ; %3: %3>>1
+ psra%1 m%2, 1 ; %2: %2>>1
+ padd%1 m%3, %5 ; %3: %3>>1+%2
+ psub%1 m%2, %4 ; %2: %2>>1-%3
+%endif
+%endmacro
+
+%macro DCT4_1D 5
+%ifnum %5
+ SUMSUB_BADC w, %4, %1, %3, %2, %5
+ SUMSUB_BA w, %3, %4, %5
+ SUMSUB2_AB w, %1, %2, %5
+ SWAP %1, %3, %4, %5, %2
+%else
+ SUMSUB_BADC w, %4, %1, %3, %2
+ SUMSUB_BA w, %3, %4
+ mova [%5], m%2
+ SUMSUB2_AB w, %1, [%5], %2
+ SWAP %1, %3, %4, %2
+%endif
+%endmacro
+
+%macro IDCT4_1D 6-7
+%ifnum %6
+ SUMSUBD2_AB %1, %3, %5, %7, %6
+ ; %3: %3>>1-%5 %5: %3+%5>>1
+ SUMSUB_BA %1, %4, %2, %7
+ ; %4: %2+%4 %2: %2-%4
+ SUMSUB_BADC %1, %5, %4, %3, %2, %7
+ ; %5: %2+%4 + (%3+%5>>1)
+ ; %4: %2+%4 - (%3+%5>>1)
+ ; %3: %2-%4 + (%3>>1-%5)
+ ; %2: %2-%4 - (%3>>1-%5)
+%else
+%ifidn %1, w
+ SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
+%else
+ SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
+%endif
+ SUMSUB_BA %1, %4, %2
+ SUMSUB_BADC %1, %5, %4, %3, %2
+%endif
+ SWAP %2, %5, %4
+ ; %2: %2+%4 + (%3+%5>>1) row0
+ ; %3: %2-%4 + (%3>>1-%5) row1
+ ; %4: %2-%4 - (%3>>1-%5) row2
+ ; %5: %2+%4 - (%3+%5>>1) row3
+%endmacro
+
+
+%macro LOAD_DIFF 5
+%ifidn %3, none
+ movh %1, %4
+ movh %2, %5
+ punpcklbw %1, %2
+ punpcklbw %2, %2
+ psubw %1, %2
+%else
+ movh %1, %4
+ punpcklbw %1, %3
+ movh %2, %5
+ punpcklbw %2, %3
+ psubw %1, %2
+%endif
+%endmacro
+
+%macro STORE_DCT 6
+ movq [%5+%6+ 0], m%1
+ movq [%5+%6+ 8], m%2
+ movq [%5+%6+16], m%3
+ movq [%5+%6+24], m%4
+ movhps [%5+%6+32], m%1
+ movhps [%5+%6+40], m%2
+ movhps [%5+%6+48], m%3
+ movhps [%5+%6+56], m%4
+%endmacro
+
+%macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
+ LOAD_DIFF m%1, m%5, m%7, [%8], [%9]
+ LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3]
+ LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
+ LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5]
+%if %10
+ lea %8, [%8+4*r1]
+ lea %9, [%9+4*r3]
+%endif
+%endmacro
+
+%macro DIFFx2 6-7
+ movh %3, %5
+ punpcklbw %3, %4
+ psraw %1, 6
+ paddsw %1, %3
+ movh %3, %6
+ punpcklbw %3, %4
+ psraw %2, 6
+ paddsw %2, %3
+ packuswb %2, %1
+%endmacro
+
+%macro STORE_DIFF 4
+ movh %2, %4
+ punpcklbw %2, %3
+ psraw %1, 6
+ paddsw %1, %2
+ packuswb %1, %1
+ movh %4, %1
+%endmacro
+
+%macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride
+ movh %3, [%7]
+ movh %4, [%7+%8]
+ psraw %1, %6
+ psraw %2, %6
+ punpcklbw %3, %5
+ punpcklbw %4, %5
+ paddw %3, %1
+ paddw %4, %2
+ packuswb %3, %5
+ packuswb %4, %5
+ movh [%7], %3
+ movh [%7+%8], %4
+%endmacro
+
+%macro PMINUB_MMX 3 ; dst, src, tmp
+ mova %3, %1
+ psubusb %3, %2
+ psubb %1, %3
+%endmacro
+
+%macro PMINUB_MMXEXT 3 ; dst, src, ignored
+ pminub %1, %2
+%endmacro
+
+%macro SPLATW 2-3 0
+%if mmsize == 16
+ pshuflw %1, %2, (%3)*0x55
+ punpcklqdq %1, %1
+%else
+ pshufw %1, %2, (%3)*0x55
+%endif
+%endmacro
+
+%macro SPLATD 2-3 0
+%if mmsize == 16
+ pshufd %1, %2, (%3)*0x55
+%else
+ pshufw %1, %2, (%3)*0x11 + ((%3)+1)*0x44
+%endif
+%endmacro
+
+%macro SPLATD_MMX 1
+ punpckldq %1, %1
+%endmacro
+
+%macro SPLATD_SSE 1
+ shufps %1, %1, 0
+%endmacro
+
+%macro SPLATD_SSE2 1
+ pshufd %1, %1, 0
+%endmacro
+
+%macro CLIPW 3 ;(dst, min, max)
+ pmaxsw %1, %2
+ pminsw %1, %3
+%endmacro
+
+%macro PMINSD_MMX 3 ; dst, src, tmp
+ mova %3, %2
+ pcmpgtd %3, %1
+ pxor %1, %2
+ pand %1, %3
+ pxor %1, %2
+%endmacro
+
+%macro PMAXSD_MMX 3 ; dst, src, tmp
+ mova %3, %1
+ pcmpgtd %3, %2
+ pand %1, %3
+ pandn %3, %2
+ por %1, %3
+%endmacro
+
+%macro CLIPD_MMX 3-4 ; src/dst, min, max, tmp
+ PMINSD_MMX %1, %3, %4
+ PMAXSD_MMX %1, %2, %4
+%endmacro
+
+%macro CLIPD_SSE2 3-4 ; src/dst, min (float), max (float), unused
+ cvtdq2ps %1, %1
+ minps %1, %3
+ maxps %1, %2
+ cvtps2dq %1, %1
+%endmacro
+
+%macro CLIPD_SSE41 3-4 ; src/dst, min, max, unused
+ pminsd %1, %3
+ pmaxsd %1, %2
+%endmacro
diff --git a/libpostproc/Makefile b/libpostproc/Makefile
index bd0b71e..86c9b5f 100644
--- a/libpostproc/Makefile
+++ b/libpostproc/Makefile
@@ -1,10 +1,6 @@
-include $(SUBDIR)../config.mak
-
NAME = postproc
FFLIBS = avutil
HEADERS = postprocess.h
OBJS = postprocess.o
-
-include $(SUBDIR)../subdir.mak
diff --git a/libpostproc/postprocess.c b/libpostproc/postprocess.c
index eacf262..c363fa7 100644
--- a/libpostproc/postprocess.c
+++ b/libpostproc/postprocess.c
@@ -246,7 +246,6 @@ static inline int isVertDC_C(uint8_t src[], int stride, PPContext *c)
static inline int isHorizMinMaxOk_C(uint8_t src[], int stride, int QP)
{
int i;
-#if 1
for(i=0; i<2; i++){
if((unsigned)(src[0] - src[5] + 2*QP) > 4*QP) return 0;
src += stride;
@@ -257,19 +256,11 @@ static inline int isHorizMinMaxOk_C(uint8_t src[], int stride, int QP)
if((unsigned)(src[6] - src[3] + 2*QP) > 4*QP) return 0;
src += stride;
}
-#else
- for(i=0; i<8; i++){
- if((unsigned)(src[0] - src[7] + 2*QP) > 4*QP) return 0;
- src += stride;
- }
-#endif
return 1;
}
static inline int isVertMinMaxOk_C(uint8_t src[], int stride, int QP)
{
-#if 1
-#if 1
int x;
src+= stride*4;
for(x=0; x<BLOCK_SIZE; x+=4){
@@ -278,30 +269,7 @@ static inline int isVertMinMaxOk_C(uint8_t src[], int stride, int QP)
if((unsigned)(src[2+x + 4*stride] - src[2+x + 1*stride] + 2*QP) > 4*QP) return 0;
if((unsigned)(src[3+x + 6*stride] - src[3+x + 3*stride] + 2*QP) > 4*QP) return 0;
}
-#else
- int x;
- src+= stride*3;
- for(x=0; x<BLOCK_SIZE; x++){
- if((unsigned)(src[x + stride] - src[x + (stride<<3)] + 2*QP) > 4*QP) return 0;
- }
-#endif
- return 1;
-#else
- int x;
- src+= stride*4;
- for(x=0; x<BLOCK_SIZE; x++){
- int min=255;
- int max=0;
- int y;
- for(y=0; y<8; y++){
- int v= src[x + y*stride];
- if(v>max) max=v;
- if(v<min) min=v;
- }
- if(max-min > 2*QP) return 0;
- }
return 1;
-#endif
}
static inline int horizClassify_C(uint8_t src[], int stride, PPContext *c)
@@ -676,7 +644,7 @@ static inline void postProcess(const uint8_t src[], int srcStride, uint8_t dst[]
#endif
postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
#endif
-#else //CONFIG_RUNTIME_CPUDETECT
+#else /* CONFIG_RUNTIME_CPUDETECT */
#if HAVE_MMX2
postProcess_MMX2(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
#elif HAVE_AMD3DNOW
@@ -688,7 +656,7 @@ static inline void postProcess(const uint8_t src[], int srcStride, uint8_t dst[]
#else
postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
#endif
-#endif //!CONFIG_RUNTIME_CPUDETECT
+#endif /* !CONFIG_RUNTIME_CPUDETECT */
}
//static void postProcess(uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height,
@@ -941,7 +909,7 @@ static void reallocBuffers(PPContext *c, int width, int height, int stride, int
c->yHistogram[i]= width*height/64*15/256;
for(i=0; i<3; i++){
- //Note: The +17*1024 is just there so i do not have to worry about r/w over the end.
+ //Note: The +17*1024 is just there so I do not have to worry about r/w over the end.
reallocAlign((void **)&c->tempBlurred[i], 8, stride*mbHeight*16 + 17*1024);
reallocAlign((void **)&c->tempBlurredPast[i], 8, 256*((height+7)&(~7))/2 + 17*1024);//FIXME size
}
diff --git a/libpostproc/postprocess.h b/libpostproc/postprocess.h
index fe8c9b9..4cc6925 100644
--- a/libpostproc/postprocess.h
+++ b/libpostproc/postprocess.h
@@ -77,9 +77,10 @@ void pp_postprocess(const uint8_t * src[3], const int srcStride[3],
/**
- * returns a pp_mode or NULL if an error occurred
- * name is the string after "-pp" on the command line
- * quality is a number from 0 to PP_QUALITY_MAX
+ * Return a pp_mode or NULL if an error occurred.
+ *
+ * @param name the string after "-pp" on the command line
+ * @param quality a number from 0 to PP_QUALITY_MAX
*/
pp_mode *pp_get_mode_by_name_and_quality(const char *name, int quality);
void pp_free_mode(pp_mode *mode);
diff --git a/libpostproc/postprocess_altivec_template.c b/libpostproc/postprocess_altivec_template.c
index 56d7b16..ac65df8 100644
--- a/libpostproc/postprocess_altivec_template.c
+++ b/libpostproc/postprocess_altivec_template.c
@@ -530,6 +530,39 @@ static inline void doVertDefFilter_altivec(uint8_t src[], int stride, PPContext
}
static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
+ const vector signed int vsint32_8 = vec_splat_s32(8);
+ const vector unsigned int vuint32_4 = vec_splat_u32(4);
+ const vector signed char neg1 = vec_splat_s8(-1);
+
+ const vector unsigned char permA1 = (vector unsigned char)
+ {0x00, 0x01, 0x02, 0x10, 0x11, 0x12, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
+ const vector unsigned char permA2 = (vector unsigned char)
+ {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x10, 0x11,
+ 0x12, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
+ const vector unsigned char permA1inc = (vector unsigned char)
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ const vector unsigned char permA2inc = (vector unsigned char)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ const vector unsigned char magic = (vector unsigned char)
+ {0x01, 0x02, 0x01, 0x02, 0x04, 0x02, 0x01, 0x02,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ const vector unsigned char extractPerm = (vector unsigned char)
+ {0x10, 0x10, 0x10, 0x01, 0x10, 0x10, 0x10, 0x01,
+ 0x10, 0x10, 0x10, 0x01, 0x10, 0x10, 0x10, 0x01};
+ const vector unsigned char extractPermInc = (vector unsigned char)
+ {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01};
+ const vector unsigned char identity = vec_lvsl(0,(unsigned char *)0);
+ const vector unsigned char tenRight = (vector unsigned char)
+ {0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ const vector unsigned char eightLeft = (vector unsigned char)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08};
+
/*
this code makes no assumption on src or stride.
One could remove the recomputation of the perm
@@ -539,11 +572,9 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
src & stride :-(
*/
uint8_t *srcCopy = src;
- DECLARE_ALIGNED(16, uint8_t, dt)[16];
+ DECLARE_ALIGNED(16, uint8_t, dt)[16] = { deringThreshold };
const vector signed int zero = vec_splat_s32(0);
- vector unsigned char v_dt;
- dt[0] = deringThreshold;
- v_dt = vec_splat(vec_ld(0, dt), 0);
+ vector unsigned char v_dt = vec_splat(vec_ld(0, dt), 0);
#define LOAD_LINE(i) \
const vector unsigned char perm##i = \
@@ -565,6 +596,11 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
#undef LOAD_LINE
vector unsigned char v_avg;
+ DECLARE_ALIGNED(16, signed int, S)[8];
+ DECLARE_ALIGNED(16, int, tQP2)[4] = { c->QP/2 + 1 };
+ vector signed int vQP2 = vec_ld(0, tQP2);
+ vQP2 = vec_splat(vQP2, 0);
+
{
const vector unsigned char trunc_perm = (vector unsigned char)
{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
@@ -575,21 +611,22 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
const vector unsigned char trunc_src78 = vec_perm(src7, src8, trunc_perm);
#define EXTRACT(op) do { \
- const vector unsigned char s##op##_1 = vec_##op(trunc_src12, trunc_src34); \
- const vector unsigned char s##op##_2 = vec_##op(trunc_src56, trunc_src78); \
- const vector unsigned char s##op##_6 = vec_##op(s##op##_1, s##op##_2); \
- const vector unsigned char s##op##_8h = vec_mergeh(s##op##_6, s##op##_6); \
- const vector unsigned char s##op##_8l = vec_mergel(s##op##_6, s##op##_6); \
- const vector unsigned char s##op##_9 = vec_##op(s##op##_8h, s##op##_8l); \
- const vector unsigned char s##op##_9h = vec_mergeh(s##op##_9, s##op##_9); \
- const vector unsigned char s##op##_9l = vec_mergel(s##op##_9, s##op##_9); \
- const vector unsigned char s##op##_10 = vec_##op(s##op##_9h, s##op##_9l); \
- const vector unsigned char s##op##_10h = vec_mergeh(s##op##_10, s##op##_10); \
- const vector unsigned char s##op##_10l = vec_mergel(s##op##_10, s##op##_10); \
- const vector unsigned char s##op##_11 = vec_##op(s##op##_10h, s##op##_10l); \
- const vector unsigned char s##op##_11h = vec_mergeh(s##op##_11, s##op##_11); \
- const vector unsigned char s##op##_11l = vec_mergel(s##op##_11, s##op##_11); \
- v_##op = vec_##op(s##op##_11h, s##op##_11l); } while (0)
+ const vector unsigned char s_1 = vec_##op(trunc_src12, trunc_src34); \
+ const vector unsigned char s_2 = vec_##op(trunc_src56, trunc_src78); \
+ const vector unsigned char s_6 = vec_##op(s_1, s_2); \
+ const vector unsigned char s_8h = vec_mergeh(s_6, s_6); \
+ const vector unsigned char s_8l = vec_mergel(s_6, s_6); \
+ const vector unsigned char s_9 = vec_##op(s_8h, s_8l); \
+ const vector unsigned char s_9h = vec_mergeh(s_9, s_9); \
+ const vector unsigned char s_9l = vec_mergel(s_9, s_9); \
+ const vector unsigned char s_10 = vec_##op(s_9h, s_9l); \
+ const vector unsigned char s_10h = vec_mergeh(s_10, s_10); \
+ const vector unsigned char s_10l = vec_mergel(s_10, s_10); \
+ const vector unsigned char s_11 = vec_##op(s_10h, s_10l); \
+ const vector unsigned char s_11h = vec_mergeh(s_11, s_11); \
+ const vector unsigned char s_11l = vec_mergel(s_11, s_11); \
+ v_##op = vec_##op(s_11h, s_11l); \
+} while (0)
vector unsigned char v_min;
vector unsigned char v_max;
@@ -603,7 +640,6 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
v_avg = vec_avg(v_min, v_max);
}
- DECLARE_ALIGNED(16, signed int, S)[8];
{
const vector unsigned short mask1 = (vector unsigned short)
{0x0001, 0x0002, 0x0004, 0x0008,
@@ -615,22 +651,27 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
const vector unsigned int vuint32_16 = vec_sl(vec_splat_u32(1), vec_splat_u32(4));
const vector unsigned int vuint32_1 = vec_splat_u32(1);
+ vector signed int sumA2;
+ vector signed int sumB2;
+ vector signed int sum0, sum1, sum2, sum3, sum4;
+ vector signed int sum5, sum6, sum7, sum8, sum9;
+
#define COMPARE(i) \
- vector signed int sum##i; \
do { \
- const vector unsigned char cmp##i = \
+ const vector unsigned char cmp = \
(vector unsigned char)vec_cmpgt(src##i, v_avg); \
- const vector unsigned short cmpHi##i = \
- (vector unsigned short)vec_mergeh(cmp##i, cmp##i); \
- const vector unsigned short cmpLi##i = \
- (vector unsigned short)vec_mergel(cmp##i, cmp##i); \
- const vector signed short cmpHf##i = \
- (vector signed short)vec_and(cmpHi##i, mask1); \
- const vector signed short cmpLf##i = \
- (vector signed short)vec_and(cmpLi##i, mask2); \
- const vector signed int sump##i = vec_sum4s(cmpHf##i, zero); \
- const vector signed int sumq##i = vec_sum4s(cmpLf##i, sump##i); \
- sum##i = vec_sums(sumq##i, zero); } while (0)
+ const vector unsigned short cmpHi = \
+ (vector unsigned short)vec_mergeh(cmp, cmp); \
+ const vector unsigned short cmpLi = \
+ (vector unsigned short)vec_mergel(cmp, cmp); \
+ const vector signed short cmpHf = \
+ (vector signed short)vec_and(cmpHi, mask1); \
+ const vector signed short cmpLf = \
+ (vector signed short)vec_and(cmpLi, mask2); \
+ const vector signed int sump = vec_sum4s(cmpHf, zero); \
+ const vector signed int sumq = vec_sum4s(cmpLf, sump); \
+ sum##i = vec_sums(sumq, zero); \
+ } while (0)
COMPARE(0);
COMPARE(1);
@@ -644,8 +685,6 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
COMPARE(9);
#undef COMPARE
- vector signed int sumA2;
- vector signed int sumB2;
{
const vector signed int sump02 = vec_mergel(sum0, sum2);
const vector signed int sump13 = vec_mergel(sum1, sum3);
@@ -699,86 +738,43 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
/* I'm not sure the following is actually faster
than straight, unvectorized C code :-( */
- DECLARE_ALIGNED(16, int, tQP2)[4];
- tQP2[0]= c->QP/2 + 1;
- vector signed int vQP2 = vec_ld(0, tQP2);
- vQP2 = vec_splat(vQP2, 0);
- const vector signed int vsint32_8 = vec_splat_s32(8);
- const vector unsigned int vuint32_4 = vec_splat_u32(4);
-
- const vector unsigned char permA1 = (vector unsigned char)
- {0x00, 0x01, 0x02, 0x10, 0x11, 0x12, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
- const vector unsigned char permA2 = (vector unsigned char)
- {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x10, 0x11,
- 0x12, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
- const vector unsigned char permA1inc = (vector unsigned char)
- {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- const vector unsigned char permA2inc = (vector unsigned char)
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- const vector unsigned char magic = (vector unsigned char)
- {0x01, 0x02, 0x01, 0x02, 0x04, 0x02, 0x01, 0x02,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- const vector unsigned char extractPerm = (vector unsigned char)
- {0x10, 0x10, 0x10, 0x01, 0x10, 0x10, 0x10, 0x01,
- 0x10, 0x10, 0x10, 0x01, 0x10, 0x10, 0x10, 0x01};
- const vector unsigned char extractPermInc = (vector unsigned char)
- {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01};
- const vector unsigned char identity = vec_lvsl(0,(unsigned char *)0);
- const vector unsigned char tenRight = (vector unsigned char)
- {0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- const vector unsigned char eightLeft = (vector unsigned char)
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08};
-
-
-#define F_INIT(i) \
- vector unsigned char tenRightM##i = tenRight; \
- vector unsigned char permA1M##i = permA1; \
- vector unsigned char permA2M##i = permA2; \
- vector unsigned char extractPermM##i = extractPerm
+#define F_INIT() \
+ vector unsigned char tenRightM = tenRight; \
+ vector unsigned char permA1M = permA1; \
+ vector unsigned char permA2M = permA2; \
+ vector unsigned char extractPermM = extractPerm
#define F2(i, j, k, l) \
if (S[i] & (1 << (l+1))) { \
- const vector unsigned char a_##j##_A##l = \
- vec_perm(src##i, src##j, permA1M##i); \
- const vector unsigned char a_##j##_B##l = \
- vec_perm(a_##j##_A##l, src##k, permA2M##i); \
- const vector signed int a_##j##_sump##l = \
- (vector signed int)vec_msum(a_##j##_B##l, magic, \
- (vector unsigned int)zero); \
- vector signed int F_##j##_##l = \
- vec_sr(vec_sums(a_##j##_sump##l, vsint32_8), vuint32_4); \
- F_##j##_##l = vec_splat(F_##j##_##l, 3); \
- const vector signed int p_##j##_##l = \
- (vector signed int)vec_perm(src##j, \
- (vector unsigned char)zero, \
- extractPermM##i); \
- const vector signed int sum_##j##_##l = vec_add( p_##j##_##l, vQP2);\
- const vector signed int diff_##j##_##l = vec_sub( p_##j##_##l, vQP2);\
- vector signed int newpm_##j##_##l; \
- if (vec_all_lt(sum_##j##_##l, F_##j##_##l)) \
- newpm_##j##_##l = sum_##j##_##l; \
- else if (vec_all_gt(diff_##j##_##l, F_##j##_##l)) \
- newpm_##j##_##l = diff_##j##_##l; \
- else newpm_##j##_##l = F_##j##_##l; \
- const vector unsigned char newpm2_##j##_##l = \
- vec_splat((vector unsigned char)newpm_##j##_##l, 15); \
- const vector unsigned char mask##j##l = vec_add(identity, \
- tenRightM##i); \
- src##j = vec_perm(src##j, newpm2_##j##_##l, mask##j##l); \
+ const vector unsigned char a_A = vec_perm(src##i, src##j, permA1M); \
+ const vector unsigned char a_B = vec_perm(a_A, src##k, permA2M); \
+ const vector signed int a_sump = \
+ (vector signed int)vec_msum(a_B, magic, (vector unsigned int)zero);\
+ vector signed int F = vec_sr(vec_sums(a_sump, vsint32_8), vuint32_4); \
+ const vector signed int p = \
+ (vector signed int)vec_perm(src##j, (vector unsigned char)zero, \
+ extractPermM); \
+ const vector signed int sum = vec_add(p, vQP2); \
+ const vector signed int diff = vec_sub(p, vQP2); \
+ vector signed int newpm; \
+ vector unsigned char newpm2, mask; \
+ F = vec_splat(F, 3); \
+ if (vec_all_lt(sum, F)) \
+ newpm = sum; \
+ else if (vec_all_gt(diff, F)) \
+ newpm = diff; \
+ else newpm = F; \
+ newpm2 = vec_splat((vector unsigned char)newpm, 15); \
+ mask = vec_add(identity, tenRightM); \
+ src##j = vec_perm(src##j, newpm2, mask); \
} \
- permA1M##i = vec_add(permA1M##i, permA1inc); \
- permA2M##i = vec_add(permA2M##i, permA2inc); \
- tenRightM##i = vec_sro(tenRightM##i, eightLeft); \
- extractPermM##i = vec_add(extractPermM##i, extractPermInc)
+ permA1M = vec_add(permA1M, permA1inc); \
+ permA2M = vec_add(permA2M, permA2inc); \
+ tenRightM = vec_sro(tenRightM, eightLeft); \
+ extractPermM = vec_add(extractPermM, extractPermInc)
-#define ITER(i, j, k) \
- F_INIT(i); \
+#define ITER(i, j, k) do { \
+ F_INIT(); \
F2(i, j, k, 0); \
F2(i, j, k, 1); \
F2(i, j, k, 2); \
@@ -786,7 +782,8 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
F2(i, j, k, 4); \
F2(i, j, k, 5); \
F2(i, j, k, 6); \
- F2(i, j, k, 7)
+ F2(i, j, k, 7); \
+} while (0)
ITER(0, 1, 2);
ITER(1, 2, 3);
@@ -797,19 +794,18 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
ITER(6, 7, 8);
ITER(7, 8, 9);
- const vector signed char neg1 = vec_splat_s8(-1);
-
-#define STORE_LINE(i) \
- const vector unsigned char permST##i = \
+#define STORE_LINE(i) do { \
+ const vector unsigned char permST = \
vec_lvsr(i * stride, srcCopy); \
- const vector unsigned char maskST##i = \
+ const vector unsigned char maskST = \
vec_perm((vector unsigned char)zero, \
- (vector unsigned char)neg1, permST##i);\
- src##i = vec_perm(src##i ,src##i, permST##i); \
- sA##i= vec_sel(sA##i, src##i, maskST##i); \
- sB##i= vec_sel(src##i, sB##i, maskST##i); \
+ (vector unsigned char)neg1, permST); \
+ src##i = vec_perm(src##i ,src##i, permST); \
+ sA##i= vec_sel(sA##i, src##i, maskST); \
+ sB##i= vec_sel(src##i, sB##i, maskST); \
vec_st(sA##i, i * stride, srcCopy); \
- vec_st(sB##i, i * stride + 16, srcCopy)
+ vec_st(sB##i, i * stride + 16, srcCopy); \
+} while (0)
STORE_LINE(1);
STORE_LINE(2);
@@ -832,16 +828,16 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
static inline void RENAME(tempNoiseReducer)(uint8_t *src, int stride,
uint8_t *tempBlurred, uint32_t *tempBlurredPast, int *maxNoise)
{
+ const vector signed char neg1 = vec_splat_s8(-1);
+ const vector unsigned char permHH = (const vector unsigned char){0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
+
const vector signed int zero = vec_splat_s32(0);
const vector signed short vsint16_1 = vec_splat_s16(1);
vector signed int v_dp = zero;
vector signed int v_sysdp = zero;
int d, sysd, i;
- tempBlurredPast[127]= maxNoise[0];
- tempBlurredPast[128]= maxNoise[1];
- tempBlurredPast[129]= maxNoise[2];
-
#define LOAD_LINE(src, i) \
register int j##src##i = i * stride; \
vector unsigned char perm##src##i = vec_lvsl(j##src##i, src); \
@@ -872,11 +868,12 @@ static inline void RENAME(tempNoiseReducer)(uint8_t *src, int stride,
LOAD_LINE(tempBlurred, 7);
#undef LOAD_LINE
-#define ACCUMULATE_DIFFS(i) \
- vector signed short v_d##i = vec_sub(v_tempBlurredAss##i, \
- v_srcAss##i); \
- v_dp = vec_msums(v_d##i, v_d##i, v_dp); \
- v_sysdp = vec_msums(v_d##i, vsint16_1, v_sysdp)
+#define ACCUMULATE_DIFFS(i) do { \
+ vector signed short v_d = vec_sub(v_tempBlurredAss##i, \
+ v_srcAss##i); \
+ v_dp = vec_msums(v_d, v_d, v_dp); \
+ v_sysdp = vec_msums(v_d, vsint16_1, v_sysdp); \
+ } while (0)
ACCUMULATE_DIFFS(0);
ACCUMULATE_DIFFS(1);
@@ -888,6 +885,10 @@ static inline void RENAME(tempNoiseReducer)(uint8_t *src, int stride,
ACCUMULATE_DIFFS(7);
#undef ACCUMULATE_DIFFS
+ tempBlurredPast[127]= maxNoise[0];
+ tempBlurredPast[128]= maxNoise[1];
+ tempBlurredPast[129]= maxNoise[2];
+
v_dp = vec_sums(v_dp, zero);
v_sysdp = vec_sums(v_sysdp, zero);
@@ -938,13 +939,12 @@ static inline void RENAME(tempNoiseReducer)(uint8_t *src, int stride,
const vector signed short vsint16_4 = vec_splat_s16(4);
const vector unsigned short vuint16_3 = vec_splat_u16(3);
-#define OP(i) \
- const vector signed short v_temp##i = \
- vec_mladd(v_tempBlurredAss##i, \
- vsint16_7, v_srcAss##i); \
- const vector signed short v_temp2##i = \
- vec_add(v_temp##i, vsint16_4); \
- v_tempBlurredAss##i = vec_sr(v_temp2##i, vuint16_3)
+#define OP(i) do { \
+ const vector signed short v_temp = \
+ vec_mladd(v_tempBlurredAss##i, vsint16_7, v_srcAss##i); \
+ const vector signed short v_temp2 = vec_add(v_temp, vsint16_4); \
+ v_tempBlurredAss##i = vec_sr(v_temp2, vuint16_3); \
+ } while (0)
OP(0);
OP(1);
@@ -959,13 +959,13 @@ static inline void RENAME(tempNoiseReducer)(uint8_t *src, int stride,
const vector signed short vsint16_3 = vec_splat_s16(3);
const vector signed short vsint16_2 = vec_splat_s16(2);
-#define OP(i) \
- const vector signed short v_temp##i = \
- vec_mladd(v_tempBlurredAss##i, \
- vsint16_3, v_srcAss##i); \
- const vector signed short v_temp2##i = \
- vec_add(v_temp##i, vsint16_2); \
- v_tempBlurredAss##i = vec_sr(v_temp2##i, (vector unsigned short)vsint16_2)
+#define OP(i) do { \
+ const vector signed short v_temp = \
+ vec_mladd(v_tempBlurredAss##i, vsint16_3, v_srcAss##i); \
+ const vector signed short v_temp2 = vec_add(v_temp, vsint16_2); \
+ v_tempBlurredAss##i = \
+ vec_sr(v_temp2, (vector unsigned short)vsint16_2); \
+ } while (0)
OP(0);
OP(1);
@@ -979,27 +979,19 @@ static inline void RENAME(tempNoiseReducer)(uint8_t *src, int stride,
}
}
- const vector signed char neg1 = vec_splat_s8(-1);
- const vector unsigned char permHH = (const vector unsigned char){0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
-
-#define PACK_AND_STORE(src, i) \
- const vector unsigned char perms##src##i = \
- vec_lvsr(i * stride, src); \
- const vector unsigned char vf##src##i = \
- vec_packsu(v_tempBlurredAss##i, (vector signed short)zero); \
- const vector unsigned char vg##src##i = \
- vec_perm(vf##src##i, v_##src##A##i, permHH); \
- const vector unsigned char mask##src##i = \
- vec_perm((vector unsigned char)zero, (vector unsigned char)neg1, perms##src##i); \
- const vector unsigned char vg2##src##i = \
- vec_perm(vg##src##i, vg##src##i, perms##src##i); \
- const vector unsigned char svA##src##i = \
- vec_sel(v_##src##A1##i, vg2##src##i, mask##src##i); \
- const vector unsigned char svB##src##i = \
- vec_sel(vg2##src##i, v_##src##A2##i, mask##src##i); \
- vec_st(svA##src##i, i * stride, src); \
- vec_st(svB##src##i, i * stride + 16, src)
+#define PACK_AND_STORE(src, i) do { \
+ const vector unsigned char perms = vec_lvsr(i * stride, src); \
+ const vector unsigned char vf = \
+ vec_packsu(v_tempBlurredAss##1, (vector signed short)zero); \
+ const vector unsigned char vg = vec_perm(vf, v_##src##A##i, permHH); \
+ const vector unsigned char mask = \
+ vec_perm((vector unsigned char)zero, (vector unsigned char)neg1, perms); \
+ const vector unsigned char vg2 = vec_perm(vg, vg, perms); \
+ const vector unsigned char svA = vec_sel(v_##src##A1##i, vg2, mask); \
+ const vector unsigned char svB = vec_sel(vg2, v_##src##A2##i, mask); \
+ vec_st(svA, i * stride, src); \
+ vec_st(svB, i * stride + 16, src); \
+} while (0)
PACK_AND_STORE(src, 0);
PACK_AND_STORE(src, 1);
@@ -1127,6 +1119,7 @@ static inline void transpose_16x8_char_toPackedAlign_altivec(unsigned char* dst,
static inline void transpose_8x16_char_fromPackedAlign_altivec(unsigned char* dst, unsigned char* src, int stride) {
const vector unsigned char zero = vec_splat_u8(0);
+ const vector signed char neg1 = vec_splat_s8(-1);
#define LOAD_DOUBLE_LINE(i, j) \
vector unsigned char src##i = vec_ld(i * 16, src); \
@@ -1187,26 +1180,28 @@ static inline void transpose_8x16_char_fromPackedAlign_altivec(unsigned char* ds
temp7 = vec_mergel(tempD, tempL);
- const vector signed char neg1 = vec_splat_s8(-1);
-#define STORE_DOUBLE_LINE(i, j) \
- vector unsigned char dstA##i = vec_ld(i * stride, dst); \
- vector unsigned char dstB##i = vec_ld(i * stride + 16, dst); \
- vector unsigned char dstA##j = vec_ld(j * stride, dst); \
- vector unsigned char dstB##j = vec_ld(j * stride+ 16, dst); \
- vector unsigned char align##i = vec_lvsr(i * stride, dst); \
- vector unsigned char align##j = vec_lvsr(j * stride, dst); \
- vector unsigned char mask##i = vec_perm(zero, (vector unsigned char)neg1, align##i); \
- vector unsigned char mask##j = vec_perm(zero, (vector unsigned char)neg1, align##j); \
- vector unsigned char dstR##i = vec_perm(temp##i, temp##i, align##i);\
- vector unsigned char dstR##j = vec_perm(temp##j, temp##j, align##j);\
- vector unsigned char dstAF##i = vec_sel(dstA##i, dstR##i, mask##i); \
- vector unsigned char dstBF##i = vec_sel(dstR##i, dstB##i, mask##i); \
- vector unsigned char dstAF##j = vec_sel(dstA##j, dstR##j, mask##j); \
- vector unsigned char dstBF##j = vec_sel(dstR##j, dstB##j, mask##j); \
- vec_st(dstAF##i, i * stride, dst); \
- vec_st(dstBF##i, i * stride + 16, dst); \
- vec_st(dstAF##j, j * stride, dst); \
- vec_st(dstBF##j, j * stride + 16, dst)
+#define STORE_DOUBLE_LINE(i, j) do { \
+ vector unsigned char dstAi = vec_ld(i * stride, dst); \
+ vector unsigned char dstBi = vec_ld(i * stride + 16, dst); \
+ vector unsigned char dstAj = vec_ld(j * stride, dst); \
+ vector unsigned char dstBj = vec_ld(j * stride+ 16, dst); \
+ vector unsigned char aligni = vec_lvsr(i * stride, dst); \
+ vector unsigned char alignj = vec_lvsr(j * stride, dst); \
+ vector unsigned char maski = \
+ vec_perm(zero, (vector unsigned char)neg1, aligni); \
+ vector unsigned char maskj = \
+ vec_perm(zero, (vector unsigned char)neg1, alignj); \
+ vector unsigned char dstRi = vec_perm(temp##i, temp##i, aligni); \
+ vector unsigned char dstRj = vec_perm(temp##j, temp##j, alignj); \
+ vector unsigned char dstAFi = vec_sel(dstAi, dstRi, maski); \
+ vector unsigned char dstBFi = vec_sel(dstRi, dstBi, maski); \
+ vector unsigned char dstAFj = vec_sel(dstAj, dstRj, maskj); \
+ vector unsigned char dstBFj = vec_sel(dstRj, dstBj, maskj); \
+ vec_st(dstAFi, i * stride, dst); \
+ vec_st(dstBFi, i * stride + 16, dst); \
+ vec_st(dstAFj, j * stride, dst); \
+ vec_st(dstBFj, j * stride + 16, dst); \
+} while (0)
STORE_DOUBLE_LINE(0,1);
STORE_DOUBLE_LINE(2,3);
diff --git a/libpostproc/postprocess_internal.h b/libpostproc/postprocess_internal.h
index 010e629..d2c6708 100644
--- a/libpostproc/postprocess_internal.h
+++ b/libpostproc/postprocess_internal.h
@@ -28,6 +28,7 @@
#include <string.h>
#include "libavutil/avutil.h"
+#include "libavutil/log.h"
#include "postprocess.h"
#define V_DEBLOCK 0x01
@@ -99,7 +100,7 @@ typedef struct PPMode{
int minAllowedY; ///< for brigtness correction
int maxAllowedY; ///< for brihtness correction
- float maxClippedThreshold; ///< amount of "black" u r willing to loose to get a brightness corrected picture
+ float maxClippedThreshold; ///< amount of "black" you are willing to lose to get a brightness-corrected picture
int maxTmpNoise[3]; ///< for Temporal Noise Reducing filter (Maximal sum of abs differences)
diff --git a/libpostproc/postprocess_template.c b/libpostproc/postprocess_template.c
index 3b6d0f8..dd4c7a0 100644
--- a/libpostproc/postprocess_template.c
+++ b/libpostproc/postprocess_template.c
@@ -1912,7 +1912,7 @@ MEDIAN((%%REGd, %1), (%%REGd, %1, 2), (%0, %1, 8))
#if HAVE_MMX
/**
- * transposes and shift the given 8x8 Block into dst1 and dst2
+ * Transpose and shift the given 8x8 Block into dst1 and dst2.
*/
static inline void RENAME(transpose1)(uint8_t *dst1, uint8_t *dst2, uint8_t *src, int srcStride)
{
@@ -1997,7 +1997,7 @@ static inline void RENAME(transpose1)(uint8_t *dst1, uint8_t *dst2, uint8_t *src
}
/**
- * transposes the given 8x8 block
+ * Transpose the given 8x8 block.
*/
static inline void RENAME(transpose2)(uint8_t *dst, int dstStride, uint8_t *src)
{
@@ -3518,9 +3518,10 @@ static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[
else if(mode & H_DEBLOCK){
#if HAVE_ALTIVEC
DECLARE_ALIGNED(16, unsigned char, tempBlock)[272];
+ int t;
transpose_16x8_char_toPackedAlign_altivec(tempBlock, dstBlock - (4 + 1), stride);
- const int t=vertClassify_altivec(tempBlock-48, 16, &c);
+ t = vertClassify_altivec(tempBlock-48, 16, &c);
if(t==1) {
doVertLowPass_altivec(tempBlock-48, 16, &c);
transpose_8x16_char_fromPackedAlign_altivec(dstBlock - (4 + 1), tempBlock, stride);
diff --git a/library.mak b/library.mak
new file mode 100644
index 0000000..f50e8e5
--- /dev/null
+++ b/library.mak
@@ -0,0 +1,98 @@
+SRC_DIR := $(SRC_PATH)/lib$(NAME)
+
+include $(SRC_PATH)/common.mak
+
+LIBVERSION := $(lib$(NAME)_VERSION)
+LIBMAJOR := $(lib$(NAME)_VERSION_MAJOR)
+INCINSTDIR := $(INCDIR)/lib$(NAME)
+THIS_LIB := $(SUBDIR)$($(CONFIG_SHARED:yes=S)LIBNAME)
+
+all-$(CONFIG_STATIC): $(SUBDIR)$(LIBNAME)
+all-$(CONFIG_SHARED): $(SUBDIR)$(SLIBNAME)
+
+$(SUBDIR)%-test.o: $(SUBDIR)%-test.c
+ $(COMPILE_C)
+
+$(SUBDIR)%-test.o: $(SUBDIR)%.c
+ $(COMPILE_C)
+
+$(SUBDIR)x86/%.o: $(SUBDIR)x86/%.asm
+ $(YASMDEP) $(YASMFLAGS) -I $(<D)/ -M -o $@ $< > $(@:.o=.d)
+ $(YASM) $(YASMFLAGS) -I $(<D)/ -o $@ $<
+
+$(OBJS) $(SUBDIR)%.ho $(TESTOBJS): CPPFLAGS += -DHAVE_AV_CONFIG_H
+$(TESTOBJS): CPPFLAGS += -DTEST
+
+$(SUBDIR)$(LIBNAME): $(OBJS)
+ $(RM) $@
+ $(AR) rc $@ $^ $(EXTRAOBJS)
+ $(RANLIB) $@
+
+install-headers: install-lib$(NAME)-headers install-lib$(NAME)-pkgconfig
+
+install-libs-$(CONFIG_STATIC): install-lib$(NAME)-static
+install-libs-$(CONFIG_SHARED): install-lib$(NAME)-shared
+
+define RULES
+$(EXAMPLES) $(TESTPROGS) $(TOOLS): %$(EXESUF): %.o
+ $$(LD) $(LDFLAGS) -o $$@ $$^ -l$(FULLNAME) $(FFEXTRALIBS) $$(ELIBS)
+
+$(SUBDIR)$(SLIBNAME): $(SUBDIR)$(SLIBNAME_WITH_MAJOR)
+ $(Q)cd ./$(SUBDIR) && $(LN_S) $(SLIBNAME_WITH_MAJOR) $(SLIBNAME)
+
+$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SUBDIR)lib$(NAME).ver $(DEP_LIBS)
+ $(SLIB_CREATE_DEF_CMD)
+ $$(LD) $(SHFLAGS) $(LDFLAGS) -o $$@ $$(filter %.o,$$^) $(FFEXTRALIBS) $(EXTRAOBJS)
+ $(SLIB_EXTRA_CMD)
+
+clean::
+ $(RM) $(addprefix $(SUBDIR),*-example$(EXESUF) *-test$(EXESUF) $(CLEANFILES) $(CLEANSUFFIXES) $(LIBSUFFIXES)) \
+ $(foreach dir,$(DIRS),$(CLEANSUFFIXES:%=$(SUBDIR)$(dir)/%)) \
+ $(HOSTOBJS) $(HOSTPROGS)
+
+distclean:: clean
+ $(RM) $(DISTCLEANSUFFIXES:%=$(SUBDIR)%) \
+ $(foreach dir,$(DIRS),$(DISTCLEANSUFFIXES:%=$(SUBDIR)$(dir)/%))
+
+install-lib$(NAME)-shared: $(SUBDIR)$(SLIBNAME)
+ $(Q)mkdir -p "$(SHLIBDIR)"
+ $$(INSTALL) -m 755 $$< "$(SHLIBDIR)/$(SLIB_INSTALL_NAME)"
+ $(Q)$(foreach F,$(SLIB_INSTALL_LINKS),cd "$(SHLIBDIR)" && $(LN_S) $(SLIB_INSTALL_NAME) $(F);)
+ $(if $(SLIB_INSTALL_EXTRA_SHLIB),$$(INSTALL) -m 644 $(SLIB_INSTALL_EXTRA_SHLIB:%=$(SUBDIR)%) "$(SHLIBDIR)")
+ $(if $(SLIB_INSTALL_EXTRA_LIB),$(Q)mkdir -p "$(LIBDIR)")
+ $(if $(SLIB_INSTALL_EXTRA_LIB),$$(INSTALL) -m 644 $(SLIB_INSTALL_EXTRA_LIB:%=$(SUBDIR)%) "$(LIBDIR)")
+
+install-lib$(NAME)-static: $(SUBDIR)$(LIBNAME)
+ $(Q)mkdir -p "$(LIBDIR)"
+ $$(INSTALL) -m 644 $$< "$(LIBDIR)"
+ $(LIB_INSTALL_EXTRA_CMD)
+
+install-lib$(NAME)-headers: $(addprefix $(SUBDIR),$(HEADERS) $(BUILT_HEADERS))
+ $(Q)mkdir -p "$(INCINSTDIR)"
+ $$(INSTALL) -m 644 $$^ "$(INCINSTDIR)"
+
+install-lib$(NAME)-pkgconfig: $(SUBDIR)lib$(NAME).pc
+ $(Q)mkdir -p "$(LIBDIR)/pkgconfig"
+ $$(INSTALL) -m 644 $$^ "$(LIBDIR)/pkgconfig"
+
+uninstall-libs::
+ -$(RM) "$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR)" \
+ "$(SHLIBDIR)/$(SLIBNAME)" \
+ "$(SHLIBDIR)/$(SLIBNAME_WITH_VERSION)"
+ -$(RM) $(SLIB_INSTALL_EXTRA_SHLIB:%="$(SHLIBDIR)"%)
+ -$(RM) $(SLIB_INSTALL_EXTRA_LIB:%="$(LIBDIR)"%)
+ -$(RM) "$(LIBDIR)/$(LIBNAME)"
+
+uninstall-headers::
+ $(RM) $(addprefix "$(INCINSTDIR)/",$(HEADERS))
+ $(RM) "$(LIBDIR)/pkgconfig/lib$(NAME).pc"
+ -rmdir "$(INCDIR)"
+endef
+
+$(eval $(RULES))
+
+$(EXAMPLES) $(TESTPROGS) $(TOOLS): $(THIS_LIB) $(DEP_LIBS)
+$(TESTPROGS): $(SUBDIR)$(LIBNAME)
+
+examples: $(EXAMPLES)
+testprogs: $(TESTPROGS)
diff --git a/libswscale/Makefile b/libswscale/Makefile
index 8bb06ba..bb9b7d3 100644
--- a/libswscale/Makefile
+++ b/libswscale/Makefile
@@ -1,5 +1,3 @@
-include $(SUBDIR)../config.mak
-
NAME = swscale
FFLIBS = avutil
@@ -19,9 +17,8 @@ OBJS-$(HAVE_MMX) += x86/rgb2rgb.o \
x86/swscale_mmx.o \
x86/yuv2rgb_mmx.o
OBJS-$(HAVE_VIS) += sparc/yuv2rgb_vis.o
+OBJS-$(HAVE_YASM) += x86/scale.o
TESTPROGS = colorspace swscale
DIRS = bfin mlib ppc sparc x86
-
-include $(SUBDIR)../subdir.mak
diff --git a/libswscale/bfin/swscale_bfin.c b/libswscale/bfin/swscale_bfin.c
index c8030ba..0c5f004 100644
--- a/libswscale/bfin/swscale_bfin.c
+++ b/libswscale/bfin/swscale_bfin.c
@@ -78,8 +78,6 @@ static int yuyvtoyv12_unscaled(SwsContext *c, uint8_t* src[], int srcStride[], i
void ff_bfin_get_unscaled_swscale(SwsContext *c)
{
- SwsFunc swScale = c->swScale;
-
if (c->dstFormat == PIX_FMT_YUV420P && c->srcFormat == PIX_FMT_UYVY422) {
av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized uyvytoyv12_unscaled\n");
c->swScale = uyvytoyv12_unscaled;
diff --git a/libswscale/options.c b/libswscale/options.c
index ecd0ecd..9ba6e5e 100644
--- a/libswscale/options.c
+++ b/libswscale/options.c
@@ -34,36 +34,41 @@ static const char * sws_context_to_name(void * ptr)
#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, {.dbl = DEFAULT }, 0, UINT_MAX, VE, "sws_flags" },
- { "fast_bilinear", "fast bilinear", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_FAST_BILINEAR }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "bilinear", "bilinear", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_BILINEAR }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "bicubic", "bicubic", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_BICUBIC }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "experimental", "experimental", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_X }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "neighbor", "nearest neighbor", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_POINT }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "area", "averaging area", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_AREA }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "bicublin", "luma bicubic, chroma bilinear", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_BICUBLIN }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "gauss", "gaussian", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_GAUSS }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "sinc", "sinc", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_SINC }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "lanczos", "lanczos", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_LANCZOS }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "spline", "natural bicubic spline", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_SPLINE }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "print_info", "print info", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_PRINT_INFO }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "accurate_rnd", "accurate rounding", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_ACCURATE_RND }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "full_chroma_int", "full chroma interpolation", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_FULL_CHR_H_INT }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "full_chroma_inp", "full chroma input", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_FULL_CHR_H_INP }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "bitexact", "", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_BITEXACT }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "sws_flags", "scaler/cpu flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, UINT_MAX, VE, "sws_flags" },
+ { "fast_bilinear", "fast bilinear", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_FAST_BILINEAR }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "bilinear", "bilinear", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_BILINEAR }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "bicubic", "bicubic", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_BICUBIC }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "experimental", "experimental", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_X }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "neighbor", "nearest neighbor", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_POINT }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "area", "averaging area", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_AREA }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "bicublin", "luma bicubic, chroma bilinear", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_BICUBLIN }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "gauss", "gaussian", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_GAUSS }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "sinc", "sinc", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_SINC }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "lanczos", "lanczos", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_LANCZOS }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "spline", "natural bicubic spline", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_SPLINE }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "print_info", "print info", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_PRINT_INFO }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "accurate_rnd", "accurate rounding", 0, AV_OPT_TYPE_CONST, {.dbl = SWS_ACCURATE_RND }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "full_chroma_int", "full chroma interpolation", 0 , AV_OPT_TYPE_CONST, {.dbl = SWS_FULL_CHR_H_INT }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "full_chroma_inp", "full chroma input", 0 , AV_OPT_TYPE_CONST, {.dbl = SWS_FULL_CHR_H_INP }, INT_MIN, INT_MAX, VE, "sws_flags" },
+ { "bitexact", "", 0 , AV_OPT_TYPE_CONST, {.dbl = SWS_BITEXACT }, INT_MIN, INT_MAX, VE, "sws_flags" },
- { "srcw", "source width" , OFFSET(srcW), FF_OPT_TYPE_INT, {.dbl = 16 }, 1, INT_MAX, VE },
- { "srch", "source height" , OFFSET(srcH), FF_OPT_TYPE_INT, {.dbl = 16 }, 1, INT_MAX, VE },
- { "dstw", "destination width" , OFFSET(dstW), FF_OPT_TYPE_INT, {.dbl = 16 }, 1, INT_MAX, VE },
- { "dsth", "destination height", OFFSET(dstH), FF_OPT_TYPE_INT, {.dbl = 16 }, 1, INT_MAX, VE },
- { "src_format", "source format" , OFFSET(srcFormat), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, PIX_FMT_NB-1, VE },
- { "dst_format", "destination format", OFFSET(dstFormat), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, PIX_FMT_NB-1, VE },
- { "src_range" , "source range" , OFFSET(srcRange) , FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, 1, VE },
- { "dst_range" , "destination range" , OFFSET(dstRange) , FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, 1, VE },
- { "param0" , "scaler param 0" , OFFSET(param[0]) , FF_OPT_TYPE_DOUBLE, {.dbl = SWS_PARAM_DEFAULT}, INT_MIN, INT_MAX, VE },
- { "param1" , "scaler param 1" , OFFSET(param[1]) , FF_OPT_TYPE_DOUBLE, {.dbl = SWS_PARAM_DEFAULT}, INT_MIN, INT_MAX, VE },
+ { "srcw", "source width" , OFFSET(srcW), AV_OPT_TYPE_INT, {.dbl = 16 }, 1, INT_MAX, VE },
+ { "srch", "source height" , OFFSET(srcH), AV_OPT_TYPE_INT, {.dbl = 16 }, 1, INT_MAX, VE },
+ { "dstw", "destination width" , OFFSET(dstW), AV_OPT_TYPE_INT, {.dbl = 16 }, 1, INT_MAX, VE },
+ { "dsth", "destination height", OFFSET(dstH), AV_OPT_TYPE_INT, {.dbl = 16 }, 1, INT_MAX, VE },
+ { "src_format", "source format" , OFFSET(srcFormat), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, PIX_FMT_NB-1, VE },
+ { "dst_format", "destination format", OFFSET(dstFormat), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, PIX_FMT_NB-1, VE },
+ { "src_range" , "source range" , OFFSET(srcRange) , AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, 1, VE },
+ { "dst_range" , "destination range" , OFFSET(dstRange) , AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, 1, VE },
+ { "param0" , "scaler param 0" , OFFSET(param[0]) , AV_OPT_TYPE_DOUBLE, {.dbl = SWS_PARAM_DEFAULT}, INT_MIN, INT_MAX, VE },
+ { "param1" , "scaler param 1" , OFFSET(param[1]) , AV_OPT_TYPE_DOUBLE, {.dbl = SWS_PARAM_DEFAULT}, INT_MIN, INT_MAX, VE },
{ NULL }
};
const AVClass sws_context_class = { "SWScaler", sws_context_to_name, options };
+
+const AVClass *sws_get_class(void)
+{
+ return &sws_context_class;
+}
diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c
index 4476e1c..87059d9 100644
--- a/libswscale/ppc/swscale_altivec.c
+++ b/libswscale/ppc/swscale_altivec.c
@@ -92,40 +92,31 @@ altivec_packIntArrayToCharArray(int *val, uint8_t* dest, int dstW)
}
}
+//FIXME remove the usage of scratch buffers.
static void
-yuv2yuvX_altivec_real(SwsContext *c,
- const int16_t *lumFilter, const int16_t **lumSrc,
- int lumFilterSize, const int16_t *chrFilter,
- const int16_t **chrUSrc, const int16_t **chrVSrc,
- int chrFilterSize, const int16_t **alpSrc,
- uint8_t *dest, uint8_t *uDest,
- uint8_t *vDest, uint8_t *aDest,
- int dstW, int chrDstW)
+yuv2planeX_altivec(const int16_t *filter, int filterSize,
+ const int16_t **src, uint8_t *dest, int dstW,
+ const uint8_t *dither, int offset)
{
- const vector signed int vini = {(1 << 18), (1 << 18), (1 << 18), (1 << 18)};
register int i, j;
{
DECLARE_ALIGNED(16, int, val)[dstW];
- for (i = 0; i < (dstW -7); i+=4) {
- vec_st(vini, i << 2, val);
- }
- for (; i < dstW; i++) {
- val[i] = (1 << 18);
- }
+ for (i=0; i<dstW; i++)
+ val[i] = dither[(i + offset) & 7] << 12;
- for (j = 0; j < lumFilterSize; j++) {
- vector signed short l1, vLumFilter = vec_ld(j << 1, lumFilter);
- vector unsigned char perm, perm0 = vec_lvsl(j << 1, lumFilter);
+ for (j = 0; j < filterSize; j++) {
+ vector signed short l1, vLumFilter = vec_ld(j << 1, filter);
+ vector unsigned char perm, perm0 = vec_lvsl(j << 1, filter);
vLumFilter = vec_perm(vLumFilter, vLumFilter, perm0);
vLumFilter = vec_splat(vLumFilter, 0); // lumFilter[j] is loaded 8 times in vLumFilter
- perm = vec_lvsl(0, lumSrc[j]);
- l1 = vec_ld(0, lumSrc[j]);
+ perm = vec_lvsl(0, src[j]);
+ l1 = vec_ld(0, src[j]);
for (i = 0; i < (dstW - 7); i+=8) {
int offset = i << 2;
- vector signed short l2 = vec_ld((i << 1) + 16, lumSrc[j]);
+ vector signed short l2 = vec_ld((i << 1) + 16, src[j]);
vector signed int v1 = vec_ld(offset, val);
vector signed int v2 = vec_ld(offset + 16, val);
@@ -147,83 +138,15 @@ yuv2yuvX_altivec_real(SwsContext *c,
l1 = l2;
}
for ( ; i < dstW; i++) {
- val[i] += lumSrc[j][i] * lumFilter[j];
+ val[i] += src[j][i] * filter[j];
}
}
altivec_packIntArrayToCharArray(val, dest, dstW);
}
- if (uDest != 0) {
- DECLARE_ALIGNED(16, int, u)[chrDstW];
- DECLARE_ALIGNED(16, int, v)[chrDstW];
-
- for (i = 0; i < (chrDstW -7); i+=4) {
- vec_st(vini, i << 2, u);
- vec_st(vini, i << 2, v);
- }
- for (; i < chrDstW; i++) {
- u[i] = (1 << 18);
- v[i] = (1 << 18);
- }
-
- for (j = 0; j < chrFilterSize; j++) {
- vector signed short l1, l1_V, vChrFilter = vec_ld(j << 1, chrFilter);
- vector unsigned char perm, perm0 = vec_lvsl(j << 1, chrFilter);
- vChrFilter = vec_perm(vChrFilter, vChrFilter, perm0);
- vChrFilter = vec_splat(vChrFilter, 0); // chrFilter[j] is loaded 8 times in vChrFilter
-
- perm = vec_lvsl(0, chrUSrc[j]);
- l1 = vec_ld(0, chrUSrc[j]);
- l1_V = vec_ld(0, chrVSrc[j]);
-
- for (i = 0; i < (chrDstW - 7); i+=8) {
- int offset = i << 2;
- vector signed short l2 = vec_ld((i << 1) + 16, chrUSrc[j]);
- vector signed short l2_V = vec_ld((i << 1) + 16, chrVSrc[j]);
-
- vector signed int v1 = vec_ld(offset, u);
- vector signed int v2 = vec_ld(offset + 16, u);
- vector signed int v1_V = vec_ld(offset, v);
- vector signed int v2_V = vec_ld(offset + 16, v);
-
- vector signed short ls = vec_perm(l1, l2, perm); // chrUSrc[j][i] ... chrUSrc[j][i+7]
- vector signed short ls_V = vec_perm(l1_V, l2_V, perm); // chrVSrc[j][i] ... chrVSrc[j][i]
-
- vector signed int i1 = vec_mule(vChrFilter, ls);
- vector signed int i2 = vec_mulo(vChrFilter, ls);
- vector signed int i1_V = vec_mule(vChrFilter, ls_V);
- vector signed int i2_V = vec_mulo(vChrFilter, ls_V);
-
- vector signed int vf1 = vec_mergeh(i1, i2);
- vector signed int vf2 = vec_mergel(i1, i2); // chrUSrc[j][i] * chrFilter[j] ... chrUSrc[j][i+7] * chrFilter[j]
- vector signed int vf1_V = vec_mergeh(i1_V, i2_V);
- vector signed int vf2_V = vec_mergel(i1_V, i2_V); // chrVSrc[j][i] * chrFilter[j] ... chrVSrc[j][i+7] * chrFilter[j]
-
- vector signed int vo1 = vec_add(v1, vf1);
- vector signed int vo2 = vec_add(v2, vf2);
- vector signed int vo1_V = vec_add(v1_V, vf1_V);
- vector signed int vo2_V = vec_add(v2_V, vf2_V);
-
- vec_st(vo1, offset, u);
- vec_st(vo2, offset + 16, u);
- vec_st(vo1_V, offset, v);
- vec_st(vo2_V, offset + 16, v);
-
- l1 = l2;
- l1_V = l2_V;
- }
- for ( ; i < chrDstW; i++) {
- u[i] += chrUSrc[j][i] * chrFilter[j];
- v[i] += chrVSrc[j][i] * chrFilter[j];
- }
- }
- altivec_packIntArrayToCharArray(u, uDest, chrDstW);
- altivec_packIntArrayToCharArray(v, vDest, chrDstW);
- }
}
-static void hScale_altivec_real(int16_t *dst, int dstW,
- const uint8_t *src, int srcW,
- int xInc, const int16_t *filter,
+static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
+ const uint8_t *src, const int16_t *filter,
const int16_t *filterPos, int filterSize)
{
register int i;
@@ -408,17 +331,25 @@ void ff_sws_init_swScale_altivec(SwsContext *c)
if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
return;
- c->hScale = hScale_altivec_real;
- if (!is16BPS(dstFormat) && !is9_OR_10BPS(dstFormat)) {
- c->yuv2yuvX = yuv2yuvX_altivec_real;
+ if (c->srcBpc == 8 && c->dstBpc <= 10) {
+ c->hyScale = c->hcScale = hScale_altivec_real;
+ }
+ if (!is16BPS(dstFormat) && !is9_OR_10BPS(dstFormat) &&
+ dstFormat != PIX_FMT_NV12 && dstFormat != PIX_FMT_NV21 &&
+ !c->alpPixBuf) {
+ c->yuv2planeX = yuv2planeX_altivec;
}
/* The following list of supported dstFormat values should
* match what's found in the body of ff_yuv2packedX_altivec() */
- if (!(c->flags & (SWS_BITEXACT | SWS_FULL_CHR_H_INT)) && !c->alpPixBuf &&
- (c->dstFormat==PIX_FMT_ABGR || c->dstFormat==PIX_FMT_BGRA ||
- c->dstFormat==PIX_FMT_BGR24 || c->dstFormat==PIX_FMT_RGB24 ||
- c->dstFormat==PIX_FMT_RGBA || c->dstFormat==PIX_FMT_ARGB)) {
- c->yuv2packedX = ff_yuv2packedX_altivec;
+ if (!(c->flags & (SWS_BITEXACT | SWS_FULL_CHR_H_INT)) && !c->alpPixBuf) {
+ switch (c->dstFormat) {
+ case PIX_FMT_ABGR: c->yuv2packedX = ff_yuv2abgr_X_altivec; break;
+ case PIX_FMT_BGRA: c->yuv2packedX = ff_yuv2bgra_X_altivec; break;
+ case PIX_FMT_ARGB: c->yuv2packedX = ff_yuv2argb_X_altivec; break;
+ case PIX_FMT_RGBA: c->yuv2packedX = ff_yuv2rgba_X_altivec; break;
+ case PIX_FMT_BGR24: c->yuv2packedX = ff_yuv2bgr24_X_altivec; break;
+ case PIX_FMT_RGB24: c->yuv2packedX = ff_yuv2rgb24_X_altivec; break;
}
+ }
}
diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
index 476db22..73c02e9 100644
--- a/libswscale/ppc/yuv2rgb_altivec.c
+++ b/libswscale/ppc/yuv2rgb_altivec.c
@@ -626,13 +626,13 @@ void ff_yuv2rgb_init_tables_altivec(SwsContext *c, const int inv_table[4], int b
}
-void
+static av_always_inline void
ff_yuv2packedX_altivec(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint8_t *dest,
- int dstW, int dstY)
+ int dstW, int dstY, enum PixelFormat target)
{
int i,j;
vector signed short X,X0,X1,Y0,U0,V0,Y1,U1,V1,U,V;
@@ -706,7 +706,7 @@ ff_yuv2packedX_altivec(SwsContext *c, const int16_t *lumFilter,
G = vec_packclp (G0,G1);
B = vec_packclp (B0,B1);
- switch(c->dstFormat) {
+ switch(target) {
case PIX_FMT_ABGR: out_abgr (R,G,B,out); break;
case PIX_FMT_BGRA: out_bgra (R,G,B,out); break;
case PIX_FMT_RGBA: out_rgba (R,G,B,out); break;
@@ -785,7 +785,7 @@ ff_yuv2packedX_altivec(SwsContext *c, const int16_t *lumFilter,
B = vec_packclp (B0,B1);
nout = (vector unsigned char *)scratch;
- switch(c->dstFormat) {
+ switch(target) {
case PIX_FMT_ABGR: out_abgr (R,G,B,nout); break;
case PIX_FMT_BGRA: out_bgra (R,G,B,nout); break;
case PIX_FMT_RGBA: out_rgba (R,G,B,nout); break;
@@ -803,3 +803,23 @@ ff_yuv2packedX_altivec(SwsContext *c, const int16_t *lumFilter,
}
}
+
+#define YUV2PACKEDX_WRAPPER(suffix, pixfmt) \
+void ff_yuv2 ## suffix ## _X_altivec(SwsContext *c, const int16_t *lumFilter, \
+ const int16_t **lumSrc, int lumFilterSize, \
+ const int16_t *chrFilter, const int16_t **chrUSrc, \
+ const int16_t **chrVSrc, int chrFilterSize, \
+ const int16_t **alpSrc, uint8_t *dest, \
+ int dstW, int dstY) \
+{ \
+ ff_yuv2packedX_altivec(c, lumFilter, lumSrc, lumFilterSize, \
+ chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
+ alpSrc, dest, dstW, dstY, pixfmt); \
+}
+
+YUV2PACKEDX_WRAPPER(abgr, PIX_FMT_ABGR);
+YUV2PACKEDX_WRAPPER(bgra, PIX_FMT_BGRA);
+YUV2PACKEDX_WRAPPER(argb, PIX_FMT_ARGB);
+YUV2PACKEDX_WRAPPER(rgba, PIX_FMT_RGBA);
+YUV2PACKEDX_WRAPPER(rgb24, PIX_FMT_RGB24);
+YUV2PACKEDX_WRAPPER(bgr24, PIX_FMT_BGR24);
diff --git a/libswscale/ppc/yuv2rgb_altivec.h b/libswscale/ppc/yuv2rgb_altivec.h
index b54a856..b809fe1 100644
--- a/libswscale/ppc/yuv2rgb_altivec.h
+++ b/libswscale/ppc/yuv2rgb_altivec.h
@@ -24,11 +24,19 @@
#ifndef PPC_YUV2RGB_ALTIVEC_H
#define PPC_YUV2RGB_ALTIVEC_H 1
-void ff_yuv2packedX_altivec(SwsContext *c, const int16_t *lumFilter,
- const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrUSrc,
- const int16_t **chrVSrc, int chrFilterSize,
- const int16_t **alpSrc, uint8_t *dest,
+#define YUV2PACKEDX_HEADER(suffix) \
+void ff_yuv2 ## suffix ## _X_altivec(SwsContext *c, const int16_t *lumFilter, \
+ const int16_t **lumSrc, int lumFilterSize, \
+ const int16_t *chrFilter, const int16_t **chrUSrc, \
+ const int16_t **chrVSrc, int chrFilterSize, \
+ const int16_t **alpSrc, uint8_t *dest, \
int dstW, int dstY);
+YUV2PACKEDX_HEADER(abgr);
+YUV2PACKEDX_HEADER(bgra);
+YUV2PACKEDX_HEADER(argb);
+YUV2PACKEDX_HEADER(rgba);
+YUV2PACKEDX_HEADER(rgb24);
+YUV2PACKEDX_HEADER(bgr24);
+
#endif /* PPC_YUV2RGB_ALTIVEC_H */
diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c
index 51cb600..0f07e57 100644
--- a/libswscale/rgb2rgb.c
+++ b/libswscale/rgb2rgb.c
@@ -310,8 +310,8 @@ void shuffle_bytes_##a##b##c##d(const uint8_t *src, uint8_t *dst, int src_size)
} \
}
-DEFINE_SHUFFLE_BYTES(0, 3, 2, 1);
-DEFINE_SHUFFLE_BYTES(1, 2, 3, 0);
-DEFINE_SHUFFLE_BYTES(3, 0, 1, 2);
-DEFINE_SHUFFLE_BYTES(3, 2, 1, 0);
+DEFINE_SHUFFLE_BYTES(0, 3, 2, 1)
+DEFINE_SHUFFLE_BYTES(1, 2, 3, 0)
+DEFINE_SHUFFLE_BYTES(3, 0, 1, 2)
+DEFINE_SHUFFLE_BYTES(3, 2, 1, 0)
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index f729c11..f24561b 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -80,17 +80,6 @@ untested special converters
#define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
#define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5))
-static const double rgb2yuv_table[8][9]={
- {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, //ITU709
- {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5}, //ITU709
- {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
- {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
- {0.59 , 0.11 , 0.30 , -0.331, 0.5, -0.169, -0.421, -0.079, 0.5}, //FCC
- {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
- {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5}, //DEFAULT / ITU601 / ITU624 / SMPTE 170M
- {0.701 , 0.087 , 0.212 , -0.384, 0.5, -0.116, -0.445, -0.055, 0.5}, //SMPTE 240M
-};
-
/*
NOTES
Special versions: fast Y 1:1 scaling (no interpolation in y direction)
@@ -193,218 +182,188 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
{ 77, 23, 60, 15, 72, 21, 56, 14, },
};
#endif
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8] = {
+{ 36, 68, 60, 92, 34, 66, 58, 90,},
+{ 100, 4,124, 28, 98, 2,122, 26,},
+{ 52, 84, 44, 76, 50, 82, 42, 74,},
+{ 116, 20,108, 12,114, 18,106, 10,},
+{ 32, 64, 56, 88, 38, 70, 62, 94,},
+{ 96, 0,120, 24,102, 6,126, 30,},
+{ 48, 80, 40, 72, 54, 86, 46, 78,},
+{ 112, 16,104, 8,118, 22,110, 14,},
+};
+DECLARE_ALIGNED(8, const uint8_t, ff_sws_pb_64)[8] =
+{ 64, 64, 64, 64, 64, 64, 64, 64 };
+
+#define output_pixel(pos, val, bias, signedness) \
+ if (big_endian) { \
+ AV_WB16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \
+ } else { \
+ AV_WL16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \
+ }
static av_always_inline void
-yuv2yuvX16_c_template(const int16_t *lumFilter, const int16_t **lumSrc,
- int lumFilterSize, const int16_t *chrFilter,
- const int16_t **chrUSrc, const int16_t **chrVSrc,
- int chrFilterSize, const int16_t **alpSrc,
- uint16_t *dest, uint16_t *uDest, uint16_t *vDest,
- uint16_t *aDest, int dstW, int chrDstW,
- int big_endian, int output_bits)
+yuv2plane1_16_c_template(const int32_t *src, uint16_t *dest, int dstW,
+ int big_endian, int output_bits)
{
- //FIXME Optimize (just quickly written not optimized..)
int i;
- int shift = 11 + 16 - output_bits;
+ int shift = 19 - output_bits;
-#define output_pixel(pos, val) \
- if (big_endian) { \
- if (output_bits == 16) { \
- AV_WB16(pos, av_clip_uint16(val >> shift)); \
- } else { \
- AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
- } \
- } else { \
- if (output_bits == 16) { \
- AV_WL16(pos, av_clip_uint16(val >> shift)); \
- } else { \
- AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
- } \
+ for (i = 0; i < dstW; i++) {
+ int val = src[i] + (1 << (shift - 1));
+ output_pixel(&dest[i], val, 0, uint);
}
+}
+
+static av_always_inline void
+yuv2planeX_16_c_template(const int16_t *filter, int filterSize,
+ const int32_t **src, uint16_t *dest, int dstW,
+ int big_endian, int output_bits)
+{
+ int i;
+ int shift = 15 + 16 - output_bits;
+
for (i = 0; i < dstW; i++) {
- int val = 1 << (26-output_bits);
+ int val = 1 << (30-output_bits);
int j;
- for (j = 0; j < lumFilterSize; j++)
- val += lumSrc[j][i] * lumFilter[j];
+ /* range of val is [0,0x7FFFFFFF], so 31 bits, but with lanczos/spline
+ * filters (or anything with negative coeffs, the range can be slightly
+ * wider in both directions. To account for this overflow, we subtract
+ * a constant so it always fits in the signed range (assuming a
+ * reasonable filterSize), and re-add that at the end. */
+ val -= 0x40000000;
+ for (j = 0; j < filterSize; j++)
+ val += src[j][i] * filter[j];
- output_pixel(&dest[i], val);
+ output_pixel(&dest[i], val, 0x8000, int);
}
+}
- if (uDest) {
- for (i = 0; i < chrDstW; i++) {
- int u = 1 << (26-output_bits);
- int v = 1 << (26-output_bits);
- int j;
+#undef output_pixel
- for (j = 0; j < chrFilterSize; j++) {
- u += chrUSrc[j][i] * chrFilter[j];
- v += chrVSrc[j][i] * chrFilter[j];
- }
+#define output_pixel(pos, val) \
+ if (big_endian) { \
+ AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
+ } else { \
+ AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
+ }
- output_pixel(&uDest[i], u);
- output_pixel(&vDest[i], v);
- }
+static av_always_inline void
+yuv2plane1_10_c_template(const int16_t *src, uint16_t *dest, int dstW,
+ int big_endian, int output_bits)
+{
+ int i;
+ int shift = 15 - output_bits;
+
+ for (i = 0; i < dstW; i++) {
+ int val = src[i] + (1 << (shift - 1));
+ output_pixel(&dest[i], val);
}
+}
- if (CONFIG_SWSCALE_ALPHA && aDest) {
- for (i = 0; i < dstW; i++) {
- int val = 1 << (26-output_bits);
- int j;
+static av_always_inline void
+yuv2planeX_10_c_template(const int16_t *filter, int filterSize,
+ const int16_t **src, uint16_t *dest, int dstW,
+ int big_endian, int output_bits)
+{
+ int i;
+ int shift = 11 + 16 - output_bits;
- for (j = 0; j < lumFilterSize; j++)
- val += alpSrc[j][i] * lumFilter[j];
+ for (i = 0; i < dstW; i++) {
+ int val = 1 << (26-output_bits);
+ int j;
- output_pixel(&aDest[i], val);
- }
+ for (j = 0; j < filterSize; j++)
+ val += src[j][i] * filter[j];
+
+ output_pixel(&dest[i], val);
}
-#undef output_pixel
}
-#define yuv2NBPS(bits, BE_LE, is_be) \
-static void yuv2yuvX ## bits ## BE_LE ## _c(SwsContext *c, const int16_t *lumFilter, \
- const int16_t **lumSrc, int lumFilterSize, \
- const int16_t *chrFilter, const int16_t **chrUSrc, \
- const int16_t **chrVSrc, \
- int chrFilterSize, const int16_t **alpSrc, \
- uint8_t *_dest, uint8_t *_uDest, uint8_t *_vDest, \
- uint8_t *_aDest, int dstW, int chrDstW) \
+#undef output_pixel
+
+#define yuv2NBPS(bits, BE_LE, is_be, template_size, typeX_t) \
+static void yuv2plane1_ ## bits ## BE_LE ## _c(const int16_t *src, \
+ uint8_t *dest, int dstW, \
+ const uint8_t *dither, int offset)\
{ \
- uint16_t *dest = (uint16_t *) _dest, *uDest = (uint16_t *) _uDest, \
- *vDest = (uint16_t *) _vDest, *aDest = (uint16_t *) _aDest; \
- yuv2yuvX16_c_template(lumFilter, lumSrc, lumFilterSize, \
- chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
- alpSrc, \
- dest, uDest, vDest, aDest, \
- dstW, chrDstW, is_be, bits); \
-}
-yuv2NBPS( 9, BE, 1);
-yuv2NBPS( 9, LE, 0);
-yuv2NBPS(10, BE, 1);
-yuv2NBPS(10, LE, 0);
-yuv2NBPS(16, BE, 1);
-yuv2NBPS(16, LE, 0);
-
-static void yuv2yuvX_c(SwsContext *c, const int16_t *lumFilter,
- const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrUSrc,
- const int16_t **chrVSrc,
- int chrFilterSize, const int16_t **alpSrc,
- uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
- uint8_t *aDest, int dstW, int chrDstW)
-{
- //FIXME Optimize (just quickly written not optimized..)
+ yuv2plane1_ ## template_size ## _c_template((const typeX_t *) src, \
+ (uint16_t *) dest, dstW, is_be, bits); \
+}\
+static void yuv2planeX_ ## bits ## BE_LE ## _c(const int16_t *filter, int filterSize, \
+ const int16_t **src, uint8_t *dest, int dstW, \
+ const uint8_t *dither, int offset)\
+{ \
+ yuv2planeX_## template_size ## _c_template(filter, \
+ filterSize, (const typeX_t **) src, \
+ (uint16_t *) dest, dstW, is_be, bits); \
+}
+yuv2NBPS( 9, BE, 1, 10, int16_t)
+yuv2NBPS( 9, LE, 0, 10, int16_t)
+yuv2NBPS(10, BE, 1, 10, int16_t)
+yuv2NBPS(10, LE, 0, 10, int16_t)
+yuv2NBPS(16, BE, 1, 16, int32_t)
+yuv2NBPS(16, LE, 0, 16, int32_t)
+
+static void yuv2planeX_8_c(const int16_t *filter, int filterSize,
+ const int16_t **src, uint8_t *dest, int dstW,
+ const uint8_t *dither, int offset)
+{
int i;
for (i=0; i<dstW; i++) {
- int val=1<<18;
+ int val = dither[(i + offset) & 7] << 12;
int j;
- for (j=0; j<lumFilterSize; j++)
- val += lumSrc[j][i] * lumFilter[j];
+ for (j=0; j<filterSize; j++)
+ val += src[j][i] * filter[j];
dest[i]= av_clip_uint8(val>>19);
}
-
- if (uDest)
- for (i=0; i<chrDstW; i++) {
- int u=1<<18;
- int v=1<<18;
- int j;
- for (j=0; j<chrFilterSize; j++) {
- u += chrUSrc[j][i] * chrFilter[j];
- v += chrVSrc[j][i] * chrFilter[j];
- }
-
- uDest[i]= av_clip_uint8(u>>19);
- vDest[i]= av_clip_uint8(v>>19);
- }
-
- if (CONFIG_SWSCALE_ALPHA && aDest)
- for (i=0; i<dstW; i++) {
- int val=1<<18;
- int j;
- for (j=0; j<lumFilterSize; j++)
- val += alpSrc[j][i] * lumFilter[j];
-
- aDest[i]= av_clip_uint8(val>>19);
- }
}
-static void yuv2yuv1_c(SwsContext *c, const int16_t *lumSrc,
- const int16_t *chrUSrc, const int16_t *chrVSrc,
- const int16_t *alpSrc,
- uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
- uint8_t *aDest, int dstW, int chrDstW)
+static void yuv2plane1_8_c(const int16_t *src, uint8_t *dest, int dstW,
+ const uint8_t *dither, int offset)
{
int i;
for (i=0; i<dstW; i++) {
- int val= (lumSrc[i]+64)>>7;
+ int val = (src[i] + dither[(i + offset) & 7]) >> 7;
dest[i]= av_clip_uint8(val);
}
-
- if (uDest)
- for (i=0; i<chrDstW; i++) {
- int u=(chrUSrc[i]+64)>>7;
- int v=(chrVSrc[i]+64)>>7;
- uDest[i]= av_clip_uint8(u);
- vDest[i]= av_clip_uint8(v);
- }
-
- if (CONFIG_SWSCALE_ALPHA && aDest)
- for (i=0; i<dstW; i++) {
- int val= (alpSrc[i]+64)>>7;
- aDest[i]= av_clip_uint8(val);
- }
}
-static void yuv2nv12X_c(SwsContext *c, const int16_t *lumFilter,
- const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrUSrc,
- const int16_t **chrVSrc, int chrFilterSize,
- const int16_t **alpSrc, uint8_t *dest, uint8_t *uDest,
- uint8_t *vDest, uint8_t *aDest,
- int dstW, int chrDstW)
+static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize,
+ const int16_t **chrUSrc, const int16_t **chrVSrc,
+ uint8_t *dest, int chrDstW)
{
enum PixelFormat dstFormat = c->dstFormat;
-
- //FIXME Optimize (just quickly written not optimized..)
+ const uint8_t *chrDither = c->chrDither8;
int i;
- for (i=0; i<dstW; i++) {
- int val=1<<18;
- int j;
- for (j=0; j<lumFilterSize; j++)
- val += lumSrc[j][i] * lumFilter[j];
-
- dest[i]= av_clip_uint8(val>>19);
- }
-
- if (!uDest)
- return;
if (dstFormat == PIX_FMT_NV12)
for (i=0; i<chrDstW; i++) {
- int u=1<<18;
- int v=1<<18;
+ int u = chrDither[i & 7] << 12;
+ int v = chrDither[(i + 3) & 7] << 12;
int j;
for (j=0; j<chrFilterSize; j++) {
u += chrUSrc[j][i] * chrFilter[j];
v += chrVSrc[j][i] * chrFilter[j];
}
- uDest[2*i]= av_clip_uint8(u>>19);
- uDest[2*i+1]= av_clip_uint8(v>>19);
+ dest[2*i]= av_clip_uint8(u>>19);
+ dest[2*i+1]= av_clip_uint8(v>>19);
}
else
for (i=0; i<chrDstW; i++) {
- int u=1<<18;
- int v=1<<18;
+ int u = chrDither[i & 7] << 12;
+ int v = chrDither[(i + 3) & 7] << 12;
int j;
for (j=0; j<chrFilterSize; j++) {
u += chrUSrc[j][i] * chrFilter[j];
v += chrVSrc[j][i] * chrFilter[j];
}
- uDest[2*i]= av_clip_uint8(v>>19);
- uDest[2*i+1]= av_clip_uint8(u>>19);
+ dest[2*i]= av_clip_uint8(v>>19);
+ dest[2*i+1]= av_clip_uint8(u>>19);
}
}
@@ -417,118 +376,119 @@ static void yuv2nv12X_c(SwsContext *c, const int16_t *lumFilter,
static av_always_inline void
yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter,
- const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrUSrc,
- const int16_t **chrVSrc, int chrFilterSize,
- const int16_t **alpSrc, uint8_t *dest, int dstW,
+ const int32_t **lumSrc, int lumFilterSize,
+ const int16_t *chrFilter, const int32_t **chrUSrc,
+ const int32_t **chrVSrc, int chrFilterSize,
+ const int32_t **alpSrc, uint16_t *dest, int dstW,
int y, enum PixelFormat target)
{
int i;
for (i = 0; i < (dstW >> 1); i++) {
int j;
- int Y1 = 1 << 18;
- int Y2 = 1 << 18;
- const int i2 = 2 * i;
+ int Y1 = (1 << 14) - 0x40000000;
+ int Y2 = (1 << 14) - 0x40000000;
for (j = 0; j < lumFilterSize; j++) {
- Y1 += lumSrc[j][i2] * lumFilter[j];
- Y2 += lumSrc[j][i2+1] * lumFilter[j];
- }
- Y1 >>= 11;
- Y2 >>= 11;
- if ((Y1 | Y2) & 0x10000) {
- Y1 = av_clip_uint16(Y1);
- Y2 = av_clip_uint16(Y2);
+ Y1 += lumSrc[j][i * 2] * lumFilter[j];
+ Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
}
- output_pixel(&dest[2 * i2 + 0], Y1);
- output_pixel(&dest[2 * i2 + 2], Y2);
+ Y1 >>= 15;
+ Y2 >>= 15;
+ Y1 = av_clip_int16(Y1);
+ Y2 = av_clip_int16(Y2);
+ output_pixel(&dest[i * 2 + 0], 0x8000 + Y1);
+ output_pixel(&dest[i * 2 + 1], 0x8000 + Y2);
}
}
static av_always_inline void
-yuv2gray16_2_c_template(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *ubuf0,
- const uint16_t *ubuf1, const uint16_t *vbuf0,
- const uint16_t *vbuf1, const uint16_t *abuf0,
- const uint16_t *abuf1, uint8_t *dest, int dstW,
+yuv2gray16_2_c_template(SwsContext *c, const int32_t *buf[2],
+ const int32_t *ubuf[2], const int32_t *vbuf[2],
+ const int32_t *abuf[2], uint16_t *dest, int dstW,
int yalpha, int uvalpha, int y,
enum PixelFormat target)
{
- int yalpha1 = 4095 - yalpha; \
+ int yalpha1 = 4095 - yalpha;
int i;
+ const int32_t *buf0 = buf[0], *buf1 = buf[1];
for (i = 0; i < (dstW >> 1); i++) {
- const int i2 = 2 * i;
- int Y1 = (buf0[i2 ] * yalpha1 + buf1[i2 ] * yalpha) >> 11;
- int Y2 = (buf0[i2+1] * yalpha1 + buf1[i2+1] * yalpha) >> 11;
+ int Y1 = (buf0[i * 2 ] * yalpha1 + buf1[i * 2 ] * yalpha) >> 15;
+ int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 15;
- output_pixel(&dest[2 * i2 + 0], Y1);
- output_pixel(&dest[2 * i2 + 2], Y2);
+ output_pixel(&dest[i * 2 + 0], Y1);
+ output_pixel(&dest[i * 2 + 1], Y2);
}
}
static av_always_inline void
-yuv2gray16_1_c_template(SwsContext *c, const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, uint8_t *dest, int dstW,
- int uvalpha, enum PixelFormat dstFormat,
- int flags, int y, enum PixelFormat target)
+yuv2gray16_1_c_template(SwsContext *c, const int32_t *buf0,
+ const int32_t *ubuf[2], const int32_t *vbuf[2],
+ const int32_t *abuf0, uint16_t *dest, int dstW,
+ int uvalpha, int y, enum PixelFormat target)
{
int i;
for (i = 0; i < (dstW >> 1); i++) {
- const int i2 = 2 * i;
- int Y1 = buf0[i2 ] << 1;
- int Y2 = buf0[i2+1] << 1;
+ int Y1 = buf0[i * 2 ] << 1;
+ int Y2 = buf0[i * 2 + 1] << 1;
- output_pixel(&dest[2 * i2 + 0], Y1);
- output_pixel(&dest[2 * i2 + 2], Y2);
+ output_pixel(&dest[i * 2 + 0], Y1);
+ output_pixel(&dest[i * 2 + 1], Y2);
}
}
#undef output_pixel
-#define YUV2PACKEDWRAPPER(name, base, ext, fmt) \
+#define YUV2PACKED16WRAPPER(name, base, ext, fmt) \
static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
- const int16_t **lumSrc, int lumFilterSize, \
- const int16_t *chrFilter, const int16_t **chrUSrc, \
- const int16_t **chrVSrc, int chrFilterSize, \
- const int16_t **alpSrc, uint8_t *dest, int dstW, \
+ const int16_t **_lumSrc, int lumFilterSize, \
+ const int16_t *chrFilter, const int16_t **_chrUSrc, \
+ const int16_t **_chrVSrc, int chrFilterSize, \
+ const int16_t **_alpSrc, uint8_t *_dest, int dstW, \
int y) \
{ \
+ const int32_t **lumSrc = (const int32_t **) _lumSrc, \
+ **chrUSrc = (const int32_t **) _chrUSrc, \
+ **chrVSrc = (const int32_t **) _chrVSrc, \
+ **alpSrc = (const int32_t **) _alpSrc; \
+ uint16_t *dest = (uint16_t *) _dest; \
name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
alpSrc, dest, dstW, y, fmt); \
} \
\
-static void name ## ext ## _2_c(SwsContext *c, const uint16_t *buf0, \
- const uint16_t *buf1, const uint16_t *ubuf0, \
- const uint16_t *ubuf1, const uint16_t *vbuf0, \
- const uint16_t *vbuf1, const uint16_t *abuf0, \
- const uint16_t *abuf1, uint8_t *dest, int dstW, \
+static void name ## ext ## _2_c(SwsContext *c, const int16_t *_buf[2], \
+ const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
+ const int16_t *_abuf[2], uint8_t *_dest, int dstW, \
int yalpha, int uvalpha, int y) \
{ \
- name ## base ## _2_c_template(c, buf0, buf1, ubuf0, ubuf1, \
- vbuf0, vbuf1, abuf0, abuf1, \
+ const int32_t **buf = (const int32_t **) _buf, \
+ **ubuf = (const int32_t **) _ubuf, \
+ **vbuf = (const int32_t **) _vbuf, \
+ **abuf = (const int32_t **) _abuf; \
+ uint16_t *dest = (uint16_t *) _dest; \
+ name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
dest, dstW, yalpha, uvalpha, y, fmt); \
} \
\
-static void name ## ext ## _1_c(SwsContext *c, const uint16_t *buf0, \
- const uint16_t *ubuf0, const uint16_t *ubuf1, \
- const uint16_t *vbuf0, const uint16_t *vbuf1, \
- const uint16_t *abuf0, uint8_t *dest, int dstW, \
- int uvalpha, enum PixelFormat dstFormat, \
- int flags, int y) \
+static void name ## ext ## _1_c(SwsContext *c, const int16_t *_buf0, \
+ const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
+ const int16_t *_abuf0, uint8_t *_dest, int dstW, \
+ int uvalpha, int y) \
{ \
- name ## base ## _1_c_template(c, buf0, ubuf0, ubuf1, vbuf0, \
- vbuf1, abuf0, dest, dstW, uvalpha, \
- dstFormat, flags, y, fmt); \
+ const int32_t *buf0 = (const int32_t *) _buf0, \
+ **ubuf = (const int32_t **) _ubuf, \
+ **vbuf = (const int32_t **) _vbuf, \
+ *abuf0 = (const int32_t *) _abuf0; \
+ uint16_t *dest = (uint16_t *) _dest; \
+ name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
+ dstW, uvalpha, y, fmt); \
}
-YUV2PACKEDWRAPPER(yuv2gray16,, LE, PIX_FMT_GRAY16LE);
-YUV2PACKEDWRAPPER(yuv2gray16,, BE, PIX_FMT_GRAY16BE);
+YUV2PACKED16WRAPPER(yuv2gray16,, LE, PIX_FMT_GRAY16LE)
+YUV2PACKED16WRAPPER(yuv2gray16,, BE, PIX_FMT_GRAY16BE)
#define output_pixel(pos, acc) \
if (target == PIX_FMT_MONOBLACK) { \
@@ -548,7 +508,7 @@ yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
const uint8_t * const d128=dither_8x8_220[y&7];
uint8_t *g = c->table_gU[128] + c->table_gV[128];
int i;
- int acc = 0;
+ unsigned acc = 0;
for (i = 0; i < dstW - 1; i += 2) {
int j;
@@ -574,14 +534,13 @@ yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
}
static av_always_inline void
-yuv2mono_2_c_template(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *ubuf0,
- const uint16_t *ubuf1, const uint16_t *vbuf0,
- const uint16_t *vbuf1, const uint16_t *abuf0,
- const uint16_t *abuf1, uint8_t *dest, int dstW,
+yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2],
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf[2], uint8_t *dest, int dstW,
int yalpha, int uvalpha, int y,
enum PixelFormat target)
{
+ const int16_t *buf0 = buf[0], *buf1 = buf[1];
const uint8_t * const d128 = dither_8x8_220[y & 7];
uint8_t *g = c->table_gU[128] + c->table_gV[128];
int yalpha1 = 4095 - yalpha;
@@ -601,12 +560,10 @@ yuv2mono_2_c_template(SwsContext *c, const uint16_t *buf0,
}
static av_always_inline void
-yuv2mono_1_c_template(SwsContext *c, const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, uint8_t *dest, int dstW,
- int uvalpha, enum PixelFormat dstFormat,
- int flags, int y, enum PixelFormat target)
+yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0,
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf0, uint8_t *dest, int dstW,
+ int uvalpha, int y, enum PixelFormat target)
{
const uint8_t * const d128 = dither_8x8_220[y & 7];
uint8_t *g = c->table_gU[128] + c->table_gV[128];
@@ -627,8 +584,40 @@ yuv2mono_1_c_template(SwsContext *c, const uint16_t *buf0,
#undef output_pixel
-YUV2PACKEDWRAPPER(yuv2mono,, white, PIX_FMT_MONOWHITE);
-YUV2PACKEDWRAPPER(yuv2mono,, black, PIX_FMT_MONOBLACK);
+#define YUV2PACKEDWRAPPER(name, base, ext, fmt) \
+static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
+ const int16_t **lumSrc, int lumFilterSize, \
+ const int16_t *chrFilter, const int16_t **chrUSrc, \
+ const int16_t **chrVSrc, int chrFilterSize, \
+ const int16_t **alpSrc, uint8_t *dest, int dstW, \
+ int y) \
+{ \
+ name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
+ chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
+ alpSrc, dest, dstW, y, fmt); \
+} \
+ \
+static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
+ const int16_t *ubuf[2], const int16_t *vbuf[2], \
+ const int16_t *abuf[2], uint8_t *dest, int dstW, \
+ int yalpha, int uvalpha, int y) \
+{ \
+ name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
+ dest, dstW, yalpha, uvalpha, y, fmt); \
+} \
+ \
+static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
+ const int16_t *ubuf[2], const int16_t *vbuf[2], \
+ const int16_t *abuf0, uint8_t *dest, int dstW, \
+ int uvalpha, int y) \
+{ \
+ name ## base ## _1_c_template(c, buf0, ubuf, vbuf, \
+ abuf0, dest, dstW, uvalpha, \
+ y, fmt); \
+}
+
+YUV2PACKEDWRAPPER(yuv2mono,, white, PIX_FMT_MONOWHITE)
+YUV2PACKEDWRAPPER(yuv2mono,, black, PIX_FMT_MONOBLACK)
#define output_pixels(pos, Y1, U, Y2, V) \
if (target == PIX_FMT_YUYV422) { \
@@ -683,14 +672,15 @@ yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
}
static av_always_inline void
-yuv2422_2_c_template(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *ubuf0,
- const uint16_t *ubuf1, const uint16_t *vbuf0,
- const uint16_t *vbuf1, const uint16_t *abuf0,
- const uint16_t *abuf1, uint8_t *dest, int dstW,
+yuv2422_2_c_template(SwsContext *c, const int16_t *buf[2],
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf[2], uint8_t *dest, int dstW,
int yalpha, int uvalpha, int y,
enum PixelFormat target)
{
+ const int16_t *buf0 = buf[0], *buf1 = buf[1],
+ *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
+ *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
int yalpha1 = 4095 - yalpha;
int uvalpha1 = 4095 - uvalpha;
int i;
@@ -706,13 +696,13 @@ yuv2422_2_c_template(SwsContext *c, const uint16_t *buf0,
}
static av_always_inline void
-yuv2422_1_c_template(SwsContext *c, const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, uint8_t *dest, int dstW,
- int uvalpha, enum PixelFormat dstFormat,
- int flags, int y, enum PixelFormat target)
+yuv2422_1_c_template(SwsContext *c, const int16_t *buf0,
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf0, uint8_t *dest, int dstW,
+ int uvalpha, int y, enum PixelFormat target)
{
+ const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
+ *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
int i;
if (uvalpha < 2048) {
@@ -738,29 +728,325 @@ yuv2422_1_c_template(SwsContext *c, const uint16_t *buf0,
#undef output_pixels
-YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, PIX_FMT_YUYV422);
-YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, PIX_FMT_UYVY422);
+YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, PIX_FMT_YUYV422)
+YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, PIX_FMT_UYVY422)
-#define r_b ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? r : b)
-#define b_r ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? b : r)
+#define R_B ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? R : B)
+#define B_R ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? B : R)
+#define output_pixel(pos, val) \
+ if (isBE(target)) { \
+ AV_WB16(pos, val); \
+ } else { \
+ AV_WL16(pos, val); \
+ }
static av_always_inline void
yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
- const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrUSrc,
- const int16_t **chrVSrc, int chrFilterSize,
- const int16_t **alpSrc, uint8_t *dest, int dstW,
+ const int32_t **lumSrc, int lumFilterSize,
+ const int16_t *chrFilter, const int32_t **chrUSrc,
+ const int32_t **chrVSrc, int chrFilterSize,
+ const int32_t **alpSrc, uint16_t *dest, int dstW,
int y, enum PixelFormat target)
{
int i;
for (i = 0; i < (dstW >> 1); i++) {
int j;
+ int Y1 = -0x40000000;
+ int Y2 = -0x40000000;
+ int U = -128 << 23; // 19
+ int V = -128 << 23;
+ int R, G, B;
+
+ for (j = 0; j < lumFilterSize; j++) {
+ Y1 += lumSrc[j][i * 2] * lumFilter[j];
+ Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
+ }
+ for (j = 0; j < chrFilterSize; j++) {
+ U += chrUSrc[j][i] * chrFilter[j];
+ V += chrVSrc[j][i] * chrFilter[j];
+ }
+
+ // 8bit: 12+15=27; 16-bit: 12+19=31
+ Y1 >>= 14; // 10
+ Y1 += 0x10000;
+ Y2 >>= 14;
+ Y2 += 0x10000;
+ U >>= 14;
+ V >>= 14;
+
+ // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit
+ Y1 -= c->yuv2rgb_y_offset;
+ Y2 -= c->yuv2rgb_y_offset;
+ Y1 *= c->yuv2rgb_y_coeff;
+ Y2 *= c->yuv2rgb_y_coeff;
+ Y1 += 1 << 13; // 21
+ Y2 += 1 << 13;
+ // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit
+
+ R = V * c->yuv2rgb_v2r_coeff;
+ G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+ B = U * c->yuv2rgb_u2b_coeff;
+
+ // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit
+ output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
+ output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
+ output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
+ output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
+ output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14);
+ output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ dest += 6;
+ }
+}
+
+static av_always_inline void
+yuv2rgb48_2_c_template(SwsContext *c, const int32_t *buf[2],
+ const int32_t *ubuf[2], const int32_t *vbuf[2],
+ const int32_t *abuf[2], uint16_t *dest, int dstW,
+ int yalpha, int uvalpha, int y,
+ enum PixelFormat target)
+{
+ const int32_t *buf0 = buf[0], *buf1 = buf[1],
+ *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
+ *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
+ int yalpha1 = 4095 - yalpha;
+ int uvalpha1 = 4095 - uvalpha;
+ int i;
+
+ for (i = 0; i < (dstW >> 1); i++) {
+ int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 14;
+ int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 14;
+ int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha + (-128 << 23)) >> 14;
+ int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha + (-128 << 23)) >> 14;
+ int R, G, B;
+
+ Y1 -= c->yuv2rgb_y_offset;
+ Y2 -= c->yuv2rgb_y_offset;
+ Y1 *= c->yuv2rgb_y_coeff;
+ Y2 *= c->yuv2rgb_y_coeff;
+ Y1 += 1 << 13;
+ Y2 += 1 << 13;
+
+ R = V * c->yuv2rgb_v2r_coeff;
+ G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+ B = U * c->yuv2rgb_u2b_coeff;
+
+ output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
+ output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
+ output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
+ output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
+ output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14);
+ output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ dest += 6;
+ }
+}
+
+static av_always_inline void
+yuv2rgb48_1_c_template(SwsContext *c, const int32_t *buf0,
+ const int32_t *ubuf[2], const int32_t *vbuf[2],
+ const int32_t *abuf0, uint16_t *dest, int dstW,
+ int uvalpha, int y, enum PixelFormat target)
+{
+ const int32_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
+ *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
+ int i;
+
+ if (uvalpha < 2048) {
+ for (i = 0; i < (dstW >> 1); i++) {
+ int Y1 = (buf0[i * 2] ) >> 2;
+ int Y2 = (buf0[i * 2 + 1]) >> 2;
+ int U = (ubuf0[i] + (-128 << 11)) >> 2;
+ int V = (vbuf0[i] + (-128 << 11)) >> 2;
+ int R, G, B;
+
+ Y1 -= c->yuv2rgb_y_offset;
+ Y2 -= c->yuv2rgb_y_offset;
+ Y1 *= c->yuv2rgb_y_coeff;
+ Y2 *= c->yuv2rgb_y_coeff;
+ Y1 += 1 << 13;
+ Y2 += 1 << 13;
+
+ R = V * c->yuv2rgb_v2r_coeff;
+ G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+ B = U * c->yuv2rgb_u2b_coeff;
+
+ output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
+ output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
+ output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
+ output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
+ output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14);
+ output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ dest += 6;
+ }
+ } else {
+ for (i = 0; i < (dstW >> 1); i++) {
+ int Y1 = (buf0[i * 2] ) >> 2;
+ int Y2 = (buf0[i * 2 + 1]) >> 2;
+ int U = (ubuf0[i] + ubuf1[i] + (-128 << 11)) >> 3;
+ int V = (vbuf0[i] + vbuf1[i] + (-128 << 11)) >> 3;
+ int R, G, B;
+
+ Y1 -= c->yuv2rgb_y_offset;
+ Y2 -= c->yuv2rgb_y_offset;
+ Y1 *= c->yuv2rgb_y_coeff;
+ Y2 *= c->yuv2rgb_y_coeff;
+ Y1 += 1 << 13;
+ Y2 += 1 << 13;
+
+ R = V * c->yuv2rgb_v2r_coeff;
+ G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+ B = U * c->yuv2rgb_u2b_coeff;
+
+ output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
+ output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
+ output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
+ output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
+ output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14);
+ output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
+ dest += 6;
+ }
+ }
+}
+
+#undef output_pixel
+#undef r_b
+#undef b_r
+
+YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48be, PIX_FMT_RGB48BE)
+YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, PIX_FMT_RGB48LE)
+YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, PIX_FMT_BGR48BE)
+YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, PIX_FMT_BGR48LE)
+
+static av_always_inline void
+yuv2rgb_write(uint8_t *_dest, int i, unsigned Y1, unsigned Y2,
+ unsigned U, unsigned V, unsigned A1, unsigned A2,
+ const void *_r, const void *_g, const void *_b, int y,
+ enum PixelFormat target, int hasAlpha)
+{
+ if (target == PIX_FMT_ARGB || target == PIX_FMT_RGBA ||
+ target == PIX_FMT_ABGR || target == PIX_FMT_BGRA) {
+ uint32_t *dest = (uint32_t *) _dest;
+ const uint32_t *r = (const uint32_t *) _r;
+ const uint32_t *g = (const uint32_t *) _g;
+ const uint32_t *b = (const uint32_t *) _b;
+
+#if CONFIG_SMALL
+ int sh = hasAlpha ? ((target == PIX_FMT_RGB32_1 || target == PIX_FMT_BGR32_1) ? 0 : 24) : 0;
+
+ dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (hasAlpha ? A1 << sh : 0);
+ dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (hasAlpha ? A2 << sh : 0);
+#else
+ if (hasAlpha) {
+ int sh = (target == PIX_FMT_RGB32_1 || target == PIX_FMT_BGR32_1) ? 0 : 24;
+
+ dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (A1 << sh);
+ dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (A2 << sh);
+ } else {
+ dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1];
+ dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2];
+ }
+#endif
+ } else if (target == PIX_FMT_RGB24 || target == PIX_FMT_BGR24) {
+ uint8_t *dest = (uint8_t *) _dest;
+ const uint8_t *r = (const uint8_t *) _r;
+ const uint8_t *g = (const uint8_t *) _g;
+ const uint8_t *b = (const uint8_t *) _b;
+
+#define r_b ((target == PIX_FMT_RGB24) ? r : b)
+#define b_r ((target == PIX_FMT_RGB24) ? b : r)
+ dest[i * 6 + 0] = r_b[Y1];
+ dest[i * 6 + 1] = g[Y1];
+ dest[i * 6 + 2] = b_r[Y1];
+ dest[i * 6 + 3] = r_b[Y2];
+ dest[i * 6 + 4] = g[Y2];
+ dest[i * 6 + 5] = b_r[Y2];
+#undef r_b
+#undef b_r
+ } else if (target == PIX_FMT_RGB565 || target == PIX_FMT_BGR565 ||
+ target == PIX_FMT_RGB555 || target == PIX_FMT_BGR555 ||
+ target == PIX_FMT_RGB444 || target == PIX_FMT_BGR444) {
+ uint16_t *dest = (uint16_t *) _dest;
+ const uint16_t *r = (const uint16_t *) _r;
+ const uint16_t *g = (const uint16_t *) _g;
+ const uint16_t *b = (const uint16_t *) _b;
+ int dr1, dg1, db1, dr2, dg2, db2;
+
+ if (target == PIX_FMT_RGB565 || target == PIX_FMT_BGR565) {
+ dr1 = dither_2x2_8[ y & 1 ][0];
+ dg1 = dither_2x2_4[ y & 1 ][0];
+ db1 = dither_2x2_8[(y & 1) ^ 1][0];
+ dr2 = dither_2x2_8[ y & 1 ][1];
+ dg2 = dither_2x2_4[ y & 1 ][1];
+ db2 = dither_2x2_8[(y & 1) ^ 1][1];
+ } else if (target == PIX_FMT_RGB555 || target == PIX_FMT_BGR555) {
+ dr1 = dither_2x2_8[ y & 1 ][0];
+ dg1 = dither_2x2_8[ y & 1 ][1];
+ db1 = dither_2x2_8[(y & 1) ^ 1][0];
+ dr2 = dither_2x2_8[ y & 1 ][1];
+ dg2 = dither_2x2_8[ y & 1 ][0];
+ db2 = dither_2x2_8[(y & 1) ^ 1][1];
+ } else {
+ dr1 = dither_4x4_16[ y & 3 ][0];
+ dg1 = dither_4x4_16[ y & 3 ][1];
+ db1 = dither_4x4_16[(y & 3) ^ 3][0];
+ dr2 = dither_4x4_16[ y & 3 ][1];
+ dg2 = dither_4x4_16[ y & 3 ][0];
+ db2 = dither_4x4_16[(y & 3) ^ 3][1];
+ }
+
+ dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
+ dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
+ } else /* 8/4-bit */ {
+ uint8_t *dest = (uint8_t *) _dest;
+ const uint8_t *r = (const uint8_t *) _r;
+ const uint8_t *g = (const uint8_t *) _g;
+ const uint8_t *b = (const uint8_t *) _b;
+ int dr1, dg1, db1, dr2, dg2, db2;
+
+ if (target == PIX_FMT_RGB8 || target == PIX_FMT_BGR8) {
+ const uint8_t * const d64 = dither_8x8_73[y & 7];
+ const uint8_t * const d32 = dither_8x8_32[y & 7];
+ dr1 = dg1 = d32[(i * 2 + 0) & 7];
+ db1 = d64[(i * 2 + 0) & 7];
+ dr2 = dg2 = d32[(i * 2 + 1) & 7];
+ db2 = d64[(i * 2 + 1) & 7];
+ } else {
+ const uint8_t * const d64 = dither_8x8_73 [y & 7];
+ const uint8_t * const d128 = dither_8x8_220[y & 7];
+ dr1 = db1 = d128[(i * 2 + 0) & 7];
+ dg1 = d64[(i * 2 + 0) & 7];
+ dr2 = db2 = d128[(i * 2 + 1) & 7];
+ dg2 = d64[(i * 2 + 1) & 7];
+ }
+
+ if (target == PIX_FMT_RGB4 || target == PIX_FMT_BGR4) {
+ dest[i] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1] +
+ ((r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]) << 4);
+ } else {
+ dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
+ dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
+ }
+ }
+}
+
+static av_always_inline void
+yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter,
+ const int16_t **lumSrc, int lumFilterSize,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc, int chrFilterSize,
+ const int16_t **alpSrc, uint8_t *dest, int dstW,
+ int y, enum PixelFormat target, int hasAlpha)
+{
+ int i;
+
+ for (i = 0; i < (dstW >> 1); i++) {
+ int j;
int Y1 = 1 << 18;
int Y2 = 1 << 18;
int U = 1 << 18;
int V = 1 << 18;
- const uint8_t *r, *g, *b;
+ int av_unused A1, A2;
+ const void *r, *g, *b;
for (j = 0; j < lumFilterSize; j++) {
Y1 += lumSrc[j][i * 2] * lumFilter[j];
@@ -780,31 +1066,43 @@ yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
U = av_clip_uint8(U);
V = av_clip_uint8(V);
}
+ if (hasAlpha) {
+ A1 = 1 << 18;
+ A2 = 1 << 18;
+ for (j = 0; j < lumFilterSize; j++) {
+ A1 += alpSrc[j][i * 2 ] * lumFilter[j];
+ A2 += alpSrc[j][i * 2 + 1] * lumFilter[j];
+ }
+ A1 >>= 19;
+ A2 >>= 19;
+ if ((A1 | A2) & 0x100) {
+ A1 = av_clip_uint8(A1);
+ A2 = av_clip_uint8(A2);
+ }
+ }
/* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/
- r = (const uint8_t *) c->table_rV[V];
- g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]);
- b = (const uint8_t *) c->table_bU[U];
+ r = c->table_rV[V];
+ g = (c->table_gU[U] + c->table_gV[V]);
+ b = c->table_bU[U];
- dest[ 0] = dest[ 1] = r_b[Y1];
- dest[ 2] = dest[ 3] = g[Y1];
- dest[ 4] = dest[ 5] = b_r[Y1];
- dest[ 6] = dest[ 7] = r_b[Y2];
- dest[ 8] = dest[ 9] = g[Y2];
- dest[10] = dest[11] = b_r[Y2];
- dest += 12;
+ yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+ r, g, b, y, target, hasAlpha);
}
}
static av_always_inline void
-yuv2rgb48_2_c_template(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *ubuf0,
- const uint16_t *ubuf1, const uint16_t *vbuf0,
- const uint16_t *vbuf1, const uint16_t *abuf0,
- const uint16_t *abuf1, uint8_t *dest, int dstW,
- int yalpha, int uvalpha, int y,
- enum PixelFormat target)
+yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf[2], uint8_t *dest, int dstW,
+ int yalpha, int uvalpha, int y,
+ enum PixelFormat target, int hasAlpha)
{
+ const int16_t *buf0 = buf[0], *buf1 = buf[1],
+ *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
+ *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
+ *abuf0 = hasAlpha ? abuf[0] : NULL,
+ *abuf1 = hasAlpha ? abuf[1] : NULL;
int yalpha1 = 4095 - yalpha;
int uvalpha1 = 4095 - uvalpha;
int i;
@@ -814,28 +1112,30 @@ yuv2rgb48_2_c_template(SwsContext *c, const uint16_t *buf0,
int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19;
int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
- const uint8_t *r = (const uint8_t *) c->table_rV[V],
- *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
- *b = (const uint8_t *) c->table_bU[U];
+ int A1, A2;
+ const void *r = c->table_rV[V],
+ *g = (c->table_gU[U] + c->table_gV[V]),
+ *b = c->table_bU[U];
+
+ if (hasAlpha) {
+ A1 = (abuf0[i * 2 ] * yalpha1 + abuf1[i * 2 ] * yalpha) >> 19;
+ A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19;
+ }
- dest[ 0] = dest[ 1] = r_b[Y1];
- dest[ 2] = dest[ 3] = g[Y1];
- dest[ 4] = dest[ 5] = b_r[Y1];
- dest[ 6] = dest[ 7] = r_b[Y2];
- dest[ 8] = dest[ 9] = g[Y2];
- dest[10] = dest[11] = b_r[Y2];
- dest += 12;
+ yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+ r, g, b, y, target, hasAlpha);
}
}
static av_always_inline void
-yuv2rgb48_1_c_template(SwsContext *c, const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, uint8_t *dest, int dstW,
- int uvalpha, enum PixelFormat dstFormat,
- int flags, int y, enum PixelFormat target)
+yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0,
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf0, uint8_t *dest, int dstW,
+ int uvalpha, int y, enum PixelFormat target,
+ int hasAlpha)
{
+ const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
+ *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
int i;
if (uvalpha < 2048) {
@@ -844,17 +1144,18 @@ yuv2rgb48_1_c_template(SwsContext *c, const uint16_t *buf0,
int Y2 = buf0[i * 2 + 1] >> 7;
int U = ubuf1[i] >> 7;
int V = vbuf1[i] >> 7;
- const uint8_t *r = (const uint8_t *) c->table_rV[V],
- *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
- *b = (const uint8_t *) c->table_bU[U];
-
- dest[ 0] = dest[ 1] = r_b[Y1];
- dest[ 2] = dest[ 3] = g[Y1];
- dest[ 4] = dest[ 5] = b_r[Y1];
- dest[ 6] = dest[ 7] = r_b[Y2];
- dest[ 8] = dest[ 9] = g[Y2];
- dest[10] = dest[11] = b_r[Y2];
- dest += 12;
+ int A1, A2;
+ const void *r = c->table_rV[V],
+ *g = (c->table_gU[U] + c->table_gV[V]),
+ *b = c->table_bU[U];
+
+ if (hasAlpha) {
+ A1 = abuf0[i * 2 ] >> 7;
+ A2 = abuf0[i * 2 + 1] >> 7;
+ }
+
+ yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+ r, g, b, y, target, hasAlpha);
}
} else {
for (i = 0; i < (dstW >> 1); i++) {
@@ -862,447 +1163,185 @@ yuv2rgb48_1_c_template(SwsContext *c, const uint16_t *buf0,
int Y2 = buf0[i * 2 + 1] >> 7;
int U = (ubuf0[i] + ubuf1[i]) >> 8;
int V = (vbuf0[i] + vbuf1[i]) >> 8;
- const uint8_t *r = (const uint8_t *) c->table_rV[V],
- *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
- *b = (const uint8_t *) c->table_bU[U];
-
- dest[ 0] = dest[ 1] = r_b[Y1];
- dest[ 2] = dest[ 3] = g[Y1];
- dest[ 4] = dest[ 5] = b_r[Y1];
- dest[ 6] = dest[ 7] = r_b[Y2];
- dest[ 8] = dest[ 9] = g[Y2];
- dest[10] = dest[11] = b_r[Y2];
- dest += 12;
+ int A1, A2;
+ const void *r = c->table_rV[V],
+ *g = (c->table_gU[U] + c->table_gV[V]),
+ *b = c->table_bU[U];
+
+ if (hasAlpha) {
+ A1 = abuf0[i * 2 ] >> 7;
+ A2 = abuf0[i * 2 + 1] >> 7;
+ }
+
+ yuv2rgb_write(dest, i, Y1, Y2, U, V, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
+ r, g, b, y, target, hasAlpha);
}
}
}
-#undef r_b
-#undef b_r
+#define YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
+static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
+ const int16_t **lumSrc, int lumFilterSize, \
+ const int16_t *chrFilter, const int16_t **chrUSrc, \
+ const int16_t **chrVSrc, int chrFilterSize, \
+ const int16_t **alpSrc, uint8_t *dest, int dstW, \
+ int y) \
+{ \
+ name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
+ chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
+ alpSrc, dest, dstW, y, fmt, hasAlpha); \
+}
+#define YUV2RGBWRAPPER(name, base, ext, fmt, hasAlpha) \
+YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
+static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
+ const int16_t *ubuf[2], const int16_t *vbuf[2], \
+ const int16_t *abuf[2], uint8_t *dest, int dstW, \
+ int yalpha, int uvalpha, int y) \
+{ \
+ name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
+ dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
+} \
+ \
+static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
+ const int16_t *ubuf[2], const int16_t *vbuf[2], \
+ const int16_t *abuf0, uint8_t *dest, int dstW, \
+ int uvalpha, int y) \
+{ \
+ name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
+ dstW, uvalpha, y, fmt, hasAlpha); \
+}
-YUV2PACKEDWRAPPER(yuv2, rgb48, rgb48be, PIX_FMT_RGB48BE);
-//YUV2PACKEDWRAPPER(yuv2, rgb48, rgb48le, PIX_FMT_RGB48LE);
-YUV2PACKEDWRAPPER(yuv2, rgb48, bgr48be, PIX_FMT_BGR48BE);
-//YUV2PACKEDWRAPPER(yuv2, rgb48, bgr48le, PIX_FMT_BGR48LE);
-
-#define YSCALE_YUV_2_RGBX_C(type,alpha) \
- for (i=0; i<(dstW>>1); i++) {\
- int j;\
- int Y1 = 1<<18;\
- int Y2 = 1<<18;\
- int U = 1<<18;\
- int V = 1<<18;\
- int av_unused A1, A2;\
- type av_unused *r, *b, *g;\
- const int i2= 2*i;\
- \
- for (j=0; j<lumFilterSize; j++) {\
- Y1 += lumSrc[j][i2] * lumFilter[j];\
- Y2 += lumSrc[j][i2+1] * lumFilter[j];\
- }\
- for (j=0; j<chrFilterSize; j++) {\
- U += chrUSrc[j][i] * chrFilter[j];\
- V += chrVSrc[j][i] * chrFilter[j];\
- }\
- Y1>>=19;\
- Y2>>=19;\
- U >>=19;\
- V >>=19;\
- if ((Y1|Y2|U|V)&0x100) {\
- Y1 = av_clip_uint8(Y1); \
- Y2 = av_clip_uint8(Y2); \
- U = av_clip_uint8(U); \
- V = av_clip_uint8(V); \
- }\
- if (alpha) {\
- A1 = 1<<18;\
- A2 = 1<<18;\
- for (j=0; j<lumFilterSize; j++) {\
- A1 += alpSrc[j][i2 ] * lumFilter[j];\
- A2 += alpSrc[j][i2+1] * lumFilter[j];\
- }\
- A1>>=19;\
- A2>>=19;\
- if ((A1|A2)&0x100) {\
- A1 = av_clip_uint8(A1); \
- A2 = av_clip_uint8(A2); \
- }\
- }\
- /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/\
- r = (type *)c->table_rV[V]; \
- g = (type *)(c->table_gU[U] + c->table_gV[V]); \
- b = (type *)c->table_bU[U];
-
-#define YSCALE_YUV_2_RGBX_FULL_C(rnd,alpha) \
- for (i=0; i<dstW; i++) {\
- int j;\
- int Y = 0;\
- int U = -128<<19;\
- int V = -128<<19;\
- int av_unused A;\
- int R,G,B;\
- \
- for (j=0; j<lumFilterSize; j++) {\
- Y += lumSrc[j][i ] * lumFilter[j];\
- }\
- for (j=0; j<chrFilterSize; j++) {\
- U += chrUSrc[j][i] * chrFilter[j];\
- V += chrVSrc[j][i] * chrFilter[j];\
- }\
- Y >>=10;\
- U >>=10;\
- V >>=10;\
- if (alpha) {\
- A = rnd;\
- for (j=0; j<lumFilterSize; j++)\
- A += alpSrc[j][i ] * lumFilter[j];\
- A >>=19;\
- if (A&0x100)\
- A = av_clip_uint8(A);\
- }\
- Y-= c->yuv2rgb_y_offset;\
- Y*= c->yuv2rgb_y_coeff;\
- Y+= rnd;\
- R= Y + V*c->yuv2rgb_v2r_coeff;\
- G= Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;\
- B= Y + U*c->yuv2rgb_u2b_coeff;\
- if ((R|G|B)&(0xC0000000)) {\
- R = av_clip_uintp2(R, 30); \
- G = av_clip_uintp2(G, 30); \
- B = av_clip_uintp2(B, 30); \
- }
+#if CONFIG_SMALL
+YUV2RGBWRAPPER(yuv2rgb,, 32_1, PIX_FMT_RGB32_1, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
+YUV2RGBWRAPPER(yuv2rgb,, 32, PIX_FMT_RGB32, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
+#else
+#if CONFIG_SWSCALE_ALPHA
+YUV2RGBWRAPPER(yuv2rgb,, a32_1, PIX_FMT_RGB32_1, 1)
+YUV2RGBWRAPPER(yuv2rgb,, a32, PIX_FMT_RGB32, 1)
+#endif
+YUV2RGBWRAPPER(yuv2rgb,, x32_1, PIX_FMT_RGB32_1, 0)
+YUV2RGBWRAPPER(yuv2rgb,, x32, PIX_FMT_RGB32, 0)
+#endif
+YUV2RGBWRAPPER(yuv2, rgb, rgb24, PIX_FMT_RGB24, 0)
+YUV2RGBWRAPPER(yuv2, rgb, bgr24, PIX_FMT_BGR24, 0)
+YUV2RGBWRAPPER(yuv2rgb,, 16, PIX_FMT_RGB565, 0)
+YUV2RGBWRAPPER(yuv2rgb,, 15, PIX_FMT_RGB555, 0)
+YUV2RGBWRAPPER(yuv2rgb,, 12, PIX_FMT_RGB444, 0)
+YUV2RGBWRAPPER(yuv2rgb,, 8, PIX_FMT_RGB8, 0)
+YUV2RGBWRAPPER(yuv2rgb,, 4, PIX_FMT_RGB4, 0)
+YUV2RGBWRAPPER(yuv2rgb,, 4b, PIX_FMT_RGB4_BYTE, 0)
-#define YSCALE_YUV_2_RGB2_C(type,alpha) \
- for (i=0; i<(dstW>>1); i++) { \
- const int i2= 2*i; \
- int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>19; \
- int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>19; \
- int U= (ubuf0[i]*uvalpha1+ubuf1[i]*uvalpha)>>19; \
- int V= (vbuf0[i]*uvalpha1+vbuf1[i]*uvalpha)>>19; \
- type av_unused *r, *b, *g; \
- int av_unused A1, A2; \
- if (alpha) {\
- A1= (abuf0[i2 ]*yalpha1+abuf1[i2 ]*yalpha)>>19; \
- A2= (abuf0[i2+1]*yalpha1+abuf1[i2+1]*yalpha)>>19; \
- }\
- r = (type *)c->table_rV[V];\
- g = (type *)(c->table_gU[U] + c->table_gV[V]);\
- b = (type *)c->table_bU[U];
-
-#define YSCALE_YUV_2_RGB1_C(type,alpha) \
- for (i=0; i<(dstW>>1); i++) {\
- const int i2= 2*i;\
- int Y1= buf0[i2 ]>>7;\
- int Y2= buf0[i2+1]>>7;\
- int U= (ubuf1[i])>>7;\
- int V= (vbuf1[i])>>7;\
- type av_unused *r, *b, *g;\
- int av_unused A1, A2;\
- if (alpha) {\
- A1= abuf0[i2 ]>>7;\
- A2= abuf0[i2+1]>>7;\
- }\
- r = (type *)c->table_rV[V];\
- g = (type *)(c->table_gU[U] + c->table_gV[V]);\
- b = (type *)c->table_bU[U];
-
-#define YSCALE_YUV_2_RGB1B_C(type,alpha) \
- for (i=0; i<(dstW>>1); i++) {\
- const int i2= 2*i;\
- int Y1= buf0[i2 ]>>7;\
- int Y2= buf0[i2+1]>>7;\
- int U= (ubuf0[i] + ubuf1[i])>>8;\
- int V= (vbuf0[i] + vbuf1[i])>>8;\
- type av_unused *r, *b, *g;\
- int av_unused A1, A2;\
- if (alpha) {\
- A1= abuf0[i2 ]>>7;\
- A2= abuf0[i2+1]>>7;\
- }\
- r = (type *)c->table_rV[V];\
- g = (type *)(c->table_gU[U] + c->table_gV[V]);\
- b = (type *)c->table_bU[U];
-
-#define YSCALE_YUV_2_ANYRGB_C(func)\
- switch(c->dstFormat) {\
- case PIX_FMT_RGBA:\
- case PIX_FMT_BGRA:\
- if (CONFIG_SMALL) {\
- int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
- func(uint32_t,needAlpha)\
- ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? (A1<<24) : 0);\
- ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? (A2<<24) : 0);\
- }\
- } else {\
- if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
- func(uint32_t,1)\
- ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (A1<<24);\
- ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (A2<<24);\
- }\
- } else {\
- func(uint32_t,0)\
- ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
- ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
- }\
- }\
- }\
- break;\
- case PIX_FMT_ARGB:\
- case PIX_FMT_ABGR:\
- if (CONFIG_SMALL) {\
- int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
- func(uint32_t,needAlpha)\
- ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? A1 : 0);\
- ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? A2 : 0);\
- }\
- } else {\
- if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
- func(uint32_t,1)\
- ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + A1;\
- ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + A2;\
- }\
- } else {\
- func(uint32_t,0)\
- ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
- ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
- }\
- }\
- } \
- break;\
- case PIX_FMT_RGB24:\
- func(uint8_t,0)\
- ((uint8_t*)dest)[0]= r[Y1];\
- ((uint8_t*)dest)[1]= g[Y1];\
- ((uint8_t*)dest)[2]= b[Y1];\
- ((uint8_t*)dest)[3]= r[Y2];\
- ((uint8_t*)dest)[4]= g[Y2];\
- ((uint8_t*)dest)[5]= b[Y2];\
- dest+=6;\
- }\
- break;\
- case PIX_FMT_BGR24:\
- func(uint8_t,0)\
- ((uint8_t*)dest)[0]= b[Y1];\
- ((uint8_t*)dest)[1]= g[Y1];\
- ((uint8_t*)dest)[2]= r[Y1];\
- ((uint8_t*)dest)[3]= b[Y2];\
- ((uint8_t*)dest)[4]= g[Y2];\
- ((uint8_t*)dest)[5]= r[Y2];\
- dest+=6;\
- }\
- break;\
- case PIX_FMT_RGB565:\
- case PIX_FMT_BGR565:\
- {\
- const int dr1= dither_2x2_8[y&1 ][0];\
- const int dg1= dither_2x2_4[y&1 ][0];\
- const int db1= dither_2x2_8[(y&1)^1][0];\
- const int dr2= dither_2x2_8[y&1 ][1];\
- const int dg2= dither_2x2_4[y&1 ][1];\
- const int db2= dither_2x2_8[(y&1)^1][1];\
- func(uint16_t,0)\
- ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
- ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
- }\
- }\
- break;\
- case PIX_FMT_RGB555:\
- case PIX_FMT_BGR555:\
- {\
- const int dr1= dither_2x2_8[y&1 ][0];\
- const int dg1= dither_2x2_8[y&1 ][1];\
- const int db1= dither_2x2_8[(y&1)^1][0];\
- const int dr2= dither_2x2_8[y&1 ][1];\
- const int dg2= dither_2x2_8[y&1 ][0];\
- const int db2= dither_2x2_8[(y&1)^1][1];\
- func(uint16_t,0)\
- ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
- ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
- }\
- }\
- break;\
- case PIX_FMT_RGB444:\
- case PIX_FMT_BGR444:\
- {\
- const int dr1= dither_4x4_16[y&3 ][0];\
- const int dg1= dither_4x4_16[y&3 ][1];\
- const int db1= dither_4x4_16[(y&3)^3][0];\
- const int dr2= dither_4x4_16[y&3 ][1];\
- const int dg2= dither_4x4_16[y&3 ][0];\
- const int db2= dither_4x4_16[(y&3)^3][1];\
- func(uint16_t,0)\
- ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
- ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
- }\
- }\
- break;\
- case PIX_FMT_RGB8:\
- case PIX_FMT_BGR8:\
- {\
- const uint8_t * const d64= dither_8x8_73[y&7];\
- const uint8_t * const d32= dither_8x8_32[y&7];\
- func(uint8_t,0)\
- ((uint8_t*)dest)[i2+0]= r[Y1+d32[(i2+0)&7]] + g[Y1+d32[(i2+0)&7]] + b[Y1+d64[(i2+0)&7]];\
- ((uint8_t*)dest)[i2+1]= r[Y2+d32[(i2+1)&7]] + g[Y2+d32[(i2+1)&7]] + b[Y2+d64[(i2+1)&7]];\
- }\
- }\
- break;\
- case PIX_FMT_RGB4:\
- case PIX_FMT_BGR4:\
- {\
- const uint8_t * const d64= dither_8x8_73 [y&7];\
- const uint8_t * const d128=dither_8x8_220[y&7];\
- func(uint8_t,0)\
- ((uint8_t*)dest)[i]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]]\
- + ((r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]])<<4);\
- }\
- }\
- break;\
- case PIX_FMT_RGB4_BYTE:\
- case PIX_FMT_BGR4_BYTE:\
- {\
- const uint8_t * const d64= dither_8x8_73 [y&7];\
- const uint8_t * const d128=dither_8x8_220[y&7];\
- func(uint8_t,0)\
- ((uint8_t*)dest)[i2+0]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]];\
- ((uint8_t*)dest)[i2+1]= r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]];\
- }\
- }\
- break;\
- }
-
-static void yuv2packedX_c(SwsContext *c, const int16_t *lumFilter,
+static av_always_inline void
+yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
- const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
+ const int16_t **alpSrc, uint8_t *dest,
+ int dstW, int y, enum PixelFormat target, int hasAlpha)
{
int i;
- YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C)
-}
+ int step = (target == PIX_FMT_RGB24 || target == PIX_FMT_BGR24) ? 3 : 4;
-static void yuv2rgbX_c_full(SwsContext *c, const int16_t *lumFilter,
- const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrUSrc,
- const int16_t **chrVSrc, int chrFilterSize,
- const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
-{
- int i;
- int step= c->dstFormatBpp/8;
- int aidx= 3;
+ for (i = 0; i < dstW; i++) {
+ int j;
+ int Y = 0;
+ int U = -128 << 19;
+ int V = -128 << 19;
+ int av_unused A;
+ int R, G, B;
- switch(c->dstFormat) {
- case PIX_FMT_ARGB:
- dest++;
- aidx= 0;
- case PIX_FMT_RGB24:
- aidx--;
- case PIX_FMT_RGBA:
- if (CONFIG_SMALL) {
- int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
- YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
- dest[aidx]= needAlpha ? A : 255;
- dest[0]= R>>22;
- dest[1]= G>>22;
- dest[2]= B>>22;
- dest+= step;
- }
- } else {
- if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
- YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
- dest[aidx]= A;
- dest[0]= R>>22;
- dest[1]= G>>22;
- dest[2]= B>>22;
- dest+= step;
- }
- } else {
- YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
- dest[aidx]= 255;
- dest[0]= R>>22;
- dest[1]= G>>22;
- dest[2]= B>>22;
- dest+= step;
- }
- }
+ for (j = 0; j < lumFilterSize; j++) {
+ Y += lumSrc[j][i] * lumFilter[j];
}
- break;
- case PIX_FMT_ABGR:
- dest++;
- aidx= 0;
- case PIX_FMT_BGR24:
- aidx--;
- case PIX_FMT_BGRA:
- if (CONFIG_SMALL) {
- int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
- YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
- dest[aidx]= needAlpha ? A : 255;
- dest[0]= B>>22;
- dest[1]= G>>22;
- dest[2]= R>>22;
- dest+= step;
- }
- } else {
- if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
- YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
- dest[aidx]= A;
- dest[0]= B>>22;
- dest[1]= G>>22;
- dest[2]= R>>22;
- dest+= step;
- }
- } else {
- YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
- dest[aidx]= 255;
- dest[0]= B>>22;
- dest[1]= G>>22;
- dest[2]= R>>22;
- dest+= step;
- }
+ for (j = 0; j < chrFilterSize; j++) {
+ U += chrUSrc[j][i] * chrFilter[j];
+ V += chrVSrc[j][i] * chrFilter[j];
+ }
+ Y >>= 10;
+ U >>= 10;
+ V >>= 10;
+ if (hasAlpha) {
+ A = 1 << 21;
+ for (j = 0; j < lumFilterSize; j++) {
+ A += alpSrc[j][i] * lumFilter[j];
}
+ A >>= 19;
+ if (A & 0x100)
+ A = av_clip_uint8(A);
+ }
+ Y -= c->yuv2rgb_y_offset;
+ Y *= c->yuv2rgb_y_coeff;
+ Y += 1 << 21;
+ R = Y + V*c->yuv2rgb_v2r_coeff;
+ G = Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;
+ B = Y + U*c->yuv2rgb_u2b_coeff;
+ if ((R | G | B) & 0xC0000000) {
+ R = av_clip_uintp2(R, 30);
+ G = av_clip_uintp2(G, 30);
+ B = av_clip_uintp2(B, 30);
}
- break;
- default:
- assert(0);
- }
-}
-
-/**
- * vertical bilinear scale YV12 to RGB
- */
-static void yuv2packed2_c(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *ubuf0,
- const uint16_t *ubuf1, const uint16_t *vbuf0,
- const uint16_t *vbuf1, const uint16_t *abuf0,
- const uint16_t *abuf1, uint8_t *dest, int dstW,
- int yalpha, int uvalpha, int y)
-{
- int yalpha1=4095- yalpha;
- int uvalpha1=4095-uvalpha;
- int i;
-
- YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C)
-}
-
-/**
- * YV12 to RGB without scaling or interpolating
- */
-static void yuv2packed1_c(SwsContext *c, const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, uint8_t *dest, int dstW,
- int uvalpha, enum PixelFormat dstFormat,
- int flags, int y)
-{
- int i;
- if (uvalpha < 2048) {
- YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C)
- } else {
- YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C)
+ switch(target) {
+ case PIX_FMT_ARGB:
+ dest[0] = hasAlpha ? A : 255;
+ dest[1] = R >> 22;
+ dest[2] = G >> 22;
+ dest[3] = B >> 22;
+ break;
+ case PIX_FMT_RGB24:
+ dest[0] = R >> 22;
+ dest[1] = G >> 22;
+ dest[2] = B >> 22;
+ break;
+ case PIX_FMT_RGBA:
+ dest[0] = R >> 22;
+ dest[1] = G >> 22;
+ dest[2] = B >> 22;
+ dest[3] = hasAlpha ? A : 255;
+ break;
+ case PIX_FMT_ABGR:
+ dest[0] = hasAlpha ? A : 255;
+ dest[1] = B >> 22;
+ dest[2] = G >> 22;
+ dest[3] = R >> 22;
+ dest += 4;
+ break;
+ case PIX_FMT_BGR24:
+ dest[0] = B >> 22;
+ dest[1] = G >> 22;
+ dest[2] = R >> 22;
+ break;
+ case PIX_FMT_BGRA:
+ dest[0] = B >> 22;
+ dest[1] = G >> 22;
+ dest[2] = R >> 22;
+ dest[3] = hasAlpha ? A : 255;
+ break;
+ }
+ dest += step;
}
}
+#if CONFIG_SMALL
+YUV2RGBWRAPPERX(yuv2, rgb_full, bgra32_full, PIX_FMT_BGRA, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
+YUV2RGBWRAPPERX(yuv2, rgb_full, abgr32_full, PIX_FMT_ABGR, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
+YUV2RGBWRAPPERX(yuv2, rgb_full, rgba32_full, PIX_FMT_RGBA, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
+YUV2RGBWRAPPERX(yuv2, rgb_full, argb32_full, PIX_FMT_ARGB, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
+#else
+#if CONFIG_SWSCALE_ALPHA
+YUV2RGBWRAPPERX(yuv2, rgb_full, bgra32_full, PIX_FMT_BGRA, 1)
+YUV2RGBWRAPPERX(yuv2, rgb_full, abgr32_full, PIX_FMT_ABGR, 1)
+YUV2RGBWRAPPERX(yuv2, rgb_full, rgba32_full, PIX_FMT_RGBA, 1)
+YUV2RGBWRAPPERX(yuv2, rgb_full, argb32_full, PIX_FMT_ARGB, 1)
+#endif
+YUV2RGBWRAPPERX(yuv2, rgb_full, bgrx32_full, PIX_FMT_BGRA, 0)
+YUV2RGBWRAPPERX(yuv2, rgb_full, xbgr32_full, PIX_FMT_ABGR, 0)
+YUV2RGBWRAPPERX(yuv2, rgb_full, rgbx32_full, PIX_FMT_RGBA, 0)
+YUV2RGBWRAPPERX(yuv2, rgb_full, xrgb32_full, PIX_FMT_ARGB, 0)
+#endif
+YUV2RGBWRAPPERX(yuv2, rgb_full, bgr24_full, PIX_FMT_BGR24, 0)
+YUV2RGBWRAPPERX(yuv2, rgb_full, rgb24_full, PIX_FMT_RGB24, 0)
+
static av_always_inline void fillPlane(uint8_t* plane, int stride,
int width, int height,
int y, uint8_t val)
@@ -1321,50 +1360,50 @@ static av_always_inline void fillPlane(uint8_t* plane, int stride,
#define b ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? r_b : b_r)
static av_always_inline void
-rgb48ToY_c_template(uint8_t *dst, const uint8_t *src, int width,
+rgb48ToY_c_template(uint16_t *dst, const uint16_t *src, int width,
enum PixelFormat origin)
{
int i;
for (i = 0; i < width; i++) {
- int r_b = input_pixel(&src[i*6+0]) >> 8;
- int g = input_pixel(&src[i*6+2]) >> 8;
- int b_r = input_pixel(&src[i*6+4]) >> 8;
+ unsigned int r_b = input_pixel(&src[i*3+0]);
+ unsigned int g = input_pixel(&src[i*3+1]);
+ unsigned int b_r = input_pixel(&src[i*3+2]);
- dst[i] = (RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
+ dst[i] = (RY*r + GY*g + BY*b + (0x2001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
}
}
static av_always_inline void
-rgb48ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
- const uint8_t *src1, const uint8_t *src2,
+rgb48ToUV_c_template(uint16_t *dstU, uint16_t *dstV,
+ const uint16_t *src1, const uint16_t *src2,
int width, enum PixelFormat origin)
{
int i;
assert(src1==src2);
for (i = 0; i < width; i++) {
- int r_b = input_pixel(&src1[i*6+0]) >> 8;
- int g = input_pixel(&src1[i*6+2]) >> 8;
- int b_r = input_pixel(&src1[i*6+4]) >> 8;
+ int r_b = input_pixel(&src1[i*3+0]);
+ int g = input_pixel(&src1[i*3+1]);
+ int b_r = input_pixel(&src1[i*3+2]);
- dstU[i] = (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
- dstV[i] = (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
+ dstU[i] = (RU*r + GU*g + BU*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
+ dstV[i] = (RV*r + GV*g + BV*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
}
}
static av_always_inline void
-rgb48ToUV_half_c_template(uint8_t *dstU, uint8_t *dstV,
- const uint8_t *src1, const uint8_t *src2,
+rgb48ToUV_half_c_template(uint16_t *dstU, uint16_t *dstV,
+ const uint16_t *src1, const uint16_t *src2,
int width, enum PixelFormat origin)
{
int i;
assert(src1==src2);
for (i = 0; i < width; i++) {
- int r_b = (input_pixel(&src1[12*i + 0]) >> 8) + (input_pixel(&src1[12*i + 6]) >> 8);
- int g = (input_pixel(&src1[12*i + 2]) >> 8) + (input_pixel(&src1[12*i + 8]) >> 8);
- int b_r = (input_pixel(&src1[12*i + 4]) >> 8) + (input_pixel(&src1[12*i + 10]) >> 8);
+ int r_b = (input_pixel(&src1[6 * i + 0]) + input_pixel(&src1[6 * i + 3]) + 1) >> 1;
+ int g = (input_pixel(&src1[6 * i + 1]) + input_pixel(&src1[6 * i + 4]) + 1) >> 1;
+ int b_r = (input_pixel(&src1[6 * i + 2]) + input_pixel(&src1[6 * i + 5]) + 1) >> 1;
- dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
- dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
+ dstU[i]= (RU*r + GU*g + BU*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
+ dstV[i]= (RV*r + GV*g + BV*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
}
}
@@ -1373,30 +1412,38 @@ rgb48ToUV_half_c_template(uint8_t *dstU, uint8_t *dstV,
#undef input_pixel
#define rgb48funcs(pattern, BE_LE, origin) \
-static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *dst, const uint8_t *src, \
+static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *_dst, const uint8_t *_src, \
int width, uint32_t *unused) \
{ \
+ const uint16_t *src = (const uint16_t *) _src; \
+ uint16_t *dst = (uint16_t *) _dst; \
rgb48ToY_c_template(dst, src, width, origin); \
} \
\
-static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
- const uint8_t *src1, const uint8_t *src2, \
+static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *_dstU, uint8_t *_dstV, \
+ const uint8_t *_src1, const uint8_t *_src2, \
int width, uint32_t *unused) \
{ \
+ const uint16_t *src1 = (const uint16_t *) _src1, \
+ *src2 = (const uint16_t *) _src2; \
+ uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV; \
rgb48ToUV_c_template(dstU, dstV, src1, src2, width, origin); \
} \
\
-static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
- const uint8_t *src1, const uint8_t *src2, \
+static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, \
+ const uint8_t *_src1, const uint8_t *_src2, \
int width, uint32_t *unused) \
{ \
+ const uint16_t *src1 = (const uint16_t *) _src1, \
+ *src2 = (const uint16_t *) _src2; \
+ uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV; \
rgb48ToUV_half_c_template(dstU, dstV, src1, src2, width, origin); \
}
-rgb48funcs(rgb, LE, PIX_FMT_RGB48LE);
-rgb48funcs(rgb, BE, PIX_FMT_RGB48BE);
-rgb48funcs(bgr, LE, PIX_FMT_BGR48LE);
-rgb48funcs(bgr, BE, PIX_FMT_BGR48BE);
+rgb48funcs(rgb, LE, PIX_FMT_RGB48LE)
+rgb48funcs(rgb, BE, PIX_FMT_RGB48BE)
+rgb48funcs(bgr, LE, PIX_FMT_BGR48LE)
+rgb48funcs(bgr, BE, PIX_FMT_BGR48BE)
#define input_pixel(i) ((origin == PIX_FMT_RGBA || origin == PIX_FMT_BGRA || \
origin == PIX_FMT_ARGB || origin == PIX_FMT_ABGR) ? AV_RN32A(&src[(i)*4]) : \
@@ -1409,8 +1456,8 @@ rgb16_32ToY_c_template(uint8_t *dst, const uint8_t *src,
int maskr, int maskg, int maskb,
int rsh, int gsh, int bsh, int S)
{
- const int ry = RY << rsh, gy = GY << gsh, by = BY << bsh,
- rnd = 33 << (S - 1);
+ const int ry = RY << rsh, gy = GY << gsh, by = BY << bsh;
+ const unsigned rnd = 33u << (S - 1);
int i;
for (i = 0; i < width; i++) {
@@ -1432,8 +1479,8 @@ rgb16_32ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
int rsh, int gsh, int bsh, int S)
{
const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
- rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
- rnd = 257 << (S - 1);
+ rv = RV << rsh, gv = GV << gsh, bv = BV << bsh;
+ const unsigned rnd = 257u << (S - 1);
int i;
for (i = 0; i < width; i++) {
@@ -1457,7 +1504,8 @@ rgb16_32ToUV_half_c_template(uint8_t *dstU, uint8_t *dstV,
{
const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
- rnd = 257 << S, maskgx = ~(maskr | maskb);
+ maskgx = ~(maskr | maskb);
+ const unsigned rnd = 257u << S;
int i;
maskr |= maskr << 1; maskb |= maskb << 1; maskg |= maskg << 1;
@@ -1508,18 +1556,18 @@ static void name ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV, \
maskr, maskg, maskb, rsh, gsh, bsh, S); \
}
-rgb16_32_wrapper(PIX_FMT_BGR32, bgr32, 16, 0, 0, 0, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8);
-rgb16_32_wrapper(PIX_FMT_BGR32_1, bgr321, 16, 0, 0, 8, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8);
-rgb16_32_wrapper(PIX_FMT_RGB32, rgb32, 0, 0, 16, 0, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8);
-rgb16_32_wrapper(PIX_FMT_RGB32_1, rgb321, 0, 0, 16, 8, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8);
-rgb16_32_wrapper(PIX_FMT_BGR565LE, bgr16le, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8);
-rgb16_32_wrapper(PIX_FMT_BGR555LE, bgr15le, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7);
-rgb16_32_wrapper(PIX_FMT_RGB565LE, rgb16le, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8);
-rgb16_32_wrapper(PIX_FMT_RGB555LE, rgb15le, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7);
-rgb16_32_wrapper(PIX_FMT_BGR565BE, bgr16be, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8);
-rgb16_32_wrapper(PIX_FMT_BGR555BE, bgr15be, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7);
-rgb16_32_wrapper(PIX_FMT_RGB565BE, rgb16be, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8);
-rgb16_32_wrapper(PIX_FMT_RGB555BE, rgb15be, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7);
+rgb16_32_wrapper(PIX_FMT_BGR32, bgr32, 16, 0, 0, 0, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8)
+rgb16_32_wrapper(PIX_FMT_BGR32_1, bgr321, 16, 0, 0, 8, 0xFF0000, 0xFF00, 0x00FF, 8, 0, 8, RGB2YUV_SHIFT+8)
+rgb16_32_wrapper(PIX_FMT_RGB32, rgb32, 0, 0, 16, 0, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8)
+rgb16_32_wrapper(PIX_FMT_RGB32_1, rgb321, 0, 0, 16, 8, 0x00FF, 0xFF00, 0xFF0000, 8, 0, 8, RGB2YUV_SHIFT+8)
+rgb16_32_wrapper(PIX_FMT_BGR565LE, bgr16le, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8)
+rgb16_32_wrapper(PIX_FMT_BGR555LE, bgr15le, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7)
+rgb16_32_wrapper(PIX_FMT_RGB565LE, rgb16le, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8)
+rgb16_32_wrapper(PIX_FMT_RGB555LE, rgb15le, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7)
+rgb16_32_wrapper(PIX_FMT_BGR565BE, bgr16be, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, 11, 5, 0, RGB2YUV_SHIFT+8)
+rgb16_32_wrapper(PIX_FMT_BGR555BE, bgr15be, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, 10, 5, 0, RGB2YUV_SHIFT+7)
+rgb16_32_wrapper(PIX_FMT_RGB565BE, rgb16be, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT+8)
+rgb16_32_wrapper(PIX_FMT_RGB555BE, rgb15be, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT+7)
static void abgrToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unused)
{
@@ -1604,13 +1652,26 @@ static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
assert(src1 == src2);
}
-static void LEToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
- const uint8_t *src2, int width, uint32_t *unused)
+static void bswap16Y_c(uint8_t *_dst, const uint8_t *_src, int width, uint32_t *unused)
{
int i;
+ const uint16_t *src = (const uint16_t *) _src;
+ uint16_t *dst = (uint16_t *) _dst;
for (i=0; i<width; i++) {
- dstU[i]= src1[2*i + 1];
- dstV[i]= src2[2*i + 1];
+ dst[i] = av_bswap16(src[i]);
+ }
+}
+
+static void bswap16UV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src1,
+ const uint8_t *_src2, int width, uint32_t *unused)
+{
+ int i;
+ const uint16_t *src1 = (const uint16_t *) _src1,
+ *src2 = (const uint16_t *) _src2;
+ uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV;
+ for (i=0; i<width; i++) {
+ dstU[i] = av_bswap16(src1[i]);
+ dstV[i] = av_bswap16(src2[i]);
}
}
@@ -1635,16 +1696,6 @@ static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
assert(src1 == src2);
}
-static void BEToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
- const uint8_t *src2, int width, uint32_t *unused)
-{
- int i;
- for (i=0; i<width; i++) {
- dstU[i]= src1[2*i];
- dstV[i]= src2[2*i];
- }
-}
-
static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
const uint8_t *src, int width)
{
@@ -1671,53 +1722,6 @@ static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
#define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
-// FIXME Maybe dither instead.
-static av_always_inline void
-yuv9_OR_10ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
- const uint8_t *_srcU, const uint8_t *_srcV,
- int width, enum PixelFormat origin, int depth)
-{
- int i;
- const uint16_t *srcU = (const uint16_t *) _srcU;
- const uint16_t *srcV = (const uint16_t *) _srcV;
-
- for (i = 0; i < width; i++) {
- dstU[i] = input_pixel(&srcU[i]) >> (depth - 8);
- dstV[i] = input_pixel(&srcV[i]) >> (depth - 8);
- }
-}
-
-static av_always_inline void
-yuv9_or_10ToY_c_template(uint8_t *dstY, const uint8_t *_srcY,
- int width, enum PixelFormat origin, int depth)
-{
- int i;
- const uint16_t *srcY = (const uint16_t*)_srcY;
-
- for (i = 0; i < width; i++)
- dstY[i] = input_pixel(&srcY[i]) >> (depth - 8);
-}
-
-#undef input_pixel
-
-#define YUV_NBPS(depth, BE_LE, origin) \
-static void BE_LE ## depth ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
- const uint8_t *srcU, const uint8_t *srcV, \
- int width, uint32_t *unused) \
-{ \
- yuv9_OR_10ToUV_c_template(dstU, dstV, srcU, srcV, width, origin, depth); \
-} \
-static void BE_LE ## depth ## ToY_c(uint8_t *dstY, const uint8_t *srcY, \
- int width, uint32_t *unused) \
-{ \
- yuv9_or_10ToY_c_template(dstY, srcY, width, origin, depth); \
-}
-
-YUV_NBPS( 9, LE, PIX_FMT_YUV420P9LE);
-YUV_NBPS( 9, BE, PIX_FMT_YUV420P9BE);
-YUV_NBPS(10, LE, PIX_FMT_YUV420P10LE);
-YUV_NBPS(10, BE, PIX_FMT_YUV420P10BE);
-
static void bgr24ToY_c(uint8_t *dst, const uint8_t *src,
int width, uint32_t *unused)
{
@@ -1804,12 +1808,139 @@ static void rgb24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
}
}
+static void planar_rgb_to_y(uint8_t *dst, const uint8_t *src[4], int width)
+{
+ int i;
+ for (i = 0; i < width; i++) {
+ int g = src[0][i];
+ int b = src[1][i];
+ int r = src[2][i];
+
+ dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+ }
+}
+
+static void planar_rgb16le_to_y(uint8_t *_dst, const uint8_t *_src[4], int width)
+{
+ int i;
+ const uint16_t **src = (const uint16_t **) _src;
+ uint16_t *dst = (uint16_t *) _dst;
+ for (i = 0; i < width; i++) {
+ int g = AV_RL16(src[0] + i);
+ int b = AV_RL16(src[1] + i);
+ int r = AV_RL16(src[2] + i);
+
+ dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+ }
+}
+
+static void planar_rgb16be_to_y(uint8_t *_dst, const uint8_t *_src[4], int width)
+{
+ int i;
+ const uint16_t **src = (const uint16_t **) _src;
+ uint16_t *dst = (uint16_t *) _dst;
+ for (i = 0; i < width; i++) {
+ int g = AV_RB16(src[0] + i);
+ int b = AV_RB16(src[1] + i);
+ int r = AV_RB16(src[2] + i);
+
+ dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+ }
+}
+
+static void planar_rgb_to_uv(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width)
+{
+ int i;
+ for (i = 0; i < width; i++) {
+ int g = src[0][i];
+ int b = src[1][i];
+ int r = src[2][i];
+
+ dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
+ dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
+ }
+}
+
+static void planar_rgb16le_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src[4], int width)
+{
+ int i;
+ const uint16_t **src = (const uint16_t **) _src;
+ uint16_t *dstU = (uint16_t *) _dstU;
+ uint16_t *dstV = (uint16_t *) _dstV;
+ for (i = 0; i < width; i++) {
+ int g = AV_RL16(src[0] + i);
+ int b = AV_RL16(src[1] + i);
+ int r = AV_RL16(src[2] + i);
+
+ dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
+ dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
+ }
+}
+
+static void planar_rgb16be_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src[4], int width)
+{
+ int i;
+ const uint16_t **src = (const uint16_t **) _src;
+ uint16_t *dstU = (uint16_t *) _dstU;
+ uint16_t *dstV = (uint16_t *) _dstV;
+ for (i = 0; i < width; i++) {
+ int g = AV_RB16(src[0] + i);
+ int b = AV_RB16(src[1] + i);
+ int r = AV_RB16(src[2] + i);
+
+ dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
+ dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
+ }
+}
+
+static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *_src,
+ const int16_t *filter,
+ const int16_t *filterPos, int filterSize)
+{
+ int i;
+ int32_t *dst = (int32_t *) _dst;
+ const uint16_t *src = (const uint16_t *) _src;
+ int bits = av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
+ int sh = bits - 4;
+
+ for (i = 0; i < dstW; i++) {
+ int j;
+ int srcPos = filterPos[i];
+ int val = 0;
+
+ for (j = 0; j < filterSize; j++) {
+ val += src[srcPos + j] * filter[filterSize * i + j];
+ }
+ // filter=14 bit, input=16 bit, output=30 bit, >> 11 makes 19 bit
+ dst[i] = FFMIN(val >> sh, (1 << 19) - 1);
+ }
+}
+
+static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *_src,
+ const int16_t *filter,
+ const int16_t *filterPos, int filterSize)
+{
+ int i;
+ const uint16_t *src = (const uint16_t *) _src;
+ int sh = av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
+
+ for (i = 0; i < dstW; i++) {
+ int j;
+ int srcPos = filterPos[i];
+ int val = 0;
+
+ for (j = 0; j < filterSize; j++) {
+ val += src[srcPos + j] * filter[filterSize * i + j];
+ }
+ // filter=14 bit, input=16 bit, output=30 bit, >> 15 makes 15 bit
+ dst[i] = FFMIN(val >> sh, (1 << 15) - 1);
+ }
+}
// bilinear / bicubic scaling
-static void hScale_c(int16_t *dst, int dstW, const uint8_t *src,
- int srcW, int xInc,
- const int16_t *filter, const int16_t *filterPos,
- int filterSize)
+static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *src,
+ const int16_t *filter, const int16_t *filterPos,
+ int filterSize)
{
int i;
for (i=0; i<dstW; i++) {
@@ -1825,6 +1956,25 @@ static void hScale_c(int16_t *dst, int dstW, const uint8_t *src,
}
}
+static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *src,
+ const int16_t *filter, const int16_t *filterPos,
+ int filterSize)
+{
+ int i;
+ int32_t *dst = (int32_t *) _dst;
+ for (i=0; i<dstW; i++) {
+ int j;
+ int srcPos= filterPos[i];
+ int val=0;
+ for (j=0; j<filterSize; j++) {
+ val += ((int)src[srcPos + j])*filter[filterSize*i + j];
+ }
+ //filter += hFilterSize;
+ dst[i] = FFMIN(val>>3, (1<<19)-1); // the cubic equation does overflow ...
+ //dst[i] = val>>7;
+ }
+}
+
//FIXME all pal and rgb srcFormats could do this convertion as well
//FIXME all scalers more complex than bilinear could do half of this transform
static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
@@ -1856,6 +2006,41 @@ static void lumRangeFromJpeg_c(int16_t *dst, int width)
dst[i] = (dst[i]*14071 + 33561947)>>14;
}
+static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
+{
+ int i;
+ int32_t *dstU = (int32_t *) _dstU;
+ int32_t *dstV = (int32_t *) _dstV;
+ for (i = 0; i < width; i++) {
+ dstU[i] = (FFMIN(dstU[i],30775<<4)*4663 - (9289992<<4))>>12; //-264
+ dstV[i] = (FFMIN(dstV[i],30775<<4)*4663 - (9289992<<4))>>12; //-264
+ }
+}
+static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
+{
+ int i;
+ int32_t *dstU = (int32_t *) _dstU;
+ int32_t *dstV = (int32_t *) _dstV;
+ for (i = 0; i < width; i++) {
+ dstU[i] = (dstU[i]*1799 + (4081085<<4))>>11; //1469
+ dstV[i] = (dstV[i]*1799 + (4081085<<4))>>11; //1469
+ }
+}
+static void lumRangeToJpeg16_c(int16_t *_dst, int width)
+{
+ int i;
+ int32_t *dst = (int32_t *) _dst;
+ for (i = 0; i < width; i++)
+ dst[i] = (FFMIN(dst[i],30189<<4)*4769 - (39057361<<2))>>12;
+}
+static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
+{
+ int i;
+ int32_t *dst = (int32_t *) _dst;
+ for (i = 0; i < width; i++)
+ dst[i] = (dst[i]*14071 + (33561947<<4))>>14;
+}
+
static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
const uint8_t *src, int srcW, int xInc)
{
@@ -1870,8 +2055,8 @@ static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
}
// *** horizontal scale Y line to temp buffer
-static av_always_inline void hyscale(SwsContext *c, uint16_t *dst, int dstWidth,
- const uint8_t *src, int srcW, int xInc,
+static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth,
+ const uint8_t *src_in[4], int srcW, int xInc,
const int16_t *hLumFilter,
const int16_t *hLumFilterPos, int hLumFilterSize,
uint8_t *formatConvBuffer,
@@ -1879,14 +2064,18 @@ static av_always_inline void hyscale(SwsContext *c, uint16_t *dst, int dstWidth,
{
void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
+ const uint8_t *src = src_in[isAlpha ? 3 : 0];
if (toYV12) {
toYV12(formatConvBuffer, src, srcW, pal);
src= formatConvBuffer;
+ } else if (c->readLumPlanar && !isAlpha) {
+ c->readLumPlanar(formatConvBuffer, src_in, srcW);
+ src = formatConvBuffer;
}
if (!c->hyscale_fast) {
- c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);
+ c->hyScale(c, dst, dstWidth, src, hLumFilter, hLumFilterPos, hLumFilterSize);
} else { // fast bilinear upscale / crap downscale
c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
}
@@ -1910,22 +2099,28 @@ static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
}
}
-static av_always_inline void hcscale(SwsContext *c, uint16_t *dst1, uint16_t *dst2, int dstWidth,
- const uint8_t *src1, const uint8_t *src2,
+static av_always_inline void hcscale(SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth,
+ const uint8_t *src_in[4],
int srcW, int xInc, const int16_t *hChrFilter,
const int16_t *hChrFilterPos, int hChrFilterSize,
uint8_t *formatConvBuffer, uint32_t *pal)
{
+ const uint8_t *src1 = src_in[1], *src2 = src_in[2];
if (c->chrToYV12) {
- uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW, 16);
+ uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW * FFALIGN(c->srcBpc, 8) >> 3, 16);
c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
src1= formatConvBuffer;
src2= buf2;
+ } else if (c->readChrPlanar) {
+ uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW * FFALIGN(c->srcBpc, 8) >> 3, 16);
+ c->readChrPlanar(formatConvBuffer, buf2, src_in, srcW);
+ src1= formatConvBuffer;
+ src2= buf2;
}
if (!c->hcscale_fast) {
- c->hScale(dst1, dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
- c->hScale(dst2, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
+ c->hcScale(c, dst1, dstWidth, src1, hChrFilter, hChrFilterPos, hChrFilterSize);
+ c->hcScale(c, dst2, dstWidth, src2, hChrFilter, hChrFilterPos, hChrFilterSize);
} else { // fast bilinear upscale / crap downscale
c->hcscale_fast(c, dst1, dst2, dstWidth, src1, src2, srcW, xInc);
}
@@ -1936,28 +2131,96 @@ static av_always_inline void hcscale(SwsContext *c, uint16_t *dst1, uint16_t *ds
static av_always_inline void
find_c_packed_planar_out_funcs(SwsContext *c,
- yuv2planar1_fn *yuv2yuv1, yuv2planarX_fn *yuv2yuvX,
+ yuv2planar1_fn *yuv2plane1, yuv2planarX_fn *yuv2planeX,
+ yuv2interleavedX_fn *yuv2nv12cX,
yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2,
yuv2packedX_fn *yuv2packedX)
{
enum PixelFormat dstFormat = c->dstFormat;
- if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
- *yuv2yuvX = yuv2nv12X_c;
- } else if (is16BPS(dstFormat)) {
- *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX16BE_c : yuv2yuvX16LE_c;
+ if (is16BPS(dstFormat)) {
+ *yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c : yuv2planeX_16LE_c;
+ *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c : yuv2plane1_16LE_c;
} else if (is9_OR_10BPS(dstFormat)) {
if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) {
- *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX9BE_c : yuv2yuvX9LE_c;
+ *yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_c : yuv2planeX_9LE_c;
+ *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_9BE_c : yuv2plane1_9LE_c;
} else {
- *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX10BE_c : yuv2yuvX10LE_c;
+ *yuv2planeX = isBE(dstFormat) ? yuv2planeX_10BE_c : yuv2planeX_10LE_c;
+ *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_10BE_c : yuv2plane1_10LE_c;
}
} else {
- *yuv2yuv1 = yuv2yuv1_c;
- *yuv2yuvX = yuv2yuvX_c;
+ *yuv2plane1 = yuv2plane1_8_c;
+ *yuv2planeX = yuv2planeX_8_c;
+ if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21)
+ *yuv2nv12cX = yuv2nv12cX_c;
}
+
if(c->flags & SWS_FULL_CHR_H_INT) {
- *yuv2packedX = yuv2rgbX_c_full;
+ switch (dstFormat) {
+ case PIX_FMT_RGBA:
+#if CONFIG_SMALL
+ *yuv2packedX = yuv2rgba32_full_X_c;
+#else
+#if CONFIG_SWSCALE_ALPHA
+ if (c->alpPixBuf) {
+ *yuv2packedX = yuv2rgba32_full_X_c;
+ } else
+#endif /* CONFIG_SWSCALE_ALPHA */
+ {
+ *yuv2packedX = yuv2rgbx32_full_X_c;
+ }
+#endif /* !CONFIG_SMALL */
+ break;
+ case PIX_FMT_ARGB:
+#if CONFIG_SMALL
+ *yuv2packedX = yuv2argb32_full_X_c;
+#else
+#if CONFIG_SWSCALE_ALPHA
+ if (c->alpPixBuf) {
+ *yuv2packedX = yuv2argb32_full_X_c;
+ } else
+#endif /* CONFIG_SWSCALE_ALPHA */
+ {
+ *yuv2packedX = yuv2xrgb32_full_X_c;
+ }
+#endif /* !CONFIG_SMALL */
+ break;
+ case PIX_FMT_BGRA:
+#if CONFIG_SMALL
+ *yuv2packedX = yuv2bgra32_full_X_c;
+#else
+#if CONFIG_SWSCALE_ALPHA
+ if (c->alpPixBuf) {
+ *yuv2packedX = yuv2bgra32_full_X_c;
+ } else
+#endif /* CONFIG_SWSCALE_ALPHA */
+ {
+ *yuv2packedX = yuv2bgrx32_full_X_c;
+ }
+#endif /* !CONFIG_SMALL */
+ break;
+ case PIX_FMT_ABGR:
+#if CONFIG_SMALL
+ *yuv2packedX = yuv2abgr32_full_X_c;
+#else
+#if CONFIG_SWSCALE_ALPHA
+ if (c->alpPixBuf) {
+ *yuv2packedX = yuv2abgr32_full_X_c;
+ } else
+#endif /* CONFIG_SWSCALE_ALPHA */
+ {
+ *yuv2packedX = yuv2xbgr32_full_X_c;
+ }
+#endif /* !CONFIG_SMALL */
+ break;
+ case PIX_FMT_RGB24:
+ *yuv2packedX = yuv2rgb24_full_X_c;
+ break;
+ case PIX_FMT_BGR24:
+ *yuv2packedX = yuv2bgr24_full_X_c;
+ break;
+ }
} else {
switch (dstFormat) {
case PIX_FMT_GRAY16BE:
@@ -1991,29 +2254,118 @@ find_c_packed_planar_out_funcs(SwsContext *c,
*yuv2packedX = yuv2uyvy422_X_c;
break;
case PIX_FMT_RGB48LE:
- //*yuv2packed1 = yuv2rgb48le_1_c;
- //*yuv2packed2 = yuv2rgb48le_2_c;
- //*yuv2packedX = yuv2rgb48le_X_c;
- //break;
+ *yuv2packed1 = yuv2rgb48le_1_c;
+ *yuv2packed2 = yuv2rgb48le_2_c;
+ *yuv2packedX = yuv2rgb48le_X_c;
+ break;
case PIX_FMT_RGB48BE:
*yuv2packed1 = yuv2rgb48be_1_c;
*yuv2packed2 = yuv2rgb48be_2_c;
*yuv2packedX = yuv2rgb48be_X_c;
break;
case PIX_FMT_BGR48LE:
- //*yuv2packed1 = yuv2bgr48le_1_c;
- //*yuv2packed2 = yuv2bgr48le_2_c;
- //*yuv2packedX = yuv2bgr48le_X_c;
- //break;
+ *yuv2packed1 = yuv2bgr48le_1_c;
+ *yuv2packed2 = yuv2bgr48le_2_c;
+ *yuv2packedX = yuv2bgr48le_X_c;
+ break;
case PIX_FMT_BGR48BE:
*yuv2packed1 = yuv2bgr48be_1_c;
*yuv2packed2 = yuv2bgr48be_2_c;
*yuv2packedX = yuv2bgr48be_X_c;
break;
- default:
- *yuv2packed1 = yuv2packed1_c;
- *yuv2packed2 = yuv2packed2_c;
- *yuv2packedX = yuv2packedX_c;
+ case PIX_FMT_RGB32:
+ case PIX_FMT_BGR32:
+#if CONFIG_SMALL
+ *yuv2packed1 = yuv2rgb32_1_c;
+ *yuv2packed2 = yuv2rgb32_2_c;
+ *yuv2packedX = yuv2rgb32_X_c;
+#else
+#if CONFIG_SWSCALE_ALPHA
+ if (c->alpPixBuf) {
+ *yuv2packed1 = yuv2rgba32_1_c;
+ *yuv2packed2 = yuv2rgba32_2_c;
+ *yuv2packedX = yuv2rgba32_X_c;
+ } else
+#endif /* CONFIG_SWSCALE_ALPHA */
+ {
+ *yuv2packed1 = yuv2rgbx32_1_c;
+ *yuv2packed2 = yuv2rgbx32_2_c;
+ *yuv2packedX = yuv2rgbx32_X_c;
+ }
+#endif /* !CONFIG_SMALL */
+ break;
+ case PIX_FMT_RGB32_1:
+ case PIX_FMT_BGR32_1:
+#if CONFIG_SMALL
+ *yuv2packed1 = yuv2rgb32_1_1_c;
+ *yuv2packed2 = yuv2rgb32_1_2_c;
+ *yuv2packedX = yuv2rgb32_1_X_c;
+#else
+#if CONFIG_SWSCALE_ALPHA
+ if (c->alpPixBuf) {
+ *yuv2packed1 = yuv2rgba32_1_1_c;
+ *yuv2packed2 = yuv2rgba32_1_2_c;
+ *yuv2packedX = yuv2rgba32_1_X_c;
+ } else
+#endif /* CONFIG_SWSCALE_ALPHA */
+ {
+ *yuv2packed1 = yuv2rgbx32_1_1_c;
+ *yuv2packed2 = yuv2rgbx32_1_2_c;
+ *yuv2packedX = yuv2rgbx32_1_X_c;
+ }
+#endif /* !CONFIG_SMALL */
+ break;
+ case PIX_FMT_RGB24:
+ *yuv2packed1 = yuv2rgb24_1_c;
+ *yuv2packed2 = yuv2rgb24_2_c;
+ *yuv2packedX = yuv2rgb24_X_c;
+ break;
+ case PIX_FMT_BGR24:
+ *yuv2packed1 = yuv2bgr24_1_c;
+ *yuv2packed2 = yuv2bgr24_2_c;
+ *yuv2packedX = yuv2bgr24_X_c;
+ break;
+ case PIX_FMT_RGB565LE:
+ case PIX_FMT_RGB565BE:
+ case PIX_FMT_BGR565LE:
+ case PIX_FMT_BGR565BE:
+ *yuv2packed1 = yuv2rgb16_1_c;
+ *yuv2packed2 = yuv2rgb16_2_c;
+ *yuv2packedX = yuv2rgb16_X_c;
+ break;
+ case PIX_FMT_RGB555LE:
+ case PIX_FMT_RGB555BE:
+ case PIX_FMT_BGR555LE:
+ case PIX_FMT_BGR555BE:
+ *yuv2packed1 = yuv2rgb15_1_c;
+ *yuv2packed2 = yuv2rgb15_2_c;
+ *yuv2packedX = yuv2rgb15_X_c;
+ break;
+ case PIX_FMT_RGB444LE:
+ case PIX_FMT_RGB444BE:
+ case PIX_FMT_BGR444LE:
+ case PIX_FMT_BGR444BE:
+ *yuv2packed1 = yuv2rgb12_1_c;
+ *yuv2packed2 = yuv2rgb12_2_c;
+ *yuv2packedX = yuv2rgb12_X_c;
+ break;
+ case PIX_FMT_RGB8:
+ case PIX_FMT_BGR8:
+ *yuv2packed1 = yuv2rgb8_1_c;
+ *yuv2packed2 = yuv2rgb8_2_c;
+ *yuv2packedX = yuv2rgb8_X_c;
+ break;
+ case PIX_FMT_RGB4:
+ case PIX_FMT_BGR4:
+ *yuv2packed1 = yuv2rgb4_1_c;
+ *yuv2packed2 = yuv2rgb4_2_c;
+ *yuv2packedX = yuv2rgb4_X_c;
+ break;
+ case PIX_FMT_RGB4_BYTE:
+ case PIX_FMT_BGR4_BYTE:
+ *yuv2packed1 = yuv2rgb4b_1_c;
+ *yuv2packed2 = yuv2rgb4b_2_c;
+ *yuv2packedX = yuv2rgb4b_X_c;
break;
}
}
@@ -2062,11 +2414,13 @@ static int swScale(SwsContext *c, const uint8_t* src[],
const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
int lastDstY;
uint32_t *pal=c->pal_yuv;
- yuv2planar1_fn yuv2yuv1 = c->yuv2yuv1;
- yuv2planarX_fn yuv2yuvX = c->yuv2yuvX;
+ yuv2planar1_fn yuv2plane1 = c->yuv2plane1;
+ yuv2planarX_fn yuv2planeX = c->yuv2planeX;
+ yuv2interleavedX_fn yuv2nv12cX = c->yuv2nv12cX;
yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
yuv2packedX_fn yuv2packedX = c->yuv2packedX;
+ int should_dither = is9_OR_10BPS(c->srcFormat) || is16BPS(c->srcFormat);
/* vars which will change and which we need to store back in the context */
int dstY= c->dstY;
@@ -2116,21 +2470,28 @@ static int swScale(SwsContext *c, const uint8_t* src[],
lastInChrBuf= -1;
}
+ if (!should_dither) {
+ c->chrDither8 = c->lumDither8 = ff_sws_pb_64;
+ }
lastDstY= dstY;
for (;dstY < dstH; dstY++) {
- unsigned char *dest =dst[0]+dstStride[0]*dstY;
const int chrDstY= dstY>>c->chrDstVSubSample;
- unsigned char *uDest=dst[1]+dstStride[1]*chrDstY;
- unsigned char *vDest=dst[2]+dstStride[2]*chrDstY;
- unsigned char *aDest=(CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3]+dstStride[3]*dstY : NULL;
+ uint8_t *dest[4] = {
+ dst[0] + dstStride[0] * dstY,
+ dst[1] + dstStride[1] * chrDstY,
+ dst[2] + dstStride[2] * chrDstY,
+ (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3] + dstStride[3] * dstY : NULL,
+ };
const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
- int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
- int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
- int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
+
+ // Last line needed as input
+ int lastLumSrcY = FFMIN(c->srcH, firstLumSrcY + vLumFilterSize) - 1;
+ int lastLumSrcY2 = FFMIN(c->srcH, firstLumSrcY2 + vLumFilterSize) - 1;
+ int lastChrSrcY = FFMIN(c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1;
int enough_lines;
//handle holes (FAST_BILINEAR & weird filters)
@@ -2157,8 +2518,12 @@ static int swScale(SwsContext *c, const uint8_t* src[],
//Do horizontal scaling
while(lastInLumBuf < lastLumSrcY) {
- const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
- const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
+ const uint8_t *src1[4] = {
+ src[0] + (lastInLumBuf + 1 - srcSliceY) * srcStride[0],
+ src[1] + (lastInLumBuf + 1 - srcSliceY) * srcStride[1],
+ src[2] + (lastInLumBuf + 1 - srcSliceY) * srcStride[2],
+ src[3] + (lastInLumBuf + 1 - srcSliceY) * srcStride[3],
+ };
lumBufIndex++;
assert(lumBufIndex < 2*vLumBufSize);
assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
@@ -2168,7 +2533,7 @@ static int swScale(SwsContext *c, const uint8_t* src[],
formatConvBuffer,
pal, 0);
if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
- hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW,
+ hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src1, srcW,
lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize,
formatConvBuffer,
pal, 1);
@@ -2177,8 +2542,12 @@ static int swScale(SwsContext *c, const uint8_t* src[],
lumBufIndex, lastInLumBuf);
}
while(lastInChrBuf < lastChrSrcY) {
- const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
- const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
+ const uint8_t *src1[4] = {
+ src[0] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[0],
+ src[1] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[1],
+ src[2] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[2],
+ src[3] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[3],
+ };
chrBufIndex++;
assert(chrBufIndex < 2*vChrBufSize);
assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
@@ -2187,7 +2556,7 @@ static int swScale(SwsContext *c, const uint8_t* src[],
if (c->needs_hcscale)
hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
- chrDstW, src1, src2, chrSrcW, chrXInc,
+ chrDstW, src1, chrSrcW, chrXInc,
hChrFilter, hChrFilterPos, hChrFilterSize,
formatConvBuffer, pal);
lastInChrBuf++;
@@ -2203,11 +2572,14 @@ static int swScale(SwsContext *c, const uint8_t* src[],
#if HAVE_MMX
updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf);
#endif
+ if (should_dither) {
+ c->chrDither8 = dither_8x8_128[chrDstY & 7];
+ c->lumDither8 = dither_8x8_128[dstY & 7];
+ }
if (dstY >= dstH-2) {
// hmm looks like we can't use MMX here without overwriting this array's tail
- find_c_packed_planar_out_funcs(c, &yuv2yuv1, &yuv2yuvX,
- &yuv2packed1, &yuv2packed2,
- &yuv2packedX);
+ find_c_packed_planar_out_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
+ &yuv2packed1, &yuv2packed2, &yuv2packedX);
}
{
@@ -2215,48 +2587,105 @@ static int swScale(SwsContext *c, const uint8_t* src[],
const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
+
+ if (firstLumSrcY < 0 || firstLumSrcY + vLumFilterSize > c->srcH) {
+ const int16_t **tmpY = (const int16_t **) lumPixBuf + 2 * vLumBufSize;
+ int neg = -firstLumSrcY, i, end = FFMIN(c->srcH - firstLumSrcY, vLumFilterSize);
+ for (i = 0; i < neg; i++)
+ tmpY[i] = lumSrcPtr[neg];
+ for ( ; i < end; i++)
+ tmpY[i] = lumSrcPtr[i];
+ for ( ; i < vLumFilterSize; i++)
+ tmpY[i] = tmpY[i-1];
+ lumSrcPtr = tmpY;
+
+ if (alpSrcPtr) {
+ const int16_t **tmpA = (const int16_t **) alpPixBuf + 2 * vLumBufSize;
+ for (i = 0; i < neg; i++)
+ tmpA[i] = alpSrcPtr[neg];
+ for ( ; i < end; i++)
+ tmpA[i] = alpSrcPtr[i];
+ for ( ; i < vLumFilterSize; i++)
+ tmpA[i] = tmpA[i - 1];
+ alpSrcPtr = tmpA;
+ }
+ }
+ if (firstChrSrcY < 0 || firstChrSrcY + vChrFilterSize > c->chrSrcH) {
+ const int16_t **tmpU = (const int16_t **) chrUPixBuf + 2 * vChrBufSize,
+ **tmpV = (const int16_t **) chrVPixBuf + 2 * vChrBufSize;
+ int neg = -firstChrSrcY, i, end = FFMIN(c->chrSrcH - firstChrSrcY, vChrFilterSize);
+ for (i = 0; i < neg; i++) {
+ tmpU[i] = chrUSrcPtr[neg];
+ tmpV[i] = chrVSrcPtr[neg];
+ }
+ for ( ; i < end; i++) {
+ tmpU[i] = chrUSrcPtr[i];
+ tmpV[i] = chrVSrcPtr[i];
+ }
+ for ( ; i < vChrFilterSize; i++) {
+ tmpU[i] = tmpU[i - 1];
+ tmpV[i] = tmpV[i - 1];
+ }
+ chrUSrcPtr = tmpU;
+ chrVSrcPtr = tmpV;
+ }
+
if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
- if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
- if (c->yuv2yuv1 && vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
- const int16_t *lumBuf = lumSrcPtr[0];
- const int16_t *chrUBuf= chrUSrcPtr[0];
- const int16_t *chrVBuf= chrVSrcPtr[0];
- const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL;
- yuv2yuv1(c, lumBuf, chrUBuf, chrVBuf, alpBuf, dest,
- uDest, vDest, aDest, dstW, chrDstW);
- } else { //General YV12
- yuv2yuvX(c,
- vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
- vChrFilter+chrDstY*vChrFilterSize, chrUSrcPtr,
- chrVSrcPtr, vChrFilterSize,
- alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW);
+
+ if (vLumFilterSize == 1) {
+ yuv2plane1(lumSrcPtr[0], dest[0], dstW, c->lumDither8, 0);
+ } else {
+ yuv2planeX(vLumFilter + dstY * vLumFilterSize, vLumFilterSize,
+ lumSrcPtr, dest[0], dstW, c->lumDither8, 0);
+ }
+
+ if (!((dstY&chrSkipMask) || isGray(dstFormat))) {
+ if (yuv2nv12cX) {
+ yuv2nv12cX(c, vChrFilter + chrDstY * vChrFilterSize, vChrFilterSize, chrUSrcPtr, chrVSrcPtr, dest[1], chrDstW);
+ } else if (vChrFilterSize == 1) {
+ yuv2plane1(chrUSrcPtr[0], dest[1], chrDstW, c->chrDither8, 0);
+ yuv2plane1(chrVSrcPtr[0], dest[2], chrDstW, c->chrDither8, 3);
+ } else {
+ yuv2planeX(vChrFilter + chrDstY * vChrFilterSize, vChrFilterSize,
+ chrUSrcPtr, dest[1], chrDstW, c->chrDither8, 0);
+ yuv2planeX(vChrFilter + chrDstY * vChrFilterSize, vChrFilterSize,
+ chrVSrcPtr, dest[2], chrDstW, c->chrDither8, 3);
+ }
+ }
+
+ if (CONFIG_SWSCALE_ALPHA && alpPixBuf){
+ if (vLumFilterSize == 1) {
+ yuv2plane1(alpSrcPtr[0], dest[3], dstW, c->lumDither8, 0);
+ } else {
+ yuv2planeX(vLumFilter + dstY * vLumFilterSize, vLumFilterSize,
+ alpSrcPtr, dest[3], dstW, c->lumDither8, 0);
+ }
}
} else {
assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize*2);
if (c->yuv2packed1 && vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB
- int chrAlpha= vChrFilter[2*dstY+1];
- yuv2packed1(c, *lumSrcPtr, *chrUSrcPtr, *(chrUSrcPtr+1),
- *chrVSrcPtr, *(chrVSrcPtr+1),
- alpPixBuf ? *alpSrcPtr : NULL,
- dest, dstW, chrAlpha, dstFormat, flags, dstY);
+ int chrAlpha = vChrFilter[2 * dstY + 1];
+ yuv2packed1(c, *lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
+ alpPixBuf ? *alpSrcPtr : NULL,
+ dest[0], dstW, chrAlpha, dstY);
} else if (c->yuv2packed2 && vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB
- int lumAlpha= vLumFilter[2*dstY+1];
- int chrAlpha= vChrFilter[2*dstY+1];
- lumMmxFilter[2]=
- lumMmxFilter[3]= vLumFilter[2*dstY ]*0x10001;
- chrMmxFilter[2]=
- chrMmxFilter[3]= vChrFilter[2*chrDstY]*0x10001;
- yuv2packed2(c, *lumSrcPtr, *(lumSrcPtr+1), *chrUSrcPtr, *(chrUSrcPtr+1),
- *chrVSrcPtr, *(chrVSrcPtr+1),
- alpPixBuf ? *alpSrcPtr : NULL, alpPixBuf ? *(alpSrcPtr+1) : NULL,
- dest, dstW, lumAlpha, chrAlpha, dstY);
+ int lumAlpha = vLumFilter[2 * dstY + 1];
+ int chrAlpha = vChrFilter[2 * dstY + 1];
+ lumMmxFilter[2] =
+ lumMmxFilter[3] = vLumFilter[2 * dstY ] * 0x10001;
+ chrMmxFilter[2] =
+ chrMmxFilter[3] = vChrFilter[2 * chrDstY] * 0x10001;
+ yuv2packed2(c, lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
+ alpPixBuf ? alpSrcPtr : NULL,
+ dest[0], dstW, lumAlpha, chrAlpha, dstY);
} else { //general RGB
- yuv2packedX(c,
- vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
- vChrFilter+dstY*vChrFilterSize, chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
- alpSrcPtr, dest, dstW, dstY);
+ yuv2packedX(c, vLumFilter + dstY * vLumFilterSize,
+ lumSrcPtr, vLumFilterSize,
+ vChrFilter + dstY * vChrFilterSize,
+ chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
+ alpSrcPtr, dest[0], dstW, dstY);
}
}
}
@@ -2285,17 +2714,10 @@ static av_cold void sws_init_swScale_c(SwsContext *c)
{
enum PixelFormat srcFormat = c->srcFormat;
- find_c_packed_planar_out_funcs(c, &c->yuv2yuv1, &c->yuv2yuvX,
- &c->yuv2packed1, &c->yuv2packed2,
+ find_c_packed_planar_out_funcs(c, &c->yuv2plane1, &c->yuv2planeX,
+ &c->yuv2nv12cX, &c->yuv2packed1, &c->yuv2packed2,
&c->yuv2packedX);
- c->hScale = hScale_c;
-
- if (c->flags & SWS_FAST_BILINEAR) {
- c->hyscale_fast = hyscale_fast_c;
- c->hcscale_fast = hcscale_fast_c;
- }
-
c->chrToYV12 = NULL;
switch(srcFormat) {
case PIX_FMT_YUYV422 : c->chrToYV12 = yuy2ToUV_c; break;
@@ -2307,22 +2729,34 @@ static av_cold void sws_init_swScale_c(SwsContext *c)
case PIX_FMT_PAL8 :
case PIX_FMT_BGR4_BYTE:
case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break;
- case PIX_FMT_YUV444P9BE:
- case PIX_FMT_YUV420P9BE: c->chrToYV12 = BE9ToUV_c; break;
+ case PIX_FMT_GBRP9LE:
+ case PIX_FMT_GBRP10LE:
+ case PIX_FMT_GBRP16LE: c->readChrPlanar = planar_rgb16le_to_uv; break;
+ case PIX_FMT_GBRP9BE:
+ case PIX_FMT_GBRP10BE:
+ case PIX_FMT_GBRP16BE: c->readChrPlanar = planar_rgb16be_to_uv; break;
+ case PIX_FMT_GBRP: c->readChrPlanar = planar_rgb_to_uv; break;
+#if HAVE_BIGENDIAN
case PIX_FMT_YUV444P9LE:
- case PIX_FMT_YUV420P9LE: c->chrToYV12 = LE9ToUV_c; break;
- case PIX_FMT_YUV444P10BE:
- case PIX_FMT_YUV422P10BE:
- case PIX_FMT_YUV420P10BE: c->chrToYV12 = BE10ToUV_c; break;
+ case PIX_FMT_YUV422P9LE:
+ case PIX_FMT_YUV420P9LE:
case PIX_FMT_YUV422P10LE:
case PIX_FMT_YUV444P10LE:
- case PIX_FMT_YUV420P10LE: c->chrToYV12 = LE10ToUV_c; break;
- case PIX_FMT_YUV420P16BE:
- case PIX_FMT_YUV422P16BE:
- case PIX_FMT_YUV444P16BE: c->chrToYV12 = BEToUV_c; break;
+ case PIX_FMT_YUV420P10LE:
case PIX_FMT_YUV420P16LE:
case PIX_FMT_YUV422P16LE:
- case PIX_FMT_YUV444P16LE: c->chrToYV12 = LEToUV_c; break;
+ case PIX_FMT_YUV444P16LE: c->chrToYV12 = bswap16UV_c; break;
+#else
+ case PIX_FMT_YUV444P9BE:
+ case PIX_FMT_YUV422P9BE:
+ case PIX_FMT_YUV420P9BE:
+ case PIX_FMT_YUV444P10BE:
+ case PIX_FMT_YUV422P10BE:
+ case PIX_FMT_YUV420P10BE:
+ case PIX_FMT_YUV420P16BE:
+ case PIX_FMT_YUV422P16BE:
+ case PIX_FMT_YUV444P16BE: c->chrToYV12 = bswap16UV_c; break;
+#endif
}
if (c->chrSrcHSubSample) {
switch(srcFormat) {
@@ -2371,27 +2805,39 @@ static av_cold void sws_init_swScale_c(SwsContext *c)
c->lumToYV12 = NULL;
c->alpToYV12 = NULL;
switch (srcFormat) {
- case PIX_FMT_YUV444P9BE:
- case PIX_FMT_YUV420P9BE: c->lumToYV12 = BE9ToY_c; break;
+ case PIX_FMT_GBRP9LE:
+ case PIX_FMT_GBRP10LE:
+ case PIX_FMT_GBRP16LE: c->readLumPlanar = planar_rgb16le_to_y; break;
+ case PIX_FMT_GBRP9BE:
+ case PIX_FMT_GBRP10BE:
+ case PIX_FMT_GBRP16BE: c->readLumPlanar = planar_rgb16be_to_y; break;
+ case PIX_FMT_GBRP: c->readLumPlanar = planar_rgb_to_y; break;
+#if HAVE_BIGENDIAN
case PIX_FMT_YUV444P9LE:
- case PIX_FMT_YUV420P9LE: c->lumToYV12 = LE9ToY_c; break;
- case PIX_FMT_YUV444P10BE:
- case PIX_FMT_YUV422P10BE:
- case PIX_FMT_YUV420P10BE: c->lumToYV12 = BE10ToY_c; break;
+ case PIX_FMT_YUV422P9LE:
+ case PIX_FMT_YUV420P9LE:
case PIX_FMT_YUV444P10LE:
case PIX_FMT_YUV422P10LE:
- case PIX_FMT_YUV420P10LE: c->lumToYV12 = LE10ToY_c; break;
- case PIX_FMT_YUYV422 :
- case PIX_FMT_YUV420P16BE:
- case PIX_FMT_YUV422P16BE:
- case PIX_FMT_YUV444P16BE:
- case PIX_FMT_Y400A :
- case PIX_FMT_GRAY16BE : c->lumToYV12 = yuy2ToY_c; break;
- case PIX_FMT_UYVY422 :
+ case PIX_FMT_YUV420P10LE:
case PIX_FMT_YUV420P16LE:
case PIX_FMT_YUV422P16LE:
case PIX_FMT_YUV444P16LE:
- case PIX_FMT_GRAY16LE : c->lumToYV12 = uyvyToY_c; break;
+ case PIX_FMT_GRAY16LE: c->lumToYV12 = bswap16Y_c; break;
+#else
+ case PIX_FMT_YUV444P9BE:
+ case PIX_FMT_YUV422P9BE:
+ case PIX_FMT_YUV420P9BE:
+ case PIX_FMT_YUV444P10BE:
+ case PIX_FMT_YUV422P10BE:
+ case PIX_FMT_YUV420P10BE:
+ case PIX_FMT_YUV420P16BE:
+ case PIX_FMT_YUV422P16BE:
+ case PIX_FMT_YUV444P16BE:
+ case PIX_FMT_GRAY16BE: c->lumToYV12 = bswap16Y_c; break;
+#endif
+ case PIX_FMT_YUYV422 :
+ case PIX_FMT_Y400A : c->lumToYV12 = yuy2ToY_c; break;
+ case PIX_FMT_UYVY422 : c->lumToYV12 = uyvyToY_c; break;
case PIX_FMT_BGR24 : c->lumToYV12 = bgr24ToY_c; break;
case PIX_FMT_BGR565LE : c->lumToYV12 = bgr16leToY_c; break;
case PIX_FMT_BGR565BE : c->lumToYV12 = bgr16beToY_c; break;
@@ -2428,13 +2874,37 @@ static av_cold void sws_init_swScale_c(SwsContext *c)
}
}
+ if (c->srcBpc == 8) {
+ if (c->dstBpc <= 10) {
+ c->hyScale = c->hcScale = hScale8To15_c;
+ if (c->flags & SWS_FAST_BILINEAR) {
+ c->hyscale_fast = hyscale_fast_c;
+ c->hcscale_fast = hcscale_fast_c;
+ }
+ } else {
+ c->hyScale = c->hcScale = hScale8To19_c;
+ }
+ } else {
+ c->hyScale = c->hcScale = c->dstBpc > 10 ? hScale16To19_c : hScale16To15_c;
+ }
+
if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
- if (c->srcRange) {
- c->lumConvertRange = lumRangeFromJpeg_c;
- c->chrConvertRange = chrRangeFromJpeg_c;
+ if (c->dstBpc <= 10) {
+ if (c->srcRange) {
+ c->lumConvertRange = lumRangeFromJpeg_c;
+ c->chrConvertRange = chrRangeFromJpeg_c;
+ } else {
+ c->lumConvertRange = lumRangeToJpeg_c;
+ c->chrConvertRange = chrRangeToJpeg_c;
+ }
} else {
- c->lumConvertRange = lumRangeToJpeg_c;
- c->chrConvertRange = chrRangeToJpeg_c;
+ if (c->srcRange) {
+ c->lumConvertRange = lumRangeFromJpeg16_c;
+ c->chrConvertRange = chrRangeFromJpeg16_c;
+ } else {
+ c->lumConvertRange = lumRangeToJpeg16_c;
+ c->chrConvertRange = chrRangeToJpeg16_c;
+ }
}
}
diff --git a/libswscale/swscale.h b/libswscale/swscale.h
index 3899596..5cd55a7 100644
--- a/libswscale/swscale.h
+++ b/libswscale/swscale.h
@@ -28,9 +28,11 @@
*/
#include "libavutil/avutil.h"
+#include "libavutil/log.h"
+#include "libavutil/pixfmt.h"
#define LIBSWSCALE_VERSION_MAJOR 2
-#define LIBSWSCALE_VERSION_MINOR 0
+#define LIBSWSCALE_VERSION_MINOR 1
#define LIBSWSCALE_VERSION_MICRO 0
#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
@@ -55,17 +57,17 @@
#endif
/**
- * Returns the LIBSWSCALE_VERSION_INT constant.
+ * Return the LIBSWSCALE_VERSION_INT constant.
*/
unsigned swscale_version(void);
/**
- * Returns the libswscale build-time configuration.
+ * Return the libswscale build-time configuration.
*/
const char *swscale_configuration(void);
/**
- * Returns the libswscale license.
+ * Return the libswscale license.
*/
const char *swscale_license(void);
@@ -122,7 +124,7 @@ const char *swscale_license(void);
#define SWS_CS_DEFAULT 5
/**
- * Returns a pointer to yuv<->rgb coefficients for the given colorspace
+ * Return a pointer to yuv<->rgb coefficients for the given colorspace
* suitable for sws_setColorspaceDetails().
*
* @param colorspace One of the SWS_CS_* macros. If invalid,
@@ -149,26 +151,26 @@ typedef struct {
struct SwsContext;
/**
- * Returns a positive value if pix_fmt is a supported input format, 0
+ * Return a positive value if pix_fmt is a supported input format, 0
* otherwise.
*/
int sws_isSupportedInput(enum PixelFormat pix_fmt);
/**
- * Returns a positive value if pix_fmt is a supported output format, 0
+ * Return a positive value if pix_fmt is a supported output format, 0
* otherwise.
*/
int sws_isSupportedOutput(enum PixelFormat pix_fmt);
/**
- * Allocates an empty SwsContext. This must be filled and passed to
+ * Allocate an empty SwsContext. This must be filled and passed to
* sws_init_context(). For filling see AVOptions, options.c and
* sws_setColorspaceDetails().
*/
struct SwsContext *sws_alloc_context(void);
/**
- * Initializes the swscaler context sws_context.
+ * Initialize the swscaler context sws_context.
*
* @return zero or positive value on success, a negative value on
* error
@@ -176,14 +178,14 @@ struct SwsContext *sws_alloc_context(void);
int sws_init_context(struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter);
/**
- * Frees the swscaler context swsContext.
+ * Free the swscaler context swsContext.
* If swsContext is NULL, then does nothing.
*/
void sws_freeContext(struct SwsContext *swsContext);
#if FF_API_SWS_GETCONTEXT
/**
- * Allocates and returns a SwsContext. You need it to perform
+ * Allocate and return an SwsContext. You need it to perform
* scaling/conversion operations using sws_scale().
*
* @param srcW the width of the source image
@@ -205,7 +207,7 @@ struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat
#endif
/**
- * Scales the image slice in srcSlice and puts the resulting scaled
+ * Scale the image slice in srcSlice and put the resulting scaled
* slice in the image in dst. A slice is a sequence of consecutive
* rows in an image.
*
@@ -213,7 +215,7 @@ struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat
* top-bottom or bottom-top order. If slices are provided in
* non-sequential order the behavior of the function is undefined.
*
- * @param context the scaling context previously created with
+ * @param c the scaling context previously created with
* sws_getContext()
* @param srcSlice the array containing the pointers to the planes of
* the source slice
@@ -230,8 +232,9 @@ struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat
* the destination image
* @return the height of the output slice
*/
-int sws_scale(struct SwsContext *context, const uint8_t* const srcSlice[], const int srcStride[],
- int srcSliceY, int srcSliceH, uint8_t* const dst[], const int dstStride[]);
+int sws_scale(struct SwsContext *c, const uint8_t* const srcSlice[],
+ const int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t* const dst[], const int dstStride[]);
/**
* @param inv_table the yuv2rgb coefficients, normally ff_yuv2rgb_coeffs[x]
@@ -249,35 +252,35 @@ int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table,
int *brightness, int *contrast, int *saturation);
/**
- * Allocates and returns an uninitialized vector with length coefficients.
+ * Allocate and return an uninitialized vector with length coefficients.
*/
SwsVector *sws_allocVec(int length);
/**
- * Returns a normalized Gaussian curve used to filter stuff
- * quality=3 is high quality, lower is lower quality.
+ * Return a normalized Gaussian curve used to filter stuff
+ * quality = 3 is high quality, lower is lower quality.
*/
SwsVector *sws_getGaussianVec(double variance, double quality);
/**
- * Allocates and returns a vector with length coefficients, all
+ * Allocate and return a vector with length coefficients, all
* with the same value c.
*/
SwsVector *sws_getConstVec(double c, int length);
/**
- * Allocates and returns a vector with just one coefficient, with
+ * Allocate and return a vector with just one coefficient, with
* value 1.0.
*/
SwsVector *sws_getIdentityVec(void);
/**
- * Scales all the coefficients of a by the scalar value.
+ * Scale all the coefficients of a by the scalar value.
*/
void sws_scaleVec(SwsVector *a, double scalar);
/**
- * Scales all the coefficients of a so that their sum equals height.
+ * Scale all the coefficients of a so that their sum equals height.
*/
void sws_normalizeVec(SwsVector *a, double height);
void sws_convVec(SwsVector *a, SwsVector *b);
@@ -286,13 +289,13 @@ void sws_subVec(SwsVector *a, SwsVector *b);
void sws_shiftVec(SwsVector *a, int shift);
/**
- * Allocates and returns a clone of the vector a, that is a vector
+ * Allocate and return a clone of the vector a, that is a vector
* with the same coefficients as a.
*/
SwsVector *sws_cloneVec(SwsVector *a);
/**
- * Prints with av_log() a textual representation of the vector a
+ * Print with av_log() a textual representation of the vector a
* if log_level <= av_log_level.
*/
void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level);
@@ -306,8 +309,7 @@ SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
void sws_freeFilter(SwsFilter *filter);
/**
- * Checks if context can be reused, otherwise reallocates a new
- * one.
+ * Check if context can be reused, otherwise reallocate a new one.
*
* If context is NULL, just calls sws_getContext() to get a new
* context. Otherwise, checks if the parameters are the ones already
@@ -325,7 +327,7 @@ struct SwsContext *sws_getCachedContext(struct SwsContext *context,
SwsFilter *dstFilter, const double *param);
/**
- * Converts an 8bit paletted frame into a frame with a color depth of 32-bits.
+ * Convert an 8-bit paletted frame into a frame with a color depth of 32 bits.
*
* The output frame will have the same packed format as the palette.
*
@@ -337,7 +339,7 @@ struct SwsContext *sws_getCachedContext(struct SwsContext *context,
void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette);
/**
- * Converts an 8bit paletted frame into a frame with a color depth of 24 bits.
+ * Convert an 8-bit paletted frame into a frame with a color depth of 24 bits.
*
* With the palette format "ABCD", the destination frame ends up with the format "ABC".
*
@@ -348,5 +350,12 @@ void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pix
*/
void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette);
+/**
+ * Get the AVClass for swsContext. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *sws_get_class(void);
#endif /* SWSCALE_SWSCALE_H */
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index ea34d8c..bb3b52d 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -28,6 +28,9 @@
#endif
#include "libavutil/avutil.h"
+#include "libavutil/log.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/pixdesc.h"
#define STR(s) AV_TOSTRING(s) //AV_STRINGIFY is too long
@@ -57,40 +60,155 @@ typedef int (*SwsFunc)(struct SwsContext *context, const uint8_t* src[],
int srcStride[], int srcSliceY, int srcSliceH,
uint8_t* dst[], int dstStride[]);
-typedef void (*yuv2planar1_fn) (struct SwsContext *c,
- const int16_t *lumSrc, const int16_t *chrUSrc,
- const int16_t *chrVSrc, const int16_t *alpSrc,
- uint8_t *dest,
- uint8_t *uDest, uint8_t *vDest, uint8_t *aDest,
- int dstW, int chrDstW);
-typedef void (*yuv2planarX_fn) (struct SwsContext *c,
- const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrUSrc,
- const int16_t **chrVSrc, int chrFilterSize,
- const int16_t **alpSrc,
- uint8_t *dest,
- uint8_t *uDest, uint8_t *vDest, uint8_t *aDest,
- int dstW, int chrDstW);
-typedef void (*yuv2packed1_fn) (struct SwsContext *c,
- const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0,
- uint8_t *dest,
- int dstW, int uvalpha, int dstFormat, int flags, int y);
-typedef void (*yuv2packed2_fn) (struct SwsContext *c,
- const uint16_t *buf0, const uint16_t *buf1,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, const uint16_t *abuf1,
- uint8_t *dest,
+
+/**
+ * Write one line of horizontally scaled data to planar output
+ * without any additional vertical scaling (or point-scaling).
+ *
+ * @param src scaled source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param dest pointer to the output plane. For >8bit
+ * output, this is in uint16_t
+ * @param dstW width of destination in pixels
+ * @param dither ordered dither array of type int16_t and size 8
+ * @param offset Dither offset
+ */
+typedef void (*yuv2planar1_fn) (const int16_t *src, uint8_t *dest, int dstW,
+ const uint8_t *dither, int offset);
+
+/**
+ * Write one line of horizontally scaled data to planar output
+ * with multi-point vertical scaling between input pixels.
+ *
+ * @param filter vertical luma/alpha scaling coefficients, 12bit [0,4096]
+ * @param src scaled luma (Y) or alpha (A) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param filterSize number of vertical input lines to scale
+ * @param dest pointer to output plane. For >8bit
+ * output, this is in uint16_t
+ * @param dstW width of destination pixels
+ * @param offset Dither offset
+ */
+typedef void (*yuv2planarX_fn) (const int16_t *filter, int filterSize,
+ const int16_t **src, uint8_t *dest, int dstW,
+ const uint8_t *dither, int offset);
+
+/**
+ * Write one line of horizontally scaled chroma to interleaved output
+ * with multi-point vertical scaling between input pixels.
+ *
+ * @param c SWS scaling context
+ * @param chrFilter vertical chroma scaling coefficients, 12bit [0,4096]
+ * @param chrUSrc scaled chroma (U) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param chrVSrc scaled chroma (V) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param chrFilterSize number of vertical chroma input lines to scale
+ * @param dest pointer to the output plane. For >8bit
+ * output, this is in uint16_t
+ * @param dstW width of chroma planes
+ */
+typedef void (*yuv2interleavedX_fn) (struct SwsContext *c, const int16_t *chrFilter, int chrFilterSize,
+ const int16_t **chrUSrc, const int16_t **chrVSrc,
+ uint8_t *dest, int dstW);
+
+/**
+ * Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB
+ * output without any additional vertical scaling (or point-scaling). Note
+ * that this function may do chroma scaling, see the "uvalpha" argument.
+ *
+ * @param c SWS scaling context
+ * @param lumSrc scaled luma (Y) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param chrUSrc scaled chroma (U) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param chrVSrc scaled chroma (V) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param alpSrc scaled alpha (A) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param dest pointer to the output plane. For 16bit output, this is
+ * uint16_t
+ * @param dstW width of lumSrc and alpSrc in pixels, number of pixels
+ * to write into dest[]
+ * @param uvalpha chroma scaling coefficient for the second line of chroma
+ * pixels, either 2048 or 0. If 0, one chroma input is used
+ * for 2 output pixels (or if the SWS_FLAG_FULL_CHR_INT flag
+ * is set, it generates 1 output pixel). If 2048, two chroma
+ * input pixels should be averaged for 2 output pixels (this
+ * only happens if SWS_FLAG_FULL_CHR_INT is not set)
+ * @param y vertical line number for this output. This does not need
+ * to be used to calculate the offset in the destination,
+ * but can be used to generate comfort noise using dithering
+ * for some output formats.
+ */
+typedef void (*yuv2packed1_fn) (struct SwsContext *c, const int16_t *lumSrc,
+ const int16_t *chrUSrc[2], const int16_t *chrVSrc[2],
+ const int16_t *alpSrc, uint8_t *dest,
+ int dstW, int uvalpha, int y);
+/**
+ * Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB
+ * output by doing bilinear scaling between two input lines.
+ *
+ * @param c SWS scaling context
+ * @param lumSrc scaled luma (Y) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param chrUSrc scaled chroma (U) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param chrVSrc scaled chroma (V) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param alpSrc scaled alpha (A) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param dest pointer to the output plane. For 16bit output, this is
+ * uint16_t
+ * @param dstW width of lumSrc and alpSrc in pixels, number of pixels
+ * to write into dest[]
+ * @param yalpha luma/alpha scaling coefficients for the second input line.
+ * The first line's coefficients can be calculated by using
+ * 4096 - yalpha
+ * @param uvalpha chroma scaling coefficient for the second input line. The
+ * first line's coefficients can be calculated by using
+ * 4096 - uvalpha
+ * @param y vertical line number for this output. This does not need
+ * to be used to calculate the offset in the destination,
+ * but can be used to generate comfort noise using dithering
+ * for some output formats.
+ */
+typedef void (*yuv2packed2_fn) (struct SwsContext *c, const int16_t *lumSrc[2],
+ const int16_t *chrUSrc[2], const int16_t *chrVSrc[2],
+ const int16_t *alpSrc[2], uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y);
-typedef void (*yuv2packedX_fn) (struct SwsContext *c,
- const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
+/**
+ * Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB
+ * output by doing multi-point vertical scaling between input pixels.
+ *
+ * @param c SWS scaling context
+ * @param lumFilter vertical luma/alpha scaling coefficients, 12bit [0,4096]
+ * @param lumSrc scaled luma (Y) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param lumFilterSize number of vertical luma/alpha input lines to scale
+ * @param chrFilter vertical chroma scaling coefficients, 12bit [0,4096]
+ * @param chrUSrc scaled chroma (U) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param chrVSrc scaled chroma (V) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param chrFilterSize number of vertical chroma input lines to scale
+ * @param alpSrc scaled alpha (A) source data, 15bit for 8-10bit output,
+ * 19-bit for 16bit output (in int32_t)
+ * @param dest pointer to the output plane. For 16bit output, this is
+ * uint16_t
+ * @param dstW width of lumSrc and alpSrc in pixels, number of pixels
+ * to write into dest[]
+ * @param y vertical line number for this output. This does not need
+ * to be used to calculate the offset in the destination,
+ * but can be used to generate comfort noise using dithering
+ * or some output formats.
+ */
+typedef void (*yuv2packedX_fn) (struct SwsContext *c, const int16_t *lumFilter,
+ const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint8_t *dest,
- int dstW, int dstY);
+ int dstW, int y);
/* This struct should be aligned on at least a 32-byte boundary. */
typedef struct SwsContext {
@@ -117,6 +235,7 @@ typedef struct SwsContext {
enum PixelFormat srcFormat; ///< Source pixel format.
int dstFormatBpp; ///< Number of bits per pixel of the destination pixel format.
int srcFormatBpp; ///< Number of bits per pixel of the source pixel format.
+ int dstBpc, srcBpc;
int chrSrcHSubSample; ///< Binary logarithm of horizontal subsampling factor between luma/alpha and chroma planes in source image.
int chrSrcVSubSample; ///< Binary logarithm of vertical subsampling factor between luma/alpha and chroma planes in source image.
int chrDstHSubSample; ///< Binary logarithm of horizontal subsampling factor between luma/alpha and chroma planes in destination image.
@@ -228,8 +347,10 @@ typedef struct SwsContext {
#define V_TEMP "11*8+4*4*256*2+32"
#define Y_TEMP "11*8+4*4*256*2+40"
#define ALP_MMX_FILTER_OFFSET "11*8+4*4*256*2+48"
-#define UV_OFF "11*8+4*4*256*3+48"
-#define UV_OFFx2 "11*8+4*4*256*3+56"
+#define UV_OFF_PX "11*8+4*4*256*3+48"
+#define UV_OFF_BYTE "11*8+4*4*256*3+56"
+#define DITHER16 "11*8+4*4*256*3+64"
+#define DITHER32 "11*8+4*4*256*3+80"
DECLARE_ALIGNED(8, uint64_t, redDither);
DECLARE_ALIGNED(8, uint64_t, greenDither);
@@ -252,8 +373,15 @@ typedef struct SwsContext {
DECLARE_ALIGNED(8, uint64_t, v_temp);
DECLARE_ALIGNED(8, uint64_t, y_temp);
int32_t alpMmxFilter[4*MAX_FILTER_SIZE];
- DECLARE_ALIGNED(8, ptrdiff_t, uv_off); ///< offset (in pixels) between u and v planes
- DECLARE_ALIGNED(8, ptrdiff_t, uv_offx2); ///< offset (in bytes) between u and v planes
+ // alignment of these values is not necessary, but merely here
+ // to maintain the same offset across x8632 and x86-64. Once we
+ // use proper offset macros in the asm, they can be removed.
+ DECLARE_ALIGNED(8, ptrdiff_t, uv_off_px); ///< offset (in pixels) between u and v planes
+ DECLARE_ALIGNED(8, ptrdiff_t, uv_off_byte); ///< offset (in bytes) between u and v planes
+ DECLARE_ALIGNED(8, uint16_t, dither16)[8];
+ DECLARE_ALIGNED(8, uint32_t, dither32)[8];
+
+ const uint8_t *chrDither8, *lumDither8;
#if HAVE_ALTIVEC
vector signed short CY;
@@ -285,8 +413,9 @@ typedef struct SwsContext {
#endif
/* function pointers for swScale() */
- yuv2planar1_fn yuv2yuv1;
- yuv2planarX_fn yuv2yuvX;
+ yuv2planar1_fn yuv2plane1;
+ yuv2planarX_fn yuv2planeX;
+ yuv2interleavedX_fn yuv2nv12cX;
yuv2packed1_fn yuv2packed1;
yuv2packed2_fn yuv2packed2;
yuv2packedX_fn yuv2packedX;
@@ -298,6 +427,35 @@ typedef struct SwsContext {
void (*chrToYV12)(uint8_t *dstU, uint8_t *dstV,
const uint8_t *src1, const uint8_t *src2,
int width, uint32_t *pal); ///< Unscaled conversion of chroma planes to YV12 for horizontal scaler.
+
+ /**
+ * Functions to read planar input, such as planar RGB, and convert
+ * internally to Y/UV.
+ */
+ /** @{ */
+ void (*readLumPlanar)(uint8_t *dst, const uint8_t *src[4], int width);
+ void (*readChrPlanar)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width);
+ /** @} */
+
+ /**
+ * Scale one horizontal line of input data using a bilinear filter
+ * to produce one line of output data. Compared to SwsContext->hScale(),
+ * please take note of the following caveats when using these:
+ * - Scaling is done using only 7bit instead of 14bit coefficients.
+ * - You can use no more than 5 input pixels to produce 4 output
+ * pixels. Therefore, this filter should not be used for downscaling
+ * by more than ~20% in width (because that equals more than 5/4th
+ * downscaling and thus more than 5 pixels input per 4 pixels output).
+ * - In general, bilinear filters create artifacts during downscaling
+ * (even when <20%), because one output pixel will span more than one
+ * input pixel, and thus some pixels will need edges of both neighbor
+ * pixels to interpolate the output pixel. Since you can use at most
+ * two input pixels per output pixel in bilinear scaling, this is
+ * impossible and thus downscaling by any size will create artifacts.
+ * To enable this type of scaling, set SWS_FLAG_FAST_BILINEAR
+ * in SwsContext->flags.
+ */
+ /** @{ */
void (*hyscale_fast)(struct SwsContext *c,
int16_t *dst, int dstWidth,
const uint8_t *src, int srcW, int xInc);
@@ -305,10 +463,46 @@ typedef struct SwsContext {
int16_t *dst1, int16_t *dst2, int dstWidth,
const uint8_t *src1, const uint8_t *src2,
int srcW, int xInc);
+ /** @} */
- void (*hScale)(int16_t *dst, int dstW, const uint8_t *src, int srcW,
- int xInc, const int16_t *filter, const int16_t *filterPos,
- int filterSize);
+ /**
+ * Scale one horizontal line of input data using a filter over the input
+ * lines, to produce one (differently sized) line of output data.
+ *
+ * @param dst pointer to destination buffer for horizontally scaled
+ * data. If the number of bits per component of one
+ * destination pixel (SwsContext->dstBpc) is <= 10, data
+ * will be 15bpc in 16bits (int16_t) width. Else (i.e.
+ * SwsContext->dstBpc == 16), data will be 19bpc in
+ * 32bits (int32_t) width.
+ * @param dstW width of destination image
+ * @param src pointer to source data to be scaled. If the number of
+ * bits per component of a source pixel (SwsContext->srcBpc)
+ * is 8, this is 8bpc in 8bits (uint8_t) width. Else
+ * (i.e. SwsContext->dstBpc > 8), this is native depth
+ * in 16bits (uint16_t) width. In other words, for 9-bit
+ * YUV input, this is 9bpc, for 10-bit YUV input, this is
+ * 10bpc, and for 16-bit RGB or YUV, this is 16bpc.
+ * @param filter filter coefficients to be used per output pixel for
+ * scaling. This contains 14bpp filtering coefficients.
+ * Guaranteed to contain dstW * filterSize entries.
+ * @param filterPos position of the first input pixel to be used for
+ * each output pixel during scaling. Guaranteed to
+ * contain dstW entries.
+ * @param filterSize the number of input coefficients to be used (and
+ * thus the number of input pixels to be used) for
+ * creating a single output pixel. Is aligned to 4
+ * (and input coefficients thus padded with zeroes)
+ * to simplify creating SIMD code.
+ */
+ /** @{ */
+ void (*hyScale)(struct SwsContext *c, int16_t *dst, int dstW, const uint8_t *src,
+ const int16_t *filter, const int16_t *filterPos,
+ int filterSize);
+ void (*hcScale)(struct SwsContext *c, int16_t *dst, int dstW, const uint8_t *src,
+ const int16_t *filter, const int16_t *filterPos,
+ int filterSize);
+ /** @} */
void (*lumConvertRange)(int16_t *dst, int width); ///< Color range conversion function for luma plane if needed.
void (*chrConvertRange)(int16_t *dst1, int16_t *dst2, int width); ///< Color range conversion function for chroma planes if needed.
@@ -337,79 +531,40 @@ void ff_bfin_get_unscaled_swscale(SwsContext *c);
const char *sws_format_name(enum PixelFormat format);
-//FIXME replace this with something faster
-#define is16BPS(x) ( \
- (x)==PIX_FMT_GRAY16BE \
- || (x)==PIX_FMT_GRAY16LE \
- || (x)==PIX_FMT_BGR48BE \
- || (x)==PIX_FMT_BGR48LE \
- || (x)==PIX_FMT_RGB48BE \
- || (x)==PIX_FMT_RGB48LE \
- || (x)==PIX_FMT_YUV420P16LE \
- || (x)==PIX_FMT_YUV422P16LE \
- || (x)==PIX_FMT_YUV444P16LE \
- || (x)==PIX_FMT_YUV420P16BE \
- || (x)==PIX_FMT_YUV422P16BE \
- || (x)==PIX_FMT_YUV444P16BE \
- )
-#define is9_OR_10BPS(x) ( \
- (x)==PIX_FMT_YUV420P9LE \
- || (x)==PIX_FMT_YUV420P9BE \
- || (x)==PIX_FMT_YUV444P9BE \
- || (x)==PIX_FMT_YUV444P9LE \
- || (x)==PIX_FMT_YUV422P10BE \
- || (x)==PIX_FMT_YUV422P10LE \
- || (x)==PIX_FMT_YUV444P10BE \
- || (x)==PIX_FMT_YUV444P10LE \
- || (x)==PIX_FMT_YUV420P10LE \
- || (x)==PIX_FMT_YUV420P10BE \
- )
-#define isBE(x) ((x)&1)
-#define isPlanar8YUV(x) ( \
- (x)==PIX_FMT_YUV410P \
- || (x)==PIX_FMT_YUV420P \
- || (x)==PIX_FMT_YUVA420P \
- || (x)==PIX_FMT_YUV411P \
- || (x)==PIX_FMT_YUV422P \
- || (x)==PIX_FMT_YUV444P \
- || (x)==PIX_FMT_YUV440P \
- || (x)==PIX_FMT_NV12 \
- || (x)==PIX_FMT_NV21 \
- )
-#define isPlanarYUV(x) ( \
- isPlanar8YUV(x) \
- || (x)==PIX_FMT_YUV420P9LE \
- || (x)==PIX_FMT_YUV444P9LE \
- || (x)==PIX_FMT_YUV420P10LE \
- || (x)==PIX_FMT_YUV422P10LE \
- || (x)==PIX_FMT_YUV444P10LE \
- || (x)==PIX_FMT_YUV420P16LE \
- || (x)==PIX_FMT_YUV422P16LE \
- || (x)==PIX_FMT_YUV444P16LE \
- || (x)==PIX_FMT_YUV420P9BE \
- || (x)==PIX_FMT_YUV444P9BE \
- || (x)==PIX_FMT_YUV420P10BE \
- || (x)==PIX_FMT_YUV422P10BE \
- || (x)==PIX_FMT_YUV444P10BE \
- || (x)==PIX_FMT_YUV420P16BE \
- || (x)==PIX_FMT_YUV422P16BE \
- || (x)==PIX_FMT_YUV444P16BE \
- )
-#define isYUV(x) ( \
- (x)==PIX_FMT_UYVY422 \
- || (x)==PIX_FMT_YUYV422 \
- || isPlanarYUV(x) \
- )
+#define is16BPS(x) \
+ (av_pix_fmt_descriptors[x].comp[0].depth_minus1 == 15)
+
+#define is9_OR_10BPS(x) \
+ (av_pix_fmt_descriptors[x].comp[0].depth_minus1 == 8 || \
+ av_pix_fmt_descriptors[x].comp[0].depth_minus1 == 9)
+
+#define isBE(x) \
+ (av_pix_fmt_descriptors[x].flags & PIX_FMT_BE)
+
+#define isYUV(x) \
+ (!(av_pix_fmt_descriptors[x].flags & PIX_FMT_RGB) && \
+ av_pix_fmt_descriptors[x].nb_components >= 2)
+
+#define isPlanarYUV(x) \
+ ((av_pix_fmt_descriptors[x].flags & PIX_FMT_PLANAR) && \
+ isYUV(x))
+
+#define isRGB(x) \
+ (av_pix_fmt_descriptors[x].flags & PIX_FMT_RGB)
+
+#if 0 // FIXME
+#define isGray(x) \
+ (!(av_pix_fmt_descriptors[x].flags & PIX_FMT_PAL) && \
+ av_pix_fmt_descriptors[x].nb_components <= 2)
+#else
#define isGray(x) ( \
(x)==PIX_FMT_GRAY8 \
|| (x)==PIX_FMT_Y400A \
|| (x)==PIX_FMT_GRAY16BE \
|| (x)==PIX_FMT_GRAY16LE \
)
-#define isGray16(x) ( \
- (x)==PIX_FMT_GRAY16BE \
- || (x)==PIX_FMT_GRAY16LE \
- )
+#endif
+
#define isRGBinInt(x) ( \
(x)==PIX_FMT_RGB48BE \
|| (x)==PIX_FMT_RGB48LE \
@@ -446,39 +601,24 @@ const char *sws_format_name(enum PixelFormat format);
|| (x)==PIX_FMT_MONOBLACK \
|| (x)==PIX_FMT_MONOWHITE \
)
-#define isRGBinBytes(x) ( \
- (x)==PIX_FMT_RGB48BE \
- || (x)==PIX_FMT_RGB48LE \
- || (x)==PIX_FMT_RGBA \
- || (x)==PIX_FMT_ARGB \
- || (x)==PIX_FMT_RGB24 \
- )
-#define isBGRinBytes(x) ( \
- (x)==PIX_FMT_BGR48BE \
- || (x)==PIX_FMT_BGR48LE \
- || (x)==PIX_FMT_BGRA \
- || (x)==PIX_FMT_ABGR \
- || (x)==PIX_FMT_BGR24 \
- )
#define isAnyRGB(x) ( \
isRGBinInt(x) \
|| isBGRinInt(x) \
)
-#define isALPHA(x) ( \
- (x)==PIX_FMT_BGR32 \
- || (x)==PIX_FMT_BGR32_1 \
- || (x)==PIX_FMT_RGB32 \
- || (x)==PIX_FMT_RGB32_1 \
- || (x)==PIX_FMT_Y400A \
- || (x)==PIX_FMT_YUVA420P \
- )
-#define isPacked(x) ( \
- (x)==PIX_FMT_PAL8 \
- || (x)==PIX_FMT_YUYV422 \
- || (x)==PIX_FMT_UYVY422 \
- || (x)==PIX_FMT_Y400A \
- || isAnyRGB(x) \
+#define isALPHA(x) \
+ (av_pix_fmt_descriptors[x].nb_components == 2 || \
+ av_pix_fmt_descriptors[x].nb_components == 4)
+
+#define isPacked(x) (\
+ (av_pix_fmt_descriptors[x].nb_components >= 2 && \
+ !(av_pix_fmt_descriptors[x].flags & PIX_FMT_PLANAR)) || \
+ (x) == PIX_FMT_PAL8\
)
+
+#define isPlanar(x) \
+ (av_pix_fmt_descriptors[x].nb_components >= 2 && \
+ (av_pix_fmt_descriptors[x].flags & PIX_FMT_PLANAR))
+
#define usePal(x) ((av_pix_fmt_descriptors[x].flags & PIX_FMT_PAL) || (x) == PIX_FMT_Y400A)
extern const uint64_t ff_dither4[2];
@@ -487,7 +627,7 @@ extern const uint64_t ff_dither8[2];
extern const AVClass sws_context_class;
/**
- * Sets c->swScale to an unscaled converter if one exists for the specific
+ * Set c->swScale to an unscaled converter if one exists for the specific
* source and destination formats, bit depths, flags, etc.
*/
void ff_get_unscaled_swscale(SwsContext *c);
@@ -495,7 +635,7 @@ void ff_get_unscaled_swscale(SwsContext *c);
void ff_swscale_get_unscaled_altivec(SwsContext *c);
/**
- * Returns function pointer to fastest main scaler path function depending
+ * Return function pointer to fastest main scaler path function depending
* on architecture and available optimizations.
*/
SwsFunc ff_getSwsFunc(SwsContext *c);
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 87cd655..7c339b6 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -34,22 +34,65 @@
#include "libavutil/bswap.h"
#include "libavutil/pixdesc.h"
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_1)[8][8] = {
+ { 0, 1, 0, 1, 0, 1, 0, 1,},
+ { 1, 0, 1, 0, 1, 0, 1, 0,},
+ { 0, 1, 0, 1, 0, 1, 0, 1,},
+ { 1, 0, 1, 0, 1, 0, 1, 0,},
+ { 0, 1, 0, 1, 0, 1, 0, 1,},
+ { 1, 0, 1, 0, 1, 0, 1, 0,},
+ { 0, 1, 0, 1, 0, 1, 0, 1,},
+ { 1, 0, 1, 0, 1, 0, 1, 0,},
+};
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_3)[8][8] = {
+ { 1, 2, 1, 2, 1, 2, 1, 2,},
+ { 3, 0, 3, 0, 3, 0, 3, 0,},
+ { 1, 2, 1, 2, 1, 2, 1, 2,},
+ { 3, 0, 3, 0, 3, 0, 3, 0,},
+ { 1, 2, 1, 2, 1, 2, 1, 2,},
+ { 3, 0, 3, 0, 3, 0, 3, 0,},
+ { 1, 2, 1, 2, 1, 2, 1, 2,},
+ { 3, 0, 3, 0, 3, 0, 3, 0,},
+};
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_64)[8][8] = {
+ { 18, 34, 30, 46, 17, 33, 29, 45,},
+ { 50, 2, 62, 14, 49, 1, 61, 13,},
+ { 26, 42, 22, 38, 25, 41, 21, 37,},
+ { 58, 10, 54, 6, 57, 9, 53, 5,},
+ { 16, 32, 28, 44, 19, 35, 31, 47,},
+ { 48, 0, 60, 12, 51, 3, 63, 15,},
+ { 24, 40, 20, 36, 27, 43, 23, 39,},
+ { 56, 8, 52, 4, 59, 11, 55, 7,},
+};
+extern const uint8_t dither_8x8_128[8][8];
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_256)[8][8] = {
+ { 72, 136, 120, 184, 68, 132, 116, 180,},
+ { 200, 8, 248, 56, 196, 4, 244, 52,},
+ { 104, 168, 88, 152, 100, 164, 84, 148,},
+ { 232, 40, 216, 24, 228, 36, 212, 20,},
+ { 64, 128, 102, 176, 76, 140, 124, 188,},
+ { 192, 0, 240, 48, 204, 12, 252, 60,},
+ { 96, 160, 80, 144, 108, 172, 92, 156,},
+ { 224, 32, 208, 16, 236, 44, 220, 28,},
+};
+
#define RGB2YUV_SHIFT 15
-#define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5))
-#define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5))
-#define BU ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
-#define GY ( (int)(0.587*219/255*(1<<RGB2YUV_SHIFT)+0.5))
-#define GV (-(int)(0.419*224/255*(1<<RGB2YUV_SHIFT)+0.5))
-#define GU (-(int)(0.331*224/255*(1<<RGB2YUV_SHIFT)+0.5))
-#define RY ( (int)(0.299*219/255*(1<<RGB2YUV_SHIFT)+0.5))
-#define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
-#define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5))
-
-static void fillPlane(uint8_t* plane, int stride, int width, int height, int y, uint8_t val)
+#define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+
+static void fillPlane(uint8_t *plane, int stride, int width, int height, int y,
+ uint8_t val)
{
int i;
- uint8_t *ptr = plane + stride*y;
- for (i=0; i<height; i++) {
+ uint8_t *ptr = plane + stride * y;
+ for (i = 0; i < height; i++) {
memset(ptr, val, width);
ptr += stride;
}
@@ -64,7 +107,7 @@ static void copyPlane(const uint8_t *src, int srcStride,
memcpy(dst, src, srcSliceH * dstStride);
} else {
int i;
- for (i=0; i<srcSliceH; i++) {
+ for (i = 0; i < srcSliceH; i++) {
memcpy(dst, src, width);
src += srcStride;
dst += dstStride;
@@ -72,70 +115,84 @@ static void copyPlane(const uint8_t *src, int srcStride,
}
}
-static int planarToNv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dstParam[], int dstStride[])
+static int planarToNv12Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY,
+ int srcSliceH, uint8_t *dstParam[],
+ int dstStride[])
{
- uint8_t *dst = dstParam[1] + dstStride[1]*srcSliceY/2;
+ uint8_t *dst = dstParam[1] + dstStride[1] * srcSliceY / 2;
copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
dstParam[0], dstStride[0]);
if (c->dstFormat == PIX_FMT_NV12)
- interleaveBytes(src[1], src[2], dst, c->srcW/2, srcSliceH/2, srcStride[1], srcStride[2], dstStride[0]);
+ interleaveBytes(src[1], src[2], dst, c->srcW / 2, srcSliceH / 2,
+ srcStride[1], srcStride[2], dstStride[0]);
else
- interleaveBytes(src[2], src[1], dst, c->srcW/2, srcSliceH/2, srcStride[2], srcStride[1], dstStride[0]);
+ interleaveBytes(src[2], src[1], dst, c->srcW / 2, srcSliceH / 2,
+ srcStride[2], srcStride[1], dstStride[0]);
return srcSliceH;
}
-static int planarToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dstParam[], int dstStride[])
+static int planarToYuy2Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dstParam[], int dstStride[])
{
- uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
+ uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
- yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]);
+ yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
+ srcStride[1], dstStride[0]);
return srcSliceH;
}
-static int planarToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dstParam[], int dstStride[])
+static int planarToUyvyWrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dstParam[], int dstStride[])
{
- uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
+ uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
- yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]);
+ yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
+ srcStride[1], dstStride[0]);
return srcSliceH;
}
-static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dstParam[], int dstStride[])
+static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dstParam[], int dstStride[])
{
- uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
+ uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
- yuv422ptoyuy2(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]);
+ yuv422ptoyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
+ srcStride[1], dstStride[0]);
return srcSliceH;
}
-static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dstParam[], int dstStride[])
+static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dstParam[], int dstStride[])
{
- uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
+ uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
- yuv422ptouyvy(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]);
+ yuv422ptouyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
+ srcStride[1], dstStride[0]);
return srcSliceH;
}
-static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dstParam[], int dstStride[])
+static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dstParam[], int dstStride[])
{
- uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
- uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2;
- uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2;
+ uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
+ uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
+ uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
- yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
+ yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
+ dstStride[1], srcStride[0]);
if (dstParam[3])
fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
@@ -143,26 +200,30 @@ static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStrid
return srcSliceH;
}
-static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dstParam[], int dstStride[])
+static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dstParam[], int dstStride[])
{
- uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
- uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY;
- uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY;
+ uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
+ uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
+ uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
- yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
+ yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
+ dstStride[1], srcStride[0]);
return srcSliceH;
}
-static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dstParam[], int dstStride[])
+static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dstParam[], int dstStride[])
{
- uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
- uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2;
- uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2;
+ uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
+ uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
+ uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
- uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
+ uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
+ dstStride[1], srcStride[0]);
if (dstParam[3])
fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
@@ -170,56 +231,84 @@ static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStrid
return srcSliceH;
}
-static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dstParam[], int dstStride[])
+static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dstParam[], int dstStride[])
{
- uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
- uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY;
- uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY;
+ uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
+ uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
+ uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
- uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
+ uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
+ dstStride[1], srcStride[0]);
return srcSliceH;
}
-static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
+static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels,
+ const uint8_t *palette)
{
int i;
- for (i=0; i<num_pixels; i++)
- ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | (src[(i<<1)+1] << 24);
+ for (i = 0; i < num_pixels; i++)
+ ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i << 1]] | (src[(i << 1) + 1] << 24);
}
-static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
+static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels,
+ const uint8_t *palette)
{
int i;
- for (i=0; i<num_pixels; i++)
- ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | src[(i<<1)+1];
+ for (i = 0; i < num_pixels; i++)
+ ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i << 1]] | src[(i << 1) + 1];
}
-static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
+static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels,
+ const uint8_t *palette)
{
int i;
- for (i=0; i<num_pixels; i++) {
+ for (i = 0; i < num_pixels; i++) {
//FIXME slow?
- dst[0]= palette[src[i<<1]*4+0];
- dst[1]= palette[src[i<<1]*4+1];
- dst[2]= palette[src[i<<1]*4+2];
- dst+= 3;
+ dst[0] = palette[src[i << 1] * 4 + 0];
+ dst[1] = palette[src[i << 1] * 4 + 1];
+ dst[2] = palette[src[i << 1] * 4 + 2];
+ dst += 3;
}
}
-static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dst[], int dstStride[])
+static int packed_16bpc_bswap(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dst[], int dstStride[])
+{
+ int i, j;
+ int srcstr = srcStride[0] >> 1;
+ int dststr = dstStride[0] >> 1;
+ uint16_t *dstPtr = (uint16_t *) dst[0];
+ const uint16_t *srcPtr = (const uint16_t *) src[0];
+ int min_stride = FFMIN(srcstr, dststr);
+
+ for (i = 0; i < srcSliceH; i++) {
+ for (j = 0; j < min_stride; j++) {
+ dstPtr[j] = av_bswap16(srcPtr[j]);
+ }
+ srcPtr += srcstr;
+ dstPtr += dststr;
+ }
+
+ return srcSliceH;
+}
+
+static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
+ int srcSliceY, int srcSliceH, uint8_t *dst[],
+ int dstStride[])
{
- const enum PixelFormat srcFormat= c->srcFormat;
- const enum PixelFormat dstFormat= c->dstFormat;
+ const enum PixelFormat srcFormat = c->srcFormat;
+ const enum PixelFormat dstFormat = c->dstFormat;
void (*conv)(const uint8_t *src, uint8_t *dst, int num_pixels,
- const uint8_t *palette)=NULL;
+ const uint8_t *palette) = NULL;
int i;
- uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
- const uint8_t *srcPtr= src[0];
+ uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
+ const uint8_t *srcPtr = src[0];
if (srcFormat == PIX_FMT_Y400A) {
switch (dstFormat) {
@@ -245,10 +334,10 @@ static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[],
av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
sws_format_name(srcFormat), sws_format_name(dstFormat));
else {
- for (i=0; i<srcSliceH; i++) {
+ for (i = 0; i < srcSliceH; i++) {
conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb);
- srcPtr+= srcStride[0];
- dstPtr+= dstStride[0];
+ srcPtr += srcStride[0];
+ dstPtr += dstStride[0];
}
}
@@ -263,16 +352,17 @@ static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[],
)
/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
-static int rgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dst[], int dstStride[])
+static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
+ int srcSliceY, int srcSliceH, uint8_t *dst[],
+ int dstStride[])
{
- const enum PixelFormat srcFormat= c->srcFormat;
- const enum PixelFormat dstFormat= c->dstFormat;
- const int srcBpp= (c->srcFormatBpp + 7) >> 3;
- const int dstBpp= (c->dstFormatBpp + 7) >> 3;
- const int srcId= c->srcFormatBpp >> 2; /* 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8 */
- const int dstId= c->dstFormatBpp >> 2;
- void (*conv)(const uint8_t *src, uint8_t *dst, int src_size)=NULL;
+ const enum PixelFormat srcFormat = c->srcFormat;
+ const enum PixelFormat dstFormat = c->dstFormat;
+ const int srcBpp = (c->srcFormatBpp + 7) >> 3;
+ const int dstBpp = (c->dstFormatBpp + 7) >> 3;
+ const int srcId = c->srcFormatBpp >> 2; /* 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8 */
+ const int dstId = c->dstFormatBpp >> 2;
+ void (*conv)(const uint8_t *src, uint8_t *dst, int src_size) = NULL;
#define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst)
@@ -291,40 +381,40 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[],
|| CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
} else
/* BGR -> BGR */
- if ( (isBGRinInt(srcFormat) && isBGRinInt(dstFormat))
- || (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
- switch(srcId | (dstId<<4)) {
- case 0x34: conv= rgb16to15; break;
- case 0x36: conv= rgb24to15; break;
- case 0x38: conv= rgb32to15; break;
- case 0x43: conv= rgb15to16; break;
- case 0x46: conv= rgb24to16; break;
- case 0x48: conv= rgb32to16; break;
- case 0x63: conv= rgb15to24; break;
- case 0x64: conv= rgb16to24; break;
- case 0x68: conv= rgb32to24; break;
- case 0x83: conv= rgb15to32; break;
- case 0x84: conv= rgb16to32; break;
- case 0x86: conv= rgb24to32; break;
+ if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) ||
+ (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
+ switch (srcId | (dstId << 4)) {
+ case 0x34: conv = rgb16to15; break;
+ case 0x36: conv = rgb24to15; break;
+ case 0x38: conv = rgb32to15; break;
+ case 0x43: conv = rgb15to16; break;
+ case 0x46: conv = rgb24to16; break;
+ case 0x48: conv = rgb32to16; break;
+ case 0x63: conv = rgb15to24; break;
+ case 0x64: conv = rgb16to24; break;
+ case 0x68: conv = rgb32to24; break;
+ case 0x83: conv = rgb15to32; break;
+ case 0x84: conv = rgb16to32; break;
+ case 0x86: conv = rgb24to32; break;
}
- } else if ( (isBGRinInt(srcFormat) && isRGBinInt(dstFormat))
- || (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
- switch(srcId | (dstId<<4)) {
- case 0x33: conv= rgb15tobgr15; break;
- case 0x34: conv= rgb16tobgr15; break;
- case 0x36: conv= rgb24tobgr15; break;
- case 0x38: conv= rgb32tobgr15; break;
- case 0x43: conv= rgb15tobgr16; break;
- case 0x44: conv= rgb16tobgr16; break;
- case 0x46: conv= rgb24tobgr16; break;
- case 0x48: conv= rgb32tobgr16; break;
- case 0x63: conv= rgb15tobgr24; break;
- case 0x64: conv= rgb16tobgr24; break;
- case 0x66: conv= rgb24tobgr24; break;
- case 0x68: conv= rgb32tobgr24; break;
- case 0x83: conv= rgb15tobgr32; break;
- case 0x84: conv= rgb16tobgr32; break;
- case 0x86: conv= rgb24tobgr32; break;
+ } else if ((isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) ||
+ (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
+ switch (srcId | (dstId << 4)) {
+ case 0x33: conv = rgb15tobgr15; break;
+ case 0x34: conv = rgb16tobgr15; break;
+ case 0x36: conv = rgb24tobgr15; break;
+ case 0x38: conv = rgb32tobgr15; break;
+ case 0x43: conv = rgb15tobgr16; break;
+ case 0x44: conv = rgb16tobgr16; break;
+ case 0x46: conv = rgb24tobgr16; break;
+ case 0x48: conv = rgb32tobgr16; break;
+ case 0x63: conv = rgb15tobgr24; break;
+ case 0x64: conv = rgb16tobgr24; break;
+ case 0x66: conv = rgb24tobgr24; break;
+ case 0x68: conv = rgb32tobgr24; break;
+ case 0x83: conv = rgb15tobgr32; break;
+ case 0x84: conv = rgb16tobgr32; break;
+ case 0x86: conv = rgb24tobgr32; break;
}
}
@@ -332,38 +422,43 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[],
av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
sws_format_name(srcFormat), sws_format_name(dstFormat));
} else {
- const uint8_t *srcPtr= src[0];
- uint8_t *dstPtr= dst[0];
- if ((srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1) && !isRGBA32(dstFormat))
+ const uint8_t *srcPtr = src[0];
+ uint8_t *dstPtr = dst[0];
+ if ((srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1) &&
+ !isRGBA32(dstFormat))
srcPtr += ALT32_CORR;
- if ((dstFormat == PIX_FMT_RGB32_1 || dstFormat == PIX_FMT_BGR32_1) && !isRGBA32(srcFormat))
+ if ((dstFormat == PIX_FMT_RGB32_1 || dstFormat == PIX_FMT_BGR32_1) &&
+ !isRGBA32(srcFormat))
dstPtr += ALT32_CORR;
- if (dstStride[0]*srcBpp == srcStride[0]*dstBpp && srcStride[0] > 0)
- conv(srcPtr, dstPtr + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]);
+ if (dstStride[0] * srcBpp == srcStride[0] * dstBpp && srcStride[0] > 0 &&
+ !(srcStride[0] % srcBpp))
+ conv(srcPtr, dstPtr + dstStride[0] * srcSliceY,
+ srcSliceH * srcStride[0]);
else {
int i;
- dstPtr += dstStride[0]*srcSliceY;
+ dstPtr += dstStride[0] * srcSliceY;
- for (i=0; i<srcSliceH; i++) {
- conv(srcPtr, dstPtr, c->srcW*srcBpp);
- srcPtr+= srcStride[0];
- dstPtr+= dstStride[0];
+ for (i = 0; i < srcSliceH; i++) {
+ conv(srcPtr, dstPtr, c->srcW * srcBpp);
+ srcPtr += srcStride[0];
+ dstPtr += dstStride[0];
}
}
}
return srcSliceH;
}
-static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dst[], int dstStride[])
+static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dst[], int dstStride[])
{
rgb24toyv12(
src[0],
- dst[0]+ srcSliceY *dstStride[0],
- dst[1]+(srcSliceY>>1)*dstStride[1],
- dst[2]+(srcSliceY>>1)*dstStride[2],
+ dst[0] + srcSliceY * dstStride[0],
+ dst[1] + (srcSliceY >> 1) * dstStride[1],
+ dst[2] + (srcSliceY >> 1) * dstStride[2],
c->srcW, srcSliceH,
dstStride[0], dstStride[1], srcStride[0]);
if (dst[3])
@@ -371,15 +466,16 @@ static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride
return srcSliceH;
}
-static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dst[], int dstStride[])
+static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dst[], int dstStride[])
{
copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
dst[0], dstStride[0]);
- planar2x(src[1], dst[1] + dstStride[1]*(srcSliceY >> 1), c->chrSrcW,
+ planar2x(src[1], dst[1] + dstStride[1] * (srcSliceY >> 1), c->chrSrcW,
srcSliceH >> 2, srcStride[1], dstStride[1]);
- planar2x(src[2], dst[2] + dstStride[2]*(srcSliceY >> 1), c->chrSrcW,
+ planar2x(src[2], dst[2] + dstStride[2] * (srcSliceY >> 1), c->chrSrcW,
srcSliceH >> 2, srcStride[2], dstStride[2]);
if (dst[3])
fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
@@ -387,65 +483,91 @@ static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[
}
/* unscaled copy like stuff (assumes nearly identical formats) */
-static int packedCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dst[], int dstStride[])
+static int packedCopyWrapper(SwsContext *c, const 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]);
+ if (dstStride[0] == srcStride[0] && srcStride[0] > 0)
+ memcpy(dst[0] + dstStride[0] * srcSliceY, src[0], srcSliceH * dstStride[0]);
else {
int i;
- const uint8_t *srcPtr= src[0];
- uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
- int length=0;
+ const 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);
+ 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++) {
+ for (i = 0; i < srcSliceH; i++) {
memcpy(dstPtr, srcPtr, length);
- srcPtr+= srcStride[0];
- dstPtr+= dstStride[0];
+ srcPtr += srcStride[0];
+ dstPtr += dstStride[0];
}
}
return srcSliceH;
}
-static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dst[], int dstStride[])
+#define clip9(x) av_clip_uintp2(x, 9)
+#define clip10(x) av_clip_uintp2(x, 10)
+#define DITHER_COPY(dst, dstStride, wfunc, src, srcStride, rfunc, dithers, shift, clip) \
+ for (i = 0; i < height; i++) { \
+ const uint8_t *dither = dithers[i & 7]; \
+ for (j = 0; j < length - 7; j += 8) { \
+ wfunc(&dst[j + 0], clip((rfunc(&src[j + 0]) + dither[0]) >> shift)); \
+ wfunc(&dst[j + 1], clip((rfunc(&src[j + 1]) + dither[1]) >> shift)); \
+ wfunc(&dst[j + 2], clip((rfunc(&src[j + 2]) + dither[2]) >> shift)); \
+ wfunc(&dst[j + 3], clip((rfunc(&src[j + 3]) + dither[3]) >> shift)); \
+ wfunc(&dst[j + 4], clip((rfunc(&src[j + 4]) + dither[4]) >> shift)); \
+ wfunc(&dst[j + 5], clip((rfunc(&src[j + 5]) + dither[5]) >> shift)); \
+ wfunc(&dst[j + 6], clip((rfunc(&src[j + 6]) + dither[6]) >> shift)); \
+ wfunc(&dst[j + 7], clip((rfunc(&src[j + 7]) + dither[7]) >> shift)); \
+ } \
+ for (; j < length; j++) \
+ wfunc(&dst[j], (rfunc(&src[j]) + dither[j & 7]) >> shift); \
+ dst += dstStride; \
+ src += srcStride; \
+ }
+
+static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dst[], int dstStride[])
{
int plane, i, j;
- for (plane=0; plane<4; plane++) {
- int length= (plane==0 || plane==3) ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample);
- int y= (plane==0 || plane==3) ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample);
- int height= (plane==0 || plane==3) ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample);
- const uint8_t *srcPtr= src[plane];
- uint8_t *dstPtr= dst[plane] + dstStride[plane]*y;
-
- if (!dst[plane]) continue;
+ for (plane = 0; plane < 4; plane++) {
+ int length = (plane == 0 || plane == 3) ? c->srcW : -((-c->srcW ) >> c->chrDstHSubSample);
+ int y = (plane == 0 || plane == 3) ? srcSliceY: -((-srcSliceY) >> c->chrDstVSubSample);
+ int height = (plane == 0 || plane == 3) ? srcSliceH: -((-srcSliceH) >> c->chrDstVSubSample);
+ const uint8_t *srcPtr = src[plane];
+ uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;
+
+ if (!dst[plane])
+ continue;
// ignore palette for GRAY8
if (plane == 1 && !dst[2]) continue;
if (!src[plane] || (plane == 1 && !src[2])) {
- if(is16BPS(c->dstFormat))
- length*=2;
- fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128);
+ if (is16BPS(c->dstFormat))
+ length *= 2;
+ fillPlane(dst[plane], dstStride[plane], length, height, y,
+ (plane == 3) ? 255 : 128);
} else {
- if(is9_OR_10BPS(c->srcFormat)) {
- const int src_depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1+1;
- const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1;
- const uint16_t *srcPtr2 = (const uint16_t*)srcPtr;
+ if (is9_OR_10BPS(c->srcFormat)) {
+ const int src_depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1 + 1;
+ const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1 + 1;
+ const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
if (is16BPS(c->dstFormat)) {
- uint16_t *dstPtr2 = (uint16_t*)dstPtr;
+ uint16_t *dstPtr2 = (uint16_t *) dstPtr;
#define COPY9_OR_10TO16(rfunc, wfunc) \
for (i = 0; i < height; i++) { \
for (j = 0; j < length; j++) { \
int srcpx = rfunc(&srcPtr2[j]); \
- wfunc(&dstPtr2[j], (srcpx<<(16-src_depth)) | (srcpx>>(2*src_depth-16))); \
+ wfunc(&dstPtr2[j], (srcpx << (16 - src_depth)) | (srcpx >> (2 * src_depth - 16))); \
} \
- dstPtr2 += dstStride[plane]/2; \
- srcPtr2 += srcStride[plane]/2; \
+ dstPtr2 += dstStride[plane] / 2; \
+ srcPtr2 += srcStride[plane] / 2; \
}
if (isBE(c->dstFormat)) {
if (isBE(c->srcFormat)) {
@@ -461,21 +583,23 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[
}
}
} else if (is9_OR_10BPS(c->dstFormat)) {
- uint16_t *dstPtr2 = (uint16_t*)dstPtr;
+ uint16_t *dstPtr2 = (uint16_t *) dstPtr;
#define COPY9_OR_10TO9_OR_10(loop) \
for (i = 0; i < height; i++) { \
for (j = 0; j < length; j++) { \
loop; \
} \
- dstPtr2 += dstStride[plane]/2; \
- srcPtr2 += srcStride[plane]/2; \
+ dstPtr2 += dstStride[plane] / 2; \
+ srcPtr2 += srcStride[plane] / 2; \
}
#define COPY9_OR_10TO9_OR_10_2(rfunc, wfunc) \
if (dst_depth > src_depth) { \
COPY9_OR_10TO9_OR_10(int srcpx = rfunc(&srcPtr2[j]); \
wfunc(&dstPtr2[j], (srcpx << 1) | (srcpx >> 9))); \
} else if (dst_depth < src_depth) { \
- COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]) >> 1)); \
+ DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
+ srcPtr2, srcStride[plane] / 2, rfunc, \
+ dither_8x8_1, 1, clip9); \
} else { \
COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]))); \
}
@@ -493,14 +617,16 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[
}
}
} else {
- // FIXME Maybe dither instead.
+#define W8(a, b) { *(a) = (b); }
#define COPY9_OR_10TO8(rfunc) \
- for (i = 0; i < height; i++) { \
- for (j = 0; j < length; j++) { \
- dstPtr[j] = rfunc(&srcPtr2[j])>>(src_depth-8); \
- } \
- dstPtr += dstStride[plane]; \
- srcPtr2 += srcStride[plane]/2; \
+ if (src_depth == 9) { \
+ DITHER_COPY(dstPtr, dstStride[plane], W8, \
+ srcPtr2, srcStride[plane] / 2, rfunc, \
+ dither_8x8_1, 1, av_clip_uint8); \
+ } else { \
+ DITHER_COPY(dstPtr, dstStride[plane], W8, \
+ srcPtr2, srcStride[plane] / 2, rfunc, \
+ dither_8x8_3, 2, av_clip_uint8); \
}
if (isBE(c->srcFormat)) {
COPY9_OR_10TO8(AV_RB16);
@@ -508,19 +634,21 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[
COPY9_OR_10TO8(AV_RL16);
}
}
- } else if(is9_OR_10BPS(c->dstFormat)) {
- const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1;
- uint16_t *dstPtr2 = (uint16_t*)dstPtr;
+ } else if (is9_OR_10BPS(c->dstFormat)) {
+ const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1 + 1;
+ uint16_t *dstPtr2 = (uint16_t *) dstPtr;
if (is16BPS(c->srcFormat)) {
- const uint16_t *srcPtr2 = (const uint16_t*)srcPtr;
+ const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
#define COPY16TO9_OR_10(rfunc, wfunc) \
- for (i = 0; i < height; i++) { \
- for (j = 0; j < length; j++) { \
- wfunc(&dstPtr2[j], rfunc(&srcPtr2[j])>>(16-dst_depth)); \
- } \
- dstPtr2 += dstStride[plane]/2; \
- srcPtr2 += srcStride[plane]/2; \
+ if (dst_depth == 9) { \
+ DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
+ srcPtr2, srcStride[plane] / 2, rfunc, \
+ dither_8x8_128, 7, clip9); \
+ } else { \
+ DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
+ srcPtr2, srcStride[plane] / 2, rfunc, \
+ dither_8x8_64, 6, clip10); \
}
if (isBE(c->dstFormat)) {
if (isBE(c->srcFormat)) {
@@ -540,9 +668,9 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[
for (i = 0; i < height; i++) { \
for (j = 0; j < length; j++) { \
const int srcpx = srcPtr[j]; \
- wfunc(&dstPtr2[j], (srcpx<<(dst_depth-8)) | (srcpx >> (16-dst_depth))); \
+ wfunc(&dstPtr2[j], (srcpx << (dst_depth - 8)) | (srcpx >> (16 - dst_depth))); \
} \
- dstPtr2 += dstStride[plane]/2; \
+ dstPtr2 += dstStride[plane] / 2; \
srcPtr += srcStride[plane]; \
}
if (isBE(c->dstFormat)) {
@@ -551,42 +679,46 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[
COPY8TO9_OR_10(AV_WL16);
}
}
- } else if(is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
- if (!isBE(c->srcFormat)) srcPtr++;
- for (i=0; i<height; i++) {
- for (j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1];
- srcPtr+= srcStride[plane];
- dstPtr+= dstStride[plane];
+ } else if (is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
+ const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
+#define COPY16TO8(rfunc) \
+ DITHER_COPY(dstPtr, dstStride[plane], W8, \
+ srcPtr2, srcStride[plane] / 2, rfunc, \
+ dither_8x8_256, 8, av_clip_uint8);
+ if (isBE(c->srcFormat)) {
+ COPY16TO8(AV_RB16);
+ } else {
+ COPY16TO8(AV_RL16);
}
- } else if(!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {
- for (i=0; i<height; i++) {
- for (j=0; j<length; j++) {
- dstPtr[ j<<1 ] = srcPtr[j];
- dstPtr[(j<<1)+1] = srcPtr[j];
+ } else if (!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < length; j++) {
+ dstPtr[ j << 1 ] = srcPtr[j];
+ dstPtr[(j << 1) + 1] = srcPtr[j];
}
- srcPtr+= srcStride[plane];
- dstPtr+= dstStride[plane];
+ srcPtr += srcStride[plane];
+ dstPtr += dstStride[plane];
}
- } else if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat)
- && isBE(c->srcFormat) != isBE(c->dstFormat)) {
-
- for (i=0; i<height; i++) {
- for (j=0; j<length; j++)
- ((uint16_t*)dstPtr)[j] = av_bswap16(((const uint16_t*)srcPtr)[j]);
- srcPtr+= srcStride[plane];
- dstPtr+= dstStride[plane];
+ } else if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat) &&
+ isBE(c->srcFormat) != isBE(c->dstFormat)) {
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < length; j++)
+ ((uint16_t *) dstPtr)[j] = av_bswap16(((const uint16_t *) srcPtr)[j]);
+ srcPtr += srcStride[plane];
+ dstPtr += dstStride[plane];
}
} else if (dstStride[plane] == srcStride[plane] &&
srcStride[plane] > 0 && srcStride[plane] == length) {
- memcpy(dst[plane] + dstStride[plane]*y, src[plane],
- height*dstStride[plane]);
+ memcpy(dst[plane] + dstStride[plane] * y, src[plane],
+ height * dstStride[plane]);
} else {
- if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
- length*=2;
- for (i=0; i<height; i++) {
+ if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
+ length *= 2;
+ for (i = 0; i < height; i++) {
memcpy(dstPtr, srcPtr, length);
- srcPtr+= srcStride[plane];
- dstPtr+= dstStride[plane];
+ srcPtr += srcStride[plane];
+ dstPtr += dstStride[plane];
}
}
}
@@ -594,6 +726,12 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[
return srcSliceH;
}
+
+#define IS_DIFFERENT_ENDIANESS(src_fmt, dst_fmt, pix_fmt) \
+ ((src_fmt == pix_fmt ## BE && dst_fmt == pix_fmt ## LE) || \
+ (src_fmt == pix_fmt ## LE && dst_fmt == pix_fmt ## BE))
+
+
void ff_get_unscaled_swscale(SwsContext *c)
{
const enum PixelFormat srcFormat = c->srcFormat;
@@ -602,27 +740,33 @@ void ff_get_unscaled_swscale(SwsContext *c)
const int dstH = c->dstH;
int needsDither;
- needsDither= isAnyRGB(dstFormat)
- && c->dstFormatBpp < 24
- && (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat)));
+ needsDither = isAnyRGB(dstFormat) &&
+ c->dstFormatBpp < 24 &&
+ (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat)));
/* yv12_to_nv12 */
- if ((srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) && (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21)) {
- c->swScale= planarToNv12Wrapper;
+ if ((srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) &&
+ (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21)) {
+ c->swScale = planarToNv12Wrapper;
}
/* yuv2bgr */
- if ((srcFormat==PIX_FMT_YUV420P || srcFormat==PIX_FMT_YUV422P || srcFormat==PIX_FMT_YUVA420P) && isAnyRGB(dstFormat)
- && !(flags & SWS_ACCURATE_RND) && !(dstH&1)) {
- c->swScale= ff_yuv2rgb_get_func_ptr(c);
+ if ((srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUV422P ||
+ srcFormat == PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
+ !(flags & SWS_ACCURATE_RND) && !(dstH & 1)) {
+ c->swScale = ff_yuv2rgb_get_func_ptr(c);
}
- if (srcFormat==PIX_FMT_YUV410P && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_BITEXACT)) {
- c->swScale= yvu9ToYv12Wrapper;
+ if (srcFormat == PIX_FMT_YUV410P &&
+ (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P) &&
+ !(flags & SWS_BITEXACT)) {
+ c->swScale = yvu9ToYv12Wrapper;
}
/* bgr24toYV12 */
- if (srcFormat==PIX_FMT_BGR24 && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_ACCURATE_RND))
- c->swScale= bgr24ToYv12Wrapper;
+ if (srcFormat == PIX_FMT_BGR24 &&
+ (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P) &&
+ !(flags & SWS_ACCURATE_RND))
+ c->swScale = bgr24ToYv12Wrapper;
/* RGB/BGR -> RGB/BGR (no dither needed forms) */
if ( isAnyRGB(srcFormat)
@@ -642,6 +786,18 @@ void ff_get_unscaled_swscale(SwsContext *c)
&& (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
c->swScale= rgbToRgbWrapper;
+ /* bswap 16 bits per pixel/component packed formats */
+ if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR444) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR48) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR555) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR565) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_GRAY16) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_RGB444) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_RGB48) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_RGB555) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_RGB565))
+ c->swScale = packed_16bpc_bswap;
+
if ((usePal(srcFormat) && (
dstFormat == PIX_FMT_RGB32 ||
dstFormat == PIX_FMT_RGB32_1 ||
@@ -649,13 +805,13 @@ void ff_get_unscaled_swscale(SwsContext *c)
dstFormat == PIX_FMT_BGR32 ||
dstFormat == PIX_FMT_BGR32_1 ||
dstFormat == PIX_FMT_BGR24)))
- c->swScale= palToRgbWrapper;
+ c->swScale = palToRgbWrapper;
if (srcFormat == PIX_FMT_YUV422P) {
if (dstFormat == PIX_FMT_YUYV422)
- c->swScale= yuv422pToYuy2Wrapper;
+ c->swScale = yuv422pToYuy2Wrapper;
else if (dstFormat == PIX_FMT_UYVY422)
- c->swScale= yuv422pToUyvyWrapper;
+ c->swScale = yuv422pToUyvyWrapper;
}
/* LQ converters if -sws 0 or -sws 4*/
@@ -663,37 +819,39 @@ void ff_get_unscaled_swscale(SwsContext *c)
/* yv12_to_yuy2 */
if (srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) {
if (dstFormat == PIX_FMT_YUYV422)
- c->swScale= planarToYuy2Wrapper;
+ c->swScale = planarToYuy2Wrapper;
else if (dstFormat == PIX_FMT_UYVY422)
- c->swScale= planarToUyvyWrapper;
+ c->swScale = planarToUyvyWrapper;
}
}
- if(srcFormat == PIX_FMT_YUYV422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P))
- c->swScale= yuyvToYuv420Wrapper;
- if(srcFormat == PIX_FMT_UYVY422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P))
- c->swScale= uyvyToYuv420Wrapper;
- if(srcFormat == PIX_FMT_YUYV422 && dstFormat == PIX_FMT_YUV422P)
- c->swScale= yuyvToYuv422Wrapper;
- if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P)
- c->swScale= uyvyToYuv422Wrapper;
+ if (srcFormat == PIX_FMT_YUYV422 &&
+ (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P))
+ c->swScale = yuyvToYuv420Wrapper;
+ if (srcFormat == PIX_FMT_UYVY422 &&
+ (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P))
+ c->swScale = uyvyToYuv420Wrapper;
+ if (srcFormat == PIX_FMT_YUYV422 && dstFormat == PIX_FMT_YUV422P)
+ c->swScale = yuyvToYuv422Wrapper;
+ if (srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P)
+ c->swScale = uyvyToYuv422Wrapper;
/* simple copy */
- if ( srcFormat == dstFormat
- || (srcFormat == PIX_FMT_YUVA420P && dstFormat == PIX_FMT_YUV420P)
- || (srcFormat == PIX_FMT_YUV420P && dstFormat == PIX_FMT_YUVA420P)
- || (isPlanarYUV(srcFormat) && isGray(dstFormat))
- || (isPlanarYUV(dstFormat) && isGray(srcFormat))
- || (isGray(dstFormat) && isGray(srcFormat))
- || (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat)
- && c->chrDstHSubSample == c->chrSrcHSubSample
- && c->chrDstVSubSample == c->chrSrcVSubSample
- && dstFormat != PIX_FMT_NV12 && dstFormat != PIX_FMT_NV21
- && srcFormat != PIX_FMT_NV12 && srcFormat != PIX_FMT_NV21))
+ if ( srcFormat == dstFormat ||
+ (srcFormat == PIX_FMT_YUVA420P && dstFormat == PIX_FMT_YUV420P) ||
+ (srcFormat == PIX_FMT_YUV420P && dstFormat == PIX_FMT_YUVA420P) ||
+ (isPlanarYUV(srcFormat) && isGray(dstFormat)) ||
+ (isPlanarYUV(dstFormat) && isGray(srcFormat)) ||
+ (isGray(dstFormat) && isGray(srcFormat)) ||
+ (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) &&
+ c->chrDstHSubSample == c->chrSrcHSubSample &&
+ c->chrDstVSubSample == c->chrSrcVSubSample &&
+ dstFormat != PIX_FMT_NV12 && dstFormat != PIX_FMT_NV21 &&
+ srcFormat != PIX_FMT_NV12 && srcFormat != PIX_FMT_NV21))
{
if (isPacked(c->srcFormat))
- c->swScale= packedCopyWrapper;
+ c->swScale = packedCopyWrapper;
else /* Planar YUV or gray */
- c->swScale= planarCopyWrapper;
+ c->swScale = planarCopyWrapper;
}
if (ARCH_BFIN)
@@ -702,15 +860,15 @@ void ff_get_unscaled_swscale(SwsContext *c)
ff_swscale_get_unscaled_altivec(c);
}
-static void reset_ptr(const uint8_t* src[], int format)
+static void reset_ptr(const uint8_t *src[], int format)
{
- if(!isALPHA(format))
- src[3]=NULL;
- if(!isPlanarYUV(format)) {
- src[3]=src[2]=NULL;
+ if (!isALPHA(format))
+ src[3] = NULL;
+ if (!isPlanar(format)) {
+ src[3] = src[2] = NULL;
if (!usePal(format))
- src[1]= NULL;
+ src[1] = NULL;
}
}
@@ -733,18 +891,21 @@ static int check_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt,
* swscale wrapper, so we don't need to export the SwsContext.
* Assumes planar YUV to be in YUV order instead of YVU.
*/
-int sws_scale(SwsContext *c, const uint8_t* const src[], const int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* const dst[], const int dstStride[])
+int attribute_align_arg sws_scale(struct SwsContext *c,
+ const uint8_t * const srcSlice[],
+ const int srcStride[], int srcSliceY,
+ int srcSliceH, uint8_t *const dst[],
+ const int dstStride[])
{
int i;
- const uint8_t* src2[4]= {src[0], src[1], src[2], src[3]};
- uint8_t* dst2[4]= {dst[0], dst[1], dst[2], dst[3]};
+ const uint8_t *src2[4] = { srcSlice[0], srcSlice[1], srcSlice[2], srcSlice[3] };
+ uint8_t *dst2[4] = { dst[0], dst[1], dst[2], dst[3] };
// do not mess up sliceDir if we have a "trailing" 0-size slice
if (srcSliceH == 0)
return 0;
- if (!check_image_pointers(src, c->srcFormat, srcStride)) {
+ if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {
av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
return 0;
}
@@ -762,63 +923,64 @@ int sws_scale(SwsContext *c, const uint8_t* const src[], const int srcStride[],
}
if (usePal(c->srcFormat)) {
- for (i=0; i<256; i++) {
- int p, r, g, b,y,u,v;
- if(c->srcFormat == PIX_FMT_PAL8) {
- p=((const uint32_t*)(src[1]))[i];
- r= (p>>16)&0xFF;
- g= (p>> 8)&0xFF;
- b= p &0xFF;
- } else if(c->srcFormat == PIX_FMT_RGB8) {
- r= (i>>5 )*36;
- g= ((i>>2)&7)*36;
- b= (i&3 )*85;
- } else if(c->srcFormat == PIX_FMT_BGR8) {
- b= (i>>6 )*85;
- g= ((i>>3)&7)*36;
- r= (i&7 )*36;
- } else if(c->srcFormat == PIX_FMT_RGB4_BYTE) {
- r= (i>>3 )*255;
- g= ((i>>1)&3)*85;
- b= (i&1 )*255;
- } else if(c->srcFormat == PIX_FMT_GRAY8 || c->srcFormat == PIX_FMT_Y400A) {
+ for (i = 0; i < 256; i++) {
+ int p, r, g, b, y, u, v;
+ if (c->srcFormat == PIX_FMT_PAL8) {
+ p = ((const uint32_t *)(srcSlice[1]))[i];
+ r = (p >> 16) & 0xFF;
+ g = (p >> 8) & 0xFF;
+ b = p & 0xFF;
+ } else if (c->srcFormat == PIX_FMT_RGB8) {
+ r = ( i >> 5 ) * 36;
+ g = ((i >> 2) & 7) * 36;
+ b = ( i & 3) * 85;
+ } else if (c->srcFormat == PIX_FMT_BGR8) {
+ b = ( i >> 6 ) * 85;
+ g = ((i >> 3) & 7) * 36;
+ r = ( i & 7) * 36;
+ } else if (c->srcFormat == PIX_FMT_RGB4_BYTE) {
+ r = ( i >> 3 ) * 255;
+ g = ((i >> 1) & 3) * 85;
+ b = ( i & 1) * 255;
+ } else if (c->srcFormat == PIX_FMT_GRAY8 ||
+ c->srcFormat == PIX_FMT_Y400A) {
r = g = b = i;
} else {
assert(c->srcFormat == PIX_FMT_BGR4_BYTE);
- b= (i>>3 )*255;
- g= ((i>>1)&3)*85;
- r= (i&1 )*255;
+ b = ( i >> 3 ) * 255;
+ g = ((i >> 1) & 3) * 85;
+ r = ( i & 1) * 255;
}
- y= av_clip_uint8((RY*r + GY*g + BY*b + ( 33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
- u= av_clip_uint8((RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
- v= av_clip_uint8((RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
- c->pal_yuv[i]= y + (u<<8) + (v<<16);
+ y = av_clip_uint8((RY * r + GY * g + BY * b + ( 33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+ u = av_clip_uint8((RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+ v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+ c->pal_yuv[i] = y + (u << 8) + (v << 16);
- switch(c->dstFormat) {
+ switch (c->dstFormat) {
case PIX_FMT_BGR32:
#if !HAVE_BIGENDIAN
case PIX_FMT_RGB24:
#endif
- c->pal_rgb[i]= r + (g<<8) + (b<<16);
+ c->pal_rgb[i] = r + (g << 8) + (b << 16);
break;
case PIX_FMT_BGR32_1:
#if HAVE_BIGENDIAN
case PIX_FMT_BGR24:
#endif
- c->pal_rgb[i]= (r + (g<<8) + (b<<16)) << 8;
+ c->pal_rgb[i] = (r + (g << 8) + (b << 16)) << 8;
break;
case PIX_FMT_RGB32_1:
#if HAVE_BIGENDIAN
case PIX_FMT_RGB24:
#endif
- c->pal_rgb[i]= (b + (g<<8) + (r<<16)) << 8;
+ c->pal_rgb[i] = (b + (g << 8) + (r << 16)) << 8;
break;
case PIX_FMT_RGB32:
#if !HAVE_BIGENDIAN
case PIX_FMT_BGR24:
#endif
default:
- c->pal_rgb[i]= b + (g<<8) + (r<<16);
+ c->pal_rgb[i] = b + (g << 8) + (r << 16);
}
}
}
@@ -826,62 +988,70 @@ int sws_scale(SwsContext *c, const uint8_t* const src[], const int srcStride[],
// copy strides, so they can safely be modified
if (c->sliceDir == 1) {
// slices go from top to bottom
- int srcStride2[4]= {srcStride[0], srcStride[1], srcStride[2], srcStride[3]};
- int dstStride2[4]= {dstStride[0], dstStride[1], dstStride[2], dstStride[3]};
+ int srcStride2[4] = { srcStride[0], srcStride[1], srcStride[2],
+ srcStride[3] };
+ int dstStride2[4] = { dstStride[0], dstStride[1], dstStride[2],
+ dstStride[3] };
reset_ptr(src2, c->srcFormat);
- reset_ptr((const uint8_t**)dst2, c->dstFormat);
+ reset_ptr((const uint8_t **) dst2, c->dstFormat);
/* reset slice direction at end of frame */
if (srcSliceY + srcSliceH == c->srcH)
c->sliceDir = 0;
- return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, dstStride2);
+ return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2,
+ dstStride2);
} else {
// slices go from bottom to top => we flip the image internally
- int srcStride2[4]= {-srcStride[0], -srcStride[1], -srcStride[2], -srcStride[3]};
- int dstStride2[4]= {-dstStride[0], -dstStride[1], -dstStride[2], -dstStride[3]};
+ int srcStride2[4] = { -srcStride[0], -srcStride[1], -srcStride[2],
+ -srcStride[3] };
+ int dstStride2[4] = { -dstStride[0], -dstStride[1], -dstStride[2],
+ -dstStride[3] };
- src2[0] += (srcSliceH-1)*srcStride[0];
+ src2[0] += (srcSliceH - 1) * srcStride[0];
if (!usePal(c->srcFormat))
- src2[1] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[1];
- src2[2] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[2];
- src2[3] += (srcSliceH-1)*srcStride[3];
- dst2[0] += ( c->dstH -1)*dstStride[0];
- dst2[1] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[1];
- dst2[2] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[2];
- dst2[3] += ( c->dstH -1)*dstStride[3];
+ src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
+ src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
+ src2[3] += (srcSliceH - 1) * srcStride[3];
+ dst2[0] += ( c->dstH - 1) * dstStride[0];
+ dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
+ dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
+ dst2[3] += ( c->dstH - 1) * dstStride[3];
reset_ptr(src2, c->srcFormat);
- reset_ptr((const uint8_t**)dst2, c->dstFormat);
+ reset_ptr((const uint8_t **) dst2, c->dstFormat);
/* reset slice direction at end of frame */
if (!srcSliceY)
c->sliceDir = 0;
- return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, srcSliceH, dst2, dstStride2);
+ return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH,
+ srcSliceH, dst2, dstStride2);
}
}
/* Convert the palette to the same packed 32-bit format as the palette */
-void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
+void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst,
+ int num_pixels, const uint8_t *palette)
{
int i;
- for (i=0; i<num_pixels; i++)
+ for (i = 0; i < num_pixels; i++)
((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
}
/* Palette format: ABCD -> dst format: ABC */
-void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
+void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst,
+ int num_pixels, const uint8_t *palette)
{
int i;
- for (i=0; i<num_pixels; i++) {
+ for (i = 0; i < num_pixels; i++) {
//FIXME slow?
- dst[0]= palette[src[i]*4+0];
- dst[1]= palette[src[i]*4+1];
- dst[2]= palette[src[i]*4+2];
- dst+= 3;
+ dst[0] = palette[src[i] * 4 + 0];
+ dst[1] = palette[src[i] * 4 + 1];
+ dst[2] = palette[src[i] * 4 + 2];
+ dst += 3;
}
}
diff --git a/libswscale/utils.c b/libswscale/utils.c
index ac22dfe..12b3202 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -65,125 +65,99 @@ const char *swscale_license(void)
#define RET 0xC3 //near return opcode for x86
-#define isSupportedIn(x) ( \
- (x)==PIX_FMT_YUV420P \
- || (x)==PIX_FMT_YUVA420P \
- || (x)==PIX_FMT_YUYV422 \
- || (x)==PIX_FMT_UYVY422 \
- || (x)==PIX_FMT_RGB48BE \
- || (x)==PIX_FMT_RGB48LE \
- || (x)==PIX_FMT_RGB32 \
- || (x)==PIX_FMT_RGB32_1 \
- || (x)==PIX_FMT_BGR48BE \
- || (x)==PIX_FMT_BGR48LE \
- || (x)==PIX_FMT_BGR24 \
- || (x)==PIX_FMT_BGR565LE \
- || (x)==PIX_FMT_BGR565BE \
- || (x)==PIX_FMT_BGR555LE \
- || (x)==PIX_FMT_BGR555BE \
- || (x)==PIX_FMT_BGR32 \
- || (x)==PIX_FMT_BGR32_1 \
- || (x)==PIX_FMT_RGB24 \
- || (x)==PIX_FMT_RGB565LE \
- || (x)==PIX_FMT_RGB565BE \
- || (x)==PIX_FMT_RGB555LE \
- || (x)==PIX_FMT_RGB555BE \
- || (x)==PIX_FMT_GRAY8 \
- || (x)==PIX_FMT_Y400A \
- || (x)==PIX_FMT_YUV410P \
- || (x)==PIX_FMT_YUV440P \
- || (x)==PIX_FMT_NV12 \
- || (x)==PIX_FMT_NV21 \
- || (x)==PIX_FMT_GRAY16BE \
- || (x)==PIX_FMT_GRAY16LE \
- || (x)==PIX_FMT_YUV444P \
- || (x)==PIX_FMT_YUV422P \
- || (x)==PIX_FMT_YUV411P \
- || (x)==PIX_FMT_YUVJ420P \
- || (x)==PIX_FMT_YUVJ422P \
- || (x)==PIX_FMT_YUVJ440P \
- || (x)==PIX_FMT_YUVJ444P \
- || (x)==PIX_FMT_PAL8 \
- || (x)==PIX_FMT_BGR8 \
- || (x)==PIX_FMT_RGB8 \
- || (x)==PIX_FMT_BGR4_BYTE \
- || (x)==PIX_FMT_RGB4_BYTE \
- || (x)==PIX_FMT_YUV440P \
- || (x)==PIX_FMT_MONOWHITE \
- || (x)==PIX_FMT_MONOBLACK \
- || (x)==PIX_FMT_YUV420P9LE \
- || (x)==PIX_FMT_YUV444P9LE \
- || (x)==PIX_FMT_YUV420P10LE \
- || (x)==PIX_FMT_YUV422P10LE \
- || (x)==PIX_FMT_YUV444P10LE \
- || (x)==PIX_FMT_YUV420P16LE \
- || (x)==PIX_FMT_YUV422P16LE \
- || (x)==PIX_FMT_YUV444P16LE \
- || (x)==PIX_FMT_YUV420P9BE \
- || (x)==PIX_FMT_YUV444P9BE \
- || (x)==PIX_FMT_YUV420P10BE \
- || (x)==PIX_FMT_YUV444P10BE \
- || (x)==PIX_FMT_YUV422P10BE \
- || (x)==PIX_FMT_YUV420P16BE \
- || (x)==PIX_FMT_YUV422P16BE \
- || (x)==PIX_FMT_YUV444P16BE \
- )
+typedef struct FormatEntry {
+ int is_supported_in, is_supported_out;
+} FormatEntry;
+
+const static FormatEntry format_entries[PIX_FMT_NB] = {
+ [PIX_FMT_YUV420P] = { 1 , 1 },
+ [PIX_FMT_YUYV422] = { 1 , 1 },
+ [PIX_FMT_RGB24] = { 1 , 1 },
+ [PIX_FMT_BGR24] = { 1 , 1 },
+ [PIX_FMT_YUV422P] = { 1 , 1 },
+ [PIX_FMT_YUV444P] = { 1 , 1 },
+ [PIX_FMT_YUV410P] = { 1 , 1 },
+ [PIX_FMT_YUV411P] = { 1 , 1 },
+ [PIX_FMT_GRAY8] = { 1 , 1 },
+ [PIX_FMT_MONOWHITE] = { 1 , 1 },
+ [PIX_FMT_MONOBLACK] = { 1 , 1 },
+ [PIX_FMT_PAL8] = { 1 , 0 },
+ [PIX_FMT_YUVJ420P] = { 1 , 1 },
+ [PIX_FMT_YUVJ422P] = { 1 , 1 },
+ [PIX_FMT_YUVJ444P] = { 1 , 1 },
+ [PIX_FMT_UYVY422] = { 1 , 1 },
+ [PIX_FMT_UYYVYY411] = { 0 , 0 },
+ [PIX_FMT_BGR8] = { 1 , 1 },
+ [PIX_FMT_BGR4] = { 0 , 1 },
+ [PIX_FMT_BGR4_BYTE] = { 1 , 1 },
+ [PIX_FMT_RGB8] = { 1 , 1 },
+ [PIX_FMT_RGB4] = { 0 , 1 },
+ [PIX_FMT_RGB4_BYTE] = { 1 , 1 },
+ [PIX_FMT_NV12] = { 1 , 1 },
+ [PIX_FMT_NV21] = { 1 , 1 },
+ [PIX_FMT_ARGB] = { 1 , 1 },
+ [PIX_FMT_RGBA] = { 1 , 1 },
+ [PIX_FMT_ABGR] = { 1 , 1 },
+ [PIX_FMT_BGRA] = { 1 , 1 },
+ [PIX_FMT_GRAY16BE] = { 1 , 1 },
+ [PIX_FMT_GRAY16LE] = { 1 , 1 },
+ [PIX_FMT_YUV440P] = { 1 , 1 },
+ [PIX_FMT_YUVJ440P] = { 1 , 1 },
+ [PIX_FMT_YUVA420P] = { 1 , 1 },
+ [PIX_FMT_RGB48BE] = { 1 , 1 },
+ [PIX_FMT_RGB48LE] = { 1 , 1 },
+ [PIX_FMT_RGB565BE] = { 1 , 1 },
+ [PIX_FMT_RGB565LE] = { 1 , 1 },
+ [PIX_FMT_RGB555BE] = { 1 , 1 },
+ [PIX_FMT_RGB555LE] = { 1 , 1 },
+ [PIX_FMT_BGR565BE] = { 1 , 1 },
+ [PIX_FMT_BGR565LE] = { 1 , 1 },
+ [PIX_FMT_BGR555BE] = { 1 , 1 },
+ [PIX_FMT_BGR555LE] = { 1 , 1 },
+ [PIX_FMT_YUV420P16LE] = { 1 , 1 },
+ [PIX_FMT_YUV420P16BE] = { 1 , 1 },
+ [PIX_FMT_YUV422P16LE] = { 1 , 1 },
+ [PIX_FMT_YUV422P16BE] = { 1 , 1 },
+ [PIX_FMT_YUV444P16LE] = { 1 , 1 },
+ [PIX_FMT_YUV444P16BE] = { 1 , 1 },
+ [PIX_FMT_RGB444LE] = { 0 , 1 },
+ [PIX_FMT_RGB444BE] = { 0 , 1 },
+ [PIX_FMT_BGR444LE] = { 0 , 1 },
+ [PIX_FMT_BGR444BE] = { 0 , 1 },
+ [PIX_FMT_Y400A] = { 1 , 0 },
+ [PIX_FMT_BGR48BE] = { 1 , 1 },
+ [PIX_FMT_BGR48LE] = { 1 , 1 },
+ [PIX_FMT_YUV420P9BE] = { 1 , 1 },
+ [PIX_FMT_YUV420P9LE] = { 1 , 1 },
+ [PIX_FMT_YUV420P10BE] = { 1 , 1 },
+ [PIX_FMT_YUV420P10LE] = { 1 , 1 },
+ [PIX_FMT_YUV422P9BE] = { 1 , 1 },
+ [PIX_FMT_YUV422P9LE] = { 1 , 1 },
+ [PIX_FMT_YUV422P10BE] = { 1 , 1 },
+ [PIX_FMT_YUV422P10LE] = { 1 , 1 },
+ [PIX_FMT_YUV444P9BE] = { 1 , 1 },
+ [PIX_FMT_YUV444P9LE] = { 1 , 1 },
+ [PIX_FMT_YUV444P10BE] = { 1 , 1 },
+ [PIX_FMT_YUV444P10LE] = { 1 , 1 },
+ [PIX_FMT_GBRP] = { 1 , 0 },
+ [PIX_FMT_GBRP9LE] = { 1 , 0 },
+ [PIX_FMT_GBRP9BE] = { 1 , 0 },
+ [PIX_FMT_GBRP10LE] = { 1 , 0 },
+ [PIX_FMT_GBRP10BE] = { 1 , 0 },
+ [PIX_FMT_GBRP16LE] = { 1 , 0 },
+ [PIX_FMT_GBRP16BE] = { 1 , 0 },
+};
int sws_isSupportedInput(enum PixelFormat pix_fmt)
{
- return isSupportedIn(pix_fmt);
+ return (unsigned)pix_fmt < PIX_FMT_NB ?
+ format_entries[pix_fmt].is_supported_in : 0;
}
-#define isSupportedOut(x) ( \
- (x)==PIX_FMT_YUV420P \
- || (x)==PIX_FMT_YUVA420P \
- || (x)==PIX_FMT_YUYV422 \
- || (x)==PIX_FMT_UYVY422 \
- || (x)==PIX_FMT_YUV444P \
- || (x)==PIX_FMT_YUV422P \
- || (x)==PIX_FMT_YUV411P \
- || (x)==PIX_FMT_YUVJ420P \
- || (x)==PIX_FMT_YUVJ422P \
- || (x)==PIX_FMT_YUVJ440P \
- || (x)==PIX_FMT_YUVJ444P \
- || isRGBinBytes(x) \
- || isBGRinBytes(x) \
- || (x)==PIX_FMT_RGB565 \
- || (x)==PIX_FMT_RGB555 \
- || (x)==PIX_FMT_RGB444 \
- || (x)==PIX_FMT_BGR565 \
- || (x)==PIX_FMT_BGR555 \
- || (x)==PIX_FMT_BGR444 \
- || (x)==PIX_FMT_RGB8 \
- || (x)==PIX_FMT_BGR8 \
- || (x)==PIX_FMT_RGB4_BYTE \
- || (x)==PIX_FMT_BGR4_BYTE \
- || (x)==PIX_FMT_RGB4 \
- || (x)==PIX_FMT_BGR4 \
- || (x)==PIX_FMT_MONOBLACK \
- || (x)==PIX_FMT_MONOWHITE \
- || (x)==PIX_FMT_NV12 \
- || (x)==PIX_FMT_NV21 \
- || (x)==PIX_FMT_GRAY16BE \
- || (x)==PIX_FMT_GRAY16LE \
- || (x)==PIX_FMT_GRAY8 \
- || (x)==PIX_FMT_YUV410P \
- || (x)==PIX_FMT_YUV440P \
- || (x)==PIX_FMT_YUV420P9LE \
- || (x)==PIX_FMT_YUV420P10LE \
- || (x)==PIX_FMT_YUV420P16LE \
- || (x)==PIX_FMT_YUV422P16LE \
- || (x)==PIX_FMT_YUV444P16LE \
- || (x)==PIX_FMT_YUV420P9BE \
- || (x)==PIX_FMT_YUV420P10BE \
- || (x)==PIX_FMT_YUV420P16BE \
- || (x)==PIX_FMT_YUV422P16BE \
- || (x)==PIX_FMT_YUV444P16BE \
- )
-
int sws_isSupportedOutput(enum PixelFormat pix_fmt)
{
- return isSupportedOut(pix_fmt);
+ return (unsigned)pix_fmt < PIX_FMT_NB ?
+ format_entries[pix_fmt].is_supported_out : 0;
}
extern const int32_t ff_yuv2rgb_coeffs[8][4];
@@ -208,7 +182,7 @@ static double getSplineCoeff(double a, double b, double c, double d, double dist
static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc,
int srcW, int dstW, int filterAlign, int one, int flags, int cpu_flags,
- SwsVector *srcFilter, SwsVector *dstFilter, double param[2])
+ SwsVector *srcFilter, SwsVector *dstFilter, double param[2], int is_horizontal)
{
int i;
int filterSize;
@@ -221,8 +195,8 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi
emms_c(); //FIXME this should not be required but it IS (even for non-MMX versions)
- // NOTE: the +1 is for the MMX scaler which reads over the end
- FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW+1)*sizeof(int16_t), fail);
+ // NOTE: the +3 is for the MMX(+1)/SSE(+3) scaler which reads over the end
+ FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW+3)*sizeof(int16_t), fail);
if (FFABS(xInc - 0x10000) <10) { // unscaled
int i;
@@ -310,15 +284,18 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi
if (flags & SWS_BICUBIC) {
int64_t B= (param[0] != SWS_PARAM_DEFAULT ? param[0] : 0) * (1<<24);
int64_t C= (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1<<24);
- int64_t dd = ( d*d)>>30;
- int64_t ddd= (dd*d)>>30;
- if (d < 1LL<<30)
- coeff = (12*(1<<24)-9*B-6*C)*ddd + (-18*(1<<24)+12*B+6*C)*dd + (6*(1<<24)-2*B)*(1<<30);
- else if (d < 1LL<<31)
- coeff = (-B-6*C)*ddd + (6*B+30*C)*dd + (-12*B-48*C)*d + (8*B+24*C)*(1<<30);
- else
- coeff=0.0;
+ if (d >= 1LL<<31) {
+ coeff = 0.0;
+ } else {
+ int64_t dd = (d * d) >> 30;
+ int64_t ddd = (dd * d) >> 30;
+
+ if (d < 1LL<<30)
+ coeff = (12*(1<<24)-9*B-6*C)*ddd + (-18*(1<<24)+12*B+6*C)*dd + (6*(1<<24)-2*B)*(1<<30);
+ else
+ coeff = (-B-6*C)*ddd + (6*B+30*C)*dd + (-12*B-48*C)*d + (8*B+24*C)*(1<<30);
+ }
coeff *= fone>>(30+24);
}
/* else if (flags & SWS_X) {
@@ -482,33 +459,35 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi
//FIXME try to align filterPos if possible
//fix borders
- for (i=0; i<dstW; i++) {
- int j;
- if ((*filterPos)[i] < 0) {
- // move filter coefficients left to compensate for filterPos
- for (j=1; j<filterSize; j++) {
- int left= FFMAX(j + (*filterPos)[i], 0);
- filter[i*filterSize + left] += filter[i*filterSize + j];
- filter[i*filterSize + j]=0;
+ if (is_horizontal) {
+ for (i = 0; i < dstW; i++) {
+ int j;
+ if ((*filterPos)[i] < 0) {
+ // move filter coefficients left to compensate for filterPos
+ for (j = 1; j < filterSize; j++) {
+ int left = FFMAX(j + (*filterPos)[i], 0);
+ filter[i * filterSize + left] += filter[i * filterSize + j];
+ filter[i * filterSize + j ] = 0;
+ }
+ (*filterPos)[i] = 0;
}
- (*filterPos)[i]= 0;
- }
- if ((*filterPos)[i] + filterSize > srcW) {
- int shift= (*filterPos)[i] + filterSize - srcW;
- // move filter coefficients right to compensate for filterPos
- for (j=filterSize-2; j>=0; j--) {
- int right= FFMIN(j + shift, filterSize-1);
- filter[i*filterSize +right] += filter[i*filterSize +j];
- filter[i*filterSize +j]=0;
+ if ((*filterPos)[i] + filterSize > srcW) {
+ int shift = (*filterPos)[i] + filterSize - srcW;
+ // move filter coefficients right to compensate for filterPos
+ for (j = filterSize - 2; j >= 0; j--) {
+ int right = FFMIN(j + shift, filterSize - 1);
+ filter[i * filterSize + right] += filter[i * filterSize + j];
+ filter[i * filterSize + j ] = 0;
+ }
+ (*filterPos)[i] = srcW - filterSize;
}
- (*filterPos)[i]= srcW - filterSize;
}
}
// Note the +1 is for the MMX scaler which reads over the end
/* align at 16 for AltiVec (needed by hScale_altivec_real) */
- FF_ALLOCZ_OR_GOTO(NULL, *outFilter, *outFilterSize*(dstW+1)*sizeof(int16_t), fail);
+ FF_ALLOCZ_OR_GOTO(NULL, *outFilter, *outFilterSize*(dstW+3)*sizeof(int16_t), fail);
/* normalize & store in outFilter */
for (i=0; i<dstW; i++) {
@@ -528,10 +507,14 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi
}
}
- (*filterPos)[dstW]= (*filterPos)[dstW-1]; // the MMX scaler will read over the end
+ (*filterPos)[dstW+0] =
+ (*filterPos)[dstW+1] =
+ (*filterPos)[dstW+2] = (*filterPos)[dstW-1]; // the MMX/SSE scaler will read over the end
for (i=0; i<*outFilterSize; i++) {
- int j= dstW*(*outFilterSize);
- (*outFilter)[j + i]= (*outFilter)[j + i - (*outFilterSize)];
+ int k= (dstW - 1) * (*outFilterSize) + i;
+ (*outFilter)[k + 1 * (*outFilterSize)] =
+ (*outFilter)[k + 2 * (*outFilterSize)] =
+ (*outFilter)[k + 3 * (*outFilterSize)] = (*outFilter)[k];
}
ret=0;
@@ -707,7 +690,9 @@ static void getSubSampleFactors(int *h, int *v, enum PixelFormat format)
*v = av_pix_fmt_descriptors[format].log2_chroma_h;
}
-int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation)
+int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
+ int srcRange, const int table[4], int dstRange,
+ int brightness, int contrast, int saturation)
{
memcpy(c->srcColorspaceTable, inv_table, sizeof(int)*4);
memcpy(c->dstColorspaceTable, table, sizeof(int)*4);
@@ -730,7 +715,9 @@ int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange
return 0;
}
-int sws_getColorspaceDetails(SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation)
+int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table,
+ int *srcRange, int **table, int *dstRange,
+ int *brightness, int *contrast, int *saturation)
{
if (isYUV(c->dstFormat) || isGray(c->dstFormat)) return -1;
@@ -788,11 +775,11 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
unscaled = (srcW == dstW && srcH == dstH);
- if (!isSupportedIn(srcFormat)) {
+ if (!sws_isSupportedInput(srcFormat)) {
av_log(c, AV_LOG_ERROR, "%s is not supported as input pixel format\n", sws_format_name(srcFormat));
return AVERROR(EINVAL);
}
- if (!isSupportedOut(dstFormat)) {
+ if (!sws_isSupportedOutput(dstFormat)) {
av_log(c, AV_LOG_ERROR, "%s is not supported as output pixel format\n", sws_format_name(dstFormat));
return AVERROR(EINVAL);
}
@@ -841,6 +828,19 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
getSubSampleFactors(&c->chrDstHSubSample, &c->chrDstVSubSample, dstFormat);
// reuse chroma for 2 pixels RGB/BGR unless user wants full chroma interpolation
+ if (flags & SWS_FULL_CHR_H_INT &&
+ dstFormat != PIX_FMT_RGBA &&
+ dstFormat != PIX_FMT_ARGB &&
+ dstFormat != PIX_FMT_BGRA &&
+ dstFormat != PIX_FMT_ABGR &&
+ dstFormat != PIX_FMT_RGB24 &&
+ dstFormat != PIX_FMT_BGR24) {
+ av_log(c, AV_LOG_ERROR,
+ "full chroma interpolation for destination format '%s' not yet implemented\n",
+ sws_format_name(dstFormat));
+ flags &= ~SWS_FULL_CHR_H_INT;
+ c->flags = flags;
+ }
if (isAnyRGB(dstFormat) && !(flags&SWS_FULL_CHR_H_INT)) c->chrDstHSubSample=1;
// drop some chroma lines if the user wants it
@@ -873,8 +873,18 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
}
}
- FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW, 16) * 2, fail);
- if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) {
+ c->srcBpc = 1 + av_pix_fmt_descriptors[srcFormat].comp[0].depth_minus1;
+ if (c->srcBpc < 8)
+ c->srcBpc = 8;
+ c->dstBpc = 1 + av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1;
+ if (c->dstBpc < 8)
+ c->dstBpc = 8;
+ if (c->dstBpc == 16)
+ dst_stride <<= 1;
+ FF_ALLOC_OR_GOTO(c, c->formatConvBuffer,
+ (FFALIGN(srcW, 16) * 2 * FFALIGN(c->srcBpc, 8) >> 3) + 16,
+ fail);
+ if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2 && c->srcBpc == 8 && c->dstBpc <= 10) {
c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;
if (!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR)) {
if (flags&SWS_PRINT_INFO)
@@ -950,12 +960,12 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
if (initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc,
srcW , dstW, filterAlign, 1<<14,
(flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags, cpu_flags,
- srcFilter->lumH, dstFilter->lumH, c->param) < 0)
+ srcFilter->lumH, dstFilter->lumH, c->param, 1) < 0)
goto fail;
if (initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc,
c->chrSrcW, c->chrDstW, filterAlign, 1<<14,
(flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags, cpu_flags,
- srcFilter->chrH, dstFilter->chrH, c->param) < 0)
+ srcFilter->chrH, dstFilter->chrH, c->param, 1) < 0)
goto fail;
}
} // initialize horizontal stuff
@@ -963,19 +973,19 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
/* precalculate vertical scaler filter coefficients */
{
const int filterAlign=
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) && (flags & SWS_ACCURATE_RND) ? 2 :
+ (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? 2 :
(HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 :
1;
if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc,
srcH , dstH, filterAlign, (1<<12),
(flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags, cpu_flags,
- srcFilter->lumV, dstFilter->lumV, c->param) < 0)
+ srcFilter->lumV, dstFilter->lumV, c->param, 0) < 0)
goto fail;
if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc,
c->chrSrcH, c->chrDstH, filterAlign, (1<<12),
(flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags, cpu_flags,
- srcFilter->chrV, dstFilter->chrV, c->param) < 0)
+ srcFilter->chrV, dstFilter->chrV, c->param, 0) < 0)
goto fail;
#if HAVE_ALTIVEC
@@ -1016,27 +1026,28 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
// allocate pixbufs (we use dynamic allocation because otherwise we would need to
// allocate several megabytes to handle all possible cases)
- FF_ALLOC_OR_GOTO(c, c->lumPixBuf, c->vLumBufSize*2*sizeof(int16_t*), fail);
- FF_ALLOC_OR_GOTO(c, c->chrUPixBuf, c->vChrBufSize*2*sizeof(int16_t*), fail);
- FF_ALLOC_OR_GOTO(c, c->chrVPixBuf, c->vChrBufSize*2*sizeof(int16_t*), fail);
+ FF_ALLOC_OR_GOTO(c, c->lumPixBuf, c->vLumBufSize*3*sizeof(int16_t*), fail);
+ FF_ALLOC_OR_GOTO(c, c->chrUPixBuf, c->vChrBufSize*3*sizeof(int16_t*), fail);
+ FF_ALLOC_OR_GOTO(c, c->chrVPixBuf, c->vChrBufSize*3*sizeof(int16_t*), fail);
if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat))
- FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf, c->vLumBufSize*2*sizeof(int16_t*), fail);
+ FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf, c->vLumBufSize*3*sizeof(int16_t*), fail);
//Note we need at least one pixel more at the end because of the MMX code (just in case someone wanna replace the 4000/8000)
/* align at 16 bytes for AltiVec */
for (i=0; i<c->vLumBufSize; i++) {
- FF_ALLOCZ_OR_GOTO(c, c->lumPixBuf[i+c->vLumBufSize], dst_stride+1, fail);
+ FF_ALLOCZ_OR_GOTO(c, c->lumPixBuf[i+c->vLumBufSize], dst_stride+16, fail);
c->lumPixBuf[i] = c->lumPixBuf[i+c->vLumBufSize];
}
- c->uv_off = dst_stride_px;
- c->uv_offx2 = dst_stride;
+ // 64 / (c->dstBpc & ~7) is the same as 16 / sizeof(scaling_intermediate)
+ c->uv_off_px = dst_stride_px + 64 / (c->dstBpc &~ 7);
+ c->uv_off_byte = dst_stride + 16;
for (i=0; i<c->vChrBufSize; i++) {
- FF_ALLOC_OR_GOTO(c, c->chrUPixBuf[i+c->vChrBufSize], dst_stride*2+1, fail);
+ FF_ALLOC_OR_GOTO(c, c->chrUPixBuf[i+c->vChrBufSize], dst_stride*2+32, fail);
c->chrUPixBuf[i] = c->chrUPixBuf[i+c->vChrBufSize];
- c->chrVPixBuf[i] = c->chrVPixBuf[i+c->vChrBufSize] = c->chrUPixBuf[i] + dst_stride_px;
+ c->chrVPixBuf[i] = c->chrVPixBuf[i+c->vChrBufSize] = c->chrUPixBuf[i] + (dst_stride >> 1) + 8;
}
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
for (i=0; i<c->vLumBufSize; i++) {
- FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf[i+c->vLumBufSize], dst_stride+1, fail);
+ FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf[i+c->vLumBufSize], dst_stride+16, fail);
c->alpPixBuf[i] = c->alpPixBuf[i+c->vLumBufSize];
}
@@ -1077,72 +1088,6 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
else if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) av_log(c, AV_LOG_INFO, "using AltiVec\n");
else av_log(c, AV_LOG_INFO, "using C\n");
- if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {
- if (c->canMMX2BeUsed && (flags&SWS_FAST_BILINEAR))
- av_log(c, AV_LOG_VERBOSE, "using FAST_BILINEAR MMX2 scaler for horizontal scaling\n");
- else {
- if (c->hLumFilterSize==4)
- av_log(c, AV_LOG_VERBOSE, "using 4-tap MMX scaler for horizontal luminance scaling\n");
- else if (c->hLumFilterSize==8)
- av_log(c, AV_LOG_VERBOSE, "using 8-tap MMX scaler for horizontal luminance scaling\n");
- else
- av_log(c, AV_LOG_VERBOSE, "using n-tap MMX scaler for horizontal luminance scaling\n");
-
- if (c->hChrFilterSize==4)
- av_log(c, AV_LOG_VERBOSE, "using 4-tap MMX scaler for horizontal chrominance scaling\n");
- else if (c->hChrFilterSize==8)
- av_log(c, AV_LOG_VERBOSE, "using 8-tap MMX scaler for horizontal chrominance scaling\n");
- else
- av_log(c, AV_LOG_VERBOSE, "using n-tap MMX scaler for horizontal chrominance scaling\n");
- }
- } else {
-#if HAVE_MMX
- av_log(c, AV_LOG_VERBOSE, "using x86 asm scaler for horizontal scaling\n");
-#else
- if (flags & SWS_FAST_BILINEAR)
- av_log(c, AV_LOG_VERBOSE, "using FAST_BILINEAR C scaler for horizontal scaling\n");
- else
- av_log(c, AV_LOG_VERBOSE, "using C scaler for horizontal scaling\n");
-#endif
- }
- if (isPlanarYUV(dstFormat)) {
- if (c->vLumFilterSize==1)
- av_log(c, AV_LOG_VERBOSE, "using 1-tap %s \"scaler\" for vertical scaling (YV12 like)\n",
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C");
- else
- av_log(c, AV_LOG_VERBOSE, "using n-tap %s scaler for vertical scaling (YV12 like)\n",
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C");
- } else {
- if (c->vLumFilterSize==1 && c->vChrFilterSize==2)
- av_log(c, AV_LOG_VERBOSE, "using 1-tap %s \"scaler\" for vertical luminance scaling (BGR)\n"
- " 2-tap scaler for vertical chrominance scaling (BGR)\n",
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C");
- else if (c->vLumFilterSize==2 && c->vChrFilterSize==2)
- av_log(c, AV_LOG_VERBOSE, "using 2-tap linear %s scaler for vertical scaling (BGR)\n",
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C");
- else
- av_log(c, AV_LOG_VERBOSE, "using n-tap %s scaler for vertical scaling (BGR)\n",
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C");
- }
-
- if (dstFormat==PIX_FMT_BGR24)
- av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR24 converter\n",
- (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) ? "MMX2" :
- ((HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C"));
- else if (dstFormat==PIX_FMT_RGB32)
- av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR32 converter\n",
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C");
- else if (dstFormat==PIX_FMT_BGR565)
- av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR16 converter\n",
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C");
- else if (dstFormat==PIX_FMT_BGR555)
- av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR15 converter\n",
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C");
- else if (dstFormat == PIX_FMT_RGB444BE || dstFormat == PIX_FMT_RGB444LE ||
- dstFormat == PIX_FMT_BGR444BE || dstFormat == PIX_FMT_BGR444LE)
- av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR12 converter\n",
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C");
-
av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
av_log(c, AV_LOG_DEBUG, "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
c->srcW, c->srcH, c->dstW, c->dstH, c->lumXInc, c->lumYInc);
diff --git a/libswscale/x86/scale.asm b/libswscale/x86/scale.asm
new file mode 100644
index 0000000..1f5e1db
--- /dev/null
+++ b/libswscale/x86/scale.asm
@@ -0,0 +1,809 @@
+;******************************************************************************
+;* x86-optimized horizontal/vertical line scaling functions
+;* Copyright (c) 2011 Ronald S. Bultje <rsbultje at gmail.com>
+;* Kieran Kunhya <kieran at kunhya.com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "x86inc.asm"
+%include "x86util.asm"
+
+SECTION_RODATA
+
+max_19bit_int: times 4 dd 0x7ffff
+max_19bit_flt: times 4 dd 524287.0
+minshort: times 8 dw 0x8000
+unicoeff: times 4 dd 0x20000000
+yuv2yuvX_16_start: times 4 dd 0x4000 - 0x40000000
+yuv2yuvX_10_start: times 4 dd 0x10000
+yuv2yuvX_9_start: times 4 dd 0x20000
+yuv2yuvX_10_upper: times 8 dw 0x3ff
+yuv2yuvX_9_upper: times 8 dw 0x1ff
+pd_4: times 4 dd 4
+pd_4min0x40000:times 4 dd 4 - (0x40000)
+pw_16: times 8 dw 16
+pw_32: times 8 dw 32
+pw_512: times 8 dw 512
+pw_1024: times 8 dw 1024
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+; horizontal line scaling
+;
+; void hscale<source_width>to<intermediate_nbits>_<filterSize>_<opt>
+; (SwsContext *c, int{16,32}_t *dst,
+; int dstW, const uint{8,16}_t *src,
+; const int16_t *filter,
+; const int16_t *filterPos, int filterSize);
+;
+; Scale one horizontal line. Input is either 8-bits width or 16-bits width
+; ($source_width can be either 8, 9, 10 or 16, difference is whether we have to
+; downscale before multiplying). Filter is 14-bits. Output is either 15bits
+; (in int16_t) or 19bits (in int32_t), as given in $intermediate_nbits. Each
+; output pixel is generated from $filterSize input pixels, the position of
+; the first pixel is given in filterPos[nOutputPixel].
+;-----------------------------------------------------------------------------
+
+; SCALE_FUNC source_width, intermediate_nbits, filtersize, filtersuffix, opt, n_args, n_xmm
+%macro SCALE_FUNC 7
+cglobal hscale%1to%2_%4_%5, %6, 7, %7
+%ifdef ARCH_X86_64
+ movsxd r2, r2d
+%endif ; x86-64
+%if %2 == 19
+%if mmsize == 8 ; mmx
+ mova m2, [max_19bit_int]
+%elifidn %5, sse4
+ mova m2, [max_19bit_int]
+%else ; ssse3/sse2
+ mova m2, [max_19bit_flt]
+%endif ; mmx/sse2/ssse3/sse4
+%endif ; %2 == 19
+%if %1 == 16
+ mova m6, [minshort]
+ mova m7, [unicoeff]
+%elif %1 == 8
+ pxor m3, m3
+%endif ; %1 == 8/16
+
+%if %1 == 8
+%define movlh movd
+%define movbh movh
+%define srcmul 1
+%else ; %1 == 9-16
+%define movlh movq
+%define movbh movu
+%define srcmul 2
+%endif ; %1 == 8/9-16
+
+%ifnidn %3, X
+
+ ; setup loop
+%if %3 == 8
+ shl r2, 1 ; this allows *16 (i.e. now *8) in lea instructions for the 8-tap filter
+%define r2shr 1
+%else ; %3 == 4
+%define r2shr 0
+%endif ; %3 == 8
+ lea r4, [r4+r2*8]
+%if %2 == 15
+ lea r1, [r1+r2*(2>>r2shr)]
+%else ; %2 == 19
+ lea r1, [r1+r2*(4>>r2shr)]
+%endif ; %2 == 15/19
+ lea r5, [r5+r2*(2>>r2shr)]
+ neg r2
+
+.loop:
+%if %3 == 4 ; filterSize == 4 scaling
+ ; load 2x4 or 4x4 source pixels into m0/m1
+ movsx r0, word [r5+r2*2+0] ; filterPos[0]
+ movsx r6, word [r5+r2*2+2] ; filterPos[1]
+ movlh m0, [r3+r0*srcmul] ; src[filterPos[0] + {0,1,2,3}]
+%if mmsize == 8
+ movlh m1, [r3+r6*srcmul] ; src[filterPos[1] + {0,1,2,3}]
+%else ; mmsize == 16
+%if %1 > 8
+ movhps m0, [r3+r6*srcmul] ; src[filterPos[1] + {0,1,2,3}]
+%else ; %1 == 8
+ movd m4, [r3+r6*srcmul] ; src[filterPos[1] + {0,1,2,3}]
+%endif
+ movsx r0, word [r5+r2*2+4] ; filterPos[2]
+ movsx r6, word [r5+r2*2+6] ; filterPos[3]
+ movlh m1, [r3+r0*srcmul] ; src[filterPos[2] + {0,1,2,3}]
+%if %1 > 8
+ movhps m1, [r3+r6*srcmul] ; src[filterPos[3] + {0,1,2,3}]
+%else ; %1 == 8
+ movd m5, [r3+r6*srcmul] ; src[filterPos[3] + {0,1,2,3}]
+ punpckldq m0, m4
+ punpckldq m1, m5
+%endif ; %1 == 8 && %5 <= ssse
+%endif ; mmsize == 8/16
+%if %1 == 8
+ punpcklbw m0, m3 ; byte -> word
+ punpcklbw m1, m3 ; byte -> word
+%endif ; %1 == 8
+
+ ; multiply with filter coefficients
+%if %1 == 16 ; pmaddwd needs signed adds, so this moves unsigned -> signed, we'll
+ ; add back 0x8000 * sum(coeffs) after the horizontal add
+ psubw m0, m6
+ psubw m1, m6
+%endif ; %1 == 16
+ pmaddwd m0, [r4+r2*8+mmsize*0] ; *= filter[{0,1,..,6,7}]
+ pmaddwd m1, [r4+r2*8+mmsize*1] ; *= filter[{8,9,..,14,15}]
+
+ ; add up horizontally (4 srcpix * 4 coefficients -> 1 dstpix)
+%if mmsize == 8 ; mmx
+ movq m4, m0
+ punpckldq m0, m1
+ punpckhdq m4, m1
+ paddd m0, m4
+%elifidn %5, sse2
+ mova m4, m0
+ shufps m0, m1, 10001000b
+ shufps m4, m1, 11011101b
+ paddd m0, m4
+%else ; ssse3/sse4
+ phaddd m0, m1 ; filter[{ 0, 1, 2, 3}]*src[filterPos[0]+{0,1,2,3}],
+ ; filter[{ 4, 5, 6, 7}]*src[filterPos[1]+{0,1,2,3}],
+ ; filter[{ 8, 9,10,11}]*src[filterPos[2]+{0,1,2,3}],
+ ; filter[{12,13,14,15}]*src[filterPos[3]+{0,1,2,3}]
+%endif ; mmx/sse2/ssse3/sse4
+%else ; %3 == 8, i.e. filterSize == 8 scaling
+ ; load 2x8 or 4x8 source pixels into m0, m1, m4 and m5
+ movsx r0, word [r5+r2*1+0] ; filterPos[0]
+ movsx r6, word [r5+r2*1+2] ; filterPos[1]
+ movbh m0, [r3+ r0 *srcmul] ; src[filterPos[0] + {0,1,2,3,4,5,6,7}]
+%if mmsize == 8
+ movbh m1, [r3+(r0+4)*srcmul] ; src[filterPos[0] + {4,5,6,7}]
+ movbh m4, [r3+ r6 *srcmul] ; src[filterPos[1] + {0,1,2,3}]
+ movbh m5, [r3+(r6+4)*srcmul] ; src[filterPos[1] + {4,5,6,7}]
+%else ; mmsize == 16
+ movbh m1, [r3+ r6 *srcmul] ; src[filterPos[1] + {0,1,2,3,4,5,6,7}]
+ movsx r0, word [r5+r2*1+4] ; filterPos[2]
+ movsx r6, word [r5+r2*1+6] ; filterPos[3]
+ movbh m4, [r3+ r0 *srcmul] ; src[filterPos[2] + {0,1,2,3,4,5,6,7}]
+ movbh m5, [r3+ r6 *srcmul] ; src[filterPos[3] + {0,1,2,3,4,5,6,7}]
+%endif ; mmsize == 8/16
+%if %1 == 8
+ punpcklbw m0, m3 ; byte -> word
+ punpcklbw m1, m3 ; byte -> word
+ punpcklbw m4, m3 ; byte -> word
+ punpcklbw m5, m3 ; byte -> word
+%endif ; %1 == 8
+
+ ; multiply
+%if %1 == 16 ; pmaddwd needs signed adds, so this moves unsigned -> signed, we'll
+ ; add back 0x8000 * sum(coeffs) after the horizontal add
+ psubw m0, m6
+ psubw m1, m6
+ psubw m4, m6
+ psubw m5, m6
+%endif ; %1 == 16
+ pmaddwd m0, [r4+r2*8+mmsize*0] ; *= filter[{0,1,..,6,7}]
+ pmaddwd m1, [r4+r2*8+mmsize*1] ; *= filter[{8,9,..,14,15}]
+ pmaddwd m4, [r4+r2*8+mmsize*2] ; *= filter[{16,17,..,22,23}]
+ pmaddwd m5, [r4+r2*8+mmsize*3] ; *= filter[{24,25,..,30,31}]
+
+ ; add up horizontally (8 srcpix * 8 coefficients -> 1 dstpix)
+%if mmsize == 8
+ paddd m0, m1
+ paddd m4, m5
+ movq m1, m0
+ punpckldq m0, m4
+ punpckhdq m1, m4
+ paddd m0, m1
+%elifidn %5, sse2
+%if %1 == 8
+%define mex m6
+%else
+%define mex m3
+%endif
+ ; emulate horizontal add as transpose + vertical add
+ mova mex, m0
+ punpckldq m0, m1
+ punpckhdq mex, m1
+ paddd m0, mex
+ mova m1, m4
+ punpckldq m4, m5
+ punpckhdq m1, m5
+ paddd m4, m1
+ mova m1, m0
+ punpcklqdq m0, m4
+ punpckhqdq m1, m4
+ paddd m0, m1
+%else ; ssse3/sse4
+ ; FIXME if we rearrange the filter in pairs of 4, we can
+ ; load pixels likewise and use 2 x paddd + phaddd instead
+ ; of 3 x phaddd here, faster on older cpus
+ phaddd m0, m1
+ phaddd m4, m5
+ phaddd m0, m4 ; filter[{ 0, 1,..., 6, 7}]*src[filterPos[0]+{0,1,...,6,7}],
+ ; filter[{ 8, 9,...,14,15}]*src[filterPos[1]+{0,1,...,6,7}],
+ ; filter[{16,17,...,22,23}]*src[filterPos[2]+{0,1,...,6,7}],
+ ; filter[{24,25,...,30,31}]*src[filterPos[3]+{0,1,...,6,7}]
+%endif ; mmx/sse2/ssse3/sse4
+%endif ; %3 == 4/8
+
+%else ; %3 == X, i.e. any filterSize scaling
+
+%ifidn %4, X4
+%define r6sub 4
+%else ; %4 == X || %4 == X8
+%define r6sub 0
+%endif ; %4 ==/!= X4
+%ifdef ARCH_X86_64
+ push r12
+ movsxd r6, r6d ; filterSize
+ lea r12, [r3+(r6-r6sub)*srcmul] ; &src[filterSize&~4]
+%define src_reg r11
+%define r1x r10
+%define filter2 r12
+%else ; x86-32
+ lea r0, [r3+(r6-r6sub)*srcmul] ; &src[filterSize&~4]
+ mov r6m, r0
+%define src_reg r3
+%define r1x r1
+%define filter2 r6m
+%endif ; x86-32/64
+ lea r5, [r5+r2*2]
+%if %2 == 15
+ lea r1, [r1+r2*2]
+%else ; %2 == 19
+ lea r1, [r1+r2*4]
+%endif ; %2 == 15/19
+ movifnidn r1mp, r1
+ neg r2
+
+.loop:
+ movsx r0, word [r5+r2*2+0] ; filterPos[0]
+ movsx r1x, word [r5+r2*2+2] ; filterPos[1]
+ ; FIXME maybe do 4px/iteration on x86-64 (x86-32 wouldn't have enough regs)?
+ pxor m4, m4
+ pxor m5, m5
+ mov src_reg, r3mp
+
+.innerloop:
+ ; load 2x4 (mmx) or 2x8 (sse) source pixels into m0/m1 -> m4/m5
+ movbh m0, [src_reg+r0 *srcmul] ; src[filterPos[0] + {0,1,2,3(,4,5,6,7)}]
+ movbh m1, [src_reg+(r1x+r6sub)*srcmul] ; src[filterPos[1] + {0,1,2,3(,4,5,6,7)}]
+%if %1 == 8
+ punpcklbw m0, m3
+ punpcklbw m1, m3
+%endif ; %1 == 8
+
+ ; multiply
+%if %1 == 16 ; pmaddwd needs signed adds, so this moves unsigned -> signed, we'll
+ ; add back 0x8000 * sum(coeffs) after the horizontal add
+ psubw m0, m6
+ psubw m1, m6
+%endif ; %1 == 16
+ pmaddwd m0, [r4 ] ; filter[{0,1,2,3(,4,5,6,7)}]
+ pmaddwd m1, [r4+(r6+r6sub)*2] ; filter[filtersize+{0,1,2,3(,4,5,6,7)}]
+ paddd m4, m0
+ paddd m5, m1
+ add r4, mmsize
+ add src_reg, srcmul*mmsize/2
+ cmp src_reg, filter2 ; while (src += 4) < &src[filterSize]
+ jl .innerloop
+
+%ifidn %4, X4
+ movsx r1x, word [r5+r2*2+2] ; filterPos[1]
+ movlh m0, [src_reg+r0 *srcmul] ; split last 4 srcpx of dstpx[0]
+ sub r1x, r6 ; and first 4 srcpx of dstpx[1]
+%if %1 > 8
+ movhps m0, [src_reg+(r1x+r6sub)*srcmul]
+%else ; %1 == 8
+ movd m1, [src_reg+(r1x+r6sub)*srcmul]
+ punpckldq m0, m1
+%endif ; %1 == 8 && %5 <= ssse
+%if %1 == 8
+ punpcklbw m0, m3
+%endif ; %1 == 8
+%if %1 == 16 ; pmaddwd needs signed adds, so this moves unsigned -> signed, we'll
+ ; add back 0x8000 * sum(coeffs) after the horizontal add
+ psubw m0, m6
+%endif ; %1 == 16
+ pmaddwd m0, [r4]
+%endif ; %4 == X4
+
+ lea r4, [r4+(r6+r6sub)*2]
+
+%if mmsize == 8 ; mmx
+ movq m0, m4
+ punpckldq m4, m5
+ punpckhdq m0, m5
+ paddd m0, m4
+%else ; mmsize == 16
+%ifidn %5, sse2
+ mova m1, m4
+ punpcklqdq m4, m5
+ punpckhqdq m1, m5
+ paddd m4, m1
+%else ; ssse3/sse4
+ phaddd m4, m5
+%endif ; sse2/ssse3/sse4
+%ifidn %4, X4
+ paddd m4, m0
+%endif ; %3 == X4
+%ifidn %5, sse2
+ pshufd m4, m4, 11011000b
+ movhlps m0, m4
+ paddd m0, m4
+%else ; ssse3/sse4
+ phaddd m4, m4
+ SWAP 0, 4
+%endif ; sse2/ssse3/sse4
+%endif ; mmsize == 8/16
+%endif ; %3 ==/!= X
+
+%if %1 == 16 ; add 0x8000 * sum(coeffs), i.e. back from signed -> unsigned
+ paddd m0, m7
+%endif ; %1 == 16
+
+ ; clip, store
+ psrad m0, 14 + %1 - %2
+%ifidn %3, X
+ movifnidn r1, r1mp
+%endif ; %3 == X
+%if %2 == 15
+ packssdw m0, m0
+%ifnidn %3, X
+ movh [r1+r2*(2>>r2shr)], m0
+%else ; %3 == X
+ movd [r1+r2*2], m0
+%endif ; %3 ==/!= X
+%else ; %2 == 19
+%if mmsize == 8
+ PMINSD_MMX m0, m2, m4
+%elifidn %5, sse4
+ pminsd m0, m2
+%else ; sse2/ssse3
+ cvtdq2ps m0, m0
+ minps m0, m2
+ cvtps2dq m0, m0
+%endif ; mmx/sse2/ssse3/sse4
+%ifnidn %3, X
+ mova [r1+r2*(4>>r2shr)], m0
+%else ; %3 == X
+ movq [r1+r2*4], m0
+%endif ; %3 ==/!= X
+%endif ; %2 == 15/19
+%ifnidn %3, X
+ add r2, (mmsize<<r2shr)/4 ; both 8tap and 4tap really only do 4 pixels (or for mmx: 2 pixels)
+ ; per iteration. see "shl r2,1" above as for why we do this
+%else ; %3 == X
+ add r2, 2
+%endif ; %3 ==/!= X
+ jl .loop
+%ifnidn %3, X
+ REP_RET
+%else ; %3 == X
+%ifdef ARCH_X86_64
+ pop r12
+ RET
+%else ; x86-32
+ REP_RET
+%endif ; x86-32/64
+%endif ; %3 ==/!= X
+%endmacro
+
+; SCALE_FUNCS source_width, intermediate_nbits, opt, n_xmm
+%macro SCALE_FUNCS 4
+SCALE_FUNC %1, %2, 4, 4, %3, 6, %4
+SCALE_FUNC %1, %2, 8, 8, %3, 6, %4
+%if mmsize == 8
+SCALE_FUNC %1, %2, X, X, %3, 7, %4
+%else
+SCALE_FUNC %1, %2, X, X4, %3, 7, %4
+SCALE_FUNC %1, %2, X, X8, %3, 7, %4
+%endif
+%endmacro
+
+; SCALE_FUNCS2 opt, 8_xmm_args, 9to10_xmm_args, 16_xmm_args
+%macro SCALE_FUNCS2 4
+%ifnidn %1, sse4
+SCALE_FUNCS 8, 15, %1, %2
+SCALE_FUNCS 9, 15, %1, %3
+SCALE_FUNCS 10, 15, %1, %3
+SCALE_FUNCS 16, 15, %1, %4
+%endif ; !sse4
+SCALE_FUNCS 8, 19, %1, %2
+SCALE_FUNCS 9, 19, %1, %3
+SCALE_FUNCS 10, 19, %1, %3
+SCALE_FUNCS 16, 19, %1, %4
+%endmacro
+
+%ifdef ARCH_X86_32
+INIT_MMX
+SCALE_FUNCS2 mmx, 0, 0, 0
+%endif
+INIT_XMM
+SCALE_FUNCS2 sse2, 6, 7, 8
+SCALE_FUNCS2 ssse3, 6, 6, 8
+SCALE_FUNCS2 sse4, 6, 6, 8
+
+;-----------------------------------------------------------------------------
+; vertical line scaling
+;
+; void yuv2plane1_<output_size>_<opt>(const int16_t *src, uint8_t *dst, int dstW,
+; const uint8_t *dither, int offset)
+; and
+; void yuv2planeX_<output_size>_<opt>(const int16_t *filter, int filterSize,
+; const int16_t **src, uint8_t *dst, int dstW,
+; const uint8_t *dither, int offset)
+;
+; Scale one or $filterSize lines of source data to generate one line of output
+; data. The input is 15-bit in int16_t if $output_size is [8,10] and 19-bit in
+; int32_t if $output_size is 16. $filter is 12-bits. $filterSize is a multiple
+; of 2. $offset is either 0 or 3. $dither holds 8 values.
+;-----------------------------------------------------------------------------
+
+%macro yuv2planeX_fn 4
+
+%ifdef ARCH_X86_32
+%define cntr_reg r1
+%define movsx mov
+%else
+%define cntr_reg r11
+%define movsx movsxd
+%endif
+
+cglobal yuv2planeX_%2_%1, %4, 7, %3
+%if %2 == 8 || %2 == 9 || %2 == 10
+ pxor m6, m6
+%endif ; %2 == 8/9/10
+
+%if %2 == 8
+%ifdef ARCH_X86_32
+%assign pad 0x2c - (stack_offset & 15)
+ SUB rsp, pad
+%define m_dith m7
+%else ; x86-64
+%define m_dith m9
+%endif ; x86-32
+
+ ; create registers holding dither
+ movq m_dith, [r5] ; dither
+ test r6d, r6d
+ jz .no_rot
+%if mmsize == 16
+ punpcklqdq m_dith, m_dith
+%endif ; mmsize == 16
+ PALIGNR m_dith, m_dith, 3, m0
+.no_rot:
+%if mmsize == 16
+ punpcklbw m_dith, m6
+%ifdef ARCH_X86_64
+ punpcklwd m8, m_dith, m6
+ pslld m8, 12
+%else ; x86-32
+ punpcklwd m5, m_dith, m6
+ pslld m5, 12
+%endif ; x86-32/64
+ punpckhwd m_dith, m6
+ pslld m_dith, 12
+%ifdef ARCH_X86_32
+ mova [rsp+ 0], m5
+ mova [rsp+16], m_dith
+%endif
+%else ; mmsize == 8
+ punpcklbw m5, m_dith, m6
+ punpckhbw m_dith, m6
+ punpcklwd m4, m5, m6
+ punpckhwd m5, m6
+ punpcklwd m3, m_dith, m6
+ punpckhwd m_dith, m6
+ pslld m4, 12
+ pslld m5, 12
+ pslld m3, 12
+ pslld m_dith, 12
+ mova [rsp+ 0], m4
+ mova [rsp+ 8], m5
+ mova [rsp+16], m3
+ mova [rsp+24], m_dith
+%endif ; mmsize == 8/16
+%endif ; %2 == 8
+
+ xor r5, r5
+
+.pixelloop:
+%assign %%i 0
+ ; the rep here is for the 8bit output mmx case, where dither covers
+ ; 8 pixels but we can only handle 2 pixels per register, and thus 4
+ ; pixels per iteration. In order to not have to keep track of where
+ ; we are w.r.t. dithering, we unroll the mmx/8bit loop x2.
+%if %2 == 8
+%rep 16/mmsize
+%endif ; %2 == 8
+
+%if %2 == 8
+%ifdef ARCH_X86_32
+ mova m2, [rsp+mmsize*(0+%%i)]
+ mova m1, [rsp+mmsize*(1+%%i)]
+%else ; x86-64
+ mova m2, m8
+ mova m1, m_dith
+%endif ; x86-32/64
+%else ; %2 == 9/10/16
+ mova m1, [yuv2yuvX_%2_start]
+ mova m2, m1
+%endif ; %2 == 8/9/10/16
+ movsx cntr_reg, r1m
+.filterloop_ %+ %%i:
+ ; input pixels
+ mov r6, [r2+gprsize*cntr_reg-2*gprsize]
+%if %2 == 16
+ mova m3, [r6+r5*4]
+ mova m5, [r6+r5*4+mmsize]
+%else ; %2 == 8/9/10
+ mova m3, [r6+r5*2]
+%endif ; %2 == 8/9/10/16
+ mov r6, [r2+gprsize*cntr_reg-gprsize]
+%if %2 == 16
+ mova m4, [r6+r5*4]
+ mova m6, [r6+r5*4+mmsize]
+%else ; %2 == 8/9/10
+ mova m4, [r6+r5*2]
+%endif ; %2 == 8/9/10/16
+
+ ; coefficients
+ movd m0, [r0+2*cntr_reg-4]; coeff[0], coeff[1]
+%if %2 == 16
+ pshuflw m7, m0, 0 ; coeff[0]
+ pshuflw m0, m0, 0x55 ; coeff[1]
+ pmovsxwd m7, m7 ; word -> dword
+ pmovsxwd m0, m0 ; word -> dword
+
+ pmulld m3, m7
+ pmulld m5, m7
+ pmulld m4, m0
+ pmulld m6, m0
+
+ paddd m2, m3
+ paddd m1, m5
+ paddd m2, m4
+ paddd m1, m6
+%else ; %2 == 10/9/8
+ punpcklwd m5, m3, m4
+ punpckhwd m3, m4
+ SPLATD m0, m0
+
+ pmaddwd m5, m0
+ pmaddwd m3, m0
+
+ paddd m2, m5
+ paddd m1, m3
+%endif ; %2 == 8/9/10/16
+
+ sub cntr_reg, 2
+ jg .filterloop_ %+ %%i
+
+%if %2 == 16
+ psrad m2, 31 - %2
+ psrad m1, 31 - %2
+%else ; %2 == 10/9/8
+ psrad m2, 27 - %2
+ psrad m1, 27 - %2
+%endif ; %2 == 8/9/10/16
+
+%if %2 == 8
+ packssdw m2, m1
+ packuswb m2, m2
+ movh [r3+r5*1], m2
+%else ; %2 == 9/10/16
+%if %2 == 16
+ packssdw m2, m1
+ paddw m2, [minshort]
+%else ; %2 == 9/10
+%ifidn %1, sse4
+ packusdw m2, m1
+%elifidn %1, avx
+ packusdw m2, m1
+%else ; mmx2/sse2
+ packssdw m2, m1
+ pmaxsw m2, m6
+%endif ; mmx2/sse2/sse4/avx
+ pminsw m2, [yuv2yuvX_%2_upper]
+%endif ; %2 == 9/10/16
+ mova [r3+r5*2], m2
+%endif ; %2 == 8/9/10/16
+
+ add r5, mmsize/2
+ sub r4d, mmsize/2
+%if %2 == 8
+%assign %%i %%i+2
+%endrep
+%endif ; %2 == 8
+ jg .pixelloop
+
+%if %2 == 8
+%ifdef ARCH_X86_32
+ ADD rsp, pad
+ RET
+%else ; x86-64
+ REP_RET
+%endif ; x86-32/64
+%else ; %2 == 9/10/16
+ REP_RET
+%endif ; %2 == 8/9/10/16
+%endmacro
+
+%define PALIGNR PALIGNR_MMX
+%ifdef ARCH_X86_32
+INIT_MMX
+yuv2planeX_fn mmx2, 8, 0, 7
+yuv2planeX_fn mmx2, 9, 0, 5
+yuv2planeX_fn mmx2, 10, 0, 5
+%endif
+
+INIT_XMM
+yuv2planeX_fn sse2, 8, 10, 7
+yuv2planeX_fn sse2, 9, 7, 5
+yuv2planeX_fn sse2, 10, 7, 5
+
+%define PALIGNR PALIGNR_SSSE3
+yuv2planeX_fn sse4, 8, 10, 7
+yuv2planeX_fn sse4, 9, 7, 5
+yuv2planeX_fn sse4, 10, 7, 5
+yuv2planeX_fn sse4, 16, 8, 5
+
+INIT_AVX
+yuv2planeX_fn avx, 8, 10, 7
+yuv2planeX_fn avx, 9, 7, 5
+yuv2planeX_fn avx, 10, 7, 5
+
+; %1=outout-bpc, %2=alignment (u/a)
+%macro yuv2plane1_mainloop 2
+.loop_%2:
+%if %1 == 8
+ paddsw m0, m2, [r0+r2*2+mmsize*0]
+ paddsw m1, m3, [r0+r2*2+mmsize*1]
+ psraw m0, 7
+ psraw m1, 7
+ packuswb m0, m1
+ mov%2 [r1+r2], m0
+%elif %1 == 16
+ paddd m0, m4, [r0+r2*4+mmsize*0]
+ paddd m1, m4, [r0+r2*4+mmsize*1]
+ paddd m2, m4, [r0+r2*4+mmsize*2]
+ paddd m3, m4, [r0+r2*4+mmsize*3]
+ psrad m0, 3
+ psrad m1, 3
+ psrad m2, 3
+ psrad m3, 3
+%if cpuflag(sse4) ; avx/sse4
+ packusdw m0, m1
+ packusdw m2, m3
+%else ; mmx/sse2
+ packssdw m0, m1
+ packssdw m2, m3
+ paddw m0, m5
+ paddw m2, m5
+%endif ; mmx/sse2/sse4/avx
+ mov%2 [r1+r2*2], m0
+ mov%2 [r1+r2*2+mmsize], m2
+%else
+ paddsw m0, m2, [r0+r2*2+mmsize*0]
+ paddsw m1, m2, [r0+r2*2+mmsize*1]
+ psraw m0, 15 - %1
+ psraw m1, 15 - %1
+ pmaxsw m0, m4
+ pmaxsw m1, m4
+ pminsw m0, m3
+ pminsw m1, m3
+ mov%2 [r1+r2*2], m0
+ mov%2 [r1+r2*2+mmsize], m1
+%endif
+ add r2, mmsize
+ jl .loop_%2
+%endmacro
+
+%macro yuv2plane1_fn 3
+cglobal yuv2plane1_%1, %3, %3, %2
+ add r2, mmsize - 1
+ and r2, ~(mmsize - 1)
+%if %1 == 8
+ add r1, r2
+%else ; %1 != 8
+ lea r1, [r1+r2*2]
+%endif ; %1 == 8
+%if %1 == 16
+ lea r0, [r0+r2*4]
+%else ; %1 != 16
+ lea r0, [r0+r2*2]
+%endif ; %1 == 16
+ neg r2
+
+%if %1 == 8
+ pxor m4, m4 ; zero
+
+ ; create registers holding dither
+ movq m3, [r3] ; dither
+ test r4d, r4d
+ jz .no_rot
+%if mmsize == 16
+ punpcklqdq m3, m3
+%endif ; mmsize == 16
+ PALIGNR_MMX m3, m3, 3, m2
+.no_rot:
+%if mmsize == 8
+ mova m2, m3
+ punpckhbw m3, m4 ; byte->word
+ punpcklbw m2, m4 ; byte->word
+%else
+ punpcklbw m3, m4
+ mova m2, m3
+%endif
+%elif %1 == 9
+ pxor m4, m4
+ mova m3, [pw_512]
+ mova m2, [pw_32]
+%elif %1 == 10
+ pxor m4, m4
+ mova m3, [pw_1024]
+ mova m2, [pw_16]
+%else ; %1 == 16
+%if cpuflag(sse4) ; sse4/avx
+ mova m4, [pd_4]
+%else ; mmx/sse2
+ mova m4, [pd_4min0x40000]
+ mova m5, [minshort]
+%endif ; mmx/sse2/sse4/avx
+%endif ; %1 == ..
+
+ ; actual pixel scaling
+%if mmsize == 8
+ yuv2plane1_mainloop %1, a
+%else ; mmsize == 16
+ test r1, 15
+ jnz .unaligned
+ yuv2plane1_mainloop %1, a
+ REP_RET
+.unaligned:
+ yuv2plane1_mainloop %1, u
+%endif ; mmsize == 8/16
+ REP_RET
+%endmacro
+
+%ifdef ARCH_X86_32
+INIT_MMX mmx
+yuv2plane1_fn 8, 0, 5
+yuv2plane1_fn 16, 0, 3
+
+INIT_MMX mmx2
+yuv2plane1_fn 9, 0, 3
+yuv2plane1_fn 10, 0, 3
+%endif
+
+INIT_XMM sse2
+yuv2plane1_fn 8, 5, 5
+yuv2plane1_fn 9, 5, 3
+yuv2plane1_fn 10, 5, 3
+yuv2plane1_fn 16, 6, 3
+
+INIT_XMM sse4
+yuv2plane1_fn 16, 5, 3
+
+INIT_XMM avx
+yuv2plane1_fn 8, 5, 5
+yuv2plane1_fn 9, 5, 3
+yuv2plane1_fn 10, 5, 3
+yuv2plane1_fn 16, 5, 3
diff --git a/libswscale/x86/swscale_mmx.c b/libswscale/x86/swscale_mmx.c
index f855a75..4305cef 100644
--- a/libswscale/x86/swscale_mmx.c
+++ b/libswscale/x86/swscale_mmx.c
@@ -176,6 +176,74 @@ void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufI
}
}
+#define SCALE_FUNC(filter_n, from_bpc, to_bpc, opt) \
+extern void ff_hscale ## from_bpc ## to ## to_bpc ## _ ## filter_n ## _ ## opt( \
+ SwsContext *c, int16_t *data, \
+ int dstW, const uint8_t *src, \
+ const int16_t *filter, \
+ const int16_t *filterPos, int filterSize)
+
+#define SCALE_FUNCS(filter_n, opt) \
+ SCALE_FUNC(filter_n, 8, 15, opt); \
+ SCALE_FUNC(filter_n, 9, 15, opt); \
+ SCALE_FUNC(filter_n, 10, 15, opt); \
+ SCALE_FUNC(filter_n, 16, 15, opt); \
+ SCALE_FUNC(filter_n, 8, 19, opt); \
+ SCALE_FUNC(filter_n, 9, 19, opt); \
+ SCALE_FUNC(filter_n, 10, 19, opt); \
+ SCALE_FUNC(filter_n, 16, 19, opt)
+
+#define SCALE_FUNCS_MMX(opt) \
+ SCALE_FUNCS(4, opt); \
+ SCALE_FUNCS(8, opt); \
+ SCALE_FUNCS(X, opt)
+
+#define SCALE_FUNCS_SSE(opt) \
+ SCALE_FUNCS(4, opt); \
+ SCALE_FUNCS(8, opt); \
+ SCALE_FUNCS(X4, opt); \
+ SCALE_FUNCS(X8, opt)
+
+#if ARCH_X86_32
+SCALE_FUNCS_MMX(mmx);
+#endif
+SCALE_FUNCS_SSE(sse2);
+SCALE_FUNCS_SSE(ssse3);
+SCALE_FUNCS_SSE(sse4);
+
+#define VSCALEX_FUNC(size, opt) \
+extern void ff_yuv2planeX_ ## size ## _ ## opt(const int16_t *filter, int filterSize, \
+ const int16_t **src, uint8_t *dest, int dstW, \
+ const uint8_t *dither, int offset)
+#define VSCALEX_FUNCS(opt) \
+ VSCALEX_FUNC(8, opt); \
+ VSCALEX_FUNC(9, opt); \
+ VSCALEX_FUNC(10, opt)
+
+#if ARCH_X86_32
+VSCALEX_FUNCS(mmx2);
+#endif
+VSCALEX_FUNCS(sse2);
+VSCALEX_FUNCS(sse4);
+VSCALEX_FUNC(16, sse4);
+VSCALEX_FUNCS(avx);
+
+#define VSCALE_FUNC(size, opt) \
+extern void ff_yuv2plane1_ ## size ## _ ## opt(const int16_t *src, uint8_t *dst, int dstW, \
+ const uint8_t *dither, int offset)
+#define VSCALE_FUNCS(opt1, opt2) \
+ VSCALE_FUNC(8, opt1); \
+ VSCALE_FUNC(9, opt2); \
+ VSCALE_FUNC(10, opt2); \
+ VSCALE_FUNC(16, opt1)
+
+#if ARCH_X86_32
+VSCALE_FUNCS(mmx, mmx2);
+#endif
+VSCALE_FUNCS(sse2, sse2);
+VSCALE_FUNC(16, sse4);
+VSCALE_FUNCS(avx, avx);
+
void ff_sws_init_swScale_mmx(SwsContext *c)
{
int cpu_flags = av_get_cpu_flags();
@@ -186,4 +254,84 @@ void ff_sws_init_swScale_mmx(SwsContext *c)
if (cpu_flags & AV_CPU_FLAG_MMX2)
sws_init_swScale_MMX2(c);
#endif
+
+#if HAVE_YASM
+#define ASSIGN_SCALE_FUNC2(hscalefn, filtersize, opt1, opt2) do { \
+ if (c->srcBpc == 8) { \
+ hscalefn = c->dstBpc <= 10 ? ff_hscale8to15_ ## filtersize ## _ ## opt2 : \
+ ff_hscale8to19_ ## filtersize ## _ ## opt1; \
+ } else if (c->srcBpc == 9) { \
+ hscalefn = c->dstBpc <= 10 ? ff_hscale9to15_ ## filtersize ## _ ## opt2 : \
+ ff_hscale9to19_ ## filtersize ## _ ## opt1; \
+ } else if (c->srcBpc == 10) { \
+ hscalefn = c->dstBpc <= 10 ? ff_hscale10to15_ ## filtersize ## _ ## opt2 : \
+ ff_hscale10to19_ ## filtersize ## _ ## opt1; \
+ } else /* c->srcBpc == 16 */ { \
+ hscalefn = c->dstBpc <= 10 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \
+ ff_hscale16to19_ ## filtersize ## _ ## opt1; \
+ } \
+} while (0)
+#define ASSIGN_MMX_SCALE_FUNC(hscalefn, filtersize, opt1, opt2) \
+ switch (filtersize) { \
+ case 4: ASSIGN_SCALE_FUNC2(hscalefn, 4, opt1, opt2); break; \
+ case 8: ASSIGN_SCALE_FUNC2(hscalefn, 8, opt1, opt2); break; \
+ default: ASSIGN_SCALE_FUNC2(hscalefn, X, opt1, opt2); break; \
+ }
+#define ASSIGN_VSCALEX_FUNC(vscalefn, opt, do_16_case) \
+switch(c->dstBpc){ \
+ case 16: do_16_case; break; \
+ case 10: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_10_ ## opt; break; \
+ case 9: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_9_ ## opt; break; \
+ default: vscalefn = ff_yuv2planeX_8_ ## opt; break; \
+ }
+#define ASSIGN_VSCALE_FUNC(vscalefn, opt1, opt2, opt2chk) \
+ switch(c->dstBpc){ \
+ case 16: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2plane1_16_ ## opt1; break; \
+ case 10: if (!isBE(c->dstFormat) && opt2chk) vscalefn = ff_yuv2plane1_10_ ## opt2; break; \
+ case 9: if (!isBE(c->dstFormat) && opt2chk) vscalefn = ff_yuv2plane1_9_ ## opt2; break; \
+ default: vscalefn = ff_yuv2plane1_8_ ## opt1; break; \
+ }
+#if ARCH_X86_32
+ if (cpu_flags & AV_CPU_FLAG_MMX) {
+ ASSIGN_MMX_SCALE_FUNC(c->hyScale, c->hLumFilterSize, mmx, mmx);
+ ASSIGN_MMX_SCALE_FUNC(c->hcScale, c->hChrFilterSize, mmx, mmx);
+ ASSIGN_VSCALE_FUNC(c->yuv2plane1, mmx, mmx2, cpu_flags & AV_CPU_FLAG_MMX2);
+ }
+ if (cpu_flags & AV_CPU_FLAG_MMX2) {
+ ASSIGN_VSCALEX_FUNC(c->yuv2planeX, mmx2,);
+ }
+#endif
+#define ASSIGN_SSE_SCALE_FUNC(hscalefn, filtersize, opt1, opt2) \
+ switch (filtersize) { \
+ case 4: ASSIGN_SCALE_FUNC2(hscalefn, 4, opt1, opt2); break; \
+ case 8: ASSIGN_SCALE_FUNC2(hscalefn, 8, opt1, opt2); break; \
+ default: if (filtersize & 4) ASSIGN_SCALE_FUNC2(hscalefn, X4, opt1, opt2); \
+ else ASSIGN_SCALE_FUNC2(hscalefn, X8, opt1, opt2); \
+ break; \
+ }
+ if (cpu_flags & AV_CPU_FLAG_SSE2) {
+ ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, sse2, sse2);
+ ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse2, sse2);
+ ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse2,);
+ ASSIGN_VSCALE_FUNC(c->yuv2plane1, sse2, sse2, 1);
+ }
+ if (cpu_flags & AV_CPU_FLAG_SSSE3) {
+ ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, ssse3, ssse3);
+ ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, ssse3, ssse3);
+ }
+ if (cpu_flags & AV_CPU_FLAG_SSE4) {
+ /* Xto15 don't need special sse4 functions */
+ ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, sse4, ssse3);
+ ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse4, ssse3);
+ ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse4,
+ if (!isBE(c->dstFormat)) c->yuv2planeX = ff_yuv2planeX_16_sse4);
+ if (c->dstBpc == 16 && !isBE(c->dstFormat))
+ c->yuv2plane1 = ff_yuv2plane1_16_sse4;
+ }
+
+ if (cpu_flags & AV_CPU_FLAG_AVX) {
+ ASSIGN_VSCALEX_FUNC(c->yuv2planeX, avx,);
+ ASSIGN_VSCALE_FUNC(c->yuv2plane1, avx, avx, 1);
+ }
+#endif
}
diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c
index dc92cdd..5e7df5c 100644
--- a/libswscale/x86/swscale_template.c
+++ b/libswscale/x86/swscale_template.c
@@ -35,213 +35,6 @@
#endif
#define MOVNTQ(a,b) REAL_MOVNTQ(a,b)
-#define YSCALEYUV2YV12X(offset, dest, end, pos) \
- __asm__ volatile(\
- "movq "VROUNDER_OFFSET"(%0), %%mm3 \n\t"\
- "movq %%mm3, %%mm4 \n\t"\
- "lea " offset "(%0), %%"REG_d" \n\t"\
- "mov (%%"REG_d"), %%"REG_S" \n\t"\
- ".p2align 4 \n\t" /* FIXME Unroll? */\
- "1: \n\t"\
- "movq 8(%%"REG_d"), %%mm0 \n\t" /* filterCoeff */\
- "movq (%%"REG_S", %3, 2), %%mm2 \n\t" /* srcData */\
- "movq 8(%%"REG_S", %3, 2), %%mm5 \n\t" /* srcData */\
- "add $16, %%"REG_d" \n\t"\
- "mov (%%"REG_d"), %%"REG_S" \n\t"\
- "test %%"REG_S", %%"REG_S" \n\t"\
- "pmulhw %%mm0, %%mm2 \n\t"\
- "pmulhw %%mm0, %%mm5 \n\t"\
- "paddw %%mm2, %%mm3 \n\t"\
- "paddw %%mm5, %%mm4 \n\t"\
- " jnz 1b \n\t"\
- "psraw $3, %%mm3 \n\t"\
- "psraw $3, %%mm4 \n\t"\
- "packuswb %%mm4, %%mm3 \n\t"\
- MOVNTQ(%%mm3, (%1, %3))\
- "add $8, %3 \n\t"\
- "cmp %2, %3 \n\t"\
- "movq "VROUNDER_OFFSET"(%0), %%mm3 \n\t"\
- "movq %%mm3, %%mm4 \n\t"\
- "lea " offset "(%0), %%"REG_d" \n\t"\
- "mov (%%"REG_d"), %%"REG_S" \n\t"\
- "jb 1b \n\t"\
- :: "r" (&c->redDither),\
- "r" (dest), "g" ((x86_reg)(end)), "r"((x86_reg)(pos))\
- : "%"REG_d, "%"REG_S\
- );
-
-static void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter,
- const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrUSrc,
- const int16_t **chrVSrc,
- int chrFilterSize, const int16_t **alpSrc,
- uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
- uint8_t *aDest, int dstW, int chrDstW)
-{
- if (uDest) {
- x86_reg uv_off = c->uv_off;
- YSCALEYUV2YV12X(CHR_MMX_FILTER_OFFSET, uDest, chrDstW, 0)
- YSCALEYUV2YV12X(CHR_MMX_FILTER_OFFSET, vDest - uv_off, chrDstW + uv_off, uv_off)
- }
- if (CONFIG_SWSCALE_ALPHA && aDest) {
- YSCALEYUV2YV12X(ALP_MMX_FILTER_OFFSET, aDest, dstW, 0)
- }
-
- YSCALEYUV2YV12X(LUM_MMX_FILTER_OFFSET, dest, dstW, 0)
-}
-
-#define YSCALEYUV2YV12X_ACCURATE(offset, dest, end, pos) \
- __asm__ volatile(\
- "lea " offset "(%0), %%"REG_d" \n\t"\
- "pxor %%mm4, %%mm4 \n\t"\
- "pxor %%mm5, %%mm5 \n\t"\
- "pxor %%mm6, %%mm6 \n\t"\
- "pxor %%mm7, %%mm7 \n\t"\
- "mov (%%"REG_d"), %%"REG_S" \n\t"\
- ".p2align 4 \n\t"\
- "1: \n\t"\
- "movq (%%"REG_S", %3, 2), %%mm0 \n\t" /* srcData */\
- "movq 8(%%"REG_S", %3, 2), %%mm2 \n\t" /* srcData */\
- "mov "STR(APCK_PTR2)"(%%"REG_d"), %%"REG_S" \n\t"\
- "movq (%%"REG_S", %3, 2), %%mm1 \n\t" /* srcData */\
- "movq %%mm0, %%mm3 \n\t"\
- "punpcklwd %%mm1, %%mm0 \n\t"\
- "punpckhwd %%mm1, %%mm3 \n\t"\
- "movq "STR(APCK_COEF)"(%%"REG_d"), %%mm1 \n\t" /* filterCoeff */\
- "pmaddwd %%mm1, %%mm0 \n\t"\
- "pmaddwd %%mm1, %%mm3 \n\t"\
- "paddd %%mm0, %%mm4 \n\t"\
- "paddd %%mm3, %%mm5 \n\t"\
- "movq 8(%%"REG_S", %3, 2), %%mm3 \n\t" /* srcData */\
- "mov "STR(APCK_SIZE)"(%%"REG_d"), %%"REG_S" \n\t"\
- "add $"STR(APCK_SIZE)", %%"REG_d" \n\t"\
- "test %%"REG_S", %%"REG_S" \n\t"\
- "movq %%mm2, %%mm0 \n\t"\
- "punpcklwd %%mm3, %%mm2 \n\t"\
- "punpckhwd %%mm3, %%mm0 \n\t"\
- "pmaddwd %%mm1, %%mm2 \n\t"\
- "pmaddwd %%mm1, %%mm0 \n\t"\
- "paddd %%mm2, %%mm6 \n\t"\
- "paddd %%mm0, %%mm7 \n\t"\
- " jnz 1b \n\t"\
- "psrad $16, %%mm4 \n\t"\
- "psrad $16, %%mm5 \n\t"\
- "psrad $16, %%mm6 \n\t"\
- "psrad $16, %%mm7 \n\t"\
- "movq "VROUNDER_OFFSET"(%0), %%mm0 \n\t"\
- "packssdw %%mm5, %%mm4 \n\t"\
- "packssdw %%mm7, %%mm6 \n\t"\
- "paddw %%mm0, %%mm4 \n\t"\
- "paddw %%mm0, %%mm6 \n\t"\
- "psraw $3, %%mm4 \n\t"\
- "psraw $3, %%mm6 \n\t"\
- "packuswb %%mm6, %%mm4 \n\t"\
- MOVNTQ(%%mm4, (%1, %3))\
- "add $8, %3 \n\t"\
- "cmp %2, %3 \n\t"\
- "lea " offset "(%0), %%"REG_d" \n\t"\
- "pxor %%mm4, %%mm4 \n\t"\
- "pxor %%mm5, %%mm5 \n\t"\
- "pxor %%mm6, %%mm6 \n\t"\
- "pxor %%mm7, %%mm7 \n\t"\
- "mov (%%"REG_d"), %%"REG_S" \n\t"\
- "jb 1b \n\t"\
- :: "r" (&c->redDither),\
- "r" (dest), "g" ((x86_reg)(end)), "r"((x86_reg)(pos))\
- : "%"REG_a, "%"REG_d, "%"REG_S\
- );
-
-static void RENAME(yuv2yuvX_ar)(SwsContext *c, const int16_t *lumFilter,
- const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrUSrc,
- const int16_t **chrVSrc,
- int chrFilterSize, const int16_t **alpSrc,
- uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
- uint8_t *aDest, int dstW, int chrDstW)
-{
- if (uDest) {
- x86_reg uv_off = c->uv_off;
- YSCALEYUV2YV12X_ACCURATE(CHR_MMX_FILTER_OFFSET, uDest, chrDstW, 0)
- YSCALEYUV2YV12X_ACCURATE(CHR_MMX_FILTER_OFFSET, vDest - uv_off, chrDstW + uv_off, uv_off)
- }
- if (CONFIG_SWSCALE_ALPHA && aDest) {
- YSCALEYUV2YV12X_ACCURATE(ALP_MMX_FILTER_OFFSET, aDest, dstW, 0)
- }
-
- YSCALEYUV2YV12X_ACCURATE(LUM_MMX_FILTER_OFFSET, dest, dstW, 0)
-}
-
-static void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc,
- const int16_t *chrUSrc, const int16_t *chrVSrc,
- const int16_t *alpSrc,
- uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
- uint8_t *aDest, int dstW, int chrDstW)
-{
- int p= 4;
- const int16_t *src[4]= { alpSrc + dstW, lumSrc + dstW, chrUSrc + chrDstW, chrVSrc + chrDstW };
- uint8_t *dst[4]= { aDest, dest, uDest, vDest };
- x86_reg counter[4]= { dstW, dstW, chrDstW, chrDstW };
-
- while (p--) {
- if (dst[p]) {
- __asm__ volatile(
- "mov %2, %%"REG_a" \n\t"
- ".p2align 4 \n\t" /* FIXME Unroll? */
- "1: \n\t"
- "movq (%0, %%"REG_a", 2), %%mm0 \n\t"
- "movq 8(%0, %%"REG_a", 2), %%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"
- :: "r" (src[p]), "r" (dst[p] + counter[p]),
- "g" (-counter[p])
- : "%"REG_a
- );
- }
- }
-}
-
-static void RENAME(yuv2yuv1_ar)(SwsContext *c, const int16_t *lumSrc,
- const int16_t *chrUSrc, const int16_t *chrVSrc,
- const int16_t *alpSrc,
- uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
- uint8_t *aDest, int dstW, int chrDstW)
-{
- int p= 4;
- const int16_t *src[4]= { alpSrc + dstW, lumSrc + dstW, chrUSrc + chrDstW, chrVSrc + chrDstW };
- uint8_t *dst[4]= { aDest, dest, uDest, vDest };
- x86_reg counter[4]= { dstW, dstW, chrDstW, chrDstW };
-
- while (p--) {
- if (dst[p]) {
- __asm__ volatile(
- "mov %2, %%"REG_a" \n\t"
- "pcmpeqw %%mm7, %%mm7 \n\t"
- "psrlw $15, %%mm7 \n\t"
- "psllw $6, %%mm7 \n\t"
- ".p2align 4 \n\t" /* FIXME Unroll? */
- "1: \n\t"
- "movq (%0, %%"REG_a", 2), %%mm0 \n\t"
- "movq 8(%0, %%"REG_a", 2), %%mm1 \n\t"
- "paddsw %%mm7, %%mm0 \n\t"
- "paddsw %%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"
- :: "r" (src[p]), "r" (dst[p] + counter[p]),
- "g" (-counter[p])
- : "%"REG_a
- );
- }
- }
-}
-
#define YSCALEYUV2PACKEDX_UV \
__asm__ volatile(\
"xor %%"REG_a", %%"REG_a" \n\t"\
@@ -467,7 +260,7 @@ static void RENAME(yuv2rgb32_X_ar)(SwsContext *c, const int16_t *lumFilter,
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
- x86_reg uv_off = c->uv_off << 1;
+ x86_reg uv_off = c->uv_off_byte;
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
YSCALEYUV2PACKEDX_ACCURATE
@@ -500,7 +293,7 @@ static void RENAME(yuv2rgb32_X)(SwsContext *c, const int16_t *lumFilter,
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
- x86_reg uv_off = c->uv_off << 1;
+ x86_reg uv_off = c->uv_off_byte;
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
YSCALEYUV2PACKEDX
@@ -557,7 +350,7 @@ static void RENAME(yuv2rgb565_X_ar)(SwsContext *c, const int16_t *lumFilter,
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
- x86_reg uv_off = c->uv_off << 1;
+ x86_reg uv_off = c->uv_off_byte;
YSCALEYUV2PACKEDX_ACCURATE
YSCALEYUV2RGBX
@@ -581,7 +374,7 @@ static void RENAME(yuv2rgb565_X)(SwsContext *c, const int16_t *lumFilter,
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
- x86_reg uv_off = c->uv_off << 1;
+ x86_reg uv_off = c->uv_off_byte;
YSCALEYUV2PACKEDX
YSCALEYUV2RGBX
@@ -634,7 +427,7 @@ static void RENAME(yuv2rgb555_X_ar)(SwsContext *c, const int16_t *lumFilter,
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
- x86_reg uv_off = c->uv_off << 1;
+ x86_reg uv_off = c->uv_off_byte;
YSCALEYUV2PACKEDX_ACCURATE
YSCALEYUV2RGBX
@@ -658,7 +451,7 @@ static void RENAME(yuv2rgb555_X)(SwsContext *c, const int16_t *lumFilter,
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
- x86_reg uv_off = c->uv_off << 1;
+ x86_reg uv_off = c->uv_off_byte;
YSCALEYUV2PACKEDX
YSCALEYUV2RGBX
@@ -791,7 +584,7 @@ static void RENAME(yuv2bgr24_X_ar)(SwsContext *c, const int16_t *lumFilter,
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
- x86_reg uv_off = c->uv_off << 1;
+ x86_reg uv_off = c->uv_off_byte;
YSCALEYUV2PACKEDX_ACCURATE
YSCALEYUV2RGBX
@@ -815,7 +608,7 @@ static void RENAME(yuv2bgr24_X)(SwsContext *c, const int16_t *lumFilter,
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
- x86_reg uv_off = c->uv_off << 1;
+ x86_reg uv_off = c->uv_off_byte;
YSCALEYUV2PACKEDX
YSCALEYUV2RGBX
@@ -856,7 +649,7 @@ static void RENAME(yuv2yuyv422_X_ar)(SwsContext *c, const int16_t *lumFilter,
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
- x86_reg uv_off = c->uv_off << 1;
+ x86_reg uv_off = c->uv_off_byte;
YSCALEYUV2PACKEDX_ACCURATE
/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
@@ -877,7 +670,7 @@ static void RENAME(yuv2yuyv422_X)(SwsContext *c, const int16_t *lumFilter,
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
- x86_reg uv_off = c->uv_off << 1;
+ x86_reg uv_off = c->uv_off_byte;
YSCALEYUV2PACKEDX
/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
@@ -895,10 +688,10 @@ static void RENAME(yuv2yuyv422_X)(SwsContext *c, const int16_t *lumFilter,
"1: \n\t"\
"movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\
"movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\
- "add "UV_OFFx2"("#c"), "#index" \n\t" \
+ "add "UV_OFF_PX"("#c"), "#index" \n\t" \
"movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
"movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
- "sub "UV_OFFx2"("#c"), "#index" \n\t" \
+ "sub "UV_OFF_PX"("#c"), "#index" \n\t" \
"psubw %%mm3, %%mm2 \n\t" /* uvbuf0[eax] - uvbuf1[eax]*/\
"psubw %%mm4, %%mm5 \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/\
"movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0 \n\t"\
@@ -969,14 +762,16 @@ static void RENAME(yuv2yuyv422_X)(SwsContext *c, const int16_t *lumFilter,
/**
* vertical bilinear scale YV12 to RGB
*/
-static void RENAME(yuv2rgb32_2)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *ubuf0,
- const uint16_t *ubuf1, const uint16_t *vbuf0,
- const uint16_t *vbuf1, const uint16_t *abuf0,
- const uint16_t *abuf1, uint8_t *dest,
+static void RENAME(yuv2rgb32_2)(SwsContext *c, const int16_t *buf[2],
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf[2], uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y)
{
+ const int16_t *buf0 = buf[0], *buf1 = buf[1],
+ *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];
+
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
+ const int16_t *abuf0 = abuf[0], *abuf1 = abuf[1];
#if ARCH_X86_64
__asm__ volatile(
YSCALEYUV2RGB(%%r8, %5)
@@ -1031,13 +826,14 @@ static void RENAME(yuv2rgb32_2)(SwsContext *c, const uint16_t *buf0,
}
}
-static void RENAME(yuv2bgr24_2)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *ubuf0,
- const uint16_t *ubuf1, const uint16_t *vbuf0,
- const uint16_t *vbuf1, const uint16_t *abuf0,
- const uint16_t *abuf1, uint8_t *dest,
+static void RENAME(yuv2bgr24_2)(SwsContext *c, const int16_t *buf[2],
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf[2], uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y)
{
+ const int16_t *buf0 = buf[0], *buf1 = buf[1],
+ *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];
+
//Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
@@ -1053,13 +849,14 @@ static void RENAME(yuv2bgr24_2)(SwsContext *c, const uint16_t *buf0,
);
}
-static void RENAME(yuv2rgb555_2)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *ubuf0,
- const uint16_t *ubuf1, const uint16_t *vbuf0,
- const uint16_t *vbuf1, const uint16_t *abuf0,
- const uint16_t *abuf1, uint8_t *dest,
+static void RENAME(yuv2rgb555_2)(SwsContext *c, const int16_t *buf[2],
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf[2], uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y)
{
+ const int16_t *buf0 = buf[0], *buf1 = buf[1],
+ *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];
+
//Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
@@ -1081,13 +878,14 @@ static void RENAME(yuv2rgb555_2)(SwsContext *c, const uint16_t *buf0,
);
}
-static void RENAME(yuv2rgb565_2)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *ubuf0,
- const uint16_t *ubuf1, const uint16_t *vbuf0,
- const uint16_t *vbuf1, const uint16_t *abuf0,
- const uint16_t *abuf1, uint8_t *dest,
+static void RENAME(yuv2rgb565_2)(SwsContext *c, const int16_t *buf[2],
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf[2], uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y)
{
+ const int16_t *buf0 = buf[0], *buf1 = buf[1],
+ *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];
+
//Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
@@ -1121,10 +919,10 @@ static void RENAME(yuv2rgb565_2)(SwsContext *c, const uint16_t *buf0,
"1: \n\t"\
"movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\
"movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\
- "add "UV_OFFx2"("#c"), "#index" \n\t" \
+ "add "UV_OFF_PX"("#c"), "#index" \n\t" \
"movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
"movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
- "sub "UV_OFFx2"("#c"), "#index" \n\t" \
+ "sub "UV_OFF_PX"("#c"), "#index" \n\t" \
"psubw %%mm3, %%mm2 \n\t" /* uvbuf0[eax] - uvbuf1[eax]*/\
"psubw %%mm4, %%mm5 \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/\
"movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0 \n\t"\
@@ -1149,13 +947,14 @@ static void RENAME(yuv2rgb565_2)(SwsContext *c, const uint16_t *buf0,
#define YSCALEYUV2PACKED(index, c) REAL_YSCALEYUV2PACKED(index, c)
-static void RENAME(yuv2yuyv422_2)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *ubuf0,
- const uint16_t *ubuf1, const uint16_t *vbuf0,
- const uint16_t *vbuf1, const uint16_t *abuf0,
- const uint16_t *abuf1, uint8_t *dest,
+static void RENAME(yuv2yuyv422_2)(SwsContext *c, const int16_t *buf[2],
+ const int16_t *ubuf[2], const int16_t *vbuf[2],
+ const int16_t *abuf[2], uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y)
{
+ const int16_t *buf0 = buf[0], *buf1 = buf[1],
+ *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];
+
//Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
@@ -1175,9 +974,9 @@ static void RENAME(yuv2yuyv422_2)(SwsContext *c, const uint16_t *buf0,
".p2align 4 \n\t"\
"1: \n\t"\
"movq (%2, "#index"), %%mm3 \n\t" /* uvbuf0[eax]*/\
- "add "UV_OFFx2"("#c"), "#index" \n\t" \
+ "add "UV_OFF_PX"("#c"), "#index" \n\t" \
"movq (%2, "#index"), %%mm4 \n\t" /* uvbuf0[eax+2048]*/\
- "sub "UV_OFFx2"("#c"), "#index" \n\t" \
+ "sub "UV_OFF_PX"("#c"), "#index" \n\t" \
"psraw $4, %%mm3 \n\t" /* uvbuf0[eax] - uvbuf1[eax] >>4*/\
"psraw $4, %%mm4 \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/\
"psubw "U_OFFSET"("#c"), %%mm3 \n\t" /* (U-128)8*/\
@@ -1228,10 +1027,10 @@ static void RENAME(yuv2yuyv422_2)(SwsContext *c, const uint16_t *buf0,
"1: \n\t"\
"movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\
"movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\
- "add "UV_OFFx2"("#c"), "#index" \n\t" \
+ "add "UV_OFF_PX"("#c"), "#index" \n\t" \
"movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
"movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
- "sub "UV_OFFx2"("#c"), "#index" \n\t" \
+ "sub "UV_OFF_PX"("#c"), "#index" \n\t" \
"paddw %%mm2, %%mm3 \n\t" /* uvbuf0[eax] + uvbuf1[eax]*/\
"paddw %%mm5, %%mm4 \n\t" /* uvbuf0[eax+2048] + uvbuf1[eax+2048]*/\
"psrlw $5, %%mm3 \n\t" /*FIXME might overflow*/\
@@ -1288,14 +1087,13 @@ static void RENAME(yuv2yuyv422_2)(SwsContext *c, const uint16_t *buf0,
/**
* YV12 to RGB without scaling or interpolating
*/
-static void RENAME(yuv2rgb32_1)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, uint8_t *dest,
- int dstW, int uvalpha, enum PixelFormat dstFormat,
- int flags, int y)
+static void RENAME(yuv2rgb32_1)(SwsContext *c, const int16_t *buf0,
+ const int16_t *ubuf[2], const int16_t *bguf[2],
+ const int16_t *abuf0, uint8_t *dest,
+ int dstW, int uvalpha, int y)
{
- const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
+ const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];
+ const int16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
@@ -1356,14 +1154,13 @@ static void RENAME(yuv2rgb32_1)(SwsContext *c, const uint16_t *buf0,
}
}
-static void RENAME(yuv2bgr24_1)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, uint8_t *dest,
- int dstW, int uvalpha, enum PixelFormat dstFormat,
- int flags, int y)
+static void RENAME(yuv2bgr24_1)(SwsContext *c, const int16_t *buf0,
+ const int16_t *ubuf[2], const int16_t *bguf[2],
+ const int16_t *abuf0, uint8_t *dest,
+ int dstW, int uvalpha, int y)
{
- const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
+ const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];
+ const int16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
__asm__ volatile(
@@ -1394,14 +1191,13 @@ static void RENAME(yuv2bgr24_1)(SwsContext *c, const uint16_t *buf0,
}
}
-static void RENAME(yuv2rgb555_1)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, uint8_t *dest,
- int dstW, int uvalpha, enum PixelFormat dstFormat,
- int flags, int y)
+static void RENAME(yuv2rgb555_1)(SwsContext *c, const int16_t *buf0,
+ const int16_t *ubuf[2], const int16_t *bguf[2],
+ const int16_t *abuf0, uint8_t *dest,
+ int dstW, int uvalpha, int y)
{
- const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
+ const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];
+ const int16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
__asm__ volatile(
@@ -1444,14 +1240,13 @@ static void RENAME(yuv2rgb555_1)(SwsContext *c, const uint16_t *buf0,
}
}
-static void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, uint8_t *dest,
- int dstW, int uvalpha, enum PixelFormat dstFormat,
- int flags, int y)
+static void RENAME(yuv2rgb565_1)(SwsContext *c, const int16_t *buf0,
+ const int16_t *ubuf[2], const int16_t *bguf[2],
+ const int16_t *abuf0, uint8_t *dest,
+ int dstW, int uvalpha, int y)
{
- const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
+ const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];
+ const int16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
__asm__ volatile(
@@ -1499,9 +1294,9 @@ static void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,
".p2align 4 \n\t"\
"1: \n\t"\
"movq (%2, "#index"), %%mm3 \n\t" /* uvbuf0[eax]*/\
- "add "UV_OFFx2"("#c"), "#index" \n\t" \
+ "add "UV_OFF_PX"("#c"), "#index" \n\t" \
"movq (%2, "#index"), %%mm4 \n\t" /* uvbuf0[eax+2048]*/\
- "sub "UV_OFFx2"("#c"), "#index" \n\t" \
+ "sub "UV_OFF_PX"("#c"), "#index" \n\t" \
"psraw $7, %%mm3 \n\t" \
"psraw $7, %%mm4 \n\t" \
"movq (%0, "#index", 2), %%mm1 \n\t" /*buf0[eax]*/\
@@ -1517,10 +1312,10 @@ static void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,
"1: \n\t"\
"movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\
"movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\
- "add "UV_OFFx2"("#c"), "#index" \n\t" \
+ "add "UV_OFF_PX"("#c"), "#index" \n\t" \
"movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
"movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
- "sub "UV_OFFx2"("#c"), "#index" \n\t" \
+ "sub "UV_OFF_PX"("#c"), "#index" \n\t" \
"paddw %%mm2, %%mm3 \n\t" /* uvbuf0[eax] + uvbuf1[eax]*/\
"paddw %%mm5, %%mm4 \n\t" /* uvbuf0[eax+2048] + uvbuf1[eax+2048]*/\
"psrlw $8, %%mm3 \n\t" \
@@ -1531,14 +1326,13 @@ static void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,
"psraw $7, %%mm7 \n\t"
#define YSCALEYUV2PACKED1b(index, c) REAL_YSCALEYUV2PACKED1b(index, c)
-static void RENAME(yuv2yuyv422_1)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *ubuf0, const uint16_t *ubuf1,
- const uint16_t *vbuf0, const uint16_t *vbuf1,
- const uint16_t *abuf0, uint8_t *dest,
- int dstW, int uvalpha, enum PixelFormat dstFormat,
- int flags, int y)
+static void RENAME(yuv2yuyv422_1)(SwsContext *c, const int16_t *buf0,
+ const int16_t *ubuf[2], const int16_t *bguf[2],
+ const int16_t *abuf0, uint8_t *dest,
+ int dstW, int uvalpha, int y)
{
- const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
+ const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];
+ const int16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
__asm__ volatile(
@@ -1618,32 +1412,6 @@ static void RENAME(yuy2ToUV)(uint8_t *dstU, uint8_t *dstV,
assert(src1 == src2);
}
-static void RENAME(LEToUV)(uint8_t *dstU, uint8_t *dstV,
- const uint8_t *src1, const uint8_t *src2,
- int width, uint32_t *unused)
-{
- __asm__ volatile(
- "mov %0, %%"REG_a" \n\t"
- "1: \n\t"
- "movq (%1, %%"REG_a",2), %%mm0 \n\t"
- "movq 8(%1, %%"REG_a",2), %%mm1 \n\t"
- "movq (%2, %%"REG_a",2), %%mm2 \n\t"
- "movq 8(%2, %%"REG_a",2), %%mm3 \n\t"
- "psrlw $8, %%mm0 \n\t"
- "psrlw $8, %%mm1 \n\t"
- "psrlw $8, %%mm2 \n\t"
- "psrlw $8, %%mm3 \n\t"
- "packuswb %%mm1, %%mm0 \n\t"
- "packuswb %%mm3, %%mm2 \n\t"
- "movq %%mm0, (%3, %%"REG_a") \n\t"
- "movq %%mm2, (%4, %%"REG_a") \n\t"
- "add $8, %%"REG_a" \n\t"
- " js 1b \n\t"
- : : "g" ((x86_reg)-width), "r" (src1+width*2), "r" (src2+width*2), "r" (dstU+width), "r" (dstV+width)
- : "%"REG_a
- );
-}
-
/* This is almost identical to the previous, end exists only because
* yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */
static void RENAME(uyvyToY)(uint8_t *dst, const uint8_t *src,
@@ -1693,33 +1461,6 @@ static void RENAME(uyvyToUV)(uint8_t *dstU, uint8_t *dstV,
assert(src1 == src2);
}
-static void RENAME(BEToUV)(uint8_t *dstU, uint8_t *dstV,
- const uint8_t *src1, const uint8_t *src2,
- int width, uint32_t *unused)
-{
- __asm__ volatile(
- "movq "MANGLE(bm01010101)", %%mm4 \n\t"
- "mov %0, %%"REG_a" \n\t"
- "1: \n\t"
- "movq (%1, %%"REG_a",2), %%mm0 \n\t"
- "movq 8(%1, %%"REG_a",2), %%mm1 \n\t"
- "movq (%2, %%"REG_a",2), %%mm2 \n\t"
- "movq 8(%2, %%"REG_a",2), %%mm3 \n\t"
- "pand %%mm4, %%mm0 \n\t"
- "pand %%mm4, %%mm1 \n\t"
- "pand %%mm4, %%mm2 \n\t"
- "pand %%mm4, %%mm3 \n\t"
- "packuswb %%mm1, %%mm0 \n\t"
- "packuswb %%mm3, %%mm2 \n\t"
- "movq %%mm0, (%3, %%"REG_a") \n\t"
- "movq %%mm2, (%4, %%"REG_a") \n\t"
- "add $8, %%"REG_a" \n\t"
- " js 1b \n\t"
- : : "g" ((x86_reg)-width), "r" (src1+width*2), "r" (src2+width*2), "r" (dstU+width), "r" (dstV+width)
- : "%"REG_a
- );
-}
-
static av_always_inline void RENAME(nvXXtoUV)(uint8_t *dst1, uint8_t *dst2,
const uint8_t *src, int width)
{
@@ -1903,165 +1644,6 @@ static void RENAME(rgb24ToUV)(uint8_t *dstU, uint8_t *dstV,
RENAME(bgr24ToUV_mmx)(dstU, dstV, src1, width, PIX_FMT_RGB24);
}
-#if !COMPILE_TEMPLATE_MMX2
-// bilinear / bicubic scaling
-static void RENAME(hScale)(int16_t *dst, int dstW,
- const uint8_t *src, int srcW,
- int xInc, const int16_t *filter,
- const int16_t *filterPos, int filterSize)
-{
- assert(filterSize % 4 == 0 && filterSize>0);
- if (filterSize==4) { // Always true for upscaling, sometimes for down, too.
- x86_reg counter= -2*dstW;
- filter-= counter*2;
- filterPos-= counter/2;
- dst-= counter/2;
- __asm__ volatile(
-#if defined(PIC)
- "push %%"REG_b" \n\t"
-#endif
- "pxor %%mm7, %%mm7 \n\t"
- "push %%"REG_BP" \n\t" // we use 7 regs here ...
- "mov %%"REG_a", %%"REG_BP" \n\t"
- ".p2align 4 \n\t"
- "1: \n\t"
- "movzwl (%2, %%"REG_BP"), %%eax \n\t"
- "movzwl 2(%2, %%"REG_BP"), %%ebx \n\t"
- "movq (%1, %%"REG_BP", 4), %%mm1 \n\t"
- "movq 8(%1, %%"REG_BP", 4), %%mm3 \n\t"
- "movd (%3, %%"REG_a"), %%mm0 \n\t"
- "movd (%3, %%"REG_b"), %%mm2 \n\t"
- "punpcklbw %%mm7, %%mm0 \n\t"
- "punpcklbw %%mm7, %%mm2 \n\t"
- "pmaddwd %%mm1, %%mm0 \n\t"
- "pmaddwd %%mm2, %%mm3 \n\t"
- "movq %%mm0, %%mm4 \n\t"
- "punpckldq %%mm3, %%mm0 \n\t"
- "punpckhdq %%mm3, %%mm4 \n\t"
- "paddd %%mm4, %%mm0 \n\t"
- "psrad $7, %%mm0 \n\t"
- "packssdw %%mm0, %%mm0 \n\t"
- "movd %%mm0, (%4, %%"REG_BP") \n\t"
- "add $4, %%"REG_BP" \n\t"
- " jnc 1b \n\t"
-
- "pop %%"REG_BP" \n\t"
-#if defined(PIC)
- "pop %%"REG_b" \n\t"
-#endif
- : "+a" (counter)
- : "c" (filter), "d" (filterPos), "S" (src), "D" (dst)
-#if !defined(PIC)
- : "%"REG_b
-#endif
- );
- } else if (filterSize==8) {
- x86_reg counter= -2*dstW;
- filter-= counter*4;
- filterPos-= counter/2;
- dst-= counter/2;
- __asm__ volatile(
-#if defined(PIC)
- "push %%"REG_b" \n\t"
-#endif
- "pxor %%mm7, %%mm7 \n\t"
- "push %%"REG_BP" \n\t" // we use 7 regs here ...
- "mov %%"REG_a", %%"REG_BP" \n\t"
- ".p2align 4 \n\t"
- "1: \n\t"
- "movzwl (%2, %%"REG_BP"), %%eax \n\t"
- "movzwl 2(%2, %%"REG_BP"), %%ebx \n\t"
- "movq (%1, %%"REG_BP", 8), %%mm1 \n\t"
- "movq 16(%1, %%"REG_BP", 8), %%mm3 \n\t"
- "movd (%3, %%"REG_a"), %%mm0 \n\t"
- "movd (%3, %%"REG_b"), %%mm2 \n\t"
- "punpcklbw %%mm7, %%mm0 \n\t"
- "punpcklbw %%mm7, %%mm2 \n\t"
- "pmaddwd %%mm1, %%mm0 \n\t"
- "pmaddwd %%mm2, %%mm3 \n\t"
-
- "movq 8(%1, %%"REG_BP", 8), %%mm1 \n\t"
- "movq 24(%1, %%"REG_BP", 8), %%mm5 \n\t"
- "movd 4(%3, %%"REG_a"), %%mm4 \n\t"
- "movd 4(%3, %%"REG_b"), %%mm2 \n\t"
- "punpcklbw %%mm7, %%mm4 \n\t"
- "punpcklbw %%mm7, %%mm2 \n\t"
- "pmaddwd %%mm1, %%mm4 \n\t"
- "pmaddwd %%mm2, %%mm5 \n\t"
- "paddd %%mm4, %%mm0 \n\t"
- "paddd %%mm5, %%mm3 \n\t"
- "movq %%mm0, %%mm4 \n\t"
- "punpckldq %%mm3, %%mm0 \n\t"
- "punpckhdq %%mm3, %%mm4 \n\t"
- "paddd %%mm4, %%mm0 \n\t"
- "psrad $7, %%mm0 \n\t"
- "packssdw %%mm0, %%mm0 \n\t"
- "movd %%mm0, (%4, %%"REG_BP") \n\t"
- "add $4, %%"REG_BP" \n\t"
- " jnc 1b \n\t"
-
- "pop %%"REG_BP" \n\t"
-#if defined(PIC)
- "pop %%"REG_b" \n\t"
-#endif
- : "+a" (counter)
- : "c" (filter), "d" (filterPos), "S" (src), "D" (dst)
-#if !defined(PIC)
- : "%"REG_b
-#endif
- );
- } else {
- const uint8_t *offset = src+filterSize;
- x86_reg counter= -2*dstW;
- //filter-= counter*filterSize/2;
- filterPos-= counter/2;
- dst-= counter/2;
- __asm__ volatile(
- "pxor %%mm7, %%mm7 \n\t"
- ".p2align 4 \n\t"
- "1: \n\t"
- "mov %2, %%"REG_c" \n\t"
- "movzwl (%%"REG_c", %0), %%eax \n\t"
- "movzwl 2(%%"REG_c", %0), %%edx \n\t"
- "mov %5, %%"REG_c" \n\t"
- "pxor %%mm4, %%mm4 \n\t"
- "pxor %%mm5, %%mm5 \n\t"
- "2: \n\t"
- "movq (%1), %%mm1 \n\t"
- "movq (%1, %6), %%mm3 \n\t"
- "movd (%%"REG_c", %%"REG_a"), %%mm0 \n\t"
- "movd (%%"REG_c", %%"REG_d"), %%mm2 \n\t"
- "punpcklbw %%mm7, %%mm0 \n\t"
- "punpcklbw %%mm7, %%mm2 \n\t"
- "pmaddwd %%mm1, %%mm0 \n\t"
- "pmaddwd %%mm2, %%mm3 \n\t"
- "paddd %%mm3, %%mm5 \n\t"
- "paddd %%mm0, %%mm4 \n\t"
- "add $8, %1 \n\t"
- "add $4, %%"REG_c" \n\t"
- "cmp %4, %%"REG_c" \n\t"
- " jb 2b \n\t"
- "add %6, %1 \n\t"
- "movq %%mm4, %%mm0 \n\t"
- "punpckldq %%mm5, %%mm4 \n\t"
- "punpckhdq %%mm5, %%mm0 \n\t"
- "paddd %%mm0, %%mm4 \n\t"
- "psrad $7, %%mm4 \n\t"
- "packssdw %%mm4, %%mm4 \n\t"
- "mov %3, %%"REG_a" \n\t"
- "movd %%mm4, (%%"REG_a", %0) \n\t"
- "add $4, %0 \n\t"
- " jnc 1b \n\t"
-
- : "+r" (counter), "+r" (filter)
- : "m" (filterPos), "m" (dst), "m"(offset),
- "m" (src), "r" ((x86_reg)filterSize*2)
- : "%"REG_a, "%"REG_c, "%"REG_d
- );
- }
-}
-#endif /* !COMPILE_TEMPLATE_MMX2 */
-
#if COMPILE_TEMPLATE_MMX2
static void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst,
int dstWidth, const uint8_t *src,
@@ -2207,8 +1789,6 @@ static av_cold void RENAME(sws_init_swScale)(SwsContext *c)
dstFormat != PIX_FMT_NV12 && dstFormat != PIX_FMT_NV21) {
if (!(c->flags & SWS_BITEXACT)) {
if (c->flags & SWS_ACCURATE_RND) {
- c->yuv2yuv1 = RENAME(yuv2yuv1_ar );
- c->yuv2yuvX = RENAME(yuv2yuvX_ar );
if (!(c->flags & SWS_FULL_CHR_H_INT)) {
switch (c->dstFormat) {
case PIX_FMT_RGB32: c->yuv2packedX = RENAME(yuv2rgb32_X_ar); break;
@@ -2220,8 +1800,6 @@ static av_cold void RENAME(sws_init_swScale)(SwsContext *c)
}
}
} else {
- c->yuv2yuv1 = RENAME(yuv2yuv1 );
- c->yuv2yuvX = RENAME(yuv2yuvX );
if (!(c->flags & SWS_FULL_CHR_H_INT)) {
switch (c->dstFormat) {
case PIX_FMT_RGB32: c->yuv2packedX = RENAME(yuv2rgb32_X); break;
@@ -2262,10 +1840,7 @@ static av_cold void RENAME(sws_init_swScale)(SwsContext *c)
}
}
-#if !COMPILE_TEMPLATE_MMX2
- c->hScale = RENAME(hScale );
-#endif /* !COMPILE_TEMPLATE_MMX2 */
-
+ if (c->srcBpc == 8 && c->dstBpc <= 10) {
// Use the new MMX scaler if the MMX2 one can't be used (it is faster than the x86 ASM one).
#if COMPILE_TEMPLATE_MMX2
if (c->flags & SWS_FAST_BILINEAR && c->canMMX2BeUsed)
@@ -2279,6 +1854,7 @@ static av_cold void RENAME(sws_init_swScale)(SwsContext *c)
#if COMPILE_TEMPLATE_MMX2
}
#endif /* COMPILE_TEMPLATE_MMX2 */
+ }
#if !COMPILE_TEMPLATE_MMX2
switch(srcFormat) {
@@ -2286,12 +1862,6 @@ static av_cold void RENAME(sws_init_swScale)(SwsContext *c)
case PIX_FMT_UYVY422 : c->chrToYV12 = RENAME(uyvyToUV); break;
case PIX_FMT_NV12 : c->chrToYV12 = RENAME(nv12ToUV); break;
case PIX_FMT_NV21 : c->chrToYV12 = RENAME(nv21ToUV); break;
- case PIX_FMT_YUV420P16BE:
- case PIX_FMT_YUV422P16BE:
- case PIX_FMT_YUV444P16BE: c->chrToYV12 = RENAME(BEToUV); break;
- case PIX_FMT_YUV420P16LE:
- case PIX_FMT_YUV422P16LE:
- case PIX_FMT_YUV444P16LE: c->chrToYV12 = RENAME(LEToUV); break;
default: break;
}
#endif /* !COMPILE_TEMPLATE_MMX2 */
@@ -2306,16 +1876,8 @@ static av_cold void RENAME(sws_init_swScale)(SwsContext *c)
switch (srcFormat) {
#if !COMPILE_TEMPLATE_MMX2
case PIX_FMT_YUYV422 :
- case PIX_FMT_YUV420P16BE:
- case PIX_FMT_YUV422P16BE:
- case PIX_FMT_YUV444P16BE:
- case PIX_FMT_Y400A :
- case PIX_FMT_GRAY16BE : c->lumToYV12 = RENAME(yuy2ToY); break;
- case PIX_FMT_UYVY422 :
- case PIX_FMT_YUV420P16LE:
- case PIX_FMT_YUV422P16LE:
- case PIX_FMT_YUV444P16LE:
- case PIX_FMT_GRAY16LE : c->lumToYV12 = RENAME(uyvyToY); break;
+ case PIX_FMT_Y400A : c->lumToYV12 = RENAME(yuy2ToY); break;
+ case PIX_FMT_UYVY422 : c->lumToYV12 = RENAME(uyvyToY); break;
#endif /* !COMPILE_TEMPLATE_MMX2 */
case PIX_FMT_BGR24 : c->lumToYV12 = RENAME(bgr24ToY); break;
case PIX_FMT_RGB24 : c->lumToYV12 = RENAME(rgb24ToY); break;
diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
index cad0933..39c8b9c 100644
--- a/libswscale/yuv2rgb.c
+++ b/libswscale/yuv2rgb.c
@@ -788,8 +788,8 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int
y_table32 = c->yuvTable;
yb = -(384<<16) - oy;
for (i = 0; i < 1024; i++) {
- uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
- y_table32[i ] = (yval << rbase) + (needAlpha ? 0 : (255 << abase));
+ unsigned yval = av_clip_uint8((yb + 0x8000) >> 16);
+ y_table32[i ] = (yval << rbase) + (needAlpha ? 0 : (255u << abase));
y_table32[i+1024] = yval << gbase;
y_table32[i+2048] = yval << bbase;
yb += cy;
diff --git a/presets/libvpx-1080p.avpreset b/presets/libvpx-1080p.avpreset
new file mode 100644
index 0000000..5c7da6f
--- /dev/null
+++ b/presets/libvpx-1080p.avpreset
@@ -0,0 +1,17 @@
+g=120
+lag-in-frames=16
+deadline=good
+cpu-used=0
+profile=1
+qmax=51
+qmin=11
+slices=4
+b=2M
+
+#ignored unless using -pass 2
+maxrate=24M
+minrate=100k
+auto-alt-ref=1
+arnr-maxframes=7
+arnr-strength=5
+arnr-type=centered
diff --git a/presets/libvpx-1080p50_60.avpreset b/presets/libvpx-1080p50_60.avpreset
new file mode 100644
index 0000000..f85d3d6
--- /dev/null
+++ b/presets/libvpx-1080p50_60.avpreset
@@ -0,0 +1,17 @@
+g=120
+lag-in-frames=25
+deadline=good
+cpu-used=0
+profile=1
+qmax=51
+qmin=11
+slices=4
+b=2M
+
+#ignored unless using -pass 2
+maxrate=24M
+minrate=100k
+auto-alt-ref=1
+arnr-maxframes=7
+arnr-strength=5
+arnr-type=centered
diff --git a/presets/libvpx-360p.avpreset b/presets/libvpx-360p.avpreset
new file mode 100644
index 0000000..2cb9e38
--- /dev/null
+++ b/presets/libvpx-360p.avpreset
@@ -0,0 +1,16 @@
+g=120
+lag-in-frames=16
+deadline=good
+cpu-used=0
+profile=0
+qmax=63
+qmin=0
+b=768k
+
+#ignored unless using -pass 2
+maxrate=1.5M
+minrate=40k
+auto-alt-ref=1
+arnr-maxframes=7
+arnr-strength=5
+arnr-type=centered
diff --git a/presets/libvpx-720p.avpreset b/presets/libvpx-720p.avpreset
new file mode 100644
index 0000000..3c7e396
--- /dev/null
+++ b/presets/libvpx-720p.avpreset
@@ -0,0 +1,17 @@
+g=120
+lag-in-frames=16
+deadline=good
+cpu-used=0
+profile=0
+qmax=51
+qmin=11
+slices=4
+b=2M
+
+#ignored unless using -pass 2
+maxrate=24M
+minrate=100k
+auto-alt-ref=1
+arnr-maxframes=7
+arnr-strength=5
+arnr-type=centered
diff --git a/presets/libvpx-720p50_60.avpreset b/presets/libvpx-720p50_60.avpreset
new file mode 100644
index 0000000..6139300
--- /dev/null
+++ b/presets/libvpx-720p50_60.avpreset
@@ -0,0 +1,17 @@
+g=120
+lag-in-frames=25
+deadline=good
+cpu-used=0
+profile=0
+qmax=51
+qmin=11
+slices=4
+b=2M
+
+#ignored unless using -pass 2
+maxrate=24M
+minrate=100k
+auto-alt-ref=1
+arnr-maxframes=7
+arnr-strength=5
+arnr-type=centered
diff --git a/presets/libx264-baseline.avpreset b/presets/libx264-baseline.avpreset
new file mode 100644
index 0000000..0626e28
--- /dev/null
+++ b/presets/libx264-baseline.avpreset
@@ -0,0 +1 @@
+profile=baseline
diff --git a/presets/libx264-fast.avpreset b/presets/libx264-fast.avpreset
new file mode 100644
index 0000000..a8c526e
--- /dev/null
+++ b/presets/libx264-fast.avpreset
@@ -0,0 +1 @@
+preset=fast
diff --git a/presets/libx264-fast_firstpass.avpreset b/presets/libx264-fast_firstpass.avpreset
new file mode 100644
index 0000000..d9cf5af
--- /dev/null
+++ b/presets/libx264-fast_firstpass.avpreset
@@ -0,0 +1,2 @@
+preset=fast
+fastfirstpass=1
diff --git a/presets/libx264-faster.avpreset b/presets/libx264-faster.avpreset
new file mode 100644
index 0000000..e311989
--- /dev/null
+++ b/presets/libx264-faster.avpreset
@@ -0,0 +1 @@
+preset=faster
diff --git a/presets/libx264-faster_firstpass.avpreset b/presets/libx264-faster_firstpass.avpreset
new file mode 100644
index 0000000..48a2d44
--- /dev/null
+++ b/presets/libx264-faster_firstpass.avpreset
@@ -0,0 +1,2 @@
+preset=faster
+fastfirstpass=1
diff --git a/presets/libx264-ipod320.avpreset b/presets/libx264-ipod320.avpreset
new file mode 100644
index 0000000..6323191
--- /dev/null
+++ b/presets/libx264-ipod320.avpreset
@@ -0,0 +1,4 @@
+profile=baseline
+level=13
+maxrate=768000
+bufsize=3000000
diff --git a/presets/libx264-ipod640.avpreset b/presets/libx264-ipod640.avpreset
new file mode 100644
index 0000000..c2c3e1a
--- /dev/null
+++ b/presets/libx264-ipod640.avpreset
@@ -0,0 +1,4 @@
+profile=baseline
+level=30
+maxrate=10000000
+bufsize=10000000
diff --git a/presets/libx264-lossless_fast.avpreset b/presets/libx264-lossless_fast.avpreset
new file mode 100644
index 0000000..1658d56
--- /dev/null
+++ b/presets/libx264-lossless_fast.avpreset
@@ -0,0 +1,2 @@
+preset=fast
+qp=0
diff --git a/presets/libx264-lossless_max.avpreset b/presets/libx264-lossless_max.avpreset
new file mode 100644
index 0000000..c25ff32
--- /dev/null
+++ b/presets/libx264-lossless_max.avpreset
@@ -0,0 +1,2 @@
+preset=placebo
+qp=0
diff --git a/presets/libx264-lossless_medium.avpreset b/presets/libx264-lossless_medium.avpreset
new file mode 100644
index 0000000..f7b1d81
--- /dev/null
+++ b/presets/libx264-lossless_medium.avpreset
@@ -0,0 +1,2 @@
+preset=medium
+qp=0
diff --git a/presets/libx264-lossless_slow.avpreset b/presets/libx264-lossless_slow.avpreset
new file mode 100644
index 0000000..a15ff4c
--- /dev/null
+++ b/presets/libx264-lossless_slow.avpreset
@@ -0,0 +1,2 @@
+preset=slow
+qp=0
diff --git a/presets/libx264-lossless_slower.avpreset b/presets/libx264-lossless_slower.avpreset
new file mode 100644
index 0000000..bd71f03
--- /dev/null
+++ b/presets/libx264-lossless_slower.avpreset
@@ -0,0 +1,2 @@
+preset=slower
+qp=0
diff --git a/presets/libx264-lossless_ultrafast.avpreset b/presets/libx264-lossless_ultrafast.avpreset
new file mode 100644
index 0000000..4d71eb7
--- /dev/null
+++ b/presets/libx264-lossless_ultrafast.avpreset
@@ -0,0 +1,2 @@
+preset=ultrafast
+qp=0
diff --git a/presets/libx264-main.avpreset b/presets/libx264-main.avpreset
new file mode 100644
index 0000000..336c69b
--- /dev/null
+++ b/presets/libx264-main.avpreset
@@ -0,0 +1 @@
+profile=main
diff --git a/presets/libx264-medium.avpreset b/presets/libx264-medium.avpreset
new file mode 100644
index 0000000..261d584
--- /dev/null
+++ b/presets/libx264-medium.avpreset
@@ -0,0 +1 @@
+preset=medium
diff --git a/presets/libx264-medium_firstpass.avpreset b/presets/libx264-medium_firstpass.avpreset
new file mode 100644
index 0000000..06c8f9f
--- /dev/null
+++ b/presets/libx264-medium_firstpass.avpreset
@@ -0,0 +1,2 @@
+preset=medium
+fastfirstpass=1
diff --git a/presets/libx264-placebo.avpreset b/presets/libx264-placebo.avpreset
new file mode 100644
index 0000000..93d721d
--- /dev/null
+++ b/presets/libx264-placebo.avpreset
@@ -0,0 +1 @@
+preset=placebo
diff --git a/presets/libx264-placebo_firstpass.avpreset b/presets/libx264-placebo_firstpass.avpreset
new file mode 100644
index 0000000..c8099e5
--- /dev/null
+++ b/presets/libx264-placebo_firstpass.avpreset
@@ -0,0 +1,2 @@
+preset=placebo
+fastfirstpass=1
diff --git a/presets/libx264-slow.avpreset b/presets/libx264-slow.avpreset
new file mode 100644
index 0000000..85778ec
--- /dev/null
+++ b/presets/libx264-slow.avpreset
@@ -0,0 +1 @@
+preset=slow
diff --git a/presets/libx264-slow_firstpass.avpreset b/presets/libx264-slow_firstpass.avpreset
new file mode 100644
index 0000000..9998bc9
--- /dev/null
+++ b/presets/libx264-slow_firstpass.avpreset
@@ -0,0 +1,2 @@
+preset=slow
+fastfirstpass=1
diff --git a/presets/libx264-slower.avpreset b/presets/libx264-slower.avpreset
new file mode 100644
index 0000000..87d6989
--- /dev/null
+++ b/presets/libx264-slower.avpreset
@@ -0,0 +1 @@
+preset=slower
diff --git a/presets/libx264-slower_firstpass.avpreset b/presets/libx264-slower_firstpass.avpreset
new file mode 100644
index 0000000..c798b82
--- /dev/null
+++ b/presets/libx264-slower_firstpass.avpreset
@@ -0,0 +1,2 @@
+preset=slower
+fastfirstpass=1
diff --git a/presets/libx264-superfast.avpreset b/presets/libx264-superfast.avpreset
new file mode 100644
index 0000000..1c117ec
--- /dev/null
+++ b/presets/libx264-superfast.avpreset
@@ -0,0 +1 @@
+preset=superfast
diff --git a/presets/libx264-superfast_firstpass.avpreset b/presets/libx264-superfast_firstpass.avpreset
new file mode 100644
index 0000000..fc70e09
--- /dev/null
+++ b/presets/libx264-superfast_firstpass.avpreset
@@ -0,0 +1,2 @@
+preset=superfast
+fastfirstpass=1
diff --git a/presets/libx264-ultrafast.avpreset b/presets/libx264-ultrafast.avpreset
new file mode 100644
index 0000000..9103301
--- /dev/null
+++ b/presets/libx264-ultrafast.avpreset
@@ -0,0 +1 @@
+preset=ultrafast
diff --git a/presets/libx264-ultrafast_firstpass.avpreset b/presets/libx264-ultrafast_firstpass.avpreset
new file mode 100644
index 0000000..e3aaa17
--- /dev/null
+++ b/presets/libx264-ultrafast_firstpass.avpreset
@@ -0,0 +1,2 @@
+preset=ultrafast
+fastfirstpass=1
diff --git a/presets/libx264-veryfast.avpreset b/presets/libx264-veryfast.avpreset
new file mode 100644
index 0000000..fa49629
--- /dev/null
+++ b/presets/libx264-veryfast.avpreset
@@ -0,0 +1 @@
+preset=veryfast
diff --git a/presets/libx264-veryfast_firstpass.avpreset b/presets/libx264-veryfast_firstpass.avpreset
new file mode 100644
index 0000000..4909030
--- /dev/null
+++ b/presets/libx264-veryfast_firstpass.avpreset
@@ -0,0 +1,2 @@
+preset=veryfast
+fastfirstpass=1
diff --git a/presets/libx264-veryslow.avpreset b/presets/libx264-veryslow.avpreset
new file mode 100644
index 0000000..7e01c8f
--- /dev/null
+++ b/presets/libx264-veryslow.avpreset
@@ -0,0 +1 @@
+preset=veryslow
diff --git a/presets/libx264-veryslow_firstpass.avpreset b/presets/libx264-veryslow_firstpass.avpreset
new file mode 100644
index 0000000..daf5a8f
--- /dev/null
+++ b/presets/libx264-veryslow_firstpass.avpreset
@@ -0,0 +1,2 @@
+preset=veryslow
+fastfirstpass=1
diff --git a/subdir.mak b/subdir.mak
deleted file mode 100644
index 1d5824b..0000000
--- a/subdir.mak
+++ /dev/null
@@ -1,100 +0,0 @@
-SRC_DIR := $(SRC_PATH_BARE)/lib$(NAME)
-
-include $(SUBDIR)../common.mak
-
-LIBVERSION := $(lib$(NAME)_VERSION)
-LIBMAJOR := $(lib$(NAME)_VERSION_MAJOR)
-INCINSTDIR := $(INCDIR)/lib$(NAME)
-THIS_LIB := $(SUBDIR)$($(CONFIG_SHARED:yes=S)LIBNAME)
-
-all-$(CONFIG_STATIC): $(SUBDIR)$(LIBNAME)
-all-$(CONFIG_SHARED): $(SUBDIR)$(SLIBNAME)
-
-$(SUBDIR)%-test.o: $(SUBDIR)%-test.c
- $(CC) $(CPPFLAGS) $(CFLAGS) -DTEST -c $(CC_O) $^
-
-$(SUBDIR)%-test.o: $(SUBDIR)%.c
- $(CC) $(CPPFLAGS) $(CFLAGS) -DTEST -c $(CC_O) $^
-
-$(SUBDIR)x86/%.o: $(SUBDIR)x86/%.asm
- $(YASMDEP) $(YASMFLAGS) -I $(<D)/ -M -o $@ $< > $(@:.o=.d)
- $(YASM) $(YASMFLAGS) -I $(<D)/ -o $@ $<
-
-$(OBJS) $(SUBDIR)%.ho $(SUBDIR)%-test.o $(TESTOBJS): CPPFLAGS += -DHAVE_AV_CONFIG_H
-
-$(SUBDIR)$(LIBNAME): $(OBJS)
- $(RM) $@
- $(AR) rc $@ $^ $(EXTRAOBJS)
- $(RANLIB) $@
-
-install-headers: install-lib$(NAME)-headers install-lib$(NAME)-pkgconfig
-
-install-libs-$(CONFIG_STATIC): install-lib$(NAME)-static
-install-libs-$(CONFIG_SHARED): install-lib$(NAME)-shared
-
-define RULES
-$(SUBDIR)%$(EXESUF): $(SUBDIR)%.o
- $$(LD) $(FFLDFLAGS) -o $$@ $$^ -l$(FULLNAME) $(FFEXTRALIBS) $$(ELIBS)
-
-$(SUBDIR)$(SLIBNAME): $(SUBDIR)$(SLIBNAME_WITH_MAJOR)
- $(Q)cd ./$(SUBDIR) && $(LN_S) $(SLIBNAME_WITH_MAJOR) $(SLIBNAME)
-
-$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SUBDIR)lib$(NAME).ver
- $(SLIB_CREATE_DEF_CMD)
- $$(LD) $(SHFLAGS) $(FFLDFLAGS) -o $$@ $$(filter %.o,$$^) $(FFEXTRALIBS) $(EXTRAOBJS)
- $(SLIB_EXTRA_CMD)
-
-ifdef SUBDIR
-$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(DEP_LIBS)
-endif
-
-clean::
- $(RM) $(addprefix $(SUBDIR),*-example$(EXESUF) *-test$(EXESUF) $(CLEANFILES) $(CLEANSUFFIXES) $(LIBSUFFIXES)) \
- $(foreach dir,$(DIRS),$(CLEANSUFFIXES:%=$(SUBDIR)$(dir)/%)) \
- $(HOSTOBJS) $(HOSTPROGS)
-
-distclean:: clean
- $(RM) $(DISTCLEANSUFFIXES:%=$(SUBDIR)%) \
- $(foreach dir,$(DIRS),$(DISTCLEANSUFFIXES:%=$(SUBDIR)$(dir)/%))
-
-install-lib$(NAME)-shared: $(SUBDIR)$(SLIBNAME)
- $(Q)mkdir -p "$(SHLIBDIR)"
- $$(INSTALL) -m 755 $$< "$(SHLIBDIR)/$(SLIBNAME_WITH_VERSION)"
- $(Q)cd "$(SHLIBDIR)" && \
- $(LN_S) $(SLIBNAME_WITH_VERSION) $(SLIBNAME_WITH_MAJOR)
- $(Q)cd "$(SHLIBDIR)" && \
- $(LN_S) $(SLIBNAME_WITH_VERSION) $(SLIBNAME)
- $(SLIB_INSTALL_EXTRA_CMD)
-
-install-lib$(NAME)-static: $(SUBDIR)$(LIBNAME)
- $(Q)mkdir -p "$(LIBDIR)"
- $$(INSTALL) -m 644 $$< "$(LIBDIR)"
- $(LIB_INSTALL_EXTRA_CMD)
-
-install-lib$(NAME)-headers: $(addprefix $(SUBDIR),$(HEADERS) $(BUILT_HEADERS))
- $(Q)mkdir -p "$(INCINSTDIR)"
- $$(INSTALL) -m 644 $$^ "$(INCINSTDIR)"
-
-install-lib$(NAME)-pkgconfig: $(SUBDIR)lib$(NAME).pc
- $(Q)mkdir -p "$(LIBDIR)/pkgconfig"
- $$(INSTALL) -m 644 $$^ "$(LIBDIR)/pkgconfig"
-
-uninstall-libs::
- -$(RM) "$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR)" \
- "$(SHLIBDIR)/$(SLIBNAME)" \
- "$(SHLIBDIR)/$(SLIBNAME_WITH_VERSION)"
- -$(SLIB_UNINSTALL_EXTRA_CMD)
- -$(RM) "$(LIBDIR)/$(LIBNAME)"
-
-uninstall-headers::
- $(RM) $(addprefix "$(INCINSTDIR)/",$(HEADERS))
- $(RM) "$(LIBDIR)/pkgconfig/lib$(NAME).pc"
- -rmdir "$(INCDIR)"
-endef
-
-$(eval $(RULES))
-
-$(EXAMPLES) $(TESTPROGS): $(THIS_LIB) $(DEP_LIBS)
-
-examples: $(EXAMPLES)
-testprogs: $(TESTPROGS)
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..d36fa5c
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,128 @@
+AREF = fate-acodec-aref
+VREF = fate-vsynth1-vref fate-vsynth2-vref
+REFS = $(AREF) $(VREF)
+
+$(VREF): avconv$(EXESUF) tests/vsynth1/00.pgm tests/vsynth2/00.pgm
+$(AREF): avconv$(EXESUF) tests/data/asynth1.sw
+
+tests/vsynth1/00.pgm: tests/videogen$(HOSTEXESUF)
+ @mkdir -p tests/vsynth1
+ $(M)./$< 'tests/vsynth1/'
+
+tests/vsynth2/00.pgm: tests/rotozoom$(HOSTEXESUF)
+ @mkdir -p tests/vsynth2
+ $(M)./$< 'tests/vsynth2/' $(SRC_PATH)/tests/lena.pnm
+
+tests/data/asynth1.sw: tests/audiogen$(HOSTEXESUF)
+ @mkdir -p tests/data
+ $(M)./$< $@
+
+tests/data/asynth-16000-1.sw: tests/audiogen$(HOSTEXESUF)
+ @mkdir -p tests/data
+ $(M)./$< $@ 16000 1
+
+tests/data/asynth%.sw tests/vsynth%/00.pgm: TAG = GEN
+
+include $(SRC_PATH)/tests/fate.mak
+include $(SRC_PATH)/tests/fate2.mak
+
+include $(SRC_PATH)/tests/fate/aac.mak
+include $(SRC_PATH)/tests/fate/ac3.mak
+include $(SRC_PATH)/tests/fate/als.mak
+include $(SRC_PATH)/tests/fate/amrnb.mak
+include $(SRC_PATH)/tests/fate/amrwb.mak
+include $(SRC_PATH)/tests/fate/atrac.mak
+include $(SRC_PATH)/tests/fate/dct.mak
+include $(SRC_PATH)/tests/fate/dpcm.mak
+include $(SRC_PATH)/tests/fate/fft.mak
+include $(SRC_PATH)/tests/fate/h264.mak
+include $(SRC_PATH)/tests/fate/image.mak
+include $(SRC_PATH)/tests/fate/indeo.mak
+include $(SRC_PATH)/tests/fate/libavcodec.mak
+include $(SRC_PATH)/tests/fate/libavutil.mak
+include $(SRC_PATH)/tests/fate/lossless-audio.mak
+include $(SRC_PATH)/tests/fate/lossless-video.mak
+include $(SRC_PATH)/tests/fate/microsoft.mak
+include $(SRC_PATH)/tests/fate/mp3.mak
+include $(SRC_PATH)/tests/fate/mpc.mak
+include $(SRC_PATH)/tests/fate/pcm.mak
+include $(SRC_PATH)/tests/fate/prores.mak
+include $(SRC_PATH)/tests/fate/qtrle.mak
+include $(SRC_PATH)/tests/fate/real.mak
+include $(SRC_PATH)/tests/fate/screen.mak
+include $(SRC_PATH)/tests/fate/utvideo.mak
+include $(SRC_PATH)/tests/fate/vorbis.mak
+include $(SRC_PATH)/tests/fate/vpx.mak
+include $(SRC_PATH)/tests/fate/vqf.mak
+include $(SRC_PATH)/tests/fate/wma.mak
+
+FATE_ACODEC = $(ACODEC_TESTS:%=fate-acodec-%)
+FATE_VSYNTH1 = $(VCODEC_TESTS:%=fate-vsynth1-%)
+FATE_VSYNTH2 = $(VCODEC_TESTS:%=fate-vsynth2-%)
+FATE_VCODEC = $(FATE_VSYNTH1) $(FATE_VSYNTH2)
+FATE_LAVF = $(LAVF_TESTS:%=fate-lavf-%)
+FATE_LAVFI = $(LAVFI_TESTS:%=fate-lavfi-%)
+FATE_SEEK = $(SEEK_TESTS:seek_%=fate-seek-%)
+
+FATE = $(FATE_ACODEC) \
+ $(FATE_VCODEC) \
+ $(FATE_LAVF) \
+ $(FATE_SEEK) \
+
+FATE-$(CONFIG_AVFILTER) += $(FATE_LAVFI)
+
+FATE += $(FATE-yes)
+
+$(filter-out %-aref,$(FATE_ACODEC)): $(AREF)
+$(filter-out %-vref,$(FATE_VSYNTH1)): fate-vsynth1-vref
+$(filter-out %-vref,$(FATE_VSYNTH2)): fate-vsynth2-vref
+$(FATE_LAVF): $(REFS)
+$(FATE_LAVFI): $(REFS) tools/lavfi-showfiltfmts$(EXESUF)
+$(FATE_SEEK): fate-codec fate-lavf libavformat/seek-test$(EXESUF)
+
+$(FATE_ACODEC): CMD = codectest acodec
+$(FATE_VSYNTH1): CMD = codectest vsynth1
+$(FATE_VSYNTH2): CMD = codectest vsynth2
+$(FATE_LAVF): CMD = lavftest
+$(FATE_LAVFI): CMD = lavfitest
+$(FATE_SEEK): CMD = seektest
+
+fate-codec: fate-acodec fate-vcodec
+fate-acodec: $(FATE_ACODEC)
+fate-vcodec: $(FATE_VCODEC)
+fate-lavf: $(FATE_LAVF)
+fate-lavfi: $(FATE_LAVFI)
+fate-seek: $(FATE_SEEK)
+
+ifdef SAMPLES
+FATE += $(FATE_TESTS) $(FATE_TESTS-yes)
+fate-rsync:
+ rsync -vaLW rsync://fate-suite.libav.org/fate-suite/ $(SAMPLES)
+else
+fate-rsync:
+ @echo "use 'make fate-rsync SAMPLES=/path/to/samples' to sync the fate suite"
+$(FATE_TESTS):
+ @echo "SAMPLES not specified, cannot run FATE"
+endif
+
+FATE_UTILS = base64 tiny_psnr
+
+fate: $(FATE)
+
+$(FATE): avconv$(EXESUF) $(FATE_UTILS:%=tests/%$(HOSTEXESUF))
+ @echo "TEST $(@:fate-%=%)"
+ $(Q)$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)' '$(CMP)' '$(REF)' '$(FUZZ)' '$(THREADS)' '$(THREAD_TYPE)'
+
+fate-list:
+ @printf '%s\n' $(sort $(FATE))
+
+clean:: testclean
+
+testclean:
+ $(RM) -r tests/vsynth1 tests/vsynth2 tests/data
+ $(RM) $(CLEANSUFFIXES:%=tests/%)
+ $(RM) $(TESTTOOLS:%=tests/%$(HOSTEXESUF))
+
+-include $(wildcard tests/*.d)
+
+.PHONY: fate*
diff --git a/tests/audiogen.c b/tests/audiogen.c
index ddd1e18..d48b591 100644
--- a/tests/audiogen.c
+++ b/tests/audiogen.c
@@ -1,6 +1,6 @@
/*
- * Generates a synthetic stereo sound
- * NOTE: No floats are used to guarantee a bit exact output.
+ * Generate a synthetic stereo sound.
+ * NOTE: No floats are used to guarantee bitexact output.
*
* Copyright (c) 2002 Fabrice Bellard
*
diff --git a/tests/codec-regression.sh b/tests/codec-regression.sh
index a858250..e20bf64 100755
--- a/tests/codec-regression.sh
+++ b/tests/codec-regression.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# automatic regression test for ffmpeg
+# automatic regression test for avconv
#
#
#set -x
@@ -11,14 +11,17 @@ set -e
eval do_$test=y
-rm -f "$logfile"
-
# generate reference for quality check
if [ -n "$do_vref" ]; then
-do_ffmpeg $raw_ref -f image2 -vcodec pgmyuv -i $raw_src -an -f rawvideo
+do_avconv $raw_ref -f image2 -vcodec pgmyuv -i $raw_src -an -f rawvideo
fi
if [ -n "$do_aref" ]; then
-do_ffmpeg $pcm_ref -ab 128k -ac 2 -ar 44100 -f s16le -i $pcm_src -f wav
+do_avconv $pcm_ref -b 128k -ac 2 -ar 44100 -f s16le -i $pcm_src -f wav
+fi
+
+if [ -n "$do_cljr" ] ; then
+do_video_encoding cljr.avi "-an -vcodec cljr"
+do_video_decoding
fi
if [ -n "$do_mpeg" ] ; then
@@ -31,19 +34,27 @@ if [ -n "$do_mpeg2" ] ; then
# mpeg2
do_video_encoding mpeg2.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video"
do_video_decoding
+fi
+if [ -n "$do_mpeg2_ivlc_qprd" ]; then
# mpeg2 encoding intra vlc qprd
do_video_encoding mpeg2ivlc-qprd.mpg "-vb 500k -bf 2 -trellis 1 -flags +qprd+mv0 -flags2 +ivlc -cmp 2 -subcmp 2 -mbd rd -vcodec mpeg2video -f mpeg2video"
do_video_decoding
+fi
+if [ -n "$do_mpeg2_422" ]; then
#mpeg2 4:2:2 encoding
do_video_encoding mpeg2_422.mpg "-vb 1000k -bf 2 -trellis 1 -flags +qprd+mv0+ildct+ilme -flags2 +ivlc -mbd rd -vcodec mpeg2video -pix_fmt yuv422p -f mpeg2video"
do_video_decoding
+fi
+if [ -n "$do_mpeg2_idct_int" ]; then
# mpeg2
-do_video_encoding mpeg2.mpg "-qscale 10 -vcodec mpeg2video -idct int -dct int -f mpeg1video"
+do_video_encoding mpeg2_idct_int.mpg "-qscale 10 -vcodec mpeg2video -idct int -dct int -f mpeg1video"
do_video_decoding "-idct int"
+fi
+if [ -n "$do_mpeg2_ilace" ]; then
# mpeg2 encoding interlaced
do_video_encoding mpeg2i.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video -flags +ildct+ilme"
do_video_decoding
@@ -53,15 +64,12 @@ if [ -n "$do_mpeg2thread" ] ; then
# mpeg2 encoding interlaced
do_video_encoding mpeg2thread.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -threads 2"
do_video_decoding
+fi
+if [ -n "$do_mpeg2thread_ilace" ]; then
# mpeg2 encoding interlaced using intra vlc
do_video_encoding mpeg2threadivlc.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -flags2 +ivlc -threads 2"
do_video_decoding
-
-# mpeg2 encoding interlaced
-file=${outfile}mpeg2reuse.mpg
-do_ffmpeg $file $DEC_OPTS -me_threshold 256 -i ${target_path}/${outfile}mpeg2thread.mpg $ENC_OPTS -sameq -me_threshold 256 -mb_threshold 1024 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -threads 4
-do_video_decoding
fi
if [ -n "$do_msmpeg4v2" ] ; then
@@ -117,13 +125,19 @@ fi
if [ -n "$do_mpeg4adv" ] ; then
do_video_encoding mpeg4-adv.avi "-qscale 9 -flags +mv4+part+aic -trellis 1 -mbd bits -ps 200 -an -vcodec mpeg4"
do_video_decoding
+fi
+if [ -n "$do_mpeg4_qprd" ]; then
do_video_encoding mpeg4-qprd.avi "-b 450k -bf 2 -trellis 1 -flags +mv4+qprd+mv0 -cmp 2 -subcmp 2 -mbd rd -an -vcodec mpeg4"
do_video_decoding
+fi
+if [ -n "$do_mpeg4_adap" ]; then
do_video_encoding mpeg4-adap.avi "-b 550k -bf 2 -flags +mv4+mv0 -trellis 1 -cmp 1 -subcmp 2 -mbd rd -scplx_mask 0.3 -an -vcodec mpeg4"
do_video_decoding
+fi
+if [ -n "$do_mpeg4_qpel" ]; then
do_video_encoding mpeg4-Q.avi "-qscale 7 -flags +mv4+qpel -mbd 2 -bf 2 -cmp 1 -subcmp 2 -an -vcodec mpeg4"
do_video_decoding
fi
@@ -206,7 +220,9 @@ fi
if [ -n "$do_dv" ] ; then
do_video_encoding dv.dv "-dct int -s pal -an"
do_video_decoding "" "-s cif"
+fi
+if [ -n "$do_dv_411" ]; then
do_video_encoding dv411.dv "-dct int -s pal -an -pix_fmt yuv411p -sws_flags area+accurate_rnd+bitexact"
do_video_decoding "" "-s cif -sws_flags area+accurate_rnd+bitexact"
fi
@@ -232,6 +248,11 @@ do_video_encoding dnxhd-720p-rd.dnxhd "-threads 4 -mbd rd -s hd720 -b 90M -pix_f
do_video_decoding "" "-s cif -pix_fmt yuv420p"
fi
+if [ -n "$do_dnxhd_720p_10bit" ] ; then
+do_video_encoding dnxhd-720p-10bit.dnxhd "-s hd720 -b 90M -pix_fmt yuv422p10 -vframes 5 -an"
+do_video_decoding "" "-s cif -pix_fmt yuv420p"
+fi
+
if [ -n "$do_svq1" ] ; then
do_video_encoding svq1.mov "-an -vcodec svq1 -qscale 3 -pix_fmt yuv410p"
do_video_decoding "" "-pix_fmt yuv420p"
@@ -257,6 +278,11 @@ do_video_encoding rgb.avi "-an -vcodec rawvideo -pix_fmt bgr24"
do_video_decoding "" "-pix_fmt yuv420p"
fi
+if [ -n "$do_v210" ] ; then
+do_video_encoding v210.avi "-an -c:v v210"
+do_video_decoding "" "-pix_fmt yuv420p"
+fi
+
if [ -n "$do_yuv" ] ; then
do_video_encoding yuv.avi "-an -vcodec rawvideo -pix_fmt yuv420p"
do_video_decoding "" "-pix_fmt yuv420p"
@@ -265,18 +291,23 @@ fi
if [ -n "$do_mp2" ] ; then
do_audio_encoding mp2.mp2
do_audio_decoding
-$tiny_psnr $pcm_dst $pcm_ref 2 1924 >> $logfile
+$tiny_psnr $pcm_dst $pcm_ref 2 1924
fi
if [ -n "$do_ac3_fixed" ] ; then
do_audio_encoding ac3.rm "-vn -acodec ac3_fixed"
# binaries configured with --disable-sse decode ac3 differently
#do_audio_decoding
-#$tiny_psnr $pcm_dst $pcm_ref 2 1024 >> $logfile
+#$tiny_psnr $pcm_dst $pcm_ref 2 1024
+fi
+
+if [ -n "$do_g722" ] ; then
+do_audio_encoding g722.wav "-b 64k -ac 1 -ar 16000 -acodec g722"
+do_audio_decoding
fi
if [ -n "$do_g726" ] ; then
-do_audio_encoding g726.wav "-ab 32k -ac 1 -ar 8000 -acodec g726"
+do_audio_encoding g726.wav "-b 32k -ac 1 -ar 8000 -acodec g726"
do_audio_decoding
fi
@@ -317,13 +348,13 @@ fi
if [ -n "$do_wmav1" ] ; then
do_audio_encoding wmav1.asf "-acodec wmav1"
-do_ffmpeg_nomd5 $pcm_dst $DEC_OPTS -i $target_path/$file -f wav
-$tiny_psnr $pcm_dst $pcm_ref 2 8192 >> $logfile
+do_avconv_nomd5 $pcm_dst $DEC_OPTS -i $target_path/$file -f wav
+$tiny_psnr $pcm_dst $pcm_ref 2 8192
fi
if [ -n "$do_wmav2" ] ; then
do_audio_encoding wmav2.asf "-acodec wmav2"
-do_ffmpeg_nomd5 $pcm_dst $DEC_OPTS -i $target_path/$file -f wav
-$tiny_psnr $pcm_dst $pcm_ref 2 8192 >> $logfile
+do_avconv_nomd5 $pcm_dst $DEC_OPTS -i $target_path/$file -f wav
+$tiny_psnr $pcm_dst $pcm_ref 2 8192
fi
#if [ -n "$do_vorbis" ] ; then
@@ -338,27 +369,62 @@ do_audio_enc_dec() {
do_audio_decoding
}
-if [ -n "$do_pcm" ] ; then
+if [ -n "$do_pcm_alaw" ] ; then
do_audio_enc_dec wav s16 pcm_alaw
+fi
+if [ -n "$do_pcm_mulaw" ] ; then
do_audio_enc_dec wav s16 pcm_mulaw
+fi
+if [ -n "$do_pcm_s8" ] ; then
do_audio_enc_dec mov u8 pcm_s8
+fi
+if [ -n "$do_pcm_u8" ] ; then
do_audio_enc_dec wav u8 pcm_u8
+fi
+if [ -n "$do_pcm_s16be" ] ; then
do_audio_enc_dec mov s16 pcm_s16be
+fi
+if [ -n "$do_pcm_s16le" ] ; then
do_audio_enc_dec wav s16 pcm_s16le
-do_audio_enc_dec mkv s16 pcm_s16be
-do_audio_enc_dec mkv s16 pcm_s16le
+fi
+if [ -n "$do_pcm_s24be" ] ; then
do_audio_enc_dec mov s32 pcm_s24be
+fi
+if [ -n "$do_pcm_s24le" ] ; then
do_audio_enc_dec wav s32 pcm_s24le
-#do_audio_enc_dec ??? s32 pcm_u24be #no compatible muxer or demuxer
-#do_audio_enc_dec ??? s32 pcm_u24le #no compatible muxer or demuxer
+fi
+# no compatible muxer or demuxer
+# if [ -n "$do_pcm_u24be" ] ; then
+# do_audio_enc_dec ??? u32 pcm_u24be
+# fi
+# if [ -n "$do_pcm_u24le" ] ; then
+# do_audio_enc_dec ??? u32 pcm_u24le
+# fi
+if [ -n "$do_pcm_s32be" ] ; then
do_audio_enc_dec mov s32 pcm_s32be
+fi
+if [ -n "$do_pcm_s32le" ] ; then
do_audio_enc_dec wav s32 pcm_s32le
-#do_audio_enc_dec ??? s32 pcm_u32be #no compatible muxer or demuxer
-#do_audio_enc_dec ??? s32 pcm_u32le #no compatible muxer or demuxer
+fi
+# no compatible muxer or demuxer
+# if [ -n "$do_pcm_u32be" ] ; then
+# do_audio_enc_dec ??? u32 pcm_u32be
+# fi
+# if [ -n "$do_pcm_u32le" ] ; then
+# do_audio_enc_dec ??? u32 pcm_u32le
+# fi
+if [ -n "$do_pcm_f32be" ] ; then
do_audio_enc_dec au flt pcm_f32be
+fi
+if [ -n "$do_pcm_f32le" ] ; then
do_audio_enc_dec wav flt pcm_f32le
+fi
+if [ -n "$do_pcm_f64be" ] ; then
do_audio_enc_dec au dbl pcm_f64be
+fi
+if [ -n "$do_pcm_f64le" ] ; then
do_audio_enc_dec wav dbl pcm_f64le
-do_audio_enc_dec wav s16 pcm_zork
+fi
+if [ -n "$do_pcm_s24daud" ] ; then
do_audio_enc_dec 302 s16 pcm_s24daud "-ac 6 -ar 96000"
fi
diff --git a/tests/copy.regression.ref b/tests/copy.regression.ref
deleted file mode 100644
index 0f62a7b..0000000
--- a/tests/copy.regression.ref
+++ /dev/null
@@ -1,465 +0,0 @@
-----------------
-./tests/data/a-ac3.rm
-first.nut second.nut differ: char 34, line 1
-1dd5a62b7edb3a1bcf77626af0a85bc1 first.nut
-----------------
-./tests/data/a-adpcm_ima.wav
-first.nut second.nut differ: char 34, line 1
-c95390143078f08db8a3bfba5789c2da first.nut
-----------------
-./tests/data/a-adpcm_ms.wav
-first.nut second.nut differ: char 34, line 1
-05e4d8842f4001fed506423e1a8ef963 first.nut
-----------------
-./tests/data/a-adpcm_qt.aiff
-first.nut second.nut differ: char 34, line 1
-7455d87f626f05e20030f4c93ec91e69 first.nut
-----------------
-./tests/data/a-adpcm_swf.flv
-c0402ee010a483403a655f353e184df1 first.nut
-----------------
-./tests/data/a-adpcm_yam.wav
-first.nut second.nut differ: char 34, line 1
-f861047f6c6f75cdf3ce7bb78a4003ad first.nut
-----------------
-./tests/data/a-alac.m4a
-first.nut second.nut differ: char 34, line 1
-ab152b0b01e540e74b04a807e3882083 first.nut
-----------------
-./tests/data/a-asv1.avi
-636fc0dfef1830cc51cf2c182bd4a7b2 first.nut
-----------------
-./tests/data/a-asv2.avi
-bbfc299390378c7bdbd7463434d8fcbe first.nut
-----------------
-./tests/data/a-dnxhd-1080i.mov
-first.nut second.nut differ: char 113, line 1
-037e31900e6cdf7161c2a0df23d9dc9d first.nut
-----------------
-./tests/data/a-dnxhd-720p-rd.dnxhd
-first.nut second.nut differ: char 113, line 1
-1237abac554ea9adb2a926641eec0de0 first.nut
-----------------
-./tests/data/a-dnxhd-720p.dnxhd
-first.nut second.nut differ: char 113, line 1
-6694322cefa2f482bc3dac8be22eb5d5 first.nut
-----------------
-./tests/data/a-dv.dv
-1aa367a56d31bb45f98d820121820909 first.nut
-----------------
-./tests/data/a-dv411.dv
-7ef296512960e00d96850f2606b4b683 first.nut
-----------------
-./tests/data/a-dv50.dv
-6424dd39e22a1789a8182d7e8da224a9 first.nut
-----------------
-./tests/data/a-error-mpeg4-adv.avi
-715b262e3e7c9be2b59525ba0289f30e first.nut
-----------------
-./tests/data/a-ffv1.avi
-edada4da2170ffd3386636cff67a90f0 first.nut
-----------------
-./tests/data/a-flac.flac
-d5e0a6d87034c21627afb2a904412a21 first.nut
-----------------
-./tests/data/a-flashsv.flv
-985076a8a87df1f91b34cbb81ce96217 first.nut
-----------------
-./tests/data/a-flv.flv
-6d01a0eb07c15ec3d0a70bfad0615bec first.nut
-----------------
-./tests/data/a-g726.wav
-first.nut second.nut differ: char 34, line 1
-59540b44c97b8e1eafc53ebdaeaf3eb8 first.nut
-----------------
-./tests/data/a-h261.avi
-18d47cc50e05e5c855a8aec1a5d8d9ec first.nut
-----------------
-./tests/data/a-h263.avi
-91b67a478420a30cf10c3d872f7e799b first.nut
-----------------
-./tests/data/a-h263p.avi
-1e9f108181dca2dd3bb621bb45fc5834 first.nut
-----------------
-./tests/data/a-huffyuv.avi
-62dccc2a428b561c08497f8378ea1567 first.nut
-----------------
-./tests/data/a-jpegls.avi
-35f1bb0f9b14bf3eb29134784f278c4f first.nut
-----------------
-./tests/data/a-ljpeg.avi
-45ec1072d8e55d6cfa784cc732830f3c first.nut
-----------------
-./tests/data/a-mjpeg.avi
-4e6d42fdda880661de8308cfa45652ee first.nut
-----------------
-./tests/data/a-mp2.mp2
-6c8d1a33dd994d63c68e5c9953b5cb8c first.nut
-----------------
-./tests/data/a-mpeg1.mpg
-first.nut second.nut differ: char 34, line 1
-9d444c67713ef70c06d35fd355200ed5 first.nut
-----------------
-./tests/data/a-mpeg1b.mpg
-first.nut second.nut differ: char 34, line 1
-9d444c67713ef70c06d35fd355200ed5 first.nut
-----------------
-./tests/data/a-mpeg2.mpg
-first.nut second.nut differ: char 34, line 1
-328f6a0069b76397c5ed0dcea8b69b50 first.nut
-----------------
-./tests/data/a-mpeg2.mpg
-first.nut second.nut differ: char 34, line 1
-328f6a0069b76397c5ed0dcea8b69b50 first.nut
-----------------
-./tests/data/a-mpeg2_422.mpg
-first.nut second.nut differ: char 34, line 1
-d27035bcf30801cd1bee6ac59e8f5e3e first.nut
-----------------
-./tests/data/a-mpeg2i.mpg
-first.nut second.nut differ: char 34, line 1
-c3351b79649825a6b9f62a2a1db633c1 first.nut
-----------------
-./tests/data/a-mpeg2ivlc-qprd.mpg
-first.nut second.nut differ: char 34, line 1
-d910da52fa10eb1deca10fa9443132d2 first.nut
-----------------
-./tests/data/a-mpeg2reuse.mpg
-first.nut second.nut differ: char 34, line 1
-c3351b79649825a6b9f62a2a1db633c1 first.nut
-----------------
-./tests/data/a-mpeg2thread.mpg
-first.nut second.nut differ: char 34, line 1
-c3351b79649825a6b9f62a2a1db633c1 first.nut
-----------------
-./tests/data/a-mpeg2threadivlc.mpg
-first.nut second.nut differ: char 34, line 1
-c3351b79649825a6b9f62a2a1db633c1 first.nut
-----------------
-./tests/data/a-mpeg4-Q.avi
-first.nut second.nut differ: char 34, line 1
-305bab90451e2c3b741e3aef51bc2a4c first.nut
-----------------
-./tests/data/a-mpeg4-adap.avi
-first.nut second.nut differ: char 34, line 1
-5d9315ec49c4122f6f23cf84cab5fc53 first.nut
-----------------
-./tests/data/a-mpeg4-adv.avi
-5d672bf4c2e879d6a20e349cb4dc09a6 first.nut
-----------------
-./tests/data/a-mpeg4-nr.avi
-0243b2e03115fe948f99da1ee10ae588 first.nut
-----------------
-./tests/data/a-mpeg4-qprd.avi
-first.nut second.nut differ: char 34, line 1
-5d9315ec49c4122f6f23cf84cab5fc53 first.nut
-----------------
-./tests/data/a-mpeg4-rc.avi
-first.nut second.nut differ: char 34, line 1
-5d9315ec49c4122f6f23cf84cab5fc53 first.nut
-----------------
-./tests/data/a-mpeg4-thread.avi
-first.nut second.nut differ: char 34, line 1
-6aa94d589e9e7626e51575d8a2aec6e7 first.nut
-----------------
-./tests/data/a-msmpeg4.avi
-836d432509ff22fd363237ef1dced5f3 first.nut
-----------------
-./tests/data/a-msmpeg4v2.avi
-37f253da3666fb057edecb86ed2dba39 first.nut
-----------------
-./tests/data/a-odivx.mp4
-e3bd9d8a3417abc749c489e64119dbf3 first.nut
-----------------
-./tests/data/a-pcm_alaw.wav
-first.nut second.nut differ: char 34, line 1
-22853e7806b0f0162fd5e2573e34b03c first.nut
-----------------
-./tests/data/a-pcm_f32be.au
-first.nut second.nut differ: char 34, line 1
-94cb60c3107ec509af79191e86099a0e first.nut
-----------------
-./tests/data/a-pcm_f32le.wav
-first.nut second.nut differ: char 34, line 1
-8d887b27a8531390af5b682557631986 first.nut
-----------------
-./tests/data/a-pcm_f64be.au
-first.nut second.nut differ: char 34, line 1
-e0c7b64e13bb9398a57dac60806515fb first.nut
-----------------
-./tests/data/a-pcm_f64le.wav
-first.nut second.nut differ: char 34, line 1
-9dbb9bda0c990502e910e082a008433f first.nut
-----------------
-./tests/data/a-pcm_mulaw.wav
-first.nut second.nut differ: char 34, line 1
-78c4aae32fdddaba4f9caa5683018c94 first.nut
-----------------
-./tests/data/a-pcm_s16be.mkv
-first.nut second.nut differ: char 34, line 1
-279810a0c30a06c4ab7de154e3de140d first.nut
-----------------
-./tests/data/a-pcm_s16be.mov
-first.nut second.nut differ: char 42, line 1
-0a8ede3d121f17a98e9038771eb98e1a first.nut
-----------------
-./tests/data/a-pcm_s16le.mkv
-47942f5188f8d081bcbe7fb82550b135 first.nut
-----------------
-./tests/data/a-pcm_s16le.wav
-first.nut second.nut differ: char 34, line 1
-9f868acb99ba107750f165431f95c382 first.nut
-----------------
-./tests/data/a-pcm_s24be.mov
-first.nut second.nut differ: char 34, line 1
-9c96762f631851014dec14b506091cc1 first.nut
-----------------
-./tests/data/a-pcm_s24daud.302
-60ecb7037b205e2013490fdadab9697b first.nut
-----------------
-./tests/data/a-pcm_s24le.wav
-first.nut second.nut differ: char 34, line 1
-5805a2e6e2eddede4757fd488d0d6adb first.nut
-----------------
-./tests/data/a-pcm_s32be.mov
-first.nut second.nut differ: char 34, line 1
-d6c868a1130be573bbe0cfc88913a60c first.nut
-----------------
-./tests/data/a-pcm_s32le.wav
-first.nut second.nut differ: char 34, line 1
-3e0a81669647739c490f12521f897527 first.nut
-----------------
-./tests/data/a-pcm_s8.mov
-first.nut second.nut differ: char 34, line 1
-a6fe0827966ee4515f27c7053d579229 first.nut
-----------------
-./tests/data/a-pcm_u8.wav
-first.nut second.nut differ: char 34, line 1
-f0d398fd651cdedfd7b4c5433c08fd79 first.nut
-----------------
-./tests/data/a-pcm_zork.wav
-first.nut second.nut differ: char 34, line 1
-69e40cc9266836a7101000677ee14a87 first.nut
-----------------
-./tests/data/a-roqav.roq
-first.nut second.nut differ: char 34, line 1
-0e7a57bb28054b7e319eac2ba0a4be23 first.nut
-----------------
-./tests/data/a-rv10.rm
-first.nut second.nut differ: char 34, line 1
-80f982c6bffea91ff45a9b320cb93c14 first.nut
-----------------
-./tests/data/a-rv20.rm
-first.nut second.nut differ: char 34, line 1
-5b02113c0941578ca6918215eed8a728 first.nut
-----------------
-./tests/data/a-snow.avi
-e73b88690aa491491ede5970641134ad first.nut
-----------------
-./tests/data/a-snow53.avi
-18a6b061252c8c74bd22b42a7d5b2bae first.nut
-----------------
-./tests/data/a-svq1.mov
-first.nut second.nut differ: char 197, line 1
-6bbe90d47c1763654e8388ce51ab911e first.nut
-----------------
-./tests/data/a-wmav1.asf
-first.nut second.nut differ: char 34, line 1
-c3f7bc239ff166d738b29252b47bd437 first.nut
-----------------
-./tests/data/a-wmav2.asf
-first.nut second.nut differ: char 34, line 1
-930f1824b9677f0b6b714f1c6ddcf825 first.nut
-----------------
-./tests/data/a-wmv1.avi
-206bd9985b575f61a8a580656af39beb first.nut
-----------------
-./tests/data/a-wmv2.avi
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-bgr24.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-gray.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-monob.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-monow.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-rgb24.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-rgb32.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-rgb555.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-rgb565.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuv410p.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuv411p.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuv420p.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuv422p.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuv440p.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuv444p.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuvj420p.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuvj422p.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuvj440p.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuvj444p.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf-yuyv422.yuv
-09178a3c2b99d4f7ad1f7a761a2b803a first.nut
-----------------
-./tests/data/b-lavf.aif
-first.nut second.nut differ: char 34, line 1
-3f1d3faae1671f1cf862ddb66a5c59d1 first.nut
-----------------
-./tests/data/b-lavf.al
-e6d4b977e74a535b039a6a1dfed2dbc1 first.nut
-----------------
-./tests/data/b-lavf.asf
-first.nut second.nut differ: char 34, line 1
-57727c41b3974697c0a79cfd08515ddd first.nut
-----------------
-./tests/data/b-lavf.au
-first.nut second.nut differ: char 34, line 1
-1da12f41bc5ea1fd851e8a48b222c204 first.nut
-----------------
-./tests/data/b-lavf.avi
-a88edf9fb8e02e658ba3cae9313a3cdc first.nut
-----------------
-./tests/data/b-lavf.dv
-first.nut second.nut differ: char 34, line 1
-819018a5d91c55312ffe784e8712ac4b first.nut
-----------------
-./tests/data/b-lavf.ffm
-first.nut second.nut differ: char 34, line 1
-17f8894a05c71adb51c9a0ff1b9040bb first.nut
-----------------
-./tests/data/b-lavf.flv
-d74edb56e74e0eea748863f3aeeafa61 first.nut
-----------------
-./tests/data/b-lavf.gif
-first.nut second.nut differ: char 34, line 1
-ef9ba6bf88f44d9d326049ef2872a4d3 first.nut
-----------------
-./tests/data/b-lavf.gxf
-first.nut second.nut differ: char 44, line 1
-522957f46ba46051fd03a0868c905e54 first.nut
-----------------
-./tests/data/b-lavf.mkv
-8c9427bb75c96210d6580d9b881d9e4d first.nut
-----------------
-./tests/data/b-lavf.mmf
-first.nut second.nut differ: char 42, line 1
-298136aef02389fc5b0844995fe6ac72 first.nut
-----------------
-./tests/data/b-lavf.mov
-ce895b33ff206fafbae89fd5a8f959d2 first.nut
-----------------
-./tests/data/b-lavf.mpg
-d279e3343993267241c2fac4f4563cdb first.nut
-----------------
-./tests/data/b-lavf.mxf
-first.nut second.nut differ: char 34, line 1
-3e98a90d40986b8ea4305be06175927a first.nut
-----------------
-./tests/data/b-lavf.mxf_d10
-1ee69644165344a096ddfaaac951a0e9 first.nut
-----------------
-./tests/data/b-lavf.nut
-1426bca4c65796516a3e94b6bebc5a58 first.nut
-----------------
-./tests/data/b-lavf.ogg
-c986ce79045f2068ae1bedc2b8702884 first.nut
-----------------
-./tests/data/b-lavf.rm
-first.nut second.nut differ: char 34, line 1
-a3b2c9d3ec2c86b6d4c3bf0ed91391c3 first.nut
-----------------
-./tests/data/b-lavf.swf
-first.nut second.nut differ: char 34, line 1
-d4a5c5e6343dc17bed49397d889e0799 first.nut
-----------------
-./tests/data/b-lavf.ts
-40fd2ece0c8386d3a250943eab023795 first.nut
-----------------
-./tests/data/b-lavf.ul
-1c4c747e2e9c0fd195656359341eef76 first.nut
-----------------
-./tests/data/b-lavf.voc
-first.nut second.nut differ: char 42, line 1
-500ef42830c5bc2af849dbdcc4380f1b first.nut
-----------------
-./tests/data/b-lavf.wav
-first.nut second.nut differ: char 42, line 1
-8d4c6a79af442610ad912625c9b85d02 first.nut
-----------------
-./tests/data/b-lavf.y4m
-f42a6ff4488de306925b057ecee75b0e first.nut
-----------------
-./tests/data/b-lavf02.bmp
-first.nut second.nut differ: char 113, line 1
-02e3c782ef3a0c96e820201d4d4b8268 first.nut
-----------------
-./tests/data/b-lavf02.jpg
-61a19c3012a5aa056d8e9a589e29de2e first.nut
-----------------
-./tests/data/b-lavf02.pcx
-first.nut second.nut differ: char 113, line 1
-3c4e1b9c8d5dd2bedb8eebd1edc7a2f5 first.nut
-----------------
-./tests/data/b-lavf02.pgm
-first.nut second.nut differ: char 113, line 1
-cc36bdadd7aef501a6d5d588dec2188b first.nut
-----------------
-./tests/data/b-lavf02.ppm
-first.nut second.nut differ: char 113, line 1
-453ec690bea6c3668e2b65e0b7ad14c8 first.nut
-----------------
-./tests/data/b-lavf02.sgi
-first.nut second.nut differ: char 113, line 1
-6cdadd58aaa5ad196697352e96723e52 first.nut
-----------------
-./tests/data/b-lavf02.tga
-4144d2b4ee2948c1a16f7fc31b381be3 first.nut
-----------------
-./tests/data/b-lavf02.tiff
-first.nut second.nut differ: char 113, line 1
-237fa2da2d5f4930dae9825c9cf928a6 first.nut
-----------------
-./tests/data/b-pbmpipe.pbm
-first.nut second.nut differ: char 113, line 1
-2c65ef7188398da8a5f107b9dd5fb998 first.nut
-----------------
-./tests/data/b-pgmpipe.pgm
-first.nut second.nut differ: char 113, line 1
-b7e98248ada1e6f7170bc7fedee3825c first.nut
-----------------
-./tests/data/b-ppmpipe.ppm
-first.nut second.nut differ: char 113, line 1
-869fcefe430c35a9a8e46fd5f040b62e first.nut
diff --git a/tests/copycooker.sh b/tests/copycooker.sh
deleted file mode 100755
index 3118e3f..0000000
--- a/tests/copycooker.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-
-LC_ALL=C
-export LC_ALL
-
-datadir="tests/data"
-
-logfile="$datadir/copy.regression"
-reffile="$1"
-
-list=$(grep -oh ' ./tests/data/.*' tests/ref/{acodec,lavf,vsynth1}/*| sort)
-rm -f $logfile
-for i in $list ; do
- echo ---------------- >> $logfile
- echo $i >> $logfile
- ./ffmpeg -flags +bitexact -i $i -acodec copy -vcodec copy -y first.nut
- ./ffmpeg -flags +bitexact -i first.nut -acodec copy -vcodec copy -y second.nut
- cmp first.nut second.nut >> $logfile
- md5sum first.nut >> $logfile
-done
-
-if diff -u -w "$reffile" "$logfile" ; then
- echo
- echo copy regression test: success
- exit 0
-else
- echo
- echo copy regression test: error
- exit 1
-fi
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index 366145d..07cfe74 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -16,7 +16,7 @@ cmp=${6:-diff}
ref=${7:-"${base}/ref/fate/${test}"}
fuzz=$8
threads=${9:-1}
-thread_type=${10:-3}
+thread_type=${10:-frame+slice}
outdir="tests/data/fate"
outfile="${outdir}/${test}"
@@ -49,36 +49,33 @@ run(){
$target_exec $target_path/"$@"
}
-ffmpeg(){
- run ffmpeg -v 0 -threads $threads -thread_type $thread_type "$@"
+avconv(){
+ run avconv -nostats -threads $threads -thread_type $thread_type "$@"
}
framecrc(){
- ffmpeg "$@" -f framecrc -
+ avconv "$@" -f framecrc -
}
framemd5(){
- ffmpeg "$@" -f framemd5 -
+ avconv "$@" -f framemd5 -
}
crc(){
- ffmpeg "$@" -f crc -
+ avconv "$@" -f crc -
}
md5(){
- ffmpeg "$@" md5:
+ avconv "$@" md5:
}
pcm(){
- ffmpeg "$@" -vn -f s16le -
+ avconv "$@" -vn -f s16le -
}
regtest(){
t="${test#$2-}"
ref=${base}/ref/$2/$t
- cleanfiles="$cleanfiles $outfile $errfile"
- outfile=tests/data/regression/$2/$t
- errfile=tests/data/$t.$2.err
${base}/${1}-regression.sh $t $2 $3 "$target_exec" "$target_path" "$threads" "$thread_type"
}
@@ -107,7 +104,7 @@ seektest(){
file=$(echo tests/data/$d/$file)
;;
esac
- $target_exec $target_path/tests/seek_test $target_path/$file
+ run libavformat/seek-test $target_path/$file
}
mkdir -p "$outdir"
@@ -126,6 +123,7 @@ if test -e "$ref"; then
diff) diff -u -w "$ref" "$outfile" >$cmpfile ;;
oneoff) oneoff "$ref" "$outfile" "$fuzz" >$cmpfile ;;
stddev) stddev "$ref" "$outfile" "$fuzz" >$cmpfile ;;
+ null) cat "$outfile" >$cmpfile ;;
esac
cmperr=$?
test $err = 0 && err=$cmperr
diff --git a/tests/fate.mak b/tests/fate.mak
index cf6c44e..89bbb9f 100644
--- a/tests/fate.mak
+++ b/tests/fate.mak
@@ -4,14 +4,10 @@ FATE_TESTS += fate-4xm-2
fate-4xm-2: CMD = framecrc -i $(SAMPLES)/4xm/version2.4xm -pix_fmt rgb24 -an
FATE_TESTS += fate-8bps
fate-8bps: CMD = framecrc -i $(SAMPLES)/8bps/full9iron-partial.mov -pix_fmt rgb24
-FATE_TESTS += fate-aac-demux
-fate-aac-demux: CMD = crc -i $(SAMPLES)/aac/ct_faac-adts.aac -acodec copy
FATE_TESTS += fate-aasc
fate-aasc: CMD = framecrc -i $(SAMPLES)/aasc/AASC-1.5MB.AVI -pix_fmt rgb24
-FATE_TESTS += fate-adpcm-ea-r2
-fate-adpcm-ea-r2: CMD = crc -i $(SAMPLES)/ea-mpc/THX_logo.mpc -vn
-FATE_TESTS += fate-adpcm-ea-r3
-fate-adpcm-ea-r3: CMD = crc -i $(SAMPLES)/ea-vp6/THX_logo.vp6 -vn
+FATE_TESTS += fate-adts-demux
+fate-adts-demux: CMD = crc -i $(SAMPLES)/aac/ct_faac-adts.aac -acodec copy
FATE_TESTS += fate-aea-demux
fate-aea-demux: CMD = crc -i $(SAMPLES)/aea/chirp.aea -acodec copy
FATE_TESTS += fate-alg-mm
@@ -35,25 +31,15 @@ fate-bink-demux-video: CMD = framecrc -i $(SAMPLES)/bink/hol2br.bik
FATE_TESTS += fate-caf
fate-caf: CMD = crc -i $(SAMPLES)/caf/caf-pcm16.caf
FATE_TESTS += fate-cdgraphics
-fate-cdgraphics: CMD = framecrc -t 1 -i $(SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24
+fate-cdgraphics: CMD = framecrc -i $(SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 -t 1
FATE_TESTS += fate-cljr
fate-cljr: CMD = framecrc -i $(SAMPLES)/cljr/testcljr-partial.avi
FATE_TESTS += fate-corepng
fate-corepng: CMD = framecrc -i $(SAMPLES)/png1/corepng-partial.avi
-FATE_TESTS += fate-creative-adpcm
-fate-creative-adpcm: CMD = md5 -i $(SAMPLES)/creative/intro-partial.wav -f s16le
-FATE_TESTS += fate-creative-adpcm-8-2.6bit
-fate-creative-adpcm-8-2.6bit: CMD = md5 -i $(SAMPLES)/creative/BBC_3BIT.VOC -f s16le
-FATE_TESTS += fate-creative-adpcm-8-2bit
-fate-creative-adpcm-8-2bit: CMD = md5 -i $(SAMPLES)/creative/BBC_2BIT.VOC -f s16le
-FATE_TESTS += fate-creative-adpcm-8-4bit
-fate-creative-adpcm-8-4bit: CMD = md5 -i $(SAMPLES)/creative/BBC_4BIT.VOC -f s16le
FATE_TESTS += fate-creatureshock-avs
fate-creatureshock-avs: CMD = framecrc -i $(SAMPLES)/creatureshock-avs/OUTATIME.AVS -pix_fmt rgb24
FATE_TESTS += fate-cryo-apc
fate-cryo-apc: CMD = md5 -i $(SAMPLES)/cryo-apc/cine007.APC -f s16le
-FATE_TESTS += fate-cscd
-fate-cscd: CMD = framecrc -i $(SAMPLES)/CSCD/sample_video.avi -an -vsync 0 -pix_fmt rgb24
FATE_TESTS += fate-cvid
fate-cvid: CMD = framecrc -i $(SAMPLES)/cvid/laracroft-cinepak-partial.avi -an
FATE_TESTS += fate-cvid-palette
@@ -68,12 +54,6 @@ FATE_TESTS += fate-delphine-cin
fate-delphine-cin: CMD = framecrc -i $(SAMPLES)/delphine-cin/LOGO-partial.CIN -pix_fmt rgb24 -vsync 0
FATE_TESTS += fate-deluxepaint-anm
fate-deluxepaint-anm: CMD = framecrc -i $(SAMPLES)/deluxepaint-anm/INTRO1.ANM -pix_fmt rgb24
-FATE_TESTS += fate-dpx
-fate-dpx: CMD = framecrc -i $(SAMPLES)/dpx/lighthouse_rgb48.dpx
-FATE_TESTS += fate-duck-dk3
-fate-duck-dk3: CMD = md5 -i $(SAMPLES)/duck/sop-audio-only.avi -f s16le
-FATE_TESTS += fate-duck-dk4
-fate-duck-dk4: CMD = md5 -i $(SAMPLES)/duck/salsa-audio-only.avi -f s16le
FATE_TESTS += fate-duck-tm2
fate-duck-tm2: CMD = framecrc -i $(SAMPLES)/duck/tm20.avi
FATE_TESTS += fate-ea-cdata
@@ -82,68 +62,34 @@ FATE_TESTS += fate-ea-cmv
fate-ea-cmv: CMD = framecrc -i $(SAMPLES)/ea-cmv/TITLE.CMV -vsync 0 -pix_fmt rgb24
FATE_TESTS += fate-ea-dct
fate-ea-dct: CMD = framecrc -idct simple -i $(SAMPLES)/ea-dct/NFS2Esprit-partial.dct
-FATE_TESTS += fate-ea-mad-adpcm-ea-r1
-fate-ea-mad-adpcm-ea-r1: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad
-FATE_TESTS += fate-ea-mad-pcm-planar
-fate-ea-mad-pcm-planar: CMD = framecrc -i $(SAMPLES)/ea-mad/xeasport.mad
FATE_TESTS += fate-ea-tgq
fate-ea-tgq: CMD = framecrc -i $(SAMPLES)/ea-tgq/v27.tgq -an
FATE_TESTS += fate-ea-tgv-ima-ea-eacs
fate-ea-tgv-ima-ea-eacs: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24
FATE_TESTS += fate-ea-tgv-ima-ea-sead
fate-ea-tgv-ima-ea-sead: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTEL_S.TGV -pix_fmt rgb24
-FATE_TESTS += fate-ea-tqi-adpcm
-fate-ea-tqi-adpcm: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve
-FATE_TESTS += fate-ea-vp60
-fate-ea-vp60: CMD = framecrc -i $(SAMPLES)/ea-vp6/g36.vp6
-FATE_TESTS += fate-ea-vp61
-fate-ea-vp61: CMD = framecrc -i $(SAMPLES)/ea-vp6/MovieSkirmishGondor.vp6 -t 4
FATE_TESTS += fate-feeble-dxa
fate-feeble-dxa: CMD = framecrc -i $(SAMPLES)/dxa/meetsquid.dxa -t 2 -pix_fmt rgb24
-FATE_TESTS += fate-film-cvid-pcm-stereo-8bit
-fate-film-cvid-pcm-stereo-8bit: CMD = framecrc -i $(SAMPLES)/film/logo-capcom.cpk
FATE_TESTS += fate-flic-af11-palette-change
fate-flic-af11-palette-change: CMD = framecrc -i $(SAMPLES)/fli/fli-engines.fli -t 3.3 -pix_fmt rgb24
FATE_TESTS += fate-flic-af12
fate-flic-af12: CMD = framecrc -i $(SAMPLES)/fli/jj00c2.fli -pix_fmt rgb24
FATE_TESTS += fate-flic-magiccarpet
fate-flic-magiccarpet: CMD = framecrc -i $(SAMPLES)/fli/intel.dat -pix_fmt rgb24
-FATE_TESTS += fate-fraps-v0
-fate-fraps-v0: CMD = framecrc -i $(SAMPLES)/fraps/Griffin_Ragdoll01-partial.avi
-FATE_TESTS += fate-fraps-v1
-fate-fraps-v1: CMD = framecrc -i $(SAMPLES)/fraps/sample-v1.avi -an
-FATE_TESTS += fate-fraps-v2
-fate-fraps-v2: CMD = framecrc -i $(SAMPLES)/fraps/test3-nosound-partial.avi
-FATE_TESTS += fate-fraps-v3
-fate-fraps-v3: CMD = framecrc -i $(SAMPLES)/fraps/psclient-partial.avi -pix_fmt rgb24
-FATE_TESTS += fate-fraps-v4
-fate-fraps-v4: CMD = framecrc -i $(SAMPLES)/fraps/WoW_2006-11-03_14-58-17-19-nosound-partial.avi
-FATE_TESTS += fate-fraps-v5
-fate-fraps-v5: CMD = framecrc -i $(SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi
FATE_TESTS += fate-frwu
fate-frwu: CMD = framecrc -i $(SAMPLES)/frwu/frwu.avi
FATE_TESTS += fate-funcom-iss
fate-funcom-iss: CMD = md5 -i $(SAMPLES)/funcom-iss/0004010100.iss -f s16le
FATE_TESTS += fate-id-cin-video
fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24
-FATE_TESTS += fate-idroq-video-dpcm
-fate-idroq-video-dpcm: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq
FATE_TESTS-$(CONFIG_AVFILTER) += fate-idroq-video-encode
-fate-idroq-video-encode: CMD = md5 -t 0.2 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f RoQ
+fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f RoQ -t 0.2
FATE_TESTS += fate-iff-byterun1
fate-iff-byterun1: CMD = framecrc -i $(SAMPLES)/iff/ASH.LBM -pix_fmt rgb24
FATE_TESTS += fate-iff-fibonacci
fate-iff-fibonacci: CMD = md5 -i $(SAMPLES)/iff/dasboot-in-compressed -f s16le
FATE_TESTS += fate-iff-ilbm
fate-iff-ilbm: CMD = framecrc -i $(SAMPLES)/iff/lms-matriks.ilbm -pix_fmt rgb24
-FATE_TESTS += fate-iff-pcm
-fate-iff-pcm: CMD = md5 -i $(SAMPLES)/iff/Bells -f s16le
-FATE_TESTS += fate-indeo2
-fate-indeo2: CMD = framecrc -i $(SAMPLES)/rt21/VPAR0026.AVI
-FATE_TESTS += fate-indeo3
-fate-indeo3: CMD = framecrc -i $(SAMPLES)/iv32/cubes.mov
-FATE_TESTS += fate-indeo5
-fate-indeo5: CMD = framecrc -i $(SAMPLES)/iv50/Educ_Movie_DeadlyForce.avi -an
FATE_TESTS += fate-interplay-mve-16bit
fate-interplay-mve-16bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/descent3-level5-16bit-partial.mve -pix_fmt rgb24
FATE_TESTS += fate-interplay-mve-8bit
@@ -154,40 +100,12 @@ FATE_TESTS += fate-kmvc
fate-kmvc: CMD = framecrc -i $(SAMPLES)/KMVC/LOGO1.AVI -an -t 3 -pix_fmt rgb24
FATE_TESTS += fate-lmlm4-demux
fate-lmlm4-demux: CMD = framecrc -i $(SAMPLES)/lmlm4/LMLM4_CIFat30fps.divx -t 3 -acodec copy -vcodec copy
-FATE_TESTS += fate-loco-rgb
-fate-loco-rgb: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-rgb.avi
-FATE_TESTS += fate-loco-yuy2
-fate-loco-yuy2: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-0.avi
-FATE_TESTS += fate-lossless-appleaudio
-fate-lossless-appleaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/inside.m4a -f s16le
-FATE_TESTS += fate-lossless-meridianaudio
-fate-lossless-meridianaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.mlp -f s16le
-FATE_TESTS += fate-lossless-monkeysaudio
-fate-lossless-monkeysaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.ape -f s16le
-FATE_TESTS += fate-lossless-shortenaudio
-fate-lossless-shortenaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.shn -f s16le
-FATE_TESTS += fate-lossless-tta
-fate-lossless-tta: CMD = crc -i $(SAMPLES)/lossless-audio/inside.tta
-FATE_TESTS += fate-lossless-wavpackaudio
-fate-lossless-wavpackaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.wv -f s16le
FATE_TESTS += fate-maxis-xa
fate-maxis-xa: CMD = md5 -i $(SAMPLES)/maxis-xa/SC2KBUG.XA -f s16le
FATE_TESTS += fate-mimic
fate-mimic: CMD = framecrc -idct simple -i $(SAMPLES)/mimic/mimic2-womanloveffmpeg.cam -vsync 0
FATE_TESTS += fate-motionpixels
-fate-motionpixels: CMD = framecrc -i $(SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24
-FATE_TESTS += fate-mpc7-demux
-fate-mpc7-demux: CMD = crc -i $(SAMPLES)/musepack/inside-mp7.mpc -acodec copy
-FATE_TESTS += fate-mpc8-demux
-fate-mpc8-demux: CMD = crc -i $(SAMPLES)/musepack/inside-mp8.mpc -acodec copy
-FATE_TESTS += fate-msrle-8bit
-fate-msrle-8bit: CMD = framecrc -i $(SAMPLES)/msrle/Search-RLE.avi -pix_fmt rgb24
-FATE_TESTS += fate-msvideo1-16bit
-fate-msvideo1-16bit: CMD = framecrc -i $(SAMPLES)/cram/clock-cram16.avi -pix_fmt rgb24
-FATE_TESTS += fate-msvideo1-8bit
-fate-msvideo1-8bit: CMD = framecrc -i $(SAMPLES)/cram/skating.avi -t 1 -pix_fmt rgb24
-FATE_TESTS += fate-mszh
-fate-mszh: CMD = framecrc -i $(SAMPLES)/lcl/mszh-1frame.avi
+fate-motionpixels: CMD = framecrc -i $(SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111
FATE_TESTS += fate-mtv
fate-mtv: CMD = framecrc -i $(SAMPLES)/mtv/comedian_auto-partial.mtv -acodec copy -pix_fmt rgb24
FATE_TESTS += fate-mxf-demux
@@ -197,19 +115,13 @@ fate-nc-demux: CMD = framecrc -i $(SAMPLES)/nc-camera/nc-sample-partial -vcodec
FATE_TESTS += fate-nsv-demux
fate-nsv-demux: CMD = framecrc -i $(SAMPLES)/nsv/witchblade-51kbps.nsv -t 6 -vcodec copy -acodec copy
FATE_TESTS += fate-nuv
-fate-nuv: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/Today.nuv
+fate-nuv: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/Today.nuv -vsync 0
FATE_TESTS += fate-oma-demux
fate-oma-demux: CMD = crc -i $(SAMPLES)/oma/01-Untitled-partial.oma -acodec copy
-FATE_TESTS += fate-pcm_dvd
-fate-pcm_dvd: CMD = framecrc -i $(SAMPLES)/pcm-dvd/coolitnow-partial.vob -vn
FATE_TESTS += fate-psx-str
fate-psx-str: CMD = framecrc -i $(SAMPLES)/psx-str/descent-partial.str
FATE_TESTS += fate-psx-str-v3-mdec
fate-psx-str-v3-mdec: CMD = framecrc -i $(SAMPLES)/psx-str/abc000_cut.str -an
-FATE_TESTS += fate-psx-str-v3-adpcm_xa
-fate-psx-str-v3-adpcm_xa: CMD = framecrc -i $(SAMPLES)/psx-str/abc000_cut.str -vn
-FATE_TESTS += fate-ptx
-fate-ptx: CMD = framecrc -i $(SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24
FATE_TESTS += fate-pva-demux
fate-pva-demux: CMD = framecrc -idct simple -i $(SAMPLES)/pva/PVA_test-partial.pva -t 0.6 -acodec copy
FATE_TESTS += fate-qcp-demux
@@ -232,42 +144,12 @@ FATE_TESTS += fate-qt-mac6-mono
fate-qt-mac6-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-MAC6.mov -f s16le
FATE_TESTS += fate-qt-mac6-stereo
fate-qt-mac6-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-MAC6.mov -f s16le
-FATE_TESTS += fate-qt-msadpcm-stereo
-fate-qt-msadpcm-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms02.mov -f s16le
-FATE_TESTS += fate-qt-msimaadpcm-stereo
-fate-qt-msimaadpcm-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms11.mov -f s16le
-FATE_TESTS += fate-qt-rawpcm-16bit-stereo-signed-be
-fate-qt-rawpcm-16bit-stereo-signed-be: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-twos.mov -f s16le
-FATE_TESTS += fate-qt-rawpcm-16bit-stereo-signed-le
-fate-qt-rawpcm-16bit-stereo-signed-le: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-sowt.mov -f s16le
-FATE_TESTS += fate-qt-rawpcm-8bit-mono-unsigned
-fate-qt-rawpcm-8bit-mono-unsigned: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-raw.mov -f s16le
-FATE_TESTS += fate-qt-rawpcm-8bit-stereo-unsigned
-fate-qt-rawpcm-8bit-stereo-unsigned: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-raw.mov -f s16le
FATE_TESTS += fate-qt-ulaw-mono
fate-qt-ulaw-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-ulaw.mov -f s16le
FATE_TESTS += fate-qt-ulaw-stereo
fate-qt-ulaw-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-ulaw.mov -f s16le
-FATE_TESTS += fate-qtrle-16bit
-fate-qtrle-16bit: CMD = framecrc -i $(SAMPLES)/qtrle/mr-cork-rle.mov -pix_fmt rgb24
-FATE_TESTS += fate-qtrle-1bit
-fate-qtrle-1bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-Monochrome.mov
-FATE_TESTS += fate-qtrle-24bit
-fate-qtrle-24bit: CMD = framecrc -i $(SAMPLES)/qtrle/aletrek-rle.mov -vsync 0
-FATE_TESTS += fate-qtrle-2bit
-fate-qtrle-2bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-4Greys.mov -pix_fmt rgb24
-FATE_TESTS += fate-qtrle-32bit
-fate-qtrle-32bit: CMD = framecrc -i $(SAMPLES)/qtrle/ultra_demo_720_480_32bpp_rle.mov -pix_fmt rgb24
-FATE_TESTS += fate-qtrle-4bit
-fate-qtrle-4bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-16Greys.mov -pix_fmt rgb24 -an
-FATE_TESTS += fate-qtrle-8bit
-fate-qtrle-8bit: CMD = framecrc -i $(SAMPLES)/qtrle/criticalpath-credits.mov -vsync 0 -pix_fmt rgb24 -an
FATE_TESTS += fate-quickdraw
fate-quickdraw: CMD = framecrc -i $(SAMPLES)/quickdraw/Airplane.mov -pix_fmt rgb24
-FATE_TESTS += fate-real-14_4
-fate-real-14_4: CMD = md5 -i $(SAMPLES)/real/ra3_in_rm_file.rm -f s16le
-FATE_TESTS += fate-real-rv40
-fate-real-rv40: CMD = framecrc -i $(SAMPLES)/real/spygames-2MB.rmvb -t 10 -an
FATE_TESTS += fate-redcode-demux
fate-redcode-demux: CMD = framecrc -i $(SAMPLES)/r3d/4MB-sample.r3d -vcodec copy -acodec copy
FATE_TESTS += fate-rl2
@@ -288,24 +170,10 @@ FATE_TESTS += fate-sp5x
fate-sp5x: CMD = framecrc -idct simple -i $(SAMPLES)/sp5x/sp5x_problem.avi
FATE_TESTS += fate-sub-srt
fate-sub-srt: CMD = md5 -i $(SAMPLES)/sub/SubRip_capability_tester.srt -f ass
-FATE_TESTS += fate-sunraster-1bit-raw
-fate-sunraster-1bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-1bit-raw.sun
-FATE_TESTS += fate-sunraster-1bit-rle
-fate-sunraster-1bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-1bit-rle.sun
-FATE_TESTS += fate-sunraster-24bit-raw
-fate-sunraster-24bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-raw.sun
-FATE_TESTS += fate-sunraster-24bit-rle
-fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun
-FATE_TESTS += fate-sunraster-8bit-raw
-fate-sunraster-8bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-8bit-raw.sun -pix_fmt rgb24
-FATE_TESTS += fate-sunraster-8bit-rle
-fate-sunraster-8bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-8bit-rle.sun -pix_fmt rgb24
FATE_TESTS += fate-svq1
fate-svq1: CMD = framecrc -i $(SAMPLES)/svq1/marymary-shackles.mov -an -t 10
FATE_TESTS += fate-svq3
fate-svq3: CMD = framecrc -i $(SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an
-FATE_TESTS += fate-thp-mjpeg-adpcm
-fate-thp-mjpeg-adpcm: CMD = framecrc -idct simple -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp
FATE_TESTS += fate-tiertex-seq
fate-tiertex-seq: CMD = framecrc -i $(SAMPLES)/tiertex-seq/Gameover.seq -pix_fmt rgb24
FATE_TESTS += fate-tmv
@@ -314,51 +182,19 @@ FATE_TESTS += fate-truemotion1-15
fate-truemotion1-15: CMD = framecrc -i $(SAMPLES)/duck/phant2-940.duk -pix_fmt rgb24
FATE_TESTS += fate-truemotion1-24
fate-truemotion1-24: CMD = framecrc -i $(SAMPLES)/duck/sonic3dblast_intro-partial.avi -pix_fmt rgb24
-FATE_TESTS += fate-tscc-15bit
-fate-tscc-15bit: CMD = framecrc -i $(SAMPLES)/tscc/oneminute.avi -t 15 -pix_fmt rgb24
-FATE_TESTS += fate-tscc-32bit
-fate-tscc-32bit: CMD = framecrc -i $(SAMPLES)/tscc/2004-12-17-uebung9-partial.avi -pix_fmt rgb24 -an
FATE_TESTS += fate-ulti
fate-ulti: CMD = framecrc -i $(SAMPLES)/ulti/hit12w.avi -an
FATE_TESTS += fate-v210
fate-v210: CMD = framecrc -i $(SAMPLES)/v210/v210_720p-partial.avi -pix_fmt yuv422p16be -an
-FATE_TESTS += fate-vc1
-fate-vc1: CMD = framecrc -i $(SAMPLES)/vc1/SA00040.vc1
FATE_TESTS += fate-vcr1
fate-vcr1: CMD = framecrc -i $(SAMPLES)/vcr1/VCR1test.avi -an
FATE_TESTS += fate-video-xl
fate-video-xl: CMD = framecrc -i $(SAMPLES)/vixl/pig-vixl.avi
-FATE_TESTS += fate-vmnc-16bit
-fate-vmnc-16bit: CMD = framecrc -i $(SAMPLES)/VMnc/test.avi -pix_fmt rgb24
-FATE_TESTS += fate-vmnc-32bit
-fate-vmnc-32bit: CMD = framecrc -i $(SAMPLES)/VMnc/VS2k5DebugDemo-01-partial.avi -pix_fmt rgb24
-FATE_TESTS += fate-vp5
-fate-vp5: CMD = framecrc -i $(SAMPLES)/vp5/potter512-400-partial.avi -an
-FATE_TESTS += fate-vp6a
-fate-vp6a: CMD = framecrc -i $(SAMPLES)/flash-vp6/300x180-Scr-f8-056alpha.flv
-FATE_TESTS += fate-vp6f
-fate-vp6f: CMD = framecrc -i $(SAMPLES)/flash-vp6/clip1024.flv
FATE_TESTS += fate-vqa-cc
fate-vqa-cc: CMD = framecrc -i $(SAMPLES)/vqa/cc-demo1-partial.vqa -pix_fmt rgb24
-FATE_TESTS += fate-vqf-demux
-fate-vqf-demux: CMD = md5 -i $(SAMPLES)/vqf/achterba.vqf -acodec copy -f framecrc
-FATE_TESTS += fate-w64
-fate-w64: CMD = crc -i $(SAMPLES)/w64/w64-pcm16.w64
FATE_TESTS += fate-wc3movie-xan
fate-wc3movie-xan: CMD = framecrc -i $(SAMPLES)/wc3movie/SC_32-part.MVE -pix_fmt rgb24
FATE_TESTS += fate-westwood-aud
fate-westwood-aud: CMD = md5 -i $(SAMPLES)/westwood-aud/excellent.aud -f s16le
FATE_TESTS += fate-wnv1
fate-wnv1: CMD = framecrc -i $(SAMPLES)/wnv1/wnv1-codec.avi -an
-FATE_TESTS += fate-xan-dpcm
-fate-xan-dpcm: CMD = md5 -i $(SAMPLES)/wc4-xan/wc4_2.avi -vn -f s16le
-FATE_TESTS += fate-zlib
-fate-zlib: CMD = framecrc -i $(SAMPLES)/lcl/zlib-1frame.avi
-FATE_TESTS += fate-zmbv-15bit
-fate-zmbv-15bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_15bit.avi -pix_fmt rgb24 -t 25
-FATE_TESTS += fate-zmbv-16bit
-fate-zmbv-16bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_16bit.avi -pix_fmt rgb24 -t 25
-FATE_TESTS += fate-zmbv-32bit
-fate-zmbv-32bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_32bit.avi -pix_fmt rgb24 -t 25
-FATE_TESTS += fate-zmbv-8bit
-fate-zmbv-8bit: CMD = framecrc -i $(SAMPLES)/zmbv/wc2_001-partial.avi -an -pix_fmt rgb24
diff --git a/tests/fate.sh b/tests/fate.sh
index 9fd117c..e04c871 100755
--- a/tests/fate.sh
+++ b/tests/fate.sh
@@ -35,7 +35,7 @@ checkout(){
update()(
cd ${src} || return
case "$repo" in
- git:*) git pull ;;
+ git:*) git pull --quiet ;;
esac
)
@@ -70,7 +70,7 @@ fate()(
)
clean(){
- rm -r ${build} ${inst}
+ rm -rf ${build} ${inst}
}
report(){
diff --git a/tests/fate/aac.mak b/tests/fate/aac.mak
index 6701e14..f17c914 100644
--- a/tests/fate/aac.mak
+++ b/tests/fate/aac.mak
@@ -2,10 +2,22 @@ FATE_AAC += fate-aac-al04_44
fate-aac-al04_44: CMD = pcm -i $(SAMPLES)/aac/al04_44.mp4
fate-aac-al04_44: REF = $(SAMPLES)/aac/al04_44.s16
+FATE_AAC += fate-aac-al05_44
+fate-aac-al05_44: CMD = pcm -i $(SAMPLES)/aac/al05_44.mp4
+fate-aac-al05_44: REF = $(SAMPLES)/aac/al05_44.s16
+
+FATE_AAC += fate-aac-al06_44
+fate-aac-al06_44: CMD = pcm -i $(SAMPLES)/aac/al06_44.mp4
+fate-aac-al06_44: REF = $(SAMPLES)/aac/al06_44.s16
+
FATE_AAC += fate-aac-al07_96
fate-aac-al07_96: CMD = pcm -i $(SAMPLES)/aac/al07_96.mp4
fate-aac-al07_96: REF = $(SAMPLES)/aac/al07_96.s16
+FATE_AAC += fate-aac-al17_44
+fate-aac-al17_44: CMD = pcm -i $(SAMPLES)/aac/al17_44.mp4
+fate-aac-al17_44: REF = $(SAMPLES)/aac/al17_44.s16
+
FATE_AAC += fate-aac-am00_88
fate-aac-am00_88: CMD = pcm -i $(SAMPLES)/aac/am00_88.mp4
fate-aac-am00_88: REF = $(SAMPLES)/aac/am00_88.s16
@@ -26,6 +38,23 @@ FATE_AAC += fate-aac-ap05_48
fate-aac-ap05_48: CMD = pcm -i $(SAMPLES)/aac/ap05_48.mp4
fate-aac-ap05_48: REF = $(SAMPLES)/aac/ap05_48.s16
+FATE_AAC += fate-aac-latm_stereo_to_51
+fate-aac-latm_stereo_to_51: CMD = pcm -i $(SAMPLES)/aac/latm_stereo_to_51.ts -ac 6
+fate-aac-latm_stereo_to_51: REF = $(SAMPLES)/aac/latm_stereo_to_51.s16
+
+fate-aac-ct%: CMD = pcm -i $(SAMPLES)/aac/CT_DecoderCheck/$(@:fate-aac-ct-%=%)
+fate-aac-ct%: REF = $(SAMPLES)/aac/CT_DecoderCheck/aacPlusv2.wav
+
+FATE_AAC_CT = sbr_bc-ps_i.3gp \
+ sbr_bic-ps_i.3gp \
+ sbr_i-ps_i.aac \
+ sbr_bc-ps_bc.mp4 \
+ sbr_bc-ps_i.mp4 \
+ sbr_i-ps_bic.mp4 \
+ sbr_i-ps_i.mp4
+
+FATE_AAC += $(FATE_AAC_CT:%=fate-aac-ct-%)
+
FATE_TESTS += $(FATE_AAC)
fate-aac: $(FATE_AAC)
$(FATE_AAC): CMP = oneoff
diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak
new file mode 100644
index 0000000..255479a
--- /dev/null
+++ b/tests/fate/ac3.mak
@@ -0,0 +1,29 @@
+FATE_TESTS += fate-ac3-2.0
+fate-ac3-2.0: CMD = pcm -i $(SAMPLES)/ac3/monsters_inc_2.0_192_small.ac3
+fate-ac3-2.0: CMP = oneoff
+fate-ac3-2.0: REF = $(SAMPLES)/ac3/monsters_inc_2.0_192_small.pcm
+
+FATE_TESTS += fate-ac3-5.1
+fate-ac3-5.1: CMD = pcm -i $(SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
+fate-ac3-5.1: CMP = oneoff
+fate-ac3-5.1: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small.pcm
+
+FATE_TESTS += fate-eac3-1
+fate-eac3-1: CMD = pcm -i $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small.eac3
+fate-eac3-1: CMP = oneoff
+fate-eac3-1: REF = $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small.pcm
+
+FATE_TESTS += fate-eac3-2
+fate-eac3-2: CMD = pcm -i $(SAMPLES)/eac3/csi_miami_stereo_128_spx_small.eac3
+fate-eac3-2: CMP = oneoff
+fate-eac3-2: REF = $(SAMPLES)/eac3/csi_miami_stereo_128_spx_small.pcm
+
+FATE_TESTS += fate-eac3-3
+fate-eac3-3: CMD = pcm -i $(SAMPLES)/eac3/matrix2_commentary1_stereo_192_small.eac3
+fate-eac3-3: CMP = oneoff
+fate-eac3-3: REF = $(SAMPLES)/eac3/matrix2_commentary1_stereo_192_small.pcm
+
+FATE_TESTS += fate-eac3-4
+fate-eac3-4: CMD = pcm -i $(SAMPLES)/eac3/serenity_english_5.1_1536_small.eac3
+fate-eac3-4: CMP = oneoff
+fate-eac3-4: REF = $(SAMPLES)/eac3/serenity_english_5.1_1536_small.pcm
diff --git a/tests/fate/amrnb.mak b/tests/fate/amrnb.mak
new file mode 100644
index 0000000..e633fec
--- /dev/null
+++ b/tests/fate/amrnb.mak
@@ -0,0 +1,47 @@
+FATE_TESTS += fate-amrnb-4k75
+fate-amrnb-4k75: CMD = pcm -i $(SAMPLES)/amrnb/4.75k.amr
+fate-amrnb-4k75: CMP = stddev
+fate-amrnb-4k75: REF = $(SAMPLES)/amrnb/4.75k.pcm
+fate-amrnb-4k75: FUZZ = 1
+
+FATE_TESTS += fate-amrnb-5k15
+fate-amrnb-5k15: CMD = pcm -i $(SAMPLES)/amrnb/5.15k.amr
+fate-amrnb-5k15: CMP = stddev
+fate-amrnb-5k15: REF = $(SAMPLES)/amrnb/5.15k.pcm
+fate-amrnb-5k15: FUZZ = 1
+
+FATE_TESTS += fate-amrnb-5k9
+fate-amrnb-5k9: CMD = pcm -i $(SAMPLES)/amrnb/5.9k.amr
+fate-amrnb-5k9: CMP = stddev
+fate-amrnb-5k9: REF = $(SAMPLES)/amrnb/5.9k.pcm
+fate-amrnb-5k9: FUZZ = 1
+
+FATE_TESTS += fate-amrnb-6k7
+fate-amrnb-6k7: CMD = pcm -i $(SAMPLES)/amrnb/6.7k.amr
+fate-amrnb-6k7: CMP = stddev
+fate-amrnb-6k7: REF = $(SAMPLES)/amrnb/6.7k.pcm
+fate-amrnb-6k7: FUZZ = 1
+
+FATE_TESTS += fate-amrnb-7k4
+fate-amrnb-7k4: CMD = pcm -i $(SAMPLES)/amrnb/7.4k.amr
+fate-amrnb-7k4: CMP = stddev
+fate-amrnb-7k4: REF = $(SAMPLES)/amrnb/7.4k.pcm
+fate-amrnb-7k4: FUZZ = 1
+
+FATE_TESTS += fate-amrnb-7k95
+fate-amrnb-7k95: CMD = pcm -i $(SAMPLES)/amrnb/7.95k.amr
+fate-amrnb-7k95: CMP = stddev
+fate-amrnb-7k95: REF = $(SAMPLES)/amrnb/7.95k.pcm
+fate-amrnb-7k95: FUZZ = 1
+
+FATE_TESTS += fate-amrnb-10k2
+fate-amrnb-10k2: CMD = pcm -i $(SAMPLES)/amrnb/10.2k.amr
+fate-amrnb-10k2: CMP = stddev
+fate-amrnb-10k2: REF = $(SAMPLES)/amrnb/10.2k.pcm
+fate-amrnb-10k2: FUZZ = 1
+
+FATE_TESTS += fate-amrnb-12k2
+fate-amrnb-12k2: CMD = pcm -i $(SAMPLES)/amrnb/12.2k.amr
+fate-amrnb-12k2: CMP = stddev
+fate-amrnb-12k2: REF = $(SAMPLES)/amrnb/12.2k.pcm
+fate-amrnb-12k2: FUZZ = 1
diff --git a/tests/fate/amrwb.mak b/tests/fate/amrwb.mak
new file mode 100644
index 0000000..d3931c7
--- /dev/null
+++ b/tests/fate/amrwb.mak
@@ -0,0 +1,59 @@
+FATE_TESTS += fate-amrwb-6k60
+fate-amrwb-6k60: CMD = pcm -i $(SAMPLES)/amrwb/seed-6k60.awb
+fate-amrwb-6k60: CMP = stddev
+fate-amrwb-6k60: REF = $(SAMPLES)/amrwb/seed-6k60.pcm
+fate-amrwb-6k60: FUZZ = 1
+
+FATE_TESTS += fate-amrwb-8k85
+fate-amrwb-8k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-8k85.awb
+fate-amrwb-8k85: CMP = stddev
+fate-amrwb-8k85: REF = $(SAMPLES)/amrwb/seed-8k85.pcm
+fate-amrwb-8k85: FUZZ = 1
+
+FATE_TESTS += fate-amrwb-12k65
+fate-amrwb-12k65: CMD = pcm -i $(SAMPLES)/amrwb/seed-12k65.awb
+fate-amrwb-12k65: CMP = stddev
+fate-amrwb-12k65: REF = $(SAMPLES)/amrwb/seed-12k65.pcm
+fate-amrwb-12k65: FUZZ = 1
+
+FATE_TESTS += fate-amrwb-14k25
+fate-amrwb-14k25: CMD = pcm -i $(SAMPLES)/amrwb/seed-14k25.awb
+fate-amrwb-14k25: CMP = stddev
+fate-amrwb-14k25: REF = $(SAMPLES)/amrwb/seed-14k25.pcm
+fate-amrwb-14k25: FUZZ = 2.6
+
+FATE_TESTS += fate-amrwb-15k85
+fate-amrwb-15k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-15k85.awb
+fate-amrwb-15k85: CMP = stddev
+fate-amrwb-15k85: REF = $(SAMPLES)/amrwb/seed-15k85.pcm
+fate-amrwb-15k85: FUZZ = 1
+
+FATE_TESTS += fate-amrwb-18k25
+fate-amrwb-18k25: CMD = pcm -i $(SAMPLES)/amrwb/seed-18k25.awb
+fate-amrwb-18k25: CMP = stddev
+fate-amrwb-18k25: REF = $(SAMPLES)/amrwb/seed-18k25.pcm
+fate-amrwb-18k25: FUZZ = 1
+
+FATE_TESTS += fate-amrwb-19k85
+fate-amrwb-19k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-19k85.awb
+fate-amrwb-19k85: CMP = stddev
+fate-amrwb-19k85: REF = $(SAMPLES)/amrwb/seed-19k85.pcm
+fate-amrwb-19k85: FUZZ = 1
+
+FATE_TESTS += fate-amrwb-23k05
+fate-amrwb-23k05: CMD = pcm -i $(SAMPLES)/amrwb/seed-23k05.awb
+fate-amrwb-23k05: CMP = stddev
+fate-amrwb-23k05: REF = $(SAMPLES)/amrwb/seed-23k05.pcm
+fate-amrwb-23k05: FUZZ = 2
+
+FATE_TESTS += fate-amrwb-23k85
+fate-amrwb-23k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-23k85.awb
+fate-amrwb-23k85: CMP = stddev
+fate-amrwb-23k85: REF = $(SAMPLES)/amrwb/seed-23k85.pcm
+fate-amrwb-23k85: FUZZ = 2
+
+FATE_TESTS += fate-amrwb-23k85-2
+fate-amrwb-23k85-2: CMD = pcm -i $(SAMPLES)/amrwb/deus-23k85.awb
+fate-amrwb-23k85-2: CMP = stddev
+fate-amrwb-23k85-2: REF = $(SAMPLES)/amrwb/deus-23k85.pcm
+fate-amrwb-23k85-2: FUZZ = 1
diff --git a/tests/fate/atrac.mak b/tests/fate/atrac.mak
new file mode 100644
index 0000000..1d586c6
--- /dev/null
+++ b/tests/fate/atrac.mak
@@ -0,0 +1,19 @@
+FATE_TESTS += fate-atrac1
+fate-atrac1: CMD = pcm -i $(SAMPLES)/atrac1/test_tones_small.aea
+fate-atrac1: CMP = oneoff
+fate-atrac1: REF = $(SAMPLES)/atrac1/test_tones_small.pcm
+
+FATE_TESTS += fate-atrac3-1
+fate-atrac3-1: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_066_small.wav
+fate-atrac3-1: CMP = oneoff
+fate-atrac3-1: REF = $(SAMPLES)/atrac3/mc_sich_at3_066_small.pcm
+
+FATE_TESTS += fate-atrac3-2
+fate-atrac3-2: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_105_small.wav
+fate-atrac3-2: CMP = oneoff
+fate-atrac3-2: REF = $(SAMPLES)/atrac3/mc_sich_at3_105_small.pcm
+
+FATE_TESTS += fate-atrac3-3
+fate-atrac3-3: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_132_small.wav
+fate-atrac3-3: CMP = oneoff
+fate-atrac3-3: REF = $(SAMPLES)/atrac3/mc_sich_at3_132_small.pcm
diff --git a/tests/fate/dct.mak b/tests/fate/dct.mak
new file mode 100644
index 0000000..8f2ab7a
--- /dev/null
+++ b/tests/fate/dct.mak
@@ -0,0 +1,5 @@
+FATE_TESTS += fate-idct8x8
+fate-idct8x8: libavcodec/dct-test$(EXESUF)
+fate-idct8x8: CMD = run libavcodec/dct-test -i
+fate-idct8x8: REF = /dev/null
+fate-idct8x8: CMP = null
diff --git a/tests/fate/dpcm.mak b/tests/fate/dpcm.mak
new file mode 100644
index 0000000..7144518
--- /dev/null
+++ b/tests/fate/dpcm.mak
@@ -0,0 +1,42 @@
+FATE_TESTS += fate-adpcm-ea-r2
+fate-adpcm-ea-r2: CMD = crc -i $(SAMPLES)/ea-mpc/THX_logo.mpc -vn
+
+FATE_TESTS += fate-adpcm-ea-r3
+fate-adpcm-ea-r3: CMD = crc -i $(SAMPLES)/ea-vp6/THX_logo.vp6 -vn
+
+FATE_TESTS += fate-creative-adpcm
+fate-creative-adpcm: CMD = md5 -i $(SAMPLES)/creative/intro-partial.wav -f s16le
+
+FATE_TESTS += fate-creative-adpcm-8-2bit
+fate-creative-adpcm-8-2bit: CMD = md5 -i $(SAMPLES)/creative/BBC_2BIT.VOC -f s16le
+
+FATE_TESTS += fate-creative-adpcm-8-2.6bit
+fate-creative-adpcm-8-2.6bit: CMD = md5 -i $(SAMPLES)/creative/BBC_3BIT.VOC -f s16le
+
+FATE_TESTS += fate-creative-adpcm-8-4bit
+fate-creative-adpcm-8-4bit: CMD = md5 -i $(SAMPLES)/creative/BBC_4BIT.VOC -f s16le
+
+FATE_TESTS += fate-ea-mad-adpcm-ea-r1
+fate-ea-mad-adpcm-ea-r1: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad
+
+FATE_TESTS += fate-ea-tqi-adpcm
+fate-ea-tqi-adpcm: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:v 26
+
+FATE_TESTS += fate-idroq-video-dpcm
+fate-idroq-video-dpcm: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq
+
+FATE_TESTS += fate-psx-str-v3-adpcm_xa
+fate-psx-str-v3-adpcm_xa: CMD = framecrc -i $(SAMPLES)/psx-str/abc000_cut.str -vn
+
+FATE_TESTS += fate-qt-msadpcm-stereo
+fate-qt-msadpcm-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms02.mov -f s16le
+
+FATE_TESTS += fate-qt-msimaadpcm-stereo
+fate-qt-msimaadpcm-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms11.mov -f s16le
+
+FATE_TESTS += fate-thp-mjpeg-adpcm
+fate-thp-mjpeg-adpcm: CMD = framecrc -idct simple -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp
+
+FATE_TESTS += fate-dpcm-xan
+fate-dpcm-xan: CMD = md5 -i $(SAMPLES)/wc4-xan/wc4_2.avi -vn -f s16le
+
diff --git a/tests/fate/fft.mak b/tests/fate/fft.mak
index 042a7bf..feb47af 100644
--- a/tests/fate/fft.mak
+++ b/tests/fate/fft.mak
@@ -1,28 +1,36 @@
-FATE_FFT = fate-fft fate-ifft \
- fate-mdct fate-imdct \
- fate-rdft fate-irdft \
- fate-dct1d fate-idct1d
-
-fate-fft: CMD = run libavcodec/fft-test
-fate-ifft: CMD = run libavcodec/fft-test -i
-fate-mdct: CMD = run libavcodec/fft-test -m
-fate-imdct: CMD = run libavcodec/fft-test -m -i
-fate-rdft: CMD = run libavcodec/fft-test -r
-fate-irdft: CMD = run libavcodec/fft-test -r -i
-fate-dct1d: CMD = run libavcodec/fft-test -d
-fate-idct1d: CMD = run libavcodec/fft-test -d -i
+define DEF_FFT
+FATE_FFT += fate-fft-$(1) fate-ifft-$(1) \
+ fate-mdct-$(1) fate-imdct-$(1) \
+ fate-rdft-$(1) fate-irdft-$(1) \
+ fate-dct1d-$(1) fate-idct1d-$(1)
+
+fate-fft-$(N): CMD = run libavcodec/fft-test -n$(1)
+fate-ifft-$(N): CMD = run libavcodec/fft-test -n$(1) -i
+fate-mdct-$(N): CMD = run libavcodec/fft-test -n$(1) -m
+fate-imdct-$(N): CMD = run libavcodec/fft-test -n$(1) -m -i
+fate-rdft-$(N): CMD = run libavcodec/fft-test -n$(1) -r
+fate-irdft-$(N): CMD = run libavcodec/fft-test -n$(1) -r -i
+fate-dct1d-$(N): CMD = run libavcodec/fft-test -n$(1) -d
+fate-idct1d-$(N): CMD = run libavcodec/fft-test -n$(1) -d -i
+endef
+
+$(foreach N, 4 5 6 7 8 9 10 11 12, $(eval $(call DEF_FFT,$(N))))
fate-fft-test: $(FATE_FFT)
$(FATE_FFT): libavcodec/fft-test$(EXESUF)
$(FATE_FFT): REF = /dev/null
-FATE_FFT_FIXED = fate-fft-fixed fate-ifft-fixed \
- fate-mdct-fixed fate-imdct-fixed
+define DEF_FFT_FIXED
+FATE_FFT_FIXED += fate-fft-fixed-$(1) fate-ifft-fixed-$(1) \
+ fate-mdct-fixed-$(1) fate-imdct-fixed-$(1)
+
+fate-fft-fixed-$(1): CMD = run libavcodec/fft-fixed-test -n$(1)
+fate-ifft-fixed-$(1): CMD = run libavcodec/fft-fixed-test -n$(1) -i
+fate-mdct-fixed-$(1): CMD = run libavcodec/fft-fixed-test -n$(1) -m
+fate-imdct-fixed-$(1): CMD = run libavcodec/fft-fixed-test -n$(1) -m -i
+endef
-fate-fft-fixed: CMD = run libavcodec/fft-fixed-test
-fate-ifft-fixed: CMD = run libavcodec/fft-fixed-test -i
-fate-mdct-fixed: CMD = run libavcodec/fft-fixed-test -m
-fate-imdct-fixed: CMD = run libavcodec/fft-fixed-test -m -i
+$(foreach N, 4 5 6 7 8 9 10 11 12, $(eval $(call DEF_FFT_FIXED,$(N))))
fate-fft-fixed-test: $(FATE_FFT_FIXED)
$(FATE_FFT_FIXED): libavcodec/fft-fixed-test$(EXESUF)
diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak
index 969bf41..20bfda2 100644
--- a/tests/fate/h264.mak
+++ b/tests/fate/h264.mak
@@ -175,6 +175,7 @@ FATE_H264 := $(FATE_H264:%=fate-h264-conformance-%) \
fate-h264-interlace-crop \
fate-h264-lossless \
fate-h264-extreme-plane-pred \
+ fate-h264-bsf-mp4toannexb \
FATE_TESTS += $(FATE_H264)
fate-h264: $(FATE_H264)
@@ -183,7 +184,7 @@ fate-h264-conformance-aud_mw_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-confo
fate-h264-conformance-ba1_ft_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/BA1_FT_C.264
fate-h264-conformance-ba1_sony_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/BA1_Sony_D.jsv
fate-h264-conformance-ba2_sony_f: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/BA2_Sony_F.jsv
-fate-h264-conformance-ba3_sva_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/BA3_SVA_C.264
+fate-h264-conformance-ba3_sva_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/BA3_SVA_C.264
fate-h264-conformance-ba_mw_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/BA_MW_D.264
fate-h264-conformance-bamq1_jvc_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/BAMQ1_JVC_C.264
fate-h264-conformance-bamq2_jvc_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/BAMQ2_JVC_C.264
@@ -193,80 +194,80 @@ fate-h264-conformance-caba1_sony_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-c
fate-h264-conformance-caba1_sva_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CABA1_SVA_B.264
fate-h264-conformance-caba2_sony_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CABA2_Sony_E.jsv
fate-h264-conformance-caba2_sva_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CABA2_SVA_B.264
-fate-h264-conformance-caba3_sony_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CABA3_Sony_C.jsv
-fate-h264-conformance-caba3_sva_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CABA3_SVA_B.264
+fate-h264-conformance-caba3_sony_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CABA3_Sony_C.jsv
+fate-h264-conformance-caba3_sva_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CABA3_SVA_B.264
fate-h264-conformance-caba3_toshiba_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CABA3_TOSHIBA_E.264
-fate-h264-conformance-cabac_mot_fld0_full: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/camp_mot_fld0_full.26l
-fate-h264-conformance-cabac_mot_frm0_full: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/camp_mot_frm0_full.26l
-fate-h264-conformance-cabac_mot_mbaff0_full: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/camp_mot_mbaff0_full.26l
-fate-h264-conformance-cabac_mot_picaff0_full: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/camp_mot_picaff0_full.26l
-fate-h264-conformance-cabaci3_sony_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CABACI3_Sony_B.jsv
-fate-h264-conformance-cabast3_sony_e: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CABAST3_Sony_E.jsv
-fate-h264-conformance-cabastbr3_sony_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CABASTBR3_Sony_B.jsv
-fate-h264-conformance-cabref3_sand_d: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CABREF3_Sand_D.264
-fate-h264-conformance-cacqp3_sony_d: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CACQP3_Sony_D.jsv
-fate-h264-conformance-cafi1_sva_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAFI1_SVA_C.264
+fate-h264-conformance-cabac_mot_fld0_full: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/camp_mot_fld0_full.26l
+fate-h264-conformance-cabac_mot_frm0_full: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/camp_mot_frm0_full.26l
+fate-h264-conformance-cabac_mot_mbaff0_full: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/camp_mot_mbaff0_full.26l
+fate-h264-conformance-cabac_mot_picaff0_full: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/camp_mot_picaff0_full.26l
+fate-h264-conformance-cabaci3_sony_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CABACI3_Sony_B.jsv
+fate-h264-conformance-cabast3_sony_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CABAST3_Sony_E.jsv
+fate-h264-conformance-cabastbr3_sony_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CABASTBR3_Sony_B.jsv
+fate-h264-conformance-cabref3_sand_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CABREF3_Sand_D.264
+fate-h264-conformance-cacqp3_sony_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CACQP3_Sony_D.jsv
+fate-h264-conformance-cafi1_sva_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAFI1_SVA_C.264
fate-h264-conformance-cama1_sony_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAMA1_Sony_C.jsv
-fate-h264-conformance-cama1_toshiba_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAMA1_TOSHIBA_B.264
-fate-h264-conformance-cama1_vtc_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/cama1_vtc_c.avc
+fate-h264-conformance-cama1_toshiba_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAMA1_TOSHIBA_B.264
+fate-h264-conformance-cama1_vtc_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/cama1_vtc_c.avc
fate-h264-conformance-cama2_vtc_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/cama2_vtc_b.avc
-fate-h264-conformance-cama3_sand_e: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAMA3_Sand_E.264
-fate-h264-conformance-cama3_vtc_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/cama3_vtc_b.avc
-fate-h264-conformance-camaci3_sony_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAMACI3_Sony_C.jsv
-fate-h264-conformance-camanl1_toshiba_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAMANL1_TOSHIBA_B.264
-fate-h264-conformance-camanl2_toshiba_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAMANL2_TOSHIBA_B.264
-fate-h264-conformance-camanl3_sand_e: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAMANL3_Sand_E.264
-fate-h264-conformance-camasl3_sony_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAMASL3_Sony_B.jsv
-fate-h264-conformance-camp_mot_mbaff_l30: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L30.26l
-fate-h264-conformance-camp_mot_mbaff_l31: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L31.26l
+fate-h264-conformance-cama3_sand_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAMA3_Sand_E.264
+fate-h264-conformance-cama3_vtc_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/cama3_vtc_b.avc
+fate-h264-conformance-camaci3_sony_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAMACI3_Sony_C.jsv
+fate-h264-conformance-camanl1_toshiba_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAMANL1_TOSHIBA_B.264
+fate-h264-conformance-camanl2_toshiba_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAMANL2_TOSHIBA_B.264
+fate-h264-conformance-camanl3_sand_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAMANL3_Sand_E.264
+fate-h264-conformance-camasl3_sony_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAMASL3_Sony_B.jsv
+fate-h264-conformance-camp_mot_mbaff_l30: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L30.26l
+fate-h264-conformance-camp_mot_mbaff_l31: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L31.26l
fate-h264-conformance-canl1_sony_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CANL1_Sony_E.jsv
fate-h264-conformance-canl1_sva_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CANL1_SVA_B.264
fate-h264-conformance-canl1_toshiba_g: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CANL1_TOSHIBA_G.264
fate-h264-conformance-canl2_sony_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CANL2_Sony_E.jsv
fate-h264-conformance-canl2_sva_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CANL2_SVA_B.264
-fate-h264-conformance-canl3_sony_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CANL3_Sony_C.jsv
+fate-h264-conformance-canl3_sony_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CANL3_Sony_C.jsv
fate-h264-conformance-canl3_sva_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CANL3_SVA_B.264
fate-h264-conformance-canl4_sva_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CANL4_SVA_B.264
fate-h264-conformance-canlma2_sony_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CANLMA2_Sony_C.jsv
fate-h264-conformance-canlma3_sony_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CANLMA3_Sony_C.jsv
-fate-h264-conformance-capa1_toshiba_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAPA1_TOSHIBA_B.264
-fate-h264-conformance-capama3_sand_f: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAPAMA3_Sand_F.264
+fate-h264-conformance-capa1_toshiba_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAPA1_TOSHIBA_B.264
+fate-h264-conformance-capama3_sand_f: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAPAMA3_Sand_F.264
fate-h264-conformance-capcm1_sand_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAPCM1_Sand_E.264
fate-h264-conformance-capcmnl1_sand_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAPCMNL1_Sand_E.264
-fate-h264-conformance-capm3_sony_d: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAPM3_Sony_D.jsv
+fate-h264-conformance-capm3_sony_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAPM3_Sony_D.jsv
fate-h264-conformance-caqp1_sony_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAQP1_Sony_B.jsv
-fate-h264-conformance-cavlc_mot_fld0_full_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/cvmp_mot_fld0_full_B.26l
-fate-h264-conformance-cavlc_mot_frm0_full_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/cvmp_mot_frm0_full_B.26l
-fate-h264-conformance-cavlc_mot_mbaff0_full_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/cvmp_mot_mbaff0_full_B.26l
-fate-h264-conformance-cavlc_mot_picaff0_full_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/cvmp_mot_picaff0_full_B.26l
+fate-h264-conformance-cavlc_mot_fld0_full_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/cvmp_mot_fld0_full_B.26l
+fate-h264-conformance-cavlc_mot_frm0_full_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/cvmp_mot_frm0_full_B.26l
+fate-h264-conformance-cavlc_mot_mbaff0_full_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/cvmp_mot_mbaff0_full_B.26l
+fate-h264-conformance-cavlc_mot_picaff0_full_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/cvmp_mot_picaff0_full_B.26l
fate-h264-conformance-cawp1_toshiba_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAWP1_TOSHIBA_E.264
-fate-h264-conformance-cawp5_toshiba_e: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CAWP5_TOSHIBA_E.264
+fate-h264-conformance-cawp5_toshiba_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CAWP5_TOSHIBA_E.264
fate-h264-conformance-ci1_ft_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CI1_FT_B.264
fate-h264-conformance-ci_mw_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CI_MW_D.264
-fate-h264-conformance-cvbs3_sony_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVBS3_Sony_C.jsv
+fate-h264-conformance-cvbs3_sony_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVBS3_Sony_C.jsv
fate-h264-conformance-cvcanlma2_sony_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVCANLMA2_Sony_C.jsv
-fate-h264-conformance-cvfi1_sony_d: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVFI1_Sony_D.jsv
-fate-h264-conformance-cvfi1_sva_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVFI1_SVA_C.264
-fate-h264-conformance-cvfi2_sony_h: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVFI2_Sony_H.jsv
-fate-h264-conformance-cvfi2_sva_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVFI2_SVA_C.264
+fate-h264-conformance-cvfi1_sony_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVFI1_Sony_D.jsv
+fate-h264-conformance-cvfi1_sva_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVFI1_SVA_C.264
+fate-h264-conformance-cvfi2_sony_h: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVFI2_Sony_H.jsv
+fate-h264-conformance-cvfi2_sva_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVFI2_SVA_C.264
fate-h264-conformance-cvma1_sony_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVMA1_Sony_D.jsv
-fate-h264-conformance-cvma1_toshiba_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVMA1_TOSHIBA_B.264
-fate-h264-conformance-cvmanl1_toshiba_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVMANL1_TOSHIBA_B.264
-fate-h264-conformance-cvmanl2_toshiba_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVMANL2_TOSHIBA_B.264
-fate-h264-conformance-cvmapaqp3_sony_e: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVMAPAQP3_Sony_E.jsv
-fate-h264-conformance-cvmaqp2_sony_g: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVMAQP2_Sony_G.jsv
-fate-h264-conformance-cvmaqp3_sony_d: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVMAQP3_Sony_D.jsv
-fate-h264-conformance-cvmp_mot_fld_l30_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVMP_MOT_FLD_L30_B.26l
-fate-h264-conformance-cvmp_mot_frm_l31_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVMP_MOT_FRM_L31_B.26l
+fate-h264-conformance-cvma1_toshiba_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVMA1_TOSHIBA_B.264
+fate-h264-conformance-cvmanl1_toshiba_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVMANL1_TOSHIBA_B.264
+fate-h264-conformance-cvmanl2_toshiba_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVMANL2_TOSHIBA_B.264
+fate-h264-conformance-cvmapaqp3_sony_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVMAPAQP3_Sony_E.jsv
+fate-h264-conformance-cvmaqp2_sony_g: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVMAQP2_Sony_G.jsv
+fate-h264-conformance-cvmaqp3_sony_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVMAQP3_Sony_D.jsv
+fate-h264-conformance-cvmp_mot_fld_l30_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVMP_MOT_FLD_L30_B.26l
+fate-h264-conformance-cvmp_mot_frm_l31_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVMP_MOT_FRM_L31_B.26l
fate-h264-conformance-cvnlfi1_sony_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVNLFI1_Sony_C.jsv
-fate-h264-conformance-cvnlfi2_sony_h: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVNLFI2_Sony_H.jsv
-fate-h264-conformance-cvpa1_toshiba_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVPA1_TOSHIBA_B.264
+fate-h264-conformance-cvnlfi2_sony_h: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVNLFI2_Sony_H.jsv
+fate-h264-conformance-cvpa1_toshiba_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVPA1_TOSHIBA_B.264
fate-h264-conformance-cvpcmnl1_sva_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVPCMNL1_SVA_C.264
fate-h264-conformance-cvpcmnl2_sva_c: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVPCMNL2_SVA_C.264
fate-h264-conformance-cvwp1_toshiba_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVWP1_TOSHIBA_E.264
-fate-h264-conformance-cvwp2_toshiba_e: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVWP2_TOSHIBA_E.264
-fate-h264-conformance-cvwp3_toshiba_e: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVWP3_TOSHIBA_E.264
-fate-h264-conformance-cvwp5_toshiba_e: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/CVWP5_TOSHIBA_E.264
+fate-h264-conformance-cvwp2_toshiba_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVWP2_TOSHIBA_E.264
+fate-h264-conformance-cvwp3_toshiba_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVWP3_TOSHIBA_E.264
+fate-h264-conformance-cvwp5_toshiba_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/CVWP5_TOSHIBA_E.264
fate-h264-conformance-fi1_sony_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FI1_Sony_E.jsv
fate-h264-conformance-frext-alphaconformanceg: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/test8b43.264
fate-h264-conformance-frext-bcrm_freh10: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/freh10.264 -vsync 0
@@ -315,23 +316,23 @@ fate-h264-conformance-frext-pph10i4_panasonic_a: CMD = framecrc -vsync 0 -i $(SA
fate-h264-conformance-frext-pph10i5_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH10I5_Panasonic_A.264 -pix_fmt yuv420p10le
fate-h264-conformance-frext-pph10i6_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH10I6_Panasonic_A.264 -pix_fmt yuv420p10le
fate-h264-conformance-frext-pph10i7_panasonic_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/FRext/PPH10I7_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-hcbp2_hhi_a: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/HCBP2_HHI_A.264
-fate-h264-conformance-hcmp1_hhi_a: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/HCMP1_HHI_A.264
+fate-h264-conformance-hcbp2_hhi_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/HCBP2_HHI_A.264
+fate-h264-conformance-hcmp1_hhi_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/HCMP1_HHI_A.264
fate-h264-conformance-ls_sva_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/LS_SVA_D.264
fate-h264-conformance-midr_mw_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MIDR_MW_D.264
fate-h264-conformance-mps_mw_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MPS_MW_A.264
fate-h264-conformance-mr1_bt_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MR1_BT_A.h264
fate-h264-conformance-mr1_mw_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MR1_MW_A.264
fate-h264-conformance-mr2_mw_a: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MR2_MW_A.264
-fate-h264-conformance-mr2_tandberg_e: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/MR2_TANDBERG_E.264
-fate-h264-conformance-mr3_tandberg_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/MR3_TANDBERG_B.264
+fate-h264-conformance-mr2_tandberg_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MR2_TANDBERG_E.264
+fate-h264-conformance-mr3_tandberg_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MR3_TANDBERG_B.264
fate-h264-conformance-mr4_tandberg_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/MR4_TANDBERG_C.264
fate-h264-conformance-mr5_tandberg_c: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/MR5_TANDBERG_C.264
-fate-h264-conformance-mr6_bt_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/MR6_BT_B.h264
-fate-h264-conformance-mr7_bt_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/MR7_BT_B.h264
-fate-h264-conformance-mr8_bt_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/MR8_BT_B.h264
-fate-h264-conformance-mr9_bt_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/MR9_BT_B.h264
-fate-h264-conformance-mv1_brcm_d: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/src19td.IBP.264
+fate-h264-conformance-mr6_bt_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MR6_BT_B.h264
+fate-h264-conformance-mr7_bt_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MR7_BT_B.h264
+fate-h264-conformance-mr8_bt_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MR8_BT_B.h264
+fate-h264-conformance-mr9_bt_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/MR9_BT_B.h264
+fate-h264-conformance-mv1_brcm_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/src19td.IBP.264
fate-h264-conformance-nl1_sony_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/NL1_Sony_D.jsv
fate-h264-conformance-nl2_sony_h: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/NL2_Sony_H.jsv
fate-h264-conformance-nl3_sva_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/NL3_SVA_E.264
@@ -341,9 +342,9 @@ fate-h264-conformance-nrf_mw_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-confo
fate-h264-conformance-sharp_mp_field_1_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_1_B.jvt
fate-h264-conformance-sharp_mp_field_2_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_2_B.jvt
fate-h264-conformance-sharp_mp_field_3_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_3_B.jvt
-fate-h264-conformance-sharp_mp_paff_1r2: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/Sharp_MP_PAFF_1r2.jvt
-fate-h264-conformance-sharp_mp_paff_2r: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/Sharp_MP_PAFF_2.jvt
-fate-h264-conformance-sl1_sva_b: CMD = framecrc -vsync 0 -strict 1 -i $(SAMPLES)/h264-conformance/SL1_SVA_B.264
+fate-h264-conformance-sharp_mp_paff_1r2: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/Sharp_MP_PAFF_1r2.jvt
+fate-h264-conformance-sharp_mp_paff_2r: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/Sharp_MP_PAFF_2.jvt
+fate-h264-conformance-sl1_sva_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/SL1_SVA_B.264
fate-h264-conformance-sva_ba1_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/SVA_BA1_B.264
fate-h264-conformance-sva_ba2_d: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/SVA_BA2_D.264
fate-h264-conformance-sva_base_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/SVA_Base_B.264
@@ -352,6 +353,7 @@ fate-h264-conformance-sva_fm1_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conf
fate-h264-conformance-sva_nl1_b: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/SVA_NL1_B.264
fate-h264-conformance-sva_nl2_e: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264-conformance/SVA_NL2_E.264
-fate-h264-interlace-crop: CMD = framecrc -vsync 0 -vframes 3 -i $(SAMPLES)/h264/interlaced_crop.mp4
+fate-h264-interlace-crop: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264/interlaced_crop.mp4 -vframes 3
fate-h264-lossless: CMD = framecrc -vsync 0 -i $(SAMPLES)/h264/lossless.h264
-fate-h264-extreme-plane-pred: CMD = framemd5 -strict 1 -vsync 0 -i $(SAMPLES)/h264/extreme-plane-pred.h264
+fate-h264-extreme-plane-pred: CMD = framemd5 -vsync 0 -i $(SAMPLES)/h264/extreme-plane-pred.h264
+fate-h264-bsf-mp4toannexb: CMD = md5 -i $(SAMPLES)/h264/interlaced_crop.mp4 -vcodec copy -bsf h264_mp4toannexb -f mpeg
diff --git a/tests/fate/image.mak b/tests/fate/image.mak
new file mode 100644
index 0000000..db52bd2
--- /dev/null
+++ b/tests/fate/image.mak
@@ -0,0 +1,32 @@
+FATE_TESTS += fate-dpx
+fate-dpx: CMD = framecrc -i $(SAMPLES)/dpx/lighthouse_rgb48.dpx
+
+FATE_TESTS += fate-fax-g3
+fate-fax-g3: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31D.TIF
+
+FATE_TESTS += fate-fax-g3s
+fate-fax-g3s: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31DS.TIF
+
+FATE_TESTS += fate-pictor
+fate-pictor: CMD = framecrc -i $(SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24
+
+FATE_TESTS += fate-ptx
+fate-ptx: CMD = framecrc -i $(SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24
+
+FATE_TESTS += fate-sunraster-1bit-raw
+fate-sunraster-1bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-1bit-raw.sun
+
+FATE_TESTS += fate-sunraster-1bit-rle
+fate-sunraster-1bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-1bit-rle.sun
+
+FATE_TESTS += fate-sunraster-8bit-raw
+fate-sunraster-8bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-8bit-raw.sun -pix_fmt rgb24
+
+FATE_TESTS += fate-sunraster-8bit-rle
+fate-sunraster-8bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-8bit-rle.sun -pix_fmt rgb24
+
+FATE_TESTS += fate-sunraster-24bit-raw
+fate-sunraster-24bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-raw.sun
+
+FATE_TESTS += fate-sunraster-24bit-rle
+fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun
diff --git a/tests/fate/indeo.mak b/tests/fate/indeo.mak
new file mode 100644
index 0000000..df07392
--- /dev/null
+++ b/tests/fate/indeo.mak
@@ -0,0 +1,8 @@
+FATE_TESTS += fate-indeo2
+fate-indeo2: CMD = framecrc -i $(SAMPLES)/rt21/VPAR0026.AVI
+
+FATE_TESTS += fate-indeo3
+fate-indeo3: CMD = framecrc -i $(SAMPLES)/iv32/cubes.mov
+
+FATE_TESTS += fate-indeo5
+fate-indeo5: CMD = framecrc -i $(SAMPLES)/iv50/Educ_Movie_DeadlyForce.avi -an
diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak
new file mode 100644
index 0000000..083f6e8
--- /dev/null
+++ b/tests/fate/libavcodec.mak
@@ -0,0 +1,3 @@
+FATE_TESTS += fate-iirfilter
+fate-iirfilter: libavcodec/iirfilter-test$(EXESUF)
+fate-iirfilter: CMD = run libavcodec/iirfilter-test
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
new file mode 100644
index 0000000..a65b724
--- /dev/null
+++ b/tests/fate/libavutil.mak
@@ -0,0 +1,38 @@
+FATE_TESTS += fate-adler32
+fate-adler32: libavutil/adler32-test$(EXESUF)
+fate-adler32: CMD = run libavutil/adler32-test
+fate-adler32: REF = /dev/null
+
+FATE_TESTS += fate-aes
+fate-aes: libavutil/aes-test$(EXESUF)
+fate-aes: CMD = run libavutil/aes-test
+fate-aes: REF = /dev/null
+
+FATE_TESTS += fate-base64
+fate-base64: libavutil/base64-test$(EXESUF)
+fate-base64: CMD = run libavutil/base64-test
+
+FATE_TESTS += fate-crc
+fate-crc: libavutil/crc-test$(EXESUF)
+fate-crc: CMD = run libavutil/crc-test
+
+FATE_TESTS += fate-des
+fate-des: libavutil/des-test$(EXESUF)
+fate-des: CMD = run libavutil/des-test
+fate-des: REF = /dev/null
+
+FATE_TESTS += fate-eval
+fate-eval: libavutil/eval-test$(EXESUF)
+fate-eval: CMD = run libavutil/eval-test
+
+FATE_TESTS += fate-fifo
+fate-fifo: libavutil/fifo-test$(EXESUF)
+fate-fifo: CMD = run libavutil/fifo-test
+
+FATE_TESTS += fate-md5
+fate-md5: libavutil/md5-test$(EXESUF)
+fate-md5: CMD = run libavutil/md5-test
+
+FATE_TESTS += fate-sha
+fate-sha: libavutil/sha-test$(EXESUF)
+fate-sha: CMD = run libavutil/sha-test
diff --git a/tests/fate/lossless-audio.mak b/tests/fate/lossless-audio.mak
new file mode 100644
index 0000000..e735597
--- /dev/null
+++ b/tests/fate/lossless-audio.mak
@@ -0,0 +1,17 @@
+FATE_TESTS += fate-lossless-appleaudio
+fate-lossless-appleaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/inside.m4a -f s16le
+
+FATE_TESTS += fate-lossless-meridianaudio
+fate-lossless-meridianaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.mlp -f s16le
+
+FATE_TESTS += fate-lossless-monkeysaudio
+fate-lossless-monkeysaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.ape -f s16le
+
+FATE_TESTS += fate-lossless-shortenaudio
+fate-lossless-shortenaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.shn -f s16le
+
+FATE_TESTS += fate-lossless-tta
+fate-lossless-tta: CMD = crc -i $(SAMPLES)/lossless-audio/inside.tta
+
+FATE_TESTS += fate-lossless-wavpackaudio
+fate-lossless-wavpackaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.wv -f s16le
diff --git a/tests/fate/lossless-video.mak b/tests/fate/lossless-video.mak
new file mode 100644
index 0000000..0d1e2b8
--- /dev/null
+++ b/tests/fate/lossless-video.mak
@@ -0,0 +1,17 @@
+FATE_TESTS += fate-loco-rgb
+fate-loco-rgb: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-rgb.avi
+
+FATE_TESTS += fate-loco-yuy2
+fate-loco-yuy2: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-0.avi
+
+FATE_TESTS += fate-msrle-8bit
+fate-msrle-8bit: CMD = framecrc -i $(SAMPLES)/msrle/Search-RLE.avi -pix_fmt rgb24
+
+FATE_TESTS += fate-mszh
+fate-mszh: CMD = framecrc -i $(SAMPLES)/lcl/mszh-1frame.avi
+
+FATE_TESTS += fate-vble
+fate-vble: CMD = framecrc -i $(SAMPLES)/vble/flowers-partial-2MB.avi
+
+FATE_TESTS += fate-zlib
+fate-zlib: CMD = framecrc -i $(SAMPLES)/lcl/zlib-1frame.avi
diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak
new file mode 100644
index 0000000..bb7e701
--- /dev/null
+++ b/tests/fate/microsoft.mak
@@ -0,0 +1,27 @@
+FATE_TESTS += fate-msmpeg4v1
+fate-msmpeg4v1: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/msmpeg4v1/mpg4.avi -an
+
+FATE_TESTS += fate-msvideo1-16bit
+fate-msvideo1-16bit: CMD = framecrc -i $(SAMPLES)/cram/clock-cram16.avi -pix_fmt rgb24
+
+FATE_TESTS += fate-msvideo1-8bit
+fate-msvideo1-8bit: CMD = framecrc -i $(SAMPLES)/cram/skating.avi -t 1 -pix_fmt rgb24
+
+FATE_TESTS += fate-wmv8-drm
+# discard last packet to avoid fails due to overread of VC-1 decoder
+fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(SAMPLES)/wmv8/wmv_drm.wmv -an -vframes 162
+
+FATE_TESTS += fate-wmv8-drm-nodec
+fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(SAMPLES)/wmv8/wmv_drm.wmv -acodec copy -vcodec copy
+
+FATE_TESTS += fate-vc1
+fate-vc1: CMD = framecrc -i $(SAMPLES)/vc1/SA00040.vc1
+
+FATE_TESTS += fate-vc1_sa00050
+fate-vc1_sa00050: CMD = framecrc -i $(SAMPLES)/vc1/SA00050.vc1
+
+FATE_TESTS += fate-vc1_sa10091
+fate-vc1_sa10091: CMD = framecrc -i $(SAMPLES)/vc1/SA10091.vc1
+
+FATE_TESTS += fate-vc1_sa20021
+fate-vc1_sa20021: CMD = framecrc -i $(SAMPLES)/vc1/SA20021.vc1
diff --git a/tests/fate/mp3.mak b/tests/fate/mp3.mak
index 859a4f3..9dfa829 100644
--- a/tests/fate/mp3.mak
+++ b/tests/fate/mp3.mak
@@ -4,32 +4,32 @@ fate-mp3-float-conf-compl: CMP = stddev
fate-mp3-float-conf-compl: REF = $(SAMPLES)/mp3-conformance/compl.pcm
FATE_MP3 += fate-mp3-float-conf-he_32khz
-fate-mp3-float-conf-he_32khz: CMD = pcm -acodec mp3float -fs 343296 -i $(SAMPLES)/mp3-conformance/he_32khz.bit
+fate-mp3-float-conf-he_32khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_32khz.bit -fs 343296
fate-mp3-float-conf-he_32khz: CMP = stddev
fate-mp3-float-conf-he_32khz: REF = $(SAMPLES)/mp3-conformance/he_32khz.pcm
FATE_MP3 += fate-mp3-float-conf-he_44khz
-fate-mp3-float-conf-he_44khz: CMD = pcm -acodec mp3float -fs 942336 -i $(SAMPLES)/mp3-conformance/he_44khz.bit
+fate-mp3-float-conf-he_44khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_44khz.bit -fs 942336
fate-mp3-float-conf-he_44khz: CMP = stddev
fate-mp3-float-conf-he_44khz: REF = $(SAMPLES)/mp3-conformance/he_44khz.pcm
FATE_MP3 += fate-mp3-float-conf-he_48khz
-fate-mp3-float-conf-he_48khz: CMD = pcm -acodec mp3float -fs 343296 -i $(SAMPLES)/mp3-conformance/he_48khz.bit
+fate-mp3-float-conf-he_48khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_48khz.bit -fs 343296
fate-mp3-float-conf-he_48khz: CMP = stddev
fate-mp3-float-conf-he_48khz: REF = $(SAMPLES)/mp3-conformance/he_48khz.pcm
FATE_MP3 += fate-mp3-float-conf-hecommon
-fate-mp3-float-conf-hecommon: CMD = pcm -acodec mp3float -fs 133632 -i $(SAMPLES)/mp3-conformance/hecommon.bit
+fate-mp3-float-conf-hecommon: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/hecommon.bit -fs 133632
fate-mp3-float-conf-hecommon: CMP = stddev
fate-mp3-float-conf-hecommon: REF = $(SAMPLES)/mp3-conformance/hecommon.pcm
FATE_MP3 += fate-mp3-float-conf-si
-fate-mp3-float-conf-si: CMD = pcm -acodec mp3float -fs 269568 -i $(SAMPLES)/mp3-conformance/si.bit
+fate-mp3-float-conf-si: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/si.bit -fs 269568
fate-mp3-float-conf-si: CMP = stddev
fate-mp3-float-conf-si: REF = $(SAMPLES)/mp3-conformance/si.pcm
FATE_MP3 += fate-mp3-float-conf-si_block
-fate-mp3-float-conf-si_block: CMD = pcm -acodec mp3float -fs 145152 -i $(SAMPLES)/mp3-conformance/si_block.bit
+fate-mp3-float-conf-si_block: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/si_block.bit -fs 145152
fate-mp3-float-conf-si_block: CMP = stddev
fate-mp3-float-conf-si_block: REF = $(SAMPLES)/mp3-conformance/si_block.pcm
diff --git a/tests/fate/mpc.mak b/tests/fate/mpc.mak
new file mode 100644
index 0000000..d7f8c47
--- /dev/null
+++ b/tests/fate/mpc.mak
@@ -0,0 +1,11 @@
+FATE_TESTS += fate-mpc7-demux
+fate-mpc7-demux: CMD = crc -i $(SAMPLES)/musepack/inside-mp7.mpc -acodec copy
+
+FATE_TESTS += fate-mpc8-demux
+fate-mpc8-demux: CMD = crc -i $(SAMPLES)/musepack/inside-mp8.mpc -acodec copy
+
+FATE_TESTS += fate-musepack7
+fate-musepack7: CMD = pcm -i $(SAMPLES)/musepack/inside-mp7.mpc
+fate-musepack7: CMP = oneoff
+fate-musepack7: REF = $(SAMPLES)/musepack/inside-mp7.pcm
+fate-musepack7: FUZZ = 1
diff --git a/tests/fate/pcm.mak b/tests/fate/pcm.mak
new file mode 100644
index 0000000..f8ee34a
--- /dev/null
+++ b/tests/fate/pcm.mak
@@ -0,0 +1,32 @@
+FATE_TESTS += fate-duck-dk3
+fate-duck-dk3: CMD = md5 -i $(SAMPLES)/duck/sop-audio-only.avi -f s16le
+
+FATE_TESTS += fate-duck-dk4
+fate-duck-dk4: CMD = md5 -i $(SAMPLES)/duck/salsa-audio-only.avi -f s16le
+
+FATE_TESTS += fate-ea-mad-pcm-planar
+fate-ea-mad-pcm-planar: CMD = framecrc -i $(SAMPLES)/ea-mad/xeasport.mad
+
+FATE_TESTS += fate-film-cvid-pcm-stereo-8bit
+fate-film-cvid-pcm-stereo-8bit: CMD = framecrc -i $(SAMPLES)/film/logo-capcom.cpk
+
+FATE_TESTS += fate-iff-pcm
+fate-iff-pcm: CMD = md5 -i $(SAMPLES)/iff/Bells -f s16le
+
+FATE_TESTS += fate-pcm_dvd
+fate-pcm_dvd: CMD = framecrc -i $(SAMPLES)/pcm-dvd/coolitnow-partial.vob -vn
+
+FATE_TESTS += fate-qt-rawpcm-8bit-mono-unsigned
+fate-qt-rawpcm-8bit-mono-unsigned: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-raw.mov -f s16le
+
+FATE_TESTS += fate-qt-rawpcm-8bit-stereo-unsigned
+fate-qt-rawpcm-8bit-stereo-unsigned: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-raw.mov -f s16le
+
+FATE_TESTS += fate-qt-rawpcm-16bit-stereo-signed-be
+fate-qt-rawpcm-16bit-stereo-signed-be: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-twos.mov -f s16le
+
+FATE_TESTS += fate-qt-rawpcm-16bit-stereo-signed-le
+fate-qt-rawpcm-16bit-stereo-signed-le: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-sowt.mov -f s16le
+
+FATE_TESTS += fate-w64
+fate-w64: CMD = crc -i $(SAMPLES)/w64/w64-pcm16.w64
diff --git a/tests/fate/prores.mak b/tests/fate/prores.mak
new file mode 100644
index 0000000..0200c6f
--- /dev/null
+++ b/tests/fate/prores.mak
@@ -0,0 +1,15 @@
+FATE_PRORES = fate-prores-422 \
+ fate-prores-422_hq \
+ fate-prores-422_lt \
+ fate-prores-422_proxy \
+ fate-prores-alpha \
+
+FATE_TESTS += $(FATE_PRORES)
+fate-prores: $(FATE_PRORES)
+
+fate-prores-422: CMD = framecrc -vsync 0 -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le
+fate-prores-422_hq: CMD = framecrc -vsync 0 -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_HQ.mov -pix_fmt yuv422p10le
+fate-prores-422_lt: CMD = framecrc -vsync 0 -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le
+fate-prores-422_proxy: CMD = framecrc -vsync 0 -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le
+fate-prores-alpha: CMD = framecrc -vsync 0 -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuv444p10le
+
diff --git a/tests/fate/qtrle.mak b/tests/fate/qtrle.mak
new file mode 100644
index 0000000..4856fe7
--- /dev/null
+++ b/tests/fate/qtrle.mak
@@ -0,0 +1,20 @@
+FATE_TESTS += fate-qtrle-1bit
+fate-qtrle-1bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-Monochrome.mov
+
+FATE_TESTS += fate-qtrle-2bit
+fate-qtrle-2bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-4Greys.mov -pix_fmt rgb24
+
+FATE_TESTS += fate-qtrle-4bit
+fate-qtrle-4bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-16Greys.mov -pix_fmt rgb24 -an
+
+FATE_TESTS += fate-qtrle-8bit
+fate-qtrle-8bit: CMD = framecrc -i $(SAMPLES)/qtrle/criticalpath-credits.mov -vsync 0 -pix_fmt rgb24 -an
+
+FATE_TESTS += fate-qtrle-16bit
+fate-qtrle-16bit: CMD = framecrc -i $(SAMPLES)/qtrle/mr-cork-rle.mov -pix_fmt rgb24
+
+FATE_TESTS += fate-qtrle-24bit
+fate-qtrle-24bit: CMD = framecrc -i $(SAMPLES)/qtrle/aletrek-rle.mov -vsync 0
+
+FATE_TESTS += fate-qtrle-32bit
+fate-qtrle-32bit: CMD = framecrc -i $(SAMPLES)/qtrle/ultra_demo_720_480_32bpp_rle.mov -pix_fmt rgb24
diff --git a/tests/fate/real.mak b/tests/fate/real.mak
new file mode 100644
index 0000000..b1ff507
--- /dev/null
+++ b/tests/fate/real.mak
@@ -0,0 +1,39 @@
+FATE_TESTS += fate-real-14_4
+fate-real-14_4: CMD = md5 -i $(SAMPLES)/real/ra3_in_rm_file.rm -f s16le
+
+FATE_TESTS += fate-ra-288
+fate-ra-288: CMD = pcm -i $(SAMPLES)/real/ra_288.rm
+fate-ra-288: CMP = oneoff
+fate-ra-288: REF = $(SAMPLES)/real/ra_288.pcm
+fate-ra-288: FUZZ = 2
+
+FATE_TESTS += fate-ra-cook
+fate-ra-cook: CMD = pcm -i $(SAMPLES)/real/ra_cook.rm
+fate-ra-cook: CMP = oneoff
+fate-ra-cook: REF = $(SAMPLES)/real/ra_cook.pcm
+
+FATE_TESTS += fate-rv30
+fate-rv30: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/real/rv30.rm -an
+
+FATE_TESTS += fate-real-rv40
+fate-real-rv40: CMD = framecrc -i $(SAMPLES)/real/spygames-2MB.rmvb -t 10 -an -vsync 0
+
+FATE_TESTS += fate-sipr-5k0
+fate-sipr-5k0: CMD = pcm -i $(SAMPLES)/sipr/sipr_5k0.rm
+fate-sipr-5k0: CMP = oneoff
+fate-sipr-5k0: REF = $(SAMPLES)/sipr/sipr_5k0.pcm
+
+FATE_TESTS += fate-sipr-6k5
+fate-sipr-6k5: CMD = pcm -i $(SAMPLES)/sipr/sipr_6k5.rm
+fate-sipr-6k5: CMP = oneoff
+fate-sipr-6k5: REF = $(SAMPLES)/sipr/sipr_6k5.pcm
+
+FATE_TESTS += fate-sipr-8k5
+fate-sipr-8k5: CMD = pcm -i $(SAMPLES)/sipr/sipr_8k5.rm
+fate-sipr-8k5: CMP = oneoff
+fate-sipr-8k5: REF = $(SAMPLES)/sipr/sipr_8k5.pcm
+
+FATE_TESTS += fate-sipr-16k
+fate-sipr-16k: CMD = pcm -i $(SAMPLES)/sipr/sipr_16k.rm
+fate-sipr-16k: CMP = oneoff
+fate-sipr-16k: REF = $(SAMPLES)/sipr/sipr_16k.pcm
diff --git a/tests/fate/screen.mak b/tests/fate/screen.mak
new file mode 100644
index 0000000..a296b00
--- /dev/null
+++ b/tests/fate/screen.mak
@@ -0,0 +1,44 @@
+FATE_TESTS += fate-cscd
+fate-cscd: CMD = framecrc -i $(SAMPLES)/CSCD/sample_video.avi -an -vsync 0 -pix_fmt rgb24
+
+FATE_TESTS += fate-fraps-v0
+fate-fraps-v0: CMD = framecrc -i $(SAMPLES)/fraps/Griffin_Ragdoll01-partial.avi
+
+FATE_TESTS += fate-fraps-v1
+fate-fraps-v1: CMD = framecrc -i $(SAMPLES)/fraps/sample-v1.avi -an
+
+FATE_TESTS += fate-fraps-v2
+fate-fraps-v2: CMD = framecrc -i $(SAMPLES)/fraps/test3-nosound-partial.avi
+
+FATE_TESTS += fate-fraps-v3
+fate-fraps-v3: CMD = framecrc -i $(SAMPLES)/fraps/psclient-partial.avi -pix_fmt rgb24
+
+FATE_TESTS += fate-fraps-v4
+fate-fraps-v4: CMD = framecrc -i $(SAMPLES)/fraps/WoW_2006-11-03_14-58-17-19-nosound-partial.avi
+
+FATE_TESTS += fate-fraps-v5
+fate-fraps-v5: CMD = framecrc -i $(SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi
+
+FATE_TESTS += fate-tscc-15bit
+fate-tscc-15bit: CMD = framecrc -i $(SAMPLES)/tscc/oneminute.avi -t 15 -pix_fmt rgb24
+
+FATE_TESTS += fate-tscc-32bit
+fate-tscc-32bit: CMD = framecrc -i $(SAMPLES)/tscc/2004-12-17-uebung9-partial.avi -pix_fmt rgb24 -an
+
+FATE_TESTS += fate-vmnc-16bit
+fate-vmnc-16bit: CMD = framecrc -i $(SAMPLES)/VMnc/test.avi -pix_fmt rgb24
+
+FATE_TESTS += fate-vmnc-32bit
+fate-vmnc-32bit: CMD = framecrc -i $(SAMPLES)/VMnc/VS2k5DebugDemo-01-partial.avi -pix_fmt rgb24
+
+FATE_TESTS += fate-zmbv-8bit
+fate-zmbv-8bit: CMD = framecrc -i $(SAMPLES)/zmbv/wc2_001-partial.avi -an -pix_fmt rgb24
+
+FATE_TESTS += fate-zmbv-15bit
+fate-zmbv-15bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_15bit.avi -pix_fmt rgb24 -t 25
+
+FATE_TESTS += fate-zmbv-16bit
+fate-zmbv-16bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_16bit.avi -pix_fmt rgb24 -t 25
+
+FATE_TESTS += fate-zmbv-32bit
+fate-zmbv-32bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_32bit.avi -pix_fmt rgb24 -t 25
diff --git a/tests/fate/utvideo.mak b/tests/fate/utvideo.mak
new file mode 100644
index 0000000..6ff0025
--- /dev/null
+++ b/tests/fate/utvideo.mak
@@ -0,0 +1,23 @@
+FATE_TESTS += fate-utvideo_rgba_left
+fate-utvideo_rgba_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_left.avi
+
+FATE_TESTS += fate-utvideo_rgba_median
+fate-utvideo_rgba_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_median.avi
+
+FATE_TESTS += fate-utvideo_rgb_left
+fate-utvideo_rgb_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_left.avi
+
+FATE_TESTS += fate-utvideo_rgb_median
+fate-utvideo_rgb_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_median.avi
+
+FATE_TESTS += fate-utvideo_yuv420_left
+fate-utvideo_yuv420_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv420_left.avi
+
+FATE_TESTS += fate-utvideo_yuv420_median
+fate-utvideo_yuv420_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv420_median.avi
+
+FATE_TESTS += fate-utvideo_yuv422_left
+fate-utvideo_yuv422_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv422_left.avi
+
+FATE_TESTS += fate-utvideo_yuv422_median
+fate-utvideo_yuv422_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv422_median.avi
diff --git a/tests/fate/vp8.mak b/tests/fate/vp8.mak
deleted file mode 100644
index 2b17130..0000000
--- a/tests/fate/vp8.mak
+++ /dev/null
@@ -1,20 +0,0 @@
-VP8_SUITE = 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017
-
-define FATE_VP8_SUITE
-FATE_VP8 += fate-vp8-test-vector$(2)-$(1)
-fate-vp8-test-vector$(2)-$(1): CMD = framemd5 $(3) -i $(SAMPLES)/vp8-test-vectors-r1/vp80-00-comprehensive-$(1).ivf
-fate-vp8-test-vector$(2)-$(1): REF = $(SRC_PATH_BARE)/tests/ref/fate/vp8-test-vector-$(1)
-endef
-
-define FATE_VP8_FULL
-$(foreach N,$(VP8_SUITE),$(eval $(call FATE_VP8_SUITE,$(N),$(1),$(2))))
-
-FATE_VP8 += fate-vp8-sign-bias$(1)
-fate-vp8-sign-bias$(1): CMD = framemd5 $(2) -i $(SAMPLES)/vp8/sintel-signbias.ivf
-fate-vp8-sign-bias$(1): REF = $(SRC_PATH_BARE)/tests/ref/fate/vp8-sign-bias
-endef
-
-$(eval $(call FATE_VP8_FULL))
-$(eval $(call FATE_VP8_FULL,-emu-edge,-flags emu_edge))
-FATE_TESTS += $(FATE_VP8)
-fate-vp8: $(FATE_VP8)
diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak
new file mode 100644
index 0000000..66e9ced
--- /dev/null
+++ b/tests/fate/vpx.mak
@@ -0,0 +1,38 @@
+FATE_TESTS += fate-ea-vp60
+fate-ea-vp60: CMD = framecrc -i $(SAMPLES)/ea-vp6/g36.vp6
+
+FATE_TESTS += fate-ea-vp61
+fate-ea-vp61: CMD = framecrc -i $(SAMPLES)/ea-vp6/MovieSkirmishGondor.vp6 -t 4
+
+FATE_TESTS += fate-vp3
+fate-vp3: CMD = framecrc -i $(SAMPLES)/vp3/vp31.avi
+
+FATE_TESTS += fate-vp5
+fate-vp5: CMD = framecrc -i $(SAMPLES)/vp5/potter512-400-partial.avi -an
+
+FATE_TESTS += fate-vp6a
+fate-vp6a: CMD = framecrc -i $(SAMPLES)/flash-vp6/300x180-Scr-f8-056alpha.flv
+
+FATE_TESTS += fate-vp6f
+fate-vp6f: CMD = framecrc -i $(SAMPLES)/flash-vp6/clip1024.flv
+
+VP8_SUITE = 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017
+
+define FATE_VP8_SUITE
+FATE_VP8 += fate-vp8-test-vector$(2)-$(1)
+fate-vp8-test-vector$(2)-$(1): CMD = framemd5 $(3) -i $(SAMPLES)/vp8-test-vectors-r1/vp80-00-comprehensive-$(1).ivf
+fate-vp8-test-vector$(2)-$(1): REF = $(SRC_PATH)/tests/ref/fate/vp8-test-vector-$(1)
+endef
+
+define FATE_VP8_FULL
+$(foreach N,$(VP8_SUITE),$(eval $(call FATE_VP8_SUITE,$(N),$(1),$(2))))
+
+FATE_VP8 += fate-vp8-sign-bias$(1)
+fate-vp8-sign-bias$(1): CMD = framemd5 $(2) -i $(SAMPLES)/vp8/sintel-signbias.ivf -vsync 0
+fate-vp8-sign-bias$(1): REF = $(SRC_PATH)/tests/ref/fate/vp8-sign-bias
+endef
+
+$(eval $(call FATE_VP8_FULL))
+$(eval $(call FATE_VP8_FULL,-emu-edge,-flags emu_edge))
+FATE_TESTS += $(FATE_VP8)
+fate-vp8: $(FATE_VP8)
diff --git a/tests/fate/vqf.mak b/tests/fate/vqf.mak
new file mode 100644
index 0000000..6860fad
--- /dev/null
+++ b/tests/fate/vqf.mak
@@ -0,0 +1,7 @@
+FATE_TESTS += fate-twinvq
+fate-twinvq: CMD = pcm -i $(SAMPLES)/vqf/achterba.vqf
+fate-twinvq: CMP = oneoff
+fate-twinvq: REF = $(SAMPLES)/vqf/achterba.pcm
+
+FATE_TESTS += fate-vqf-demux
+fate-vqf-demux: CMD = md5 -i $(SAMPLES)/vqf/achterba.vqf -acodec copy -f framecrc
diff --git a/tests/fate/wma.mak b/tests/fate/wma.mak
new file mode 100644
index 0000000..25626f3
--- /dev/null
+++ b/tests/fate/wma.mak
@@ -0,0 +1,27 @@
+FATE_TESTS += fate-wmapro-2ch
+fate-wmapro-2ch: CMD = pcm -i $(SAMPLES)/wmapro/Beethovens_9th-1_small.wma
+fate-wmapro-2ch: CMP = oneoff
+fate-wmapro-2ch: REF = $(SAMPLES)/wmapro/Beethovens_9th-1_small.pcm
+
+FATE_TESTS += fate-wmapro-5.1
+fate-wmapro-5.1: CMD = pcm -i $(SAMPLES)/wmapro/latin_192_mulitchannel_cut.wma
+fate-wmapro-5.1: CMP = oneoff
+fate-wmapro-5.1: REF = $(SAMPLES)/wmapro/latin_192_mulitchannel_cut.pcm
+
+FATE_TESTS += fate-wmavoice-7k
+fate-wmavoice-7k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-7K.wma
+fate-wmavoice-7k: CMP = stddev
+fate-wmavoice-7k: REF = $(SAMPLES)/wmavoice/streaming_CBR-7K.pcm
+fate-wmavoice-7k: FUZZ = 3
+
+FATE_TESTS += fate-wmavoice-11k
+fate-wmavoice-11k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-11K.wma
+fate-wmavoice-11k: CMP = stddev
+fate-wmavoice-11k: REF = $(SAMPLES)/wmavoice/streaming_CBR-11K.pcm
+fate-wmavoice-11k: FUZZ = 3
+
+FATE_TESTS += fate-wmavoice-19k
+fate-wmavoice-19k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-19K.wma
+fate-wmavoice-19k: CMP = stddev
+fate-wmavoice-19k: REF = $(SAMPLES)/wmavoice/streaming_CBR-19K.pcm
+fate-wmavoice-19k: FUZZ = 3
diff --git a/tests/fate2.mak b/tests/fate2.mak
index b4139f3..40cebfe 100644
--- a/tests/fate2.mak
+++ b/tests/fate2.mak
@@ -1,39 +1,3 @@
-FATE_TESTS += fate-twinvq
-fate-twinvq: CMD = pcm -i $(SAMPLES)/vqf/achterba.vqf
-fate-twinvq: CMP = oneoff
-fate-twinvq: REF = $(SAMPLES)/vqf/achterba.pcm
-
-FATE_TESTS += fate-sipr-16k
-fate-sipr-16k: CMD = pcm -i $(SAMPLES)/sipr/sipr_16k.rm
-fate-sipr-16k: CMP = oneoff
-fate-sipr-16k: REF = $(SAMPLES)/sipr/sipr_16k.pcm
-
-FATE_TESTS += fate-sipr-8k5
-fate-sipr-8k5: CMD = pcm -i $(SAMPLES)/sipr/sipr_8k5.rm
-fate-sipr-8k5: CMP = oneoff
-fate-sipr-8k5: REF = $(SAMPLES)/sipr/sipr_8k5.pcm
-
-FATE_TESTS += fate-sipr-6k5
-fate-sipr-6k5: CMD = pcm -i $(SAMPLES)/sipr/sipr_6k5.rm
-fate-sipr-6k5: CMP = oneoff
-fate-sipr-6k5: REF = $(SAMPLES)/sipr/sipr_6k5.pcm
-
-FATE_TESTS += fate-sipr-5k0
-fate-sipr-5k0: CMD = pcm -i $(SAMPLES)/sipr/sipr_5k0.rm
-fate-sipr-5k0: CMP = oneoff
-fate-sipr-5k0: REF = $(SAMPLES)/sipr/sipr_5k0.pcm
-
-FATE_TESTS += fate-ra-288
-fate-ra-288: CMD = pcm -i $(SAMPLES)/real/ra_288.rm
-fate-ra-288: CMP = oneoff
-fate-ra-288: REF = $(SAMPLES)/real/ra_288.pcm
-fate-ra-288: FUZZ = 2
-
-FATE_TESTS += fate-ra-cook
-fate-ra-cook: CMD = pcm -i $(SAMPLES)/real/ra_cook.rm
-fate-ra-cook: CMP = oneoff
-fate-ra-cook: REF = $(SAMPLES)/real/ra_cook.pcm
-
FATE_TESTS += fate-mpeg2-field-enc
fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an
@@ -56,9 +20,6 @@ fate-imc: REF = $(SAMPLES)/imc/imc.pcm
FATE_TESTS += fate-yop
fate-yop: CMD = framecrc -i $(SAMPLES)/yop/test1.yop -pix_fmt rgb24 -an
-FATE_TESTS += fate-pictor
-fate-pictor: CMD = framecrc -i $(SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24 -an
-
FATE_TESTS += fate-dts
fate-dts: CMD = pcm -i $(SAMPLES)/dts/dts.ts
fate-dts: CMP = oneoff
@@ -74,106 +35,22 @@ fate-truespeech: CMD = pcm -i $(SAMPLES)/truespeech/a6.wav
fate-truespeech: CMP = oneoff
fate-truespeech: REF = $(SAMPLES)/truespeech/a6.pcm
-FATE_TESTS += fate-ac3-2.0
-fate-ac3-2.0: CMD = pcm -i $(SAMPLES)/ac3/monsters_inc_2.0_192_small.ac3
-fate-ac3-2.0: CMP = oneoff
-fate-ac3-2.0: REF = $(SAMPLES)/ac3/monsters_inc_2.0_192_small.pcm
-
-FATE_TESTS += fate-ac3-5.1
-fate-ac3-5.1: CMD = pcm -i $(SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
-fate-ac3-5.1: CMP = oneoff
-fate-ac3-5.1: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small.pcm
-
-FATE_TESTS += fate-eac3-1
-fate-eac3-1: CMD = pcm -i $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small.eac3
-fate-eac3-1: CMP = oneoff
-fate-eac3-1: REF = $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small.pcm
-
-FATE_TESTS += fate-eac3-2
-fate-eac3-2: CMD = pcm -i $(SAMPLES)/eac3/csi_miami_stereo_128_spx_small.eac3
-fate-eac3-2: CMP = oneoff
-fate-eac3-2: REF = $(SAMPLES)/eac3/csi_miami_stereo_128_spx_small.pcm
-
-FATE_TESTS += fate-eac3-3
-fate-eac3-3: CMD = pcm -i $(SAMPLES)/eac3/matrix2_commentary1_stereo_192_small.eac3
-fate-eac3-3: CMP = oneoff
-fate-eac3-3: REF = $(SAMPLES)/eac3/matrix2_commentary1_stereo_192_small.pcm
-
-FATE_TESTS += fate-eac3-4
-fate-eac3-4: CMD = pcm -i $(SAMPLES)/eac3/serenity_english_5.1_1536_small.eac3
-fate-eac3-4: CMP = oneoff
-fate-eac3-4: REF = $(SAMPLES)/eac3/serenity_english_5.1_1536_small.pcm
-
-FATE_TESTS += fate-atrac1
-fate-atrac1: CMD = pcm -i $(SAMPLES)/atrac1/test_tones_small.aea
-fate-atrac1: CMP = oneoff
-fate-atrac1: REF = $(SAMPLES)/atrac1/test_tones_small.pcm
-
-FATE_TESTS += fate-atrac3-1
-fate-atrac3-1: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_066_small.wav
-fate-atrac3-1: CMP = oneoff
-fate-atrac3-1: REF = $(SAMPLES)/atrac3/mc_sich_at3_066_small.pcm
-
-FATE_TESTS += fate-atrac3-2
-fate-atrac3-2: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_105_small.wav
-fate-atrac3-2: CMP = oneoff
-fate-atrac3-2: REF = $(SAMPLES)/atrac3/mc_sich_at3_105_small.pcm
-
-FATE_TESTS += fate-atrac3-3
-fate-atrac3-3: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_132_small.wav
-fate-atrac3-3: CMP = oneoff
-fate-atrac3-3: REF = $(SAMPLES)/atrac3/mc_sich_at3_132_small.pcm
-
FATE_TESTS += fate-gsm
-fate-gsm: CMD = framecrc -t 10 -i $(SAMPLES)/gsm/sample-gsm-8000.mov
+fate-gsm: CMD = framecrc -i $(SAMPLES)/gsm/sample-gsm-8000.mov -t 10
FATE_TESTS += fate-gsm-ms
fate-gsm-ms: CMD = framecrc -i $(SAMPLES)/gsm/ciao.wav
FATE_TESTS += fate-g722dec-1
-fate-g722dec-1: CMD = framecrc -ar 16000 -i $(SAMPLES)/g722/conf-adminmenu-162.g722
-
-FATE_TESTS += fate-msmpeg4v1
-fate-msmpeg4v1: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/msmpeg4v1/mpg4.avi -an
-
-FATE_TESTS += fate-wmavoice-7k
-fate-wmavoice-7k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-7K.wma
-fate-wmavoice-7k: CMP = stddev
-fate-wmavoice-7k: REF = $(SAMPLES)/wmavoice/streaming_CBR-7K.pcm
-fate-wmavoice-7k: FUZZ = 3
-
-FATE_TESTS += fate-wmavoice-11k
-fate-wmavoice-11k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-11K.wma
-fate-wmavoice-11k: CMP = stddev
-fate-wmavoice-11k: REF = $(SAMPLES)/wmavoice/streaming_CBR-11K.pcm
-fate-wmavoice-11k: FUZZ = 3
-
-FATE_TESTS += fate-wmavoice-19k
-fate-wmavoice-19k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-19K.wma
-fate-wmavoice-19k: CMP = stddev
-fate-wmavoice-19k: REF = $(SAMPLES)/wmavoice/streaming_CBR-19K.pcm
-fate-wmavoice-19k: FUZZ = 3
-
-FATE_TESTS += fate-wmapro-5.1
-fate-wmapro-5.1: CMD = pcm -i $(SAMPLES)/wmapro/latin_192_mulitchannel_cut.wma
-fate-wmapro-5.1: CMP = oneoff
-fate-wmapro-5.1: REF = $(SAMPLES)/wmapro/latin_192_mulitchannel_cut.pcm
+fate-g722dec-1: CMD = framecrc -i $(SAMPLES)/g722/conf-adminmenu-162.g722
-FATE_TESTS += fate-wmapro-2ch
-fate-wmapro-2ch: CMD = pcm -i $(SAMPLES)/wmapro/Beethovens_9th-1_small.wma
-fate-wmapro-2ch: CMP = oneoff
-fate-wmapro-2ch: REF = $(SAMPLES)/wmapro/Beethovens_9th-1_small.pcm
+FATE_TESTS += fate-g722enc
+fate-g722enc: tests/data/asynth-16000-1.sw
+fate-g722enc: CMD = md5 -ar 16000 -ac 1 -f s16le -i $(TARGET_PATH)/tests/data/asynth-16000-1.sw -acodec g722 -ac 1 -f g722
FATE_TESTS += fate-ansi
fate-ansi: CMD = framecrc -chars_per_frame 44100 -i $(SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24
-FATE_TESTS += fate-wmv8-drm
-# discard last packet to avoid fails due to overread of VC-1 decoder
-fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(SAMPLES)/wmv8/wmv_drm.wmv -an -vframes 162
-
-FATE_TESTS += fate-wmv8-drm-nodec
-fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(SAMPLES)/wmv8/wmv_drm.wmv -acodec copy -vcodec copy
-
FATE_TESTS += fate-binkaudio-dct
fate-binkaudio-dct: CMD = pcm -i $(SAMPLES)/bink/binkaudio_dct.bik
fate-binkaudio-dct: CMP = oneoff
@@ -192,15 +69,6 @@ fate-txd-pal8: CMD = framecrc -i $(SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an
FATE_TESTS += fate-txd-16bpp
fate-txd-16bpp: CMD = framecrc -i $(SAMPLES)/txd/misc.txd -pix_fmt bgra -an
-FATE_TESTS += fate-vp3
-fate-vp3: CMD = framecrc -i $(SAMPLES)/vp3/vp31.avi
-
-FATE_TESTS += fate-fax-g3
-fate-fax-g3: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31D.TIF
-
-FATE_TESTS += fate-fax-g3s
-fate-fax-g3s: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31DS.TIF
-
FATE_TESTS += fate-ws_snd
fate-ws_snd: CMD = md5 -i $(SAMPLES)/vqa/ws_snd.vqa -f s16le
@@ -210,123 +78,15 @@ fate-dxa-scummvm: CMD = framecrc -i $(SAMPLES)/dxa/scummvm.dxa -pix_fmt rgb24
FATE_TESTS += fate-mjpegb
fate-mjpegb: CMD = framecrc -idct simple -flags +bitexact -i $(SAMPLES)/mjpegb/mjpegb_part.mov -an
-FATE_TESTS += fate-rv30
-fate-rv30: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/real/rv30.rm -an
-
-FATE_TESTS += fate-sha
-fate-sha: libavutil/sha-test$(EXESUF)
-fate-sha: CMD = run libavutil/sha-test
-
-FATE_TESTS += fate-musepack7
-fate-musepack7: CMD = pcm -i $(SAMPLES)/musepack/inside-mp7.mpc
-fate-musepack7: CMP = oneoff
-fate-musepack7: REF = $(SAMPLES)/musepack/inside-mp7.pcm
-fate-musepack7: FUZZ = 1
-
-FATE_TESTS += fate-amrnb-4k75
-fate-amrnb-4k75: CMD = pcm -i $(SAMPLES)/amrnb/4.75k.amr
-fate-amrnb-4k75: CMP = stddev
-fate-amrnb-4k75: REF = $(SAMPLES)/amrnb/4.75k.pcm
-fate-amrnb-4k75: FUZZ = 1
-
-FATE_TESTS += fate-amrnb-5k15
-fate-amrnb-5k15: CMD = pcm -i $(SAMPLES)/amrnb/5.15k.amr
-fate-amrnb-5k15: CMP = stddev
-fate-amrnb-5k15: REF = $(SAMPLES)/amrnb/5.15k.pcm
-fate-amrnb-5k15: FUZZ = 1
-
-FATE_TESTS += fate-amrnb-5k9
-fate-amrnb-5k9: CMD = pcm -i $(SAMPLES)/amrnb/5.9k.amr
-fate-amrnb-5k9: CMP = stddev
-fate-amrnb-5k9: REF = $(SAMPLES)/amrnb/5.9k.pcm
-fate-amrnb-5k9: FUZZ = 1
-
-FATE_TESTS += fate-amrnb-6k7
-fate-amrnb-6k7: CMD = pcm -i $(SAMPLES)/amrnb/6.7k.amr
-fate-amrnb-6k7: CMP = stddev
-fate-amrnb-6k7: REF = $(SAMPLES)/amrnb/6.7k.pcm
-fate-amrnb-6k7: FUZZ = 1
-
-FATE_TESTS += fate-amrnb-7k4
-fate-amrnb-7k4: CMD = pcm -i $(SAMPLES)/amrnb/7.4k.amr
-fate-amrnb-7k4: CMP = stddev
-fate-amrnb-7k4: REF = $(SAMPLES)/amrnb/7.4k.pcm
-fate-amrnb-7k4: FUZZ = 1
-
-FATE_TESTS += fate-amrnb-7k95
-fate-amrnb-7k95: CMD = pcm -i $(SAMPLES)/amrnb/7.95k.amr
-fate-amrnb-7k95: CMP = stddev
-fate-amrnb-7k95: REF = $(SAMPLES)/amrnb/7.95k.pcm
-fate-amrnb-7k95: FUZZ = 1
-
-FATE_TESTS += fate-amrnb-10k2
-fate-amrnb-10k2: CMD = pcm -i $(SAMPLES)/amrnb/10.2k.amr
-fate-amrnb-10k2: CMP = stddev
-fate-amrnb-10k2: REF = $(SAMPLES)/amrnb/10.2k.pcm
-fate-amrnb-10k2: FUZZ = 1
-
-FATE_TESTS += fate-amrnb-12k2
-fate-amrnb-12k2: CMD = pcm -i $(SAMPLES)/amrnb/12.2k.amr
-fate-amrnb-12k2: CMP = stddev
-fate-amrnb-12k2: REF = $(SAMPLES)/amrnb/12.2k.pcm
-fate-amrnb-12k2: FUZZ = 1
-
-FATE_TESTS += fate-amrwb-6k60
-fate-amrwb-6k60: CMD = pcm -i $(SAMPLES)/amrwb/seed-6k60.awb
-fate-amrwb-6k60: CMP = stddev
-fate-amrwb-6k60: REF = $(SAMPLES)/amrwb/seed-6k60.pcm
-fate-amrwb-6k60: FUZZ = 1
-
-FATE_TESTS += fate-amrwb-8k85
-fate-amrwb-8k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-8k85.awb
-fate-amrwb-8k85: CMP = stddev
-fate-amrwb-8k85: REF = $(SAMPLES)/amrwb/seed-8k85.pcm
-fate-amrwb-8k85: FUZZ = 1
-
-FATE_TESTS += fate-amrwb-12k65
-fate-amrwb-12k65: CMD = pcm -i $(SAMPLES)/amrwb/seed-12k65.awb
-fate-amrwb-12k65: CMP = stddev
-fate-amrwb-12k65: REF = $(SAMPLES)/amrwb/seed-12k65.pcm
-fate-amrwb-12k65: FUZZ = 1
-
-FATE_TESTS += fate-amrwb-14k25
-fate-amrwb-14k25: CMD = pcm -i $(SAMPLES)/amrwb/seed-14k25.awb
-fate-amrwb-14k25: CMP = stddev
-fate-amrwb-14k25: REF = $(SAMPLES)/amrwb/seed-14k25.pcm
-fate-amrwb-14k25: FUZZ = 2.6
-
-FATE_TESTS += fate-amrwb-15k85
-fate-amrwb-15k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-15k85.awb
-fate-amrwb-15k85: CMP = stddev
-fate-amrwb-15k85: REF = $(SAMPLES)/amrwb/seed-15k85.pcm
-fate-amrwb-15k85: FUZZ = 1
-
-FATE_TESTS += fate-amrwb-18k25
-fate-amrwb-18k25: CMD = pcm -i $(SAMPLES)/amrwb/seed-18k25.awb
-fate-amrwb-18k25: CMP = stddev
-fate-amrwb-18k25: REF = $(SAMPLES)/amrwb/seed-18k25.pcm
-fate-amrwb-18k25: FUZZ = 1
-
-FATE_TESTS += fate-amrwb-19k85
-fate-amrwb-19k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-19k85.awb
-fate-amrwb-19k85: CMP = stddev
-fate-amrwb-19k85: REF = $(SAMPLES)/amrwb/seed-19k85.pcm
-fate-amrwb-19k85: FUZZ = 1
+FATE_TESTS += fate-v410dec
+fate-v410dec: CMD = framecrc -i $(SAMPLES)/v410/lenav410.mov -pix_fmt yuv444p10le
-FATE_TESTS += fate-amrwb-23k05
-fate-amrwb-23k05: CMD = pcm -i $(SAMPLES)/amrwb/seed-23k05.awb
-fate-amrwb-23k05: CMP = stddev
-fate-amrwb-23k05: REF = $(SAMPLES)/amrwb/seed-23k05.pcm
-fate-amrwb-23k05: FUZZ = 2
+FATE_TESTS += fate-v410enc
+fate-v410enc: tests/vsynth1/00.pgm
+fate-v410enc: CMD = md5 -f image2 -vcodec pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -flags +bitexact -vcodec v410 -f avi
-FATE_TESTS += fate-amrwb-23k85
-fate-amrwb-23k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-23k85.awb
-fate-amrwb-23k85: CMP = stddev
-fate-amrwb-23k85: REF = $(SAMPLES)/amrwb/seed-23k85.pcm
-fate-amrwb-23k85: FUZZ = 2
+FATE_TESTS += fate-r210
+fate-r210: CMD = framecrc -i $(SAMPLES)/r210/r210.avi -pix_fmt rgb48le
-FATE_TESTS += fate-amrwb-23k85-2
-fate-amrwb-23k85-2: CMD = pcm -i $(SAMPLES)/amrwb/deus-23k85.awb
-fate-amrwb-23k85-2: CMP = stddev
-fate-amrwb-23k85-2: REF = $(SAMPLES)/amrwb/deus-23k85.pcm
-fate-amrwb-23k85-2: FUZZ = 1
+FATE_TESTS += fate-xxan-wc4
+fate-xxan-wc4: CMD = framecrc -i $(SAMPLES)/wc4-xan/wc4_2.avi -an -vframes 10
diff --git a/tests/ffserver-regression.sh b/tests/ffserver-regression.sh
deleted file mode 100755
index 11e4a54..0000000
--- a/tests/ffserver-regression.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-
-#perl -e 'chomp($wd = `pwd`); print map { s!tests/data/!!; "<Stream $_>\nFile $wd/tests/data/$_\n</Stream>\n\n" } @ARGV' tests/data/a* >> tests/data/ffserver.conf
-#perl -e 'chomp($wd = `pwd`); print map { s!tests/data/!!; "<Stream $_.asf>\nFile $wd/tests/data/$_\n</Stream>\n\n" } @ARGV' tests/data/a* >> tests/data/ffserver.conf
-
-. $(dirname $0)/md5.sh
-
-FILES=$(sed -n 's/^[^#]*<Stream \(.*\)>.*/\1/p' $2 | grep -v html)
-
-rm -f tests/feed1.ffm
-./ffserver -d -f "$2" 2> /dev/null &
-FFSERVER_PID=$!
-echo "Waiting for feeds to startup..."
-sleep 2
-(
- cd tests/data || exit $?
- rm -f ff-* ffserver.regression
- WGET_OPTIONS="--user-agent=NSPlayer -q --proxy=off -e verbose=off -e server_response=off"
- for file in $FILES; do
- if [ $(expr $file : "a-*") != 0 ]; then
- wget $WGET_OPTIONS -O - http://localhost:9999/$file > ff-$file
- else
- wget $WGET_OPTIONS -O - http://localhost:9999/$file?date=19700101T000000Z | dd bs=1 count=20000 > ff-$file 2>/dev/null
- fi
- do_md5sum ff-$file >>ffserver.regression
- done
-)
-kill $FFSERVER_PID
-wait > /dev/null 2>&1
-rm -f tests/feed1.ffm
-if diff -u "$1" tests/data/ffserver.regression; then
- echo
- echo Server regression test succeeded.
- exit 0
-else
- echo
- echo Server regression test: Error.
- exit 1
-fi
diff --git a/tests/ffserver.conf b/tests/ffserver.conf
deleted file mode 100644
index 1e6994a..0000000
--- a/tests/ffserver.conf
+++ /dev/null
@@ -1,307 +0,0 @@
-#
-# This is a test configuration file. You can invoke it with
-# ../ffserver -f ffserver.conf
-# when in the tests directory and once the vsynth1 subdirectory
-# has been populated. Then point your browser at http://whatever:9999/teststat.html
-# and you can look at the streams
-#
-
-#
-# Port on which the server is listening. You must select a different
-# port from your standard http web server if it is running on the same
-# computer.
-
-Port 9999
-RTSPPort 9990
-
-# Address on which the server is bound. Only useful if you have
-# several network interfaces.
-
-BindAddress 0.0.0.0
-
-# Number of simultaneous requests that can be handled. Since FFServer
-# is very fast, this limit is determined mainly by your Internet
-# connection speed.
-
-MaxClients 1000
-
-MaxBandwidth 100000
-
-# Access Log file (uses standard Apache log file format)
-# '-' is the standard output
-
-CustomLog -
-
-##################################################################
-# Definition of the live feeds. Each live feed contains one video
-# and/or audio sequence coming from an ffmpeg encoder or another
-# ffserver. This sequence may be encoded simultaneously with several
-# codecs at several resolutions.
-
-<Feed feed1.ffm>
-
-# You must use 'ffmpeg' to send a live feed to ffserver. In this
-# example, you can type:
-#
-# ffmpeg http://localhost:8090/feed1.ffm
-
-# ffserver can also do time shifting. It means that it can stream any
-# previously recorded live stream. The request should contain:
-# "http://xxxx?date=[YYYY-MM-DDT][[HH:]MM:]SS[.m...]".You must specify
-# a path where the feed is stored on disk. You also specify the
-# maximum size of the feed (100M bytes here). Default:
-# File=/tmp/feed_name.ffm FileMaxSize=5M
-
-File tests/feed1.ffm
-FileMaxSize 100M
-
-# Fire up ffmpeg pointing at this stream
-
-Launch ./ffmpeg -v 0 -y -f pgmyuv -i tests/vsynth1/%02d.pgm
-
-ACL allow localhost
-</Feed>
-
-##################################################################
-# Now you can define each stream which will be generated from the
-# original audio and video stream. Each format has a filename (here
-# 'test128.mpg'). FFServer will send this stream when answering a
-# request containing this filename.
-
-<Stream test_h.avi>
-Feed feed1.ffm
-Format avi
-#
-BitExact
-DctFastint
-IdctSimple
-VideoFrameRate 10
-VideoSize 352x288
-VideoBitRate 100
-VideoGopSize 30
-NoAudio
-
-PreRoll 10
-StartSendOnKey
-MaxTime 100
-
-</Stream>
-
-<Stream test_l.avi>
-Feed feed1.ffm
-Format avi
-#
-BitExact
-DctFastint
-IdctSimple
-VideoFrameRate 2
-VideoSize 320x240
-VideoBitRate 40
-VideoGopSize 20
-NoAudio
-
-PreRoll 20
-StartSendOnKey
-MaxTime 100
-
-</Stream>
-
-#<Stream test_h.mpg>
-#Feed feed1.ffm
-#
-#VideoFrameRate 10
-#VideoSize 352x288
-#VideoBitRate 100
-#VideoGopSize 30
-#NoAudio
-
-#PreRoll 10
-#StartSendOnKey
-#MaxTime 100
-#
-#</Stream>
-#
-#<Stream test_l.mpg>
-#Feed feed1.ffm
-##
-#VideoFrameRate 2
-#VideoSize 320x240
-#VideoBitRate 40
-#VideoGopSize 20
-#NoAudio
-#
-#PreRoll 20
-#StartSendOnKey
-#MaxTime 100
-#
-#</Stream>
-#
-<Stream test.swf>
-Feed feed1.ffm
-#
-BitExact
-DctFastint
-IdctSimple
-Qscale 10
-VideoFrameRate 10
-VideoSize 352x288
-VideoBitRate 100
-VideoGopSize 30
-NoAudio
-
-PreRoll 10
-StartSendOnKey
-MaxTime 100
-
-</Stream>
-
-<Stream test_h.asf>
-Feed feed1.ffm
-Format asf
-#
-BitExact
-DctFastint
-IdctSimple
-Qscale 10
-VideoFrameRate 10
-VideoSize 320x240
-VideoBitRate 100
-VideoGopSize 30
-NoAudio
-
-PreRoll 10
-StartSendOnKey
-MaxTime 100
-
-Title "Test data stream"
-
-</Stream>
-
-<Stream test_l.asf>
-Feed feed1.ffm
-Format asf
-#
-BitExact
-DctFastint
-IdctSimple
-Qscale 10
-VideoFrameRate 2
-VideoSize 320x240
-VideoBitRate 40
-VideoGopSize 20
-NoAudio
-
-PreRoll 20
-StartSendOnKey
-MaxTime 100
-
-Title "Test data stream"
-
-</Stream>
-
-<Stream test_h.rm>
-
-Feed feed1.ffm
-Format rm
-
-BitExact
-DctFastint
-IdctSimple
-Qscale 10
-VideoBitRate 100
-VideoFrameRate 10
-VideoGopSize 30
-VideoSize 320x240
-NoAudio
-
-PreRoll 10
-StartSendOnKey
-MaxTime 100
-
-</Stream>
-
-<Stream test_l.rm>
-
-Feed feed1.ffm
-Format rm
-
-BitExact
-DctFastint
-IdctSimple
-Qscale 10
-VideoBitRate 40
-VideoFrameRate 2
-VideoGopSize 20
-VideoSize 320x240
-NoAudio
-
-PreRoll 20
-StartSendOnKey
-MaxTime 100
-
-</Stream>
-
-
-<Stream test.jpg>
-
-Feed feed1.ffm
-Format jpeg
-Strict -1
-
-BitExact
-DctFastint
-IdctSimple
-VideoFrameRate 1
-VideoSize 352x288
-NoAudio
-
-PreRoll 2
-
-</Stream>
-
-<Stream test_small.jpg>
-
-Feed feed1.ffm
-Format jpeg
-Strict -1
-
-BitExact
-DctFastint
-IdctSimple
-VideoFrameRate 1
-VideoSize 160x128
-NoAudio
-
-PreRoll 2
-
-</Stream>
-
-<Stream test.mjpg>
-
-Feed feed1.ffm
-Format mpjpeg
-Strict -1
-
-BitExact
-DctFastint
-IdctSimple
-VideoFrameRate 1
-VideoSize 320x240
-NoAudio
-StartSendOnKey
-
-PreRoll 1
-MaxTime 100
-
-</Stream>
-
-
-##################################################################
-# Special stream : server status
-
-<Stream teststat.html>
-
-Format status
-
-</Stream>
-
diff --git a/tests/ffserver.regression.ref b/tests/ffserver.regression.ref
deleted file mode 100644
index 9fc7497..0000000
--- a/tests/ffserver.regression.ref
+++ /dev/null
@@ -1,10 +0,0 @@
-18c4ba0e8e7adb781216e38de61c2e39 ff-test_h.avi
-f84767c7af61f360f4b443c2c73f322f ff-test_l.avi
-d976848a9e4d5d8fc2659e4841cdece5 ff-test.swf
-28fd87d5075b9b011aad57292f271a04 ff-test_h.asf
-a31ccd3aba2551e60b9fb1c156fca2f8 ff-test_l.asf
-3279d3ed0ef2d1347b5eda84db2cf3e6 ff-test_h.rm
-440231fe3cf0849887390b4d67d6894a ff-test_l.rm
-e0dc91430660c619e97b5c82e0f398fc ff-test.jpg
-0d6c98fc8a4f00560fe34e94e26880a9 ff-test_small.jpg
-e2a315d7ac0576279f8b4d917999615a ff-test.mjpg
diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh
index 07dedb2..4a72e0a 100755
--- a/tests/lavf-regression.sh
+++ b/tests/lavf-regression.sh
@@ -14,15 +14,15 @@ eval do_$test=y
do_lavf()
{
file=${outfile}lavf.$1
- do_ffmpeg $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 $2
- do_ffmpeg_crc $file $DEC_OPTS -i $target_path/$file $3
+ do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -b:a 64k -t 1 -qscale:v 10 $2
+ do_avconv_crc $file $DEC_OPTS -i $target_path/$file $3
}
do_streamed_images()
{
file=${outfile}${1}pipe.$1
- do_ffmpeg $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src -f image2pipe $ENC_OPTS -t 1 -qscale 10
- do_ffmpeg_crc $file $DEC_OPTS -f image2pipe -i $target_path/$file
+ do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src -f image2pipe $ENC_OPTS -t 1 -qscale 10
+ do_avconv_crc $file $DEC_OPTS -f image2pipe -i $target_path/$file
}
do_image_formats()
@@ -30,23 +30,21 @@ do_image_formats()
outfile="$datadir/images/$1/"
mkdir -p "$outfile"
file=${outfile}%02d.$1
- run_ffmpeg $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $2 $ENC_OPTS $3 -t 0.5 -y -qscale 10 $target_path/$file
- do_md5sum ${outfile}02.$1 >> $logfile
- do_ffmpeg_crc $file $DEC_OPTS $3 -i $target_path/$file
- wc -c ${outfile}02.$1 >> $logfile
+ run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $2 $ENC_OPTS $3 -t 0.5 -y -qscale 10 $target_path/$file
+ do_md5sum ${outfile}02.$1
+ do_avconv_crc $file $DEC_OPTS $3 -i $target_path/$file
+ wc -c ${outfile}02.$1
}
do_audio_only()
{
file=${outfile}lavf.$1
- do_ffmpeg $file $DEC_OPTS $2 -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 $3
- do_ffmpeg_crc $file $DEC_OPTS $4 -i $target_path/$file
+ do_avconv $file $DEC_OPTS $2 -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 $3
+ do_avconv_crc $file $DEC_OPTS $4 -i $target_path/$file
}
-rm -f "$logfile"
-
if [ -n "$do_avi" ] ; then
-do_lavf avi
+do_lavf avi "-acodec mp2"
fi
if [ -n "$do_asf" ] ; then
@@ -55,9 +53,9 @@ fi
if [ -n "$do_rm" ] ; then
file=${outfile}lavf.rm
-do_ffmpeg $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 -acodec ac3_fixed
+do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 -acodec ac3_fixed -b:a 64k
# broken
-#do_ffmpeg_crc $file -i $target_path/$file
+#do_avconv_crc $file -i $target_path/$file
fi
if [ -n "$do_mpg" ] ; then
@@ -69,11 +67,11 @@ do_lavf mxf "-ar 48000 -bf 2 -timecode_frame_start 264363"
fi
if [ -n "$do_mxf_d10" ]; then
-do_lavf mxf_d10 "-ar 48000 -ac 2 -r 25 -s 720x576 -vf pad=720:608:0:32 -vcodec mpeg2video -intra -flags +ildct+low_delay -dc 10 -flags2 +ivlc+non_linear_q -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10"
+do_lavf mxf_d10 "-ar 48000 -ac 2 -r 25 -s 720x576 -vf pad=720:608:0:32 -vcodec mpeg2video -g 0 -flags +ildct+low_delay -dc 10 -flags2 +ivlc+non_linear_q -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10"
fi
if [ -n "$do_ts" ] ; then
-do_lavf ts
+do_lavf ts "-mpegts_transport_stream_id 42"
fi
if [ -n "$do_swf" ] ; then
@@ -89,7 +87,7 @@ do_lavf flv -an
fi
if [ -n "$do_mov" ] ; then
-do_lavf mov "-acodec pcm_alaw"
+do_lavf mov "-acodec pcm_alaw -c:v mpeg4"
fi
if [ -n "$do_dv_fmt" ] ; then
@@ -105,15 +103,15 @@ do_lavf nut "-acodec mp2"
fi
if [ -n "$do_mkv" ] ; then
-do_lavf mkv
+do_lavf mkv "-c:a mp2 -c:v mpeg4"
fi
# streamed images
# mjpeg
#file=${outfile}lavf.mjpeg
-#do_ffmpeg $file -t 1 -qscale 10 -f image2 -vcodec pgmyuv -i $raw_src
-#do_ffmpeg_crc $file -i $target_path/$file
+#do_avconv $file -t 1 -qscale 10 -f image2 -vcodec pgmyuv -i $raw_src
+#do_avconv_crc $file -i $target_path/$file
if [ -n "$do_pbmpipe" ] ; then
do_streamed_images pbm
@@ -129,14 +127,14 @@ fi
if [ -n "$do_gif" ] ; then
file=${outfile}lavf.gif
-do_ffmpeg $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS -t 1 -qscale 10 -pix_fmt rgb24
-do_ffmpeg_crc $file $DEC_OPTS -i $target_path/$file -pix_fmt rgb24
+do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS -t 1 -qscale 10 -pix_fmt rgb24
+do_avconv_crc $file $DEC_OPTS -i $target_path/$file -pix_fmt rgb24
fi
if [ -n "$do_yuv4mpeg" ] ; then
file=${outfile}lavf.y4m
-do_ffmpeg $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS -t 1 -qscale 10
-#do_ffmpeg_crc $file -i $target_path/$file
+do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS -t 1 -qscale 10
+#do_avconv_crc $file -i $target_path/$file
fi
# image formats
@@ -229,9 +227,9 @@ conversions="yuv420p yuv422p yuv444p yuyv422 yuv410p yuv411p yuvj420p \
monob yuv440p yuvj440p"
for pix_fmt in $conversions ; do
file=${outfile}${pix_fmt}.yuv
- run_ffmpeg $DEC_OPTS -r 1 -t 1 -f image2 -vcodec pgmyuv -i $raw_src \
- $ENC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt $target_path/$raw_dst
- do_ffmpeg $file $DEC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt -i $target_path/$raw_dst \
+ run_avconv $DEC_OPTS -r 1 -f image2 -vcodec pgmyuv -i $raw_src \
+ $ENC_OPTS -f rawvideo -t 1 -s 352x288 -pix_fmt $pix_fmt $target_path/$raw_dst
+ do_avconv $file $DEC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt -i $target_path/$raw_dst \
$ENC_OPTS -f rawvideo -s 352x288 -pix_fmt yuv444p
done
fi
diff --git a/tests/lavfi-regression.sh b/tests/lavfi-regression.sh
index b2a195a..f8c0c4e 100755
--- a/tests/lavfi-regression.sh
+++ b/tests/lavfi-regression.sh
@@ -11,15 +11,13 @@ set -e
eval do_$test=y
-rm -f "$logfile"
-
do_video_filter() {
label=$1
filters=$2
shift 2
- printf '%-20s' $label >>$logfile
- run_ffmpeg $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src \
- $ENC_OPTS -vf "$filters" -vcodec rawvideo $* -f nut md5: >>$logfile
+ printf '%-20s' $label
+ run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src \
+ $ENC_OPTS -vf "$filters" -vcodec rawvideo $* -f nut md5:
}
do_lavfi() {
@@ -51,7 +49,7 @@ do_lavfi_pixfmts(){
out_fmts=${outfile}${1}_out_fmts
# exclude pixel formats which are not supported as input
- $ffmpeg -pix_fmts list 2>/dev/null | sed -ne '9,$p' | grep '^\..\.' | cut -d' ' -f2 | sort >$exclude_fmts
+ $avconv -pix_fmts list 2>/dev/null | sed -ne '9,$p' | grep '^\..\.' | cut -d' ' -f2 | sort >$exclude_fmts
$showfiltfmts scale | awk -F '[ \r]' '/^OUTPUT/{ print $3 }' | sort | comm -23 - $exclude_fmts >$out_fmts
pix_fmts=$($showfiltfmts $filter | awk -F '[ \r]' '/^INPUT/{ print $3 }' | sort | comm -12 - $out_fmts)
@@ -71,8 +69,8 @@ do_lavfi_pixfmts "pad" "500:400:20:20"
do_lavfi_pixfmts "scale" "200:100"
do_lavfi_pixfmts "vflip" ""
-if [ -n "$do_pixdesc_be" ] || [ -n "$do_pixdesc_le" ]; then
- pix_fmts="$($ffmpeg -pix_fmts list 2>/dev/null | sed -ne '9,$p' | grep '^IO' | cut -d' ' -f2 | sort)"
+if [ -n "$do_pixdesc" ]; then
+ pix_fmts="$($avconv -pix_fmts list 2>/dev/null | sed -ne '9,$p' | grep '^IO' | cut -d' ' -f2 | sort)"
for pix_fmt in $pix_fmts; do
do_video_filter $pix_fmt "slicify=random,format=$pix_fmt,pixdesctest" -pix_fmt $pix_fmt
done
diff --git a/tests/ref/acodec/ac3_fixed b/tests/ref/acodec/ac3_fixed
index ca8a082..dba2dfc 100644
--- a/tests/ref/acodec/ac3_fixed
+++ b/tests/ref/acodec/ac3_fixed
@@ -1,2 +1,2 @@
-0f14801e166819dd4a58981aea36e08b *./tests/data/acodec/ac3.rm
+e7fa185030a56d9db8663ad9e38c6c94 *./tests/data/acodec/ac3.rm
98751 ./tests/data/acodec/ac3.rm
diff --git a/tests/ref/acodec/adpcm_ima_qt b/tests/ref/acodec/adpcm_ima_qt
index 6e44156..c1db43f 100644
--- a/tests/ref/acodec/adpcm_ima_qt
+++ b/tests/ref/acodec/adpcm_ima_qt
@@ -1,4 +1,4 @@
-3c06fd2f7831e3e8735b936e23ca220c *./tests/data/acodec/adpcm_qt.aiff
+057d27978b35888776512e4e9669a63b *./tests/data/acodec/adpcm_qt.aiff
281252 ./tests/data/acodec/adpcm_qt.aiff
-9580492803ba1c1a3746367b24b751c8 *./tests/data/adpcm_ima_qt.acodec.out.wav
-stddev: 914.65 PSNR: 37.10 MAXDIFF:34026 bytes: 1058560/ 1058400
+169c40435c68d50112c9c61fc67e446d *./tests/data/adpcm_ima_qt.acodec.out.wav
+stddev: 918.61 PSNR: 37.07 MAXDIFF:34029 bytes: 1058560/ 1058400
diff --git a/tests/ref/acodec/adpcm_ima_wav b/tests/ref/acodec/adpcm_ima_wav
index 29f5836..f83dbad 100644
--- a/tests/ref/acodec/adpcm_ima_wav
+++ b/tests/ref/acodec/adpcm_ima_wav
@@ -1,4 +1,4 @@
56b75c3a6dacedcf2ce7b0586aa33594 *./tests/data/acodec/adpcm_ima.wav
267324 ./tests/data/acodec/adpcm_ima.wav
-78a2af1c895792d0c221d127bdd48ece *./tests/data/adpcm_ima_wav.acodec.out.wav
+ddddfa47302da540abf19224202bef57 *./tests/data/adpcm_ima_wav.acodec.out.wav
stddev: 903.51 PSNR: 37.21 MAXDIFF:34026 bytes: 1061748/ 1058400
diff --git a/tests/ref/acodec/adpcm_ms b/tests/ref/acodec/adpcm_ms
index 65d2a6c..301bc80 100644
--- a/tests/ref/acodec/adpcm_ms
+++ b/tests/ref/acodec/adpcm_ms
@@ -1,4 +1,4 @@
a407b87daeef5b25dfb6c5b3f519e9c1 *./tests/data/acodec/adpcm_ms.wav
268378 ./tests/data/acodec/adpcm_ms.wav
-7be370f937c51e8a967e6a3d08d5156a *./tests/data/adpcm_ms.acodec.out.wav
+22863fb278c4e0ebe9c34cb15db5dd6b *./tests/data/adpcm_ms.acodec.out.wav
stddev: 1050.01 PSNR: 35.91 MAXDIFF:29806 bytes: 1060576/ 1058400
diff --git a/tests/ref/acodec/adpcm_swf b/tests/ref/acodec/adpcm_swf
index 27a5da5..5306dc4 100644
--- a/tests/ref/acodec/adpcm_swf
+++ b/tests/ref/acodec/adpcm_swf
@@ -1,4 +1,4 @@
42d4639866ed4d692eaf126228a4fa2a *./tests/data/acodec/adpcm_swf.flv
269166 ./tests/data/acodec/adpcm_swf.flv
-628089745a7059ae4055c2515b6d668b *./tests/data/adpcm_swf.acodec.out.wav
+f7df69d3fe708303820f2a9d00140a5b *./tests/data/adpcm_swf.acodec.out.wav
stddev: 933.58 PSNR: 36.93 MAXDIFF:51119 bytes: 1064960/ 1058400
diff --git a/tests/ref/acodec/adpcm_yam b/tests/ref/acodec/adpcm_yam
index d7076e7..0fd7029 100644
--- a/tests/ref/acodec/adpcm_yam
+++ b/tests/ref/acodec/adpcm_yam
@@ -1,4 +1,4 @@
-2546d72df736b5ffa1557e8c9c9ef788 *./tests/data/acodec/adpcm_yam.wav
-266296 ./tests/data/acodec/adpcm_yam.wav
-c80c847a53a0fee17a88fa889ec34a4e *./tests/data/adpcm_yam.acodec.out.wav
+006f8dc92eb4f7bab82eded314ca1124 *./tests/data/acodec/adpcm_yam.wav
+266298 ./tests/data/acodec/adpcm_yam.wav
+c36a9d5a1e0ad57fbe9665a31373b7c1 *./tests/data/adpcm_yam.acodec.out.wav
stddev: 1247.60 PSNR: 34.41 MAXDIFF:39895 bytes: 1064960/ 1058400
diff --git a/tests/ref/acodec/alac b/tests/ref/acodec/alac
index 35a1d8e..15d1a1f 100644
--- a/tests/ref/acodec/alac
+++ b/tests/ref/acodec/alac
@@ -1,4 +1,4 @@
-b25bcc7ec3f5c19cdfc01a6bbd32edb8 *./tests/data/acodec/alac.m4a
-389386 ./tests/data/acodec/alac.m4a
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/alac.acodec.out.wav
+8d9cb7f65c5b17c74e5f9bdc36f32b7d *./tests/data/acodec/alac.m4a
+389410 ./tests/data/acodec/alac.m4a
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/alac.acodec.out.wav
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/aref b/tests/ref/acodec/aref
index 8e6773b..cd89a63 100644
--- a/tests/ref/acodec/aref
+++ b/tests/ref/acodec/aref
@@ -1,2 +1,2 @@
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/acodec.ref.wav
-1058444 ./tests/data/acodec.ref.wav
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/acodec.ref.wav
+1058446 ./tests/data/acodec.ref.wav
diff --git a/tests/ref/acodec/flac b/tests/ref/acodec/flac
index e9d7cfc..cc5c173 100644
--- a/tests/ref/acodec/flac
+++ b/tests/ref/acodec/flac
@@ -1,4 +1,4 @@
-151eef9097f944726968bec48649f00a *./tests/data/acodec/flac.flac
-361582 ./tests/data/acodec/flac.flac
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/flac.acodec.out.wav
+f582b59cc68adfcb3342dcfd7e020b71 *./tests/data/acodec/flac.flac
+361581 ./tests/data/acodec/flac.flac
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/flac.acodec.out.wav
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/g722 b/tests/ref/acodec/g722
new file mode 100644
index 0000000..a1fc72a
--- /dev/null
+++ b/tests/ref/acodec/g722
@@ -0,0 +1,4 @@
+b380355e0360b4e50ee78f33fd60a0f5 *./tests/data/acodec/g722.wav
+47991 ./tests/data/acodec/g722.wav
+82fdd5bb059336e0550de7ba5947c5bb *./tests/data/g722.acodec.out.wav
+stddev: 8860.44 PSNR: 17.38 MAXDIFF:33814 bytes: 191732/ 1058400
diff --git a/tests/ref/acodec/g726 b/tests/ref/acodec/g726
index d2dbe50..9abed4b 100644
--- a/tests/ref/acodec/g726
+++ b/tests/ref/acodec/g726
@@ -1,4 +1,4 @@
-fd090ddf05cc3401cc75c4a5ace1d05a *./tests/data/acodec/g726.wav
-24052 ./tests/data/acodec/g726.wav
-74abea06027375111eeac1b2f8c7d3af *./tests/data/g726.acodec.out.wav
+64bfac75bd371304b704be5b3dbcd04a *./tests/data/acodec/g726.wav
+24054 ./tests/data/acodec/g726.wav
+79523adfec05760931fda877e1eaf7b4 *./tests/data/g726.acodec.out.wav
stddev: 8554.55 PSNR: 17.69 MAXDIFF:29353 bytes: 95984/ 1058400
diff --git a/tests/ref/acodec/mp2 b/tests/ref/acodec/mp2
index df21be2..3be6c58 100644
--- a/tests/ref/acodec/mp2
+++ b/tests/ref/acodec/mp2
@@ -1,5 +1,5 @@
f6eb0a205350bbd7fb1028a01c7ae8aa *./tests/data/acodec/mp2.mp2
96130 ./tests/data/acodec/mp2.mp2
-74c7b6b15a001add199619fafe4059a1 *./tests/data/mp2.acodec.out.wav
+5a669ca7321adc6ab66a3eade4035909 *./tests/data/mp2.acodec.out.wav
stddev: 9315.99 PSNR: 16.94 MAXDIFF:65388 bytes: 1059840/ 1058400
stddev: 4384.33 PSNR: 23.49 MAXDIFF:52631 bytes: 1057916/ 1058400
diff --git a/tests/ref/acodec/pcm b/tests/ref/acodec/pcm
deleted file mode 100644
index fc9dd8f..0000000
--- a/tests/ref/acodec/pcm
+++ /dev/null
@@ -1,72 +0,0 @@
-89f5b8dd97e0dddbe59af0d44fd229f3 *./tests/data/acodec/pcm_alaw.wav
-529256 ./tests/data/acodec/pcm_alaw.wav
-0568b0b9a72e31559e150e7e09d301cd *./tests/data/pcm.acodec.out.wav
-stddev: 101.67 PSNR: 56.19 MAXDIFF: 515 bytes: 1058400/ 1058400
-f443a8eeb1647ec1eeb8370c939e52d4 *./tests/data/acodec/pcm_mulaw.wav
-529256 ./tests/data/acodec/pcm_mulaw.wav
-1c3eeaa8814ebd4916780dff80ed6dc5 *./tests/data/pcm.acodec.out.wav
-stddev: 103.38 PSNR: 56.04 MAXDIFF: 644 bytes: 1058400/ 1058400
-760f85fb9f4e8aba326fb44ae84c9507 *./tests/data/acodec/pcm_s8.mov
-530837 ./tests/data/acodec/pcm_s8.mov
-652edf30f35ad89bf27bcc9d2f9c7b53 *./tests/data/pcm.acodec.out.wav
-stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400
-98cadb3502dbdc99e6e077c28b1a036c *./tests/data/acodec/pcm_u8.wav
-529244 ./tests/data/acodec/pcm_u8.wav
-652edf30f35ad89bf27bcc9d2f9c7b53 *./tests/data/pcm.acodec.out.wav
-stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400
-a4e18d1ca9ef5b8132a84d43625ddc47 *./tests/data/acodec/pcm_s16be.mov
-1060037 ./tests/data/acodec/pcm_s16be.mov
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/acodec/pcm_s16le.wav
-1058444 ./tests/data/acodec/pcm_s16le.wav
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-af717ca95eaca310772eb1238c745d1b *./tests/data/acodec/pcm_s16be.mkv
-1060638 ./tests/data/acodec/pcm_s16be.mkv
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-c4f51bf32fad2f7af8ea5beedb56168b *./tests/data/acodec/pcm_s16le.mkv
-1060638 ./tests/data/acodec/pcm_s16le.mkv
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-971d2d2633e41a0326fe2d04a2d0350f *./tests/data/acodec/pcm_s24be.mov
-1589237 ./tests/data/acodec/pcm_s24be.mov
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-a85380fb79b0d4fff38e24ac1e34bb94 *./tests/data/acodec/pcm_s24le.wav
-1587668 ./tests/data/acodec/pcm_s24le.wav
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-fc4f4e3e195bbde037ed31021d229f12 *./tests/data/acodec/pcm_s32be.mov
-2118437 ./tests/data/acodec/pcm_s32be.mov
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-da6ed80f4f40f0082577dea80827e014 *./tests/data/acodec/pcm_s32le.wav
-2116868 ./tests/data/acodec/pcm_s32le.wav
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-118ff3dc83c62ce9ce669eef57e55bb2 *./tests/data/acodec/pcm_f32be.au
-2116824 ./tests/data/acodec/pcm_f32be.au
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-46f44f86a18984a832206ab9e29a79f2 *./tests/data/acodec/pcm_f32le.wav
-2116880 ./tests/data/acodec/pcm_f32le.wav
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-8112296b1ed94f72f20d04b1a54850a7 *./tests/data/acodec/pcm_f64be.au
-4233624 ./tests/data/acodec/pcm_f64be.au
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-ba17c6d1a270e1333e981f239bf7eb45 *./tests/data/acodec/pcm_f64le.wav
-4233680 ./tests/data/acodec/pcm_f64le.wav
-95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/pcm.acodec.out.wav
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
-8c74234928ed425b1171211a89f67ead *./tests/data/acodec/pcm_zork.wav
-529256 ./tests/data/acodec/pcm_zork.wav
-864c8c866ac25642c29a13b122c70709 *./tests/data/pcm.acodec.out.wav
-stddev: 633.11 PSNR: 40.30 MAXDIFF:32768 bytes: 1058400/ 1058400
-8168a5c1343553ef027541830f2cb879 *./tests/data/acodec/pcm_s24daud.302
-10368730 ./tests/data/acodec/pcm_s24daud.302
-f552afadfdfcd6348a07095da6382de5 *./tests/data/pcm.acodec.out.wav
-stddev: 9416.28 PSNR: 16.85 MAXDIFF:42744 bytes: 6911796/ 1058400
diff --git a/tests/ref/acodec/pcm_alaw b/tests/ref/acodec/pcm_alaw
new file mode 100644
index 0000000..4943831
--- /dev/null
+++ b/tests/ref/acodec/pcm_alaw
@@ -0,0 +1,4 @@
+ede2da07839a00c255a43129922f2c7b *./tests/data/acodec/pcm_alaw.wav
+529258 ./tests/data/acodec/pcm_alaw.wav
+f323f7551ffad91de8613f44dcb198b6 *./tests/data/pcm_alaw.acodec.out.wav
+stddev: 101.67 PSNR: 56.19 MAXDIFF: 515 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_f32be b/tests/ref/acodec/pcm_f32be
new file mode 100644
index 0000000..5f067c2
--- /dev/null
+++ b/tests/ref/acodec/pcm_f32be
@@ -0,0 +1,4 @@
+118ff3dc83c62ce9ce669eef57e55bb2 *./tests/data/acodec/pcm_f32be.au
+2116824 ./tests/data/acodec/pcm_f32be.au
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_f32be.acodec.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_f32le b/tests/ref/acodec/pcm_f32le
new file mode 100644
index 0000000..38e5c0b
--- /dev/null
+++ b/tests/ref/acodec/pcm_f32le
@@ -0,0 +1,4 @@
+46f44f86a18984a832206ab9e29a79f2 *./tests/data/acodec/pcm_f32le.wav
+2116880 ./tests/data/acodec/pcm_f32le.wav
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_f32le.acodec.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_f64be b/tests/ref/acodec/pcm_f64be
new file mode 100644
index 0000000..9abdabc
--- /dev/null
+++ b/tests/ref/acodec/pcm_f64be
@@ -0,0 +1,4 @@
+8112296b1ed94f72f20d04b1a54850a7 *./tests/data/acodec/pcm_f64be.au
+4233624 ./tests/data/acodec/pcm_f64be.au
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_f64be.acodec.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_f64le b/tests/ref/acodec/pcm_f64le
new file mode 100644
index 0000000..42875a8
--- /dev/null
+++ b/tests/ref/acodec/pcm_f64le
@@ -0,0 +1,4 @@
+ba17c6d1a270e1333e981f239bf7eb45 *./tests/data/acodec/pcm_f64le.wav
+4233680 ./tests/data/acodec/pcm_f64le.wav
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_f64le.acodec.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_mulaw b/tests/ref/acodec/pcm_mulaw
new file mode 100644
index 0000000..cefd76b
--- /dev/null
+++ b/tests/ref/acodec/pcm_mulaw
@@ -0,0 +1,4 @@
+0c2a55850fb46ad5385a69b15b271f10 *./tests/data/acodec/pcm_mulaw.wav
+529258 ./tests/data/acodec/pcm_mulaw.wav
+7ae8c3fc804bd574006fd547fe28980c *./tests/data/pcm_mulaw.acodec.out.wav
+stddev: 103.38 PSNR: 56.04 MAXDIFF: 644 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s16be b/tests/ref/acodec/pcm_s16be
new file mode 100644
index 0000000..aea4c98
--- /dev/null
+++ b/tests/ref/acodec/pcm_s16be
@@ -0,0 +1,4 @@
+dd832e23156643becce8e9d2c24cb31d *./tests/data/acodec/pcm_s16be.mov
+1060073 ./tests/data/acodec/pcm_s16be.mov
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s16be.acodec.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s16le b/tests/ref/acodec/pcm_s16le
new file mode 100644
index 0000000..c7b5de7
--- /dev/null
+++ b/tests/ref/acodec/pcm_s16le
@@ -0,0 +1,4 @@
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/acodec/pcm_s16le.wav
+1058446 ./tests/data/acodec/pcm_s16le.wav
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s16le.acodec.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s24be b/tests/ref/acodec/pcm_s24be
new file mode 100644
index 0000000..4407af3
--- /dev/null
+++ b/tests/ref/acodec/pcm_s24be
@@ -0,0 +1,4 @@
+1b570c296bce03e36e1dfb369190ffb6 *./tests/data/acodec/pcm_s24be.mov
+1589273 ./tests/data/acodec/pcm_s24be.mov
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s24be.acodec.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s24daud b/tests/ref/acodec/pcm_s24daud
new file mode 100644
index 0000000..eab6f8d
--- /dev/null
+++ b/tests/ref/acodec/pcm_s24daud
@@ -0,0 +1,4 @@
+8168a5c1343553ef027541830f2cb879 *./tests/data/acodec/pcm_s24daud.302
+10368730 ./tests/data/acodec/pcm_s24daud.302
+f552afadfdfcd6348a07095da6382de5 *./tests/data/pcm_s24daud.acodec.out.wav
+stddev: 9416.28 PSNR: 16.85 MAXDIFF:42744 bytes: 6911796/ 1058400
diff --git a/tests/ref/acodec/pcm_s24le b/tests/ref/acodec/pcm_s24le
new file mode 100644
index 0000000..a724e8c
--- /dev/null
+++ b/tests/ref/acodec/pcm_s24le
@@ -0,0 +1,4 @@
+a85380fb79b0d4fff38e24ac1e34bb94 *./tests/data/acodec/pcm_s24le.wav
+1587668 ./tests/data/acodec/pcm_s24le.wav
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s24le.acodec.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s32be b/tests/ref/acodec/pcm_s32be
new file mode 100644
index 0000000..fc8fb5e
--- /dev/null
+++ b/tests/ref/acodec/pcm_s32be
@@ -0,0 +1,4 @@
+249c2ca88e2d8cdaed345e3d446e5bc3 *./tests/data/acodec/pcm_s32be.mov
+2118473 ./tests/data/acodec/pcm_s32be.mov
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s32be.acodec.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s32le b/tests/ref/acodec/pcm_s32le
new file mode 100644
index 0000000..8677750
--- /dev/null
+++ b/tests/ref/acodec/pcm_s32le
@@ -0,0 +1,4 @@
+da6ed80f4f40f0082577dea80827e014 *./tests/data/acodec/pcm_s32le.wav
+2116868 ./tests/data/acodec/pcm_s32le.wav
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s32le.acodec.out.wav
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_s8 b/tests/ref/acodec/pcm_s8
new file mode 100644
index 0000000..01c2240
--- /dev/null
+++ b/tests/ref/acodec/pcm_s8
@@ -0,0 +1,4 @@
+f467f8899b2bd11c736d0f4e61efb1c4 *./tests/data/acodec/pcm_s8.mov
+530873 ./tests/data/acodec/pcm_s8.mov
+651d4eb8d98dfcdda96ae6c43d8f156b *./tests/data/pcm_s8.acodec.out.wav
+stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400
diff --git a/tests/ref/acodec/pcm_u8 b/tests/ref/acodec/pcm_u8
new file mode 100644
index 0000000..e8d70c9
--- /dev/null
+++ b/tests/ref/acodec/pcm_u8
@@ -0,0 +1,4 @@
+70fecbae732f81143a560c7315eda49a *./tests/data/acodec/pcm_u8.wav
+529246 ./tests/data/acodec/pcm_u8.wav
+651d4eb8d98dfcdda96ae6c43d8f156b *./tests/data/pcm_u8.acodec.out.wav
+stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400
diff --git a/tests/ref/fate/aac-demux b/tests/ref/fate/adts-demux
similarity index 100%
rename from tests/ref/fate/aac-demux
rename to tests/ref/fate/adts-demux
diff --git a/tests/ref/fate/base64 b/tests/ref/fate/base64
new file mode 100644
index 0000000..24fa9ad
--- /dev/null
+++ b/tests/ref/fate/base64
@@ -0,0 +1,9 @@
+Encoding/decoding tests
+Passed!
+Passed!
+Passed!
+Passed!
+Passed!
+Passed!
+Passed!
+Passed!
diff --git a/tests/ref/fate/bethsoft-vid b/tests/ref/fate/bethsoft-vid
index 92c694b..0886bfc 100644
--- a/tests/ref/fate/bethsoft-vid
+++ b/tests/ref/fate/bethsoft-vid
@@ -1,90 +1,91 @@
-0, 0, 192000, 0x00000000
+0, 0, 192000, 0xdecc683b
1, 0, 1480, 0x00000000
-0, 1500, 192000, 0x01a6cf45
-0, 3000, 192000, 0xd07d57e9
-0, 4500, 192000, 0x3cb1dff5
+0, 1500, 192000, 0x00000000
+0, 3000, 192000, 0x01a6cf45
+0, 4500, 192000, 0xd07d57e9
1, 5994, 1480, 0x20a92bd4
-0, 6000, 192000, 0xd1aaa8fb
-0, 7500, 192000, 0x75f526cd
-0, 9000, 192000, 0x0f673577
-0, 10500, 192000, 0x897b6781
+0, 6000, 192000, 0x3cb1dff5
+0, 7500, 192000, 0xd1aaa8fb
+0, 9000, 192000, 0x75f526cd
+0, 10500, 192000, 0x0f673577
1, 11988, 1850, 0xa9e48a74
-0, 12000, 192000, 0x81e6b7f7
-0, 13500, 192000, 0x1f45ce61
-0, 15000, 192000, 0x5a0772a6
-0, 16500, 192000, 0xf78732b3
-0, 18000, 192000, 0x8427f9e5
+0, 12000, 192000, 0x897b6781
+0, 13500, 192000, 0x81e6b7f7
+0, 15000, 192000, 0x1f45ce61
+0, 16500, 192000, 0x5a0772a6
+0, 18000, 192000, 0xf78732b3
1, 19481, 1480, 0x23ecd018
-0, 19500, 192000, 0x40473f11
-0, 21000, 192000, 0x173ceebe
-0, 22500, 192000, 0x136b9516
-0, 24000, 192000, 0x138d11ae
+0, 19500, 192000, 0x8427f9e5
+0, 21000, 192000, 0x40473f11
+0, 22500, 192000, 0x173ceebe
+0, 24000, 192000, 0x136b9516
1, 25475, 1480, 0x206bb915
-0, 25500, 192000, 0x063dbff3
-0, 27000, 192000, 0x5280852f
-0, 28500, 192000, 0x99943a8f
-0, 30000, 192000, 0x0330a728
+0, 25500, 192000, 0x138d11ae
+0, 27000, 192000, 0x063dbff3
+0, 28500, 192000, 0x5280852f
+0, 30000, 192000, 0x99943a8f
1, 31469, 1850, 0xb0e10e75
-0, 31500, 192000, 0x5d35467d
-0, 33000, 192000, 0xfd436343
-0, 34500, 192000, 0xc323fcfe
-0, 36000, 192000, 0x2a1530a0
-0, 37500, 192000, 0xbd43bb60
+0, 31500, 192000, 0x0330a728
+0, 33000, 192000, 0x5d35467d
+0, 34500, 192000, 0xfd436343
+0, 36000, 192000, 0xc323fcfe
+0, 37500, 192000, 0x2a1530a0
1, 38961, 1480, 0x8d9baedd
-0, 39000, 192000, 0xa47f5eab
-0, 40500, 192000, 0xff17f5f7
-0, 42000, 192000, 0xb4140b55
-0, 43500, 192000, 0xb8782cc4
+0, 39000, 192000, 0xbd43bb60
+0, 40500, 192000, 0xa47f5eab
+0, 42000, 192000, 0xff17f5f7
+0, 43500, 192000, 0xb4140b55
1, 44955, 1480, 0xb802aae1
-0, 45000, 192000, 0x92975b8b
-0, 46500, 192000, 0xf42a64d6
-0, 48000, 192000, 0x2cc7077d
-0, 49500, 192000, 0x00080cc8
+0, 45000, 192000, 0xb8782cc4
+0, 46500, 192000, 0x92975b8b
+0, 48000, 192000, 0xf42a64d6
+0, 49500, 192000, 0x2cc7077d
1, 50950, 1480, 0xecd7b5cc
-0, 51000, 192000, 0x584b48f3
-0, 52500, 192000, 0xd68f57da
-0, 54000, 192000, 0x60158422
-0, 55500, 192000, 0xd7fb89e6
+0, 51000, 192000, 0x00080cc8
+0, 52500, 192000, 0x584b48f3
+0, 54000, 192000, 0xd68f57da
+0, 55500, 192000, 0x60158422
1, 56944, 1850, 0x16861355
-0, 57000, 192000, 0x97f1c76a
-0, 58500, 192000, 0x46c4bb9e
-0, 60000, 192000, 0xd32f9b66
-0, 61500, 192000, 0x74f43886
-0, 63000, 192000, 0x3c4e47df
+0, 57000, 192000, 0xd7fb89e6
+0, 58500, 192000, 0x97f1c76a
+0, 60000, 192000, 0x46c4bb9e
+0, 61500, 192000, 0xd32f9b66
+0, 63000, 192000, 0x74f43886
1, 64436, 1480, 0xa51690bd
-0, 64500, 192000, 0xb5ac0a58
-0, 66000, 192000, 0xcc572b31
-0, 67500, 192000, 0xb1739d26
-0, 69000, 192000, 0x73da5473
+0, 64500, 192000, 0x3c4e47df
+0, 66000, 192000, 0xb5ac0a58
+0, 67500, 192000, 0xcc572b31
+0, 69000, 192000, 0xb1739d26
1, 70430, 1480, 0xdd0b90d1
-0, 70500, 192000, 0x5f79f5bc
-0, 72000, 192000, 0x0affc0a0
-0, 73500, 192000, 0x2b4d5c1c
-0, 75000, 192000, 0x309b41bc
+0, 70500, 192000, 0x73da5473
+0, 72000, 192000, 0x5f79f5bc
+0, 73500, 192000, 0x0affc0a0
+0, 75000, 192000, 0x2b4d5c1c
1, 76424, 1850, 0x3ce6e333
-0, 76500, 192000, 0xd42b6424
-0, 78000, 192000, 0x4795c948
-0, 79500, 192000, 0xbc1a3a8b
-0, 81000, 192000, 0x16529c5b
-0, 82500, 192000, 0x6b1b31ba
+0, 76500, 192000, 0x309b41bc
+0, 78000, 192000, 0xd42b6424
+0, 79500, 192000, 0x4795c948
+0, 81000, 192000, 0xbc1a3a8b
+0, 82500, 192000, 0x16529c5b
1, 83917, 1480, 0xf8ce8ea3
-0, 84000, 192000, 0x569182ce
-0, 85500, 192000, 0xe6ea9866
-0, 87000, 192000, 0x102c6076
-0, 88500, 192000, 0xb29f527a
+0, 84000, 192000, 0x6b1b31ba
+0, 85500, 192000, 0x569182ce
+0, 87000, 192000, 0xe6ea9866
+0, 88500, 192000, 0x102c6076
1, 89911, 1480, 0xda4597af
-0, 90000, 192000, 0x040b4eee
-0, 91500, 192000, 0x92574f4a
-0, 93000, 192000, 0x1e8acdce
-0, 94500, 192000, 0x1becf516
+0, 90000, 192000, 0xb29f527a
+0, 91500, 192000, 0x040b4eee
+0, 93000, 192000, 0x92574f4a
+0, 94500, 192000, 0x1e8acdce
1, 95905, 1480, 0x918f7cb3
-0, 96000, 192000, 0xb62e9776
-0, 97500, 192000, 0xed37a08e
-0, 99000, 192000, 0xc0719912
-0, 100500, 192000, 0x24cf7a7e
+0, 96000, 192000, 0x1becf516
+0, 97500, 192000, 0xb62e9776
+0, 99000, 192000, 0xed37a08e
+0, 100500, 192000, 0xc0719912
1, 101899, 1850, 0xca6edb15
-0, 102000, 192000, 0x0307f62f
-0, 103500, 192000, 0x79b7417b
+0, 102000, 192000, 0x24cf7a7e
+0, 103500, 192000, 0x0307f62f
+0, 105000, 192000, 0x79b7417b
1, 109392, 1480, 0xba279597
1, 115386, 1480, 0xc5a38a9e
1, 121380, 1850, 0x8147eef5
diff --git a/tests/ref/fate/cdgraphics b/tests/ref/fate/cdgraphics
index 0f9e74e..10873fd 100644
--- a/tests/ref/fate/cdgraphics
+++ b/tests/ref/fate/cdgraphics
@@ -37,263 +37,264 @@
0, 10800, 194400, 0x7b8cf983
0, 11100, 194400, 0x07a20f7c
0, 11400, 194400, 0xa63e2962
-0, 11700, 194400, 0xa63e2962
-0, 12000, 194400, 0x2dd54447
-0, 12300, 194400, 0x90735e2d
-0, 12600, 194400, 0x90735e2d
-0, 12900, 194400, 0x90d98506
-0, 13200, 194400, 0xe5b08ffb
-0, 13500, 194400, 0xe5b08ffb
-0, 13800, 194400, 0x7a0d95f5
-0, 14100, 194400, 0xff6bacde
-0, 14400, 194400, 0xff6bacde
-0, 14700, 194400, 0xd998c2c8
-0, 15000, 194400, 0x3d1ddfab
-0, 15300, 194400, 0x3d1ddfab
-0, 15600, 194400, 0x817de4a6
-0, 15900, 194400, 0xfa3ef694
-0, 16200, 194400, 0xfa3ef694
-0, 16500, 194400, 0x0b5bfb8f
-0, 16800, 194400, 0x00f62376
-0, 17100, 194400, 0x00f62376
-0, 17400, 194400, 0x2f6b2d6c
-0, 17700, 194400, 0x40cb4752
-0, 18000, 194400, 0x40cb4752
-0, 18300, 194400, 0xd8456435
-0, 18600, 194400, 0x459f6a2f
-0, 18900, 194400, 0x459f6a2f
-0, 19200, 194400, 0x9b678910
-0, 19500, 194400, 0x8791a1f7
-0, 19800, 194400, 0x8791a1f7
-0, 20100, 194400, 0xdb4ac5d3
-0, 20400, 194400, 0xb223c8d0
-0, 20700, 194400, 0xb223c8d0
-0, 21000, 194400, 0x4a9ce7b1
-0, 21300, 194400, 0x187eeaae
-0, 21600, 194400, 0x187eeaae
-0, 21900, 194400, 0xc712f8a0
-0, 22200, 194400, 0x549c00a7
-0, 22500, 194400, 0x549c00a7
-0, 22800, 194400, 0x4d991295
-0, 23100, 194400, 0xc41b2681
-0, 23400, 194400, 0xc41b2681
-0, 23700, 194400, 0xed5a3077
-0, 24000, 194400, 0x85ad4463
-0, 24300, 194400, 0x85ad4463
-0, 24600, 194400, 0xb98f4760
-0, 24900, 194400, 0x87ef5e49
-0, 25200, 194400, 0x87ef5e49
-0, 25500, 194400, 0x830a6146
-0, 25800, 194400, 0xe33a792e
-0, 26100, 194400, 0xe33a792e
-0, 26400, 194400, 0x83517a2d
-0, 26700, 194400, 0xa97e9314
-0, 27000, 194400, 0xa97e9314
-0, 27300, 194400, 0x39059611
-0, 27600, 194400, 0xbf4eb9ed
-0, 27900, 194400, 0xbf4eb9ed
-0, 28200, 194400, 0xe5afc4e2
-0, 28500, 194400, 0x35d4cdd9
-0, 28800, 194400, 0x35d4cdd9
-0, 29100, 194400, 0xb376e1c5
-0, 29400, 194400, 0x6128e3c3
-0, 29700, 194400, 0x6128e3c3
-0, 30000, 194400, 0x30b7f7af
-0, 30300, 194400, 0xf1effaac
-0, 30600, 194400, 0xf1effaac
-0, 30900, 194400, 0x483914a1
-0, 31200, 194400, 0xbd48199c
-0, 31500, 194400, 0xbd48199c
-0, 31800, 194400, 0x382f2d88
-0, 32100, 194400, 0x5a573085
-0, 32400, 194400, 0x5a573085
-0, 32700, 194400, 0x89733580
-0, 33000, 194400, 0xd1325a5b
-0, 33300, 194400, 0xd1325a5b
-0, 33600, 194400, 0x655b6253
-0, 33900, 194400, 0x55146352
-0, 34200, 194400, 0x55146352
-0, 34500, 194400, 0xda527c39
-0, 34800, 194400, 0xb0cd7e37
-0, 35100, 194400, 0xb0cd7e37
-0, 35400, 194400, 0x25e7991c
-0, 35700, 194400, 0x5c22a411
-0, 36000, 194400, 0x5c22a411
-0, 36300, 194400, 0x1e2abdf7
-0, 36600, 194400, 0x8308bff5
-0, 36900, 194400, 0x8308bff5
-0, 37200, 194400, 0xfdbfd6de
-0, 37500, 194400, 0xd4d4d9db
-0, 37800, 194400, 0xd4d4d9db
-0, 38100, 194400, 0xa449fbb9
-0, 38400, 194400, 0x3dcafdb7
-0, 38700, 194400, 0x3dcafdb7
-0, 39000, 194400, 0x6f1f01c2
-0, 39300, 194400, 0xf54a1da6
-0, 39600, 194400, 0xf54a1da6
-0, 39900, 194400, 0x88d11fa4
-0, 40200, 194400, 0x59642d96
-0, 40500, 194400, 0x59642d96
-0, 40800, 194400, 0x8ba44182
-0, 41100, 194400, 0x88f56360
-0, 41400, 194400, 0x88f56360
-0, 41700, 194400, 0xfb246d56
-0, 42000, 194400, 0xad128043
-0, 42300, 194400, 0xad128043
-0, 42600, 194400, 0x3a4f8a39
-0, 42900, 194400, 0x563d9d26
-0, 43200, 194400, 0x563d9d26
-0, 43500, 194400, 0x6ff8a320
-0, 43800, 194400, 0xcdb9b70c
-0, 44100, 194400, 0xcdb9b70c
-0, 44400, 194400, 0x99c2bd06
-0, 44700, 194400, 0x4b47cef4
-0, 45000, 194400, 0x4b47cef4
-0, 45300, 194400, 0x10b9dce6
-0, 45600, 194400, 0xdd39f1d1
-0, 45900, 194400, 0xdd39f1d1
-0, 46200, 194400, 0xbcf104cd
-0, 46500, 194400, 0x85ec17ba
-0, 46800, 194400, 0x85ec17ba
-0, 47100, 194400, 0x069219b8
-0, 47400, 194400, 0x84dd3899
-0, 47700, 194400, 0x84dd3899
-0, 48000, 194400, 0xacca4190
-0, 48300, 194400, 0xcf5b5d74
-0, 48600, 194400, 0xcf5b5d74
-0, 48900, 194400, 0x4b8c626f
-0, 49200, 194400, 0xf0817958
-0, 49500, 194400, 0xf0817958
-0, 49800, 194400, 0xc0887e53
-0, 50100, 194400, 0x42e6854c
-0, 50400, 194400, 0x42e6854c
-0, 50700, 194400, 0x036c9140
-0, 51000, 194400, 0x0f21a62b
-0, 51300, 194400, 0x0f21a62b
-0, 51600, 194400, 0xcdaeaa27
-0, 51900, 194400, 0xe425bc15
-0, 52200, 194400, 0xe425bc15
-0, 52500, 194400, 0x8e18c20f
-0, 52800, 194400, 0x767cd5fb
-0, 53100, 194400, 0x767cd5fb
-0, 53400, 194400, 0x554ae6ea
-0, 53700, 194400, 0xeac1f9d7
-0, 54000, 194400, 0xeac1f9d7
-0, 54300, 194400, 0x0b32fed2
-0, 54600, 194400, 0xe30c19c6
-0, 54900, 194400, 0xe30c19c6
-0, 55200, 194400, 0x6a8a23bc
-0, 55500, 194400, 0x26bf36a9
-0, 55800, 194400, 0x26bf36a9
-0, 56100, 194400, 0x1e4f3fa0
-0, 56400, 194400, 0x231f5986
-0, 56700, 194400, 0x231f5986
-0, 57000, 194400, 0xf557756a
-0, 57300, 194400, 0x6bce805f
-0, 57600, 194400, 0x6bce805f
-0, 57900, 194400, 0xcd80924d
-0, 58200, 194400, 0x65dc9f40
-0, 58500, 194400, 0x65dc9f40
-0, 58800, 194400, 0x2ab7af30
-0, 59100, 194400, 0xd43cb728
-0, 59400, 194400, 0xd43cb728
-0, 59700, 194400, 0x05d9c916
-0, 60000, 194400, 0x43cad10e
-0, 60300, 194400, 0x43cad10e
-0, 60600, 194400, 0x06b5e0fe
-0, 60900, 194400, 0xa142f0ee
-0, 61200, 194400, 0xa142f0ee
-0, 61500, 194400, 0xed7f03ea
-0, 61800, 194400, 0xf26019d4
-0, 62100, 194400, 0xf26019d4
-0, 62400, 194400, 0x3b7f29c4
-0, 62700, 194400, 0x30282ebf
-0, 63000, 194400, 0x30282ebf
-0, 63300, 194400, 0xaeff4aa3
-0, 63600, 194400, 0x1d355697
-0, 63900, 194400, 0x1d355697
-0, 64200, 194400, 0x2ead6f7e
-0, 64500, 194400, 0xf1b67776
-0, 64800, 194400, 0xf1b67776
-0, 65100, 194400, 0x93b38b62
-0, 65400, 194400, 0x9469905d
-0, 65700, 194400, 0x9469905d
-0, 66000, 194400, 0x27bf9756
-0, 66300, 194400, 0xd016a548
-0, 66600, 194400, 0xd016a548
-0, 66900, 194400, 0x6889b835
-0, 67200, 194400, 0x6a05be2f
-0, 67500, 194400, 0x6a05be2f
-0, 67800, 194400, 0xe0a1ce1f
-0, 68100, 194400, 0x8fdbd617
-0, 68400, 194400, 0x8fdbd617
-0, 68700, 194400, 0xd68fe805
-0, 69000, 194400, 0x0d1dfbf1
-0, 69300, 194400, 0x0d1dfbf1
-0, 69600, 194400, 0x0fe70bf0
-0, 69900, 194400, 0x0a8f13e8
-0, 70200, 194400, 0x0a8f13e8
-0, 70500, 194400, 0x0ca42bd0
-0, 70800, 194400, 0x6f3838c3
-0, 71100, 194400, 0x6f3838c3
-0, 71400, 194400, 0x045448b3
-0, 71700, 194400, 0x764349b2
-0, 72000, 194400, 0x764349b2
-0, 72300, 194400, 0xed1651aa
-0, 72600, 194400, 0xbb376398
-0, 72900, 194400, 0xbb376398
-0, 73200, 194400, 0xd0d5718a
-0, 73500, 194400, 0xcd977e7d
-0, 73800, 194400, 0xcd977e7d
-0, 74100, 194400, 0x8cb39665
-0, 74400, 194400, 0xb935b04b
-0, 74700, 194400, 0xb935b04b
-0, 75000, 194400, 0x0292be3d
-0, 75300, 194400, 0x4f21c833
-0, 75600, 194400, 0x4f21c833
-0, 75900, 194400, 0xa5c7d823
-0, 76200, 194400, 0xfb8ee01b
-0, 76500, 194400, 0xfb8ee01b
-0, 76800, 194400, 0xea53ee0d
-0, 77100, 194400, 0x803efcfe
-0, 77400, 194400, 0x803efcfe
-0, 77700, 194400, 0x2c0e0aff
-0, 78000, 194400, 0x3df318f1
-0, 78300, 194400, 0x3df318f1
-0, 78600, 194400, 0xc4cb26e3
-0, 78900, 194400, 0x92a033d6
-0, 79200, 194400, 0x92a033d6
-0, 79500, 194400, 0x1b2048c1
-0, 79800, 194400, 0x236858b1
-0, 80100, 194400, 0x236858b1
-0, 80400, 194400, 0x482f6d9c
-0, 80700, 194400, 0x9ee97891
-0, 81000, 194400, 0x9ee97891
-0, 81300, 194400, 0xe0dc8683
-0, 81600, 194400, 0x461b9079
-0, 81900, 194400, 0x461b9079
-0, 82200, 194400, 0xd346a960
-0, 82500, 194400, 0xa384b554
-0, 82800, 194400, 0xa384b554
-0, 83100, 194400, 0x3246cf3a
-0, 83400, 194400, 0xa53fe722
-0, 83700, 194400, 0xa53fe722
-0, 84000, 194400, 0xe620fd0c
-0, 84300, 194400, 0xd6370414
-0, 84600, 194400, 0xd6370414
-0, 84900, 194400, 0xf57f1404
-0, 85200, 194400, 0x8c6420f7
-0, 85500, 194400, 0x8c6420f7
-0, 85800, 194400, 0xd4be3add
-0, 86100, 194400, 0xa8dc4ec9
-0, 86400, 194400, 0xa8dc4ec9
-0, 86700, 194400, 0xda1563b4
-0, 87000, 194400, 0xd51873a4
-0, 87300, 194400, 0xd51873a4
-0, 87600, 194400, 0x68588196
-0, 87900, 194400, 0x40d18e89
-0, 88200, 194400, 0x40d18e89
-0, 88500, 194400, 0x1b75a275
-0, 88800, 194400, 0xedd1a572
-0, 89100, 194400, 0xedd1a572
-0, 89400, 194400, 0x55daad6a
+0, 11700, 194400, 0x2dd54447
+0, 12000, 194400, 0x90735e2d
+0, 12300, 194400, 0x90d98506
+0, 12600, 194400, 0xe5b08ffb
+0, 12900, 194400, 0x7a0d95f5
+0, 13200, 194400, 0xff6bacde
+0, 13500, 194400, 0xd998c2c8
+0, 13800, 194400, 0x3d1ddfab
+0, 14100, 194400, 0x817de4a6
+0, 14400, 194400, 0xfa3ef694
+0, 14700, 194400, 0x0b5bfb8f
+0, 15000, 194400, 0x00f62376
+0, 15300, 194400, 0x2f6b2d6c
+0, 15600, 194400, 0x40cb4752
+0, 15900, 194400, 0xd8456435
+0, 16200, 194400, 0x459f6a2f
+0, 16500, 194400, 0x9b678910
+0, 16800, 194400, 0x8791a1f7
+0, 17100, 194400, 0xdb4ac5d3
+0, 17400, 194400, 0xb223c8d0
+0, 17700, 194400, 0x4a9ce7b1
+0, 18000, 194400, 0x187eeaae
+0, 18300, 194400, 0xc712f8a0
+0, 18600, 194400, 0x549c00a7
+0, 18900, 194400, 0x4d991295
+0, 19200, 194400, 0xc41b2681
+0, 19500, 194400, 0xed5a3077
+0, 19800, 194400, 0x85ad4463
+0, 20100, 194400, 0xb98f4760
+0, 20400, 194400, 0x87ef5e49
+0, 20700, 194400, 0x830a6146
+0, 21000, 194400, 0xe33a792e
+0, 21300, 194400, 0x83517a2d
+0, 21600, 194400, 0xa97e9314
+0, 21900, 194400, 0x39059611
+0, 22200, 194400, 0xbf4eb9ed
+0, 22500, 194400, 0xe5afc4e2
+0, 22800, 194400, 0x35d4cdd9
+0, 23100, 194400, 0xb376e1c5
+0, 23400, 194400, 0x6128e3c3
+0, 23700, 194400, 0x30b7f7af
+0, 24000, 194400, 0xf1effaac
+0, 24300, 194400, 0x483914a1
+0, 24600, 194400, 0xbd48199c
+0, 24900, 194400, 0x382f2d88
+0, 25200, 194400, 0x5a573085
+0, 25500, 194400, 0x89733580
+0, 25800, 194400, 0xd1325a5b
+0, 26100, 194400, 0x655b6253
+0, 26400, 194400, 0x55146352
+0, 26700, 194400, 0xda527c39
+0, 27000, 194400, 0xb0cd7e37
+0, 27300, 194400, 0x25e7991c
+0, 27600, 194400, 0x5c22a411
+0, 27900, 194400, 0x1e2abdf7
+0, 28200, 194400, 0x8308bff5
+0, 28500, 194400, 0xfdbfd6de
+0, 28800, 194400, 0xd4d4d9db
+0, 29100, 194400, 0xa449fbb9
+0, 29400, 194400, 0x3dcafdb7
+0, 29700, 194400, 0x6f1f01c2
+0, 30000, 194400, 0xf54a1da6
+0, 30300, 194400, 0x88d11fa4
+0, 30600, 194400, 0x59642d96
+0, 30900, 194400, 0x8ba44182
+0, 31200, 194400, 0x88f56360
+0, 31500, 194400, 0xfb246d56
+0, 31800, 194400, 0xad128043
+0, 32100, 194400, 0x3a4f8a39
+0, 32400, 194400, 0x563d9d26
+0, 32700, 194400, 0x6ff8a320
+0, 33000, 194400, 0xcdb9b70c
+0, 33300, 194400, 0x99c2bd06
+0, 33600, 194400, 0x4b47cef4
+0, 33900, 194400, 0x10b9dce6
+0, 34200, 194400, 0xdd39f1d1
+0, 34500, 194400, 0xbcf104cd
+0, 34800, 194400, 0x85ec17ba
+0, 35100, 194400, 0x069219b8
+0, 35400, 194400, 0x84dd3899
+0, 35700, 194400, 0xacca4190
+0, 36000, 194400, 0xcf5b5d74
+0, 36300, 194400, 0x4b8c626f
+0, 36600, 194400, 0xf0817958
+0, 36900, 194400, 0xc0887e53
+0, 37200, 194400, 0x42e6854c
+0, 37500, 194400, 0x036c9140
+0, 37800, 194400, 0x0f21a62b
+0, 38100, 194400, 0xcdaeaa27
+0, 38400, 194400, 0xe425bc15
+0, 38700, 194400, 0x8e18c20f
+0, 39000, 194400, 0x767cd5fb
+0, 39300, 194400, 0x554ae6ea
+0, 39600, 194400, 0xeac1f9d7
+0, 39900, 194400, 0x0b32fed2
+0, 40200, 194400, 0xe30c19c6
+0, 40500, 194400, 0x6a8a23bc
+0, 40800, 194400, 0x26bf36a9
+0, 41100, 194400, 0x1e4f3fa0
+0, 41400, 194400, 0x231f5986
+0, 41700, 194400, 0xf557756a
+0, 42000, 194400, 0x6bce805f
+0, 42300, 194400, 0xcd80924d
+0, 42600, 194400, 0x65dc9f40
+0, 42900, 194400, 0x2ab7af30
+0, 43200, 194400, 0xd43cb728
+0, 43500, 194400, 0x05d9c916
+0, 43800, 194400, 0x43cad10e
+0, 44100, 194400, 0x06b5e0fe
+0, 44400, 194400, 0xa142f0ee
+0, 44700, 194400, 0xed7f03ea
+0, 45000, 194400, 0xf26019d4
+0, 45300, 194400, 0x3b7f29c4
+0, 45600, 194400, 0x30282ebf
+0, 45900, 194400, 0xaeff4aa3
+0, 46200, 194400, 0x1d355697
+0, 46500, 194400, 0x2ead6f7e
+0, 46800, 194400, 0xf1b67776
+0, 47100, 194400, 0x93b38b62
+0, 47400, 194400, 0x9469905d
+0, 47700, 194400, 0x27bf9756
+0, 48000, 194400, 0xd016a548
+0, 48300, 194400, 0x6889b835
+0, 48600, 194400, 0x6a05be2f
+0, 48900, 194400, 0xe0a1ce1f
+0, 49200, 194400, 0x8fdbd617
+0, 49500, 194400, 0xd68fe805
+0, 49800, 194400, 0x0d1dfbf1
+0, 50100, 194400, 0x0fe70bf0
+0, 50400, 194400, 0x0a8f13e8
+0, 50700, 194400, 0x0ca42bd0
+0, 51000, 194400, 0x6f3838c3
+0, 51300, 194400, 0x045448b3
+0, 51600, 194400, 0x764349b2
+0, 51900, 194400, 0xed1651aa
+0, 52200, 194400, 0xbb376398
+0, 52500, 194400, 0xd0d5718a
+0, 52800, 194400, 0xcd977e7d
+0, 53100, 194400, 0x8cb39665
+0, 53400, 194400, 0xb935b04b
+0, 53700, 194400, 0x0292be3d
+0, 54000, 194400, 0x4f21c833
+0, 54300, 194400, 0xa5c7d823
+0, 54600, 194400, 0xfb8ee01b
+0, 54900, 194400, 0xea53ee0d
+0, 55200, 194400, 0x803efcfe
+0, 55500, 194400, 0x2c0e0aff
+0, 55800, 194400, 0x3df318f1
+0, 56100, 194400, 0xc4cb26e3
+0, 56400, 194400, 0x92a033d6
+0, 56700, 194400, 0x1b2048c1
+0, 57000, 194400, 0x236858b1
+0, 57300, 194400, 0x482f6d9c
+0, 57600, 194400, 0x9ee97891
+0, 57900, 194400, 0xe0dc8683
+0, 58200, 194400, 0x461b9079
+0, 58500, 194400, 0xd346a960
+0, 58800, 194400, 0xa384b554
+0, 59100, 194400, 0x3246cf3a
+0, 59400, 194400, 0xa53fe722
+0, 59700, 194400, 0xe620fd0c
+0, 60000, 194400, 0xd6370414
+0, 60300, 194400, 0xf57f1404
+0, 60600, 194400, 0x8c6420f7
+0, 60900, 194400, 0xd4be3add
+0, 61200, 194400, 0xa8dc4ec9
+0, 61500, 194400, 0xda1563b4
+0, 61800, 194400, 0xd51873a4
+0, 62100, 194400, 0x68588196
+0, 62400, 194400, 0x40d18e89
+0, 62700, 194400, 0x1b75a275
+0, 63000, 194400, 0xedd1a572
+0, 63300, 194400, 0x55daad6a
+0, 63600, 194400, 0xcb93b067
+0, 63900, 194400, 0x5888ba5d
+0, 64200, 194400, 0x2c11c84f
+0, 64500, 194400, 0x0fbae334
+0, 64800, 194400, 0x773fed2a
+0, 65100, 194400, 0x2f87fc1b
+0, 65400, 194400, 0xe8120521
+0, 65700, 194400, 0x64ac0f17
+0, 66000, 194400, 0xba531c0a
+0, 66300, 194400, 0xf49433f2
+0, 66600, 194400, 0x79e234f1
+0, 66900, 194400, 0x043937ee
+0, 67200, 194400, 0x9e6141e4
+0, 67500, 194400, 0x34204fd6
+0, 67800, 194400, 0xa1dd60c5
+0, 68100, 194400, 0x12b36eb7
+0, 68400, 194400, 0x68987aab
+0, 68700, 194400, 0x3207889d
+0, 69000, 194400, 0x3bb59194
+0, 69300, 194400, 0x0a119f86
+0, 69600, 194400, 0x472bab7a
+0, 69900, 194400, 0x7364c85d
+0, 70200, 194400, 0xa812d84d
+0, 70500, 194400, 0xf384f530
+0, 70800, 194400, 0x1546052f
+0, 71100, 194400, 0xeb611a1a
+0, 71400, 194400, 0xc39d250f
+0, 71700, 194400, 0x7bd73301
+0, 72000, 194400, 0x10f73cf7
+0, 72300, 194400, 0x95dc55de
+0, 72600, 194400, 0x392e61d2
+0, 72900, 194400, 0x113c7bb8
+0, 73200, 194400, 0x17128fa4
+0, 73500, 194400, 0xf95e9b98
+0, 73800, 194400, 0xdc47aa89
+0, 74100, 194400, 0xea5dc073
+0, 74400, 194400, 0x8dfadc57
+0, 74700, 194400, 0xe5c3e84b
+0, 75000, 194400, 0x8952f43f
+0, 75300, 194400, 0xec9e0240
+0, 75600, 194400, 0x8f460c36
+0, 75900, 194400, 0xd43e182a
+0, 76200, 194400, 0xb00b2919
+0, 76500, 194400, 0xc9f6350d
+0, 76800, 194400, 0x87ca44fd
+0, 77100, 194400, 0xa6a250f1
+0, 77400, 194400, 0x34fa60e1
+0, 77700, 194400, 0xe1a372cf
+0, 78000, 194400, 0xc80785bc
+0, 78300, 194400, 0x43e297aa
+0, 78600, 194400, 0x7e8ea49d
+0, 78900, 194400, 0xd009b091
+0, 79200, 194400, 0x9126bc85
+0, 79500, 194400, 0x175ad36e
+0, 79800, 194400, 0xf9dae160
+0, 80100, 194400, 0x1b98f948
+0, 80400, 194400, 0xa6c5133d
+0, 80700, 194400, 0xf5d42729
+0, 81000, 194400, 0x8cfe311f
+0, 81300, 194400, 0x18733e12
+0, 81600, 194400, 0x24ac50ff
+0, 81900, 194400, 0x0d1c64eb
+0, 82200, 194400, 0xde947cd3
+0, 82500, 194400, 0x08268dc2
+0, 82800, 194400, 0xfec69fb0
+0, 83100, 194400, 0xba83aba4
+0, 83400, 194400, 0xfbe2bc93
+0, 83700, 194400, 0xe22fcc83
+0, 84000, 194400, 0x050fcf80
+0, 84300, 194400, 0xee1ed778
+0, 84600, 194400, 0xb44cda75
+0, 84900, 194400, 0xa29fe46b
+0, 85200, 194400, 0xa99bf55a
+0, 85500, 194400, 0x4f840d51
+0, 85800, 194400, 0x58941945
+0, 86100, 194400, 0x62cb2638
+0, 86400, 194400, 0x22ee312d
+0, 86700, 194400, 0xea8f3925
+0, 87000, 194400, 0xed294c12
+0, 87300, 194400, 0xafa75e00
+0, 87600, 194400, 0x19d45ffe
+0, 87900, 194400, 0x7fcf61fc
+0, 88200, 194400, 0x2c126df0
+0, 88500, 194400, 0x331379e4
+0, 88800, 194400, 0x99fe8cd1
+0, 89100, 194400, 0xa5ec98c5
+0, 89400, 194400, 0xac68a6b7
+0, 89700, 194400, 0x28e6b2ab
diff --git a/tests/ref/fate/crc b/tests/ref/fate/crc
new file mode 100644
index 0000000..4a82680
--- /dev/null
+++ b/tests/ref/fate/crc
@@ -0,0 +1,4 @@
+crc EDB88320 =3D5CDD04
+crc 04C11DB7 =E0BAF5C0
+crc 00008005 =BB1F
+crc 00000007 =E3
diff --git a/tests/ref/fate/deluxepaint-anm b/tests/ref/fate/deluxepaint-anm
index 2a60606..98da928 100644
--- a/tests/ref/fate/deluxepaint-anm
+++ b/tests/ref/fate/deluxepaint-anm
@@ -69,87 +69,55 @@
0, 204000, 192000, 0xdd7f371d
0, 207000, 192000, 0xeed134c6
0, 210000, 192000, 0x362931f5
-0, 213000, 192000, 0x362931f5
-0, 216000, 192000, 0x362931f5
-0, 219000, 192000, 0x362931f5
-0, 222000, 192000, 0x362931f5
-0, 225000, 192000, 0x362931f5
-0, 228000, 192000, 0x362931f5
-0, 231000, 192000, 0x362931f5
-0, 234000, 192000, 0x362931f5
-0, 237000, 192000, 0x362931f5
-0, 240000, 192000, 0x362931f5
-0, 243000, 192000, 0x362931f5
-0, 246000, 192000, 0x362931f5
-0, 249000, 192000, 0x362931f5
-0, 252000, 192000, 0x362931f5
-0, 255000, 192000, 0x362931f5
-0, 258000, 192000, 0x362931f5
-0, 261000, 192000, 0x362931f5
-0, 264000, 192000, 0x362931f5
-0, 267000, 192000, 0x362931f5
-0, 270000, 192000, 0x362931f5
-0, 273000, 192000, 0x362931f5
-0, 276000, 192000, 0x362931f5
-0, 279000, 192000, 0x362931f5
-0, 282000, 192000, 0x362931f5
-0, 285000, 192000, 0x362931f5
-0, 288000, 192000, 0x362931f5
-0, 291000, 192000, 0x362931f5
-0, 294000, 192000, 0x362931f5
-0, 297000, 192000, 0x362931f5
-0, 300000, 192000, 0x362931f5
-0, 303000, 192000, 0x362931f5
-0, 306000, 192000, 0x362931f5
-0, 309000, 192000, 0xfb41331d
-0, 312000, 192000, 0x087433f8
-0, 315000, 192000, 0xf36b34a6
-0, 318000, 192000, 0x652a33cd
-0, 321000, 192000, 0x652a33cd
-0, 324000, 192000, 0xe50c336a
-0, 327000, 192000, 0x652a33cd
-0, 330000, 192000, 0xeed134c6
-0, 333000, 192000, 0x652a33cd
-0, 336000, 192000, 0x5d7633e5
-0, 339000, 192000, 0x845233b5
-0, 342000, 192000, 0x9d1c349b
-0, 345000, 192000, 0x25843317
-0, 348000, 192000, 0xc84b375c
-0, 351000, 192000, 0xaf2b3410
-0, 354000, 192000, 0xaf2b3410
-0, 357000, 192000, 0x26d23594
-0, 360000, 192000, 0xaf2b3410
-0, 363000, 192000, 0x26d23594
-0, 366000, 192000, 0xaf2b3410
-0, 369000, 192000, 0x72c4dfb9
-0, 372000, 192000, 0x3c72e390
-0, 375000, 192000, 0xb4466634
-0, 378000, 192000, 0x84f064f5
-0, 381000, 192000, 0xad43f3f5
-0, 384000, 192000, 0xa8644d57
-0, 387000, 192000, 0xfac35238
-0, 390000, 192000, 0xe9374d1e
-0, 393000, 192000, 0x0bd14cfa
-0, 396000, 192000, 0x7e51a437
-0, 399000, 192000, 0x92678dfa
-0, 402000, 192000, 0x43338d41
-0, 405000, 192000, 0x00000000
-0, 408000, 192000, 0x00000000
-0, 411000, 192000, 0x00000000
-0, 414000, 192000, 0x00000000
-0, 417000, 192000, 0x00000000
-0, 420000, 192000, 0x00000000
-0, 423000, 192000, 0x00000000
-0, 426000, 192000, 0x00000000
-0, 429000, 192000, 0x00000000
-0, 432000, 192000, 0x00000000
-0, 435000, 192000, 0x00000000
-0, 438000, 192000, 0x00000000
-0, 441000, 192000, 0x00000000
-0, 444000, 192000, 0x00000000
-0, 447000, 192000, 0x00000000
-0, 450000, 192000, 0x00000000
-0, 453000, 192000, 0x00000000
-0, 456000, 192000, 0x00000000
-0, 459000, 192000, 0x00000000
-0, 462000, 192000, 0x82a79641
+0, 213000, 192000, 0xfb41331d
+0, 216000, 192000, 0x087433f8
+0, 219000, 192000, 0xf36b34a6
+0, 222000, 192000, 0x652a33cd
+0, 225000, 192000, 0x652a33cd
+0, 228000, 192000, 0xe50c336a
+0, 231000, 192000, 0x652a33cd
+0, 234000, 192000, 0xeed134c6
+0, 237000, 192000, 0x652a33cd
+0, 240000, 192000, 0x5d7633e5
+0, 243000, 192000, 0x845233b5
+0, 246000, 192000, 0x9d1c349b
+0, 249000, 192000, 0x25843317
+0, 252000, 192000, 0xc84b375c
+0, 255000, 192000, 0xaf2b3410
+0, 258000, 192000, 0xaf2b3410
+0, 261000, 192000, 0x26d23594
+0, 264000, 192000, 0xaf2b3410
+0, 267000, 192000, 0x26d23594
+0, 270000, 192000, 0xaf2b3410
+0, 273000, 192000, 0x72c4dfb9
+0, 276000, 192000, 0x3c72e390
+0, 279000, 192000, 0xb4466634
+0, 282000, 192000, 0x84f064f5
+0, 285000, 192000, 0xad43f3f5
+0, 288000, 192000, 0xa8644d57
+0, 291000, 192000, 0xfac35238
+0, 294000, 192000, 0xe9374d1e
+0, 297000, 192000, 0x0bd14cfa
+0, 300000, 192000, 0x7e51a437
+0, 303000, 192000, 0x92678dfa
+0, 306000, 192000, 0x43338d41
+0, 309000, 192000, 0x00000000
+0, 312000, 192000, 0x00000000
+0, 315000, 192000, 0x00000000
+0, 318000, 192000, 0x00000000
+0, 321000, 192000, 0x00000000
+0, 324000, 192000, 0x00000000
+0, 327000, 192000, 0x00000000
+0, 330000, 192000, 0x00000000
+0, 333000, 192000, 0x00000000
+0, 336000, 192000, 0x00000000
+0, 339000, 192000, 0x00000000
+0, 342000, 192000, 0x00000000
+0, 345000, 192000, 0x00000000
+0, 348000, 192000, 0x00000000
+0, 351000, 192000, 0x00000000
+0, 354000, 192000, 0x00000000
+0, 357000, 192000, 0x00000000
+0, 360000, 192000, 0x00000000
+0, 363000, 192000, 0x00000000
+0, 366000, 192000, 0x82a79641
diff --git a/tests/ref/fate/xan-dpcm b/tests/ref/fate/dpcm-xan
similarity index 100%
rename from tests/ref/fate/xan-dpcm
rename to tests/ref/fate/dpcm-xan
diff --git a/tests/ref/fate/duck-dk3 b/tests/ref/fate/duck-dk3
index 08c0fd1..9aad92b 100644
--- a/tests/ref/fate/duck-dk3
+++ b/tests/ref/fate/duck-dk3
@@ -1 +1 @@
-62fbe4db4a49cb044f57f92cce9993c5
+bb952ae86c72d461aef7583685ec0a4d
diff --git a/tests/ref/fate/ea-tqi-adpcm b/tests/ref/fate/ea-tqi-adpcm
index c79eed5..4fbc117 100644
--- a/tests/ref/fate/ea-tqi-adpcm
+++ b/tests/ref/fate/ea-tqi-adpcm
@@ -49,4 +49,3 @@
0, 144000, 115200, 0x65fd5e60
1, 144000, 5936, 0x2174304d
0, 150000, 115200, 0x0c256424
-0, 156000, 115200, 0xa9cdd8d2
diff --git a/tests/ref/fate/eval b/tests/ref/fate/eval
new file mode 100644
index 0000000..ef50292
--- /dev/null
+++ b/tests/ref/fate/eval
@@ -0,0 +1,152 @@
+Evaluating ''
+'' -> nan
+
+Evaluating '1;2'
+'1;2' -> 2.000000
+
+Evaluating '-20'
+'-20' -> -20.000000
+
+Evaluating '-PI'
+'-PI' -> -3.141593
+
+Evaluating '+PI'
+'+PI' -> 3.141593
+
+Evaluating '1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)'
+'1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)' -> 12.700000
+
+Evaluating '80G/80Gi'
+'80G/80Gi' -> 0.931323
+
+Evaluating '1k'
+'1k' -> 1000.000000
+
+Evaluating '1Gi'
+'1Gi' -> 1073741824.000000
+
+Evaluating '1gi'
+'1gi' -> nan
+
+Evaluating '1GiFoo'
+'1GiFoo' -> nan
+
+Evaluating '1k+1k'
+'1k+1k' -> 2000.000000
+
+Evaluating '1Gi*3foo'
+'1Gi*3foo' -> nan
+
+Evaluating 'foo'
+'foo' -> nan
+
+Evaluating 'foo('
+'foo(' -> nan
+
+Evaluating 'foo()'
+'foo()' -> nan
+
+Evaluating 'foo)'
+'foo)' -> nan
+
+Evaluating 'sin'
+'sin' -> nan
+
+Evaluating 'sin('
+'sin(' -> nan
+
+Evaluating 'sin()'
+'sin()' -> nan
+
+Evaluating 'sin)'
+'sin)' -> nan
+
+Evaluating 'sin 10'
+'sin 10' -> nan
+
+Evaluating 'sin(1,2,3)'
+'sin(1,2,3)' -> nan
+
+Evaluating 'sin(1 )'
+'sin(1 )' -> 0.841471
+
+Evaluating '1'
+'1' -> 1.000000
+
+Evaluating '1foo'
+'1foo' -> nan
+
+Evaluating 'bar + PI + E + 100f*2 + foo'
+'bar + PI + E + 100f*2 + foo' -> nan
+
+Evaluating '13k + 12f - foo(1, 2)'
+'13k + 12f - foo(1, 2)' -> nan
+
+Evaluating '1gi'
+'1gi' -> nan
+
+Evaluating '1Gi'
+'1Gi' -> 1073741824.000000
+
+Evaluating 'st(0, 123)'
+'st(0, 123)' -> 123.000000
+
+Evaluating 'st(1, 123); ld(1)'
+'st(1, 123); ld(1)' -> 123.000000
+
+Evaluating 'st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)'
+'st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)' -> 4950.000000
+
+Evaluating 'st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)'
+'st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)' -> 144.000000
+
+Evaluating 'while(0, 10)'
+'while(0, 10)' -> nan
+
+Evaluating 'st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))'
+'st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))' -> 100.000000
+
+Evaluating 'isnan(1)'
+'isnan(1)' -> 0.000000
+
+Evaluating 'isnan(NAN)'
+'isnan(NAN)' -> 1.000000
+
+Evaluating 'floor(NAN)'
+'floor(NAN)' -> nan
+
+Evaluating 'floor(123.123)'
+'floor(123.123)' -> 123.000000
+
+Evaluating 'floor(-123.123)'
+'floor(-123.123)' -> -124.000000
+
+Evaluating 'trunc(123.123)'
+'trunc(123.123)' -> 123.000000
+
+Evaluating 'trunc(-123.123)'
+'trunc(-123.123)' -> -123.000000
+
+Evaluating 'ceil(123.123)'
+'ceil(123.123)' -> 124.000000
+
+Evaluating 'ceil(-123.123)'
+'ceil(-123.123)' -> -123.000000
+
+Evaluating 'sqrt(1764)'
+'sqrt(1764)' -> 42.000000
+
+Evaluating 'isnan(sqrt(-1))'
+'isnan(sqrt(-1))' -> 1.000000
+
+Evaluating 'not(1)'
+'not(1)' -> 0.000000
+
+Evaluating 'not(NAN)'
+'not(NAN)' -> 0.000000
+
+Evaluating 'not(0)'
+'not(0)' -> 1.000000
+
+12.700000 == 12.7
+0.931323 == 0.931322575
diff --git a/tests/ref/fate/feeble-dxa b/tests/ref/fate/feeble-dxa
index 9013f99..caea4c2 100644
--- a/tests/ref/fate/feeble-dxa
+++ b/tests/ref/fate/feeble-dxa
@@ -62,4 +62,3 @@
0, 171000, 921600, 0x5639e670
1, 171429, 1000, 0xa491f3ef
1, 175510, 1000, 0x2c036e18
-1, 179592, 1000, 0x52d65e2a
diff --git a/tests/ref/fate/fifo b/tests/ref/fate/fifo
new file mode 100644
index 0000000..18a5691
--- /dev/null
+++ b/tests/ref/fate/fifo
@@ -0,0 +1,27 @@
+-12: 1
+-11: 2
+-10: 3
+-9: 4
+-8: 5
+-7: 6
+-6: 7
+-5: 8
+-4: 9
+-3: 10
+-2: 11
+-1: 12
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+10: 10
+11: 11
+12: 12
+
+0 1 2 3 4 5 6 7 8 9 10 11 12
diff --git a/tests/ref/fate/film-cvid-pcm-stereo-8bit b/tests/ref/fate/film-cvid-pcm-stereo-8bit
index 3566b0f..4f3fcf4 100644
--- a/tests/ref/fate/film-cvid-pcm-stereo-8bit
+++ b/tests/ref/fate/film-cvid-pcm-stereo-8bit
@@ -2,246 +2,138 @@
1, 0, 88192, 0x23bb50ae
0, 3000, 107520, 0x61eb28c1
0, 6000, 107520, 0x45e20af7
-0, 9000, 107520, 0x45e20af7
-0, 12000, 107520, 0x366970fc
-0, 15000, 107520, 0x366970fc
-0, 18000, 107520, 0xa392bcb3
-0, 21000, 107520, 0xa392bcb3
-0, 24000, 107520, 0xcf7bac98
-0, 27000, 107520, 0xcf7bac98
-0, 30000, 107520, 0x222eba53
-0, 33000, 107520, 0x222eba53
-0, 36000, 107520, 0x74e255a1
-0, 39000, 107520, 0x74e255a1
-0, 42000, 107520, 0xc19eec6f
+0, 9000, 107520, 0x366970fc
+0, 12000, 107520, 0xa392bcb3
+0, 15000, 107520, 0xcf7bac98
+0, 18000, 107520, 0x222eba53
+0, 21000, 107520, 0x74e255a1
+0, 24000, 107520, 0xc19eec6f
+0, 27000, 107520, 0xa3880681
+0, 30000, 107520, 0x957878db
+0, 33000, 107520, 0x18340692
+0, 36000, 107520, 0x9970f24d
+0, 39000, 107520, 0xf08618aa
+0, 42000, 107520, 0xee7324f0
1, 44996, 44112, 0x79600f01
-0, 45000, 107520, 0xc19eec6f
-0, 48000, 107520, 0xa3880681
-0, 51000, 107520, 0xa3880681
-0, 54000, 107520, 0x957878db
-0, 57000, 107520, 0x957878db
-0, 60000, 107520, 0x18340692
-0, 63000, 107520, 0x18340692
-0, 66000, 107520, 0x9970f24d
+0, 45000, 107520, 0xe15025b3
+0, 48000, 107520, 0x8afa312e
+0, 51000, 107520, 0x717a7d0f
+0, 54000, 107520, 0x355c6e23
+0, 57000, 107520, 0x7015a50f
+0, 60000, 107520, 0xcdfc1a16
+0, 63000, 107520, 0x38d929e7
+0, 66000, 107520, 0x52913423
1, 67502, 44096, 0x09dbf7aa
-0, 69000, 107520, 0x9970f24d
-0, 72000, 107520, 0xf08618aa
-0, 75000, 107520, 0xf08618aa
-0, 78000, 107520, 0xee7324f0
-0, 81000, 107520, 0xee7324f0
-0, 84000, 107520, 0xe15025b3
-0, 87000, 107520, 0xe15025b3
-0, 90000, 107520, 0x8afa312e
+0, 69000, 107520, 0xe2c91c10
+0, 72000, 107520, 0x85516e9c
+0, 75000, 107520, 0xd1626030
+0, 78000, 107520, 0xea7b16de
+0, 81000, 107520, 0xa33eaa0d
+0, 84000, 107520, 0x8e3be6a6
+0, 87000, 107520, 0x14147bd6
+0, 90000, 107520, 0x07d54bec
1, 90000, 44112, 0x18fed048
-0, 93000, 107520, 0x8afa312e
-0, 96000, 107520, 0x717a7d0f
-0, 99000, 107520, 0x717a7d0f
-0, 102000, 107520, 0x355c6e23
-0, 105000, 107520, 0x355c6e23
-0, 108000, 107520, 0x7015a50f
-0, 111000, 107520, 0x7015a50f
+0, 93000, 107520, 0xe287a0a7
+0, 96000, 107520, 0xc023a14d
+0, 99000, 107520, 0x2437085d
+0, 102000, 107520, 0x63823918
+0, 105000, 107520, 0xbc17e198
+0, 108000, 107520, 0x9d99bc81
+0, 111000, 107520, 0x7e4ec71e
1, 112506, 44112, 0x030d35ef
-0, 114000, 107520, 0xcdfc1a16
-0, 117000, 107520, 0xcdfc1a16
-0, 120000, 107520, 0x38d929e7
-0, 123000, 107520, 0x38d929e7
-0, 126000, 107520, 0x52913423
-0, 129000, 107520, 0x52913423
-0, 132000, 107520, 0xe2c91c10
-0, 135000, 107520, 0xe2c91c10
+0, 114000, 107520, 0x55b98376
+0, 117000, 107520, 0x356d8e9e
+0, 120000, 107520, 0xf77e8a61
+0, 123000, 107520, 0x5ae7c8c7
+0, 126000, 107520, 0x8acf9322
+0, 129000, 107520, 0x40a9177e
+0, 132000, 107520, 0x3e0e4d8d
+0, 135000, 107520, 0xd268865b
1, 135012, 44112, 0xc23154d5
-0, 138000, 107520, 0x85516e9c
-0, 141000, 107520, 0x85516e9c
-0, 144000, 107520, 0xd1626030
-0, 147000, 107520, 0xd1626030
-0, 150000, 107520, 0xea7b16de
-0, 153000, 107520, 0xea7b16de
-0, 156000, 107520, 0xa33eaa0d
+0, 138000, 107520, 0x89a4efeb
+0, 141000, 107520, 0x70ca2478
+0, 144000, 107520, 0xcc9ec981
+0, 147000, 107520, 0xf0648459
+0, 150000, 107520, 0x7e4a4cca
+0, 153000, 107520, 0xb315dc65
+0, 156000, 107520, 0x2aecc7b4
1, 157518, 44064, 0xe4713ee7
-0, 159000, 107520, 0xa33eaa0d
-0, 162000, 107520, 0x8e3be6a6
-0, 165000, 107520, 0x8e3be6a6
-0, 168000, 107520, 0x14147bd6
-0, 171000, 107520, 0x14147bd6
-0, 174000, 107520, 0x07d54bec
-0, 177000, 107520, 0x07d54bec
-0, 180000, 107520, 0xe287a0a7
+0, 159000, 107520, 0x81742f51
+0, 162000, 107520, 0x3a1d7571
+0, 165000, 107520, 0x3a1d7571
+0, 168000, 107520, 0x3a1d7571
+0, 171000, 107520, 0x3a1d7571
+0, 174000, 107520, 0x3a1d7571
+0, 177000, 107520, 0x3a1d7571
+0, 180000, 107520, 0x3a1d7571
1, 180000, 44112, 0xddc19d91
-0, 183000, 107520, 0xe287a0a7
-0, 186000, 107520, 0xc023a14d
-0, 189000, 107520, 0xc023a14d
-0, 192000, 107520, 0x2437085d
-0, 195000, 107520, 0x2437085d
-0, 198000, 107520, 0x63823918
-0, 201000, 107520, 0x63823918
+0, 183000, 107520, 0xe974733e
+0, 186000, 107520, 0x999c6fbf
+0, 189000, 107520, 0x26b56b6e
+0, 192000, 107520, 0xc9f9647b
+0, 195000, 107520, 0x6d025d00
+0, 198000, 107520, 0xf9c056c1
+0, 201000, 107520, 0xa5cc4d0b
1, 202506, 44112, 0x9591522d
-0, 204000, 107520, 0xbc17e198
-0, 207000, 107520, 0xbc17e198
-0, 210000, 107520, 0x9d99bc81
-0, 213000, 107520, 0x9d99bc81
-0, 216000, 107520, 0x7e4ec71e
-0, 219000, 107520, 0x7e4ec71e
-0, 222000, 107520, 0x55b98376
-0, 225000, 107520, 0x55b98376
+0, 204000, 107520, 0x1a4c4236
+0, 207000, 107520, 0xa9d538b6
+0, 210000, 107520, 0x14682d00
+0, 213000, 107520, 0x6236204f
+0, 216000, 107520, 0x303e14aa
+0, 219000, 107520, 0x943b0837
+0, 222000, 107520, 0xfce5fd07
+0, 225000, 107520, 0xd993f193
1, 225012, 44112, 0x90deb013
-0, 228000, 107520, 0x356d8e9e
-0, 231000, 107520, 0x356d8e9e
-0, 234000, 107520, 0xf77e8a61
-0, 237000, 107520, 0xf77e8a61
-0, 240000, 107520, 0x5ae7c8c7
-0, 243000, 107520, 0x5ae7c8c7
-0, 246000, 107520, 0x8acf9322
+0, 228000, 107520, 0x4d48e7b4
+0, 231000, 107520, 0x61ccdf83
+0, 234000, 107520, 0xfb4fd608
+0, 237000, 107520, 0x5efdcdb3
+0, 240000, 107520, 0xb03ec886
+0, 243000, 107520, 0xf464c343
+0, 246000, 107520, 0xf464c343
1, 247518, 44064, 0x3842d420
-0, 249000, 107520, 0x8acf9322
-0, 252000, 107520, 0x40a9177e
-0, 255000, 107520, 0x40a9177e
-0, 258000, 107520, 0x3e0e4d8d
-0, 261000, 107520, 0x3e0e4d8d
-0, 264000, 107520, 0xd268865b
-0, 267000, 107520, 0xd268865b
-0, 270000, 107520, 0x89a4efeb
+0, 249000, 107520, 0xf464c343
+0, 252000, 107520, 0xf464c343
+0, 255000, 107520, 0xf464c343
+0, 258000, 107520, 0xf464c343
+0, 261000, 107520, 0xf464c343
+0, 264000, 107520, 0xf464c343
+0, 267000, 107520, 0xf464c343
+0, 270000, 107520, 0xf464c343
1, 270000, 44112, 0x99c8c3d9
-0, 273000, 107520, 0x89a4efeb
-0, 276000, 107520, 0x70ca2478
-0, 279000, 107520, 0x70ca2478
-0, 282000, 107520, 0xcc9ec981
-0, 285000, 107520, 0xcc9ec981
-0, 288000, 107520, 0xf0648459
-0, 291000, 107520, 0xf0648459
+0, 273000, 107520, 0xf464c343
+0, 276000, 107520, 0xf2b2c712
+0, 279000, 107520, 0xf2b2c712
+0, 282000, 107520, 0xf2b2c712
+0, 285000, 107520, 0xf2b2c712
+0, 288000, 107520, 0xb95e6bc8
+0, 291000, 107520, 0x33feee37
1, 292506, 44112, 0xffaf3824
-0, 294000, 107520, 0x7e4a4cca
-0, 297000, 107520, 0x7e4a4cca
-0, 300000, 107520, 0xb315dc65
-0, 303000, 107520, 0xb315dc65
-0, 306000, 107520, 0x2aecc7b4
-0, 309000, 107520, 0x2aecc7b4
-0, 312000, 107520, 0x81742f51
-0, 315000, 107520, 0x81742f51
+0, 294000, 107520, 0x36ee3cd5
+0, 297000, 107520, 0x59096471
+0, 300000, 107520, 0x53b470c6
+0, 303000, 107520, 0xdb7c64ff
+0, 306000, 107520, 0xe5a1596a
+0, 309000, 107520, 0x8c8942eb
+0, 312000, 107520, 0x5ecc379e
+0, 315000, 107520, 0xea09432a
1, 315012, 44112, 0x3dbe1aef
-0, 318000, 107520, 0x3a1d7571
-0, 321000, 107520, 0x3a1d7571
-0, 324000, 107520, 0x3a1d7571
-0, 327000, 107520, 0x3a1d7571
-0, 330000, 107520, 0x3a1d7571
-0, 333000, 107520, 0x3a1d7571
-0, 336000, 107520, 0x3a1d7571
+0, 318000, 107520, 0xe01e6b73
+0, 321000, 107520, 0x1d13bba8
+0, 324000, 107520, 0x3a993a6c
+0, 327000, 107520, 0x2ede041a
1, 337518, 44064, 0xed2c7dfb
-0, 339000, 107520, 0x3a1d7571
-0, 342000, 107520, 0x3a1d7571
-0, 345000, 107520, 0x3a1d7571
-0, 348000, 107520, 0x3a1d7571
-0, 351000, 107520, 0x3a1d7571
-0, 354000, 107520, 0x3a1d7571
-0, 357000, 107520, 0x3a1d7571
-0, 360000, 107520, 0xe974733e
1, 360000, 44112, 0x9e475274
-0, 363000, 107520, 0xe974733e
-0, 366000, 107520, 0x999c6fbf
-0, 369000, 107520, 0x999c6fbf
-0, 372000, 107520, 0x26b56b6e
-0, 375000, 107520, 0x26b56b6e
-0, 378000, 107520, 0xc9f9647b
-0, 381000, 107520, 0xc9f9647b
1, 382506, 44112, 0x541f05d4
-0, 384000, 107520, 0x6d025d00
-0, 387000, 107520, 0x6d025d00
-0, 390000, 107520, 0xf9c056c1
-0, 393000, 107520, 0xf9c056c1
-0, 396000, 107520, 0xa5cc4d0b
-0, 399000, 107520, 0xa5cc4d0b
-0, 402000, 107520, 0x1a4c4236
-0, 405000, 107520, 0x1a4c4236
1, 405012, 44112, 0x09e39025
-0, 408000, 107520, 0xa9d538b6
-0, 411000, 107520, 0xa9d538b6
-0, 414000, 107520, 0x14682d00
-0, 417000, 107520, 0x14682d00
-0, 420000, 107520, 0x6236204f
-0, 423000, 107520, 0x6236204f
-0, 426000, 107520, 0x303e14aa
1, 427518, 44064, 0xdc111087
-0, 429000, 107520, 0x303e14aa
-0, 432000, 107520, 0x943b0837
-0, 435000, 107520, 0x943b0837
-0, 438000, 107520, 0xfce5fd07
-0, 441000, 107520, 0xfce5fd07
-0, 444000, 107520, 0xd993f193
-0, 447000, 107520, 0xd993f193
-0, 450000, 107520, 0x4d48e7b4
1, 450000, 44112, 0xb8f86e48
-0, 453000, 107520, 0x4d48e7b4
-0, 456000, 107520, 0x61ccdf83
-0, 459000, 107520, 0x61ccdf83
-0, 462000, 107520, 0xfb4fd608
-0, 465000, 107520, 0xfb4fd608
-0, 468000, 107520, 0x5efdcdb3
-0, 471000, 107520, 0x5efdcdb3
1, 472506, 44112, 0xa1e0c75c
-0, 474000, 107520, 0xb03ec886
-0, 477000, 107520, 0xb03ec886
-0, 480000, 107520, 0xf464c343
-0, 483000, 107520, 0xf464c343
-0, 486000, 107520, 0xf464c343
-0, 489000, 107520, 0xf464c343
-0, 492000, 107520, 0xf464c343
-0, 495000, 107520, 0xf464c343
1, 495012, 44112, 0x0654dcb0
-0, 498000, 107520, 0xf464c343
-0, 501000, 107520, 0xf464c343
-0, 504000, 107520, 0xf464c343
-0, 507000, 107520, 0xf464c343
-0, 510000, 107520, 0xf464c343
-0, 513000, 107520, 0xf464c343
-0, 516000, 107520, 0xf464c343
1, 517518, 44064, 0xb921e11a
-0, 519000, 107520, 0xf464c343
-0, 522000, 107520, 0xf464c343
-0, 525000, 107520, 0xf464c343
-0, 528000, 107520, 0xf464c343
-0, 531000, 107520, 0xf464c343
-0, 534000, 107520, 0xf464c343
-0, 537000, 107520, 0xf464c343
-0, 540000, 107520, 0xf464c343
1, 540000, 44112, 0xe0ac619f
-0, 543000, 107520, 0xf464c343
-0, 546000, 107520, 0xf2b2c712
-0, 549000, 107520, 0xf2b2c712
-0, 552000, 107520, 0xf2b2c712
-0, 555000, 107520, 0xf2b2c712
-0, 558000, 107520, 0xf2b2c712
-0, 561000, 107520, 0xf2b2c712
1, 562506, 44112, 0xb07aa65c
-0, 564000, 107520, 0xf2b2c712
-0, 567000, 107520, 0xf2b2c712
-0, 570000, 107520, 0xb95e6bc8
-0, 573000, 107520, 0xb95e6bc8
-0, 576000, 107520, 0x33feee37
-0, 579000, 107520, 0x33feee37
-0, 582000, 107520, 0x36ee3cd5
-0, 585000, 107520, 0x36ee3cd5
1, 585012, 44112, 0x24610ff0
-0, 588000, 107520, 0x59096471
-0, 591000, 107520, 0x59096471
-0, 594000, 107520, 0x53b470c6
-0, 597000, 107520, 0x53b470c6
-0, 600000, 107520, 0xdb7c64ff
-0, 603000, 107520, 0xdb7c64ff
-0, 606000, 107520, 0xe5a1596a
1, 607518, 44064, 0x00000000
-0, 609000, 107520, 0xe5a1596a
-0, 612000, 107520, 0x8c8942eb
-0, 615000, 107520, 0x8c8942eb
-0, 618000, 107520, 0x5ecc379e
-0, 621000, 107520, 0x5ecc379e
-0, 624000, 107520, 0xea09432a
-0, 627000, 107520, 0xea09432a
-0, 630000, 107520, 0xe01e6b73
1, 630000, 44112, 0x00000000
-0, 633000, 107520, 0xe01e6b73
-0, 636000, 107520, 0x1d13bba8
-0, 639000, 107520, 0x1d13bba8
-0, 642000, 107520, 0x3a993a6c
-0, 645000, 107520, 0x3a993a6c
-0, 648000, 107520, 0x2ede041a
-0, 651000, 107520, 0x2ede041a
1, 652506, 8800, 0x00000000
diff --git a/tests/ref/fate/g722enc b/tests/ref/fate/g722enc
new file mode 100644
index 0000000..c109456
--- /dev/null
+++ b/tests/ref/fate/g722enc
@@ -0,0 +1 @@
+750269cc236541df28e15da5c7b0df7a
diff --git a/tests/ref/fate/h264-bsf-mp4toannexb b/tests/ref/fate/h264-bsf-mp4toannexb
new file mode 100644
index 0000000..6395f24
--- /dev/null
+++ b/tests/ref/fate/h264-bsf-mp4toannexb
@@ -0,0 +1 @@
+503d34ff458a86387ab349c31726f19a
diff --git a/tests/ref/fate/h264-lossless b/tests/ref/fate/h264-lossless
index c6659ca..30a70b5 100644
--- a/tests/ref/fate/h264-lossless
+++ b/tests/ref/fate/h264-lossless
@@ -1,10 +1,10 @@
0, 0, 460800, 0x7731dd2f
-0, 1500, 460800, 0x944b8c64
-0, 3000, 460800, 0xbe833041
-0, 4500, 460800, 0xbe95d96a
-0, 6000, 460800, 0xfe7ea5e6
-0, 7500, 460800, 0x381743c7
-0, 9000, 460800, 0x63fcc2e9
-0, 10500, 460800, 0x79574960
-0, 12000, 460800, 0xdab9e18a
-0, 13500, 460800, 0xd88e8fe8
+0, 3600, 460800, 0x944b8c64
+0, 7200, 460800, 0xbe833041
+0, 10800, 460800, 0xbe95d96a
+0, 14400, 460800, 0xfe7ea5e6
+0, 18000, 460800, 0x381743c7
+0, 21600, 460800, 0x63fcc2e9
+0, 25200, 460800, 0x79574960
+0, 28800, 460800, 0xdab9e18a
+0, 32400, 460800, 0xd88e8fe8
diff --git a/tests/ref/fate/iirfilter b/tests/ref/fate/iirfilter
new file mode 100644
index 0000000..2e5902d
--- /dev/null
+++ b/tests/ref/fate/iirfilter
@@ -0,0 +1,1024 @@
+ 0 0
+ 38 2
+ 151 15
+ 339 65
+ 603 182
+ 942 381
+ 1356 664
+ 1845 1021
+ 2409 1450
+ 3046 1953
+ 3755 2530
+ 4535 3182
+ 5384 3907
+ 6300 4700
+ 7278 5563
+ 8315 6491
+ 9405 7481
+ 10541 8529
+ 11717 9629
+ 12924 10773
+ 14151 11956
+ 15385 13167
+ 16615 14396
+ 17825 15630
+ 18997 16857
+ 20114 18060
+ 21156 19222
+ 22102 20325
+ 22929 21349
+ 23613 22273
+ 24132 23073
+ 24461 23726
+ 24575 24208
+ 24453 24495
+ 24073 24564
+ 23416 24392
+ 22467 23959
+ 21213 23245
+ 19649 22236
+ 17773 20922
+ 15590 19296
+ 13116 17360
+ 10371 15119
+ 7386 12591
+ 4201 9797
+ 867 6771
+ -2559 3554
+ -6008 199
+ -9405 -3235
+-12667 -6678
+-15707 -10053
+-18435 -13277
+-20762 -16261
+-22602 -18916
+-23875 -21153
+-24511 -22887
+-24457 -24040
+-23675 -24546
+-22151 -24352
+-19895 -23428
+-16946 -21762
+-13370 -19370
+ -9265 -16296
+ -4757 -12613
+ 0 -8423
+ 4831 -3858
+ 9544 923
+ 13934 5743
+ 17799 10406
+ 20942 14708
+ 23189 18447
+ 24395 21430
+ 24457 23488
+ 23323 24483
+ 21001 24321
+ 17563 22963
+ 13148 20426
+ 7959 16795
+ 2259 12223
+ -3643 6922
+ -9405 1166
+-14670 -4731
+-19092 -10421
+-22359 -15550
+-24213 -19777
+-24481 -22797
+-23087 -24368
+-20071 -24334
+-15590 -22639
+ -9924 -19343
+ -3457 -14629
+ 3345 -8793
+ 9959 -2236
+ 15851 4563
+ 20517 11078
+ 23528 16779
+ 24575 21171
+ 23506 23846
+ 20349 24522
+ 15327 23076
+ 8845 19572
+ 1469 14264
+ -6117 7589
+-13180 135
+-18997 -7403
+-22942 -14289
+-24553 -19814
+-23592 -23377
+-20092 -24551
+-14366 -23145
+ -6989 -19239
+ 1244 -13192
+ 9405 -5620
+ 16532 2656
+ 21744 10697
+ 24357 17548
+ 23978 22356
+ 20579 24483
+ 14518 23593
+ 6518 19723
+ -2409 13293
+-11083 5078
+-18310 -3876
+-23048 -12378
+-24568 -19252
+-22573 -23500
+-17270 -24458
+ -9370 -21908
+ 0 -16140
+ 9439 -7935
+ 17484 1526
+ 22832 10824
+ 24568 18508
+ 22327 23330
+ 16392 24452
+ 7673 21608
+ -2409 15181
+-12146 6168
+-19828 -3955
+-24050 -13466
+-23978 -20689
+-19535 -24292
+-11451 -23552
+ -1168 -18512
+ 9405 -10015
+ 18234 416
+ 23560 10836
+ 24257 19234
+ 20092 23929
+ 11817 23916
+ 1055 19105
+ -9993 10379
+-18997 -540
+-23986 -11413
+-23802 -19939
+-18385 -24246
+ -8845 -23318
+ 2746 -17260
+ 13778 -7325
+ 21691 4319
+ 24575 15045
+ 21656 22357
+ 13528 24482
+ 2071 20823
+ -9959 12152
+-19581 484
+-24331 -11367
+-22915 -20460
+-15590 -24459
+ -4164 -22257
+ 8421 -14315
+ 18828 -2603
+ 24213 9857
+ 23022 19756
+ 15474 24383
+ 3569 22388
+ -9405 14211
+-19761 2031
+-24471 -10785
+-22069 -20591
+-13148 -24512
+ -264 -21311
+ 12763 -11818
+ 21968 1241
+ 24457 13990
+ 19351 22545
+ 8137 24211
+ -5715 18362
+-17799 6720
+-24167 -7108
+-22646 -18722
+-13622 -24326
+ 0 -21995
+ 13685 -12382
+ 22762 1409
+ 24035 14788
+ 16946 23188
+ 3867 23644
+-10643 15884
+-21401 2514
+-24457 -11806
+-18584 -21960
+ -5825 -24220
+ 9160 -17649
+ 20762 -4546
+ 24527 10303
+ 18901 21343
+ 5935 24337
+ -9405 18028
+-21098 4727
+-24442 -10470
+-17979 -21608
+ -4201 -24206
+ 11351 -17110
+ 22280 -3064
+ 23970 12287
+ 15590 22636
+ 565 23615
+-14760 14693
+-23773 -479
+-22467 -15504
+-11284 -23907
+ 4942 -21954
+ 19021 -10373
+ 24575 5837
+ 18973 19502
+ 4646 24445
+-11883 18316
+-22929 3786
+-23226 -12541
+-12505 -23090
+ 4239 -22841
+ 18997 -11784
+ 24567 4932
+ 18107 19331
+ 2671 24403
+-14151 17558
+-23919 2036
+-21602 -14549
+ -8244 -23897
+ 9405 -21206
+ 22232 -7710
+ 23473 9785
+ 12342 22272
+ -5384 23186
+-20286 11920
+-24287 -5693
+-15090 -20319
+ 2409 -24060
+ 18633 -14771
+ 24538 2613
+ 16698 18608
+ -603 24329
+-17616 16471
+-24575 -682
+-17351 -17495
+ 0 -24355
+ 17404 -17211
+ 24575 -65
+ 17136 17163
+ -603 24334
+-18031 17094
+-24538 -374
+-16023 -17660
+ 2409 -24287
+ 19397 -16108
+ 24287 1992
+ 13872 18902
+ -5384 24066
+-21251 14131
+-23473 -4761
+-10473 -20664
+ 9405 -23351
+ 23151 -10967
+ 21602 8573
+ 5642 22543
+-14151 21682
+-24430 6431
+-18107 -13147
+ 641 -23920
+ 18997 -18514
+ 24207 -475
+ 12505 17922
+ -8030 23970
+-22929 13357
+-21511 -6625
+ -4646 -21972
+ 15619 -21758
+ 24575 -6009
+ 15561 14083
+ -4942 24019
+-21831 16485
+-22467 -3138
+ -6227 -20474
+ 14760 -22641
+ 24569 -7904
+ 15590 12791
+ -5421 23839
+-22280 16760
+-21797 -3160
+ -4201 -20666
+ 16754 -22169
+ 24442 -6381
+ 12602 14430
+ -9405 23865
+-23848 14348
+-18901 -6644
+ 1545 -22308
+ 20762 -19937
+ 22804 -1339
+ 5825 18365
+-16080 22954
+-24457 8529
+-12080 -13009
+ 10643 -23650
+ 24269 -14353
+ 16946 7119
+ -5127 22521
+-22762 18602
+-20413 -1370
+ 0 -20152
+ 20454 -21342
+ 22646 -3797
+ 4461 17096
+-17799 22804
+-23902 8148
+ -8137 -13817
+ 15149 -23296
+ 24457 -11618
+ 11016 10660
+-12763 23135
+-24574 14243
+-13148 -7861
+ 10813 -22608
+ 24471 -16124
+ 14609 5565
+ -9405 21949
+-24315 17379
+-15474 -3849
+ 8598 -21336
+ 24213 -18120
+ 15793 2745
+ -8421 20885
+-24220 18429
+-15590 -2263
+ 8880 -20663
+ 24331 -18359
+ 14851 2398
+ -9959 20685
+-24488 17917
+-13528 -3137
+ 11618 -20918
+ 24575 -17075
+ 11551 4460
+-13778 21286
+-24421 15770
+ -8845 -6328
+ 16307 -21661
+ 23802 -13916
+ 5348 8671
+-18997 21868
+-22452 11421
+ -1055 -11371
+ 21548 -21685
+ 20092 -8212
+ -3941 14242
+-23560 20853
+-16476 4267
+ 9405 -17009
+ 24547 -19106
+ 11451 343
+-14911 19309
+-23978 16208
+ -5053 -5409
+ 19828 -20699
+ 21364 -12016
+ -2409 10553
+-23347 20700
+-16392 6559
+ 10268 -15211
+ 24568 -18879
+ 9090 -118
+-17484 18664
+-22690 14969
+ 0 -6714
+ 22719 -20134
+ 17270 -9014
+ -9717 13022
+-24568 18943
+ -8527 1506
+ 18310 -17662
+ 21934 -14749
+ -2409 6538
+-23695 19463
+-14518 7789
+ 13433 -13633
+ 23978 -17566
+ 3270 935
+-21744 18075
+-18184 11812
+ 9405 -9654
+ 24544 -18394
+ 6989 -3082
+-19939 16117
+-20092 13945
+ 6881 -6613
+ 24553 -18196
+ 8809 -5437
+-18997 14458
+-20742 14731
+ 6117 -4859
+ 24531 -17657
+ 8845 -6307
+-19210 13526
+-20349 14588
+ 7170 -4444
+ 24575 -17109
+ 7098 -5874
+-20517 13412
+-18780 13691
+ 9959 -5272
+ 24347 -16558
+ 3457 -4241
+-22482 13949
+-15590 11979
+ 14181 -7142
+ 23087 -15723
+ -2146 -1459
+-24213 14726
+-10200 9228
+ 19092 -9692
+ 19717 -14108
+ -9405 2343
+-24304 15085
+ -2259 5221
+ 23251 -12286
+ 13148 -11127
+-17190 6746
+-21001 14161
+ 7745 2
+ 24457 -13938
+ 2971 -6372
+-23189 10842
+-12860 11094
+ 17799 -5795
+ 20243 -13421
+ -9544 -30
+-24096 13184
+ 0 5498
+ 24110 -10713
+ 9265 -9718
+-20620 6673
+-16946 12155
+ 14427 -1883
+ 22151 -12653
+ -6591 -2861
+-24457 11378
+ -1770 6908
+ 23875 -8726
+ 9648 -9817
+-20762 5209
+-16251 11385
+ 15707 -1358
+ 21059 -11610
+ -9405 -2353
+-23830 10656
+ 2559 5560
+ 24560 -8789
+ 4201 -8028
+-23439 6314
+-10371 9643
+ 20783 -3542
+ 15590 -10404
+-16973 742
+-19649 10386
+ 12407 1870
+ 22467 -9720
+ -7458 -4144
+-24073 8562
+ 2446 5991
+ 24575 -7072
+ 2371 -7375
+-24132 5398
+ -6808 8306
+ 22929 -3667
+ 10745 -8824
+-21156 1980
+-14120 8987
+ 18997 -408
+ 16918 -8863
+-16615 -1001
+-19163 8521
+ 14151 2220
+ 20902 -8027
+-11717 -3241
+-22200 7441
+ 9405 4071
+ 23126 -6811
+ -7278 -4722
+-23754 6177
+ 5384 5213
+ 24153 -5571
+ -3755 -5566
+-24386 5013
+ 2409 5801
+ 24506 -4521
+ -1356 -5939
+-24557 4104
+ 603 5999
+ 24573 -3765
+ -151 -5994
+-24575 3508
+ 0 5937
+ 24575 -3331
+ -151 -5835
+-24573 3232
+ 603 5694
+ 24557 -3205
+ -1356 -5517
+-24506 3244
+ 2409 5303
+ 24386 -3343
+ -3755 -5049
+-24153 3494
+ 5384 4752
+ 23754 -3685
+ -7278 -4407
+-23126 3906
+ 9405 4007
+ 22200 -4143
+-11717 -3547
+-20902 4380
+ 14151 3025
+ 19163 -4598
+-16615 -2434
+-16918 4778
+ 18997 1780
+ 14120 -4898
+-21156 -1066
+-10745 4934
+ 22929 304
+ 6808 -4862
+-24132 489
+ -2371 4664
+ 24575 -1288
+ -2446 -4320
+-24073 2060
+ 7458 3820
+ 22467 -2767
+-12407 -3162
+-19649 3365
+ 16973 2357
+ 15590 -3808
+-20783 -1429
+-10371 4050
+ 23439 419
+ 4201 -4055
+-24560 616
+ 2559 3795
+ 23830 -1607
+ -9405 -3266
+-21059 2473
+ 15707 2486
+ 16251 -3130
+-20762 -1499
+ -9648 3505
+ 23875 386
+ 1770 -3539
+-24457 754
+ 6591 3205
+ 22151 -1798
+-14427 -2518
+-16946 2618
+ 20620 1540
+ 9265 -3101
+-24110 -381
+ 0 3162
+ 24096 -809
+ -9544 -2775
+-20243 1859
+ 17799 1978
+ 12860 -2598
+-23189 -879
+ -2971 2893
+ 24457 -344
+ -7745 -2674
+-21001 1478
+ 17190 1966
+ 13148 -2304
+-23251 -890
+ -2259 2647
+ 24304 -341
+ -9405 -2421
+-19717 1467
+ 19092 1662
+ 10200 -2229
+-24213 -535
+ 2146 2434
+ 23087 -692
+-14181 -2022
+-15590 1706
+ 22482 1090
+ 3457 -2230
+-24347 115
+ 9959 2111
+ 18780 -1251
+-20517 -1374
+ -7098 1975
+ 24575 238
+ -7170 -2057
+-20349 938
+ 19210 1464
+ 8845 -1763
+-24531 -392
+ 6117 1949
+ 20742 -783
+-18997 -1425
+ -8809 1630
+ 24553 385
+ -6881 -1825
+-20092 770
+ 19939 1291
+ 6989 -1572
+-24544 -244
+ 9405 1688
+ 18184 -869
+-21744 -1069
+ -3270 1559
+ 23978 -7
+-13433 -1511
+-14518 1041
+ 23695 753
+ -2409 -1536
+-21934 344
+ 18310 1251
+ 8527 -1225
+-24568 -337
+ 9717 1436
+ 17270 -719
+-22719 -869
+ 0 1342
+ 22690 -157
+-17484 -1188
+ -9090 1051
+ 24568 353
+-10268 -1293
+-16392 658
+ 23347 745
+ -2409 -1224
+-21364 244
+ 19828 996
+ 5053 -1036
+-23978 -132
+ 14911 1114
+ 11451 -783
+-24547 -437
+ 9405 1124
+ 16476 -513
+-23560 -661
+ 3941 1058
+ 20092 -257
+-21548 -807
+ -1055 945
+ 22452 -37
+-18997 -887
+ -5348 815
+ 23802 142
+-16307 -917
+ -8845 682
+ 24421 276
+-13778 -913
+-11551 563
+ 24575 371
+-11618 -888
+-13528 463
+ 24488 431
+ -9959 -854
+-14851 386
+ 24331 462
+ -8880 -815
+-15590 333
+ 24220 471
+ -8421 -779
+-15793 302
+ 24213 460
+ -8598 -746
+-15474 292
+ 24315 433
+ -9405 -717
+-14609 300
+ 24471 391
+-10813 -689
+-13148 324
+ 24574 336
+-12763 -660
+-11016 359
+ 24457 267
+-15149 -627
+ -8137 400
+ 23902 184
+-17799 -584
+ -4461 444
+ 22646 90
+-20454 -527
+ 0 483
+ 20413 -15
+-22762 -452
+ 5127 511
+ 16946 -124
+-24269 -357
+ 10643 517
+ 12080 -232
+-24457 -241
+ 16080 495
+ 5825 -328
+-22804 -107
+ 20762 440
+ -1545 -400
+-18901 35
+ 23848 347
+ -9405 -437
+-12602 173
+ 24442 220
+-16754 -426
+ -4201 290
+ 21797 69
+-22280 -362
+ 5421 366
+ 15590 -89
+-24569 -247
+ 14760 384
+ 6227 -228
+-22467 -95
+ 21831 335
+ -4942 -321
+-15561 71
+ 24575 222
+-15619 -344
+ -4646 214
+ 21511 65
+-22929 -288
+ 8030 300
+ 12505 -102
+-24207 -162
+ 18997 304
+ -641 -232
+-18107 4
+ 24430 218
+-14151 -286
+ -5642 160
+ 21602 68
+-23151 -244
+ 9405 253
+ 10473 -97
+-23473 -115
+ 21251 247
+ -5384 -216
+-13872 49
+ 24287 142
+-19397 -238
+ 2409 183
+ 16023 -17
+-24538 -153
+ 18031 224
+ -603 -158
+-17136 0
+ 24575 153
+-17404 -209
+ 0 142
+ 17351 6
+-24575 -144
+ 17616 196
+ -603 -133
+-16698 -1
+ 24538 131
+-18633 -182
+ 2409 132
+ 15090 -11
+-24287 -111
+ 20286 169
+ -5384 -134
+-12342 30
+ 23473 86
+-22232 -152
+ 9405 138
+ 8244 -53
+-21602 -56
+ 23919 132
+-14151 -138
+ -2671 76
+ 18107 21
+-24567 -104
+ 18997 134
+ -4239 -98
+-12505 16
+ 23226 69
+-22929 -119
+ 11883 111
+ 4646 -53
+-18973 -28
+ 24575 92
+-19021 -113
+ 4942 82
+ 11284 -16
+-22467 -54
+ 23773 97
+-14760 -97
+ -565 56
+ 15590 8
+-23970 -65
+ 22280 93
+-11351 -82
+ -4201 37
+ 17979 21
+-24442 -67
+ 21098 85
+ -9405 -69
+ -5935 26
+ 18901 24
+-24527 -64
+ 20762 77
+ -9160 -61
+ -5825 23
+ 18584 21
+-24457 -56
+ 21401 69
+-10643 -57
+ -3867 25
+ 16946 15
+-24035 -47
+ 22762 62
+-13685 -55
+ 0 29
+ 13622 4
+-22646 -35
+ 24167 53
+-17799 -52
+ 5715 36
+ 8137 -8
+-19351 -21
+ 24457 41
+-21968 -49
+ 12763 41
+ 264 -21
+-13148 -4
+ 22069 27
+-24471 -40
+ 19761 42
+ -9405 -31
+ -3569 12
+ 15474 9
+-23022 -27
+ 24213 36
+-18828 -35
+ 8421 25
+ 4164 -9
+-15590 -9
+ 22915 23
+-24331 -31
+ 19581 31
+ -9959 -23
+ -2071 10
+ 13528 5
+-21656 -18
+ 24575 26
+-21691 -27
+ 13778 22
+ -2746 -12
+ -8845 0
+ 18385 11
+-23802 -20
+ 23986 23
+-18997 -22
+ 9993 15
+ 1055 -7
+-11817 -3
+ 20092 11
+-24257 -17
+ 23560 19
+-18234 -17
+ 9405 12
+ 1168 -5
+-11451 -3
+ 19535 10
+-23978 -14
+ 24050 16
+-19828 -14
+ 12146 11
+ -2409 -5
+ -7673 0
+ 16392 6
+-22327 -10
+ 24568 12
+-22832 -12
+ 17484 11
+ -9439 -7
+ 0 3
+ 9370 2
+-17270 -5
+ 22573 8
+-24568 -9
+ 23048 10
+-18310 -8
+ 11083 5
+ -2409 -3
+ -6518 -1
+ 14518 3
+-20579 -5
+ 23978 7
+-24357 -7
+ 21744 7
+-16532 -6
+ 9405 3
+ -1244 -1
+ -6989 -1
+ 14366 3
+-20092 -4
+ 23592 5
+-24553 -5
+ 22942 5
+-18997 -4
+ 13180 3
+ -6117 -2
+ -1469 1
+ 8845 2
+-15327 -2
+ 20349 3
+-23506 -4
+ 24575 3
+-23528 -4
+ 20517 3
+-15851 -2
+ 9959 1
+ -3345 0
+ -3457 0
+ 9924 1
+-15590 -2
+ 20071 2
+-23087 -2
+ 24481 3
+-24213 -2
+ 22359 2
+-19092 -1
+ 14670 1
+ -9405 0
+ 3643 0
+ 2259 0
+ -7959 -1
+ 13148 1
+-17563 -1
+ 21001 1
+-23323 -1
+ 24457 1
+-24395 -1
+ 23189 1
+-20942 -1
+ 17799 1
+-13934 0
+ 9544 0
+ -4831 0
+ 0 0
+ 4757 1
+ -9265 0
+ 13370 0
+-16946 -1
+ 19895 0
+-22151 -1
+ 23675 0
+-24457 -1
+ 24511 0
+-23875 0
+ 22602 0
+-20762 0
+ 18435 0
+-15707 0
+ 12667 0
+ -9405 0
+ 6008 0
+ -2559 0
+ -867 0
+ 4201 0
+ -7386 0
+ 10371 0
+-13116 0
+ 15590 0
+-17773 0
+ 19649 0
+-21213 0
+ 22467 0
+-23416 0
+ 24073 0
+-24453 0
+ 24575 0
+-24461 0
+ 24132 0
+-23613 0
+ 22929 0
+-22102 0
+ 21156 0
+-20114 0
+ 18997 0
+-17825 0
+ 16615 0
+-15385 0
+ 14151 0
+-12924 0
+ 11717 0
+-10541 0
+ 9405 0
+ -8315 0
+ 7278 0
+ -6300 0
+ 5384 0
+ -4535 0
+ 3755 0
+ -3046 0
+ 2409 0
+ -1845 0
+ 1356 0
+ -942 0
+ 603 0
+ -339 0
+ 151 0
+ -38 0
diff --git a/tests/ref/fate/lmlm4-demux b/tests/ref/fate/lmlm4-demux
index f322300..f321423 100644
--- a/tests/ref/fate/lmlm4-demux
+++ b/tests/ref/fate/lmlm4-demux
@@ -213,335 +213,3 @@
1, 265680, 768, 0xfd6c7597
0, 267267, 1327, 0x7d15307c
1, 267840, 768, 0x8d766d40
-0, 270270, 1225, 0x1b5d0f5f
-0, 273273, 1173, 0x840efed5
-0, 276276, 1215, 0xa8e0035e
-0, 279279, 1295, 0x142918ca
-0, 282282, 1144, 0xf50cef50
-0, 285285, 1527, 0x7d13bd9d
-0, 288288, 5609, 0x1ae1921d
-0, 291291, 1303, 0xabdc264f
-0, 294294, 1419, 0x878169bf
-0, 297297, 972, 0x00c4a257
-0, 300300, 1277, 0x87d520cf
-0, 303303, 1014, 0x5946b4ee
-0, 306306, 1177, 0x124e0e23
-0, 309309, 1402, 0x8e6363cc
-0, 312312, 1171, 0x9bdaeda2
-0, 315315, 1389, 0x2db53b22
-0, 318318, 1056, 0xd1c3de3e
-0, 321321, 1320, 0x1ea142c7
-0, 324324, 1250, 0x33612229
-0, 327327, 1477, 0xb9648b48
-0, 330330, 1522, 0x5352c318
-0, 333333, 1391, 0x5e9157e0
-0, 336336, 5545, 0x569e64c1
-0, 339339, 1354, 0xdb39469e
-0, 342342, 1302, 0x79912b5d
-0, 345345, 1065, 0x4befcdd2
-0, 348348, 1408, 0x7d2f65a2
-0, 351351, 1727, 0x9cac0398
-0, 354354, 1590, 0xa321b563
-0, 357357, 1039, 0xfa35cabf
-0, 360360, 1184, 0xb332fde7
-0, 363363, 669, 0xb10e3783
-0, 366366, 784, 0x57275e09
-0, 369369, 1051, 0xe072cd33
-0, 372372, 1119, 0x635ee9ee
-0, 375375, 1147, 0x3916f981
-0, 378378, 1086, 0x306ef895
-0, 381381, 827, 0x213f7aef
-0, 384384, 5525, 0x19157827
-0, 387387, 1044, 0xb661abc5
-0, 390390, 1143, 0x032e1109
-0, 393393, 1460, 0x5a2f9503
-0, 396396, 1178, 0xd038141f
-0, 399399, 1004, 0x410ec3b2
-0, 402402, 1089, 0xc89af8c9
-0, 405405, 1367, 0x52085e0a
-0, 408408, 1115, 0x8bb2ee7f
-0, 411411, 1325, 0xc2e05647
-0, 414414, 1295, 0x213951c9
-0, 417417, 1054, 0xbb8bdaae
-0, 420420, 1210, 0x431122bd
-0, 423423, 1400, 0x47526fcc
-0, 426426, 1188, 0x19770b07
-0, 429429, 1301, 0x437161c8
-0, 432432, 5281, 0xc0c92b55
-0, 435435, 840, 0x67da7b2f
-0, 438438, 1094, 0x3fd6d944
-0, 441441, 832, 0x0eda74bc
-0, 444444, 1096, 0x3300da7b
-0, 447447, 1018, 0xa208c971
-0, 450450, 1389, 0x1167724c
-0, 453453, 1411, 0xe3be666b
-0, 456456, 1294, 0xa8f35cc6
-0, 459459, 1232, 0xfd0d20fd
-0, 462462, 1252, 0xadd83a26
-0, 465465, 844, 0xcbaf6a55
-0, 468468, 979, 0x78d9b241
-0, 471471, 1057, 0x6743e16c
-0, 474474, 776, 0xfedd6615
-0, 477477, 1158, 0xa39fee34
-0, 480480, 5288, 0x5f26ee02
-0, 483483, 1029, 0xa681bee8
-0, 486486, 1106, 0xa68dea33
-0, 489489, 844, 0x42fd83ec
-0, 492492, 779, 0xb5006759
-0, 495495, 951, 0xec13af4f
-0, 498498, 1011, 0x90e5c86e
-0, 501501, 892, 0x4db48ca4
-0, 504504, 804, 0x59bf73a7
-0, 507507, 1001, 0x10c2b3ff
-0, 510510, 879, 0x65c57eaf
-0, 513513, 1320, 0x80815836
-0, 516516, 1448, 0xaf457b3b
-0, 519519, 1168, 0x65b9f96a
-0, 522522, 1002, 0x053fafb9
-0, 525525, 1101, 0x2d30c3d5
-0, 528528, 5314, 0x87cee383
-0, 531531, 1305, 0xb19035db
-0, 534534, 1240, 0xdc6a0a65
-0, 537537, 1067, 0x9c88ba67
-0, 540540, 823, 0x2f736a43
-0, 543543, 1183, 0x2ef9f3c9
-0, 546546, 899, 0x3fcc8d11
-0, 549549, 886, 0xccec8d49
-0, 552552, 1190, 0x2d020fa1
-0, 555555, 1017, 0x0776b627
-0, 558558, 1202, 0xbdd808d5
-0, 561561, 998, 0x64c7c246
-0, 564564, 1200, 0x9d6e2289
-0, 567567, 895, 0xa8a68d80
-0, 570570, 748, 0xe61a49fb
-0, 573573, 929, 0x30168b50
-0, 576576, 5276, 0xceb2edf2
-0, 579579, 1127, 0xab43ddc3
-0, 582582, 1028, 0xaacfbff5
-0, 585585, 914, 0xb63c8fb0
-0, 588588, 1067, 0xbdacd1ed
-0, 591591, 1109, 0x6792ddec
-0, 594594, 1310, 0x71bc4da2
-0, 597597, 1098, 0xc464de9b
-0, 600600, 1018, 0x6833b875
-0, 603603, 1210, 0x44faf34b
-0, 606606, 1200, 0x9ee816f6
-0, 609609, 1461, 0xc76b7d2b
-0, 612612, 829, 0x006677e6
-0, 615615, 1145, 0xc769fb13
-0, 618618, 1292, 0xb63225f5
-0, 621621, 1252, 0x0e2a2626
-0, 624624, 5257, 0x3877eca1
-0, 627627, 952, 0x7f708d25
-0, 630630, 1125, 0x140cd81b
-0, 633633, 1095, 0x3025dade
-0, 636636, 1388, 0xd7494d4e
-0, 639639, 1124, 0x0c48ee92
-0, 642642, 1556, 0xa0749ee2
-0, 645645, 1461, 0xe5fd7d7f
-0, 648648, 903, 0x07a58303
-0, 651651, 1049, 0x4b6cd03b
-0, 654654, 1044, 0x5f47cb48
-0, 657657, 1253, 0xba281c6a
-0, 660660, 1618, 0xed7cd040
-0, 663663, 981, 0x2926b6f4
-0, 666666, 1560, 0xa0e1ab73
-0, 669669, 1479, 0x41a77e88
-0, 672672, 5222, 0xc2dbd182
-0, 675675, 925, 0x967580dd
-0, 678678, 1284, 0x5b7822e0
-0, 681681, 1512, 0xe84da1e0
-0, 684684, 1514, 0xc38bb09e
-0, 687687, 1224, 0x8752228e
-0, 690690, 1296, 0xcf053c03
-0, 693693, 1117, 0x9a81e659
-0, 696696, 1090, 0x003ed687
-0, 699699, 1196, 0x3a510937
-0, 702702, 1075, 0x05eec8d4
-0, 705705, 1048, 0x3b19cb96
-0, 708708, 944, 0xaad89770
-0, 711711, 960, 0x94649e4c
-0, 714714, 1079, 0x530ddaba
-0, 717717, 1150, 0x0339e696
-0, 720720, 5189, 0xb8dac0bf
-0, 723723, 1129, 0x3b2cd64d
-0, 726726, 962, 0xe9df9a07
-0, 729729, 1113, 0xc6ccddb2
-0, 732732, 1069, 0xf589d4a4
-0, 735735, 889, 0x5f7b8762
-0, 738738, 863, 0xe9c36be4
-0, 741741, 1021, 0xcfb5a737
-0, 744744, 1048, 0x203ac9ff
-0, 747747, 1223, 0x3e30fe35
-0, 750750, 814, 0x59c076fc
-0, 753753, 1157, 0x0dcf0bd0
-0, 756756, 1691, 0xdd030547
-0, 759759, 1700, 0x7641fb7e
-0, 762762, 1791, 0x57ac147b
-0, 765765, 2008, 0x3d4483ca
-0, 768768, 4579, 0x874aa75b
-0, 771771, 1647, 0xeddef621
-0, 774774, 1999, 0x61d4a23a
-0, 777777, 1572, 0x1c3ae6e1
-0, 780780, 1803, 0xb31c3a11
-0, 783783, 1919, 0xccbf64e3
-0, 786786, 1720, 0xa4d010e5
-0, 789789, 1721, 0x87ee0c7b
-0, 792792, 1626, 0x8211f3d0
-0, 795795, 1675, 0xef8a0b3d
-0, 798798, 1609, 0x8731ce06
-0, 801801, 1691, 0xcf24038b
-0, 804804, 1637, 0x21d8e1b2
-0, 807807, 1546, 0xc597a700
-0, 810810, 1518, 0xb944bc11
-0, 813813, 1403, 0x999e59a8
-0, 816816, 2467, 0xe69f2507
-0, 819819, 531, 0x3c7cea7e
-0, 822822, 555, 0xdf20fb22
-0, 825825, 500, 0xebeee00d
-0, 828828, 446, 0x664cc711
-0, 831831, 521, 0xf223df4b
-0, 834834, 559, 0x4dc60028
-0, 837837, 593, 0xec440ba9
-0, 840840, 557, 0xef0100b1
-0, 843843, 602, 0x7b1cfd88
-0, 846846, 566, 0x77700a1d
-0, 849849, 523, 0x3df7eb64
-0, 852852, 482, 0x5da1dba9
-0, 855855, 541, 0x9c8ff3d7
-0, 858858, 572, 0x3e1204b2
-0, 861861, 549, 0x0921fe3d
-0, 864864, 2429, 0xba4fe5a8
-0, 867867, 495, 0xc35ade54
-0, 870870, 453, 0xcc66c9dc
-0, 873873, 421, 0x3aa7ce8f
-0, 876876, 448, 0x56c6d3d7
-0, 879879, 478, 0x4131d467
-0, 882882, 497, 0xac3ce3ca
-0, 885885, 470, 0x41b9d9d3
-0, 888888, 454, 0x44c2d956
-0, 891891, 460, 0x6629db01
-0, 894894, 488, 0x6be2dd68
-0, 897897, 512, 0xda4cf116
-0, 900900, 550, 0x6e990da9
-0, 903903, 561, 0x81180e5e
-0, 906906, 689, 0xe58a5a9a
-0, 909909, 548, 0xfa1417a9
-0, 912912, 2832, 0x942495a5
-0, 915915, 610, 0x6b201ab9
-0, 918918, 1015, 0x5f36b3f9
-0, 921921, 870, 0x14e48f0c
-0, 924924, 716, 0xf4034b52
-0, 927927, 763, 0xcbf4694e
-0, 930930, 778, 0xb9396764
-0, 933933, 831, 0x31999005
-0, 936936, 877, 0xc95e977f
-0, 939939, 836, 0xb56c7d61
-0, 942942, 853, 0x2d5980cf
-0, 945945, 861, 0x25629295
-0, 948948, 897, 0x0ff78a5f
-0, 951951, 1016, 0x4dd8cdfd
-0, 954954, 1117, 0x763f06c4
-0, 957957, 984, 0xcf7bc906
-0, 960960, 2750, 0xd428962d
-0, 963963, 995, 0x5cbdd6a4
-0, 966966, 894, 0xc42b9e25
-0, 969969, 1028, 0xdf8ad906
-0, 972972, 1059, 0x4c49f0cc
-0, 975975, 1122, 0x8880eed8
-0, 978978, 1007, 0xa9b4c243
-0, 981981, 1055, 0x6051dcd6
-0, 984984, 1293, 0xc3b32fa5
-0, 987987, 1101, 0xf986f9af
-0, 990990, 1272, 0x13883127
-0, 993993, 1037, 0xb97cebff
-0, 996996, 980, 0x0931d807
-0, 999999, 928, 0xbc3eb30b
-0, 1003002, 1068, 0x62d9e8de
-0, 1006005, 852, 0x9278a49a
-0, 1009008, 2841, 0x3091d12d
-0, 1012011, 931, 0x60f6c26e
-0, 1015014, 949, 0x31b9c856
-0, 1018017, 835, 0xfe018775
-0, 1021020, 779, 0x85356cd7
-0, 1024023, 748, 0x862756bf
-0, 1027026, 768, 0x0b7d645c
-0, 1030029, 786, 0x7c196f5b
-0, 1033032, 716, 0x4e8252cc
-0, 1036035, 671, 0x0b2d3023
-0, 1039038, 708, 0x3b2b4f25
-0, 1042041, 786, 0x523d670e
-0, 1045044, 680, 0x329142ec
-0, 1048047, 703, 0x841b456c
-0, 1051050, 660, 0x5cf332f1
-0, 1054053, 681, 0xcd7b3915
-0, 1057056, 2445, 0x27660ecb
-0, 1060059, 667, 0xf3d53d2a
-0, 1063062, 652, 0xe2b037b0
-0, 1066065, 695, 0x200248fc
-0, 1069068, 659, 0x7f6434c5
-0, 1072071, 682, 0x8d243afb
-0, 1075074, 701, 0x16e6476f
-0, 1078077, 636, 0x319a3236
-0, 1081080, 679, 0x81fa41f9
-0, 1084083, 740, 0xb32850af
-0, 1087086, 694, 0xe3f832c2
-0, 1090089, 681, 0x8174353f
-0, 1093092, 757, 0xebbe5a1f
-0, 1096095, 683, 0x9b46383c
-0, 1099098, 816, 0xd41e6bdf
-0, 1102101, 1058, 0x6170d2e6
-0, 1105104, 2489, 0x58fb28e1
-0, 1108107, 804, 0xb3037da8
-0, 1111110, 1053, 0x81ffc0a8
-0, 1114113, 868, 0xf73583cb
-0, 1117116, 875, 0xfa5d85bd
-0, 1120119, 723, 0x0714418d
-0, 1123122, 670, 0xd04333a1
-0, 1126125, 854, 0x370e730d
-0, 1129128, 794, 0x3d8a5e3c
-0, 1132131, 836, 0xebe26aa7
-0, 1135134, 871, 0x1da58c5e
-0, 1138137, 827, 0xda1e6ccb
-0, 1141140, 805, 0x10ad6a44
-0, 1144143, 831, 0x826f6fc9
-0, 1147146, 832, 0xb2517364
-0, 1150149, 887, 0x11bf8a3f
-0, 1153152, 2718, 0x26a8a174
-0, 1156155, 805, 0x4d0179f9
-0, 1159158, 699, 0x176c4f45
-0, 1162161, 758, 0xc1fc5b16
-0, 1165164, 707, 0x161b4891
-0, 1168167, 733, 0x99b554c0
-0, 1171170, 671, 0xccee2f89
-0, 1174173, 762, 0xd6416c9d
-0, 1177176, 721, 0x2ad94f0c
-0, 1180179, 727, 0x6280572e
-0, 1183182, 856, 0x0a7b797e
-0, 1186185, 843, 0xc64288aa
-0, 1189188, 877, 0x6d1c945d
-0, 1192191, 780, 0x4ba464e8
-0, 1195194, 808, 0xb3087cca
-0, 1198197, 870, 0x75809930
-0, 1201200, 2919, 0x5a80f685
-0, 1204203, 1027, 0xc98add3d
-0, 1207206, 1003, 0x0d88bd54
-0, 1210209, 1189, 0xb2f91ec7
-0, 1213212, 1320, 0x5acc4db3
-0, 1216215, 1381, 0xbd585feb
-0, 1219218, 1378, 0xe1a656f0
-0, 1222221, 1398, 0x88b57a5e
-0, 1225224, 1449, 0x1c737698
-0, 1228227, 1420, 0x6f0f80cd
-0, 1231230, 1032, 0x2d16d643
-0, 1234233, 1275, 0x38844729
-0, 1237236, 1112, 0x300207ea
-0, 1240239, 1105, 0xa2b700be
-0, 1243242, 1283, 0x08d04bef
-0, 1246245, 1056, 0xf795d994
-0, 1249248, 3202, 0xebf07050
-0, 1252251, 1034, 0x1099dbe5
-0, 1255254, 922, 0x88be9edc
-0, 1258257, 1050, 0xd3d7eb96
-0, 1261260, 979, 0x8de6b302
-0, 1264263, 1053, 0x5de2eca8
diff --git a/tests/ref/fate/lossless-shortenaudio b/tests/ref/fate/lossless-shortenaudio
index 9448052..9cdb369 100644
--- a/tests/ref/fate/lossless-shortenaudio
+++ b/tests/ref/fate/lossless-shortenaudio
@@ -1 +1 @@
-9949141c405524f37ef1058b1ef4114b
+da93c50961443b88fce416ae61c8ca8a
diff --git a/tests/ref/fate/md5 b/tests/ref/fate/md5
new file mode 100644
index 0000000..af08a84
--- /dev/null
+++ b/tests/ref/fate/md5
@@ -0,0 +1,5 @@
+0bf1bcc8a1d72e2cf58d42182b637e56
+993a3eb298e52aca83ecfbb6a766b4d0
+07c01ca7c733475fad38c84c56f305c1
+9fc8404827cac26385f48f4f58fd32ce
+a22bfef14302c5ca46e0ae91092bc0e0
diff --git a/tests/ref/fate/motionpixels b/tests/ref/fate/motionpixels
index e588ed3..fa86f73 100644
--- a/tests/ref/fate/motionpixels
+++ b/tests/ref/fate/motionpixels
@@ -109,4 +109,3 @@
0, 648003, 230400, 0xb343f372
0, 654003, 230400, 0xf7f1e588
0, 660003, 230400, 0x9682bdb2
-0, 666003, 230400, 0x538a3db8
diff --git a/tests/ref/fate/mpeg2-field-enc b/tests/ref/fate/mpeg2-field-enc
index 1ea05bd..9ae5d62 100644
--- a/tests/ref/fate/mpeg2-field-enc
+++ b/tests/ref/fate/mpeg2-field-enc
@@ -1,39 +1,31 @@
0, 0, 622080, 0xb3b66c5c
-0, 3600, 622080, 0xb3b66c5c
-0, 7200, 622080, 0xb3b66c5c
-0, 10800, 622080, 0xb3b66c5c
-0, 14400, 622080, 0xb3b66c5c
-0, 18000, 622080, 0xb3b66c5c
-0, 21600, 622080, 0xb3b66c5c
-0, 25200, 622080, 0xb3b66c5c
-0, 28800, 622080, 0xb3b66c5c
-0, 32400, 622080, 0x088ec02b
-0, 36000, 622080, 0x7a36db21
-0, 39600, 622080, 0x541b286f
-0, 43200, 622080, 0xb6c3e590
-0, 46800, 622080, 0x39dbed51
-0, 50400, 622080, 0x973dc728
-0, 54000, 622080, 0xd7a4f804
-0, 57600, 622080, 0xa2484762
-0, 61200, 622080, 0x0cd268d1
-0, 64800, 622080, 0x72eb663d
-0, 68400, 622080, 0x8fdbac59
-0, 72000, 622080, 0xa6f4feb9
-0, 75600, 622080, 0xadb828c6
-0, 79200, 622080, 0xea630a63
-0, 82800, 622080, 0xa901d925
-0, 86400, 622080, 0xac5e7087
-0, 90000, 622080, 0x10274a2b
-0, 93600, 622080, 0x143d541c
-0, 97200, 622080, 0xee94c93a
-0, 100800, 622080, 0xca030208
-0, 104400, 622080, 0x26f30ead
-0, 108000, 622080, 0xfc22f32c
-0, 111600, 622080, 0x940a5ff8
-0, 115200, 622080, 0x2164f805
-0, 118800, 622080, 0xa76f5aba
-0, 122400, 622080, 0x8c311471
-0, 126000, 622080, 0xa45e1d95
-0, 129600, 622080, 0x6cc61d6c
-0, 133200, 622080, 0x6983b417
-0, 136800, 622080, 0x982363c0
+0, 3600, 622080, 0x088ec02b
+0, 7200, 622080, 0x7a36db21
+0, 10800, 622080, 0x541b286f
+0, 14400, 622080, 0xb6c3e590
+0, 18000, 622080, 0x39dbed51
+0, 21600, 622080, 0x973dc728
+0, 25200, 622080, 0xd7a4f804
+0, 28800, 622080, 0xa2484762
+0, 32400, 622080, 0x0cd268d1
+0, 36000, 622080, 0x72eb663d
+0, 39600, 622080, 0x8fdbac59
+0, 43200, 622080, 0xa6f4feb9
+0, 46800, 622080, 0xadb828c6
+0, 50400, 622080, 0xea630a63
+0, 54000, 622080, 0xa901d925
+0, 57600, 622080, 0xac5e7087
+0, 61200, 622080, 0x10274a2b
+0, 64800, 622080, 0x143d541c
+0, 68400, 622080, 0xee94c93a
+0, 72000, 622080, 0xca030208
+0, 75600, 622080, 0x26f30ead
+0, 79200, 622080, 0xfc22f32c
+0, 82800, 622080, 0x940a5ff8
+0, 86400, 622080, 0x2164f805
+0, 90000, 622080, 0xa76f5aba
+0, 93600, 622080, 0x8c311471
+0, 97200, 622080, 0xa45e1d95
+0, 100800, 622080, 0x6cc61d6c
+0, 104400, 622080, 0x6983b417
+0, 108000, 622080, 0x982363c0
diff --git a/tests/ref/fate/nuv b/tests/ref/fate/nuv
index b047378..f1fcae3 100644
--- a/tests/ref/fate/nuv
+++ b/tests/ref/fate/nuv
@@ -1,30 +1,27 @@
0, 0, 460800, 0x54aedafe
1, 0, 4096, 0x00000000
1, 2090, 4096, 0x4dfae7a6
-0, 3003, 460800, 0x54aedafe
+0, 3003, 460800, 0xb7aa8b56
1, 4180, 4096, 0x3fd9f5c6
-0, 6006, 460800, 0x54aedafe
+0, 6006, 460800, 0x283ea3b5
1, 6269, 4096, 0x7b86e310
1, 8359, 4096, 0x611cece5
-0, 9009, 460800, 0x54aedafe
+0, 9009, 460800, 0x283ea3b5
1, 10449, 4096, 0xb7d8e872
-0, 12012, 460800, 0xb7aa8b56
+0, 12012, 460800, 0x10e577de
1, 12539, 4096, 0x072ef72b
1, 14629, 4096, 0xb3560144
-0, 15015, 460800, 0x283ea3b5
+0, 15015, 460800, 0x4e091ee2
1, 16718, 4096, 0x0a3d119e
-0, 18018, 460800, 0x283ea3b5
+0, 18018, 460800, 0x2ea88828
1, 18808, 4096, 0xbe391aa4
1, 20898, 4096, 0x28f7c6e5
-0, 21021, 460800, 0x10e577de
+0, 21021, 460800, 0x4b7f4df0
1, 22988, 4096, 0xca9d9df2
-0, 24024, 460800, 0x4e091ee2
+0, 24024, 460800, 0xb30eb322
1, 25078, 4096, 0x5c6b95a9
-0, 27027, 460800, 0x2ea88828
1, 27167, 4096, 0x0bdfc0bf
1, 29257, 4096, 0xd95a9277
-0, 30030, 460800, 0x4b7f4df0
1, 31347, 4096, 0xae2bef2c
-0, 33033, 460800, 0xb30eb322
1, 33437, 4096, 0xbf031e83
1, 35527, 4096, 0x4c83e2d1
diff --git a/tests/ref/fate/prores-422 b/tests/ref/fate/prores-422
new file mode 100644
index 0000000..8d6f3ab
--- /dev/null
+++ b/tests/ref/fate/prores-422
@@ -0,0 +1,2 @@
+0, 0, 8294400, 0xe8e9d448
+0, 3003, 8294400, 0xe8e9d448
diff --git a/tests/ref/fate/prores-422_hq b/tests/ref/fate/prores-422_hq
new file mode 100644
index 0000000..8ce6937
--- /dev/null
+++ b/tests/ref/fate/prores-422_hq
@@ -0,0 +1,2 @@
+0, 0, 8294400, 0x817063b0
+0, 3003, 8294400, 0x817063b0
diff --git a/tests/ref/fate/prores-422_lt b/tests/ref/fate/prores-422_lt
new file mode 100644
index 0000000..e9d0437
--- /dev/null
+++ b/tests/ref/fate/prores-422_lt
@@ -0,0 +1,2 @@
+0, 0, 8294400, 0xcd4ccde1
+0, 3003, 8294400, 0xcd4ccde1
diff --git a/tests/ref/fate/prores-422_proxy b/tests/ref/fate/prores-422_proxy
new file mode 100644
index 0000000..c9e454f
--- /dev/null
+++ b/tests/ref/fate/prores-422_proxy
@@ -0,0 +1,2 @@
+0, 0, 8294400, 0x51d29320
+0, 3003, 8294400, 0x51d29320
diff --git a/tests/ref/fate/prores-alpha b/tests/ref/fate/prores-alpha
new file mode 100644
index 0000000..4592652
--- /dev/null
+++ b/tests/ref/fate/prores-alpha
@@ -0,0 +1,2 @@
+0, 0, 12441600, 0x9d3dc525
+0, 3003, 12441600, 0x9d3dc525
diff --git a/tests/ref/fate/qt-ima4-mono b/tests/ref/fate/qt-ima4-mono
index 66767d5..b8fc5f9 100644
--- a/tests/ref/fate/qt-ima4-mono
+++ b/tests/ref/fate/qt-ima4-mono
@@ -1 +1 @@
-721b51fd66c3bb3dc49dd88d404188eb
+e178ed520edf2f46492ae740d88f5815
diff --git a/tests/ref/fate/qt-ima4-stereo b/tests/ref/fate/qt-ima4-stereo
index 5e6b123..84c9f46 100644
--- a/tests/ref/fate/qt-ima4-stereo
+++ b/tests/ref/fate/qt-ima4-stereo
@@ -1 +1 @@
-c9e4c21fb62eca34a533f3a9ad2e394a
+d22be0e193dcbba1068a1ca6ab04cf77
diff --git a/tests/ref/fate/r210 b/tests/ref/fate/r210
new file mode 100644
index 0000000..238a136
--- /dev/null
+++ b/tests/ref/fate/r210
@@ -0,0 +1,3 @@
+0, 0, 1843200, 0xbd414b93
+0, 3003, 1843200, 0x23298f1f
+0, 6006, 1843200, 0x5a56df19
diff --git a/tests/ref/fate/real-rv40 b/tests/ref/fate/real-rv40
index 2a445d0..c63c525 100644
--- a/tests/ref/fate/real-rv40
+++ b/tests/ref/fate/real-rv40
@@ -1,121 +1,240 @@
0, 0, 276480, 0x5f7a0d4f
-0, 7500, 276480, 0x5f7a0d4f
-0, 15000, 276480, 0x5f7a0d4f
-0, 22500, 276480, 0x5f7a0d4f
-0, 30000, 276480, 0x5f7a0d4f
-0, 37500, 276480, 0x5f7a0d4f
-0, 45000, 276480, 0x5f7a0d4f
-0, 52500, 276480, 0x5f7a0d4f
-0, 60000, 276480, 0x5f7a0d4f
-0, 67500, 276480, 0x5f7a0d4f
-0, 75000, 276480, 0x5f7a0d4f
-0, 82500, 276480, 0x5f7a0d4f
-0, 90000, 276480, 0x5f7a0d4f
-0, 97500, 276480, 0x5f7a0d4f
-0, 105000, 276480, 0x5f7a0d4f
-0, 112500, 276480, 0x5f7a0d4f
-0, 120000, 276480, 0x5f7a0d4f
-0, 127500, 276480, 0x5f7a0d4f
-0, 135000, 276480, 0x2d722f8a
-0, 142500, 276480, 0xebbb3c8f
-0, 150000, 276480, 0x8574c868
-0, 157500, 276480, 0x4ec1e418
-0, 165000, 276480, 0x95f22651
-0, 172500, 276480, 0x071d897e
-0, 180000, 276480, 0x9f7623f9
-0, 187500, 276480, 0x86d4dedf
-0, 195000, 276480, 0xc0a0be22
-0, 202500, 276480, 0xc5902aec
-0, 210000, 276480, 0xe000f066
-0, 217500, 276480, 0x0b2a48d5
-0, 225000, 276480, 0xa1565256
-0, 232500, 276480, 0x8de3ceb3
-0, 240000, 276480, 0x654b564a
-0, 247500, 276480, 0xc9c57884
-0, 255000, 276480, 0x89cdcdd4
-0, 262500, 276480, 0x3594fe61
-0, 270000, 276480, 0x9d082a81
-0, 277500, 276480, 0x4e6cd0c3
-0, 285000, 276480, 0xc129765f
-0, 292500, 276480, 0x92a04c99
-0, 300000, 276480, 0x5ca62953
-0, 307500, 276480, 0xb7e478aa
-0, 315000, 276480, 0x932735d5
-0, 322500, 276480, 0xaaa2d7aa
-0, 330000, 276480, 0xd1329996
-0, 337500, 276480, 0x6de1e34b
-0, 345000, 276480, 0x8c963c9b
-0, 352500, 276480, 0xce6eff29
-0, 360000, 276480, 0x25412f7e
-0, 367500, 276480, 0x11a5ad85
-0, 375000, 276480, 0x26ea3248
-0, 382500, 276480, 0x86c35fa4
-0, 390000, 276480, 0xa98a2d38
-0, 397500, 276480, 0xed827333
-0, 405000, 276480, 0x5d44a824
-0, 412500, 276480, 0x46d54d04
-0, 420000, 276480, 0x413fd26a
-0, 427500, 276480, 0xf0b3b71b
-0, 435000, 276480, 0x459bc06d
-0, 442500, 276480, 0x4199cd45
-0, 450000, 276480, 0xa8d35683
-0, 457500, 276480, 0x9a3e7de0
-0, 465000, 276480, 0x5a30f666
-0, 472500, 276480, 0x40152668
-0, 480000, 276480, 0x90c4d22c
-0, 487500, 276480, 0x5cbaacc9
-0, 495000, 276480, 0x72b658f1
-0, 502500, 276480, 0x0ba3dcc9
-0, 510000, 276480, 0x259ed5c1
-0, 517500, 276480, 0x7fd73a99
-0, 525000, 276480, 0x488980c5
-0, 532500, 276480, 0x1d4c96a5
-0, 540000, 276480, 0x41ced7f2
-0, 547500, 276480, 0xd62d1837
-0, 555000, 276480, 0xf5fd9d20
-0, 562500, 276480, 0x2af91fda
-0, 570000, 276480, 0x38ce229d
-0, 577500, 276480, 0xf3a712c0
-0, 585000, 276480, 0x57b111d2
-0, 592500, 276480, 0x8556b792
-0, 600000, 276480, 0xb32d0896
-0, 607500, 276480, 0x923b9937
-0, 615000, 276480, 0x0da1e7e3
-0, 622500, 276480, 0x7f172382
-0, 630000, 276480, 0x93622b88
-0, 637500, 276480, 0x2599d540
-0, 645000, 276480, 0xed20c105
-0, 652500, 276480, 0x62ce256e
-0, 660000, 276480, 0x286a04bb
-0, 667500, 276480, 0x423f7e7c
-0, 675000, 276480, 0x21fc252a
-0, 682500, 276480, 0xf8a8e8ee
-0, 690000, 276480, 0x770d4a8d
-0, 697500, 276480, 0xaa12b6fd
-0, 705000, 276480, 0xdc7221a8
-0, 712500, 276480, 0x487eeb30
-0, 720000, 276480, 0x1e74f2db
-0, 727500, 276480, 0x40ae2bc3
-0, 735000, 276480, 0x9ca9b930
-0, 742500, 276480, 0x9fb19b0f
-0, 750000, 276480, 0x7bdf836c
-0, 757500, 276480, 0x1e607ba7
-0, 765000, 276480, 0xbd96578b
-0, 772500, 276480, 0x2124bf07
-0, 780000, 276480, 0x4895e27a
-0, 787500, 276480, 0x694d76e3
-0, 795000, 276480, 0xe70df513
-0, 802500, 276480, 0xcacafe6b
-0, 810000, 276480, 0x64087748
-0, 817500, 276480, 0x571fda23
-0, 825000, 276480, 0x8c86cbe9
-0, 832500, 276480, 0xc8ea4671
-0, 840000, 276480, 0xbfb74300
-0, 847500, 276480, 0xbe1e3770
-0, 855000, 276480, 0x757a0232
-0, 862500, 276480, 0xa5f50c84
-0, 870000, 276480, 0x6d95f808
-0, 877500, 276480, 0xf002c5ca
-0, 885000, 276480, 0x1a2abb26
-0, 892500, 276480, 0x6cf69bf2
-0, 900000, 276480, 0x8f316c66
+0, 3754, 276480, 0x5f7a0d4f
+0, 7507, 276480, 0x5f7a0d4f
+0, 11261, 276480, 0x5f7a0d4f
+0, 15015, 276480, 0x5f7a0d4f
+0, 18769, 276480, 0x5f7a0d4f
+0, 22522, 276480, 0x5f7a0d4f
+0, 26276, 276480, 0x5f7a0d4f
+0, 30030, 276480, 0x5f7a0d4f
+0, 33784, 276480, 0x5f7a0d4f
+0, 37537, 276480, 0x5f7a0d4f
+0, 41291, 276480, 0x5f7a0d4f
+0, 45045, 276480, 0x5f7a0d4f
+0, 48799, 276480, 0x5f7a0d4f
+0, 52552, 276480, 0x5f7a0d4f
+0, 56306, 276480, 0x5f7a0d4f
+0, 60060, 276480, 0x5f7a0d4f
+0, 63814, 276480, 0x5f7a0d4f
+0, 67567, 276480, 0x5f7a0d4f
+0, 71321, 276480, 0x5f7a0d4f
+0, 75075, 276480, 0x5f7a0d4f
+0, 78829, 276480, 0x5f7a0d4f
+0, 82582, 276480, 0x5f7a0d4f
+0, 86336, 276480, 0x5f7a0d4f
+0, 90090, 276480, 0x5f7a0d4f
+0, 93844, 276480, 0x5f7a0d4f
+0, 97597, 276480, 0x5f7a0d4f
+0, 101351, 276480, 0x5f7a0d4f
+0, 105105, 276480, 0x5f7a0d4f
+0, 108859, 276480, 0x5f7a0d4f
+0, 112612, 276480, 0x5f7a0d4f
+0, 116366, 276480, 0x5f7a0d4f
+0, 120120, 276480, 0x5f7a0d4f
+0, 123874, 276480, 0x75641594
+0, 127627, 276480, 0x32ee3526
+0, 131381, 276480, 0xcb53479a
+0, 135135, 276480, 0x7ca9658e
+0, 138889, 276480, 0x5ce39368
+0, 142642, 276480, 0x4ec1e418
+0, 146396, 276480, 0xb3790499
+0, 150150, 276480, 0xa9f1506f
+0, 153904, 276480, 0x85cbc3b5
+0, 157657, 276480, 0x377c7b46
+0, 161411, 276480, 0x1a61d8db
+0, 165165, 276480, 0xe1de7f0a
+0, 168919, 276480, 0x756a4a2e
+0, 172672, 276480, 0xcb379547
+0, 176426, 276480, 0xbae14484
+0, 180180, 276480, 0x8e12331c
+0, 183934, 276480, 0x99c085be
+0, 187687, 276480, 0xe479ffed
+0, 191441, 276480, 0x99c82949
+0, 195195, 276480, 0xac7672dd
+0, 198949, 276480, 0x1e4fae19
+0, 202702, 276480, 0x776412ef
+0, 206456, 276480, 0x7d9b579f
+0, 210210, 276480, 0x1cd1ab29
+0, 213964, 276480, 0x58ce0f38
+0, 217717, 276480, 0x5ab69b27
+0, 221471, 276480, 0x0afad610
+0, 225225, 276480, 0x9eca3f11
+0, 228979, 276480, 0xc3db9706
+0, 232732, 276480, 0xc9c57884
+0, 236486, 276480, 0xd9fbb2cf
+0, 240240, 276480, 0xdc07f3c9
+0, 243994, 276480, 0x000b5269
+0, 247747, 276480, 0x27ff7a5d
+0, 251501, 276480, 0xd92e2017
+0, 255255, 276480, 0x18d4b27d
+0, 259009, 276480, 0x70647530
+0, 262762, 276480, 0x97612c4b
+0, 266516, 276480, 0xc9d4ac78
+0, 270270, 276480, 0x4ec4d57f
+0, 274024, 276480, 0xdf4e04d7
+0, 277777, 276480, 0xbd98f57c
+0, 281531, 276480, 0x7247ea3e
+0, 285285, 276480, 0xa5d670ec
+0, 289039, 276480, 0x5163b29b
+0, 292792, 276480, 0x99170e64
+0, 296546, 276480, 0x37f4c0b0
+0, 300300, 276480, 0x7a4f2561
+0, 304053, 276480, 0x8a4e991f
+0, 307807, 276480, 0x6a45425f
+0, 311561, 276480, 0x1f0e2bb6
+0, 315315, 276480, 0xd75482c6
+0, 319068, 276480, 0x7bf6b1ef
+0, 322822, 276480, 0x6de1e34b
+0, 326576, 276480, 0x4526c89b
+0, 330330, 276480, 0xf964e18e
+0, 334083, 276480, 0xdcaaa99a
+0, 337837, 276480, 0xd1e98808
+0, 341591, 276480, 0x556b2365
+0, 345345, 276480, 0x0cf65540
+0, 349098, 276480, 0x6e2d524e
+0, 352852, 276480, 0x22c50a3d
+0, 356606, 276480, 0x293f19af
+0, 360360, 276480, 0xf4b1c461
+0, 364113, 276480, 0x62b76407
+0, 367867, 276480, 0x51e9b3eb
+0, 371621, 276480, 0x7b910bc7
+0, 375375, 276480, 0x6dd14ca6
+0, 379128, 276480, 0x441f7afd
+0, 382882, 276480, 0xfb01efc6
+0, 386636, 276480, 0x4f73ccea
+0, 390390, 276480, 0x5ac8e06f
+0, 394143, 276480, 0x294bb441
+0, 397897, 276480, 0xe04ac45e
+0, 401651, 276480, 0xa7a38d41
+0, 405405, 276480, 0xf688a3ed
+0, 409158, 276480, 0x58f275ea
+0, 412912, 276480, 0xf0b3b71b
+0, 416666, 276480, 0x3ce773bf
+0, 420420, 276480, 0x01840548
+0, 424173, 276480, 0x674e34e4
+0, 427927, 276480, 0x41dda2d9
+0, 431681, 276480, 0xc5b60838
+0, 435435, 276480, 0x9b209f41
+0, 439188, 276480, 0xf46ba7fb
+0, 442942, 276480, 0x28b54815
+0, 446696, 276480, 0xb605a933
+0, 450450, 276480, 0x34484aff
+0, 454203, 276480, 0xaf2b5d89
+0, 457957, 276480, 0x8facba58
+0, 461711, 276480, 0xbbe3e99f
+0, 465465, 276480, 0x02162c7c
+0, 469218, 276480, 0x28a63236
+0, 472972, 276480, 0x1ad43fd7
+0, 476726, 276480, 0xe37883e5
+0, 480480, 276480, 0x2b8a89c5
+0, 484233, 276480, 0x71507bd2
+0, 487987, 276480, 0x35626022
+0, 491741, 276480, 0x461fc3e7
+0, 495495, 276480, 0xce5af1ec
+0, 499248, 276480, 0x7c1139b3
+0, 503002, 276480, 0x7fd73a99
+0, 506756, 276480, 0x4ae4c3a6
+0, 510510, 276480, 0xcb60725a
+0, 514263, 276480, 0xb52e1aa2
+0, 518017, 276480, 0xd6f82cae
+0, 521771, 276480, 0x6310e665
+0, 525525, 276480, 0xfa88a483
+0, 529278, 276480, 0xf88f75d4
+0, 533032, 276480, 0x04a8e3ee
+0, 536786, 276480, 0x54766a12
+0, 540540, 276480, 0x0b41f0d7
+0, 544293, 276480, 0xa29f5b01
+0, 548047, 276480, 0x754ceaf5
+0, 551801, 276480, 0x150c0423
+0, 555555, 276480, 0xde084059
+0, 559308, 276480, 0x5a38b4af
+0, 563062, 276480, 0xfcebc261
+0, 566816, 276480, 0x0eb9770d
+0, 570570, 276480, 0x046394ae
+0, 574323, 276480, 0x3d3ca985
+0, 578077, 276480, 0x94a03c75
+0, 581831, 276480, 0x800eea2d
+0, 585585, 276480, 0x6a841f41
+0, 589338, 276480, 0x2f98911c
+0, 593092, 276480, 0x923b9937
+0, 596846, 276480, 0xe82f8e0f
+0, 600600, 276480, 0xee82d657
+0, 604353, 276480, 0xefab7ffd
+0, 608107, 276480, 0x6b9fbc80
+0, 611861, 276480, 0x4a1ada47
+0, 615614, 276480, 0x6d4b49d7
+0, 619368, 276480, 0xe4bdbd1e
+0, 623122, 276480, 0x225a56c0
+0, 626876, 276480, 0xd4adadad
+0, 630629, 276480, 0xff4e1a8c
+0, 634383, 276480, 0xf58b1b7c
+0, 638137, 276480, 0xbaffcdcc
+0, 641891, 276480, 0x374f88f0
+0, 645644, 276480, 0x3d861ae6
+0, 649398, 276480, 0xeb6eb88f
+0, 653152, 276480, 0xdb753d35
+0, 656906, 276480, 0x9aa543af
+0, 660659, 276480, 0xb24c8016
+0, 664413, 276480, 0xea80a82e
+0, 668167, 276480, 0x2aae902a
+0, 671921, 276480, 0x5bba3cfb
+0, 675674, 276480, 0x5c6e97a9
+0, 679428, 276480, 0x9b9ee961
+0, 683182, 276480, 0xaa12b6fd
+0, 686936, 276480, 0xe9d2439f
+0, 690689, 276480, 0xbf09053c
+0, 694443, 276480, 0x50c31e73
+0, 698197, 276480, 0xdd9fb89f
+0, 701951, 276480, 0x3e4e5aec
+0, 705704, 276480, 0x0b752d28
+0, 709458, 276480, 0xaf82399a
+0, 713212, 276480, 0x7ce5f23c
+0, 716966, 276480, 0xad135d0f
+0, 720719, 276480, 0x55dadd30
+0, 724473, 276480, 0x5aaa7519
+0, 728227, 276480, 0xe45a5599
+0, 731981, 276480, 0xc8e89913
+0, 735734, 276480, 0x2f447fd3
+0, 739488, 276480, 0x704411fb
+0, 743242, 276480, 0x9d7430a1
+0, 746996, 276480, 0x24dd5fd3
+0, 750749, 276480, 0x51cb657c
+0, 754503, 276480, 0x2c230702
+0, 758257, 276480, 0x4a4f76cd
+0, 762011, 276480, 0xdcd71e88
+0, 765764, 276480, 0x87160f99
+0, 769518, 276480, 0x27f54854
+0, 773272, 276480, 0x694d76e3
+0, 777026, 276480, 0xcbe93c19
+0, 780779, 276480, 0x50742e1b
+0, 784533, 276480, 0x525463e2
+0, 788287, 276480, 0x819898f9
+0, 792041, 276480, 0x08fac755
+0, 795794, 276480, 0x35c46927
+0, 799548, 276480, 0xeeed00fc
+0, 803302, 276480, 0xb6f99ee3
+0, 807056, 276480, 0xd87f4c73
+0, 810809, 276480, 0xde97d9fd
+0, 814563, 276480, 0xefc83107
+0, 818317, 276480, 0xbb22e024
+0, 822071, 276480, 0x53a7cfcb
+0, 825824, 276480, 0xbe1fbb19
+0, 829578, 276480, 0x300f922a
+0, 833332, 276480, 0x826fc3bd
+0, 837086, 276480, 0x679aa57a
+0, 840839, 276480, 0x5497097b
+0, 844593, 276480, 0x679a53f8
+0, 848347, 276480, 0x976c9e93
+0, 852101, 276480, 0xe80f87f2
+0, 855854, 276480, 0xdc2d7c6c
+0, 859608, 276480, 0xb194656e
+0, 863362, 276480, 0xf002c5ca
+0, 867116, 276480, 0x43fc1c64
+0, 870869, 276480, 0xf62d8581
+0, 874623, 276480, 0xb243dda5
+0, 878377, 276480, 0x1700efbb
+0, 882131, 276480, 0x9ebe6ba2
+0, 885884, 276480, 0x8f316c66
+0, 889638, 276480, 0x6348ecf5
+0, 893392, 276480, 0x34b5b78a
+0, 897146, 276480, 0xcbf66922
diff --git a/tests/ref/fate/rv30 b/tests/ref/fate/rv30
index 5b43588..a3c5dcf 100644
--- a/tests/ref/fate/rv30
+++ b/tests/ref/fate/rv30
@@ -1,46 +1,109 @@
0, 0, 126720, 0xcefaec47
-0, 7500, 126720, 0xa416ece5
-0, 15000, 126720, 0xa416ece5
-0, 22500, 126720, 0xa416ece5
-0, 30000, 126720, 0xcc10f4b7
-0, 37500, 126720, 0xeb6fb8d7
-0, 45000, 126720, 0xda71b917
-0, 52500, 126720, 0xbb1abbb7
-0, 60000, 126720, 0x273fbc37
-0, 67500, 126720, 0x16eebbd7
-0, 75000, 126720, 0x105eb927
-0, 82500, 126720, 0x7fa3ae27
-0, 90000, 126720, 0xd115a757
-0, 97500, 126720, 0x04e7897c
-0, 105000, 126720, 0x68cfda2b
-0, 112500, 126720, 0xe572dfc9
-0, 120000, 126720, 0xbc3cc34f
-0, 127500, 126720, 0xcf8cb0e2
-0, 135000, 126720, 0x6d1c630d
-0, 142500, 126720, 0x4338e469
-0, 150000, 126720, 0x9d82ea38
-0, 157500, 126720, 0x55e0b559
-0, 165000, 126720, 0x5eefb5ef
-0, 172500, 126720, 0x4b10b746
-0, 180000, 126720, 0x8b07a1db
-0, 187500, 126720, 0x8c639b34
-0, 195000, 126720, 0x63eb0b9f
-0, 202500, 126720, 0x31c80c83
-0, 210000, 126720, 0x78495352
-0, 217500, 126720, 0x63d609c4
-0, 225000, 126720, 0xcd2a62d8
-0, 232500, 126720, 0x4aea732d
-0, 240000, 126720, 0xe3bb352c
-0, 247500, 126720, 0x4b9036ad
-0, 255000, 126720, 0x88b66e2d
-0, 262500, 126720, 0x4a8a1b16
-0, 270000, 126720, 0x2e014eac
-0, 277500, 126720, 0x83212c67
-0, 285000, 126720, 0x4937e897
-0, 292500, 126720, 0x2d38babe
-0, 300000, 126720, 0xbcb43c09
-0, 307500, 126720, 0x955ffaf4
-0, 315000, 126720, 0x3337d4a2
-0, 322500, 126720, 0xe8f58c33
-0, 330000, 126720, 0x3a7f771f
-0, 337500, 126720, 0xb67c39b9
+0, 3003, 126720, 0xa416ece5
+0, 6006, 126720, 0xa416ece5
+0, 9009, 126720, 0xa416ece5
+0, 12012, 126720, 0x60d6ed27
+0, 15015, 126720, 0x259af497
+0, 18018, 126720, 0x5e6ff4d7
+0, 21021, 126720, 0xcc10f4b7
+0, 24024, 126720, 0x763ab817
+0, 27027, 126720, 0xeb6fb8d7
+0, 30030, 126720, 0xda71b917
+0, 33033, 126720, 0x0967b8f7
+0, 36036, 126720, 0x4b62b947
+0, 39039, 126720, 0xbb1abbb7
+0, 42042, 126720, 0x273fbc37
+0, 45045, 126720, 0x16eebbd7
+0, 48048, 126720, 0x105eb927
+0, 51051, 126720, 0x7fa3ae27
+0, 54054, 126720, 0x722e99f7
+0, 57057, 126720, 0x5ac9a827
+0, 60060, 126720, 0x07beba77
+0, 63063, 126720, 0x29d6a887
+0, 66066, 126720, 0xa5caab87
+0, 69069, 126720, 0x9ca7aac7
+0, 72072, 126720, 0xb7debcd7
+0, 75075, 126720, 0xd115a757
+0, 78078, 126720, 0x6ddaef32
+0, 81081, 126720, 0xde1bb900
+0, 84084, 126720, 0xac6c071b
+0, 87087, 126720, 0x04e7897c
+0, 90090, 126720, 0x5eee050f
+0, 93093, 126720, 0xe675be59
+0, 96096, 126720, 0xdc3e0837
+0, 99099, 126720, 0x68cfda2b
+0, 102102, 126720, 0xe572dfc9
+0, 105105, 126720, 0x582fb176
+0, 108108, 126720, 0xa9477df0
+0, 111111, 126720, 0xbc3cc34f
+0, 114114, 126720, 0xcf8cb0e2
+0, 117117, 126720, 0xcff1db35
+0, 120120, 126720, 0xc6e10f9f
+0, 123123, 126720, 0x75ae61b6
+0, 126126, 126720, 0x12af3119
+0, 129129, 126720, 0x85597543
+0, 132132, 126720, 0x68c27aca
+0, 135135, 126720, 0x554fe3e4
+0, 138138, 126720, 0x72ecea95
+0, 141141, 126720, 0xf4d003d1
+0, 144144, 126720, 0x9bf6a605
+0, 147147, 126720, 0x5d00b5fe
+0, 150150, 126720, 0x93f7b040
+0, 153153, 126720, 0x0d6ad154
+0, 156156, 126720, 0x4be8b4ea
+0, 159159, 126720, 0xe39bba0d
+0, 162162, 126720, 0x9c21bad8
+0, 165165, 126720, 0xa567f25b
+0, 168168, 126720, 0x7a82663a
+0, 171171, 126720, 0x72f2a47d
+0, 174174, 126720, 0x4f639ebe
+0, 177177, 126720, 0xab0fce83
+0, 180180, 126720, 0x6cf87d39
+0, 183183, 126720, 0x534a10cc
+0, 186186, 126720, 0x6bbcf44c
+0, 189189, 126720, 0xfdca11d3
+0, 192192, 126720, 0x7e58f5a6
+0, 195195, 126720, 0x5fd753d8
+0, 198198, 126720, 0x0c735615
+0, 201201, 126720, 0x2a034ebf
+0, 204204, 126720, 0xeaf3dd0b
+0, 207207, 126720, 0x0eaf0c1b
+0, 210210, 126720, 0xce5e6794
+0, 213213, 126720, 0xf27c31c3
+0, 216216, 126720, 0xb64af168
+0, 219219, 126720, 0x14cf7974
+0, 222222, 126720, 0x1c2a513d
+0, 225225, 126720, 0xa3f515ab
+0, 228228, 126720, 0xcfd62765
+0, 231231, 126720, 0xbc513f2a
+0, 234234, 126720, 0xbc303fae
+0, 237237, 126720, 0x2f8f69b9
+0, 240240, 126720, 0x0a22cc69
+0, 243243, 126720, 0xd9f67585
+0, 246246, 126720, 0x20403001
+0, 249249, 126720, 0xf92b2a25
+0, 252252, 126720, 0x3c170aad
+0, 255255, 126720, 0x3378251f
+0, 258258, 126720, 0xb3ed5911
+0, 261261, 126720, 0x35d24ef8
+0, 264264, 126720, 0x8da30275
+0, 267267, 126720, 0xc15a3577
+0, 270270, 126720, 0xf2942f53
+0, 273273, 126720, 0x44d8304a
+0, 276276, 126720, 0xd688a932
+0, 279279, 126720, 0x0a24f256
+0, 282282, 126720, 0xfab9c45d
+0, 285285, 126720, 0x10e939ce
+0, 288288, 126720, 0x97fcaa3a
+0, 291291, 126720, 0x45464610
+0, 294294, 126720, 0xfe2e057d
+0, 297297, 126720, 0x0b6718ae
+0, 300300, 126720, 0x5284da7b
+0, 303303, 126720, 0x23efdc35
+0, 306306, 126720, 0xc387b2b3
+0, 309309, 126720, 0xc9e92bf1
+0, 312312, 126720, 0xfbf20a01
+0, 315315, 126720, 0x4d888b2e
+0, 318318, 126720, 0xdd0d74df
+0, 321321, 126720, 0x49d07aa4
+0, 324324, 126720, 0x08382b8e
diff --git a/tests/ref/fate/tiertex-seq b/tests/ref/fate/tiertex-seq
index 6aa7fc7..24819eb 100644
--- a/tests/ref/fate/tiertex-seq
+++ b/tests/ref/fate/tiertex-seq
@@ -2,145 +2,94 @@
1, 0, 1764, 0x00000000
0, 3600, 98304, 0xb20c19d0
1, 3600, 1764, 0x80a253d9
-0, 7200, 98304, 0xb20c19d0
+0, 7200, 98304, 0x6b8538c0
1, 7200, 1764, 0x95a16721
-0, 10800, 98304, 0xb20c19d0
+0, 10800, 98304, 0x172207e3
1, 10800, 1764, 0x0f0d4cb6
-0, 14400, 98304, 0x6b8538c0
+0, 14400, 98304, 0x63fb7dc1
1, 14400, 1764, 0x75026779
-0, 18000, 98304, 0x6b8538c0
+0, 18000, 98304, 0x37cf1601
1, 18000, 1764, 0xb4356e37
-0, 21600, 98304, 0x6b8538c0
+0, 21600, 98304, 0x82941990
1, 21600, 1764, 0xfafa64cb
-0, 25200, 98304, 0x172207e3
+0, 25200, 98304, 0xe0a5309e
1, 25200, 1764, 0xe8fd7970
-0, 28800, 98304, 0x172207e3
+0, 28800, 98304, 0x164cb67d
1, 28800, 1764, 0x666879b7
-0, 32400, 98304, 0x172207e3
+0, 32400, 98304, 0xed2189f8
1, 32400, 1764, 0xf2cd7770
-0, 36000, 98304, 0x172207e3
+0, 36000, 98304, 0x7215e529
1, 36000, 1764, 0x54317a1c
-0, 39600, 98304, 0x63fb7dc1
+0, 39600, 98304, 0x170c783b
1, 39600, 1764, 0x9c396930
-0, 43200, 98304, 0x63fb7dc1
+0, 43200, 98304, 0xf6bd74c7
1, 43200, 1764, 0x87115ec4
-0, 46800, 98304, 0x63fb7dc1
+0, 46800, 98304, 0x1efd38c4
1, 46800, 1764, 0x0c9b69b6
-0, 50400, 98304, 0x37cf1601
+0, 50400, 98304, 0x29c26bba
1, 50400, 1764, 0x8c3a758a
-0, 54000, 98304, 0x37cf1601
+0, 54000, 98304, 0x880a6313
1, 54000, 1764, 0x605d776a
-0, 57600, 98304, 0x37cf1601
+0, 57600, 98304, 0x73f5bb00
1, 57600, 1764, 0x0556852d
-0, 61200, 98304, 0x37cf1601
+0, 61200, 98304, 0xc85b19ec
1, 61200, 1764, 0x7d4363f8
-0, 64800, 98304, 0x82941990
+0, 64800, 98304, 0x00000000
1, 64800, 1764, 0xc5cd75d0
-0, 68400, 98304, 0x82941990
+0, 68400, 98304, 0x00000000
1, 68400, 1764, 0x3ff3646d
-0, 72000, 98304, 0x82941990
+0, 72000, 98304, 0x00000000
1, 72000, 1764, 0x10136d25
-0, 75600, 98304, 0x82941990
1, 75600, 1764, 0xeb1a6cd0
-0, 79200, 98304, 0xe0a5309e
1, 79200, 1764, 0xef937ed1
-0, 82800, 98304, 0xe0a5309e
1, 82800, 1764, 0x2d2b6f79
-0, 86400, 98304, 0xe0a5309e
1, 86400, 1764, 0x6f457231
-0, 90000, 98304, 0x164cb67d
1, 90000, 1764, 0x56267c9d
-0, 93600, 98304, 0x164cb67d
1, 93600, 1764, 0xd49e79c8
-0, 97200, 98304, 0x164cb67d
1, 97200, 1764, 0xc726703d
-0, 100800, 98304, 0x164cb67d
1, 100800, 1764, 0x2abf8074
-0, 104400, 98304, 0xed2189f8
1, 104400, 1764, 0xb50c556d
-0, 108000, 98304, 0xed2189f8
1, 108000, 1764, 0xc1f2523c
-0, 111600, 98304, 0xed2189f8
1, 111600, 1764, 0x850a6f93
-0, 115200, 98304, 0x7215e529
1, 115200, 1764, 0x8da76c31
-0, 118800, 98304, 0x7215e529
1, 118800, 1764, 0xfcccdf13
-0, 122400, 98304, 0x7215e529
1, 122400, 1764, 0x00000000
-0, 126000, 98304, 0x7215e529
1, 126000, 1764, 0x00000000
-0, 129600, 98304, 0x170c783b
1, 129600, 1764, 0x00000000
-0, 133200, 98304, 0x170c783b
1, 133200, 1764, 0x00000000
-0, 136800, 98304, 0x170c783b
1, 136800, 1764, 0x00000000
-0, 140400, 98304, 0xf6bd74c7
1, 140400, 1764, 0x00000000
-0, 144000, 98304, 0xf6bd74c7
1, 144000, 1764, 0x00000000
-0, 147600, 98304, 0xf6bd74c7
1, 147600, 1764, 0x00000000
-0, 151200, 98304, 0xf6bd74c7
1, 151200, 1764, 0x00000000
-0, 154800, 98304, 0x1efd38c4
1, 154800, 1764, 0x00000000
-0, 158400, 98304, 0x1efd38c4
1, 158400, 1764, 0x00000000
-0, 162000, 98304, 0x1efd38c4
1, 162000, 1764, 0x00000000
-0, 165600, 98304, 0x1efd38c4
1, 165600, 1764, 0x00000000
-0, 169200, 98304, 0x29c26bba
1, 169200, 1764, 0x00000000
-0, 172800, 98304, 0x29c26bba
1, 172800, 1764, 0x00000000
-0, 176400, 98304, 0x29c26bba
1, 176400, 1764, 0x00000000
-0, 180000, 98304, 0x880a6313
1, 180000, 1764, 0x00000000
-0, 183600, 98304, 0x880a6313
1, 183600, 1764, 0x00000000
-0, 187200, 98304, 0x880a6313
1, 187200, 1764, 0x00000000
-0, 190800, 98304, 0x880a6313
1, 190800, 1764, 0x00000000
-0, 194400, 98304, 0x73f5bb00
1, 194400, 1764, 0x00000000
-0, 198000, 98304, 0x73f5bb00
1, 198000, 1764, 0x00000000
-0, 201600, 98304, 0x73f5bb00
1, 201600, 1764, 0x00000000
-0, 205200, 98304, 0xc85b19ec
1, 205200, 1764, 0x00000000
-0, 208800, 98304, 0xc85b19ec
1, 208800, 1764, 0x00000000
-0, 212400, 98304, 0xc85b19ec
1, 212400, 1764, 0x00000000
-0, 216000, 98304, 0xc85b19ec
1, 216000, 1764, 0x00000000
-0, 219600, 98304, 0x00000000
1, 219600, 1764, 0x00000000
-0, 223200, 98304, 0x00000000
1, 223200, 1764, 0x00000000
-0, 226800, 98304, 0x00000000
1, 226800, 1764, 0x00000000
-0, 230400, 98304, 0x00000000
1, 230400, 1764, 0x00000000
-0, 234000, 98304, 0x00000000
1, 234000, 1764, 0x00000000
-0, 237600, 98304, 0x00000000
1, 237600, 1764, 0x00000000
-0, 241200, 98304, 0x00000000
1, 241200, 1764, 0x00000000
-0, 244800, 98304, 0x00000000
1, 244800, 1764, 0x00000000
-0, 248400, 98304, 0x00000000
1, 248400, 1764, 0x00000000
-0, 252000, 98304, 0x00000000
1, 252000, 1764, 0x00000000
-0, 255600, 98304, 0x00000000
1, 255600, 1764, 0x00000000
1, 259200, 1764, 0x00000000
1, 262800, 1764, 0x00000000
diff --git a/tests/ref/fate/truemotion1-15 b/tests/ref/fate/truemotion1-15
index d103f01..d9925c7 100644
--- a/tests/ref/fate/truemotion1-15
+++ b/tests/ref/fate/truemotion1-15
@@ -1,218 +1,218 @@
0, 0, 161280, 0x7041748d
-1, 0, 10832, 0xe1a811fa
-1, 5527, 10832, 0xb47841f9
+1, 0, 10836, 0x2a531236
+1, 5529, 10836, 0xc58f45af
0, 6000, 161280, 0x3cc4dfb5
-1, 11053, 10832, 0x839eedf1
+1, 11057, 10836, 0x436cf135
0, 12000, 161280, 0xca3af22d
-1, 16580, 10832, 0xb48b1f60
+1, 16586, 10836, 0x3a6022cc
0, 18000, 161280, 0x23ad1d85
-1, 22106, 10832, 0x743936c0
+1, 22114, 10836, 0x57e83a4a
0, 24000, 161280, 0x9c9cf364
-1, 27633, 10832, 0xe1f039fb
+1, 27643, 10836, 0xca4b3a1b
0, 30000, 161280, 0x1551d6a8
-1, 33159, 10832, 0xef00751a
+1, 33171, 10836, 0xc3da7536
0, 36000, 161280, 0xc39f6b95
-1, 38686, 10832, 0x401ed099
+1, 38700, 10836, 0x8c57d47b
0, 42000, 161280, 0x3b036dcc
-1, 44212, 10832, 0x432a53bd
+1, 44229, 10836, 0x9a79572b
0, 48000, 161280, 0xa6fac1db
-1, 49739, 10832, 0xc4276bfd
+1, 49757, 10836, 0x7dbd6fd3
0, 54000, 161280, 0x67656b62
-1, 55265, 10832, 0x51f0fa8c
+1, 55286, 10836, 0x4454fdde
0, 60000, 161280, 0xb41f47d1
-1, 60792, 10832, 0xcebae622
+1, 60814, 10836, 0x68aae686
0, 66000, 161280, 0xc207249e
-1, 66318, 10832, 0xe9f6dc1f
-1, 71845, 10832, 0xda087fee
+1, 66343, 10836, 0x61f2df35
+1, 71871, 10836, 0xe36883c6
0, 72000, 161280, 0xbee8f843
-1, 77371, 10832, 0x67a621bb
+1, 77400, 10836, 0xefa62217
0, 78000, 161280, 0x092acf46
-1, 82898, 10832, 0xd7be207f
+1, 82929, 10836, 0x63b92479
0, 84000, 161280, 0x8d9e2680
-1, 88424, 10832, 0x19d32507
+1, 88457, 10836, 0xaf452579
0, 90000, 161280, 0x8becc20c
-1, 93951, 10832, 0xe1a3fbfa
+1, 93986, 10836, 0xdbb10001
0, 96000, 161280, 0x655e444e
-1, 99478, 10832, 0xd10df779
+1, 99514, 10836, 0xafb7f7a7
0, 102000, 161280, 0x5c112da0
-1, 105004, 10832, 0x4428e1a7
+1, 105043, 10836, 0xd4b1e591
0, 108000, 161280, 0x232fa9eb
-1, 110531, 10832, 0x7ea9b33d
+1, 110571, 10836, 0x4d44b3bb
0, 114000, 161280, 0x9721745d
-1, 116057, 10832, 0x6852a5a5
+1, 116100, 10836, 0xff2ea5b3
0, 120000, 161280, 0x92f1d880
-1, 121584, 10832, 0xfeb78863
+1, 121629, 10836, 0x214e88ad
0, 126000, 161280, 0x16233978
-1, 127110, 10832, 0xf157f928
+1, 127157, 10836, 0xde8bfc9a
0, 132000, 161280, 0x19a27e69
-1, 132637, 10832, 0x86414b3e
+1, 132686, 10836, 0xb3cc4b6a
0, 138000, 161280, 0x7b6ad73a
-1, 138163, 10832, 0x2e28cdf6
-1, 143690, 10832, 0x00212e44
+1, 138214, 10836, 0x670bce40
+1, 143743, 10836, 0xc17d31b2
0, 144000, 161280, 0xa7a674aa
-1, 149216, 10832, 0x2d7f9378
+1, 149271, 10836, 0x7bcb9392
0, 150000, 161280, 0x4e434abb
-1, 154743, 10832, 0x84cb25d7
+1, 154800, 10836, 0x230e28c9
0, 156000, 161280, 0xb96eea14
-1, 160269, 10832, 0x3aca41fa
+1, 160329, 10836, 0x42df4204
0, 162000, 161280, 0x1350188c
-1, 165796, 10832, 0x27ad34b9
+1, 165857, 10836, 0xfa9134b9
0, 168000, 161280, 0x79c6f305
-1, 171322, 10832, 0xe665144a
+1, 171386, 10836, 0x418c1844
0, 174000, 161280, 0xa9c7782d
-1, 176849, 10832, 0xf9546626
+1, 176914, 10836, 0x93ba66b6
0, 180000, 161280, 0x40a4f456
-1, 182376, 10832, 0xe71c4f22
+1, 182443, 10836, 0x264a4ffa
0, 186000, 161280, 0xaf291ed6
-1, 187902, 10832, 0x5e61869c
+1, 187971, 10836, 0x82c78a8e
0, 192000, 161280, 0xab29b4e1
-1, 193429, 10832, 0x571d2c10
+1, 193500, 10836, 0x10d22fdc
0, 198000, 161280, 0xbfcd2712
-1, 198955, 10832, 0xf0e08cd5
+1, 199029, 10836, 0x2d25906b
0, 204000, 161280, 0xff22a0d7
-1, 204482, 10832, 0x66650e49
+1, 204557, 10836, 0xa8a111fb
0, 210000, 161280, 0xb0ae88a9
-1, 210008, 10832, 0x4024deaf
-1, 215535, 10832, 0xda7bdb14
+1, 210086, 10836, 0xbd95df87
+1, 215614, 10836, 0x500ddec0
0, 216000, 161280, 0x811d1259
-1, 221061, 10832, 0xc27a342f
+1, 221143, 10836, 0x95d9350b
0, 222000, 161280, 0x593c39a1
-1, 226588, 10832, 0x574fe679
+1, 226671, 10836, 0xfa54ea1f
0, 228000, 161280, 0x5a5a97f8
-1, 232114, 10832, 0x37db464e
+1, 232200, 10836, 0x51b2467e
0, 234000, 161280, 0xa5639ecf
-1, 237641, 10832, 0xb1fa2a83
+1, 237729, 10836, 0x5d772af9
0, 240000, 161280, 0x543920c6
-1, 243167, 10832, 0x3d98d9b7
+1, 243257, 10836, 0xae25dd8d
0, 246000, 161280, 0xb41689ee
-1, 248694, 10832, 0xb7c908e2
+1, 248786, 10836, 0xe4bd0cb0
0, 252000, 161280, 0xc0ad83de
-1, 254220, 10832, 0x9f7e44d8
+1, 254314, 10836, 0xb33544f0
0, 258000, 161280, 0x9e9e7456
-1, 259747, 10832, 0xae9b8774
+1, 259843, 10836, 0xd5658b12
0, 264000, 161280, 0x777ccbfe
-1, 265273, 10832, 0x36916e3f
+1, 265371, 10836, 0xeff66e5d
0, 270000, 161280, 0x9c2df916
-1, 270800, 10832, 0xd785f5ef
+1, 270900, 10836, 0xb1fff6c5
0, 276000, 161280, 0xe0c13b35
-1, 276327, 10832, 0x2a3a5673
-1, 281853, 10832, 0x7320e379
+1, 276429, 10836, 0x84db56b5
+1, 281957, 10836, 0x0230e3c9
0, 282000, 161280, 0x39bfa5a5
-1, 287380, 10832, 0xec787be5
+1, 287486, 10836, 0xe58a7faf
0, 288000, 161280, 0x35dfb264
-1, 292906, 10832, 0xd0d13aa0
+1, 293014, 10836, 0xc4003e2a
0, 294000, 161280, 0x43018613
-1, 298433, 10832, 0x34dfcb17
+1, 298543, 10836, 0x6360cbbf
0, 300000, 161280, 0x43584b8a
-1, 303959, 10832, 0x1a9c29f1
+1, 304071, 10836, 0xc29c2a05
0, 306000, 161280, 0xa5cd230a
-1, 309486, 10832, 0x3e73dcc1
+1, 309600, 10836, 0xb294dd11
0, 312000, 161280, 0x6fe2cfb3
-1, 315012, 10832, 0x7855b053
+1, 315129, 10836, 0x4388b43b
0, 318000, 161280, 0x88a7c0db
-1, 320539, 10832, 0x5588df8f
+1, 320657, 10836, 0xdd7be367
0, 324000, 161280, 0x476f1cd2
-1, 326065, 10832, 0x6f621299
+1, 326186, 10836, 0xb9f612a9
0, 330000, 161280, 0x96401d49
-1, 331592, 10832, 0xce7f39c2
+1, 331714, 10836, 0xb64a39fe
0, 336000, 161280, 0x7d932919
-1, 337118, 10832, 0xd88e6552
+1, 337243, 10836, 0x6eba6594
0, 342000, 161280, 0x06465481
-1, 342645, 10832, 0xddc63597
+1, 342771, 10836, 0xb4af35c1
0, 348000, 161280, 0x39631520
-1, 348171, 10832, 0xe3071865
-1, 353698, 10832, 0x2a44a123
+1, 348300, 10836, 0x4e581c49
+1, 353829, 10836, 0xb062a19f
0, 354000, 161280, 0xc3fff780
-1, 359224, 10832, 0x08d85d45
+1, 359357, 10836, 0x87cd6135
0, 360000, 161280, 0xa81faf28
-1, 364751, 10832, 0x4dc5f83a
+1, 364886, 10836, 0x37bffbd6
0, 366000, 161280, 0x7a311f4f
-1, 370278, 10832, 0x89497812
+1, 370414, 10836, 0x6c797900
0, 372000, 161280, 0x52f9b931
-1, 375804, 10832, 0x9ee1db54
+1, 375943, 10836, 0x1615df36
0, 378000, 161280, 0x938cf016
-1, 381331, 10832, 0x5277d611
+1, 381471, 10836, 0xb472d9e9
0, 384000, 161280, 0xf8f6e19c
-1, 386857, 10832, 0x570a619c
+1, 387000, 10836, 0xdfff626e
0, 390000, 161280, 0xca90561b
-1, 392384, 10832, 0xa217d70f
+1, 392529, 10836, 0xffa6d771
0, 396000, 161280, 0x8594d06b
-1, 397910, 10832, 0x6f0ecbf4
+1, 398057, 10836, 0xa7f3cf96
0, 402000, 161280, 0xea32bf3b
-1, 403437, 10832, 0x2704b114
+1, 403586, 10836, 0xf556b50a
0, 408000, 161280, 0x4646111a
-1, 408963, 10832, 0xf24e679f
+1, 409114, 10836, 0x99b86b39
0, 414000, 161280, 0xee891162
-1, 414490, 10832, 0x05572099
+1, 414643, 10836, 0x886920d3
0, 420000, 161280, 0xcfc32082
-1, 420016, 10832, 0x33942d0c
-1, 425543, 10832, 0xa77ea674
+1, 420171, 10836, 0xefb0305a
+1, 425700, 10836, 0x4ab7aa32
0, 426000, 161280, 0x863c281a
-1, 431069, 10832, 0xeba663bc
+1, 431229, 10836, 0x7f106530
0, 432000, 161280, 0x01b591aa
-1, 436596, 10832, 0x1338524a
+1, 436757, 10836, 0x6461559a
0, 438000, 161280, 0x211fbc62
-1, 442122, 10832, 0x6182b0b3
+1, 442286, 10836, 0x25e3b12b
0, 444000, 161280, 0xae2bafe2
-1, 447649, 10832, 0xa410a364
+1, 447814, 10836, 0x32cfa3ba
0, 450000, 161280, 0xcfe46dca
-1, 453176, 10832, 0x2f4374b0
+1, 453343, 10836, 0x0bff78a4
0, 456000, 161280, 0xcf8fe8a3
-1, 458702, 10832, 0xf41f3a07
+1, 458871, 10836, 0xe4323d53
0, 462000, 161280, 0x3f8474eb
-1, 464229, 10832, 0x2b1c50c6
+1, 464400, 10836, 0x70b35196
0, 468000, 161280, 0x06da345a
-1, 469755, 10832, 0x3692ac89
+1, 469929, 10836, 0xf2b8b07f
0, 474000, 161280, 0xbd4d3280
-1, 475282, 10832, 0x5d6bc87e
+1, 475457, 10836, 0x826cc972
0, 480000, 161280, 0xb5e70fea
-1, 480808, 10832, 0x1b1cda0c
+1, 480986, 10836, 0x8a0fdce8
0, 486000, 161280, 0x0c99c804
-1, 486335, 10832, 0x11eaa15f
-1, 491861, 10832, 0x73c7d7ef
+1, 486514, 10836, 0xa072a503
0, 492000, 161280, 0x19841ed4
-1, 497388, 10832, 0x65d7e3be
+1, 492043, 10836, 0xd698d8e7
+1, 497571, 10836, 0xfe80e794
0, 498000, 161280, 0xf81dea50
-1, 502914, 10832, 0xb9c00688
+1, 503100, 10836, 0xdd580a5a
0, 504000, 161280, 0x7777d81c
-1, 508441, 10832, 0x0b98c125
+1, 508629, 10836, 0x121bc1bb
0, 510000, 161280, 0x0497cfd8
-1, 513967, 10832, 0x331ed413
+1, 514157, 10836, 0x8cebd7d9
0, 516000, 161280, 0x50b6eb64
-1, 519494, 10832, 0x9b68f485
+1, 519686, 10836, 0x6eaef4d7
0, 522000, 161280, 0x5071fc07
-1, 525020, 10832, 0x1b865c55
+1, 525214, 10836, 0x8f0b5d0b
0, 528000, 161280, 0xbb7527fb
-1, 530547, 10832, 0x68cef565
+1, 530743, 10836, 0x40ccf61f
0, 534000, 161280, 0x13054f1f
-1, 536073, 10832, 0x3a605f15
+1, 536271, 10836, 0xb6db5f1d
0, 540000, 161280, 0x4b78fb27
-1, 541600, 10832, 0xd72ff22e
+1, 541800, 10836, 0xa089f250
0, 546000, 161280, 0xf504968f
-1, 547127, 10832, 0x1c672b67
+1, 547329, 10836, 0xd3512f2b
0, 552000, 161280, 0x555b10b7
-1, 552653, 10832, 0xfd1a7e7e
+1, 552857, 10836, 0xfa127f74
0, 558000, 161280, 0xcc0dde40
-1, 558180, 10832, 0x9bf20ead
-1, 563706, 10832, 0x00000000
+1, 558386, 10836, 0xd6a60ead
+1, 563914, 10836, 0x00000000
0, 564000, 161280, 0xcc0dde40
-1, 569233, 10832, 0x00000000
+1, 569443, 10836, 0x00000000
0, 570000, 161280, 0x367f60c8
-1, 574759, 10832, 0x00000000
+1, 574971, 10836, 0x00000000
0, 576000, 161280, 0x367f60c8
-1, 580286, 10832, 0x00000000
+1, 580500, 10836, 0x00000000
0, 582000, 161280, 0x367f60c8
-1, 585812, 10832, 0x00000000
+1, 586029, 10836, 0x00000000
0, 588000, 161280, 0x367f60c8
-1, 591339, 10832, 0x00000000
+1, 591557, 10836, 0x00000000
0, 594000, 161280, 0x367f60c8
-1, 596865, 10832, 0x00000000
+1, 597086, 10836, 0x00000000
0, 600000, 161280, 0x367f60c8
-1, 602392, 10832, 0x00000000
+1, 602614, 10836, 0x00000000
0, 606000, 161280, 0x367f60c8
-1, 607918, 10832, 0x00000000
+1, 608143, 10836, 0x00000000
0, 612000, 161280, 0x367f60c8
-1, 613445, 10832, 0x00000000
+1, 613671, 10836, 0x00000000
0, 618000, 161280, 0x367f60c8
-1, 618971, 10832, 0x00000000
+1, 619200, 10836, 0x00000000
0, 624000, 161280, 0x367f60c8
diff --git a/tests/ref/fate/truemotion1-24 b/tests/ref/fate/truemotion1-24
index b0b1c4e..054f6b3 100644
--- a/tests/ref/fate/truemotion1-24
+++ b/tests/ref/fate/truemotion1-24
@@ -1,43 +1,43 @@
0, 0, 69120, 0x68beb30f
-1, 0, 10832, 0x1597b4c8
-1, 5527, 10832, 0xf9479f8b
+1, 0, 10836, 0xedecb6a7
+1, 5529, 10836, 0x8098a323
0, 6000, 69120, 0x3976f5cf
-1, 11053, 10832, 0x8db50e74
+1, 11057, 10836, 0xcfa1112e
0, 12000, 69120, 0xf815bc3c
-1, 16580, 10832, 0x2b33ecbb
+1, 16586, 10836, 0xe241ede4
0, 18000, 69120, 0xa7cc0ae6
-1, 22106, 10832, 0x8d0f537b
+1, 22114, 10836, 0xddf254bb
0, 24000, 69120, 0xd85ac282
-1, 27633, 10832, 0x922081c7
+1, 27643, 10836, 0xa16c8507
0, 30000, 69120, 0xf7fd7edb
-1, 33159, 10832, 0x40291f19
+1, 33171, 10836, 0xbe211f93
0, 36000, 69120, 0x433bb6f6
-1, 38686, 10832, 0x88f5271a
+1, 38700, 10836, 0x26c7283d
0, 42000, 69120, 0xdbac8bee
-1, 44212, 10832, 0x55c6bbe5
+1, 44229, 10836, 0x4d18be56
0, 48000, 69120, 0x88e2a799
-1, 49739, 10832, 0x9b51ae82
+1, 49757, 10836, 0x57b9af6f
0, 54000, 69120, 0x49617b26
-1, 55265, 10832, 0xcdf2409b
+1, 55286, 10836, 0xd5864280
0, 60000, 69120, 0xeb44ca01
-1, 60792, 10832, 0x0933b1a4
+1, 60814, 10836, 0xd582b451
0, 66000, 69120, 0x6fea37e8
-1, 66318, 10832, 0x24b77006
-1, 71845, 10832, 0xf612fa8a
+1, 66343, 10836, 0xec13731d
+1, 71871, 10836, 0xe3d4fbb8
0, 72000, 69120, 0xf55d74c7
-1, 77371, 10832, 0x99884b06
+1, 77400, 10836, 0xcbb54d18
0, 78000, 69120, 0xb5082ca7
-1, 82898, 10832, 0x3c746fbe
+1, 82929, 10836, 0xff7e7133
0, 84000, 69120, 0x5876d758
-1, 88424, 10832, 0x05f3b08a
-1, 93951, 10832, 0xa6560483
-1, 99478, 10832, 0xd98a8e19
-1, 105004, 10832, 0xf98a0b2e
-1, 110531, 10832, 0xb1039582
-1, 116057, 10832, 0x85dd5c3f
-1, 121584, 10832, 0x19fc801a
-1, 127110, 10832, 0x95805089
-1, 132637, 10832, 0x576fdec3
-1, 138163, 10832, 0x704a0905
-1, 143690, 10832, 0xf87ce1fa
-1, 149216, 10832, 0xfc0076b9
+1, 88457, 10836, 0xcc28b1a7
+1, 93986, 10836, 0xbf9e07a5
+1, 99514, 10836, 0x16408f38
+1, 105043, 10836, 0x2b000c9f
+1, 110571, 10836, 0x0ccd9811
+1, 116100, 10836, 0xf9575d48
+1, 121629, 10836, 0x1ee68190
+1, 127157, 10836, 0xde435373
+1, 132686, 10836, 0xd83be17a
+1, 138214, 10836, 0x9a7f0bbe
+1, 143743, 10836, 0x8709e4d3
+1, 149271, 10836, 0xde1879cb
diff --git a/tests/ref/fate/tscc-32bit b/tests/ref/fate/tscc-32bit
index dd888a8..90deaf5 100644
--- a/tests/ref/fate/tscc-32bit
+++ b/tests/ref/fate/tscc-32bit
@@ -9,151 +9,148 @@
0, 48000, 2359296, 0xe990f855
0, 54000, 2359296, 0x3ec2c64e
0, 60000, 2359296, 0xda3ba3cf
-0, 66000, 2359296, 0xda3ba3cf
-0, 72000, 2359296, 0xda3ba3cf
-0, 78000, 2359296, 0x60a070fd
-0, 84000, 2359296, 0x42e5fedc
-0, 90000, 2359296, 0x42e5fedc
+0, 66000, 2359296, 0x60a070fd
+0, 72000, 2359296, 0x42e5fedc
+0, 78000, 2359296, 0x42e5fedc
+0, 84000, 2359296, 0x699cf990
+0, 90000, 2359296, 0x699cf990
0, 96000, 2359296, 0x699cf990
0, 102000, 2359296, 0x699cf990
0, 108000, 2359296, 0x699cf990
0, 114000, 2359296, 0x699cf990
0, 120000, 2359296, 0x699cf990
-0, 126000, 2359296, 0x699cf990
-0, 132000, 2359296, 0x699cf990
+0, 126000, 2359296, 0x1524160c
+0, 132000, 2359296, 0x1524160c
0, 138000, 2359296, 0x1524160c
0, 144000, 2359296, 0x1524160c
0, 150000, 2359296, 0x1524160c
0, 156000, 2359296, 0x1524160c
0, 162000, 2359296, 0x1524160c
-0, 168000, 2359296, 0x1524160c
-0, 174000, 2359296, 0x1524160c
+0, 168000, 2359296, 0x33df0c8c
+0, 174000, 2359296, 0x33df0c8c
0, 180000, 2359296, 0x33df0c8c
0, 186000, 2359296, 0x33df0c8c
0, 192000, 2359296, 0x33df0c8c
0, 198000, 2359296, 0x33df0c8c
0, 204000, 2359296, 0x33df0c8c
-0, 210000, 2359296, 0x33df0c8c
-0, 216000, 2359296, 0x33df0c8c
+0, 210000, 2359296, 0xfe3d29f8
+0, 216000, 2359296, 0xfe3d29f8
0, 222000, 2359296, 0xfe3d29f8
0, 228000, 2359296, 0xfe3d29f8
0, 234000, 2359296, 0xfe3d29f8
0, 240000, 2359296, 0xfe3d29f8
0, 246000, 2359296, 0xfe3d29f8
-0, 252000, 2359296, 0xfe3d29f8
-0, 258000, 2359296, 0xfe3d29f8
+0, 252000, 2359296, 0x1b9d197f
+0, 258000, 2359296, 0x1b9d197f
0, 264000, 2359296, 0x1b9d197f
0, 270000, 2359296, 0x1b9d197f
0, 276000, 2359296, 0x1b9d197f
0, 282000, 2359296, 0x1b9d197f
0, 288000, 2359296, 0x1b9d197f
-0, 294000, 2359296, 0x1b9d197f
-0, 300000, 2359296, 0x1b9d197f
+0, 294000, 2359296, 0x48c126fb
+0, 300000, 2359296, 0x48c126fb
0, 306000, 2359296, 0x48c126fb
0, 312000, 2359296, 0x48c126fb
0, 318000, 2359296, 0x48c126fb
0, 324000, 2359296, 0x48c126fb
0, 330000, 2359296, 0x48c126fb
-0, 336000, 2359296, 0x48c126fb
-0, 342000, 2359296, 0x48c126fb
+0, 336000, 2359296, 0xcaa31c7c
+0, 342000, 2359296, 0xcaa31c7c
0, 348000, 2359296, 0xcaa31c7c
0, 354000, 2359296, 0xcaa31c7c
0, 360000, 2359296, 0xcaa31c7c
0, 366000, 2359296, 0xcaa31c7c
0, 372000, 2359296, 0xcaa31c7c
-0, 378000, 2359296, 0xcaa31c7c
-0, 384000, 2359296, 0xcaa31c7c
+0, 378000, 2359296, 0xc6a333ee
+0, 384000, 2359296, 0xc6a333ee
0, 390000, 2359296, 0xc6a333ee
0, 396000, 2359296, 0xc6a333ee
0, 402000, 2359296, 0xc6a333ee
0, 408000, 2359296, 0xc6a333ee
0, 414000, 2359296, 0xc6a333ee
-0, 420000, 2359296, 0xc6a333ee
-0, 426000, 2359296, 0xc6a333ee
+0, 420000, 2359296, 0xb96d1583
+0, 426000, 2359296, 0xb96d1583
0, 432000, 2359296, 0xb96d1583
0, 438000, 2359296, 0xb96d1583
0, 444000, 2359296, 0xb96d1583
0, 450000, 2359296, 0xb96d1583
0, 456000, 2359296, 0xb96d1583
-0, 462000, 2359296, 0xb96d1583
-0, 468000, 2359296, 0xb96d1583
+0, 462000, 2359296, 0x878135ec
+0, 468000, 2359296, 0x878135ec
0, 474000, 2359296, 0x878135ec
0, 480000, 2359296, 0x878135ec
0, 486000, 2359296, 0x878135ec
0, 492000, 2359296, 0x878135ec
0, 498000, 2359296, 0x878135ec
-0, 504000, 2359296, 0x878135ec
-0, 510000, 2359296, 0x878135ec
-0, 516000, 2359296, 0x878135ec
+0, 504000, 2359296, 0x76922870
+0, 510000, 2359296, 0x76922870
+0, 516000, 2359296, 0x76922870
0, 522000, 2359296, 0x76922870
0, 528000, 2359296, 0x76922870
0, 534000, 2359296, 0x76922870
0, 540000, 2359296, 0x76922870
-0, 546000, 2359296, 0x76922870
-0, 552000, 2359296, 0x76922870
-0, 558000, 2359296, 0x76922870
+0, 546000, 2359296, 0xb0e031f0
+0, 552000, 2359296, 0xb0e031f0
+0, 558000, 2359296, 0xb0e031f0
0, 564000, 2359296, 0xb0e031f0
0, 570000, 2359296, 0xb0e031f0
0, 576000, 2359296, 0xb0e031f0
0, 582000, 2359296, 0xb0e031f0
-0, 588000, 2359296, 0xb0e031f0
-0, 594000, 2359296, 0xb0e031f0
-0, 600000, 2359296, 0xb0e031f0
-0, 606000, 2359296, 0xb2ef2a6e
-0, 612000, 2359296, 0xb2ef2a6e
-0, 618000, 2359296, 0xb2ef2a6e
+0, 588000, 2359296, 0xb2ef2a6e
+0, 594000, 2359296, 0xb2ef2a6e
+0, 600000, 2359296, 0xb2ef2a6e
+0, 606000, 2359296, 0x083c2474
+0, 612000, 2359296, 0x083c2474
+0, 618000, 2359296, 0x083c2474
0, 624000, 2359296, 0x083c2474
-0, 630000, 2359296, 0x083c2474
-0, 636000, 2359296, 0x083c2474
-0, 642000, 2359296, 0x083c2474
+0, 630000, 2359296, 0xbdfe2ef3
+0, 636000, 2359296, 0xbdfe2ef3
+0, 642000, 2359296, 0xbdfe2ef3
0, 648000, 2359296, 0xbdfe2ef3
0, 654000, 2359296, 0xbdfe2ef3
0, 660000, 2359296, 0xbdfe2ef3
0, 666000, 2359296, 0xbdfe2ef3
-0, 672000, 2359296, 0xbdfe2ef3
-0, 678000, 2359296, 0xbdfe2ef3
-0, 684000, 2359296, 0xbdfe2ef3
+0, 672000, 2359296, 0x934b1484
+0, 678000, 2359296, 0x934b1484
+0, 684000, 2359296, 0x934b1484
0, 690000, 2359296, 0x934b1484
-0, 696000, 2359296, 0x934b1484
-0, 702000, 2359296, 0x934b1484
-0, 708000, 2359296, 0x934b1484
-0, 714000, 2359296, 0x3e0d1a7e
-0, 720000, 2359296, 0x3e0d1a7e
-0, 726000, 2359296, 0x3e0d1a7e
+0, 696000, 2359296, 0x3e0d1a7e
+0, 702000, 2359296, 0x3e0d1a7e
+0, 708000, 2359296, 0x3e0d1a7e
+0, 714000, 2359296, 0x3ce539e8
+0, 720000, 2359296, 0x3ce539e8
+0, 726000, 2359296, 0x3ce539e8
0, 732000, 2359296, 0x3ce539e8
0, 738000, 2359296, 0x3ce539e8
0, 744000, 2359296, 0x3ce539e8
0, 750000, 2359296, 0x3ce539e8
-0, 756000, 2359296, 0x3ce539e8
-0, 762000, 2359296, 0x3ce539e8
-0, 768000, 2359296, 0x3ce539e8
+0, 756000, 2359296, 0xd46c2f69
+0, 762000, 2359296, 0xd46c2f69
+0, 768000, 2359296, 0xd46c2f69
0, 774000, 2359296, 0xd46c2f69
0, 780000, 2359296, 0xd46c2f69
0, 786000, 2359296, 0xd46c2f69
0, 792000, 2359296, 0xd46c2f69
-0, 798000, 2359296, 0xd46c2f69
-0, 804000, 2359296, 0xd46c2f69
-0, 810000, 2359296, 0xd46c2f69
+0, 798000, 2359296, 0x8d2933ee
+0, 804000, 2359296, 0x8d2933ee
+0, 810000, 2359296, 0x8d2933ee
0, 816000, 2359296, 0x8d2933ee
0, 822000, 2359296, 0x8d2933ee
0, 828000, 2359296, 0x8d2933ee
0, 834000, 2359296, 0x8d2933ee
-0, 840000, 2359296, 0x8d2933ee
-0, 846000, 2359296, 0x8d2933ee
-0, 852000, 2359296, 0x8d2933ee
+0, 840000, 2359296, 0xb6092b6d
+0, 846000, 2359296, 0xb6092b6d
+0, 852000, 2359296, 0xb6092b6d
0, 858000, 2359296, 0xb6092b6d
0, 864000, 2359296, 0xb6092b6d
0, 870000, 2359296, 0xb6092b6d
0, 876000, 2359296, 0xb6092b6d
-0, 882000, 2359296, 0xb6092b6d
-0, 888000, 2359296, 0xb6092b6d
-0, 894000, 2359296, 0xb6092b6d
+0, 882000, 2359296, 0xe4ef27fa
+0, 888000, 2359296, 0xe4ef27fa
+0, 894000, 2359296, 0xe4ef27fa
0, 900000, 2359296, 0xe4ef27fa
0, 906000, 2359296, 0xe4ef27fa
0, 912000, 2359296, 0xe4ef27fa
0, 918000, 2359296, 0xe4ef27fa
-0, 924000, 2359296, 0xe4ef27fa
-0, 930000, 2359296, 0xe4ef27fa
-0, 936000, 2359296, 0xe4ef27fa
-0, 942000, 2359296, 0x5e5b2672
-0, 948000, 2359296, 0x5e5b2672
+0, 924000, 2359296, 0x5e5b2672
+0, 930000, 2359296, 0x5e5b2672
diff --git a/tests/ref/fate/utvideo_rgb_left b/tests/ref/fate/utvideo_rgb_left
new file mode 100644
index 0000000..5d2b73c
--- /dev/null
+++ b/tests/ref/fate/utvideo_rgb_left
@@ -0,0 +1,4 @@
+0, 0, 921600, 0x27e6001e
+0, 3003, 921600, 0x7c0a92bc
+0, 6006, 921600, 0x4d2be42c
+0, 9009, 921600, 0x58ddd0be
diff --git a/tests/ref/fate/utvideo_rgb_median b/tests/ref/fate/utvideo_rgb_median
new file mode 100644
index 0000000..6914153
--- /dev/null
+++ b/tests/ref/fate/utvideo_rgb_median
@@ -0,0 +1,5 @@
+0, 0, 921600, 0x9776611f
+0, 3003, 921600, 0xdbfa64f4
+0, 6006, 921600, 0xed2a0580
+0, 9009, 921600, 0x6ecc80bc
+0, 12012, 921600, 0x58ddd0be
diff --git a/tests/ref/fate/utvideo_rgba_left b/tests/ref/fate/utvideo_rgba_left
new file mode 100644
index 0000000..7d3800e
--- /dev/null
+++ b/tests/ref/fate/utvideo_rgba_left
@@ -0,0 +1,5 @@
+0, 0, 1228800, 0xf1bc9432
+0, 3003, 1228800, 0x8480d1e5
+0, 6006, 1228800, 0xb01d5fb2
+0, 9009, 1228800, 0x53cb42c4
+0, 12012, 1228800, 0x2b2ea176
diff --git a/tests/ref/fate/utvideo_rgba_median b/tests/ref/fate/utvideo_rgba_median
new file mode 100644
index 0000000..7d3800e
--- /dev/null
+++ b/tests/ref/fate/utvideo_rgba_median
@@ -0,0 +1,5 @@
+0, 0, 1228800, 0xf1bc9432
+0, 3003, 1228800, 0x8480d1e5
+0, 6006, 1228800, 0xb01d5fb2
+0, 9009, 1228800, 0x53cb42c4
+0, 12012, 1228800, 0x2b2ea176
diff --git a/tests/ref/fate/utvideo_yuv420_left b/tests/ref/fate/utvideo_yuv420_left
new file mode 100644
index 0000000..bdb90a6
--- /dev/null
+++ b/tests/ref/fate/utvideo_yuv420_left
@@ -0,0 +1,7 @@
+0, 0, 460800, 0xece98fc8
+0, 3003, 460800, 0x9baf786b
+0, 6006, 460800, 0x8e8e0510
+0, 9009, 460800, 0x27c1f2ba
+0, 12012, 460800, 0x6a817987
+0, 15015, 460800, 0x2f713ec2
+0, 18018, 460800, 0x003b560e
diff --git a/tests/ref/fate/utvideo_yuv420_median b/tests/ref/fate/utvideo_yuv420_median
new file mode 100644
index 0000000..5cd3bc8
--- /dev/null
+++ b/tests/ref/fate/utvideo_yuv420_median
@@ -0,0 +1,4 @@
+0, 0, 460800, 0x6a817987
+0, 3003, 460800, 0x2f713ec2
+0, 6006, 460800, 0x003b560e
+0, 9009, 460800, 0x9e1bbf63
diff --git a/tests/ref/fate/utvideo_yuv422_left b/tests/ref/fate/utvideo_yuv422_left
new file mode 100644
index 0000000..d68bf4e
--- /dev/null
+++ b/tests/ref/fate/utvideo_yuv422_left
@@ -0,0 +1,4 @@
+0, 0, 614400, 0x9a6b8802
+0, 3003, 614400, 0xaa8687e2
+0, 6006, 614400, 0x2fe5bd40
+0, 9009, 614400, 0x1c8f3737
diff --git a/tests/ref/fate/utvideo_yuv422_median b/tests/ref/fate/utvideo_yuv422_median
new file mode 100644
index 0000000..d68bf4e
--- /dev/null
+++ b/tests/ref/fate/utvideo_yuv422_median
@@ -0,0 +1,4 @@
+0, 0, 614400, 0x9a6b8802
+0, 3003, 614400, 0xaa8687e2
+0, 6006, 614400, 0x2fe5bd40
+0, 9009, 614400, 0x1c8f3737
diff --git a/tests/ref/fate/v210 b/tests/ref/fate/v210
index 8cbf7df..6a551a5 100644
--- a/tests/ref/fate/v210
+++ b/tests/ref/fate/v210
@@ -1 +1 @@
-0, 0, 3686400, 0x8d5c3847
+0, 0, 3686400, 0x75ee1dde
diff --git a/tests/ref/fate/v410dec b/tests/ref/fate/v410dec
new file mode 100644
index 0000000..f72d74f
--- /dev/null
+++ b/tests/ref/fate/v410dec
@@ -0,0 +1 @@
+0, 0, 393216, 0xfe11a6b0
diff --git a/tests/ref/fate/v410enc b/tests/ref/fate/v410enc
new file mode 100644
index 0000000..e5332de
--- /dev/null
+++ b/tests/ref/fate/v410enc
@@ -0,0 +1 @@
+979c9a9a09e8eaaf6467b8c22c0ac8bb
diff --git a/tests/ref/fate/vble b/tests/ref/fate/vble
new file mode 100644
index 0000000..748052e
--- /dev/null
+++ b/tests/ref/fate/vble
@@ -0,0 +1,4 @@
+0, 0, 1382400, 0x5e1bc307
+0, 3003, 1382400, 0x198795f7
+0, 6006, 1382400, 0xa9102ac2
+0, 9009, 1382400, 0x9e347932
diff --git a/tests/ref/fate/vc1_sa00050 b/tests/ref/fate/vc1_sa00050
new file mode 100644
index 0000000..3eb27bd
--- /dev/null
+++ b/tests/ref/fate/vc1_sa00050
@@ -0,0 +1,30 @@
+0, 0, 115200, 0xb8830eef
+0, 3600, 115200, 0xb8830eef
+0, 7200, 115200, 0xb8830eef
+0, 10800, 115200, 0x952ff5e1
+0, 14400, 115200, 0xa4362b14
+0, 18000, 115200, 0x32bacbe7
+0, 21600, 115200, 0x509eb814
+0, 25200, 115200, 0x509eb814
+0, 28800, 115200, 0x11a76c3e
+0, 32400, 115200, 0x11a76c3e
+0, 36000, 115200, 0x00cf734a
+0, 39600, 115200, 0x00cf734a
+0, 43200, 115200, 0x00cf734a
+0, 46800, 115200, 0x00cf734a
+0, 50400, 115200, 0x00cf734a
+0, 54000, 115200, 0x00cf734a
+0, 57600, 115200, 0x00cf734a
+0, 61200, 115200, 0x00cf734a
+0, 64800, 115200, 0xfddf48e6
+0, 68400, 115200, 0xfddf48e6
+0, 72000, 115200, 0x1eccebbf
+0, 75600, 115200, 0x3da2f77e
+0, 79200, 115200, 0x7c232572
+0, 82800, 115200, 0xedf426e5
+0, 86400, 115200, 0x5324ab20
+0, 90000, 115200, 0x5324ab20
+0, 93600, 115200, 0xa23e66bb
+0, 97200, 115200, 0x680a50ff
+0, 100800, 115200, 0x680a50ff
+0, 104400, 115200, 0x680a50ff
diff --git a/tests/ref/fate/vc1_sa10091 b/tests/ref/fate/vc1_sa10091
new file mode 100644
index 0000000..c121090
--- /dev/null
+++ b/tests/ref/fate/vc1_sa10091
@@ -0,0 +1,30 @@
+0, 0, 518400, 0xae20b4fa
+0, 3600, 518400, 0x2b4ccdf9
+0, 7200, 518400, 0x2b4ccdf9
+0, 10800, 518400, 0x2b4ccdf9
+0, 14400, 518400, 0x2b4ccdf9
+0, 18000, 518400, 0x2b4ccdf9
+0, 21600, 518400, 0x70d9a891
+0, 25200, 518400, 0x70d9a891
+0, 28800, 518400, 0x70d9a891
+0, 32400, 518400, 0xa461ee86
+0, 36000, 518400, 0x722bc6e8
+0, 39600, 518400, 0x722bc6e8
+0, 43200, 518400, 0x722bc6e8
+0, 46800, 518400, 0xf752fd2c
+0, 50400, 518400, 0xf752fd2c
+0, 54000, 518400, 0x91abcaca
+0, 57600, 518400, 0x572727c3
+0, 61200, 518400, 0x572727c3
+0, 64800, 518400, 0x24c12382
+0, 68400, 518400, 0x24c12382
+0, 72000, 518400, 0x9aa39fe8
+0, 75600, 518400, 0x9aa39fe8
+0, 79200, 518400, 0x5cb6bd19
+0, 82800, 518400, 0x704d9300
+0, 86400, 518400, 0x590fad49
+0, 90000, 518400, 0x590fad49
+0, 93600, 518400, 0x590fad49
+0, 97200, 518400, 0x46bea10b
+0, 100800, 518400, 0x46bea10b
+0, 104400, 518400, 0x46bea10b
diff --git a/tests/ref/fate/vc1_sa20021 b/tests/ref/fate/vc1_sa20021
new file mode 100644
index 0000000..aae607b
--- /dev/null
+++ b/tests/ref/fate/vc1_sa20021
@@ -0,0 +1,60 @@
+0, 0, 506880, 0x884bc093
+0, 3600, 506880, 0x4b09548f
+0, 7200, 506880, 0x195cbee1
+0, 10800, 506880, 0xc8141e28
+0, 14400, 506880, 0xb170c49b
+0, 18000, 506880, 0x2782268a
+0, 21600, 506880, 0x2782268a
+0, 25200, 506880, 0x2782268a
+0, 28800, 506880, 0x2782268a
+0, 32400, 506880, 0xe6803b32
+0, 36000, 506880, 0xe6803b32
+0, 39600, 506880, 0xa5ef9baf
+0, 43200, 506880, 0xa5ef9baf
+0, 46800, 506880, 0x46e8cbcb
+0, 50400, 506880, 0x28a2239b
+0, 54000, 506880, 0x7667af2f
+0, 57600, 506880, 0x7667af2f
+0, 61200, 506880, 0x8011bcaf
+0, 64800, 506880, 0xd422115b
+0, 68400, 506880, 0xd422115b
+0, 72000, 506880, 0xd422115b
+0, 75600, 506880, 0xbcee0b5b
+0, 79200, 506880, 0x08fe9ec8
+0, 82800, 506880, 0xc8fb8b37
+0, 86400, 506880, 0xc8fb8b37
+0, 90000, 506880, 0x2c698b52
+0, 93600, 506880, 0x2c698b52
+0, 97200, 506880, 0x2c698b52
+0, 100800, 506880, 0x2b4ad9bc
+0, 104400, 506880, 0x2b4ad9bc
+0, 108000, 506880, 0x2b4ad9bc
+0, 111600, 506880, 0x2b4ad9bc
+0, 115200, 506880, 0x92e84ebb
+0, 118800, 506880, 0x92e84ebb
+0, 122400, 506880, 0xdb877da3
+0, 126000, 506880, 0xdb877da3
+0, 129600, 506880, 0xdb877da3
+0, 133200, 506880, 0x44610654
+0, 136800, 506880, 0x44610654
+0, 140400, 506880, 0xe254ce67
+0, 144000, 506880, 0xa6085385
+0, 147600, 506880, 0x2d45d744
+0, 151200, 506880, 0x2d45d744
+0, 154800, 506880, 0x6e684f51
+0, 158400, 506880, 0xe96186cf
+0, 162000, 506880, 0xb535d369
+0, 165600, 506880, 0xb535d369
+0, 169200, 506880, 0xb535d369
+0, 172800, 506880, 0xeed0b7e0
+0, 176400, 506880, 0xeed0b7e0
+0, 180000, 506880, 0xeed0b7e0
+0, 183600, 506880, 0xeed0b7e0
+0, 187200, 506880, 0x8789b20b
+0, 190800, 506880, 0x0a0f42fb
+0, 194400, 506880, 0x09bbac2d
+0, 198000, 506880, 0x09bbac2d
+0, 201600, 506880, 0x09bbac2d
+0, 205200, 506880, 0x09bbac2d
+0, 208800, 506880, 0x09bbac2d
+0, 212400, 506880, 0xda77f0df
diff --git a/tests/ref/fate/vmnc-32bit b/tests/ref/fate/vmnc-32bit
index fa3d6a0..6abcd0d 100644
--- a/tests/ref/fate/vmnc-32bit
+++ b/tests/ref/fate/vmnc-32bit
@@ -2,170 +2,48 @@
0, 18000, 3655644, 0x87973530
0, 36000, 3655644, 0x3c3167fd
0, 54000, 3655644, 0x87973530
-0, 72000, 3655644, 0x87973530
-0, 90000, 3655644, 0x3c3167fd
-0, 108000, 3655644, 0x3c3167fd
-0, 126000, 3655644, 0x87973530
+0, 72000, 3655644, 0x3c3167fd
+0, 90000, 3655644, 0x87973530
+0, 108000, 3655644, 0x87973530
+0, 126000, 3655644, 0x3c3167fd
0, 144000, 3655644, 0x87973530
-0, 162000, 3655644, 0x87973530
-0, 180000, 3655644, 0x87973530
-0, 198000, 3655644, 0x3c3167fd
-0, 216000, 3655644, 0x87973530
-0, 234000, 3655644, 0x87973530
-0, 252000, 3655644, 0x87973530
-0, 270000, 3655644, 0x4f0da763
-0, 288000, 3655644, 0x4f0da763
-0, 306000, 3655644, 0x4f0da763
-0, 324000, 3655644, 0x66a4a763
-0, 342000, 3655644, 0xb20a7496
-0, 360000, 3655644, 0x66a4a763
-0, 378000, 3655644, 0x66a4a763
-0, 396000, 3655644, 0x66a4a763
-0, 414000, 3655644, 0x5600644a
-0, 432000, 3655644, 0xce5880ee
-0, 450000, 3655644, 0xce5880ee
-0, 468000, 3655644, 0xa993ef3d
-0, 486000, 3655644, 0xa993ef3d
-0, 504000, 3655644, 0xa993ef3d
-0, 522000, 3655644, 0xa993ef3d
-0, 540000, 3655644, 0xa993ef3d
-0, 558000, 3655644, 0xa993ef3d
-0, 576000, 3655644, 0xa993ef3d
-0, 594000, 3655644, 0xa993ef3d
-0, 612000, 3655644, 0xa993ef3d
-0, 630000, 3655644, 0xa993ef3d
-0, 648000, 3655644, 0xa993ef3d
-0, 666000, 3655644, 0xa993ef3d
-0, 684000, 3655644, 0xa993ef3d
-0, 702000, 3655644, 0xa993ef3d
-0, 720000, 3655644, 0xa993ef3d
-0, 738000, 3655644, 0xa993ef3d
-0, 756000, 3655644, 0xa993ef3d
-0, 774000, 3655644, 0xa993ef3d
-0, 792000, 3655644, 0xa993ef3d
-0, 810000, 3655644, 0xa993ef3d
-0, 828000, 3655644, 0xa993ef3d
-0, 846000, 3655644, 0xa993ef3d
-0, 864000, 3655644, 0xa993ef3d
-0, 882000, 3655644, 0x73564014
-0, 900000, 3655644, 0x73564014
-0, 918000, 3655644, 0x73564014
-0, 936000, 3655644, 0x73564014
-0, 954000, 3655644, 0x73564014
-0, 972000, 3655644, 0x73564014
-0, 990000, 3655644, 0x73564014
-0, 1008000, 3655644, 0x73564014
-0, 1026000, 3655644, 0x73564014
-0, 1044000, 3655644, 0x73564014
-0, 1062000, 3655644, 0x73564014
-0, 1080000, 3655644, 0x73564014
-0, 1098000, 3655644, 0x2a6e1e8c
-0, 1116000, 3655644, 0x2a6e1e8c
-0, 1134000, 3655644, 0x2a6e1e8c
-0, 1152000, 3655644, 0xbae02e7c
-0, 1170000, 3655644, 0xbae02e7c
-0, 1188000, 3655644, 0xbae02e7c
-0, 1206000, 3655644, 0xbae02e7c
-0, 1224000, 3655644, 0x55af4a2d
-0, 1242000, 3655644, 0x55af4a2d
-0, 1260000, 3655644, 0x55af4a2d
-0, 1278000, 3655644, 0x55af4a2d
-0, 1296000, 3655644, 0x54b7ff2d
-0, 1314000, 3655644, 0x39af1aed
-0, 1332000, 3655644, 0x39af1aed
-0, 1350000, 3655644, 0x39af1aed
-0, 1368000, 3655644, 0x39af1aed
-0, 1386000, 3655644, 0xe48dd11c
-0, 1404000, 3655644, 0xe48dd11c
-0, 1422000, 3655644, 0xe48dd11c
-0, 1440000, 3655644, 0xe48dd11c
-0, 1458000, 3655644, 0xe48dd11c
-0, 1476000, 3655644, 0xba15c78d
-0, 1494000, 3655644, 0xba15c78d
-0, 1512000, 3655644, 0xba15c78d
-0, 1530000, 3655644, 0xba15c78d
-0, 1548000, 3655644, 0xba15c78d
-0, 1566000, 3655644, 0xba15c78d
-0, 1584000, 3655644, 0xba15c78d
-0, 1602000, 3655644, 0x39af1aed
-0, 1620000, 3655644, 0x39af1aed
-0, 1638000, 3655644, 0x39af1aed
-0, 1656000, 3655644, 0x39af1aed
-0, 1674000, 3655644, 0x39af1aed
-0, 1692000, 3655644, 0x39af1aed
-0, 1710000, 3655644, 0x39af1aed
-0, 1728000, 3655644, 0x27f96cd8
-0, 1746000, 3655644, 0x27f96cd8
-0, 1764000, 3655644, 0x27f96cd8
-0, 1782000, 3655644, 0x27f96cd8
-0, 1800000, 3655644, 0x27f96cd8
-0, 1818000, 3655644, 0x27f96cd8
-0, 1836000, 3655644, 0x27f96cd8
-0, 1854000, 3655644, 0xf4f068dc
-0, 1872000, 3655644, 0xf4f068dc
-0, 1890000, 3655644, 0xf4f068dc
-0, 1908000, 3655644, 0xf4f068dc
-0, 1926000, 3655644, 0xf4f068dc
-0, 1944000, 3655644, 0xf4f068dc
-0, 1962000, 3655644, 0xf4f068dc
-0, 1980000, 3655644, 0xf1c55cf5
-0, 1998000, 3655644, 0xd932633d
-0, 2016000, 3655644, 0xd932633d
-0, 2034000, 3655644, 0xc6e95e0a
-0, 2052000, 3655644, 0x9a63c9de
-0, 2070000, 3655644, 0xf166ad4f
-0, 2088000, 3655644, 0xe9eeba41
-0, 2106000, 3655644, 0x7e598ad7
-0, 2124000, 3655644, 0xf3bd257e
-0, 2142000, 3655644, 0xf3bd257e
-0, 2160000, 3655644, 0xf3bd257e
-0, 2178000, 3655644, 0xf3bd257e
-0, 2196000, 3655644, 0xf3bd257e
-0, 2214000, 3655644, 0xf35b3852
-0, 2232000, 3655644, 0xf35b3852
-0, 2250000, 3655644, 0xf35b3852
-0, 2268000, 3655644, 0xf35b3852
-0, 2286000, 3655644, 0x9d553959
-0, 2304000, 3655644, 0x0a9de8e2
-0, 2322000, 3655644, 0xf2325b6c
-0, 2340000, 3655644, 0xf2325b6c
-0, 2358000, 3655644, 0xf2325b6c
-0, 2376000, 3655644, 0xf2325b6c
-0, 2394000, 3655644, 0xf2325b6c
-0, 2412000, 3655644, 0xf2325b6c
-0, 2430000, 3655644, 0xcf924028
-0, 2448000, 3655644, 0xcf924028
-0, 2466000, 3655644, 0x8dae55bc
-0, 2484000, 3655644, 0x8dae55bc
-0, 2502000, 3655644, 0x57b08ced
-0, 2520000, 3655644, 0x57b08ced
-0, 2538000, 3655644, 0xef89a1d8
-0, 2556000, 3655644, 0xef89a1d8
-0, 2574000, 3655644, 0x69e5503a
-0, 2592000, 3655644, 0x69e5503a
-0, 2610000, 3655644, 0xc3de7b3f
-0, 2628000, 3655644, 0xc3de7b3f
-0, 2646000, 3655644, 0x88eea64a
-0, 2664000, 3655644, 0x88eea64a
-0, 2682000, 3655644, 0xe39cce1f
-0, 2700000, 3655644, 0xe39cce1f
-0, 2718000, 3655644, 0xe39cce1f
-0, 2736000, 3655644, 0xe39cce1f
-0, 2754000, 3655644, 0xe39cce1f
-0, 2772000, 3655644, 0xe39cce1f
-0, 2790000, 3655644, 0xe39cce1f
-0, 2808000, 3655644, 0xe39cce1f
-0, 2826000, 3655644, 0xe39cce1f
-0, 2844000, 3655644, 0xe39cce1f
-0, 2862000, 3655644, 0xe39cce1f
-0, 2880000, 3655644, 0xe39cce1f
-0, 2898000, 3655644, 0xe39cce1f
-0, 2916000, 3655644, 0xf0ed0d04
-0, 2934000, 3655644, 0xf0ed0d04
-0, 2952000, 3655644, 0xf0ed0d04
-0, 2970000, 3655644, 0xf0ed0d04
-0, 2988000, 3655644, 0x32490d3e
-0, 3006000, 3655644, 0x32490d3e
-0, 3024000, 3655644, 0x32490d3e
-0, 3042000, 3655644, 0x32490d3e
-0, 3060000, 3655644, 0x32490d3e
+0, 162000, 3655644, 0x4f0da763
+0, 180000, 3655644, 0x66a4a763
+0, 198000, 3655644, 0xb20a7496
+0, 216000, 3655644, 0x66a4a763
+0, 234000, 3655644, 0x5600644a
+0, 252000, 3655644, 0xce5880ee
+0, 270000, 3655644, 0xa993ef3d
+0, 288000, 3655644, 0x73564014
+0, 306000, 3655644, 0x2a6e1e8c
+0, 324000, 3655644, 0xbae02e7c
+0, 342000, 3655644, 0x55af4a2d
+0, 360000, 3655644, 0x54b7ff2d
+0, 378000, 3655644, 0x39af1aed
+0, 396000, 3655644, 0xe48dd11c
+0, 414000, 3655644, 0xba15c78d
+0, 432000, 3655644, 0x39af1aed
+0, 450000, 3655644, 0x27f96cd8
+0, 468000, 3655644, 0xf4f068dc
+0, 486000, 3655644, 0xf1c55cf5
+0, 504000, 3655644, 0xd932633d
+0, 522000, 3655644, 0xc6e95e0a
+0, 540000, 3655644, 0x9a63c9de
+0, 558000, 3655644, 0xf166ad4f
+0, 576000, 3655644, 0xe9eeba41
+0, 594000, 3655644, 0x7e598ad7
+0, 612000, 3655644, 0xf3bd257e
+0, 630000, 3655644, 0xf35b3852
+0, 648000, 3655644, 0x9d553959
+0, 666000, 3655644, 0x0a9de8e2
+0, 684000, 3655644, 0xf2325b6c
+0, 702000, 3655644, 0xcf924028
+0, 720000, 3655644, 0x8dae55bc
+0, 738000, 3655644, 0x57b08ced
+0, 756000, 3655644, 0xef89a1d8
+0, 774000, 3655644, 0x69e5503a
+0, 792000, 3655644, 0xc3de7b3f
+0, 810000, 3655644, 0x88eea64a
+0, 828000, 3655644, 0xe39cce1f
+0, 846000, 3655644, 0xf0ed0d04
+0, 864000, 3655644, 0x32490d3e
diff --git a/tests/ref/fate/wmv8-drm b/tests/ref/fate/wmv8-drm
index 0150535..e18309b 100644
--- a/tests/ref/fate/wmv8-drm
+++ b/tests/ref/fate/wmv8-drm
@@ -1,162 +1,130 @@
0, 0, 84480, 0x7760a00b
0, 3750, 84480, 0xfe39a1db
-0, 7500, 84480, 0xfe39a1db
-0, 11250, 84480, 0xfe39a1db
-0, 15000, 84480, 0xfe39a1db
-0, 18750, 84480, 0xfe39a1db
-0, 22500, 84480, 0xfe39a1db
-0, 26250, 84480, 0xfe39a1db
-0, 30000, 84480, 0xfe39a1db
-0, 33750, 84480, 0xfe39a1db
-0, 37500, 84480, 0xfe39a1db
-0, 41250, 84480, 0xfe39a1db
-0, 45000, 84480, 0xfe39a1db
-0, 48750, 84480, 0xfe39a1db
-0, 52500, 84480, 0xfe39a1db
-0, 56250, 84480, 0xfe39a1db
-0, 60000, 84480, 0xfe39a1db
-0, 63750, 84480, 0xfe39a1db
-0, 67500, 84480, 0xfe39a1db
-0, 71250, 84480, 0xfe39a1db
-0, 75000, 84480, 0xfe39a1db
-0, 78750, 84480, 0xfe39a1db
-0, 82500, 84480, 0xfe39a1db
-0, 86250, 84480, 0xfe39a1db
-0, 90000, 84480, 0xfe39a1db
-0, 93750, 84480, 0xfe39a1db
-0, 97500, 84480, 0xfe39a1db
-0, 101250, 84480, 0xfe39a1db
-0, 105000, 84480, 0xfe39a1db
-0, 108750, 84480, 0xd71961b4
-0, 112500, 84480, 0xc80dedba
-0, 116250, 84480, 0x34d8b538
-0, 120000, 84480, 0x1a86b8e5
-0, 123750, 84480, 0xabf7c25d
-0, 127500, 84480, 0x912600ee
-0, 131250, 84480, 0x7ee7c70b
-0, 135000, 84480, 0x09c5b0d1
-0, 138750, 84480, 0x6dbe6c0c
-0, 142500, 84480, 0x0fe0a120
-0, 146250, 84480, 0x2352d3a2
-0, 150000, 84480, 0xb22ce92e
-0, 153750, 84480, 0x31db0099
-0, 157500, 84480, 0xad2dd73a
-0, 161250, 84480, 0xb9af8e20
-0, 165000, 84480, 0x7b956549
-0, 168750, 84480, 0x3f774b87
-0, 172500, 84480, 0x824a23a3
-0, 176250, 84480, 0x4469a8d8
-0, 180000, 84480, 0xc80c7a0a
-0, 183750, 84480, 0xcf958549
-0, 187500, 84480, 0x449746e3
-0, 191250, 84480, 0xbac66a82
-0, 195000, 84480, 0x99e85855
-0, 198750, 84480, 0xa4a17d17
-0, 202500, 84480, 0xe29c7587
-0, 206250, 84480, 0x551de592
-0, 210000, 84480, 0xe0877bce
-0, 213750, 84480, 0x9660eb35
-0, 217500, 84480, 0x0a34b644
-0, 221250, 84480, 0x352919f0
-0, 225000, 84480, 0xef56ce27
-0, 228750, 84480, 0x030fe862
-0, 232500, 84480, 0x2eba33e2
-0, 236250, 84480, 0x242de401
-0, 240000, 84480, 0xbadd61ca
-0, 243750, 84480, 0x2060465b
-0, 247500, 84480, 0x256e6965
-0, 251250, 84480, 0x243b7084
-0, 255000, 84480, 0x8b3c0b47
-0, 258750, 84480, 0xc174a9af
-0, 262500, 84480, 0xb6d48686
-0, 266250, 84480, 0xa3dd1871
-0, 270000, 84480, 0x04cdcaf7
-0, 273750, 84480, 0x55f89c94
-0, 277500, 84480, 0xda657032
-0, 281250, 84480, 0x38ba7698
-0, 285000, 84480, 0x4d03a7f2
-0, 288750, 84480, 0x115d9035
-0, 292500, 84480, 0x24c6acc6
-0, 296250, 84480, 0xdd2bbcae
-0, 300000, 84480, 0xb4fee0b9
-0, 303750, 84480, 0xc51c14e0
-0, 307500, 84480, 0xfb7737de
-0, 311250, 84480, 0x38675fb0
-0, 315000, 84480, 0x4752c710
-0, 318750, 84480, 0xfeb7491b
-0, 322500, 84480, 0xaa248122
-0, 326250, 84480, 0x9a4af87c
-0, 330000, 84480, 0xedcf09df
-0, 333750, 84480, 0x563a05df
-0, 337500, 84480, 0x0dde1e03
-0, 341250, 84480, 0xd8f0ff65
-0, 345000, 84480, 0xbeb9ae1a
-0, 348750, 84480, 0x416d1468
-0, 352500, 84480, 0x66c87d4c
-0, 356250, 84480, 0xa67c0774
-0, 360000, 84480, 0xd8f8aec1
-0, 363750, 84480, 0xadfa502b
-0, 367500, 84480, 0x50bf20e4
-0, 371250, 84480, 0xbcb3d8cc
-0, 375000, 84480, 0xa54677d7
-0, 378750, 84480, 0x3566042d
-0, 382500, 84480, 0x4c9eed57
-0, 386250, 84480, 0xc3b90e58
-0, 390000, 84480, 0x3c042bfa
-0, 393750, 84480, 0x19f8e890
-0, 397500, 84480, 0xd3dacfb9
-0, 401250, 84480, 0x2365fc6f
-0, 405000, 84480, 0xa2c19d00
-0, 408750, 84480, 0xce94336f
-0, 412500, 84480, 0xfa9bcf14
-0, 416250, 84480, 0x24d6a243
-0, 420000, 84480, 0x24d6a243
-0, 423750, 84480, 0x24d6a243
-0, 427500, 84480, 0x24d6a243
-0, 431250, 84480, 0x24d6a243
-0, 435000, 84480, 0x24d6a243
-0, 438750, 84480, 0x24d6a243
-0, 442500, 84480, 0xae1c8854
-0, 446250, 84480, 0xbb8968bf
-0, 450000, 84480, 0x6f923623
-0, 453750, 84480, 0x22e98029
-0, 457500, 84480, 0x8ac33af3
-0, 461250, 84480, 0x05947b6e
-0, 465000, 84480, 0xfc35661a
-0, 468750, 84480, 0x0e6b6e47
-0, 472500, 84480, 0x82c764bb
-0, 476250, 84480, 0x57a36833
-0, 480000, 84480, 0xc8dd690a
-0, 483750, 84480, 0x02c47232
-0, 487500, 84480, 0x6645715d
-0, 491250, 84480, 0xc64860f7
-0, 495000, 84480, 0x4f5614b3
-0, 498750, 84480, 0xa70842ca
-0, 502500, 84480, 0x379d8458
-0, 506250, 84480, 0xa14701cf
-0, 510000, 84480, 0xad1aa2b2
-0, 513750, 84480, 0xee28f320
-0, 517500, 84480, 0x505801e9
-0, 521250, 84480, 0x7947233b
-0, 525000, 84480, 0x3ce72a9d
-0, 528750, 84480, 0xa6834e64
-0, 532500, 84480, 0xfebf4d70
-0, 536250, 84480, 0x4a0775e2
-0, 540000, 84480, 0x9d7e945b
-0, 543750, 84480, 0xaa9eadd9
-0, 547500, 84480, 0xaa85c9b1
-0, 551250, 84480, 0xa005edaf
-0, 555000, 84480, 0x7fc4e5cc
-0, 558750, 84480, 0xb0f6e8d1
-0, 562500, 84480, 0x9ef9f330
-0, 566250, 84480, 0xbe14ff1f
-0, 570000, 84480, 0xd494048c
-0, 573750, 84480, 0x046166a7
-0, 577500, 84480, 0x052a09b2
-0, 581250, 84480, 0x71fff4ab
-0, 585000, 84480, 0xb9684e41
-0, 588750, 84480, 0x1ddce068
-0, 592500, 84480, 0xb9de300e
-0, 596250, 84480, 0x13962590
-0, 600000, 84480, 0xde79482f
-0, 603750, 84480, 0x7d1ca064
+0, 7500, 84480, 0xd71961b4
+0, 11250, 84480, 0xc80dedba
+0, 15000, 84480, 0x34d8b538
+0, 18750, 84480, 0x1a86b8e5
+0, 22500, 84480, 0xabf7c25d
+0, 26250, 84480, 0x912600ee
+0, 30000, 84480, 0x7ee7c70b
+0, 33750, 84480, 0x09c5b0d1
+0, 37500, 84480, 0x6dbe6c0c
+0, 41250, 84480, 0x0fe0a120
+0, 45000, 84480, 0x2352d3a2
+0, 48750, 84480, 0xb22ce92e
+0, 52500, 84480, 0x31db0099
+0, 56250, 84480, 0xad2dd73a
+0, 60000, 84480, 0xb9af8e20
+0, 63750, 84480, 0x7b956549
+0, 67500, 84480, 0x3f774b87
+0, 71250, 84480, 0x824a23a3
+0, 75000, 84480, 0x4469a8d8
+0, 78750, 84480, 0xc80c7a0a
+0, 82500, 84480, 0xcf958549
+0, 86250, 84480, 0x449746e3
+0, 90000, 84480, 0xbac66a82
+0, 93750, 84480, 0x99e85855
+0, 97500, 84480, 0xa4a17d17
+0, 101250, 84480, 0xe29c7587
+0, 105000, 84480, 0x551de592
+0, 108750, 84480, 0xe0877bce
+0, 112500, 84480, 0x9660eb35
+0, 116250, 84480, 0x0a34b644
+0, 120000, 84480, 0x352919f0
+0, 123750, 84480, 0xef56ce27
+0, 127500, 84480, 0x030fe862
+0, 131250, 84480, 0x2eba33e2
+0, 135000, 84480, 0x242de401
+0, 138750, 84480, 0xbadd61ca
+0, 142500, 84480, 0x2060465b
+0, 146250, 84480, 0x256e6965
+0, 150000, 84480, 0x243b7084
+0, 153750, 84480, 0x8b3c0b47
+0, 157500, 84480, 0xc174a9af
+0, 161250, 84480, 0xb6d48686
+0, 165000, 84480, 0xa3dd1871
+0, 168750, 84480, 0x04cdcaf7
+0, 172500, 84480, 0x55f89c94
+0, 176250, 84480, 0xda657032
+0, 180000, 84480, 0x38ba7698
+0, 183750, 84480, 0x4d03a7f2
+0, 187500, 84480, 0x115d9035
+0, 191250, 84480, 0x24c6acc6
+0, 195000, 84480, 0xdd2bbcae
+0, 198750, 84480, 0xb4fee0b9
+0, 202500, 84480, 0xc51c14e0
+0, 206250, 84480, 0xfb7737de
+0, 210000, 84480, 0x38675fb0
+0, 213750, 84480, 0x4752c710
+0, 217500, 84480, 0xfeb7491b
+0, 221250, 84480, 0xaa248122
+0, 225000, 84480, 0x9a4af87c
+0, 228750, 84480, 0xedcf09df
+0, 232500, 84480, 0x563a05df
+0, 236250, 84480, 0x0dde1e03
+0, 240000, 84480, 0xd8f0ff65
+0, 243750, 84480, 0xbeb9ae1a
+0, 247500, 84480, 0x416d1468
+0, 251250, 84480, 0x66c87d4c
+0, 255000, 84480, 0xa67c0774
+0, 258750, 84480, 0xd8f8aec1
+0, 262500, 84480, 0xadfa502b
+0, 266250, 84480, 0x50bf20e4
+0, 270000, 84480, 0xbcb3d8cc
+0, 273750, 84480, 0xa54677d7
+0, 277500, 84480, 0x3566042d
+0, 281250, 84480, 0x4c9eed57
+0, 285000, 84480, 0xc3b90e58
+0, 288750, 84480, 0x3c042bfa
+0, 292500, 84480, 0x19f8e890
+0, 296250, 84480, 0xd3dacfb9
+0, 300000, 84480, 0x2365fc6f
+0, 303750, 84480, 0xa2c19d00
+0, 307500, 84480, 0xce94336f
+0, 311250, 84480, 0xfa9bcf14
+0, 315000, 84480, 0x24d6a243
+0, 318750, 84480, 0xae1c8854
+0, 322500, 84480, 0xbb8968bf
+0, 326250, 84480, 0x6f923623
+0, 330000, 84480, 0x22e98029
+0, 333750, 84480, 0x8ac33af3
+0, 337500, 84480, 0x05947b6e
+0, 341250, 84480, 0xfc35661a
+0, 345000, 84480, 0x0e6b6e47
+0, 348750, 84480, 0x82c764bb
+0, 352500, 84480, 0x57a36833
+0, 356250, 84480, 0xc8dd690a
+0, 360000, 84480, 0x02c47232
+0, 363750, 84480, 0x6645715d
+0, 367500, 84480, 0xc64860f7
+0, 371250, 84480, 0x4f5614b3
+0, 375000, 84480, 0xa70842ca
+0, 378750, 84480, 0x379d8458
+0, 382500, 84480, 0xa14701cf
+0, 386250, 84480, 0xad1aa2b2
+0, 390000, 84480, 0xee28f320
+0, 393750, 84480, 0x505801e9
+0, 397500, 84480, 0x7947233b
+0, 401250, 84480, 0x3ce72a9d
+0, 405000, 84480, 0xa6834e64
+0, 408750, 84480, 0xfebf4d70
+0, 412500, 84480, 0x4a0775e2
+0, 416250, 84480, 0x9d7e945b
+0, 420000, 84480, 0xaa9eadd9
+0, 423750, 84480, 0xaa85c9b1
+0, 427500, 84480, 0xa005edaf
+0, 431250, 84480, 0x7fc4e5cc
+0, 435000, 84480, 0xb0f6e8d1
+0, 438750, 84480, 0x9ef9f330
+0, 442500, 84480, 0xbe14ff1f
+0, 446250, 84480, 0xd494048c
+0, 450000, 84480, 0x046166a7
+0, 453750, 84480, 0x052a09b2
+0, 457500, 84480, 0x71fff4ab
+0, 461250, 84480, 0xb9684e41
+0, 465000, 84480, 0x1ddce068
+0, 468750, 84480, 0xb9de300e
+0, 472500, 84480, 0x13962590
+0, 476250, 84480, 0xde79482f
+0, 480000, 84480, 0x7d1ca064
+0, 483750, 84480, 0x2676a064
diff --git a/tests/ref/fate/xxan-wc4 b/tests/ref/fate/xxan-wc4
new file mode 100644
index 0000000..d31fbb6
--- /dev/null
+++ b/tests/ref/fate/xxan-wc4
@@ -0,0 +1,10 @@
+0, 0, 79360, 0x877eb3ed
+0, 6000, 79360, 0x9ff8707c
+0, 12000, 79360, 0x144dec86
+0, 18000, 79360, 0x56d59588
+0, 24000, 79360, 0x2d20f8ce
+0, 30000, 79360, 0x1a752c42
+0, 36000, 79360, 0x85705730
+0, 42000, 79360, 0xddea3741
+0, 48000, 79360, 0x46448efd
+0, 54000, 79360, 0x27186e2b
diff --git a/tests/ref/lavf/ffm b/tests/ref/lavf/ffm
index b89af6e..cdfec4d 100644
--- a/tests/ref/lavf/ffm
+++ b/tests/ref/lavf/ffm
@@ -1,3 +1,3 @@
-b6acf782a38d313153b68c4ca204fc90 *./tests/data/lavf/lavf.ffm
+bf46c0b53fc318d0a60fa9bf446b2e4f *./tests/data/lavf/lavf.ffm
376832 ./tests/data/lavf/lavf.ffm
./tests/data/lavf/lavf.ffm CRC=0xf361ed74
diff --git a/tests/ref/lavf/gif b/tests/ref/lavf/gif
index fa55d0e..4a4ebfb 100644
--- a/tests/ref/lavf/gif
+++ b/tests/ref/lavf/gif
@@ -1,3 +1,3 @@
-98968ceb210ab260a6a7af36767b94d3 *./tests/data/lavf/lavf.gif
-2906382 ./tests/data/lavf/lavf.gif
+e6089fd4ef3b9df44090ab3650bdd810 *./tests/data/lavf/lavf.gif
+2906401 ./tests/data/lavf/lavf.gif
./tests/data/lavf/lavf.gif CRC=0xe5605ff6
diff --git a/tests/ref/lavf/mov b/tests/ref/lavf/mov
index 07404aa..f51b42d 100644
--- a/tests/ref/lavf/mov
+++ b/tests/ref/lavf/mov
@@ -1,3 +1,3 @@
-4a3ad13f0355cb5d119109778d555207 *./tests/data/lavf/lavf.mov
-357681 ./tests/data/lavf/lavf.mov
+8dc82a08a0abb47c822d03a6e408383b *./tests/data/lavf/lavf.mov
+357717 ./tests/data/lavf/lavf.mov
./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
diff --git a/tests/ref/lavf/ogg b/tests/ref/lavf/ogg
index eb96fd9..b90bb70 100644
--- a/tests/ref/lavf/ogg
+++ b/tests/ref/lavf/ogg
@@ -1,3 +1,3 @@
-364714f1087f3c1320b60f4209191d23 *./tests/data/lavf/lavf.ogg
-13820 ./tests/data/lavf/lavf.ogg
+b55661ae1a65f99af249d8efc7619a03 *./tests/data/lavf/lavf.ogg
+13819 ./tests/data/lavf/lavf.ogg
./tests/data/lavf/lavf.ogg CRC=0xf1ae5536
diff --git a/tests/ref/lavf/ts b/tests/ref/lavf/ts
index 989f8fb..ebe6a77 100644
--- a/tests/ref/lavf/ts
+++ b/tests/ref/lavf/ts
@@ -1,3 +1,3 @@
-d260ac0534ff2e26b44b5192fd4fdc21 *./tests/data/lavf/lavf.ts
+293142d7286db15e5f4d7d1ca0d9c97c *./tests/data/lavf/lavf.ts
406644 ./tests/data/lavf/lavf.ts
./tests/data/lavf/lavf.ts CRC=0x133216c1
diff --git a/tests/ref/lavf/wav b/tests/ref/lavf/wav
index aa6f943..bbbacc3 100644
--- a/tests/ref/lavf/wav
+++ b/tests/ref/lavf/wav
@@ -1,3 +1,3 @@
-6a3bec31d92baf52161e25179ebba315 *./tests/data/lavf/lavf.wav
-90156 ./tests/data/lavf/lavf.wav
+8854ea97f2d2172383941b001c69228b *./tests/data/lavf/lavf.wav
+90158 ./tests/data/lavf/lavf.wav
./tests/data/lavf/lavf.wav CRC=0xf1ae5536
diff --git a/tests/ref/lavfi/pixdesc b/tests/ref/lavfi/pixdesc
new file mode 100644
index 0000000..a5016ee
--- /dev/null
+++ b/tests/ref/lavfi/pixdesc
@@ -0,0 +1,60 @@
+abgr 037bf9df6a765520ad6d490066bf4b89
+argb c442a8261c2265a07212ef0f72e35f5a
+bgr24 0d0cb38ab3fa0b2ec0865c14f78b217b
+bgr48be 00624e6c7ec7ab19897ba2f0a3257fe8
+bgr48le d02c235ebba7167881ca2d576497ff84
+bgr4_byte 50d23cc82d9dcef2fd12adb81fb9b806
+bgr555be 49f01b1f1f0c84fd9e776dd34cc3c280
+bgr555le 378d6ac4223651a1adcbf94a3d0d807b
+bgr565be 257cf78afa35dc31e9696f139c916715
+bgr565le 1dfdd03995c287e3c754b164bf26a355
+bgr8 24bd566170343d06fec6fccfff5abc54
+bgra 76a18a5151242fa137133f604cd624d2
+gray db08f7f0751900347e6b8649e4164d21
+gray16be 7becf34ae825a3df3969bf4c6bfeb5e2
+gray16le 10bd87059b5c189f3caef2837f4f2b5c
+monob 668ebe8b8103b9046b251b2fa8a1d88f
+monow 9251497f3b0634f1165d12d5a289d943
+nv12 e0af357888584d36eec5aa0f673793ef
+nv21 9a3297f3b34baa038b1f37cb202b512f
+rgb24 b41eba9651e1b5fe386289b506188105
+rgb48be cc139ec1dd9451f0e049c0cb3a0c8aa2
+rgb48le 86c5608904f75360d492dbc5c9589969
+rgb4_byte c93ba89b74c504e7f5ae9d9ab1546c73
+rgb555be 912a62c5e53bfcbac2a0340e10973cf2
+rgb555le a937a0fc764fb57dc1b3af87cba0273c
+rgb565be 9cadf742e05ddc23a3b5b270f89aad3c
+rgb565le d39aa298bb525e9be8860351c6f62dab
+rgb8 4a9d8e4f2f154e83a7e1735be6300700
+rgba 93a5b3712e6eb8c5b9a09ffc7b9fbc12
+uyvy422 adcf64516a19fce44df77082bdb16291
+yuv410p 2d9225153c83ee1132397d619d94d1b3
+yuv411p 8b298af3e43348ca1b11eb8a3252ac6c
+yuv420p eba2f135a08829387e2f698ff72a2939
+yuv420p10be 299fe1d785a3d3dd5e70778700d7fb06
+yuv420p10le 8aee004e765a5383be0954f5e916b72f
+yuv420p16be 16c009a235cd52b74791a895423152a3
+yuv420p16le 2d59c4f1d0314a5a957a7cfc4b6fabcc
+yuv420p9be ce880fa07830e5297c22acf6e20555ce
+yuv420p9le 16543fda8f87d94a6cf857d2e8d4461a
+yuv422p c9bba4529821d796a6ab09f6a5fd355a
+yuv422p10be 11af7dfafe8bc025c7e3bd82b830fe8a
+yuv422p10le ec04efb76efa79bf0d02b21572371a56
+yuv422p16be 5499502e1c29534a158a1fe60e889f60
+yuv422p16le e3d61fde6978591596bc36b914386623
+yuv422p9be 29b71579946940a8c00fa844c9dff507
+yuv422p9le 062b7f9cbb972bf36b5bdb1a7623701a
+yuv440p 5a064afe2b453bb52cdb3f176b1aa1cf
+yuv444p 0a98447b78fd476aa39686da6a74fa2e
+yuv444p10be 71be185a2fb7a353eb024df9bc63212d
+yuv444p10le c1c6b30a12065c7901c0a267e4861a0f
+yuv444p16be 1c6ea2c2f5e539006112ceec3d4e7d90
+yuv444p16le 20f86bc2f68d2b3f1f2b48b97b2189f4
+yuv444p9be 6ab31f4c12b533ce318ecdff83cdd054
+yuv444p9le f0606604a5c08becab6ba500124c4b7c
+yuva420p a29884f3f3dfe1e00b961bc17bef3d47
+yuvj420p 32eec78ba51857b16ce9b813a49b7189
+yuvj422p 0dfa0ed434f73be51428758c69e082cb
+yuvj440p 657501a28004e27a592757a7509f5189
+yuvj444p 98d3d054f2ec09a75eeed5d328dc75b7
+yuyv422 f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixdesc_be b/tests/ref/lavfi/pixdesc_be
deleted file mode 100644
index 830fd2a..0000000
--- a/tests/ref/lavfi/pixdesc_be
+++ /dev/null
@@ -1,48 +0,0 @@
-abgr 037bf9df6a765520ad6d490066bf4b89
-argb c442a8261c2265a07212ef0f72e35f5a
-bgr24 0d0cb38ab3fa0b2ec0865c14f78b217b
-bgr48be 4ba0ff7fc9e011ea264610ad1585bb1f
-bgr48le d022bfdd6a07d5dcc693799322a386b4
-bgr4_byte 50d23cc82d9dcef2fd12adb81fb9b806
-bgr555be 49f01b1f1f0c84fd9e776dd34cc3c280
-bgr565be 257cf78afa35dc31e9696f139c916715
-bgr8 24bd566170343d06fec6fccfff5abc54
-bgra 76a18a5151242fa137133f604cd624d2
-gray db08f7f0751900347e6b8649e4164d21
-gray16be 7becf34ae825a3df3969bf4c6bfeb5e2
-gray16le 10bd87059b5c189f3caef2837f4f2b5c
-monob 668ebe8b8103b9046b251b2fa8a1d88f
-monow 9251497f3b0634f1165d12d5a289d943
-nv12 e0af357888584d36eec5aa0f673793ef
-nv21 9a3297f3b34baa038b1f37cb202b512f
-rgb24 b41eba9651e1b5fe386289b506188105
-rgb48be 460b6de89b156290a12d3941db8bd731
-rgb48le cd93cb34d15996987367dabda3a10128
-rgb4_byte c93ba89b74c504e7f5ae9d9ab1546c73
-rgb555be 912a62c5e53bfcbac2a0340e10973cf2
-rgb565be 9cadf742e05ddc23a3b5b270f89aad3c
-rgb8 4a9d8e4f2f154e83a7e1735be6300700
-rgba 93a5b3712e6eb8c5b9a09ffc7b9fbc12
-uyvy422 adcf64516a19fce44df77082bdb16291
-yuv410p 2d9225153c83ee1132397d619d94d1b3
-yuv411p 8b298af3e43348ca1b11eb8a3252ac6c
-yuv420p eba2f135a08829387e2f698ff72a2939
-yuv420p10be 7605e266c088d0fcf68c7b27c3ceff5f
-yuv420p10le 4228ee628c6deec123a13b9784516cc7
-yuv420p16be 16c009a235cd52b74791a895423152a3
-yuv420p16le 2d59c4f1d0314a5a957a7cfc4b6fabcc
-yuv420p9be ce880fa07830e5297c22acf6e20555ce
-yuv420p9le 16543fda8f87d94a6cf857d2e8d4461a
-yuv422p c9bba4529821d796a6ab09f6a5fd355a
-yuv422p16be 5499502e1c29534a158a1fe60e889f60
-yuv422p16le e3d61fde6978591596bc36b914386623
-yuv440p 5a064afe2b453bb52cdb3f176b1aa1cf
-yuv444p 0a98447b78fd476aa39686da6a74fa2e
-yuv444p16be ea602a24b8e6969679265078bd8607b6
-yuv444p16le 1262a0dc57ee147967fc896d04206313
-yuva420p a29884f3f3dfe1e00b961bc17bef3d47
-yuvj420p 32eec78ba51857b16ce9b813a49b7189
-yuvj422p 0dfa0ed434f73be51428758c69e082cb
-yuvj440p 657501a28004e27a592757a7509f5189
-yuvj444p 98d3d054f2ec09a75eeed5d328dc75b7
-yuyv422 f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixdesc_le b/tests/ref/lavfi/pixdesc_le
deleted file mode 100644
index b5afb92..0000000
--- a/tests/ref/lavfi/pixdesc_le
+++ /dev/null
@@ -1,48 +0,0 @@
-abgr 037bf9df6a765520ad6d490066bf4b89
-argb c442a8261c2265a07212ef0f72e35f5a
-bgr24 0d0cb38ab3fa0b2ec0865c14f78b217b
-bgr48be 4ba0ff7fc9e011ea264610ad1585bb1f
-bgr48le d022bfdd6a07d5dcc693799322a386b4
-bgr4_byte 50d23cc82d9dcef2fd12adb81fb9b806
-bgr555le 378d6ac4223651a1adcbf94a3d0d807b
-bgr565le 1dfdd03995c287e3c754b164bf26a355
-bgr8 24bd566170343d06fec6fccfff5abc54
-bgra 76a18a5151242fa137133f604cd624d2
-gray db08f7f0751900347e6b8649e4164d21
-gray16be 7becf34ae825a3df3969bf4c6bfeb5e2
-gray16le 10bd87059b5c189f3caef2837f4f2b5c
-monob 668ebe8b8103b9046b251b2fa8a1d88f
-monow 9251497f3b0634f1165d12d5a289d943
-nv12 e0af357888584d36eec5aa0f673793ef
-nv21 9a3297f3b34baa038b1f37cb202b512f
-rgb24 b41eba9651e1b5fe386289b506188105
-rgb48be 460b6de89b156290a12d3941db8bd731
-rgb48le cd93cb34d15996987367dabda3a10128
-rgb4_byte c93ba89b74c504e7f5ae9d9ab1546c73
-rgb555le a937a0fc764fb57dc1b3af87cba0273c
-rgb565le d39aa298bb525e9be8860351c6f62dab
-rgb8 4a9d8e4f2f154e83a7e1735be6300700
-rgba 93a5b3712e6eb8c5b9a09ffc7b9fbc12
-uyvy422 adcf64516a19fce44df77082bdb16291
-yuv410p 2d9225153c83ee1132397d619d94d1b3
-yuv411p 8b298af3e43348ca1b11eb8a3252ac6c
-yuv420p eba2f135a08829387e2f698ff72a2939
-yuv420p10be 7605e266c088d0fcf68c7b27c3ceff5f
-yuv420p10le 4228ee628c6deec123a13b9784516cc7
-yuv420p16be 16c009a235cd52b74791a895423152a3
-yuv420p16le 2d59c4f1d0314a5a957a7cfc4b6fabcc
-yuv420p9be ce880fa07830e5297c22acf6e20555ce
-yuv420p9le 16543fda8f87d94a6cf857d2e8d4461a
-yuv422p c9bba4529821d796a6ab09f6a5fd355a
-yuv422p16be 5499502e1c29534a158a1fe60e889f60
-yuv422p16le e3d61fde6978591596bc36b914386623
-yuv440p 5a064afe2b453bb52cdb3f176b1aa1cf
-yuv444p 0a98447b78fd476aa39686da6a74fa2e
-yuv444p16be ea602a24b8e6969679265078bd8607b6
-yuv444p16le 1262a0dc57ee147967fc896d04206313
-yuva420p a29884f3f3dfe1e00b961bc17bef3d47
-yuvj420p 32eec78ba51857b16ce9b813a49b7189
-yuvj422p 0dfa0ed434f73be51428758c69e082cb
-yuvj440p 657501a28004e27a592757a7509f5189
-yuvj444p 98d3d054f2ec09a75eeed5d328dc75b7
-yuyv422 f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_copy b/tests/ref/lavfi/pixfmts_copy
new file mode 100644
index 0000000..a5016ee
--- /dev/null
+++ b/tests/ref/lavfi/pixfmts_copy
@@ -0,0 +1,60 @@
+abgr 037bf9df6a765520ad6d490066bf4b89
+argb c442a8261c2265a07212ef0f72e35f5a
+bgr24 0d0cb38ab3fa0b2ec0865c14f78b217b
+bgr48be 00624e6c7ec7ab19897ba2f0a3257fe8
+bgr48le d02c235ebba7167881ca2d576497ff84
+bgr4_byte 50d23cc82d9dcef2fd12adb81fb9b806
+bgr555be 49f01b1f1f0c84fd9e776dd34cc3c280
+bgr555le 378d6ac4223651a1adcbf94a3d0d807b
+bgr565be 257cf78afa35dc31e9696f139c916715
+bgr565le 1dfdd03995c287e3c754b164bf26a355
+bgr8 24bd566170343d06fec6fccfff5abc54
+bgra 76a18a5151242fa137133f604cd624d2
+gray db08f7f0751900347e6b8649e4164d21
+gray16be 7becf34ae825a3df3969bf4c6bfeb5e2
+gray16le 10bd87059b5c189f3caef2837f4f2b5c
+monob 668ebe8b8103b9046b251b2fa8a1d88f
+monow 9251497f3b0634f1165d12d5a289d943
+nv12 e0af357888584d36eec5aa0f673793ef
+nv21 9a3297f3b34baa038b1f37cb202b512f
+rgb24 b41eba9651e1b5fe386289b506188105
+rgb48be cc139ec1dd9451f0e049c0cb3a0c8aa2
+rgb48le 86c5608904f75360d492dbc5c9589969
+rgb4_byte c93ba89b74c504e7f5ae9d9ab1546c73
+rgb555be 912a62c5e53bfcbac2a0340e10973cf2
+rgb555le a937a0fc764fb57dc1b3af87cba0273c
+rgb565be 9cadf742e05ddc23a3b5b270f89aad3c
+rgb565le d39aa298bb525e9be8860351c6f62dab
+rgb8 4a9d8e4f2f154e83a7e1735be6300700
+rgba 93a5b3712e6eb8c5b9a09ffc7b9fbc12
+uyvy422 adcf64516a19fce44df77082bdb16291
+yuv410p 2d9225153c83ee1132397d619d94d1b3
+yuv411p 8b298af3e43348ca1b11eb8a3252ac6c
+yuv420p eba2f135a08829387e2f698ff72a2939
+yuv420p10be 299fe1d785a3d3dd5e70778700d7fb06
+yuv420p10le 8aee004e765a5383be0954f5e916b72f
+yuv420p16be 16c009a235cd52b74791a895423152a3
+yuv420p16le 2d59c4f1d0314a5a957a7cfc4b6fabcc
+yuv420p9be ce880fa07830e5297c22acf6e20555ce
+yuv420p9le 16543fda8f87d94a6cf857d2e8d4461a
+yuv422p c9bba4529821d796a6ab09f6a5fd355a
+yuv422p10be 11af7dfafe8bc025c7e3bd82b830fe8a
+yuv422p10le ec04efb76efa79bf0d02b21572371a56
+yuv422p16be 5499502e1c29534a158a1fe60e889f60
+yuv422p16le e3d61fde6978591596bc36b914386623
+yuv422p9be 29b71579946940a8c00fa844c9dff507
+yuv422p9le 062b7f9cbb972bf36b5bdb1a7623701a
+yuv440p 5a064afe2b453bb52cdb3f176b1aa1cf
+yuv444p 0a98447b78fd476aa39686da6a74fa2e
+yuv444p10be 71be185a2fb7a353eb024df9bc63212d
+yuv444p10le c1c6b30a12065c7901c0a267e4861a0f
+yuv444p16be 1c6ea2c2f5e539006112ceec3d4e7d90
+yuv444p16le 20f86bc2f68d2b3f1f2b48b97b2189f4
+yuv444p9be 6ab31f4c12b533ce318ecdff83cdd054
+yuv444p9le f0606604a5c08becab6ba500124c4b7c
+yuva420p a29884f3f3dfe1e00b961bc17bef3d47
+yuvj420p 32eec78ba51857b16ce9b813a49b7189
+yuvj422p 0dfa0ed434f73be51428758c69e082cb
+yuvj440p 657501a28004e27a592757a7509f5189
+yuvj444p 98d3d054f2ec09a75eeed5d328dc75b7
+yuyv422 f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_copy_le b/tests/ref/lavfi/pixfmts_copy_le
deleted file mode 100644
index b5afb92..0000000
--- a/tests/ref/lavfi/pixfmts_copy_le
+++ /dev/null
@@ -1,48 +0,0 @@
-abgr 037bf9df6a765520ad6d490066bf4b89
-argb c442a8261c2265a07212ef0f72e35f5a
-bgr24 0d0cb38ab3fa0b2ec0865c14f78b217b
-bgr48be 4ba0ff7fc9e011ea264610ad1585bb1f
-bgr48le d022bfdd6a07d5dcc693799322a386b4
-bgr4_byte 50d23cc82d9dcef2fd12adb81fb9b806
-bgr555le 378d6ac4223651a1adcbf94a3d0d807b
-bgr565le 1dfdd03995c287e3c754b164bf26a355
-bgr8 24bd566170343d06fec6fccfff5abc54
-bgra 76a18a5151242fa137133f604cd624d2
-gray db08f7f0751900347e6b8649e4164d21
-gray16be 7becf34ae825a3df3969bf4c6bfeb5e2
-gray16le 10bd87059b5c189f3caef2837f4f2b5c
-monob 668ebe8b8103b9046b251b2fa8a1d88f
-monow 9251497f3b0634f1165d12d5a289d943
-nv12 e0af357888584d36eec5aa0f673793ef
-nv21 9a3297f3b34baa038b1f37cb202b512f
-rgb24 b41eba9651e1b5fe386289b506188105
-rgb48be 460b6de89b156290a12d3941db8bd731
-rgb48le cd93cb34d15996987367dabda3a10128
-rgb4_byte c93ba89b74c504e7f5ae9d9ab1546c73
-rgb555le a937a0fc764fb57dc1b3af87cba0273c
-rgb565le d39aa298bb525e9be8860351c6f62dab
-rgb8 4a9d8e4f2f154e83a7e1735be6300700
-rgba 93a5b3712e6eb8c5b9a09ffc7b9fbc12
-uyvy422 adcf64516a19fce44df77082bdb16291
-yuv410p 2d9225153c83ee1132397d619d94d1b3
-yuv411p 8b298af3e43348ca1b11eb8a3252ac6c
-yuv420p eba2f135a08829387e2f698ff72a2939
-yuv420p10be 7605e266c088d0fcf68c7b27c3ceff5f
-yuv420p10le 4228ee628c6deec123a13b9784516cc7
-yuv420p16be 16c009a235cd52b74791a895423152a3
-yuv420p16le 2d59c4f1d0314a5a957a7cfc4b6fabcc
-yuv420p9be ce880fa07830e5297c22acf6e20555ce
-yuv420p9le 16543fda8f87d94a6cf857d2e8d4461a
-yuv422p c9bba4529821d796a6ab09f6a5fd355a
-yuv422p16be 5499502e1c29534a158a1fe60e889f60
-yuv422p16le e3d61fde6978591596bc36b914386623
-yuv440p 5a064afe2b453bb52cdb3f176b1aa1cf
-yuv444p 0a98447b78fd476aa39686da6a74fa2e
-yuv444p16be ea602a24b8e6969679265078bd8607b6
-yuv444p16le 1262a0dc57ee147967fc896d04206313
-yuva420p a29884f3f3dfe1e00b961bc17bef3d47
-yuvj420p 32eec78ba51857b16ce9b813a49b7189
-yuvj422p 0dfa0ed434f73be51428758c69e082cb
-yuvj440p 657501a28004e27a592757a7509f5189
-yuvj444p 98d3d054f2ec09a75eeed5d328dc75b7
-yuyv422 f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_crop b/tests/ref/lavfi/pixfmts_crop
new file mode 100644
index 0000000..cbbcf90
--- /dev/null
+++ b/tests/ref/lavfi/pixfmts_crop
@@ -0,0 +1,42 @@
+abgr cd761690872843d1b7ab0c695393c751
+argb 2ec6ef18769bcd651c2e8904d5a3ee67
+bgr24 3450fd00cf1493d1ded75544d82ba3ec
+bgr48be 18ca4002732f278cc9f525215c2fca41
+bgr48le 395a4c187c4e95217d089bd3df9f3654
+bgr4_byte 2f6ac3cdd4676ab4e2982bdf0664945b
+bgr555be d3a7c273604723adeb7e5f5dd1c4272b
+bgr555le d22442fc13b464f9ba455b08df4e981f
+bgr565be fadceef4a64ad6873fcb43ddee0deb3c
+bgr565le 891664e5a54ae5968901347da92bc5e9
+bgr8 4b7159e05765bd4703180072d86423c8
+bgra 395c9f706fccda721471acaa5c96c16c
+gray 8c4850e66562a587a292dc728a65ea4a
+gray16be daa5a6b98fb4a280c57c57bff1a2ab5a
+gray16le 84f5ea7259073edcb893113b42213c8e
+rgb24 3b90ed64b687d3dc186c6ef521dc71a8
+rgb48be e6fd353c0eb9bea889423954414bea35
+rgb48le 68a1723da11ce08b502d42e204376503
+rgb4_byte 6958029f73c6cdfed4f71020d816f027
+rgb555be 41a7d1836837bc90f2cae19a9c9df3b3
+rgb555le eeb78f8ce6186fba55c941469e60ba67
+rgb565be b2d1cb525f3a0cfe27753c0d479b2fa9
+rgb565le 6a49700680be9a0d434411825a769556
+rgb8 88b0398c265d1ed7a837dc084fa0917c
+rgba fd00b24c7597268c32759a84a1de2de4
+yuv410p a9f2eaa747bf988b7bebe4f442b9c67a
+yuv411p 3334d3aef8dba238658090ac172375d1
+yuv420p bfea0188ddd4889787c403caae119cc7
+yuv420p16be 8365eff38b8c329aeb95fc605fa229bb
+yuv420p16le 5e8dd38d973d5854abe1ad4efad20cc1
+yuv422p f2f930a91fe00d4252c4720b5ecd8961
+yuv422p16be 167e4338811a7d272925a4c6417d60da
+yuv422p16le 3359395d5875d581fa1e975013d30114
+yuv440p 2472417d980e395ad6843cbb8b633b29
+yuv444p 1f151980486848c96bc5585ced99003e
+yuv444p16be 1ce8fcd4712d525af983e6179d6a4f9e
+yuv444p16le 5f1441e18345aadb3f881dac99c6c08a
+yuva420p 7536753dfbc7932560fb50c921369a0e
+yuvj420p 21f891093006d42d7683b0e1d773a657
+yuvj422p 9a43d474c407590ad8f213880586b45e
+yuvj440p 977351350450ebdbf7a9d20020c6b5a5
+yuvj444p 4a50ba26859dad91dcf7000de0d0efa1
diff --git a/tests/ref/lavfi/pixfmts_crop_le b/tests/ref/lavfi/pixfmts_crop_le
deleted file mode 100644
index 01da415..0000000
--- a/tests/ref/lavfi/pixfmts_crop_le
+++ /dev/null
@@ -1,38 +0,0 @@
-abgr cd761690872843d1b7ab0c695393c751
-argb 2ec6ef18769bcd651c2e8904d5a3ee67
-bgr24 3450fd00cf1493d1ded75544d82ba3ec
-bgr48be 90cb5d373a1123432d63c6a10c101afa
-bgr48le 9371f54ceda9010f1199e86f4930ac3f
-bgr4_byte 2f6ac3cdd4676ab4e2982bdf0664945b
-bgr555le d22442fc13b464f9ba455b08df4e981f
-bgr565le 891664e5a54ae5968901347da92bc5e9
-bgr8 4b7159e05765bd4703180072d86423c8
-bgra 395c9f706fccda721471acaa5c96c16c
-gray 8c4850e66562a587a292dc728a65ea4a
-gray16be daa5a6b98fb4a280c57c57bff1a2ab5a
-gray16le 84f5ea7259073edcb893113b42213c8e
-rgb24 3b90ed64b687d3dc186c6ef521dc71a8
-rgb48be a808128041a1962deaa8620c7448feba
-rgb48le ce92d02cc322608d5be377cb1940677b
-rgb4_byte 6958029f73c6cdfed4f71020d816f027
-rgb555le eeb78f8ce6186fba55c941469e60ba67
-rgb565le 6a49700680be9a0d434411825a769556
-rgb8 88b0398c265d1ed7a837dc084fa0917c
-rgba fd00b24c7597268c32759a84a1de2de4
-yuv410p a9f2eaa747bf988b7bebe4f442b9c67a
-yuv411p 3334d3aef8dba238658090ac172375d1
-yuv420p bfea0188ddd4889787c403caae119cc7
-yuv420p16be 8365eff38b8c329aeb95fc605fa229bb
-yuv420p16le 5e8dd38d973d5854abe1ad4efad20cc1
-yuv422p f2f930a91fe00d4252c4720b5ecd8961
-yuv422p16be 167e4338811a7d272925a4c6417d60da
-yuv422p16le 3359395d5875d581fa1e975013d30114
-yuv440p 2472417d980e395ad6843cbb8b633b29
-yuv444p 1f151980486848c96bc5585ced99003e
-yuv444p16be d69280c2856865d2ea94bd5292aac1c6
-yuv444p16le 33f43e030bedf9723be4f63c3e9fc80e
-yuva420p 7536753dfbc7932560fb50c921369a0e
-yuvj420p 21f891093006d42d7683b0e1d773a657
-yuvj422p 9a43d474c407590ad8f213880586b45e
-yuvj440p 977351350450ebdbf7a9d20020c6b5a5
-yuvj444p 4a50ba26859dad91dcf7000de0d0efa1
diff --git a/tests/ref/lavfi/pixfmts_hflip b/tests/ref/lavfi/pixfmts_hflip
new file mode 100644
index 0000000..3741713
--- /dev/null
+++ b/tests/ref/lavfi/pixfmts_hflip
@@ -0,0 +1,42 @@
+abgr 49468c6c9ceee5d52b08b1270a909323
+argb 50ba9f16c6475530602f2983278b82d0
+bgr24 cc53d2011d097972db0d22756c3699e3
+bgr48be 815192d3757c66de97b0d51818acbe0f
+bgr48le 8e4184ac6eae251b4bace51dba7d790c
+bgr4_byte aac987e7d1a6a96477cfc0b48a4285de
+bgr555be bc07265898440116772200390d70c092
+bgr555le ccee08679bac84a1f960c6c9070c5538
+bgr565be e088789ce46224b87c6e46610ef19add
+bgr565le 3703466e19e1b52e03a34fd244a8e8e4
+bgr8 50b505a889f0428242305acb642da107
+bgra 01ca21e7e6a8d1281b4553bde8e8a404
+gray 03efcb4ab52a24c0af0e03cfd26c9377
+gray16be 9bcbca979601ddc4869f846f08f3d1dd
+gray16le c1b8965adcc7f847ee343149ff507073
+rgb24 754f1722fc738590cc407ac65749bfe8
+rgb48be d690412ca5fada031b5da47b87096248
+rgb48le c901feb564232f5d0bc0eabd66dae3e7
+rgb4_byte c8a3f995fcf3e0919239ea2c413ddc29
+rgb555be 045ce8607d3910586f4d97481dda8632
+rgb555le 8778ee0cf58ce9ad1d99a1eca9f95e87
+rgb565be c8022a1b2470e72f124e4389fad4c372
+rgb565le 2cb690eb3fcb72da3771ad6a48931158
+rgb8 9e462b811b9b6173397b9cfc1f6b2f17
+rgba d3d0dc1ecef3ed72f26a2986d0efc204
+yuv410p acb543ebbbf63eefe533e6faffc006da
+yuv411p c626cf6d191139b4ca7efc0155f957f1
+yuv420p 2d5c80f9ba2ddd85b2aeda3564cc7d64
+yuv420p16be 758b0c1e2113b15e7afde48da4e4d024
+yuv420p16le 480ccd951dcb806bc875d307e02e50a0
+yuv422p 6e728f4eb9eae287c224f396d84be6ea
+yuv422p16be a05d43cd62b790087bd37083174557de
+yuv422p16le 6954abebcbc62d81068d58d0c62bdd5b
+yuv440p a99e2b57ed601f39852715c9d675d0d3
+yuv444p 947e47f7bb5fdccc659d19b7df2b6fc3
+yuv444p16be 58c012e5ab73b066ef3c2b6411a395f1
+yuv444p16le 32c12794e184042a59738ab2de608c8d
+yuva420p d83ec0c01498189f179ec574918185f1
+yuvj420p df3aaaec3bb157c3bde5f0365af30f4f
+yuvj422p d113871528d510a192797af59df9c05c
+yuvj440p 07f5ff12ced85aba1b5cf51692fff4bb
+yuvj444p 8d95f6b4d4c9b4b0389d36df686bfa46
diff --git a/tests/ref/lavfi/pixfmts_hflip_le b/tests/ref/lavfi/pixfmts_hflip_le
deleted file mode 100644
index 514eed7..0000000
--- a/tests/ref/lavfi/pixfmts_hflip_le
+++ /dev/null
@@ -1,38 +0,0 @@
-abgr 49468c6c9ceee5d52b08b1270a909323
-argb 50ba9f16c6475530602f2983278b82d0
-bgr24 cc53d2011d097972db0d22756c3699e3
-bgr48be 11641cf0f4516a9aed98f7872720f801
-bgr48le b5440734eed128554dd9f83b34ba582f
-bgr4_byte aac987e7d1a6a96477cfc0b48a4285de
-bgr555le ccee08679bac84a1f960c6c9070c5538
-bgr565le 3703466e19e1b52e03a34fd244a8e8e4
-bgr8 50b505a889f0428242305acb642da107
-bgra 01ca21e7e6a8d1281b4553bde8e8a404
-gray 03efcb4ab52a24c0af0e03cfd26c9377
-gray16be 9bcbca979601ddc4869f846f08f3d1dd
-gray16le c1b8965adcc7f847ee343149ff507073
-rgb24 754f1722fc738590cc407ac65749bfe8
-rgb48be 10743e1577dc3198dbbc7c0b3b8f429e
-rgb48le dd945a44f39119221407bf7a04f1bc49
-rgb4_byte c8a3f995fcf3e0919239ea2c413ddc29
-rgb555le 8778ee0cf58ce9ad1d99a1eca9f95e87
-rgb565le 2cb690eb3fcb72da3771ad6a48931158
-rgb8 9e462b811b9b6173397b9cfc1f6b2f17
-rgba d3d0dc1ecef3ed72f26a2986d0efc204
-yuv410p acb543ebbbf63eefe533e6faffc006da
-yuv411p c626cf6d191139b4ca7efc0155f957f1
-yuv420p 2d5c80f9ba2ddd85b2aeda3564cc7d64
-yuv420p16be 758b0c1e2113b15e7afde48da4e4d024
-yuv420p16le 480ccd951dcb806bc875d307e02e50a0
-yuv422p 6e728f4eb9eae287c224f396d84be6ea
-yuv422p16be a05d43cd62b790087bd37083174557de
-yuv422p16le 6954abebcbc62d81068d58d0c62bdd5b
-yuv440p a99e2b57ed601f39852715c9d675d0d3
-yuv444p 947e47f7bb5fdccc659d19b7df2b6fc3
-yuv444p16be e5ef45bc3d2f5b0b2542d5151340c382
-yuv444p16le 70793e3d66d0c23a0cdedabe9c24c2a7
-yuva420p d83ec0c01498189f179ec574918185f1
-yuvj420p df3aaaec3bb157c3bde5f0365af30f4f
-yuvj422p d113871528d510a192797af59df9c05c
-yuvj440p 07f5ff12ced85aba1b5cf51692fff4bb
-yuvj444p 8d95f6b4d4c9b4b0389d36df686bfa46
diff --git a/tests/ref/lavfi/pixfmts_null b/tests/ref/lavfi/pixfmts_null
new file mode 100644
index 0000000..a5016ee
--- /dev/null
+++ b/tests/ref/lavfi/pixfmts_null
@@ -0,0 +1,60 @@
+abgr 037bf9df6a765520ad6d490066bf4b89
+argb c442a8261c2265a07212ef0f72e35f5a
+bgr24 0d0cb38ab3fa0b2ec0865c14f78b217b
+bgr48be 00624e6c7ec7ab19897ba2f0a3257fe8
+bgr48le d02c235ebba7167881ca2d576497ff84
+bgr4_byte 50d23cc82d9dcef2fd12adb81fb9b806
+bgr555be 49f01b1f1f0c84fd9e776dd34cc3c280
+bgr555le 378d6ac4223651a1adcbf94a3d0d807b
+bgr565be 257cf78afa35dc31e9696f139c916715
+bgr565le 1dfdd03995c287e3c754b164bf26a355
+bgr8 24bd566170343d06fec6fccfff5abc54
+bgra 76a18a5151242fa137133f604cd624d2
+gray db08f7f0751900347e6b8649e4164d21
+gray16be 7becf34ae825a3df3969bf4c6bfeb5e2
+gray16le 10bd87059b5c189f3caef2837f4f2b5c
+monob 668ebe8b8103b9046b251b2fa8a1d88f
+monow 9251497f3b0634f1165d12d5a289d943
+nv12 e0af357888584d36eec5aa0f673793ef
+nv21 9a3297f3b34baa038b1f37cb202b512f
+rgb24 b41eba9651e1b5fe386289b506188105
+rgb48be cc139ec1dd9451f0e049c0cb3a0c8aa2
+rgb48le 86c5608904f75360d492dbc5c9589969
+rgb4_byte c93ba89b74c504e7f5ae9d9ab1546c73
+rgb555be 912a62c5e53bfcbac2a0340e10973cf2
+rgb555le a937a0fc764fb57dc1b3af87cba0273c
+rgb565be 9cadf742e05ddc23a3b5b270f89aad3c
+rgb565le d39aa298bb525e9be8860351c6f62dab
+rgb8 4a9d8e4f2f154e83a7e1735be6300700
+rgba 93a5b3712e6eb8c5b9a09ffc7b9fbc12
+uyvy422 adcf64516a19fce44df77082bdb16291
+yuv410p 2d9225153c83ee1132397d619d94d1b3
+yuv411p 8b298af3e43348ca1b11eb8a3252ac6c
+yuv420p eba2f135a08829387e2f698ff72a2939
+yuv420p10be 299fe1d785a3d3dd5e70778700d7fb06
+yuv420p10le 8aee004e765a5383be0954f5e916b72f
+yuv420p16be 16c009a235cd52b74791a895423152a3
+yuv420p16le 2d59c4f1d0314a5a957a7cfc4b6fabcc
+yuv420p9be ce880fa07830e5297c22acf6e20555ce
+yuv420p9le 16543fda8f87d94a6cf857d2e8d4461a
+yuv422p c9bba4529821d796a6ab09f6a5fd355a
+yuv422p10be 11af7dfafe8bc025c7e3bd82b830fe8a
+yuv422p10le ec04efb76efa79bf0d02b21572371a56
+yuv422p16be 5499502e1c29534a158a1fe60e889f60
+yuv422p16le e3d61fde6978591596bc36b914386623
+yuv422p9be 29b71579946940a8c00fa844c9dff507
+yuv422p9le 062b7f9cbb972bf36b5bdb1a7623701a
+yuv440p 5a064afe2b453bb52cdb3f176b1aa1cf
+yuv444p 0a98447b78fd476aa39686da6a74fa2e
+yuv444p10be 71be185a2fb7a353eb024df9bc63212d
+yuv444p10le c1c6b30a12065c7901c0a267e4861a0f
+yuv444p16be 1c6ea2c2f5e539006112ceec3d4e7d90
+yuv444p16le 20f86bc2f68d2b3f1f2b48b97b2189f4
+yuv444p9be 6ab31f4c12b533ce318ecdff83cdd054
+yuv444p9le f0606604a5c08becab6ba500124c4b7c
+yuva420p a29884f3f3dfe1e00b961bc17bef3d47
+yuvj420p 32eec78ba51857b16ce9b813a49b7189
+yuvj422p 0dfa0ed434f73be51428758c69e082cb
+yuvj440p 657501a28004e27a592757a7509f5189
+yuvj444p 98d3d054f2ec09a75eeed5d328dc75b7
+yuyv422 f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_null_le b/tests/ref/lavfi/pixfmts_null_le
deleted file mode 100644
index b5afb92..0000000
--- a/tests/ref/lavfi/pixfmts_null_le
+++ /dev/null
@@ -1,48 +0,0 @@
-abgr 037bf9df6a765520ad6d490066bf4b89
-argb c442a8261c2265a07212ef0f72e35f5a
-bgr24 0d0cb38ab3fa0b2ec0865c14f78b217b
-bgr48be 4ba0ff7fc9e011ea264610ad1585bb1f
-bgr48le d022bfdd6a07d5dcc693799322a386b4
-bgr4_byte 50d23cc82d9dcef2fd12adb81fb9b806
-bgr555le 378d6ac4223651a1adcbf94a3d0d807b
-bgr565le 1dfdd03995c287e3c754b164bf26a355
-bgr8 24bd566170343d06fec6fccfff5abc54
-bgra 76a18a5151242fa137133f604cd624d2
-gray db08f7f0751900347e6b8649e4164d21
-gray16be 7becf34ae825a3df3969bf4c6bfeb5e2
-gray16le 10bd87059b5c189f3caef2837f4f2b5c
-monob 668ebe8b8103b9046b251b2fa8a1d88f
-monow 9251497f3b0634f1165d12d5a289d943
-nv12 e0af357888584d36eec5aa0f673793ef
-nv21 9a3297f3b34baa038b1f37cb202b512f
-rgb24 b41eba9651e1b5fe386289b506188105
-rgb48be 460b6de89b156290a12d3941db8bd731
-rgb48le cd93cb34d15996987367dabda3a10128
-rgb4_byte c93ba89b74c504e7f5ae9d9ab1546c73
-rgb555le a937a0fc764fb57dc1b3af87cba0273c
-rgb565le d39aa298bb525e9be8860351c6f62dab
-rgb8 4a9d8e4f2f154e83a7e1735be6300700
-rgba 93a5b3712e6eb8c5b9a09ffc7b9fbc12
-uyvy422 adcf64516a19fce44df77082bdb16291
-yuv410p 2d9225153c83ee1132397d619d94d1b3
-yuv411p 8b298af3e43348ca1b11eb8a3252ac6c
-yuv420p eba2f135a08829387e2f698ff72a2939
-yuv420p10be 7605e266c088d0fcf68c7b27c3ceff5f
-yuv420p10le 4228ee628c6deec123a13b9784516cc7
-yuv420p16be 16c009a235cd52b74791a895423152a3
-yuv420p16le 2d59c4f1d0314a5a957a7cfc4b6fabcc
-yuv420p9be ce880fa07830e5297c22acf6e20555ce
-yuv420p9le 16543fda8f87d94a6cf857d2e8d4461a
-yuv422p c9bba4529821d796a6ab09f6a5fd355a
-yuv422p16be 5499502e1c29534a158a1fe60e889f60
-yuv422p16le e3d61fde6978591596bc36b914386623
-yuv440p 5a064afe2b453bb52cdb3f176b1aa1cf
-yuv444p 0a98447b78fd476aa39686da6a74fa2e
-yuv444p16be ea602a24b8e6969679265078bd8607b6
-yuv444p16le 1262a0dc57ee147967fc896d04206313
-yuva420p a29884f3f3dfe1e00b961bc17bef3d47
-yuvj420p 32eec78ba51857b16ce9b813a49b7189
-yuvj422p 0dfa0ed434f73be51428758c69e082cb
-yuvj440p 657501a28004e27a592757a7509f5189
-yuvj444p 98d3d054f2ec09a75eeed5d328dc75b7
-yuyv422 f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_pad_le b/tests/ref/lavfi/pixfmts_pad
similarity index 100%
rename from tests/ref/lavfi/pixfmts_pad_le
rename to tests/ref/lavfi/pixfmts_pad
diff --git a/tests/ref/lavfi/pixfmts_scale b/tests/ref/lavfi/pixfmts_scale
new file mode 100644
index 0000000..7abe0d7
--- /dev/null
+++ b/tests/ref/lavfi/pixfmts_scale
@@ -0,0 +1,60 @@
+abgr d894cb97f6c80eb21bdbe8a4eea62d86
+argb 54346f2b2eef10919e0f247241df3b24
+bgr24 570f8d6b51a838aed022ef67535f6bdc
+bgr48be 390d3058a12a99c2b153ed7922508bea
+bgr48le 39fe06feb4ec1d9730dccc04a0cfac4c
+bgr4_byte ee1d35a7baf8e9016891929a2f565c0b
+bgr555be de8901c1358834fddea060fcb3a67beb
+bgr555le 36b745067197f9ca8c1731cac51329c9
+bgr565be 922a2503767036ae9536f4f7823c04ee
+bgr565le 3a514a298c6161a071ddf9963c06509d
+bgr8 7f007fa6c153a16e808a9c51605a4016
+bgra a5e7040f9a80cccd65e5acf2ca09ace5
+gray d7786a7d9d99ac74230cc045cab5632c
+gray16be b554d6c1cc8da23967445be4dd3e4a86
+gray16le 715a33aa1c19cb26b14f5cc000e7a3d1
+monob 88c4c050758e64d120f50c7eff694381
+monow d31772ebaa877fc2a78565937f7f9673
+nv12 4676d59db43d657dc12841f6bc3ab452
+nv21 69c699510ff1fb777b118ebee1002f14
+rgb24 514692e28e8ff6860e415ce4fcf6eb8c
+rgb48be 8fac63787a711886030f8e056872b488
+rgb48le ab92f2763a2eb264c3870cc758f97149
+rgb4_byte d81ffd3add95842a618eec81024f0b5c
+rgb555be 4607309f9f217d51cbb53d13b84b4537
+rgb555le a350ef1dc2c9688ed49e7ba018843795
+rgb565be 678ce231c4ea13629c1353b1df4ffbef
+rgb565le 6f4bb711238baa762d73305213f8d035
+rgb8 091d0170b354ef0e97312b95feb5483f
+rgba a3d362f222098a00e63867f612018659
+uyvy422 314bd486277111a95d9369b944fa0400
+yuv410p 7df8f6d69b56a8dcb6c7ee908e5018b5
+yuv411p 1143e7c5cc28fe0922b051b17733bc4c
+yuv420p fdad2d8df8985e3d17e73c71f713cb14
+yuv420p10be 27f28a6e09b1c04d0f755035a5db1f43
+yuv420p10le a5a1692e026590ba2eddb46b9b827529
+yuv420p16be d7270efce54eb59c7b01c14157a1b890
+yuv420p16le e85abf00bad940a922b623c91c9026d7
+yuv420p9be bb87fddca65d1742412c8d2b1caf96c6
+yuv420p9le 828eec50014a41258a5423c1fe56ac97
+yuv422p 918e37701ee7377d16a8a6c119c56a40
+yuv422p10be 315654908d50718e175aae018c484732
+yuv422p10le 91bbc78a9a56f659b55abc17722dcc09
+yuv422p16be e7e34fe9264784763ab6cb406524c0f3
+yuv422p16le c435b76b08204dda6908640fb5fd4621
+yuv422p9be 82494823944912f73cebc58ad2979bbd
+yuv422p9le fc69c8a21f473916a4b4225636b97e06
+yuv440p 461503fdb9b90451020aa3b25ddf041c
+yuv444p 81b2eba962d12e8d64f003ac56f6faf2
+yuv444p10be fb304d77c6d2e18df5938662a22176f0
+yuv444p10le b17136913eb066dca6be6af645b9f7e8
+yuv444p16be 0da9bed80f5542682ab286f3261cf24c
+yuv444p16le a0c5d3c7bf3f181db503cf8e450d1335
+yuv444p9be 9ac2643ce7f7e5c4e17c8c9fd8494d4a
+yuv444p9le 896a1cc9cccca1ba410dd53942d33cc4
+yuva420p 8673a9131fb47de69788863f93a50eb7
+yuvj420p 30427bd6caf5bda93a173dbebe759e09
+yuvj422p fc8288f64fd149573f73cf8da05d8e6d
+yuvj440p 508ac7a9ddeb6d1794a1100ba7a1664c
+yuvj444p 73aebe144085b22d1189caf6ca07e18c
+yuyv422 169e19ac91b257bd84ace0fdf56559ad
diff --git a/tests/ref/lavfi/pixfmts_scale_le b/tests/ref/lavfi/pixfmts_scale_le
deleted file mode 100644
index 275dce8..0000000
--- a/tests/ref/lavfi/pixfmts_scale_le
+++ /dev/null
@@ -1,48 +0,0 @@
-abgr d894cb97f6c80eb21bdbe8a4eea62d86
-argb 54346f2b2eef10919e0f247241df3b24
-bgr24 570f8d6b51a838aed022ef67535f6bdc
-bgr48be fcc0f2dbf45d325f84f816c74cbeeebe
-bgr48le 3f9c2b23eed3b8d196d1c14b38ce50f5
-bgr4_byte ee1d35a7baf8e9016891929a2f565c0b
-bgr555le 36b745067197f9ca8c1731cac51329c9
-bgr565le 3a514a298c6161a071ddf9963c06509d
-bgr8 7f007fa6c153a16e808a9c51605a4016
-bgra a5e7040f9a80cccd65e5acf2ca09ace5
-gray d7786a7d9d99ac74230cc045cab5632c
-gray16be af39ce3a497f6734b157c8b94544f537
-gray16le 7ac1b788bcc472010df7a97e762485e0
-monob 88c4c050758e64d120f50c7eff694381
-monow d31772ebaa877fc2a78565937f7f9673
-nv12 4676d59db43d657dc12841f6bc3ab452
-nv21 69c699510ff1fb777b118ebee1002f14
-rgb24 514692e28e8ff6860e415ce4fcf6eb8c
-rgb48be 1894cd30dabcd3180518e4d5f09f25e7
-rgb48le 1354e6e27ce3c1d4d4989ee56030c94b
-rgb4_byte d81ffd3add95842a618eec81024f0b5c
-rgb555le a350ef1dc2c9688ed49e7ba018843795
-rgb565le 6f4bb711238baa762d73305213f8d035
-rgb8 091d0170b354ef0e97312b95feb5483f
-rgba a3d362f222098a00e63867f612018659
-uyvy422 314bd486277111a95d9369b944fa0400
-yuv410p 7df8f6d69b56a8dcb6c7ee908e5018b5
-yuv411p 1143e7c5cc28fe0922b051b17733bc4c
-yuv420p fdad2d8df8985e3d17e73c71f713cb14
-yuv420p10be 6d335e75b553da590135cf8bb999610c
-yuv420p10le d510ddbabefd03ef39ec943fcb51b709
-yuv420p16be 29a0265764530070f5cd3251cc01f66a
-yuv420p16le 6f3a265b084a78baec229238d9f7945f
-yuv420p9be ec4983b7a949c0472110a7a2c58e278a
-yuv420p9le c136dce5913a722eee44ab72cff664b2
-yuv422p 918e37701ee7377d16a8a6c119c56a40
-yuv422p16be ef3e865fc1d0c68977c735323c50af6e
-yuv422p16le 428a9b96214c09cb5a983ce36d6961ff
-yuv440p 461503fdb9b90451020aa3b25ddf041c
-yuv444p 81b2eba962d12e8d64f003ac56f6faf2
-yuv444p16be 99a3738c70c8fbdc5a0e4ad4bf50648d
-yuv444p16le 385d0cc5240d62da0871915be5d86f0a
-yuva420p 8673a9131fb47de69788863f93a50eb7
-yuvj420p 30427bd6caf5bda93a173dbebe759e09
-yuvj422p fc8288f64fd149573f73cf8da05d8e6d
-yuvj440p 508ac7a9ddeb6d1794a1100ba7a1664c
-yuvj444p 73aebe144085b22d1189caf6ca07e18c
-yuyv422 169e19ac91b257bd84ace0fdf56559ad
diff --git a/tests/ref/lavfi/pixfmts_vflip b/tests/ref/lavfi/pixfmts_vflip
new file mode 100644
index 0000000..e834394
--- /dev/null
+++ b/tests/ref/lavfi/pixfmts_vflip
@@ -0,0 +1,60 @@
+abgr 25e72e9dbd01ab00727c976d577f7be5
+argb 19869bf1a5ac0b6af4d8bbe2c104533c
+bgr24 89108a4ba00201f79b75b9305c42352d
+bgr48be 2f23931844f57641f3737348182d118c
+bgr48le 4242a026012b6c135a6aa138a6d67031
+bgr4_byte 407fcf564ed764c38e1d748f700ab921
+bgr555be f739d2519f7e9d494359bf67a3821537
+bgr555le bd7b3ec4d684dfad075d89a606cb8b74
+bgr565be f19e9a4786395e1ddcd51399c98c9f6c
+bgr565le fdb617533e1e7ff512ea5b6b6233e738
+bgr8 c60f93fd152c6903391d1fe9decd3547
+bgra 7f9b799fb48544e49ce93e91d7f9fca8
+gray 30d9014a9d43b5f37e7aa64be3a3ecfc
+gray16be 6b84b85d3326182fa1217e138249edc5
+gray16le 66bb8faa09dc149734aca3c768a6d4e1
+monob d0cf8732677a5360b6160133043590d8
+monow ff9869d067ecb94eb9d90c9750c31fea
+nv12 046f00f598ce14d9854a3534a5c99114
+nv21 01ea369dd2d0d3ed7451dc5c8d61497f
+rgb24 eaefabc168d0b14576bab45bc1e56e1e
+rgb48be 62dd185862ed142283bd300eb6dbd216
+rgb48le dcb76353268bc5862194d131762220da
+rgb4_byte 8c6ff02df0b06dd2d574836c3741b2a2
+rgb555be 40dc33cfb5cf56aac1c5a290ac486c36
+rgb555le 4f8eaad29a17e0f8e9d8ab743e76b999
+rgb565be b57623ad9df74648339311a0edcebc7b
+rgb565le 73f247a3315dceaea3022ac7c197c5ef
+rgb8 13a8d89ef78d8127297d899005456ff0
+rgba 1fc6e920a42ec812aaa3b2aa02f37987
+uyvy422 ffbd36720c77398d9a0d03ce2625928f
+yuv410p 7bfb39d7afb49d6a6173e6b23ae321eb
+yuv411p 4a90048cc3a65fac150e53289700efe1
+yuv420p 2e6d6062e8cad37fb3ab2c433b55f382
+yuv420p10be fb0772f5e2b9da20ff826e64c3893137
+yuv420p10le e95879e14c4a6805f39643964baf41f7
+yuv420p16be 539076782902664a8acf381bf4f713e8
+yuv420p16le 0f609e588e5a258644ef85170d70e030
+yuv420p9be be40ec975fb2873891643cbbbddbc3b0
+yuv420p9le 7e606310d3f5ff12badf911e8f333471
+yuv422p d7f5cb44d9b0210d66d6a8762640ab34
+yuv422p10be 0be8378c3773e1c0b394315ef4994351
+yuv422p10le 6518094fe8de6bee95af21af1e5dc1e1
+yuv422p16be 9bd8f8c961822b586fa4cf992be54acc
+yuv422p16le 9c4a1239605c7952b736ac3130163f14
+yuv422p9be 7c6f1e140b3999ee7d923854e507752a
+yuv422p9le 51f10d79c07989060dd06e767e6d7d60
+yuv440p 876385e96165acf51271b20e5d85a416
+yuv444p 9c3c667d1613b72d15bc6d851c5eb8f7
+yuv444p10be ee069cc6db48975eb029d72f889a7fe6
+yuv444p10le 645b3335248113cafe3c29edb1d7f3be
+yuv444p16be de2dedfc6f12073ffead113f86e07ecf
+yuv444p16le 8e83323cf102d6c823a03ae8a7b7e033
+yuv444p9be 6ac92b7dc9ab2fc59bee99204886899a
+yuv444p9le 85aef13a654953d3455d89770b0d74bd
+yuva420p c705d1cf061d8c6580ac690b55f92276
+yuvj420p 41fd02b204da0ab62452cd14b595e2e4
+yuvj422p 7f6ca9bc1812cde02036d7d29a7cce43
+yuvj440p 25711c3c0fd15ec19c59a10784fcfb96
+yuvj444p e45dee2ac02276dfab92e8ebfbe52e00
+yuyv422 e944ff7316cd03c42c091717ce74f602
diff --git a/tests/ref/lavfi/pixfmts_vflip_le b/tests/ref/lavfi/pixfmts_vflip_le
deleted file mode 100644
index 5100c42..0000000
--- a/tests/ref/lavfi/pixfmts_vflip_le
+++ /dev/null
@@ -1,48 +0,0 @@
-abgr 25e72e9dbd01ab00727c976d577f7be5
-argb 19869bf1a5ac0b6af4d8bbe2c104533c
-bgr24 89108a4ba00201f79b75b9305c42352d
-bgr48be ed82382da09b64a8e04728fcf76e6814
-bgr48le 0f1f135608c2ff24d26d03e939fc2112
-bgr4_byte 407fcf564ed764c38e1d748f700ab921
-bgr555le bd7b3ec4d684dfad075d89a606cb8b74
-bgr565le fdb617533e1e7ff512ea5b6b6233e738
-bgr8 c60f93fd152c6903391d1fe9decd3547
-bgra 7f9b799fb48544e49ce93e91d7f9fca8
-gray 30d9014a9d43b5f37e7aa64be3a3ecfc
-gray16be 6b84b85d3326182fa1217e138249edc5
-gray16le 66bb8faa09dc149734aca3c768a6d4e1
-monob d0cf8732677a5360b6160133043590d8
-monow ff9869d067ecb94eb9d90c9750c31fea
-nv12 046f00f598ce14d9854a3534a5c99114
-nv21 01ea369dd2d0d3ed7451dc5c8d61497f
-rgb24 eaefabc168d0b14576bab45bc1e56e1e
-rgb48be 4e0c384163ebab06a08e74637beb02bc
-rgb48le a77bfeefcd96750cf0e1917a2e2bf1e7
-rgb4_byte 8c6ff02df0b06dd2d574836c3741b2a2
-rgb555le 4f8eaad29a17e0f8e9d8ab743e76b999
-rgb565le 73f247a3315dceaea3022ac7c197c5ef
-rgb8 13a8d89ef78d8127297d899005456ff0
-rgba 1fc6e920a42ec812aaa3b2aa02f37987
-uyvy422 ffbd36720c77398d9a0d03ce2625928f
-yuv410p 7bfb39d7afb49d6a6173e6b23ae321eb
-yuv411p 4a90048cc3a65fac150e53289700efe1
-yuv420p 2e6d6062e8cad37fb3ab2c433b55f382
-yuv420p10be df97d20b3b4a10c174d4360552c4160d
-yuv420p10le 4b5249208602b941332945c926f80ae9
-yuv420p16be 539076782902664a8acf381bf4f713e8
-yuv420p16le 0f609e588e5a258644ef85170d70e030
-yuv420p9be be40ec975fb2873891643cbbbddbc3b0
-yuv420p9le 7e606310d3f5ff12badf911e8f333471
-yuv422p d7f5cb44d9b0210d66d6a8762640ab34
-yuv422p16be 9bd8f8c961822b586fa4cf992be54acc
-yuv422p16le 9c4a1239605c7952b736ac3130163f14
-yuv440p 876385e96165acf51271b20e5d85a416
-yuv444p 9c3c667d1613b72d15bc6d851c5eb8f7
-yuv444p16be 0f4afa4a4aacf4bb6b87641abde71ea9
-yuv444p16le 8f31557bc52adfe00ae8b40a9b8c23f8
-yuva420p c705d1cf061d8c6580ac690b55f92276
-yuvj420p 41fd02b204da0ab62452cd14b595e2e4
-yuvj422p 7f6ca9bc1812cde02036d7d29a7cce43
-yuvj440p 25711c3c0fd15ec19c59a10784fcfb96
-yuvj444p e45dee2ac02276dfab92e8ebfbe52e00
-yuyv422 e944ff7316cd03c42c091717ce74f602
diff --git a/tests/ref/seek/ac3_rm b/tests/ref/seek/ac3_rm
index 05772fc..b38758b 100644
--- a/tests/ref/seek/ac3_rm
+++ b/tests/ref/seek/ac3_rm
@@ -5,35 +5,40 @@ ret:-1 st:-1 flags:1 ts: 1.894167
ret:-1 st: 0 flags:0 ts: 0.788000
ret: 0 st: 0 flags:1 ts:-0.317000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556
-ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.577000 pts: 2.577000 pos: 42397 size: 558
+ret:-1 st:-1 flags:0 ts: 2.576668
ret:-1 st:-1 flags:1 ts: 1.470835
ret:-1 st: 0 flags:0 ts: 0.365000
ret: 0 st: 0 flags:1 ts:-0.741000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556
-ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.159000 pts: 2.159000 pos: 35567 size: 556
+ret:-1 st:-1 flags:0 ts: 2.153336
ret:-1 st:-1 flags:1 ts: 1.047503
ret: 0 st: 0 flags:0 ts:-0.058000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556
ret:-1 st: 0 flags:1 ts: 2.836000
-ret:-1 st:-1 flags:0 ts: 1.730004
-ret:-1 st:-1 flags:1 ts: 0.624171
+ret: 0 st:-1 flags:0 ts: 1.730004
+ret: 0 st: 0 flags:1 dts:8589.800000 pts:8589.800000 pos: 65950 size: 32801
+ret: 0 st:-1 flags:1 ts: 0.624171
+ret: 0 st: 0 flags:1 dts: 0.256000 pts: 0.256000 pos: 65337 size: 400
ret: 0 st: 0 flags:0 ts:-0.482000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556
-ret: 0 st: 0 flags:1 ts: 2.413000
-ret: 0 st: 0 flags:1 dts: 2.368000 pts: 2.368000 pos: 38981 size: 558
-ret:-1 st:-1 flags:0 ts: 1.306672
-ret:-1 st:-1 flags:1 ts: 0.200839
+ret:-1 st: 0 flags:1 ts: 2.413000
+ret: 0 st:-1 flags:0 ts: 1.306672
+ret: 0 st: 0 flags:1 dts:8589.800000 pts:8589.800000 pos: 65950 size: 32801
+ret: 0 st:-1 flags:1 ts: 0.200839
+ret: 0 st: 0 flags:1 dts: 0.034000 pts: 0.034000 pos: 839 size: 558
ret: 0 st: 0 flags:0 ts:-0.905000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556
-ret:-1 st: 0 flags:1 ts: 1.989000
-ret:-1 st:-1 flags:0 ts: 0.883340
+ret: 0 st: 0 flags:1 ts: 1.989000
+ret: 0 st: 0 flags:1 dts: 0.256000 pts: 0.256000 pos: 65337 size: 400
+ret: 0 st:-1 flags:0 ts: 0.883340
+ret: 0 st: 0 flags:1 dts: 3.378000 pts: 3.378000 pos: 55491 size: 558
ret: 0 st:-1 flags:1 ts:-0.222493
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556
ret: 0 st: 0 flags:0 ts: 2.672000
-ret: 0 st: 0 flags:1 dts: 2.821000 pts: 2.821000 pos: 46383 size: 556
-ret:-1 st: 0 flags:1 ts: 1.566000
-ret:-1 st:-1 flags:0 ts: 0.460008
+ret: 0 st: 0 flags:1 dts: 3.378000 pts: 3.378000 pos: 55491 size: 558
+ret: 0 st: 0 flags:1 ts: 1.566000
+ret: 0 st: 0 flags:1 dts: 0.256000 pts: 0.256000 pos: 65337 size: 400
+ret: 0 st:-1 flags:0 ts: 0.460008
+ret: 0 st: 0 flags:1 dts: 3.378000 pts: 3.378000 pos: 55491 size: 558
ret: 0 st:-1 flags:1 ts:-0.645825
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556
diff --git a/tests/ref/seek/adpcm_yam_wav b/tests/ref/seek/adpcm_yam_wav
index c326470..5cbfaed 100644
--- a/tests/ref/seek/adpcm_yam_wav
+++ b/tests/ref/seek/adpcm_yam_wav
@@ -1,53 +1,53 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.856009 pts: 1.856009 pos: 29752 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.856009 pts: 1.856009 pos: 29754 size: 4096
ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.831995 pts: 0.831995 pos: 13368 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.831995 pts: 0.831995 pos: 13370 size: 4096
ret: 0 st: 0 flags:1 ts:-0.317506
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.623991 pts: 2.623991 pos: 42040 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.623991 pts: 2.623991 pos: 42042 size: 4096
ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.408005 pts: 1.408005 pos: 22584 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.408005 pts: 1.408005 pos: 22586 size: 4096
ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.383991 pts: 0.383991 pos: 6200 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.383991 pts: 0.383991 pos: 6202 size: 4096
ret: 0 st: 0 flags:1 ts:-0.740839
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.176009 pts: 2.176009 pos: 34872 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.176009 pts: 2.176009 pos: 34874 size: 4096
ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.023991 pts: 1.023991 pos: 16440 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.023991 pts: 1.023991 pos: 16442 size: 4096
ret: 0 st: 0 flags:0 ts:-0.058322
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.835828
-ret: 0 st: 0 flags:1 dts: 2.816009 pts: 2.816009 pos: 45112 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.816009 pts: 2.816009 pos: 45114 size: 4096
ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.791995 pts: 1.791995 pos: 28728 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.791995 pts: 1.791995 pos: 28730 size: 4096
ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.576009 pts: 0.576009 pos: 9272 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.576009 pts: 0.576009 pos: 9274 size: 4096
ret: 0 st: 0 flags:0 ts:-0.481655
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.412494
-ret: 0 st: 0 flags:1 dts: 2.368005 pts: 2.368005 pos: 37944 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.368005 pts: 2.368005 pos: 37946 size: 4096
ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.343991 pts: 1.343991 pos: 21560 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.343991 pts: 1.343991 pos: 21562 size: 4096
ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.191995 pts: 0.191995 pos: 3128 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.191995 pts: 0.191995 pos: 3130 size: 4096
ret: 0 st: 0 flags:0 ts:-0.904989
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 1.989184
-ret: 0 st: 0 flags:1 dts: 1.983991 pts: 1.983991 pos: 31800 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.983991 pts: 1.983991 pos: 31802 size: 4096
ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.896009 pts: 0.896009 pos: 14392 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.896009 pts: 0.896009 pos: 14394 size: 4096
ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.688005 pts: 2.688005 pos: 43064 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.688005 pts: 2.688005 pos: 43066 size: 4096
ret: 0 st: 0 flags:1 ts: 1.565850
-ret: 0 st: 0 flags:1 dts: 1.536009 pts: 1.536009 pos: 24632 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.536009 pts: 1.536009 pos: 24634 size: 4096
ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.511995 pts: 0.511995 pos: 8248 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.511995 pts: 0.511995 pos: 8250 size: 4096
ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
diff --git a/tests/ref/seek/flac_flac b/tests/ref/seek/flac_flac
index ab31891..15ab0d2 100644
--- a/tests/ref/seek/flac_flac
+++ b/tests/ref/seek/flac_flac
@@ -1,49 +1,49 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 8256 size: 614
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 8255 size: 614
ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 8256 size: 614
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 8255 size: 614
ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.880816 pts: 1.880816 pos: 86742 size: 2191
+ret: 0 st: 0 flags:1 dts: 1.880816 pts: 1.880816 pos: 86741 size: 2191
ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos: 27366 size: 615
+ret: 0 st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos: 27365 size: 615
ret:-1 st: 0 flags:1 ts:-0.317506
ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 145606 size: 2384
+ret: 0 st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 145605 size: 2384
ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.462857 pts: 1.462857 pos: 53388 size: 1851
+ret: 0 st: 0 flags:1 dts: 1.462857 pts: 1.462857 pos: 53387 size: 1851
ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.365714 pts: 0.365714 pos: 16890 size: 614
+ret: 0 st: 0 flags:1 dts: 0.365714 pts: 0.365714 pos: 16889 size: 614
ret:-1 st: 0 flags:1 ts:-0.740839
ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.168163 pts: 2.168163 pos: 110531 size: 2143
+ret: 0 st: 0 flags:1 dts: 2.168163 pts: 2.168163 pos: 110530 size: 2143
ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.044898 pts: 1.044898 pos: 32880 size: 579
+ret: 0 st: 0 flags:1 dts: 1.044898 pts: 1.044898 pos: 32879 size: 579
ret: 0 st: 0 flags:0 ts:-0.058322
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 8256 size: 614
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 8255 size: 614
ret: 0 st: 0 flags:1 ts: 2.835828
-ret: 0 st: 0 flags:1 dts: 2.821224 pts: 2.821224 pos: 167112 size: 2391
+ret: 0 st: 0 flags:1 dts: 2.821224 pts: 2.821224 pos: 167111 size: 2391
ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.750204 pts: 1.750204 pos: 75788 size: 2191
+ret: 0 st: 0 flags:1 dts: 1.750204 pts: 1.750204 pos: 75787 size: 2191
ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.600816 pts: 0.600816 pos: 22446 size: 616
+ret: 0 st: 0 flags:1 dts: 0.600816 pts: 0.600816 pos: 22445 size: 616
ret: 0 st: 0 flags:0 ts:-0.481655
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 8256 size: 614
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 8255 size: 614
ret: 0 st: 0 flags:1 ts: 2.412494
-ret: 0 st: 0 flags:1 dts: 2.403265 pts: 2.403265 pos: 129793 size: 2138
+ret: 0 st: 0 flags:1 dts: 2.403265 pts: 2.403265 pos: 129792 size: 2138
ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.332245 pts: 1.332245 pos: 44812 size: 1609
+ret: 0 st: 0 flags:1 dts: 1.332245 pts: 1.332245 pos: 44811 size: 1609
ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.182857 pts: 0.182857 pos: 12572 size: 628
+ret: 0 st: 0 flags:1 dts: 0.182857 pts: 0.182857 pos: 12571 size: 628
ret: 0 st: 0 flags:0 ts:-0.904989
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 8256 size: 614
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 8255 size: 614
ret: 0 st: 0 flags:1 ts: 1.989184
-ret: 0 st: 0 flags:1 dts: 1.985306 pts: 1.985306 pos: 95508 size: 2169
+ret: 0 st: 0 flags:1 dts: 1.985306 pts: 1.985306 pos: 95507 size: 2169
ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.888163 pts: 0.888163 pos: 29211 size: 620
+ret: 0 st: 0 flags:1 dts: 0.888163 pts: 0.888163 pos: 29210 size: 620
ret:-1 st:-1 flags:1 ts:-0.222493
ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.690612 pts: 2.690612 pos: 155154 size: 2394
+ret: 0 st: 0 flags:1 dts: 2.690612 pts: 2.690612 pos: 155153 size: 2394
ret: 0 st: 0 flags:1 ts: 1.565850
-ret: 0 st: 0 flags:1 dts: 1.541224 pts: 1.541224 pos: 59082 size: 1974
+ret: 0 st: 0 flags:1 dts: 1.541224 pts: 1.541224 pos: 59081 size: 1974
ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.470204 pts: 0.470204 pos: 19353 size: 608
+ret: 0 st: 0 flags:1 dts: 0.470204 pts: 0.470204 pos: 19352 size: 608
ret:-1 st:-1 flags:1 ts:-0.645825
diff --git a/tests/ref/seek/g726_wav b/tests/ref/seek/g726_wav
index b84c87c..0e145a2 100644
--- a/tests/ref/seek/g726_wav
+++ b/tests/ref/seek/g726_wav
@@ -1,53 +1,53 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.894000 pts: 1.894000 pos: 7632 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.894000 pts: 1.894000 pos: 7634 size: 4096
ret: 0 st: 0 flags:0 ts: 0.788375
-ret: 0 st: 0 flags:1 dts: 0.788500 pts: 0.788500 pos: 3210 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.788500 pts: 0.788500 pos: 3212 size: 4096
ret: 0 st: 0 flags:1 ts:-0.317500
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.576750 pts: 2.576750 pos: 10363 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.576750 pts: 2.576750 pos: 10365 size: 4096
ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.470750 pts: 1.470750 pos: 5939 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.470750 pts: 1.470750 pos: 5941 size: 4096
ret: 0 st: 0 flags:0 ts: 0.365000
-ret: 0 st: 0 flags:1 dts: 0.365000 pts: 0.365000 pos: 1516 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.365000 pts: 0.365000 pos: 1518 size: 4096
ret: 0 st: 0 flags:1 ts:-0.740875
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.153500 pts: 2.153500 pos: 8670 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.153500 pts: 2.153500 pos: 8672 size: 4096
ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.047500 pts: 1.047500 pos: 4246 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.047500 pts: 1.047500 pos: 4248 size: 4096
ret: 0 st: 0 flags:0 ts:-0.058375
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.835875
-ret: 0 st: 0 flags:1 dts: 2.835750 pts: 2.835750 pos: 11399 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.835750 pts: 2.835750 pos: 11401 size: 4096
ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 6976 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 6978 size: 4096
ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.624000 pts: 0.624000 pos: 2552 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.624000 pts: 0.624000 pos: 2554 size: 4096
ret: 0 st: 0 flags:0 ts:-0.481625
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.412500
-ret: 0 st: 0 flags:1 dts: 2.412500 pts: 2.412500 pos: 9706 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.412500 pts: 2.412500 pos: 9708 size: 4096
ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.306750 pts: 1.306750 pos: 5283 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.306750 pts: 1.306750 pos: 5285 size: 4096
ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.200750 pts: 0.200750 pos: 859 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.200750 pts: 0.200750 pos: 861 size: 4096
ret: 0 st: 0 flags:0 ts:-0.905000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 1.989125
-ret: 0 st: 0 flags:1 dts: 1.989000 pts: 1.989000 pos: 8012 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.989000 pts: 1.989000 pos: 8014 size: 4096
ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.883500 pts: 0.883500 pos: 3590 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.883500 pts: 0.883500 pos: 3592 size: 4096
ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:0 ts: 2.671625
-ret: 0 st: 0 flags:1 dts: 2.671750 pts: 2.671750 pos: 10743 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.671750 pts: 2.671750 pos: 10745 size: 4096
ret: 0 st: 0 flags:1 ts: 1.565875
-ret: 0 st: 0 flags:1 dts: 1.565750 pts: 1.565750 pos: 6319 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.565750 pts: 1.565750 pos: 6321 size: 4096
ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 1896 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 1898 size: 4096
ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
diff --git a/tests/ref/seek/lavf_asf b/tests/ref/seek/lavf_asf
index 757fd0e..72c0f56 100644
--- a/tests/ref/seek/lavf_asf
+++ b/tests/ref/seek/lavf_asf
@@ -2,9 +2,9 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 575 size: 28487
ret: 0 st:-1 flags:0 ts:-1.000000
ret: 0 st: 1 flags:1 dts: 0.444000 pts: 0.444000 pos: 147775 size: 209
ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos: -1 size: 209
+ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301375 size: 209
ret: 0 st: 0 flags:0 ts: 0.788000
-ret: 0 st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos: -1 size: 209
+ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301375 size: 209
ret: 0 st: 0 flags:1 ts:-0.317000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 575 size: 28487
ret:-1 st: 1 flags:0 ts: 2.577000
@@ -14,29 +14,29 @@ ret: 0 st: 1 flags:1 dts: 0.444000 pts: 0.444000 pos: 147775 size: 209
ret: 0 st:-1 flags:1 ts:-0.740831
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 575 size: 28487
ret: 0 st: 0 flags:0 ts: 2.153000
-ret: 0 st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos: -1 size: 209
+ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301375 size: 209
ret: 0 st: 0 flags:1 ts: 1.048000
-ret: 0 st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos: -1 size: 209
+ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301375 size: 209
ret: 0 st: 1 flags:0 ts:-0.058000
ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 29375 size: 208
ret:-1 st: 1 flags:1 ts: 2.836000
ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos: -1 size: 209
+ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301375 size: 209
ret: 0 st:-1 flags:1 ts: 0.624171
ret: 0 st: 1 flags:1 dts: 0.444000 pts: 0.444000 pos: 147775 size: 209
ret: 0 st: 0 flags:0 ts:-0.482000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 575 size: 28487
ret: 0 st: 0 flags:1 ts: 2.413000
-ret: 0 st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos: -1 size: 209
+ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301375 size: 209
ret:-1 st: 1 flags:0 ts: 1.307000
ret: 0 st: 1 flags:1 ts: 0.201000
ret: 0 st: 1 flags:1 dts: 0.183000 pts: 0.183000 pos: 70975 size: 209
ret: 0 st:-1 flags:0 ts:-0.904994
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 575 size: 28487
ret: 0 st:-1 flags:1 ts: 1.989173
-ret: 0 st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos: -1 size: 209
+ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301375 size: 209
ret: 0 st: 0 flags:0 ts: 0.883000
-ret: 0 st: 1 flags:1 dts: 0.960000 pts: 0.960000 pos: -1 size: 209
+ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301375 size: 209
ret: 0 st: 0 flags:1 ts:-0.222000
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 575 size: 28487
ret:-1 st: 1 flags:0 ts: 2.672000
diff --git a/tests/ref/seek/lavf_gif b/tests/ref/seek/lavf_gif
index 5da803d..883f187 100644
--- a/tests/ref/seek/lavf_gif
+++ b/tests/ref/seek/lavf_gif
@@ -1,4 +1,4 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: -1 size:2906382
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: -1 size:2906401
ret:-EINVAL st:-1 flags:0 ts:-1.000000
ret:-EINVAL st:-1 flags:1 ts: 1.894167
ret:-EINVAL st: 0 flags:0 ts: 0.800000
diff --git a/tests/ref/seek/lavf_ogg b/tests/ref/seek/lavf_ogg
index c9be9c6..ea8eb8b 100644
--- a/tests/ref/seek/lavf_ogg
+++ b/tests/ref/seek/lavf_ogg
@@ -1,4 +1,4 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 125 size: 1364
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 124 size: 1364
ret:-1 st:-1 flags:0 ts:-1.000000
ret:-1 st:-1 flags:1 ts: 1.894167
ret:-1 st: 0 flags:0 ts: 0.788345
diff --git a/tests/ref/seek/lavf_wav b/tests/ref/seek/lavf_wav
index b411c3c..1a9cfc5 100644
--- a/tests/ref/seek/lavf_wav
+++ b/tests/ref/seek/lavf_wav
@@ -1,53 +1,53 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:1 ts: 1.894167
ret:-EOF
ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 69576 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 69578 size: 4096
ret: 0 st: 0 flags:1 ts:-0.317506
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:0 ts: 2.576668
ret:-EOF
ret: 0 st:-1 flags:1 ts: 1.470835
ret:-EOF
ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos: 32238 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos: 32240 size: 4096
ret: 0 st: 0 flags:1 ts:-0.740839
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:0 ts: 2.153336
ret:-EOF
ret: 0 st:-1 flags:1 ts: 1.047503
ret:-EOF
ret: 0 st: 0 flags:0 ts:-0.058322
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:1 ts: 2.835828
ret:-EOF
ret: 0 st:-1 flags:0 ts: 1.730004
ret:-EOF
ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 55096 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 55098 size: 4096
ret: 0 st: 0 flags:0 ts:-0.481655
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:1 ts: 2.412494
ret:-EOF
ret: 0 st:-1 flags:0 ts: 1.306672
ret:-EOF
ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos: 17758 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos: 17760 size: 4096
ret: 0 st: 0 flags:0 ts:-0.904989
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:1 ts: 1.989184
ret:-EOF
ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos: 77954 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos: 77956 size: 4096
ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:0 ts: 2.671678
ret:-EOF
ret: 0 st: 0 flags:1 ts: 1.565850
ret:-EOF
ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 40616 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 40618 size: 4096
ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
diff --git a/tests/ref/seek/mpeg2_mpg b/tests/ref/seek/mpeg2_idct_int_mpg
similarity index 100%
rename from tests/ref/seek/mpeg2_mpg
rename to tests/ref/seek/mpeg2_idct_int_mpg
diff --git a/tests/ref/seek/mpeg2reuse_mpg b/tests/ref/seek/mpeg2reuse_mpg
deleted file mode 100644
index c4ae3ea..0000000
--- a/tests/ref/seek/mpeg2reuse_mpg
+++ /dev/null
@@ -1,46 +0,0 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 0 size: 20829
-ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 0 size: 20829
-ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.840000 pts: NOPTS pos: 337078 size: 26840
-ret: 0 st: 0 flags:0 ts: 0.788334
-ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 141401 size: 23537
-ret:-1 st: 0 flags:1 ts:-0.317499
-ret:-1 st:-1 flags:0 ts: 2.576668
-ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.360000 pts: NOPTS pos: 232037 size: 26192
-ret: 0 st: 0 flags:0 ts: 0.365002
-ret: 0 st: 0 flags:1 dts: 0.400000 pts: NOPTS pos: 63793 size: 21295
-ret:-1 st: 0 flags:1 ts:-0.740831
-ret:-1 st:-1 flags:0 ts: 2.153336
-ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 141401 size: 23537
-ret: 0 st: 0 flags:0 ts:-0.058330
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 0 size: 20829
-ret: 0 st: 0 flags:1 ts: 2.835837
-ret: 0 st: 0 flags:1 dts: 1.840000 pts: NOPTS pos: 337078 size: 26840
-ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.840000 pts: NOPTS pos: 337078 size: 26840
-ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.400000 pts: NOPTS pos: 63793 size: 21295
-ret: 0 st: 0 flags:0 ts:-0.481662
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 0 size: 20829
-ret: 0 st: 0 flags:1 ts: 2.412505
-ret: 0 st: 0 flags:1 dts: 1.840000 pts: NOPTS pos: 337078 size: 26840
-ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.360000 pts: NOPTS pos: 232037 size: 26192
-ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 0 size: 20829
-ret: 0 st: 0 flags:0 ts:-0.904994
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: NOPTS pos: 0 size: 20829
-ret: 0 st: 0 flags:1 ts: 1.989173
-ret: 0 st: 0 flags:1 dts: 1.840000 pts: NOPTS pos: 337078 size: 26840
-ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 1.360000 pts: NOPTS pos: 232037 size: 26192
-ret:-1 st:-1 flags:1 ts:-0.222493
-ret:-1 st: 0 flags:0 ts: 2.671674
-ret: 0 st: 0 flags:1 ts: 1.565841
-ret: 0 st: 0 flags:1 dts: 1.360000 pts: NOPTS pos: 232037 size: 26192
-ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.880000 pts: NOPTS pos: 141401 size: 23537
-ret:-1 st:-1 flags:1 ts:-0.645825
diff --git a/tests/ref/seek/pcm_alaw_wav b/tests/ref/seek/pcm_alaw_wav
index 06f50e7..22d95bf 100644
--- a/tests/ref/seek/pcm_alaw_wav
+++ b/tests/ref/seek/pcm_alaw_wav
@@ -1,53 +1,53 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.894127 pts: 1.894127 pos: 30362 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.894127 pts: 1.894127 pos: 30364 size: 4096
ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.788367 pts: 0.788367 pos: 12670 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.788367 pts: 0.788367 pos: 12672 size: 4096
ret: 0 st: 0 flags:1 ts:-0.317506
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.576757 pts: 2.576757 pos: 41284 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.576757 pts: 2.576757 pos: 41286 size: 4096
ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.470748 pts: 1.470748 pos: 23588 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.470748 pts: 1.470748 pos: 23590 size: 4096
ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.365125 pts: 0.365125 pos: 5898 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.365125 pts: 0.365125 pos: 5900 size: 4096
ret: 0 st: 0 flags:1 ts:-0.740839
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.153379 pts: 2.153379 pos: 34510 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.153379 pts: 2.153379 pos: 34512 size: 4096
ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 16816 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 16818 size: 4096
ret: 0 st: 0 flags:0 ts:-0.058322
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.835828
-ret: 0 st: 0 flags:1 dts: 2.835760 pts: 2.835760 pos: 45428 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.835760 pts: 2.835760 pos: 45430 size: 4096
ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 27736 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 27738 size: 4096
ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.624127 pts: 0.624127 pos: 10042 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.624127 pts: 0.624127 pos: 10044 size: 4096
ret: 0 st: 0 flags:0 ts:-0.481655
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.412494
-ret: 0 st: 0 flags:1 dts: 2.412381 pts: 2.412381 pos: 38654 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.412381 pts: 2.412381 pos: 38656 size: 4096
ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.306757 pts: 1.306757 pos: 20964 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.306757 pts: 1.306757 pos: 20966 size: 4096
ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.200748 pts: 0.200748 pos: 3268 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.200748 pts: 0.200748 pos: 3270 size: 4096
ret: 0 st: 0 flags:0 ts:-0.904989
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 1.989184
-ret: 0 st: 0 flags:1 dts: 1.989116 pts: 1.989116 pos: 31882 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.989116 pts: 1.989116 pos: 31884 size: 4096
ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.883379 pts: 0.883379 pos: 14190 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.883379 pts: 0.883379 pos: 14192 size: 4096
ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.671746 pts: 2.671746 pos: 42804 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.671746 pts: 2.671746 pos: 42806 size: 4096
ret: 0 st: 0 flags:1 ts: 1.565850
-ret: 0 st: 0 flags:1 dts: 1.565760 pts: 1.565760 pos: 25108 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.565760 pts: 1.565760 pos: 25110 size: 4096
ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 7416 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 7418 size: 4096
ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
diff --git a/tests/ref/seek/pcm_mulaw_wav b/tests/ref/seek/pcm_mulaw_wav
index 06f50e7..22d95bf 100644
--- a/tests/ref/seek/pcm_mulaw_wav
+++ b/tests/ref/seek/pcm_mulaw_wav
@@ -1,53 +1,53 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.894127 pts: 1.894127 pos: 30362 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.894127 pts: 1.894127 pos: 30364 size: 4096
ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.788367 pts: 0.788367 pos: 12670 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.788367 pts: 0.788367 pos: 12672 size: 4096
ret: 0 st: 0 flags:1 ts:-0.317506
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.576757 pts: 2.576757 pos: 41284 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.576757 pts: 2.576757 pos: 41286 size: 4096
ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.470748 pts: 1.470748 pos: 23588 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.470748 pts: 1.470748 pos: 23590 size: 4096
ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.365125 pts: 0.365125 pos: 5898 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.365125 pts: 0.365125 pos: 5900 size: 4096
ret: 0 st: 0 flags:1 ts:-0.740839
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.153379 pts: 2.153379 pos: 34510 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.153379 pts: 2.153379 pos: 34512 size: 4096
ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 16816 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 16818 size: 4096
ret: 0 st: 0 flags:0 ts:-0.058322
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.835828
-ret: 0 st: 0 flags:1 dts: 2.835760 pts: 2.835760 pos: 45428 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.835760 pts: 2.835760 pos: 45430 size: 4096
ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 27736 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 27738 size: 4096
ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.624127 pts: 0.624127 pos: 10042 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.624127 pts: 0.624127 pos: 10044 size: 4096
ret: 0 st: 0 flags:0 ts:-0.481655
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 2.412494
-ret: 0 st: 0 flags:1 dts: 2.412381 pts: 2.412381 pos: 38654 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.412381 pts: 2.412381 pos: 38656 size: 4096
ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.306757 pts: 1.306757 pos: 20964 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.306757 pts: 1.306757 pos: 20966 size: 4096
ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.200748 pts: 0.200748 pos: 3268 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.200748 pts: 0.200748 pos: 3270 size: 4096
ret: 0 st: 0 flags:0 ts:-0.904989
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:1 ts: 1.989184
-ret: 0 st: 0 flags:1 dts: 1.989116 pts: 1.989116 pos: 31882 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.989116 pts: 1.989116 pos: 31884 size: 4096
ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.883379 pts: 0.883379 pos: 14190 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.883379 pts: 0.883379 pos: 14192 size: 4096
ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.671746 pts: 2.671746 pos: 42804 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.671746 pts: 2.671746 pos: 42806 size: 4096
ret: 0 st: 0 flags:1 ts: 1.565850
-ret: 0 st: 0 flags:1 dts: 1.565760 pts: 1.565760 pos: 25108 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.565760 pts: 1.565760 pos: 25110 size: 4096
ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 7416 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 7418 size: 4096
ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096
diff --git a/tests/ref/seek/pcm_s16be_mkv b/tests/ref/seek/pcm_s16be_mkv
deleted file mode 100644
index 8889c42..0000000
--- a/tests/ref/seek/pcm_s16be_mkv
+++ /dev/null
@@ -1,53 +0,0 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.881000 pts: 1.881000 pos: 332755 size: 4096
-ret: 0 st: 0 flags:0 ts: 0.788000
-ret: 0 st: 0 flags:1 dts: 0.789000 pts: 0.789000 pos: 139914 size: 4096
-ret: 0 st: 0 flags:1 ts:-0.317000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.577000 pts: 2.577000 pos: 455845 size: 4096
-ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.463000 pts: 1.463000 pos: 258901 size: 4096
-ret: 0 st: 0 flags:0 ts: 0.365000
-ret: 0 st: 0 flags:1 dts: 0.372000 pts: 0.372000 pos: 66060 size: 4096
-ret: 0 st: 0 flags:1 ts:-0.741000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.159000 pts: 2.159000 pos: 381991 size: 4096
-ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.045000 pts: 1.045000 pos: 185047 size: 4096
-ret: 0 st: 0 flags:0 ts:-0.058000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st: 0 flags:1 ts: 2.836000
-ret: 0 st: 0 flags:1 dts: 2.833000 pts: 2.833000 pos: 500978 size: 4096
-ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.741000 pts: 1.741000 pos: 308137 size: 4096
-ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.604000 pts: 0.604000 pos: 107090 size: 4096
-ret: 0 st: 0 flags:0 ts:-0.482000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st: 0 flags:1 ts: 2.413000
-ret: 0 st: 0 flags:1 dts: 2.392000 pts: 2.392000 pos: 423021 size: 4096
-ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.324000 pts: 1.324000 pos: 234283 size: 4096
-ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.186000 pts: 0.186000 pos: 33236 size: 4096
-ret: 0 st: 0 flags:0 ts:-0.905000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st: 0 flags:1 ts: 1.989000
-ret: 0 st: 0 flags:1 dts: 1.974000 pts: 1.974000 pos: 349167 size: 4096
-ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.906000 pts: 0.906000 pos: 160429 size: 4096
-ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st: 0 flags:0 ts: 2.672000
-ret: 0 st: 0 flags:1 dts: 2.694000 pts: 2.694000 pos: 476360 size: 4096
-ret: 0 st: 0 flags:1 ts: 1.566000
-ret: 0 st: 0 flags:1 dts: 1.556000 pts: 1.556000 pos: 275313 size: 4096
-ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.464000 pts: 0.464000 pos: 82472 size: 4096
-ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
diff --git a/tests/ref/seek/pcm_s16le_mkv b/tests/ref/seek/pcm_s16le_mkv
deleted file mode 100644
index 8889c42..0000000
--- a/tests/ref/seek/pcm_s16le_mkv
+++ /dev/null
@@ -1,53 +0,0 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.881000 pts: 1.881000 pos: 332755 size: 4096
-ret: 0 st: 0 flags:0 ts: 0.788000
-ret: 0 st: 0 flags:1 dts: 0.789000 pts: 0.789000 pos: 139914 size: 4096
-ret: 0 st: 0 flags:1 ts:-0.317000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.577000 pts: 2.577000 pos: 455845 size: 4096
-ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.463000 pts: 1.463000 pos: 258901 size: 4096
-ret: 0 st: 0 flags:0 ts: 0.365000
-ret: 0 st: 0 flags:1 dts: 0.372000 pts: 0.372000 pos: 66060 size: 4096
-ret: 0 st: 0 flags:1 ts:-0.741000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.159000 pts: 2.159000 pos: 381991 size: 4096
-ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.045000 pts: 1.045000 pos: 185047 size: 4096
-ret: 0 st: 0 flags:0 ts:-0.058000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st: 0 flags:1 ts: 2.836000
-ret: 0 st: 0 flags:1 dts: 2.833000 pts: 2.833000 pos: 500978 size: 4096
-ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.741000 pts: 1.741000 pos: 308137 size: 4096
-ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.604000 pts: 0.604000 pos: 107090 size: 4096
-ret: 0 st: 0 flags:0 ts:-0.482000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st: 0 flags:1 ts: 2.413000
-ret: 0 st: 0 flags:1 dts: 2.392000 pts: 2.392000 pos: 423021 size: 4096
-ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.324000 pts: 1.324000 pos: 234283 size: 4096
-ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.186000 pts: 0.186000 pos: 33236 size: 4096
-ret: 0 st: 0 flags:0 ts:-0.905000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st: 0 flags:1 ts: 1.989000
-ret: 0 st: 0 flags:1 dts: 1.974000 pts: 1.974000 pos: 349167 size: 4096
-ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.906000 pts: 0.906000 pos: 160429 size: 4096
-ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
-ret: 0 st: 0 flags:0 ts: 2.672000
-ret: 0 st: 0 flags:1 dts: 2.694000 pts: 2.694000 pos: 476360 size: 4096
-ret: 0 st: 0 flags:1 ts: 1.566000
-ret: 0 st: 0 flags:1 dts: 1.556000 pts: 1.556000 pos: 275313 size: 4096
-ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.464000 pts: 0.464000 pos: 82472 size: 4096
-ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 412 size: 4096
diff --git a/tests/ref/seek/pcm_s16le_wav b/tests/ref/seek/pcm_s16le_wav
index 41acc98..4f1ffc5 100644
--- a/tests/ref/seek/pcm_s16le_wav
+++ b/tests/ref/seek/pcm_s16le_wav
@@ -1,53 +1,53 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.894172 pts: 1.894172 pos: 334176 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.894172 pts: 1.894172 pos: 334178 size: 4096
ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 139108 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 139110 size: 4096
ret: 0 st: 0 flags:1 ts:-0.317506
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.576667 pts: 2.576667 pos: 454568 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.576667 pts: 2.576667 pos: 454570 size: 4096
ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.470839 pts: 1.470839 pos: 259500 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.470839 pts: 1.470839 pos: 259502 size: 4096
ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos: 64432 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos: 64434 size: 4096
ret: 0 st: 0 flags:1 ts:-0.740839
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.153333 pts: 2.153333 pos: 379892 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.153333 pts: 2.153333 pos: 379894 size: 4096
ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 184824 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 184826 size: 4096
ret: 0 st: 0 flags:0 ts:-0.058322
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:1 ts: 2.835828
-ret: 0 st: 0 flags:1 dts: 2.835828 pts: 2.835828 pos: 500284 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.835828 pts: 2.835828 pos: 500286 size: 4096
ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 305216 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 305218 size: 4096
ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 110148 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 110150 size: 4096
ret: 0 st: 0 flags:0 ts:-0.481655
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:1 ts: 2.412494
-ret: 0 st: 0 flags:1 dts: 2.412494 pts: 2.412494 pos: 425608 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.412494 pts: 2.412494 pos: 425610 size: 4096
ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.306667 pts: 1.306667 pos: 230540 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.306667 pts: 1.306667 pos: 230542 size: 4096
ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos: 35472 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos: 35474 size: 4096
ret: 0 st: 0 flags:0 ts:-0.904989
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:1 ts: 1.989184
-ret: 0 st: 0 flags:1 dts: 1.989184 pts: 1.989184 pos: 350936 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.989184 pts: 1.989184 pos: 350938 size: 4096
ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos: 155864 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos: 155866 size: 4096
ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.671678 pts: 2.671678 pos: 471328 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.671678 pts: 2.671678 pos: 471330 size: 4096
ret: 0 st: 0 flags:1 ts: 1.565850
-ret: 0 st: 0 flags:1 dts: 1.565850 pts: 1.565850 pos: 276260 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.565850 pts: 1.565850 pos: 276262 size: 4096
ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 81188 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 81190 size: 4096
ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
diff --git a/tests/ref/seek/pcm_u8_wav b/tests/ref/seek/pcm_u8_wav
index afa3351..8348916 100644
--- a/tests/ref/seek/pcm_u8_wav
+++ b/tests/ref/seek/pcm_u8_wav
@@ -1,53 +1,53 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.894172 pts: 1.894172 pos: 167110 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.894172 pts: 1.894172 pos: 167112 size: 4096
ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 69576 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 69578 size: 4096
ret: 0 st: 0 flags:1 ts:-0.317506
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.576667 pts: 2.576667 pos: 227306 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.576667 pts: 2.576667 pos: 227308 size: 4096
ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.470839 pts: 1.470839 pos: 129772 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.470839 pts: 1.470839 pos: 129774 size: 4096
ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos: 32238 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos: 32240 size: 4096
ret: 0 st: 0 flags:1 ts:-0.740839
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.153333 pts: 2.153333 pos: 189968 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.153333 pts: 2.153333 pos: 189970 size: 4096
ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 92434 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 92436 size: 4096
ret: 0 st: 0 flags:0 ts:-0.058322
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:1 ts: 2.835828
-ret: 0 st: 0 flags:1 dts: 2.835828 pts: 2.835828 pos: 250164 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.835828 pts: 2.835828 pos: 250166 size: 4096
ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 152630 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 152632 size: 4096
ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 55096 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 55098 size: 4096
ret: 0 st: 0 flags:0 ts:-0.481655
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:1 ts: 2.412494
-ret: 0 st: 0 flags:1 dts: 2.412494 pts: 2.412494 pos: 212826 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.412494 pts: 2.412494 pos: 212828 size: 4096
ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.306667 pts: 1.306667 pos: 115292 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.306667 pts: 1.306667 pos: 115294 size: 4096
ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos: 17758 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos: 17760 size: 4096
ret: 0 st: 0 flags:0 ts:-0.904989
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:1 ts: 1.989184
-ret: 0 st: 0 flags:1 dts: 1.989184 pts: 1.989184 pos: 175490 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.989184 pts: 1.989184 pos: 175492 size: 4096
ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos: 77954 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos: 77956 size: 4096
ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.671678 pts: 2.671678 pos: 235686 size: 4096
+ret: 0 st: 0 flags:1 dts: 2.671678 pts: 2.671678 pos: 235688 size: 4096
ret: 0 st: 0 flags:1 ts: 1.565850
-ret: 0 st: 0 flags:1 dts: 1.565850 pts: 1.565850 pos: 138152 size: 4096
+ret: 0 st: 0 flags:1 dts: 1.565850 pts: 1.565850 pos: 138154 size: 4096
ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 40616 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 40618 size: 4096
ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 44 size: 4096
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 46 size: 4096
diff --git a/tests/ref/seek/pcm_zork_wav b/tests/ref/seek/pcm_zork_wav
deleted file mode 100644
index 06f50e7..0000000
--- a/tests/ref/seek/pcm_zork_wav
+++ /dev/null
@@ -1,53 +0,0 @@
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
-ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
-ret: 0 st:-1 flags:1 ts: 1.894167
-ret: 0 st: 0 flags:1 dts: 1.894127 pts: 1.894127 pos: 30362 size: 4096
-ret: 0 st: 0 flags:0 ts: 0.788345
-ret: 0 st: 0 flags:1 dts: 0.788367 pts: 0.788367 pos: 12670 size: 4096
-ret: 0 st: 0 flags:1 ts:-0.317506
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
-ret: 0 st:-1 flags:0 ts: 2.576668
-ret: 0 st: 0 flags:1 dts: 2.576757 pts: 2.576757 pos: 41284 size: 4096
-ret: 0 st:-1 flags:1 ts: 1.470835
-ret: 0 st: 0 flags:1 dts: 1.470748 pts: 1.470748 pos: 23588 size: 4096
-ret: 0 st: 0 flags:0 ts: 0.365011
-ret: 0 st: 0 flags:1 dts: 0.365125 pts: 0.365125 pos: 5898 size: 4096
-ret: 0 st: 0 flags:1 ts:-0.740839
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
-ret: 0 st:-1 flags:0 ts: 2.153336
-ret: 0 st: 0 flags:1 dts: 2.153379 pts: 2.153379 pos: 34510 size: 4096
-ret: 0 st:-1 flags:1 ts: 1.047503
-ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 16816 size: 4096
-ret: 0 st: 0 flags:0 ts:-0.058322
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
-ret: 0 st: 0 flags:1 ts: 2.835828
-ret: 0 st: 0 flags:1 dts: 2.835760 pts: 2.835760 pos: 45428 size: 4096
-ret: 0 st:-1 flags:0 ts: 1.730004
-ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 27736 size: 4096
-ret: 0 st:-1 flags:1 ts: 0.624171
-ret: 0 st: 0 flags:1 dts: 0.624127 pts: 0.624127 pos: 10042 size: 4096
-ret: 0 st: 0 flags:0 ts:-0.481655
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
-ret: 0 st: 0 flags:1 ts: 2.412494
-ret: 0 st: 0 flags:1 dts: 2.412381 pts: 2.412381 pos: 38654 size: 4096
-ret: 0 st:-1 flags:0 ts: 1.306672
-ret: 0 st: 0 flags:1 dts: 1.306757 pts: 1.306757 pos: 20964 size: 4096
-ret: 0 st:-1 flags:1 ts: 0.200839
-ret: 0 st: 0 flags:1 dts: 0.200748 pts: 0.200748 pos: 3268 size: 4096
-ret: 0 st: 0 flags:0 ts:-0.904989
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
-ret: 0 st: 0 flags:1 ts: 1.989184
-ret: 0 st: 0 flags:1 dts: 1.989116 pts: 1.989116 pos: 31882 size: 4096
-ret: 0 st:-1 flags:0 ts: 0.883340
-ret: 0 st: 0 flags:1 dts: 0.883379 pts: 0.883379 pos: 14190 size: 4096
-ret: 0 st:-1 flags:1 ts:-0.222493
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
-ret: 0 st: 0 flags:0 ts: 2.671678
-ret: 0 st: 0 flags:1 dts: 2.671746 pts: 2.671746 pos: 42804 size: 4096
-ret: 0 st: 0 flags:1 ts: 1.565850
-ret: 0 st: 0 flags:1 dts: 1.565760 pts: 1.565760 pos: 25108 size: 4096
-ret: 0 st:-1 flags:0 ts: 0.460008
-ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 7416 size: 4096
-ret: 0 st:-1 flags:1 ts:-0.645825
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 56 size: 4096
diff --git a/tests/ref/vsynth1/cljr b/tests/ref/vsynth1/cljr
new file mode 100644
index 0000000..9865726
--- /dev/null
+++ b/tests/ref/vsynth1/cljr
@@ -0,0 +1,4 @@
+d149cadc43100d8e98ff04e57fdaa31f *./tests/data/vsynth1/cljr.avi
+ 5075660 ./tests/data/vsynth1/cljr.avi
+4debaab994c2c7273bebaa0c5733017b *./tests/data/cljr.vsynth1.out.yuv
+stddev: 30.75 PSNR: 18.37 MAXDIFF: 225 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/dnxhd_720p_10bit b/tests/ref/vsynth1/dnxhd_720p_10bit
new file mode 100644
index 0000000..ad97b66
--- /dev/null
+++ b/tests/ref/vsynth1/dnxhd_720p_10bit
@@ -0,0 +1,4 @@
+b5e24a055af02edec8674333260214fd *./tests/data/vsynth1/dnxhd-720p-10bit.dnxhd
+ 2293760 ./tests/data/vsynth1/dnxhd-720p-10bit.dnxhd
+4466ff3d73d01bbe75ea25001d379b63 *./tests/data/dnxhd_720p_10bit.vsynth1.out.yuv
+stddev: 6.27 PSNR: 32.18 MAXDIFF: 64 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth1/dv b/tests/ref/vsynth1/dv
index cb0427c..c309bb2 100644
--- a/tests/ref/vsynth1/dv
+++ b/tests/ref/vsynth1/dv
@@ -2,7 +2,3 @@
7200000 ./tests/data/vsynth1/dv.dv
02ac7cdeab91d4d5621e7ce96dddc498 *./tests/data/dv.vsynth1.out.yuv
stddev: 6.90 PSNR: 31.34 MAXDIFF: 76 bytes: 7603200/ 7603200
-bd67f2431db160d4bb6dcd791cea6efd *./tests/data/vsynth1/dv411.dv
-7200000 ./tests/data/vsynth1/dv411.dv
-b6640a3a572353f51284acb746eb00c4 *./tests/data/dv.vsynth1.out.yuv
-stddev: 30.76 PSNR: 18.37 MAXDIFF: 205 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/dv_411 b/tests/ref/vsynth1/dv_411
new file mode 100644
index 0000000..841c3fd
--- /dev/null
+++ b/tests/ref/vsynth1/dv_411
@@ -0,0 +1,4 @@
+bd67f2431db160d4bb6dcd791cea6efd *./tests/data/vsynth1/dv411.dv
+7200000 ./tests/data/vsynth1/dv411.dv
+b6640a3a572353f51284acb746eb00c4 *./tests/data/dv_411.vsynth1.out.yuv
+stddev: 30.76 PSNR: 18.37 MAXDIFF: 205 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2 b/tests/ref/vsynth1/mpeg2
index e6d404d..0df3b7f 100644
--- a/tests/ref/vsynth1/mpeg2
+++ b/tests/ref/vsynth1/mpeg2
@@ -2,19 +2,3 @@ fbddea2368cd2028fc8db4dfd4682e94 *./tests/data/vsynth1/mpeg2.mpg
728044 ./tests/data/vsynth1/mpeg2.mpg
b41ca49c1a02e66ce64d262e2cdaec15 *./tests/data/mpeg2.vsynth1.out.yuv
stddev: 7.65 PSNR: 30.45 MAXDIFF: 84 bytes: 7603200/ 7603200
-8f6b20714918e6443e0c03716ed06f0d *./tests/data/vsynth1/mpeg2ivlc-qprd.mpg
-783552 ./tests/data/vsynth1/mpeg2ivlc-qprd.mpg
-98eb9da15f880978e7f2ee1e7ce476ef *./tests/data/mpeg2.vsynth1.out.yuv
-stddev: 10.07 PSNR: 28.06 MAXDIFF: 165 bytes: 7603200/ 7603200
-af0cb75451aaa807beb5102707a98823 *./tests/data/vsynth1/mpeg2_422.mpg
-728200 ./tests/data/vsynth1/mpeg2_422.mpg
-29b518282493203e83b27a939795dc3a *./tests/data/mpeg2.vsynth1.out.yuv
-stddev: 63.33 PSNR: 12.10 MAXDIFF: 242 bytes: 10137600/ 7603200
-4c067397b504d65532d7779cd36f3f88 *./tests/data/vsynth1/mpeg2.mpg
-725668 ./tests/data/vsynth1/mpeg2.mpg
-9f7b065f98d57cdecf90e6f7a2524eb5 *./tests/data/mpeg2.vsynth1.out.yuv
-stddev: 7.65 PSNR: 30.45 MAXDIFF: 81 bytes: 7603200/ 7603200
-ec3f6713c88a2b41f6c369fd64341077 *./tests/data/vsynth1/mpeg2i.mpg
-737473 ./tests/data/vsynth1/mpeg2i.mpg
-97615390fdd69abfcbc7e02df863a7d2 *./tests/data/mpeg2.vsynth1.out.yuv
-stddev: 7.67 PSNR: 30.43 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2_422 b/tests/ref/vsynth1/mpeg2_422
new file mode 100644
index 0000000..beef80b
--- /dev/null
+++ b/tests/ref/vsynth1/mpeg2_422
@@ -0,0 +1,4 @@
+af0cb75451aaa807beb5102707a98823 *./tests/data/vsynth1/mpeg2_422.mpg
+728200 ./tests/data/vsynth1/mpeg2_422.mpg
+29b518282493203e83b27a939795dc3a *./tests/data/mpeg2_422.vsynth1.out.yuv
+stddev: 63.33 PSNR: 12.10 MAXDIFF: 242 bytes: 10137600/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2_idct_int b/tests/ref/vsynth1/mpeg2_idct_int
new file mode 100644
index 0000000..be73750
--- /dev/null
+++ b/tests/ref/vsynth1/mpeg2_idct_int
@@ -0,0 +1,4 @@
+4c067397b504d65532d7779cd36f3f88 *./tests/data/vsynth1/mpeg2_idct_int.mpg
+725668 ./tests/data/vsynth1/mpeg2_idct_int.mpg
+9f7b065f98d57cdecf90e6f7a2524eb5 *./tests/data/mpeg2_idct_int.vsynth1.out.yuv
+stddev: 7.65 PSNR: 30.45 MAXDIFF: 81 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2_ilace b/tests/ref/vsynth1/mpeg2_ilace
new file mode 100644
index 0000000..e05951f
--- /dev/null
+++ b/tests/ref/vsynth1/mpeg2_ilace
@@ -0,0 +1,4 @@
+ec3f6713c88a2b41f6c369fd64341077 *./tests/data/vsynth1/mpeg2i.mpg
+737473 ./tests/data/vsynth1/mpeg2i.mpg
+97615390fdd69abfcbc7e02df863a7d2 *./tests/data/mpeg2_ilace.vsynth1.out.yuv
+stddev: 7.67 PSNR: 30.43 MAXDIFF: 84 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2_ivlc_qprd b/tests/ref/vsynth1/mpeg2_ivlc_qprd
new file mode 100644
index 0000000..c8a6694
--- /dev/null
+++ b/tests/ref/vsynth1/mpeg2_ivlc_qprd
@@ -0,0 +1,4 @@
+8f6b20714918e6443e0c03716ed06f0d *./tests/data/vsynth1/mpeg2ivlc-qprd.mpg
+783552 ./tests/data/vsynth1/mpeg2ivlc-qprd.mpg
+98eb9da15f880978e7f2ee1e7ce476ef *./tests/data/mpeg2_ivlc_qprd.vsynth1.out.yuv
+stddev: 10.07 PSNR: 28.06 MAXDIFF: 165 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2thread b/tests/ref/vsynth1/mpeg2thread
index 470c2e9..a44c00d 100644
--- a/tests/ref/vsynth1/mpeg2thread
+++ b/tests/ref/vsynth1/mpeg2thread
@@ -2,11 +2,3 @@ ecd183706688bd977c9994c3d1b23d61 *./tests/data/vsynth1/mpeg2thread.mpg
801313 ./tests/data/vsynth1/mpeg2thread.mpg
d1658911ca83f5616c1d32abc40750de *./tests/data/mpeg2thread.vsynth1.out.yuv
stddev: 7.63 PSNR: 30.48 MAXDIFF: 110 bytes: 7603200/ 7603200
-23d600b026222253c2340e23300a4c02 *./tests/data/vsynth1/mpeg2threadivlc.mpg
-791773 ./tests/data/vsynth1/mpeg2threadivlc.mpg
-d1658911ca83f5616c1d32abc40750de *./tests/data/mpeg2thread.vsynth1.out.yuv
-stddev: 7.63 PSNR: 30.48 MAXDIFF: 110 bytes: 7603200/ 7603200
-d119fe917dd81d1ff758b4ce684a8d9d *./tests/data/vsynth1/mpeg2reuse.mpg
-2074636 ./tests/data/vsynth1/mpeg2reuse.mpg
-92ced6afe8c02304943c400cce51a5f4 *./tests/data/mpeg2thread.vsynth1.out.yuv
-stddev: 7.66 PSNR: 30.44 MAXDIFF: 111 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg2thread_ilace b/tests/ref/vsynth1/mpeg2thread_ilace
new file mode 100644
index 0000000..0667b68
--- /dev/null
+++ b/tests/ref/vsynth1/mpeg2thread_ilace
@@ -0,0 +1,4 @@
+23d600b026222253c2340e23300a4c02 *./tests/data/vsynth1/mpeg2threadivlc.mpg
+791773 ./tests/data/vsynth1/mpeg2threadivlc.mpg
+d1658911ca83f5616c1d32abc40750de *./tests/data/mpeg2thread_ilace.vsynth1.out.yuv
+stddev: 7.63 PSNR: 30.48 MAXDIFF: 110 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4 b/tests/ref/vsynth1/mpeg4
index ebe2f5a..133e228 100644
--- a/tests/ref/vsynth1/mpeg4
+++ b/tests/ref/vsynth1/mpeg4
@@ -1,4 +1,4 @@
-080e75117f8142001b096cd977ba287e *./tests/data/vsynth1/odivx.mp4
-540156 ./tests/data/vsynth1/odivx.mp4
+9251145d12150cb639098016d61fc75e *./tests/data/vsynth1/odivx.mp4
+540180 ./tests/data/vsynth1/odivx.mp4
8828a375448dc5c2215163ba70656f89 *./tests/data/mpeg4.vsynth1.out.yuv
stddev: 7.97 PSNR: 30.10 MAXDIFF: 105 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4_adap b/tests/ref/vsynth1/mpeg4_adap
new file mode 100644
index 0000000..7513a22
--- /dev/null
+++ b/tests/ref/vsynth1/mpeg4_adap
@@ -0,0 +1,4 @@
+2d870c0da9ab2231ab5fc06981e70399 *./tests/data/vsynth1/mpeg4-adap.avi
+403456 ./tests/data/vsynth1/mpeg4-adap.avi
+fa2049396479b5f170aa764fed5b2a31 *./tests/data/mpeg4_adap.vsynth1.out.yuv
+stddev: 14.05 PSNR: 25.17 MAXDIFF: 184 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4_qpel b/tests/ref/vsynth1/mpeg4_qpel
new file mode 100644
index 0000000..51547d8
--- /dev/null
+++ b/tests/ref/vsynth1/mpeg4_qpel
@@ -0,0 +1,4 @@
+3bf17c3d04f52988386ce106a2a58976 *./tests/data/vsynth1/mpeg4-Q.avi
+860678 ./tests/data/vsynth1/mpeg4-Q.avi
+756928496245ecc701f79eebeec8e5e6 *./tests/data/mpeg4_qpel.vsynth1.out.yuv
+stddev: 5.63 PSNR: 33.12 MAXDIFF: 70 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4_qprd b/tests/ref/vsynth1/mpeg4_qprd
new file mode 100644
index 0000000..aa3b506
--- /dev/null
+++ b/tests/ref/vsynth1/mpeg4_qprd
@@ -0,0 +1,4 @@
+d6b7e724a6ad66ab5e4c5a499218b40d *./tests/data/vsynth1/mpeg4-qprd.avi
+710944 ./tests/data/vsynth1/mpeg4-qprd.avi
+e65f4c7f343fe2bad1cac44b7da5f7c4 *./tests/data/mpeg4_qprd.vsynth1.out.yuv
+stddev: 9.79 PSNR: 28.31 MAXDIFF: 176 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/mpeg4adv b/tests/ref/vsynth1/mpeg4adv
index d614310..374f0b2 100644
--- a/tests/ref/vsynth1/mpeg4adv
+++ b/tests/ref/vsynth1/mpeg4adv
@@ -2,15 +2,3 @@
589716 ./tests/data/vsynth1/mpeg4-adv.avi
f8b226876b1b2c0b98fd6928fd9adbd8 *./tests/data/mpeg4adv.vsynth1.out.yuv
stddev: 6.98 PSNR: 31.25 MAXDIFF: 84 bytes: 7603200/ 7603200
-d6b7e724a6ad66ab5e4c5a499218b40d *./tests/data/vsynth1/mpeg4-qprd.avi
-710944 ./tests/data/vsynth1/mpeg4-qprd.avi
-e65f4c7f343fe2bad1cac44b7da5f7c4 *./tests/data/mpeg4adv.vsynth1.out.yuv
-stddev: 9.79 PSNR: 28.31 MAXDIFF: 176 bytes: 7603200/ 7603200
-2d870c0da9ab2231ab5fc06981e70399 *./tests/data/vsynth1/mpeg4-adap.avi
-403456 ./tests/data/vsynth1/mpeg4-adap.avi
-fa2049396479b5f170aa764fed5b2a31 *./tests/data/mpeg4adv.vsynth1.out.yuv
-stddev: 14.05 PSNR: 25.17 MAXDIFF: 184 bytes: 7603200/ 7603200
-3bf17c3d04f52988386ce106a2a58976 *./tests/data/vsynth1/mpeg4-Q.avi
-860678 ./tests/data/vsynth1/mpeg4-Q.avi
-756928496245ecc701f79eebeec8e5e6 *./tests/data/mpeg4adv.vsynth1.out.yuv
-stddev: 5.63 PSNR: 33.12 MAXDIFF: 70 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth1/v210 b/tests/ref/vsynth1/v210
new file mode 100644
index 0000000..bb84c3e
--- /dev/null
+++ b/tests/ref/vsynth1/v210
@@ -0,0 +1,4 @@
+dd6c870a2a52c9e75ce61c3670e710e7 *./tests/data/vsynth1/v210.avi
+14752460 ./tests/data/vsynth1/v210.avi
+50973792d3f1abe04a51ee0121f077f2 *./tests/data/v210.vsynth1.out.yuv
+stddev: 1.85 PSNR: 42.78 MAXDIFF: 29 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/cljr b/tests/ref/vsynth2/cljr
new file mode 100644
index 0000000..6f8670c
--- /dev/null
+++ b/tests/ref/vsynth2/cljr
@@ -0,0 +1,4 @@
+86250984790dd745a932f36cf229cef7 *./tests/data/vsynth2/cljr.avi
+ 5075660 ./tests/data/vsynth2/cljr.avi
+3a70ba2a535ef9c7fc6478b27a2cb58a *./tests/data/cljr.vsynth2.out.yuv
+stddev: 10.48 PSNR: 27.72 MAXDIFF: 64 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/dnxhd_720p_10bit b/tests/ref/vsynth2/dnxhd_720p_10bit
new file mode 100644
index 0000000..60c0d84
--- /dev/null
+++ b/tests/ref/vsynth2/dnxhd_720p_10bit
@@ -0,0 +1,4 @@
+4b57da2c0c1280469ff3579f7151c227 *./tests/data/vsynth2/dnxhd-720p-10bit.dnxhd
+ 2293760 ./tests/data/vsynth2/dnxhd-720p-10bit.dnxhd
+31a6aa8b8702e85fa3b48e73f035c4e4 *./tests/data/dnxhd_720p_10bit.vsynth2.out.yuv
+stddev: 1.35 PSNR: 45.46 MAXDIFF: 23 bytes: 760320/ 7603200
diff --git a/tests/ref/vsynth2/dv b/tests/ref/vsynth2/dv
index 676b209..6c010b9 100644
--- a/tests/ref/vsynth2/dv
+++ b/tests/ref/vsynth2/dv
@@ -2,7 +2,3 @@ bfa766f89bfeabc0ae1044f3954bed52 *./tests/data/vsynth2/dv.dv
7200000 ./tests/data/vsynth2/dv.dv
7ec62bd3350a6848364669e6e1e4b9cc *./tests/data/dv.vsynth2.out.yuv
stddev: 1.71 PSNR: 43.47 MAXDIFF: 33 bytes: 7603200/ 7603200
-00a9d8683ac6826af41bcf7223fb0389 *./tests/data/vsynth2/dv411.dv
-7200000 ./tests/data/vsynth2/dv411.dv
-7f9fa421028aabb11eaf4c6513a5a843 *./tests/data/dv.vsynth2.out.yuv
-stddev: 10.09 PSNR: 28.05 MAXDIFF: 60 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/dv_411 b/tests/ref/vsynth2/dv_411
new file mode 100644
index 0000000..2340ef0
--- /dev/null
+++ b/tests/ref/vsynth2/dv_411
@@ -0,0 +1,4 @@
+00a9d8683ac6826af41bcf7223fb0389 *./tests/data/vsynth2/dv411.dv
+7200000 ./tests/data/vsynth2/dv411.dv
+7f9fa421028aabb11eaf4c6513a5a843 *./tests/data/dv_411.vsynth2.out.yuv
+stddev: 10.09 PSNR: 28.05 MAXDIFF: 60 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2 b/tests/ref/vsynth2/mpeg2
index a6ab3f6..5232eea 100644
--- a/tests/ref/vsynth2/mpeg2
+++ b/tests/ref/vsynth2/mpeg2
@@ -2,19 +2,3 @@
198667 ./tests/data/vsynth2/mpeg2.mpg
b7cae8a1f751b821cddcbe4d5dbc518c *./tests/data/mpeg2.vsynth2.out.yuv
stddev: 4.96 PSNR: 34.20 MAXDIFF: 59 bytes: 7603200/ 7603200
-1ba5efeb53fab7b4b71edc96d86f6c91 *./tests/data/vsynth2/mpeg2ivlc-qprd.mpg
-244694 ./tests/data/vsynth2/mpeg2ivlc-qprd.mpg
-b26e21599dee48a174bdbc40b2817e55 *./tests/data/mpeg2.vsynth2.out.yuv
-stddev: 4.15 PSNR: 35.76 MAXDIFF: 74 bytes: 7603200/ 7603200
-2c8e33c2d2efab86fc16a195f6877682 *./tests/data/vsynth2/mpeg2_422.mpg
-356124 ./tests/data/vsynth2/mpeg2_422.mpg
-de44597c6c470f3e7019b31245a3ff69 *./tests/data/mpeg2.vsynth2.out.yuv
-stddev: 54.55 PSNR: 13.39 MAXDIFF: 201 bytes: 10137600/ 7603200
-f979bcca866e6e4cad5dc6cb06e56cfb *./tests/data/vsynth2/mpeg2.mpg
-198041 ./tests/data/vsynth2/mpeg2.mpg
-f6d9bf24ff8676a7f6076c05cd2c81a3 *./tests/data/mpeg2.vsynth2.out.yuv
-stddev: 4.97 PSNR: 34.19 MAXDIFF: 58 bytes: 7603200/ 7603200
-f90197a8b6e62ae25f82625337f27240 *./tests/data/vsynth2/mpeg2i.mpg
-204579 ./tests/data/vsynth2/mpeg2i.mpg
-ea5057b60146c06d40449cdfc686bf13 *./tests/data/mpeg2.vsynth2.out.yuv
-stddev: 4.98 PSNR: 34.18 MAXDIFF: 65 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2_422 b/tests/ref/vsynth2/mpeg2_422
new file mode 100644
index 0000000..c4e28dd
--- /dev/null
+++ b/tests/ref/vsynth2/mpeg2_422
@@ -0,0 +1,4 @@
+2c8e33c2d2efab86fc16a195f6877682 *./tests/data/vsynth2/mpeg2_422.mpg
+356124 ./tests/data/vsynth2/mpeg2_422.mpg
+de44597c6c470f3e7019b31245a3ff69 *./tests/data/mpeg2_422.vsynth2.out.yuv
+stddev: 54.55 PSNR: 13.39 MAXDIFF: 201 bytes: 10137600/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2_idct_int b/tests/ref/vsynth2/mpeg2_idct_int
new file mode 100644
index 0000000..9900497
--- /dev/null
+++ b/tests/ref/vsynth2/mpeg2_idct_int
@@ -0,0 +1,4 @@
+f979bcca866e6e4cad5dc6cb06e56cfb *./tests/data/vsynth2/mpeg2_idct_int.mpg
+198041 ./tests/data/vsynth2/mpeg2_idct_int.mpg
+f6d9bf24ff8676a7f6076c05cd2c81a3 *./tests/data/mpeg2_idct_int.vsynth2.out.yuv
+stddev: 4.97 PSNR: 34.19 MAXDIFF: 58 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2_ilace b/tests/ref/vsynth2/mpeg2_ilace
new file mode 100644
index 0000000..99d80a4
--- /dev/null
+++ b/tests/ref/vsynth2/mpeg2_ilace
@@ -0,0 +1,4 @@
+f90197a8b6e62ae25f82625337f27240 *./tests/data/vsynth2/mpeg2i.mpg
+204579 ./tests/data/vsynth2/mpeg2i.mpg
+ea5057b60146c06d40449cdfc686bf13 *./tests/data/mpeg2_ilace.vsynth2.out.yuv
+stddev: 4.98 PSNR: 34.18 MAXDIFF: 65 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2_ivlc_qprd b/tests/ref/vsynth2/mpeg2_ivlc_qprd
new file mode 100644
index 0000000..d8aa1ab
--- /dev/null
+++ b/tests/ref/vsynth2/mpeg2_ivlc_qprd
@@ -0,0 +1,4 @@
+1ba5efeb53fab7b4b71edc96d86f6c91 *./tests/data/vsynth2/mpeg2ivlc-qprd.mpg
+244694 ./tests/data/vsynth2/mpeg2ivlc-qprd.mpg
+b26e21599dee48a174bdbc40b2817e55 *./tests/data/mpeg2_ivlc_qprd.vsynth2.out.yuv
+stddev: 4.15 PSNR: 35.76 MAXDIFF: 74 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2thread b/tests/ref/vsynth2/mpeg2thread
index 3c9c0d0..7d7ed21 100644
--- a/tests/ref/vsynth2/mpeg2thread
+++ b/tests/ref/vsynth2/mpeg2thread
@@ -2,11 +2,3 @@
179650 ./tests/data/vsynth2/mpeg2thread.mpg
8c6a7ed2eb73bd18fd2bb9829464100d *./tests/data/mpeg2thread.vsynth2.out.yuv
stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
-10b900e32809758857c596d56746e00e *./tests/data/vsynth2/mpeg2threadivlc.mpg
-178801 ./tests/data/vsynth2/mpeg2threadivlc.mpg
-8c6a7ed2eb73bd18fd2bb9829464100d *./tests/data/mpeg2thread.vsynth2.out.yuv
-stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
-864d6bf2982a61e510003a518be65a2d *./tests/data/vsynth2/mpeg2reuse.mpg
-383419 ./tests/data/vsynth2/mpeg2reuse.mpg
-bb20fa080cfd2b0a687ea7376ff4f902 *./tests/data/mpeg2thread.vsynth2.out.yuv
-stddev: 4.73 PSNR: 34.63 MAXDIFF: 72 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg2thread_ilace b/tests/ref/vsynth2/mpeg2thread_ilace
new file mode 100644
index 0000000..1320db9
--- /dev/null
+++ b/tests/ref/vsynth2/mpeg2thread_ilace
@@ -0,0 +1,4 @@
+10b900e32809758857c596d56746e00e *./tests/data/vsynth2/mpeg2threadivlc.mpg
+178801 ./tests/data/vsynth2/mpeg2threadivlc.mpg
+8c6a7ed2eb73bd18fd2bb9829464100d *./tests/data/mpeg2thread_ilace.vsynth2.out.yuv
+stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4 b/tests/ref/vsynth2/mpeg4
index fe436e8..b89a3ec 100644
--- a/tests/ref/vsynth2/mpeg4
+++ b/tests/ref/vsynth2/mpeg4
@@ -1,4 +1,4 @@
-8ffbe8ce43fe126b12cf9621717d641b *./tests/data/vsynth2/odivx.mp4
-119809 ./tests/data/vsynth2/odivx.mp4
+c2ca709a0ed64833fd38f703b19e5e85 *./tests/data/vsynth2/odivx.mp4
+119833 ./tests/data/vsynth2/odivx.mp4
90a3577850239083a9042bef33c50e85 *./tests/data/mpeg4.vsynth2.out.yuv
stddev: 5.34 PSNR: 33.57 MAXDIFF: 83 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4_adap b/tests/ref/vsynth2/mpeg4_adap
new file mode 100644
index 0000000..b7a07de
--- /dev/null
+++ b/tests/ref/vsynth2/mpeg4_adap
@@ -0,0 +1,4 @@
+547e1849dcf910935ff6383ca49e5706 *./tests/data/vsynth2/mpeg4-adap.avi
+198510 ./tests/data/vsynth2/mpeg4-adap.avi
+4affb83f6adc94f31024b4f9e0168945 *./tests/data/mpeg4_adap.vsynth2.out.yuv
+stddev: 3.75 PSNR: 36.65 MAXDIFF: 71 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4_qpel b/tests/ref/vsynth2/mpeg4_qpel
new file mode 100644
index 0000000..d1f4515
--- /dev/null
+++ b/tests/ref/vsynth2/mpeg4_qpel
@@ -0,0 +1,4 @@
+7680d2e7d34399dfdfb8a49cf1e10239 *./tests/data/vsynth2/mpeg4-Q.avi
+163688 ./tests/data/vsynth2/mpeg4-Q.avi
+26dc7c78955fa678fbf150e236eb5627 *./tests/data/mpeg4_qpel.vsynth2.out.yuv
+stddev: 3.97 PSNR: 36.14 MAXDIFF: 54 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4_qprd b/tests/ref/vsynth2/mpeg4_qprd
new file mode 100644
index 0000000..17eec96
--- /dev/null
+++ b/tests/ref/vsynth2/mpeg4_qprd
@@ -0,0 +1,4 @@
+fd5ab0f55dbc959316e32923e86290df *./tests/data/vsynth2/mpeg4-qprd.avi
+231458 ./tests/data/vsynth2/mpeg4-qprd.avi
+de8a883865e2dff7a51f66da6c48df48 *./tests/data/mpeg4_qprd.vsynth2.out.yuv
+stddev: 3.71 PSNR: 36.72 MAXDIFF: 61 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/mpeg4adv b/tests/ref/vsynth2/mpeg4adv
index f8568c7..b47cbf1 100644
--- a/tests/ref/vsynth2/mpeg4adv
+++ b/tests/ref/vsynth2/mpeg4adv
@@ -2,15 +2,3 @@ dee7be19486a76d96c88d18eefba8f86 *./tests/data/vsynth2/mpeg4-adv.avi
141546 ./tests/data/vsynth2/mpeg4-adv.avi
3f3a21e9db85a9c0f7022f557a5374c1 *./tests/data/mpeg4adv.vsynth2.out.yuv
stddev: 4.94 PSNR: 34.25 MAXDIFF: 69 bytes: 7603200/ 7603200
-fd5ab0f55dbc959316e32923e86290df *./tests/data/vsynth2/mpeg4-qprd.avi
-231458 ./tests/data/vsynth2/mpeg4-qprd.avi
-de8a883865e2dff7a51f66da6c48df48 *./tests/data/mpeg4adv.vsynth2.out.yuv
-stddev: 3.71 PSNR: 36.72 MAXDIFF: 61 bytes: 7603200/ 7603200
-547e1849dcf910935ff6383ca49e5706 *./tests/data/vsynth2/mpeg4-adap.avi
-198510 ./tests/data/vsynth2/mpeg4-adap.avi
-4affb83f6adc94f31024b4f9e0168945 *./tests/data/mpeg4adv.vsynth2.out.yuv
-stddev: 3.75 PSNR: 36.65 MAXDIFF: 71 bytes: 7603200/ 7603200
-7680d2e7d34399dfdfb8a49cf1e10239 *./tests/data/vsynth2/mpeg4-Q.avi
-163688 ./tests/data/vsynth2/mpeg4-Q.avi
-26dc7c78955fa678fbf150e236eb5627 *./tests/data/mpeg4adv.vsynth2.out.yuv
-stddev: 3.97 PSNR: 36.14 MAXDIFF: 54 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/v210 b/tests/ref/vsynth2/v210
new file mode 100644
index 0000000..31160bd
--- /dev/null
+++ b/tests/ref/vsynth2/v210
@@ -0,0 +1,4 @@
+db0579bd46e1ba133ff86c0f7cdd761f *./tests/data/vsynth2/v210.avi
+14752460 ./tests/data/vsynth2/v210.avi
+a627fb50c8276200fd71383977d87ca3 *./tests/data/v210.vsynth2.out.yuv
+stddev: 0.34 PSNR: 57.43 MAXDIFF: 6 bytes: 7603200/ 7603200
diff --git a/tests/regression-funcs.sh b/tests/regression-funcs.sh
index e57cdf1..6d23fa3 100755
--- a/tests/regression-funcs.sh
+++ b/tests/regression-funcs.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# common regression functions for ffmpeg
+# common regression functions for avconv
#
#
@@ -15,13 +15,10 @@ datadir="./tests/data"
target_datadir="${target_path}/${datadir}"
this="$test.$test_ref"
-logdir="$datadir/regression/$test_ref"
-logfile="$logdir/$test"
outfile="$datadir/$test_ref/"
-errfile="$datadir/$this.err"
# various files
-ffmpeg="$target_exec ${target_path}/ffmpeg"
+avconv="$target_exec ${target_path}/avconv"
tiny_psnr="tests/tiny_psnr"
raw_src="${target_path}/$raw_src_dir/%02d.pgm"
raw_dst="$datadir/$this.out.yuv"
@@ -37,12 +34,8 @@ trap 'rm -f -- $cleanfiles' EXIT
mkdir -p "$datadir"
mkdir -p "$outfile"
-mkdir -p "$logdir"
-
-(exec >&3) 2>/dev/null || exec 3>&2
[ "${V-0}" -gt 0 ] && echov=echov || echov=:
-[ "${V-0}" -gt 1 ] || exec 2>$errfile
echov(){
echo "$@" >&3
@@ -50,74 +43,74 @@ echov(){
. $(dirname $0)/md5.sh
-FFMPEG_OPTS="-v 0 -y"
+AVCONV_OPTS="-nostats -y"
COMMON_OPTS="-flags +bitexact -idct simple -sws_flags +accurate_rnd+bitexact"
DEC_OPTS="$COMMON_OPTS -threads $threads"
ENC_OPTS="$COMMON_OPTS -threads 1 -dct fastint"
-run_ffmpeg()
+run_avconv()
{
- $echov $ffmpeg $FFMPEG_OPTS $*
- $ffmpeg $FFMPEG_OPTS $*
+ $echov $avconv $AVCONV_OPTS $*
+ $avconv $AVCONV_OPTS $*
}
-do_ffmpeg()
+do_avconv()
{
f="$1"
shift
set -- $* ${target_path}/$f
- run_ffmpeg $*
- do_md5sum $f >> $logfile
+ run_avconv $*
+ do_md5sum $f
if [ $f = $raw_dst ] ; then
- $tiny_psnr $f $raw_ref >> $logfile
+ $tiny_psnr $f $raw_ref
elif [ $f = $pcm_dst ] ; then
- $tiny_psnr $f $pcm_ref 2 >> $logfile
+ $tiny_psnr $f $pcm_ref 2
else
- wc -c $f >> $logfile
+ wc -c $f
fi
}
-do_ffmpeg_nomd5()
+do_avconv_nomd5()
{
f="$1"
shift
set -- $* ${target_path}/$f
- run_ffmpeg $*
+ run_avconv $*
if [ $f = $raw_dst ] ; then
- $tiny_psnr $f $raw_ref >> $logfile
+ $tiny_psnr $f $raw_ref
elif [ $f = $pcm_dst ] ; then
- $tiny_psnr $f $pcm_ref 2 >> $logfile
+ $tiny_psnr $f $pcm_ref 2
else
- wc -c $f >> $logfile
+ wc -c $f
fi
}
-do_ffmpeg_crc()
+do_avconv_crc()
{
f="$1"
shift
- run_ffmpeg $* -f crc "$target_crcfile"
- echo "$f $(cat $crcfile)" >> $logfile
+ run_avconv $* -f crc "$target_crcfile"
+ echo "$f $(cat $crcfile)"
}
do_video_decoding()
{
- do_ffmpeg $raw_dst $DEC_OPTS $1 -i $target_path/$file -f rawvideo $ENC_OPTS -vsync 0 $2
+ do_avconv $raw_dst $DEC_OPTS $1 -i $target_path/$file -f rawvideo $ENC_OPTS -vsync 0 $2
}
do_video_encoding()
{
file=${outfile}$1
- do_ffmpeg $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS $2
+ do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS $2
}
do_audio_encoding()
{
file=${outfile}$1
- do_ffmpeg $file $DEC_OPTS -ac 2 -ar 44100 -f s16le -i $pcm_src -ab 128k $ENC_OPTS $2
+ do_avconv $file $DEC_OPTS -ac 2 -ar 44100 -f s16le -i $pcm_src -ab 128k $ENC_OPTS $2
}
do_audio_decoding()
{
- do_ffmpeg $pcm_dst $DEC_OPTS -i $target_path/$file -sample_fmt s16 -f wav
+ do_avconv $pcm_dst $DEC_OPTS -i $target_path/$file -sample_fmt s16 -f wav
}
diff --git a/tests/rotozoom.c b/tests/rotozoom.c
index ff817ac..ba1db29 100644
--- a/tests/rotozoom.c
+++ b/tests/rotozoom.c
@@ -1,5 +1,5 @@
/*
- * Generates a synthetic YUV video sequence suitable for codec testing.
+ * Generate a synthetic YUV video sequence suitable for codec testing.
*
* copyright (c) Sebastien Bechet <s.bechet at av7.net>
*
diff --git a/tests/seek_test.c b/tests/seek_test.c
deleted file mode 100644
index 5d4f41c..0000000
--- a/tests/seek_test.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2003 Fabrice Bellard
- * Copyright (c) 2007 Michael Niedermayer
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libavutil/common.h"
-#include "libavformat/avformat.h"
-
-#undef exit
-#undef printf
-#undef fprintf
-
-static char buffer[20];
-
-static const char *ret_str(int v)
-{
- switch (v) {
- case AVERROR_EOF: return "-EOF";
- case AVERROR(EIO): return "-EIO";
- case AVERROR(ENOMEM): return "-ENOMEM";
- case AVERROR(EINVAL): return "-EINVAL";
- default:
- snprintf(buffer, sizeof(buffer), "%2d", v);
- return buffer;
- }
-}
-
-static void ts_str(char buffer[60], int64_t ts, AVRational base)
-{
- double tsval;
- if (ts == AV_NOPTS_VALUE) {
- strcpy(buffer, " NOPTS ");
- return;
- }
- tsval = ts * av_q2d(base);
- snprintf(buffer, 60, "%9f", tsval);
-}
-
-int main(int argc, char **argv)
-{
- const char *filename;
- AVFormatContext *ic = NULL;
- int i, ret, stream_id;
- int64_t timestamp;
- AVFormatParameters params, *ap= ¶ms;
- memset(ap, 0, sizeof(params));
- ap->channels=1;
- ap->sample_rate= 22050;
-
- /* initialize libavcodec, and register all codecs and formats */
- av_register_all();
-
- if (argc != 2) {
- printf("usage: %s input_file\n"
- "\n", argv[0]);
- exit(1);
- }
-
- filename = argv[1];
-
- ret = av_open_input_file(&ic, filename, NULL, 0, ap);
- if (ret < 0) {
- fprintf(stderr, "cannot open %s\n", filename);
- exit(1);
- }
-
- ret = av_find_stream_info(ic);
- if (ret < 0) {
- fprintf(stderr, "%s: could not find codec parameters\n", filename);
- exit(1);
- }
-
- for(i=0; ; i++){
- AVPacket pkt;
- AVStream *av_uninit(st);
- char ts_buf[60];
-
- memset(&pkt, 0, sizeof(pkt));
- if(ret>=0){
- ret= av_read_frame(ic, &pkt);
- if(ret>=0){
- char dts_buf[60];
- st= ic->streams[pkt.stream_index];
- ts_str(dts_buf, pkt.dts, st->time_base);
- ts_str(ts_buf, pkt.pts, st->time_base);
- printf("ret:%-10s st:%2d flags:%d dts:%s pts:%s pos:%7" PRId64 " size:%6d", ret_str(ret), pkt.stream_index, pkt.flags, dts_buf, ts_buf, pkt.pos, pkt.size);
- av_free_packet(&pkt);
- } else
- printf("ret:%s", ret_str(ret)); // necessary to avoid trailing whitespace
- printf("\n");
- }
-
- if(i>25) break;
-
- stream_id= (i>>1)%(ic->nb_streams+1) - 1;
- timestamp= (i*19362894167LL) % (4*AV_TIME_BASE) - AV_TIME_BASE;
- if(stream_id>=0){
- st= ic->streams[stream_id];
- timestamp= av_rescale_q(timestamp, AV_TIME_BASE_Q, st->time_base);
- }
- //FIXME fully test the new seek API
- if(i&1) ret = avformat_seek_file(ic, stream_id, INT64_MIN, timestamp, timestamp, 0);
- else ret = avformat_seek_file(ic, stream_id, timestamp, timestamp, INT64_MAX, 0);
- ts_str(ts_buf, timestamp, stream_id < 0 ? AV_TIME_BASE_Q : st->time_base);
- printf("ret:%-10s st:%2d flags:%d ts:%s\n", ret_str(ret), stream_id, i&1, ts_buf);
- }
-
- av_close_input_file(ic);
-
- return 0;
-}
diff --git a/tests/videogen.c b/tests/videogen.c
index f114801..957692d 100644
--- a/tests/videogen.c
+++ b/tests/videogen.c
@@ -1,6 +1,6 @@
/*
- * Generates a synthetic YUV video sequence suitable for codec testing.
- * NOTE: No floats are used to guarantee a bit exact output.
+ * Generate a synthetic YUV video sequence suitable for codec testing.
+ * NOTE: No floats are used to guarantee bitexact output.
*
* Copyright (c) 2002 Fabrice Bellard
*
diff --git a/tools/cws2fws.c b/tools/cws2fws.c
index b8535fe..35fce35 100644
--- a/tools/cws2fws.c
+++ b/tools/cws2fws.c
@@ -29,14 +29,14 @@ int main(int argc, char *argv[])
if (argc < 3)
{
printf("Usage: %s <infile.swf> <outfile.swf>\n", argv[0]);
- exit(1);
+ return 1;
}
fd_in = open(argv[1], O_RDONLY);
if (fd_in < 0)
{
perror("Error opening input file");
- exit(1);
+ return 1;
}
fd_out = open(argv[2], O_WRONLY|O_CREAT, 00644);
@@ -44,7 +44,7 @@ int main(int argc, char *argv[])
{
perror("Error opening output file");
close(fd_in);
- exit(1);
+ return 1;
}
if (read(fd_in, &buf_in, 8) != 8)
@@ -52,13 +52,13 @@ int main(int argc, char *argv[])
printf("Header error\n");
close(fd_in);
close(fd_out);
- exit(1);
+ return 1;
}
if (buf_in[0] != 'C' || buf_in[1] != 'W' || buf_in[2] != 'S')
{
printf("Not a compressed flash file\n");
- exit(1);
+ return 1;
}
fstat(fd_in, &statbuf);
@@ -71,7 +71,7 @@ int main(int argc, char *argv[])
buf_in[0] = 'F';
if (write(fd_out, &buf_in, 8) < 8) {
perror("Error writing output file");
- exit(1);
+ return 1;
}
zstream.zalloc = NULL;
@@ -97,7 +97,7 @@ int main(int argc, char *argv[])
{
printf("Error while decompressing: %d\n", ret);
inflateEnd(&zstream);
- exit(1);
+ return 1;
}
dbgprintf("a_in: %d t_in: %lu a_out: %d t_out: %lu -- %lu out\n",
@@ -106,7 +106,7 @@ int main(int argc, char *argv[])
if (write(fd_out, &buf_out, zstream.total_out - last_out) < zstream.total_out - last_out) {
perror("Error writing output file");
- exit(1);
+ return 1;
}
i += len;
@@ -128,7 +128,7 @@ int main(int argc, char *argv[])
lseek(fd_out, 4, SEEK_SET);
if (write(fd_out, &buf_in, 4) < 4) {
perror("Error writing output file");
- exit(1);
+ return 1;
}
}
diff --git a/tools/patcheck b/tools/patcheck
index 19faf47..ae2c80b 100755
--- a/tools/patcheck
+++ b/tools/patcheck
@@ -55,6 +55,7 @@ hiegrep 'INIT_VLC_USE_STATIC' 'forbidden ancient vlc type' $*
hiegrep '=[-+\*\&] ' 'looks like compound assignment' $*
hiegrep2 '/\*\* *[a-zA-Z0-9].*' '\*/' 'Inconsistently formatted doxygen comment' $*
hiegrep '; */\*\*[^<]' 'Misformatted doxygen comment' $*
+hiegrep '//!|/\*!' 'inconsistent doxygen syntax' $*
hiegrep2 '(int|unsigned|static|void)[a-zA-Z0-9 _]*(init|end)[a-zA-Z0-9 _]*\(.*[^;]$' '(av_cold|:\+[^a-zA-Z_])' 'These functions may need av_cold, please review the whole patch for similar functions needing av_cold' $*
@@ -66,7 +67,7 @@ $EGREP $OPT '^\+ *(const *|)static' $*| $EGREP --color=always '[^=]= *(0|NULL)[^
cat $TMP
hiegrep '# *ifdef * (HAVE|CONFIG)_' 'ifdefs that should be #if' $*
-hiegrep '\b(awnser|cant|dont|quantised|quantisation|teh|wont)\b' 'common typos' $*
+hiegrep '\b(awnser|cant|dont|wont|usefull|successfull|occured|teh|alot|wether|skiped|heigth|informations|colums|loosy|loosing|seperate|preceed)\b' 'common typos' $*
hiegrep 'av_log\( *NULL' 'Missing context in av_log' $*
hiegrep '[^sn]printf' 'Please use av_log' $*
diff --git a/tools/pktdumper.c b/tools/pktdumper.c
index 80816d2..e9e5acf 100644
--- a/tools/pktdumper.c
+++ b/tools/pktdumper.c
@@ -44,7 +44,7 @@ int main(int argc, char **argv)
{
char fntemplate[PATH_MAX];
char pktfilename[PATH_MAX];
- AVFormatContext *fctx;
+ AVFormatContext *fctx = NULL;
AVPacket pkt;
int64_t pktnum = 0;
int64_t maxpkts = 0;
@@ -83,15 +83,15 @@ int main(int argc, char **argv)
// register all file formats
av_register_all();
- err = av_open_input_file(&fctx, argv[1], NULL, 0, NULL);
+ err = avformat_open_input(&fctx, argv[1], NULL, NULL);
if (err < 0) {
- fprintf(stderr, "av_open_input_file: error %d\n", err);
+ fprintf(stderr, "cannot open input: error %d\n", err);
return 1;
}
- err = av_find_stream_info(fctx);
+ err = avformat_find_stream_info(fctx, NULL);
if (err < 0) {
- fprintf(stderr, "av_find_stream_info: error %d\n", err);
+ fprintf(stderr, "avformat_find_stream_info: error %d\n", err);
return 1;
}
@@ -117,7 +117,7 @@ int main(int argc, char **argv)
break;
}
- av_close_input_file(fctx);
+ avformat_close_input(&fctx);
while (donotquit)
sleep(60);
diff --git a/tools/qt-faststart.c b/tools/qt-faststart.c
index eefeafd..71fe845 100644
--- a/tools/qt-faststart.c
+++ b/tools/qt-faststart.c
@@ -30,29 +30,31 @@
#include <string.h>
#ifdef __MINGW32__
-#define fseeko(x,y,z) fseeko64(x,y,z)
-#define ftello(x) ftello64(x)
+#define fseeko(x, y, z) fseeko64(x, y, z)
+#define ftello(x) ftello64(x)
#endif
-#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
-#define BE_32(x) ((((uint8_t*)(x))[0] << 24) | \
- (((uint8_t*)(x))[1] << 16) | \
- (((uint8_t*)(x))[2] << 8) | \
+#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
+
+#define BE_32(x) ((((uint8_t*)(x))[0] << 24) | \
+ (((uint8_t*)(x))[1] << 16) | \
+ (((uint8_t*)(x))[2] << 8) | \
((uint8_t*)(x))[3])
-#define BE_64(x) (((uint64_t)(((uint8_t*)(x))[0]) << 56) | \
- ((uint64_t)(((uint8_t*)(x))[1]) << 48) | \
- ((uint64_t)(((uint8_t*)(x))[2]) << 40) | \
- ((uint64_t)(((uint8_t*)(x))[3]) << 32) | \
- ((uint64_t)(((uint8_t*)(x))[4]) << 24) | \
- ((uint64_t)(((uint8_t*)(x))[5]) << 16) | \
- ((uint64_t)(((uint8_t*)(x))[6]) << 8) | \
- ((uint64_t)((uint8_t*)(x))[7]))
-
-#define BE_FOURCC( ch0, ch1, ch2, ch3 ) \
- ( (uint32_t)(unsigned char)(ch3) | \
- ( (uint32_t)(unsigned char)(ch2) << 8 ) | \
- ( (uint32_t)(unsigned char)(ch1) << 16 ) | \
- ( (uint32_t)(unsigned char)(ch0) << 24 ) )
+
+#define BE_64(x) (((uint64_t)(((uint8_t*)(x))[0]) << 56) | \
+ ((uint64_t)(((uint8_t*)(x))[1]) << 48) | \
+ ((uint64_t)(((uint8_t*)(x))[2]) << 40) | \
+ ((uint64_t)(((uint8_t*)(x))[3]) << 32) | \
+ ((uint64_t)(((uint8_t*)(x))[4]) << 24) | \
+ ((uint64_t)(((uint8_t*)(x))[5]) << 16) | \
+ ((uint64_t)(((uint8_t*)(x))[6]) << 8) | \
+ ((uint64_t)( (uint8_t*)(x))[7]))
+
+#define BE_FOURCC(ch0, ch1, ch2, ch3) \
+ ( (uint32_t)(unsigned char)(ch3) | \
+ ((uint32_t)(unsigned char)(ch2) << 8) | \
+ ((uint32_t)(unsigned char)(ch1) << 16) | \
+ ((uint32_t)(unsigned char)(ch0) << 24) )
#define QT_ATOM BE_FOURCC
/* top level atoms */
@@ -71,16 +73,16 @@
#define STCO_ATOM QT_ATOM('s', 't', 'c', 'o')
#define CO64_ATOM QT_ATOM('c', 'o', '6', '4')
-#define ATOM_PREAMBLE_SIZE 8
-#define COPY_BUFFER_SIZE 1024
+#define ATOM_PREAMBLE_SIZE 8
+#define COPY_BUFFER_SIZE 1024
int main(int argc, char *argv[])
{
FILE *infile = NULL;
FILE *outfile = NULL;
unsigned char atom_bytes[ATOM_PREAMBLE_SIZE];
- uint32_t atom_type = 0;
- uint64_t atom_size = 0;
+ uint32_t atom_type = 0;
+ uint64_t atom_size = 0;
uint64_t atom_offset = 0;
uint64_t last_offset;
unsigned char *moov_atom = NULL;
@@ -95,7 +97,7 @@ int main(int argc, char *argv[])
int bytes_to_copy;
if (argc != 3) {
- printf ("Usage: qt-faststart <infile.mov> <outfile.mov>\n");
+ printf("Usage: qt-faststart <infile.mov> <outfile.mov>\n");
return 0;
}
@@ -116,7 +118,7 @@ int main(int argc, char *argv[])
if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) {
break;
}
- atom_size = (uint32_t)BE_32(&atom_bytes[0]);
+ atom_size = (uint32_t) BE_32(&atom_bytes[0]);
atom_type = BE_32(&atom_bytes[4]);
/* keep ftyp atom */
@@ -125,8 +127,8 @@ int main(int argc, char *argv[])
free(ftyp_atom);
ftyp_atom = malloc(ftyp_atom_size);
if (!ftyp_atom) {
- printf ("could not allocate %"PRIu64" byte for ftyp atom\n",
- atom_size);
+ printf("could not allocate %"PRIu64" bytes for ftyp atom\n",
+ atom_size);
goto error_out;
}
fseeko(infile, -ATOM_PREAMBLE_SIZE, SEEK_CUR);
@@ -137,17 +139,17 @@ int main(int argc, char *argv[])
start_offset = ftello(infile);
} else {
- /* 64-bit special case */
- if (atom_size == 1) {
- if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) {
- break;
+ /* 64-bit special case */
+ if (atom_size == 1) {
+ if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) {
+ break;
+ }
+ atom_size = BE_64(&atom_bytes[0]);
+ fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE * 2, SEEK_CUR);
+ } else {
+ fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE, SEEK_CUR);
}
- atom_size = BE_64(&atom_bytes[0]);
- fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE * 2, SEEK_CUR);
- } else {
- fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE, SEEK_CUR);
}
- }
printf("%c%c%c%c %10"PRIu64" %"PRIu64"\n",
(atom_type >> 24) & 255,
(atom_type >> 16) & 255,
@@ -165,7 +167,7 @@ int main(int argc, char *argv[])
(atom_type != PICT_ATOM) &&
(atom_type != UUID_ATOM) &&
(atom_type != FTYP_ATOM)) {
- printf ("encountered non-QT top-level atom (is this a Quicktime file?)\n");
+ printf("encountered non-QT top-level atom (is this a QuickTime file?)\n");
break;
}
atom_offset += atom_size;
@@ -178,7 +180,7 @@ int main(int argc, char *argv[])
}
if (atom_type != MOOV_ATOM) {
- printf ("last atom in file was not a moov atom\n");
+ printf("last atom in file was not a moov atom\n");
free(ftyp_atom);
fclose(infile);
return 0;
@@ -187,12 +189,11 @@ int main(int argc, char *argv[])
/* moov atom was, in fact, the last atom in the chunk; load the whole
* moov atom */
fseeko(infile, -atom_size, SEEK_END);
- last_offset = ftello(infile);
+ last_offset = ftello(infile);
moov_atom_size = atom_size;
- moov_atom = malloc(moov_atom_size);
+ moov_atom = malloc(moov_atom_size);
if (!moov_atom) {
- printf ("could not allocate %"PRIu64" byte for moov atom\n",
- atom_size);
+ printf("could not allocate %"PRIu64" bytes for moov atom\n", atom_size);
goto error_out;
}
if (fread(moov_atom, atom_size, 1, infile) != 1) {
@@ -203,7 +204,7 @@ int main(int argc, char *argv[])
/* this utility does not support compressed atoms yet, so disqualify
* files with compressed QT atoms */
if (BE_32(&moov_atom[12]) == CMOV_ATOM) {
- printf ("this utility does not support compressed moov atoms yet\n");
+ printf("this utility does not support compressed moov atoms yet\n");
goto error_out;
}
@@ -215,15 +216,15 @@ int main(int argc, char *argv[])
for (i = 4; i < moov_atom_size - 4; i++) {
atom_type = BE_32(&moov_atom[i]);
if (atom_type == STCO_ATOM) {
- printf (" patching stco atom...\n");
+ printf(" patching stco atom...\n");
atom_size = BE_32(&moov_atom[i - 4]);
if (i + atom_size - 4 > moov_atom_size) {
- printf (" bad atom size\n");
+ printf(" bad atom size\n");
goto error_out;
}
offset_count = BE_32(&moov_atom[i + 8]);
for (j = 0; j < offset_count; j++) {
- current_offset = BE_32(&moov_atom[i + 12 + j * 4]);
+ current_offset = BE_32(&moov_atom[i + 12 + j * 4]);
current_offset += moov_atom_size;
moov_atom[i + 12 + j * 4 + 0] = (current_offset >> 24) & 0xFF;
moov_atom[i + 12 + j * 4 + 1] = (current_offset >> 16) & 0xFF;
@@ -232,15 +233,15 @@ int main(int argc, char *argv[])
}
i += atom_size - 4;
} else if (atom_type == CO64_ATOM) {
- printf (" patching co64 atom...\n");
+ printf(" patching co64 atom...\n");
atom_size = BE_32(&moov_atom[i - 4]);
if (i + atom_size - 4 > moov_atom_size) {
- printf (" bad atom size\n");
+ printf(" bad atom size\n");
goto error_out;
}
offset_count = BE_32(&moov_atom[i + 8]);
for (j = 0; j < offset_count; j++) {
- current_offset = BE_64(&moov_atom[i + 12 + j * 8]);
+ current_offset = BE_64(&moov_atom[i + 12 + j * 8]);
current_offset += moov_atom_size;
moov_atom[i + 12 + j * 8 + 0] = (current_offset >> 56) & 0xFF;
moov_atom[i + 12 + j * 8 + 1] = (current_offset >> 48) & 0xFF;
@@ -275,7 +276,7 @@ int main(int argc, char *argv[])
/* dump the same ftyp atom */
if (ftyp_atom_size > 0) {
- printf (" writing ftyp atom...\n");
+ printf(" writing ftyp atom...\n");
if (fwrite(ftyp_atom, ftyp_atom_size, 1, outfile) != 1) {
perror(argv[2]);
goto error_out;
@@ -283,14 +284,14 @@ int main(int argc, char *argv[])
}
/* dump the new moov atom */
- printf (" writing moov atom...\n");
+ printf(" writing moov atom...\n");
if (fwrite(moov_atom, moov_atom_size, 1, outfile) != 1) {
perror(argv[2]);
goto error_out;
}
/* copy the remainder of the infile, from offset 0 -> last_offset - 1 */
- printf (" copying rest of file...\n");
+ printf(" copying rest of file...\n");
while (last_offset) {
if (last_offset > COPY_BUFFER_SIZE)
bytes_to_copy = COPY_BUFFER_SIZE;
@@ -305,7 +306,6 @@ int main(int argc, char *argv[])
perror(argv[2]);
goto error_out;
}
-
last_offset -= bytes_to_copy;
}
--
Libav/FFmpeg packaging
More information about the pkg-multimedia-commits
mailing list